Beispiel #1
0
/* Parsing for the rule option */
static int SIP_MethodInit(struct _SnortConfig *sc, char *name, char *params, void **data)
{

	int flags = 0, mask = 0;
	char *end = NULL;
	char *tok;
	int negated = 0;
	int numTokens = 0;
	SipMethodRuleOptData *sdata;
	SIPMethodNode *method;
	SIPConfig * sip_parsing_config;

	if (strcasecmp(name, SIP_ROPT__METHOD) != 0)
		return 0;


	/*Evaluate whether all the methods are in the PP configurations */
	sip_parsing_config = getParsingSIPConfig(sc);

	if (NULL == sip_parsing_config)
	    DynamicPreprocessorFatalMessage("%s(%d) => Configuration error!\n",
	            *(_dpd.config_file), *(_dpd.config_line));

	/* Must have arguments */
	if (SIP_IsEmptyStr(params))
	{
	    DynamicPreprocessorFatalMessage("%s(%d) => missing argument to sip_method keyword\n",
	                    *(_dpd.config_file), *(_dpd.config_line));
	}

	tok = strtok_r(params, ",", &end);

	if(!tok)
		DynamicPreprocessorFatalMessage("%s(%d) => missing argument to sip_method keyword\n",
				*(_dpd.config_file), *(_dpd.config_line));

	while (NULL != tok)
	{

	    numTokens++;

	    if (tok[0] == '!')
	    {
	        negated = 1;
	        tok++;
	    }

	    /*Only one method is allowed with !*/
	    if (negated && (numTokens > 1))
	    {
	        DynamicPreprocessorFatalMessage("%s(%d) => %s, only one method is allowed with ! for %s.\n",
	                *(_dpd.config_file), *(_dpd.config_line), tok, name);
	    }
		method = SIP_FindMethod (sip_parsing_config->methods, tok, strlen (tok));

		/*if method is not found, add it as a user defined method*/
		if (NULL == method)
		{
		    method = SIP_AddUserDefinedMethod(tok, &sip_parsing_config->methodsConfig, &sip_parsing_config->methods );
		    if (NULL == method)
		        DynamicPreprocessorFatalMessage("%s(%d) => %s can't add new method to %s.\n",
		                *(_dpd.config_file), *(_dpd.config_line), tok, name);
		    _dpd.logMsg("%s(%d) => Add user defined method: %s to SIP preprocessor through rule.\n",
		            *(_dpd.config_file), *(_dpd.config_line), method->methodName);
		}

		flags |= 1 << (method->methodFlag - 1);
		if (negated)
			mask |= 1 << (method->methodFlag - 1);

		tok = strtok_r(NULL, ", ", &end);

	}

	sdata = (SipMethodRuleOptData *)calloc(1, sizeof(*sdata));
	if (sdata == NULL)
	{
		DynamicPreprocessorFatalMessage("Could not allocate memory for the "
				"sip preprocessor rule option.\n");
	}

	sdata->flags = flags;
	sdata->mask = mask;
	*data = (void *)sdata;
	return 1;

}
Beispiel #2
0
static int sip_startline_parse(SIPMsg *msg, const char *buff, char *end, char **lineEnd)
{
	char *next;
	char *start;
	int length;
	int numOfLineBreaks;

	start = (char *) buff;

	numOfLineBreaks = sip_find_linebreak(start, end, &next);
	if (numOfLineBreaks < 1)
	{
		/*No CRLF */
		DEBUG_WRAP(DebugMessage(DEBUG_SIP, "No CRLF, check failed\n"));
		return SIP_FAILURE;
	}

	/*Exclude CRLF from start line*/
	length =  next - start - numOfLineBreaks;

	DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Start line: %.*s \n", length, start));
	DEBUG_WRAP(DebugMessage(DEBUG_SIP, "End of Start line \n"));

	/*Should at least have SIP/2.0 */
	if (length < SIP_MIN_MSG_LEN)
	{
		DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Message too short, check failed\n"));
			return SIP_FAILURE;
	}

	*lineEnd = next;
	// This is a response
	if (0 == strncmp((const char *) buff, (const char *) SIP_KEYWORD, SIP_KEYWORD_LEN))
	{
		char *space;
		unsigned long statusCode;

		/*Process response*/
		msg->method = NULL;
		msg->uri = NULL;

        /*Check SIP version number, end with SP*/
        if (!(sip_is_valid_version(buff + SIP_KEYWORD_LEN) && (*(buff + SIP_VERSION_LEN) == ' ')))
        {
            ALERT(SIP_EVENT_INVALID_VERSION,SIP_EVENT_INVALID_VERSION_STR);
        }

		space = strchr(buff, ' ');
		if (space == NULL)
			return SIP_FAILURE;
		statusCode = _dpd.SnortStrtoul(space + 1, NULL, 10);
		if (( statusCode > MAX_STAT_CODE) || (statusCode < MIN_STAT_CODE ))
		{
			ALERT(SIP_EVENT_BAD_STATUS_CODE,SIP_EVENT_BAD_STATUS_CODE_STR)
    		msg->status_code =  MAX_STAT_CODE + 1;
		}
        else
		    msg->status_code =  (uint16_t)statusCode;
		DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Status code: %d \n", msg->status_code));

	}
	else  /* This might be a request*/
	{
		char *space;
		char *version;
		int length;
		SIPMethodNode *method;

		/*Process request*/
		if (NULL ==sip_eval_config)
			return SIP_FAILURE;
		msg->status_code = 0;

        // Parse the method
		space = memchr(buff, ' ', end - buff);
		if (space == NULL)
			return SIP_FAILURE;
		length = space - buff;
		msg->method = (char*)buff;
		msg->methodLen = length;
		DEBUG_WRAP(DebugMessage(DEBUG_SIP, "method: %.*s\n", msg->methodLen, msg->method));

		method = SIP_FindMethod (sip_eval_config->methods, msg->method, msg->methodLen);
		if (method)
		{
		    msg->methodFlag = method->methodFlag;
		    DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Found the method: %s, Flag: 0x%x\n", method->methodName, method->methodFlag));
		}

		// parse the uri
		if (space + 1 > end)
			return SIP_FAILURE;
		msg->uri = space + 1;
		space = memchr(space + 1, ' ', end - msg->uri);
		if (space == NULL)
			return SIP_FAILURE;
		msg->uriLen = space - msg->uri;
		DEBUG_WRAP(DebugMessage(DEBUG_SIP, "uri: %.*s, length: %u\n", msg->uriLen, msg->uri, msg->uriLen));
		if(0 == msg->uriLen)
			ALERT(SIP_EVENT_EMPTY_REQUEST_URI,SIP_EVENT_EMPTY_REQUEST_URI_STR)
		else if (sip_eval_config->maxUriLen && (msg->uriLen > sip_eval_config->maxUriLen))
			ALERT(SIP_EVENT_BAD_URI,SIP_EVENT_BAD_URI_STR);

		version = space + 1;
		if (version + SIP_VERSION_LEN > end)
		    return SIP_FAILURE;
		if (0 != strncmp((const char *) version, (const char *) SIP_KEYWORD, SIP_KEYWORD_LEN))
		    return SIP_FAILURE;
		/*Check SIP version number, end with CRLF*/
		if (!sip_is_valid_version(*lineEnd - SIP_VERSION_NUM_LEN - numOfLineBreaks))
		{
		    ALERT(SIP_EVENT_INVALID_VERSION,SIP_EVENT_INVALID_VERSION_STR);
		}

        if (NULL == method)
        {
            ALERT(SIP_EVENT_UNKOWN_METHOD, SIP_EVENT_UNKOWN_METHOD_STR);
            return SIP_FAILURE;
        }
	}

	return SIP_SUCCESS;
}