|
@@ -30,6 +30,7 @@
|
|
|
|
|
|
#include "mod_sanity.h"
|
|
|
#include "sanity.h"
|
|
|
+#include "api.h"
|
|
|
#include "../../sr_module.h"
|
|
|
#include "../../ut.h"
|
|
|
#include "../../error.h"
|
|
@@ -40,8 +41,8 @@ MODULE_VERSION
|
|
|
|
|
|
str pr_str = STR_STATIC_INIT(PROXY_REQUIRE_DEF);
|
|
|
|
|
|
-int default_checks = SANITY_DEFAULT_CHECKS;
|
|
|
-int uri_checks = SANITY_DEFAULT_URI_CHECKS;
|
|
|
+int default_msg_checks = SANITY_DEFAULT_CHECKS;
|
|
|
+int default_uri_checks = SANITY_DEFAULT_URI_CHECKS;
|
|
|
int _sanity_drop = 1;
|
|
|
|
|
|
strl* proxyrequire_list = NULL;
|
|
@@ -50,18 +51,20 @@ sl_api_t slb;
|
|
|
|
|
|
static int mod_init(void);
|
|
|
static int sanity_fixup(void** param, int param_no);
|
|
|
-static int sanity_check(struct sip_msg* _msg, char* _foo, char* _bar);
|
|
|
+static int w_sanity_check(struct sip_msg* _msg, char* _foo, char* _bar);
|
|
|
+static int bind_sanity(sanity_api_t* api);
|
|
|
|
|
|
/*
|
|
|
* Exported functions
|
|
|
*/
|
|
|
static cmd_export_t cmds[] = {
|
|
|
- {"sanity_check", (cmd_function)sanity_check, 0, 0,
|
|
|
+ {"sanity_check", (cmd_function)w_sanity_check, 0, 0,
|
|
|
REQUEST_ROUTE},
|
|
|
- {"sanity_check", (cmd_function)sanity_check, 1, sanity_fixup,
|
|
|
+ {"sanity_check", (cmd_function)w_sanity_check, 1, sanity_fixup,
|
|
|
REQUEST_ROUTE},
|
|
|
- {"sanity_check", (cmd_function)sanity_check, 2, sanity_fixup,
|
|
|
+ {"sanity_check", (cmd_function)w_sanity_check, 2, sanity_fixup,
|
|
|
REQUEST_ROUTE},
|
|
|
+ {"bind_sanity", (cmd_function)bind_sanity, 0, 0, 0},
|
|
|
{0, 0, 0, 0}
|
|
|
};
|
|
|
|
|
@@ -69,8 +72,8 @@ static cmd_export_t cmds[] = {
|
|
|
* Exported parameters
|
|
|
*/
|
|
|
static param_export_t params[] = {
|
|
|
- {"default_checks", PARAM_INT, &default_checks },
|
|
|
- {"uri_checks", PARAM_INT, &uri_checks },
|
|
|
+ {"default_checks", PARAM_INT, &default_msg_checks },
|
|
|
+ {"uri_checks", PARAM_INT, &default_uri_checks },
|
|
|
{"proxy_require", PARAM_STR, &pr_str },
|
|
|
{"autodrop", PARAM_INT, &_sanity_drop },
|
|
|
{0, 0, 0}
|
|
@@ -151,79 +154,117 @@ static int sanity_fixup(void** param, int param_no) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int sanity_check(struct sip_msg* _msg, char* _number, char* _arg) {
|
|
|
- int ret, check, arg;
|
|
|
-
|
|
|
- if (_number == NULL) {
|
|
|
- check = default_checks;
|
|
|
- }
|
|
|
- else {
|
|
|
- check = (int)(long)_number;
|
|
|
- }
|
|
|
- if (_arg == NULL) {
|
|
|
- arg = uri_checks;
|
|
|
- }
|
|
|
- else {
|
|
|
- arg = (int)(long)_arg;
|
|
|
- }
|
|
|
+/**
|
|
|
+ * perform SIP message sanity check
|
|
|
+ * @param _msg - SIP message structure
|
|
|
+ * @param msg_checks - bitmask of sanity tests to perform over message
|
|
|
+ * @param uri_checks - bitmask of sanity tests to perform over uri
|
|
|
+ * @return -1 on error, 0 on tests failure, 1 on success
|
|
|
+ */
|
|
|
+int sanity_check(struct sip_msg* _msg, int msg_checks, int uri_checks)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
|
|
|
- ret = 1;
|
|
|
- if (SANITY_RURI_SIP_VERSION & check &&
|
|
|
+ ret = SANITY_CHECK_PASSED;
|
|
|
+ if (SANITY_RURI_SIP_VERSION & msg_checks &&
|
|
|
(ret = check_ruri_sip_version(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_RURI_SCHEME & check &&
|
|
|
+ if (SANITY_RURI_SCHEME & msg_checks &&
|
|
|
(ret = check_ruri_scheme(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_REQUIRED_HEADERS & check &&
|
|
|
+ if (SANITY_REQUIRED_HEADERS & msg_checks &&
|
|
|
(ret = check_required_headers(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_VIA_SIP_VERSION & check &&
|
|
|
+ if (SANITY_VIA_SIP_VERSION & msg_checks &&
|
|
|
(ret = check_via_sip_version(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_VIA_PROTOCOL & check &&
|
|
|
+ if (SANITY_VIA_PROTOCOL & msg_checks &&
|
|
|
(ret = check_via_protocol(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_CSEQ_METHOD & check &&
|
|
|
+ if (SANITY_CSEQ_METHOD & msg_checks &&
|
|
|
(ret = check_cseq_method(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_CSEQ_VALUE & check &&
|
|
|
+ if (SANITY_CSEQ_VALUE & msg_checks &&
|
|
|
(ret = check_cseq_value(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_CL & check &&
|
|
|
+ if (SANITY_CL & msg_checks &&
|
|
|
(ret = check_cl(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_EXPIRES_VALUE & check &&
|
|
|
+ if (SANITY_EXPIRES_VALUE & msg_checks &&
|
|
|
(ret = check_expires_value(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_PROXY_REQUIRE & check &&
|
|
|
+ if (SANITY_PROXY_REQUIRE & msg_checks &&
|
|
|
(ret = check_proxy_require(_msg)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
- if (SANITY_PARSE_URIS & check &&
|
|
|
- (ret = check_parse_uris(_msg, arg)) != SANITY_CHECK_PASSED) {
|
|
|
+ if (SANITY_PARSE_URIS & msg_checks &&
|
|
|
+ (ret = check_parse_uris(_msg, uri_checks)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
- if (SANITY_CHECK_DIGEST & check &&
|
|
|
- (ret = check_digest(_msg, arg)) != SANITY_CHECK_PASSED) {
|
|
|
+ if (SANITY_CHECK_DIGEST & msg_checks &&
|
|
|
+ (ret = check_digest(_msg, uri_checks)) != SANITY_CHECK_PASSED) {
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
done:
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * do default checks
|
|
|
+ */
|
|
|
+int sanity_check_defaults(struct sip_msg* msg)
|
|
|
+{
|
|
|
+ return sanity_check(msg, default_msg_checks, default_uri_checks);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * wrapper for sanity_check() to be used from config file
|
|
|
+ */
|
|
|
+static int w_sanity_check(struct sip_msg* _msg, char* _number, char* _arg) {
|
|
|
+ int ret, check, arg;
|
|
|
+
|
|
|
+ if (_number == NULL) {
|
|
|
+ check = default_msg_checks;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ check = (int)(long)_number;
|
|
|
+ }
|
|
|
+ if (_arg == NULL) {
|
|
|
+ arg = default_uri_checks;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ arg = (int)(long)_arg;
|
|
|
+ }
|
|
|
+ ret = sanity_check(_msg, check, arg);
|
|
|
+
|
|
|
+ DBG("sanity checks result: %d\n", ret);
|
|
|
if(_sanity_drop!=0)
|
|
|
return ret;
|
|
|
return (ret==SANITY_CHECK_FAILED)?-1:ret;
|
|
|
+}
|
|
|
|
|
|
- DBG("all sanity checks passed\n");
|
|
|
- /* nobody complained so everything is fine */
|
|
|
- return 1;
|
|
|
+/**
|
|
|
+ * load sanity module API
|
|
|
+ */
|
|
|
+static int bind_sanity(sanity_api_t* api)
|
|
|
+{
|
|
|
+ if (!api) {
|
|
|
+ ERR("Invalid parameter value\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ api->check = sanity_check;
|
|
|
+ api->check_defaults = sanity_check_defaults;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|