/**
 * logeater_dispatch_log:
 * @list: List of regex.
 * @str: The log.
 * @from: Where does this log come from.
 *
 * This function is to be called by module reading log devices.
 * It will take appropriate action.
 */
void logeater_dispatch_log(logeater_log_source_t *ls, const char *str, size_t size)
{
        int ret;
        char *out;
        struct regex_data rdata;
        logeater_log_entry_t *log_entry;

        ret = logeater_log_source_preprocess_input(ls, str, size, &out, &size);
        if ( ret < 0 )
                return;

        requiem_log_debug(3, "[LOG] %s\n", out);

        log_entry = logeater_log_entry_new();
        if ( ! log_entry )
                return;

        logeater_log_entry_set_log(log_entry, ls, out, size);

        rdata.log_source = ls;
        rdata.log_entry = log_entry;

        regex_exec(logeater_log_source_get_regex_list(ls), &regex_match_cb, &rdata,
                   logeater_log_entry_get_message(log_entry), logeater_log_entry_get_message_len(log_entry));

        logeater_log_entry_destroy(log_entry);
        config.line_processed++;
}
Пример #2
0
int paircmp_pairs(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp)
#endif
{
	int ret = 0;

	/*
	 *      Check for =* and !* and return appropriately
	 */
	if (check->op == T_OP_CMP_TRUE)  return 0;
	if (check->op == T_OP_CMP_FALSE) return 1;

	if (!vp) {
		REDEBUG("Non-Unary operations require two operands");
		return -2;
	}

#ifdef HAVE_REGEX
	if ((check->op == T_OP_REG_EQ) || (check->op == T_OP_REG_NE)) {
		ssize_t		slen;
		regex_t		*preg = NULL;
		uint32_t	subcaptures;
		fr_regmatch_t	*regmatch;

		char *expr = NULL, *value = NULL;
		char const *expr_p, *value_p;

		if (check->vp_type == FR_TYPE_STRING) {
			expr_p = check->vp_strvalue;
		} else {
			expr_p = expr = fr_pair_value_asprint(check, check, '\0');
		}

		if (vp->vp_type == FR_TYPE_STRING) {
			value_p = vp->vp_strvalue;
		} else {
			value_p = value = fr_pair_value_asprint(vp, vp, '\0');
		}

		if (!expr_p || !value_p) {
			REDEBUG("Error stringifying operand for regular expression");

		regex_error:
			talloc_free(preg);
			talloc_free(expr);
			talloc_free(value);
			return -2;
		}

		/*
		 *	Include substring matches.
		 */
		slen = regex_compile(request, &preg, expr_p, talloc_array_length(expr_p) - 1,
				     false, false, true, true);
		if (slen <= 0) {
			REMARKER(expr_p, -slen, fr_strerror());

			goto regex_error;
		}

		subcaptures = regex_subcapture_count(preg);
		if (!subcaptures) subcaptures = REQUEST_MAX_REGEX + 1;	/* +1 for %{0} (whole match) capture group */
		MEM(regmatch = regex_match_data_alloc(NULL, subcaptures));

		/*
		 *	Evaluate the expression
		 */
		slen = regex_exec(preg, value_p, talloc_array_length(value_p) - 1, regmatch);
		if (slen < 0) {
			RPERROR("Invalid regex");

			goto regex_error;
		}

		if (check->op == T_OP_REG_EQ) {
			/*
			 *	Add in %{0}. %{1}, etc.
			 */
			regex_sub_to_request(request, &preg, &regmatch);
			ret = (slen == 1) ? 0 : -1;
		} else {
			ret = (slen != 1) ? 0 : -1;
		}

		talloc_free(regmatch);
		talloc_free(preg);
		talloc_free(expr);
		talloc_free(value);

		goto finish;
	}
#endif

	/*
	 *	Attributes must be of the same type.
	 *
	 *	FIXME: deal with type mismatch properly if one side contain
	 *	ABINARY, OCTETS or STRING by converting the other side to
	 *	a string
	 *
	 */
	if (vp->vp_type != check->vp_type) return -1;

	/*
	 *	Tagged attributes are equal if and only if both the
	 *	tag AND value match.
	 */
	if (check->da->flags.has_tag && !TAG_EQ(check->tag, vp->tag)) {
		ret = ((int) vp->tag) - ((int) check->tag);
		if (ret != 0) goto finish;
	}

	/*
	 *	Not a regular expression, compare the types.
	 */
	switch (check->vp_type) {
#ifdef WITH_ASCEND_BINARY
		/*
		 *	Ascend binary attributes can be treated
		 *	as opaque objects, I guess...
		 */
		case FR_TYPE_ABINARY:
#endif
		case FR_TYPE_OCTETS:
			if (vp->vp_length != check->vp_length) {
				ret = 1; /* NOT equal */
				break;
			}
			ret = memcmp(vp->vp_strvalue, check->vp_strvalue, vp->vp_length);
			break;

		case FR_TYPE_STRING:
			ret = strcmp(vp->vp_strvalue, check->vp_strvalue);
			break;

		case FR_TYPE_UINT8:
			ret = vp->vp_uint8 - check->vp_uint8;
			break;

		case FR_TYPE_UINT16:
			ret = vp->vp_uint16 - check->vp_uint16;
			break;

		case FR_TYPE_UINT32:
			ret = vp->vp_uint32 - check->vp_uint32;
			break;

		case FR_TYPE_UINT64:
			/*
			 *	Don't want integer overflow!
			 */
			if (vp->vp_uint64 < check->vp_uint64) {
				ret = -1;
			} else if (vp->vp_uint64 > check->vp_uint64) {
				ret = +1;
			} else {
				ret = 0;
			}
			break;

		case FR_TYPE_INT32:
			if (vp->vp_int32 < check->vp_int32) {
				ret = -1;
			} else if (vp->vp_int32 > check->vp_int32) {
				ret = +1;
			} else {
				ret = 0;
			}
			break;

		case FR_TYPE_DATE:
			ret = vp->vp_date - check->vp_date;
			break;

		case FR_TYPE_IPV4_ADDR:
			ret = ntohl(vp->vp_ipv4addr) - ntohl(check->vp_ipv4addr);
			break;

		case FR_TYPE_IPV6_ADDR:
			ret = memcmp(vp->vp_ip.addr.v6.s6_addr, check->vp_ip.addr.v6.s6_addr,
				     sizeof(vp->vp_ip.addr.v6.s6_addr));
			break;

		case FR_TYPE_IPV4_PREFIX:
		case FR_TYPE_IPV6_PREFIX:
			ret = memcmp(&vp->vp_ip, &check->vp_ip, sizeof(vp->vp_ip));
			break;

		case FR_TYPE_IFID:
			ret = memcmp(vp->vp_ifid, check->vp_ifid, sizeof(vp->vp_ifid));
			break;

		default:
			break;
	}

finish:
	if (ret > 0) return 1;
	if (ret < 0) return -1;
	return 0;
}
Пример #3
0
long long evaluate(TERM* term, EVALUATION_CONTEXT* context)
{
	size_t offs, hi_bound, lo_bound;
    long long op1;
    long long op2;
    long long index;
	unsigned int i;
	unsigned int needed;
	unsigned int satisfied;
	int ovector[3];
	int rc;
	
    STRING* string;
    STRING* saved_anonymous_string;
	
	TERM_CONST* term_const = ((TERM_CONST*) term);
	TERM_UNARY_OPERATION* term_unary = ((TERM_UNARY_OPERATION*) term);
	TERM_BINARY_OPERATION* term_binary = ((TERM_BINARY_OPERATION*) term);
	TERM_TERNARY_OPERATION* term_ternary = ((TERM_TERNARY_OPERATION*) term);
	TERM_STRING* term_string = ((TERM_STRING*) term);
	TERM_VARIABLE* term_variable = ((TERM_VARIABLE*) term);
	TERM_STRING_OPERATION* term_string_operation = ((TERM_STRING_OPERATION*) term);
	
    TERM_INTEGER_FOR* term_integer_for;
	
	MATCH* match;
    TERM* item;
    TERM_RANGE* range;
    TERM_ITERABLE* items;
	TERM_STRING* t;
	
	switch(term->type)
	{
	case TERM_TYPE_CONST:
		return term_const->value;
		
	case TERM_TYPE_FILESIZE:
		return context->file_size;
		
	case TERM_TYPE_ENTRYPOINT:
		return context->entry_point;
		
	case TERM_TYPE_RULE:
		return evaluate(term_binary->op1, context);
		
	case TERM_TYPE_STRING:
	
	    if (term_string->string == NULL) /* it's an anonymous string */
	    {
            string = context->current_string;
	    }
	    else
	    {
            string = term_string->string;
	    }
	    	
		return string->flags & STRING_FLAGS_FOUND;
		
	case TERM_TYPE_STRING_AT:
	
    	if (term_string->string == NULL) /* it's an anonymous string */
        {
            string = context->current_string;
        }
        else
        {
            string = term_string->string;
        }
	
		if (string->flags & STRING_FLAGS_FOUND)
		{	
			offs = evaluate(term_string->offset, context);
								
			match = string->matches_head;
			
			while (match != NULL)
			{
				if (match->offset == offs)
					return 1;
					
				match = match->next;
			}
			
			return 0;				
		}
		else return 0;
		
	case TERM_TYPE_STRING_IN_RANGE:
	
        if (term_string->string == NULL) /* it's an anonymous string */
        {
            string = context->current_string;
        }
        else
        {
            string = term_string->string;
        }
	
		if (string->flags & STRING_FLAGS_FOUND)
		{	
            range = (TERM_RANGE*) term_string->range;
		    
			lo_bound = evaluate(range->min, context);
			hi_bound = evaluate(range->max, context);
				
			match = string->matches_head;

			while (match != NULL)
			{
				if (match->offset >= lo_bound && match->offset <= hi_bound)
					return 1;

				match = match->next;
			}

			return 0;				
		}
		else return 0;
		
	case TERM_TYPE_STRING_IN_SECTION_BY_NAME:
		return 0; /*TODO: Implementar section by name*/
		
	case TERM_TYPE_STRING_COUNT:
	
		i = 0;
		
		if (term_string->string == NULL) /* it's an anonymous string */
        {
            string = context->current_string;
        }
        else
        {
            string = term_string->string;
        }
        
		match = string->matches_head;
		
		while (match != NULL)
		{
			i++;
			match = match->next;
		}
		
		return i;
		
	case TERM_TYPE_STRING_OFFSET:
	
        i = 1;
	    index = evaluate(term_string->index, context);
	
    	if (term_string->string == NULL) /* it's an anonymous string */
        {
            string = context->current_string;
        }
        else
        {
            string = term_string->string;
        }
	
        match = string->matches_head;
        
		while (match != NULL && i < index)
		{
			match = match->next;
            i++;
		}
		
		if (match != NULL && i == index)
		{
		    return match->offset; 
		}   

        return UNDEFINED;


	case TERM_TYPE_AND:
        
	    if (evaluate(term_binary->op1, context))
		    return evaluate(term_binary->op2, context);
	    else
		    return 0;
			
	case TERM_TYPE_OR:
	
		if (evaluate(term_binary->op1, context))
			return 1;
		else
			return evaluate(term_binary->op2, context);
			
	case TERM_TYPE_NOT:
		return !evaluate(term_unary->op, context);
		
	case TERM_TYPE_ADD:
	    ARITHMETIC_OPERATOR(+, term_binary, context);
		                      
	case TERM_TYPE_SUB:            
		ARITHMETIC_OPERATOR(-, term_binary, context);
		                      
	case TERM_TYPE_MUL:            
		ARITHMETIC_OPERATOR(*, term_binary, context);
		                      
	case TERM_TYPE_DIV:            
		ARITHMETIC_OPERATOR(/, term_binary, context);
		
	case TERM_TYPE_BITWISE_AND:
	    ARITHMETIC_OPERATOR(&, term_binary, context);
	    
	case TERM_TYPE_BITWISE_OR:
    	ARITHMETIC_OPERATOR(|, term_binary, context);
    	
	case TERM_TYPE_SHIFT_LEFT:
    	ARITHMETIC_OPERATOR(<<, term_binary, context);    	
	
	case TERM_TYPE_SHIFT_RIGHT:
    	ARITHMETIC_OPERATOR(>>, term_binary, context);
    
    case TERM_TYPE_BITWISE_NOT:
    
        op1 = evaluate(term_unary->op, context);
        if (IS_UNDEFINED(op1))
            return UNDEFINED;
        else
            return ~op1;
               
	case TERM_TYPE_GT:
        COMPARISON_OPERATOR(>, term_binary, context);
		                      
	case TERM_TYPE_LT:
	    COMPARISON_OPERATOR(<, term_binary, context);
		                      
	case TERM_TYPE_GE:             
		COMPARISON_OPERATOR(>=, term_binary, context);
		                      
	case TERM_TYPE_LE:             
		COMPARISON_OPERATOR(<=, term_binary, context);	
		                      
	case TERM_TYPE_EQ:    
		COMPARISON_OPERATOR(==, term_binary, context);
	
	case TERM_TYPE_NOT_EQ:             
		COMPARISON_OPERATOR(!=, term_binary, context);
		
	case TERM_TYPE_OF:
			
		t = (TERM_STRING*) term_binary->op2;
		needed = evaluate(term_binary->op1, context);
        satisfied = 0;
        i = 0;	
						
		while (t != NULL)
		{
			if (evaluate((TERM*) t, context)) 
			{
				satisfied++;
			}	
						
			t = t->next;
            i++;
		} 
		
		if (needed == 0)  /* needed == 0 means ALL*/
            needed = i;
        
        return (satisfied >= needed);
		
	case TERM_TYPE_STRING_FOR:

        t = (TERM_STRING*) term_ternary->op2;
		
		needed = evaluate(term_ternary->op1, context);		
        satisfied = 0;
        i = 0;

		while (t != NULL)
		{
            saved_anonymous_string = context->current_string;
            context->current_string = t->string;
            	    
			if (evaluate(term_ternary->op3, context)) 
			{
				satisfied++;
			}	
			
            context->current_string = saved_anonymous_string;
						
			t = t->next;	
            i++;
		} 
		
		if (needed == 0)  /* needed == 0 means ALL*/
            needed = i;
        
        return (satisfied >= needed);
	
	case TERM_TYPE_INTEGER_FOR:
		
        term_integer_for = (TERM_INTEGER_FOR*) term;
        items = term_integer_for->items;
        
        needed = evaluate(term_integer_for->count, context);
        satisfied = 0;
        i = 0;    
        
        item = items->first(items, evaluate, context);
        
        while (item != NULL)
        {                
            term_integer_for->variable->integer = evaluate(item, context);
                                           
            if (evaluate(term_integer_for->expression, context)) 
			{
				satisfied++;
			}
						
            item = items->next(items, evaluate, context);
            i++;	
        }
        
        if (needed == 0)  /* needed == 0 means ALL*/
            needed = i;
        
        return (satisfied >= needed);
    
    case TERM_TYPE_UINT8_AT_OFFSET:

        return read_uint8(context->mem_block, evaluate(term_unary->op, context));

    case TERM_TYPE_UINT16_AT_OFFSET:
        
        return read_uint16(context->mem_block, evaluate(term_unary->op, context));
        
    case TERM_TYPE_UINT32_AT_OFFSET:

        return read_uint32(context->mem_block, evaluate(term_unary->op, context));
        
    case TERM_TYPE_INT8_AT_OFFSET:

        return read_int8(context->mem_block, evaluate(term_unary->op, context));

    case TERM_TYPE_INT16_AT_OFFSET:

        return read_int16(context->mem_block, evaluate(term_unary->op, context));

    case TERM_TYPE_INT32_AT_OFFSET:

        return read_int32(context->mem_block, evaluate(term_unary->op, context));  
        
    case TERM_TYPE_VARIABLE:
    
        if (term_variable->variable->type == VARIABLE_TYPE_STRING)
        {
            return ( term_variable->variable->string != NULL && *term_variable->variable->string != '\0');
        }
        else
        {
            return term_variable->variable->integer;
        }
        
    case TERM_TYPE_STRING_MATCH:
        rc = regex_exec(&(term_string_operation->re),
                        FALSE,
                        term_string_operation->variable->string,
                        strlen(term_string_operation->variable->string));
        return (rc >= 0);

	case TERM_TYPE_STRING_CONTAINS:
		
		return (strstr(term_string_operation->variable->string, term_string_operation->string) != NULL);
     	
	default:
		return 0;
	}
}