FS-4315 --resolve

This commit is contained in:
Anthony Minessale 2012-09-20 09:53:53 -05:00
parent c6e7549055
commit 0dac490086
1 changed files with 71 additions and 42 deletions

View File

@ -46,22 +46,39 @@ struct mod_spy_globals {
uint32_t spy_count; uint32_t spy_count;
} globals; } globals;
typedef struct spy {
const char *uuid;
struct spy *next;
} spy_t;
static switch_status_t spy_on_hangup(switch_core_session_t *session) static switch_status_t spy_on_hangup(switch_core_session_t *session)
{ {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
const char *data = switch_channel_get_private(channel, "_userspy_");
const char *uuid = switch_core_session_get_uuid(session);
spy_t *spy = NULL, *p = NULL, *prev = NULL;
char *data = switch_channel_get_private(channel, "_userspy_");
switch_thread_rwlock_wrlock(globals.spy_hash_lock); switch_thread_rwlock_wrlock(globals.spy_hash_lock);
if ((switch_core_hash_delete(globals.spy_hash, data) != SWITCH_STATUS_SUCCESS)) { spy = switch_core_hash_find(globals.spy_hash, data);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No such key in userspy: %s \n", data); for (p = spy; p; p = p->next) {
if (p->uuid == uuid) {
} else { if (prev) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Userspy deactivated on %s\n", data); prev->next = p->next;
globals.spy_count--; } else {
spy = p->next;
}
globals.spy_count--;
break;
}
prev = p;
} }
switch_core_hash_insert(globals.spy_hash, data, spy);
switch_thread_rwlock_unlock(globals.spy_hash_lock); switch_thread_rwlock_unlock(globals.spy_hash_lock);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -115,12 +132,20 @@ SWITCH_STANDARD_API(dump_hash)
switch_hash_index_t *hi; switch_hash_index_t *hi;
const void *key; const void *key;
void *val; void *val;
spy_t *spy;
switch_thread_rwlock_rdlock(globals.spy_hash_lock); switch_thread_rwlock_rdlock(globals.spy_hash_lock);
for (hi = switch_hash_first(NULL, globals.spy_hash); hi; hi = switch_hash_next(hi)) { for (hi = switch_hash_first(NULL, globals.spy_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &key, NULL, &val); switch_hash_this(hi, &key, NULL, &val);
stream->write_function(stream, "%s : %s\n", (char *) key, (const char *) val); spy = (spy_t *) val;
stream->write_function(stream, "%s :");
while (spy) {
stream->write_function(stream, " %s", spy->uuid);
spy = spy->next;
}
stream->write_function(stream, "\n");
} }
stream->write_function(stream, "\n%d total spy\n", globals.spy_count); stream->write_function(stream, "\n%d total spy\n", globals.spy_count);
@ -130,9 +155,10 @@ SWITCH_STANDARD_API(dump_hash)
static switch_status_t process_event(switch_event_t *event) static switch_status_t process_event(switch_event_t *event)
{ {
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
char *username[3] = { 0 }; char *username[3] = { NULL };
char *domain[3] = { 0 }; char *domain[3] = { NULL };
char key[512]; char key[512];
char *uuid = NULL, *my_uuid = NULL; char *uuid = NULL, *my_uuid = NULL;
int i; int i;
@ -147,8 +173,8 @@ static switch_status_t process_event(switch_event_t *event)
username[0] = switch_event_get_header(event, "Caller-Username"); username[0] = switch_event_get_header(event, "Caller-Username");
domain[0] = switch_event_get_header(event, "variable_domain_name"); domain[0] = switch_event_get_header(event, "variable_domain_name");
domain[1] = switch_event_get_header(event, "variable_dialed_domain");
username[1] = switch_event_get_header(event, "variable_dialed_user"); username[1] = switch_event_get_header(event, "variable_dialed_user");
domain[1] = switch_event_get_header(event, "variable_dialed_domain");
username[2] = switch_event_get_header(event, "variable_user_name"); username[2] = switch_event_get_header(event, "variable_user_name");
domain[2] = switch_event_get_header(event, "variable_domain_name"); domain[2] = switch_event_get_header(event, "variable_domain_name");
@ -156,35 +182,39 @@ static switch_status_t process_event(switch_event_t *event)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (username[i] && domain[i]) { if (username[i] && domain[i]) {
spy_t *spy = NULL;
switch_snprintf(key, sizeof(key), "%s@%s", username[i], domain[i]); switch_snprintf(key, sizeof(key), "%s@%s", username[i], domain[i]);
if ((uuid = switch_core_hash_find(globals.spy_hash, key))) { if ((spy = switch_core_hash_find(globals.spy_hash, key))) {
while (spy) {
if ((session = switch_core_session_locate(spy->uuid))) {
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop\n", uuid, key);
my_uuid = switch_event_get_header(event, "Unique-ID");
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
switch_channel_set_flag(channel, CF_BREAK);
switch_core_session_rwunlock(session);
}
spy = spy->next;
}
break; break;
} else {
/* not found */
status = SWITCH_STATUS_FALSE;
} }
} }
} }
done: done:
switch_thread_rwlock_unlock(globals.spy_hash_lock); switch_thread_rwlock_unlock(globals.spy_hash_lock);
return status;
if (!uuid) {
return SWITCH_STATUS_FALSE;
}
if ((session = switch_core_session_locate(uuid))) {
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop \n", uuid, key);
my_uuid = switch_event_get_header(event, "Unique-ID");
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
switch_channel_set_state(channel, CS_EXCHANGE_MEDIA);
switch_channel_set_flag(channel, CF_BREAK);
switch_core_session_rwunlock(session);
}
return SWITCH_STATUS_SUCCESS;
} }
@ -233,20 +263,20 @@ SWITCH_STANDARD_APP(userspy_function)
if (!zstr(data) && (params = switch_core_session_strdup(session, data))) { if (!zstr(data) && (params = switch_core_session_strdup(session, data))) {
if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) { if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 1) {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
char *uuid = switch_core_session_get_uuid(session); char *uuid = switch_core_session_get_uuid(session);
switch_status_t status; switch_status_t status;
spy_t *spy = NULL;
spy = switch_core_session_alloc(session, sizeof(spy_t));
switch_assert(spy != NULL);
spy->uuid = uuid;
switch_thread_rwlock_wrlock(globals.spy_hash_lock); switch_thread_rwlock_wrlock(globals.spy_hash_lock);
if (switch_core_hash_find(globals.spy_hash, argv[0])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Spy already exists for %s\n", argv[0]);
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
switch_thread_rwlock_unlock(globals.spy_hash_lock);
return;
}
status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) uuid); spy->next = (spy_t *) switch_core_hash_find(globals.spy_hash, argv[0]);
status = switch_core_hash_insert(globals.spy_hash, argv[0], (void *) spy);
if ((status != SWITCH_STATUS_SUCCESS)) { if ((status != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't insert to spy hash\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't insert to spy hash\n");
@ -270,11 +300,10 @@ SWITCH_STANDARD_APP(userspy_function)
} }
switch_channel_set_state(channel, CS_PARK); switch_channel_set_state(channel, CS_PARK);
return;
} }
return; } else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", USERSPY_SYNTAX);
} }
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", USERSPY_SYNTAX);
} }
SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load) SWITCH_MODULE_LOAD_FUNCTION(mod_spy_load)