diff --git a/doc/siproxd.conf.example b/doc/siproxd.conf.example index 42ce004..9e65344 100644 --- a/doc/siproxd.conf.example +++ b/doc/siproxd.conf.example @@ -344,6 +344,7 @@ load_plugin=plugin_logcall.la #load_plugin=plugin_siptrunk.la #load_plugin=plugin_fix_fbox_anoncall.la #load_plugin=plugin_stats.la +#load_plugin=plugin_blacklist.la ###################################################################### @@ -535,17 +536,20 @@ plugin_fix_fbox_anoncall_networks = 192.168.0.0/16,10.0.0.0/8,172.16.0.0/20 # during the duration to recover (the UAC must remain silent during # this period) # -# ..._dbpath: path where to locate the database -# ..._mode: 0: no block, 1: IP based, 2: IP and SIP-user based -# ..._simulate: 0: block UACs once the failure count limit has been reached -# 1: simulate, only log but don't block -# ..._duration: block duration in seconds, 0: forever -# ..._hitcount: required failed REGISTER attempts until blocked. +# ...dbpath: path where the database is located +# ...mode: 0: no block, 1: IP based, 2: IP and SIP-user based +# ...simulate: 0: block UACs once the failure count limit has been reached +# 1: simulate, only log but don't block +# ...duration: block duration in seconds, 0: forever +# ...hitcount: required failed REGISTER attempts until blocked. +# ...register_window: time window within which a response to a REGISTER must +# be received, otherwise the REGISTER response will be +# ignored for blacklisting # plugin_blacklist_dbpath = /var/lib/siproxd/blacklist.sqlite //plugin_blacklist_mode = 0 plugin_blacklist_simulate = 0 plugin_blacklist_duration = 3600 plugin_blacklist_hitcount = 10 - +plugin_blacklist_register_window = 30 diff --git a/src/plugin_blacklist.c b/src/plugin_blacklist.c index b85bb6e..dc4d654 100644 --- a/src/plugin_blacklist.c +++ b/src/plugin_blacklist.c @@ -23,6 +23,7 @@ #include "config.h" +#include #include #include @@ -57,6 +58,7 @@ static struct plugin_config { int simulate; /* 0: no, 1: don't block, just log */ int duration; /* in seconds, 0: forever, dont' expire */ int hitcount; /* required attempts until blocked */ + int register_window;/* time window for REGISTER reesponse to arrive */ } plugin_cfg; /* Instructions for config parser */ @@ -66,6 +68,7 @@ static cfgopts_t plugin_cfg_opts[] = { { "plugin_blacklist_simulate", TYP_INT4, &plugin_cfg.simulate, {0, NULL} }, { "plugin_blacklist_duration", TYP_INT4, &plugin_cfg.duration, {3600, NULL} }, { "plugin_blacklist_hitcount", TYP_INT4, &plugin_cfg.hitcount, {10, NULL} }, + { "plugin_blacklist_register_window", TYP_INT4, &plugin_cfg.register_window, {30, NULL} }, {0, 0, 0} }; @@ -83,27 +86,29 @@ static sql_statement_t sql_statement[] = { /* blacklist_check() */ { 0, NULL, "SELECT count(*) from blacklist WHERE ip=?001 and sipuri=?002 AND (type=1 or failcount>?003);" }, { 1, NULL, "UPDATE OR IGNORE blacklist SET lastseen=?003 WHERE ip=?001 and sipuri=?002;" }, - { 2, NULL, "INSERT OR REPLACE INTO requests (timestamp, ip, sipuri, callid) VALUES (?001, ?002, ?003, ?004);" }, + { 2, NULL, "UPDATE OR IGNORE requests SET timestamp=?001, callid=?004 WHERE ip=?002 AND sipuri=?003;" }, + { 3, NULL, "INSERT OR IGNORE INTO requests (timestamp, ip, sipuri, callid) VALUES (?001, ?002, ?003, ?004);" }, /* blacklist_update() */ - { 3, NULL, "DELETE FROM requests WHERE timestampsipmsg)) { - /* Query 3: INSERT OR IGNORE REGISTER request into requests DB */ + /* Query 3: UPDATE OR IGNORE REGISTER request into requests DB */ /* bind */ sql_stmt = &sql_statement[SQL_CHECK_3]; sts = sqlite3_bind_int(sql_stmt->stmt, 001, ticket->timestamp); @@ -295,15 +302,27 @@ static int blacklist_check(sip_ticket_t *ticket) { sts = sqlite3_bind_text(sql_stmt->stmt, 004, call_id,-1, SQLITE_TRANSIENT); sts = sqlite_exec_stmt_none(sql_stmt); sql_stmt = NULL; + /* Query 3: INSERT OR IGNORE REGISTER request into requests DB */ + /* bind */ + sql_stmt = &sql_statement[SQL_CHECK_4]; + sts = sqlite3_bind_int(sql_stmt->stmt, 001, ticket->timestamp); + sts = sqlite3_bind_text(sql_stmt->stmt, 002, srcip, -1, SQLITE_TRANSIENT); + sts = sqlite3_bind_text(sql_stmt->stmt, 003, from, -1, SQLITE_TRANSIENT); + sts = sqlite3_bind_text(sql_stmt->stmt, 004, call_id,-1, SQLITE_TRANSIENT); + sts = sqlite_exec_stmt_none(sql_stmt); + sql_stmt = NULL; } // not present in sqlite 3.3.6 sts = sqlite3_clear_bindings(stmt1); - if (retval > 0) { + if ((retval > 0) && (plugin_cfg.simulate==0)) { DEBUGC(DBCLASS_BABBLE, "leaving blacklist_check, UAC is blocked"); INFO ("UAC with IP %s [%s] is blocked", srcip, from); osip_free(from); return STS_FAILURE; + } else if (retval > 0) { + DEBUGC(DBCLASS_BABBLE, "leaving blacklist_check, UAC is blocked"); + INFO ("UAC with IP %s [%s] would be blocked (simulate=1)", srcip, from); } /* free resources */ @@ -325,10 +344,10 @@ static int blacklist_update(sip_ticket_t *ticket) { DEBUGC(DBCLASS_BABBLE, "entering blacklist_update"); - /* Query 1: remove old records (> 30s) */ + /* Query 1: remove old records (> register_window seconds) */ /* bind */ sql_stmt = &sql_statement[SQL_UPDATE_1]; - sts = sqlite3_bind_int(sql_stmt->stmt, 001, ticket->timestamp - 30); + sts = sqlite3_bind_int(sql_stmt->stmt, 001, ticket->timestamp - plugin_cfg.register_window); sts = sqlite_exec_stmt_none(sql_stmt); sql_stmt = NULL; @@ -417,6 +436,7 @@ static int blacklist_update(sip_ticket_t *ticket) { } +#if 0 static int blacklist_expire(sip_ticket_t *ticket) { // int sts; // char *zErrMsg = NULL; @@ -428,7 +448,7 @@ static int blacklist_expire(sip_ticket_t *ticket) { DEBUGC(DBCLASS_BABBLE, "leaving blacklist_expire"); return STS_SUCCESS; } - +#endif /*--------------------------------------------------------------------*/ /* helper functions */ diff --git a/src/plugin_codecfilter.c b/src/plugin_codecfilter.c index ce72592..e65ce62 100644 --- a/src/plugin_codecfilter.c +++ b/src/plugin_codecfilter.c @@ -267,7 +267,7 @@ static int sdp_filter_codec(sdp_message_t *sdp) { // for (i=0; ia_att_value, plugin_cfg.codec_blacklist.string[i])) { +/*&&&*/ if (strcasestr(sdp_attr->a_att_value, plugin_cfg.codec_blacklist.string[i])) { // match, need to remove this codec DEBUGC(DBCLASS_PLUGIN, "%s: blacklisted - removing media attr [%s] at attrpos=%i", name, sdp_attr->a_att_value, media_attr_no); @@ -289,7 +289,7 @@ static int sdp_filter_codec(sdp_message_t *sdp) { if ((attr = osip_list_get(&med->a_attributes, media_attr_no)) != NULL) { osip_list_remove(&med->a_attributes, media_attr_no); - sdp_attribute_free(attr); +/*&&&*/ sdp_attribute_free(attr); attr=NULL; // as I have removed the current attribute, all other // attributes are shifted one down, so for the next iteration