/**
 * Handle managed collection registration for vars "name=value" parameters
 *
 * @param[in] ib Engine
 * @param[in] module Collection manager's module object (unused)
 * @param[in] manager The collection manager object to register with (unused)
 * @param[in] mp Memory pool to use for allocations
 * @param[in] collection_name Name of the collection
 * @param[in] uri Full collection URI (unused)
 * @param[in] uri_scheme URI scheme (unused)
 * @param[in] uri_data Hierarchical/data part of the URI
 * @param[in] params List of parameter strings
 * @param[in] register_data Register callback data (unused)
 * @param[out] pmanager_inst_data Pointer to manager specific collection data
 *
 * @returns Status code:
 *   - IB_OK All OK
 *   - IB_Exxx Other error
 */
static ib_status_t core_managed_collection_vars_register_fn(
    const ib_engine_t             *ib,
    const ib_module_t             *module,
    const ib_collection_manager_t *manager,
    ib_mpool_t                    *mp,
    const char                    *collection_name,
    const char                    *uri,
    const char                    *uri_scheme,
    const char                    *uri_data,
    const ib_list_t               *params,
    void                          *register_data,
    void                         **pmanager_inst_data)
{
    assert(ib != NULL);
    assert(module != NULL);
    assert(mp != NULL);
    assert(collection_name != NULL);
    assert(params != NULL);
    assert(pmanager_inst_data != NULL);

    const ib_list_node_t *node;
    ib_list_t *vars_list;
    ib_list_t *field_list;
    ib_mpool_t *tmp = ib_engine_pool_temp_get(ib);
    ib_status_t rc;

    if (strlen(uri_data) != 0) {
        return IB_DECLINED;
    }
    if (ib_list_elements(params) < 1) {
        return IB_EINVAL;
    }

    /* Create a temporary list */
    rc = ib_list_create(&vars_list, tmp);
    if (rc != IB_OK) {
        return rc;
    }

    /* First pass; walk through all params, look for "a=b" type syntax */
    IB_LIST_LOOP_CONST(params, node) {
        static const int ovecsize = 9;
        int ovector[ovecsize];
        const char *param = (const char *)node->data;
        core_vars_t *vars;
        int pcre_rc;

        pcre_rc = pcre_exec(core_vars_manager.pattern, NULL,
                            param, strlen(param),
                            0, 0, ovector, ovecsize);
        if (pcre_rc < 0) {
            return IB_DECLINED;
        }

        vars = ib_mpool_alloc(tmp, sizeof(*vars));
        if (vars == NULL) {
            return IB_EALLOC;
        }
        vars->name  = ib_mpool_memdup_to_str(tmp,
                                             param + ovector[2],
                                             ovector[3] - ovector[2]);
        vars->value = ib_mpool_memdup_to_str(tmp,
                                             param + ovector[4],
                                             ovector[5] - ovector[4]);
        if ( (vars->name == NULL) || (vars->value == NULL) ) {
            return IB_EALLOC;
        }
        rc = ib_list_push(vars_list, vars);
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* Build the list of fields */
    rc = ib_list_create(&field_list, mp);
    if (rc != IB_OK) {
        return rc;
    }

    /* Now walk though the list, creating a field for each one */
    IB_LIST_LOOP_CONST(vars_list, node) {
        const core_vars_t *vars = (const core_vars_t *)node->data;
        ib_field_t *field;
        ib_field_val_union_t fval;

        rc = ib_field_from_string(mp,
                                  IB_FIELD_NAME(vars->name), vars->value,
                                  &field, &fval);
        if (rc != IB_OK) {
            ib_log_error(ib, "Error creating field (\"%s\", \"%s\"): %s",
                         vars->name, vars->value,
                         ib_status_to_string(rc));
            return rc;
        }
        rc = ib_list_push(field_list, field);
        if (rc != IB_OK) {
            return rc;
        }

        if (field->type == IB_FTYPE_NUM) {
            ib_log_trace(ib, "Created numeric field \"%s\" %"PRId64" in \"%s\"",
                         vars->name, fval.num, collection_name);
        }

        else if (field->type == IB_FTYPE_FLOAT) {
            ib_log_trace(ib, "Created float field \"%s\" %f in \"%s\"",
                         vars->name, (double)fval.fnum, collection_name);
        }
        else {
            ib_log_trace(ib, "Created string field \"%s\" \"%s\" in \"%s\"",
                         vars->name, fval.nulstr, collection_name);
        }
    }

    /* Finally, store the list as the manager specific collection data */
    *pmanager_inst_data = field_list;

    return IB_OK;
}
Exemplo n.º 2
0
static void *mne_search(void *_ctx) {
  int rc, i, num_results, n, matches[MAX_CAPTURES], offset;
  mne_search_ctx *ctx = (mne_search_ctx *)_ctx;
  mne_search_result *results = search_results[ctx->initial];

  while (1) {
    pthread_mutex_lock(&search_mutex);
    pthread_cond_wait(&search_cond, &search_mutex);
    pthread_mutex_unlock(&search_mutex);

    if (exiting)
      break;

    num_results = 0;

    for (n = ctx->initial; n < ctx->num_blobs; n += num_cores) {
      offset = 0;

      while (1) {
        rc = pcre_exec(re, re_extra, blob_index[n], blob_sizes[n], offset, 0, matches, MAX_CAPTURES);

        if (unlikely(rc == 0)) {
          mne_printf_async("Too many captured substrings in blob %s (> %d).\n", sha1_index[n], MAX_CAPTURES);
          continue;          
        }

        if (rc > 0) {
          for (i = 0; i < rc; ++i) {
            // TODO: These are captured substrings, they should all be part of the same result.
            results[num_results].fresh = 1;
            results[num_results].sha1_offset = n;
            results[num_results].offset = matches[2*i];
            results[num_results].length = matches[2*i+1] - matches[2*i];

            if (unlikely(num_results == MAX_SEARCH_RESULTS_PER_THREAD))
              break;

            offset = matches[2*i] + (matches[2*i+1] - matches[2*i]);
            num_results++;        
          }    
        } else {
          break;
        }

        if (unlikely(num_results == MAX_SEARCH_RESULTS_PER_THREAD))
          break;
      }

      if (unlikely(num_results == MAX_SEARCH_RESULTS_PER_THREAD)) {
        break;
      }
    }

    /* Mark the next result as unfresh so the main threads knows how many results we found. */
    if (num_results < MAX_SEARCH_RESULTS_PER_THREAD)
      results[num_results].fresh = 0;
    
    pthread_mutex_lock(&done_incr_mutex);
    threads_complete++;
    if (threads_complete == num_cores)
      pthread_mutex_unlock(&all_done_mutex);
    pthread_mutex_unlock(&done_incr_mutex);
  }

  pthread_exit(NULL);
}
Exemplo n.º 3
0
static struct sol_vector
string_regexp_search_and_split(struct string_regexp_search_data *mdata)
{
    int r;
    size_t str_len, match_sz;
    pcre *compiled_re = NULL;
    pcre_extra *p_extra = NULL;
    int *match_vector, sub_match_count = 0;
    struct sol_vector v = SOL_VECTOR_INIT(struct sol_str_slice);

#define CREATE_SLICE(_str, _len) \
    do { \
        struct sol_str_slice *s; \
        s = sol_vector_append(&v); \
        if (!s) \
            goto err; \
        s->data = (const char *)_str; \
        s->len = _len; \
    } while (0)

    //mdata->string should never be NULL
    str_len = strlen(mdata->string);
    if (!str_len)
        return v;

    r = pcre_compile_do(mdata->node, mdata->regexp, &compiled_re,
        &p_extra, &sub_match_count);
    SOL_INT_CHECK(r, < 0, v);

    match_sz = (sub_match_count + 1) * 3;
    match_vector = calloc(match_sz, sizeof(*match_vector));

    r = pcre_exec(compiled_re, p_extra, mdata->string, str_len,
        0, 0, match_vector, match_sz);

    if (r < 0) {
        sol_flow_send_error_packet(mdata->node, EINVAL,
            "Fail on matching regular expression '%s' on string %s",
            mdata->regexp, mdata->string);
        goto err;
    } else {
        int i;

        /* The value returned by pcre_exec() is one more than the
         * highest numbered pair that has been set. If the vector is
         * too small to hold all the captured substring offsets, it is
         * used as far as possible (up to two-thirds of its length),
         * and the function returns a value of zero.
         */
        if (r == 0) { // should not happen, but let's treat the case
            sol_flow_send_error_packet(mdata->node, EINVAL,
                "A memory overflow happened while executing"
                " regular expression '%s' on string %s",
                mdata->regexp, mdata->string);
            goto err;
        }
        for (i = 0; i < r; i++) {
            CREATE_SLICE(mdata->string + match_vector[i * 2],
                match_vector[i * 2 + 1] - match_vector[i * 2]);
        }
    }

err:
    if (p_extra != NULL)
        pcre_free(p_extra);
    pcre_free(compiled_re);
    free(match_vector);

    return v;
#undef CREATE_SLICE
}
Exemplo n.º 4
0
void handle_packet(const u_char *packet)
{
	int i;
	uint16_t pkt_size, payload_size;

	struct iphdr *ip;				/* The IP header */
	struct tcphdr *tcp;				/* The TCP header */
	char *payload;					/* Packet payload */

	int vector_size = 18;
	int substrvec[vector_size];
	const char *submatchstr;

	ip = (struct iphdr*)(packet + SIZE_ETHERNET);

	if (ip->protocol != IPPROTO_TCP)
	{
		/* We are only interested in TCP traffic */

		if (debug_mode >= 3)
		{
			fprintf(stderr, "-- Skipping non TCP packet\n");
		}

		return;
	}

	if ((ip->ihl * 4) < 20)
	{
		if (debug_mode >= 3)
		{
			fprintf(stderr, "-- Skipping Invalid IP header\n");
		}

		return;
	}

	tcp = (struct tcphdr*)(packet + SIZE_ETHERNET + (ip->ihl * 4));

	if ((tcp->doff * 4) < 20)
	{
		if (debug_mode >= 3)
		{
			fprintf(stderr, "-- Skipping Invalid TCP header\n");
		}

		return;
	}

	if (debug_mode >= 4)
	{
		print_ip_hdr(ip);
		print_tcp_hdr(tcp);
	}

	pkt_size = ntohs(ip->tot_len);
	payload_size = pkt_size - ((ip->ihl * 4) + (tcp->doff * 4));
	payload = (char *)(packet + SIZE_ETHERNET + (ip->ihl * 4) + (tcp->doff * 4));

	if (ntohl(tcp->ack_seq) == prev_package.ack_nr &&
			ip->saddr == prev_package.s_ip && ip->daddr == prev_package.d_ip)
	{
		if ((prev_package.payload_size + payload_size) > (1500 * PKT_HISTORY_SIZE) + 1)
		{
			if (debug_mode >= 3)
			{
				fprintf(stderr, "-- Dropping packet due to full packet buffer\n");
			}

			return;
		}

		prev_package.payload_size += payload_size;
		strncat(prev_package.payload, payload, payload_size);

		payload = prev_package.payload;
		payload_size = prev_package.payload_size;
	}
	else
	{
		if (prev_package.payload_size > 0)
		{
			memset(&prev_package, 0x00, sizeof(struct pPackageT));
		}

		prev_package.ack_nr = ntohl(tcp->ack_seq);
		prev_package.s_ip = ip->saddr;
		prev_package.d_ip = ip->daddr;

		prev_package.payload_size += payload_size;
		strncat(prev_package.payload, payload, payload_size);

//		if (pkt_size >= 1500)
//		{
//			if (debug_mode >= 3)
//			{
//				fprintf(stderr, "-- Skipping due to 1500bytes\n");
//			}
//
//			return;
//		}
	}

	if (debug_mode >= 5)
	{
	    fprintf(stderr, "Payload (%u): \n", payload_size);

	    for (i = 0; i < payload_size; i++)
	    {
	    	if (isprint(payload[i]) || payload[i] == 10)
	    	{
	    		fprintf(stderr, "%c", payload[i]);
	    	}
	    	else
	    	{
	    		fprintf(stderr, ".");
	    	}
	    }

	    fprintf(stderr, "\n--\n");
	}

	int pcre_match = pcre_exec(re, ree, payload, payload_size, 0, 0, substrvec, vector_size);

	if (debug_mode)
	{
		fprintf(stderr, ">> pcre: %d\n", pcre_match);
	}

	if(pcre_match < 0)
	{
//		switch (pcre_match)
//		{
//			case PCRE_ERROR_NOMATCH:
//			case PCRE_ERROR_NULL:
//			case PCRE_ERROR_BADOPTION:
//			case PCRE_ERROR_BADMAGIC:
//			case PCRE_ERROR_UNKNOWN_NODE:
//			case PCRE_ERROR_NOMEMORY:
//				return;
//				break;
//		}
		return;
	}

	if (pcre_match == 0)
	{
		if (debug_mode >= 3)
		{
			fprintf(stderr, "PCRE Matched but too many substrings returned\n");
		}

		pcre_match = (vector_size / 3);
	}

	if (pcre_match >= 2)
	{
		pcre_get_substring(payload, substrvec, pcre_match, 1, &(submatchstr));
		char *clean_str = clean_xml(submatchstr);

		fprintf(stdout, "%s\n", clean_str);

		// Free up the stuff
		free (clean_str);

		pcre_free_substring(submatchstr);
		memset(&prev_package, 0x00, sizeof(struct pPackageT));
	}
}
Exemplo n.º 5
0
Arquivo: node.c Projeto: czchen/r3
/**
 * This function matches the URL path and return the left node
 *
 * r3_tree_matchl returns NULL when the path does not match. returns *node when the path matches.
 *
 * @param node         n        the root of the tree
 * @param char*        path     the URL path to dispatch
 * @param int          path_len the length of the URL path.
 * @param match_entry* entry match_entry is used for saving the captured dynamic strings from pcre result.
 */
node * r3_tree_matchl(const node * n, char * path, int path_len, match_entry * entry) {
    info("try matching: %s\n", path);

    edge *e;
    int rc;
    int i;

    // if the pcre_pattern is found, and the pointer is not NULL, then it's
    // pcre pattern node, we use pcre_exec to match the nodes
    if (n->pcre_pattern) {
        info("pcre matching %s on %s\n", n->combined_pattern, path);

        rc = pcre_exec(
                n->pcre_pattern,   /* the compiled pattern */

                // PCRE Study makes this slow
                NULL, // n->pcre_extra,     /* no extra data - we didn't study the pattern */
                path,              /* the subject string */
                path_len,          /* the length of the subject */
                0,                 /* start at offset 0 in the subject */
                0,                 /* default options */
                n->ov,           /* output vector for substring information */
                n->ov_cnt);      /* number of elements in the output vector */

        // info("rc: %d\n", rc );
        if (rc < 0) {
            switch(rc)
            {
                case PCRE_ERROR_NOMATCH: printf("pcre: no match\n"); break;
                /*
                Handle other special cases if you like
                */
                default: printf("pcre matching error '%d' on pattern '%s'\n", rc, n->combined_pattern); break;
            }
            // does not match all edges, return NULL;
            return NULL;
        }


        for (i = 1; i < rc; i++)
        {
            char *substring_start = path + n->ov[2*i];
            int   substring_length = n->ov[2*i+1] - n->ov[2*i];
            // info("%2d: %.*s\n", i, substring_length, substring_start);

            if ( substring_length > 0) {
                int restlen = path_len - n->ov[1]; // fully match to the end
                // info("matched item => restlen:%d edges:%d i:%d\n", restlen, n->edge_len, i);

                e = n->edges[i - 1];

                if (entry && e->has_slug) {
                    // append captured token to entry
                    str_array_append(entry->vars , zstrndup(substring_start, substring_length));
                }
                if (restlen == 0 ) {
                    return e->child && e->child->endpoint > 0 ? e->child : NULL;
                }
                // get the length of orginal string: $0
                return r3_tree_matchl( e->child, path + (n->ov[1] - n->ov[0]), restlen, entry);
            }
        }
        // does not match
        return NULL;
    }

    if ( (e = r3_node_find_edge_str(n, path, path_len)) != NULL ) {
        int restlen = path_len - e->pattern_len;
        if (restlen == 0) {
            return e->child && e->child->endpoint > 0 ? e->child : NULL;
        }
        return r3_tree_matchl(e->child, path + e->pattern_len, restlen, entry);
    }
    return NULL;
}
Exemplo n.º 6
0
static DetectBytetestData *DetectBytetestParse(const char *optstr, char **value, char **offset)
{
    DetectBytetestData *data = NULL;
    char *args[9] = {
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        NULL
    };
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];
    int i;
    uint32_t nbytes;
    const char *str_ptr = NULL;

    /* Execute the regex and populate args with captures. */
    ret = pcre_exec(parse_regex, parse_regex_study, optstr,
                    strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS);
    if (ret < 6 || ret > 10) {
        SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32
               ", string %s", ret, optstr);
        goto error;
    }
    for (i = 0; i < (ret - 1); i++) {
        res = pcre_get_substring((char *)optstr, ov, MAX_SUBSTRINGS,
                                 i + 1, &str_ptr);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed "
                   "for arg %d", i + 1);
            goto error;
        }
        args[i] = (char *)str_ptr;
    }

    /* Initialize the data */
    data = SCMalloc(sizeof(DetectBytetestData));
    if (unlikely(data == NULL))
        goto error;
    data->base = DETECT_BYTETEST_BASE_UNSET;
    data->flags = 0;


    /*
     * The first four options are required and positional.  The
     * remaining arguments are flags and are not positional.
     */

    /* Number of bytes */
    if (ByteExtractStringUint32(&nbytes, 10, 0, args[0]) <= 0) {
        SCLogError(SC_ERR_INVALID_VALUE, "Malformed number of bytes: %s", str_ptr);
        goto error;
    }

    /* Operator is next two args: neg + op */
    data->op = 0;
    if (args[1] != NULL && *args[1] == '!') {
        data->flags |= DETECT_BYTETEST_NEGOP;
    }

    if (args[2] != NULL) {
        if ((strcmp("=", args[2]) == 0) || ((data->flags & DETECT_BYTETEST_NEGOP)
                && strcmp("", args[2]) == 0)) {
            data->op |= DETECT_BYTETEST_OP_EQ;
        } else if (strcmp("<", args[2]) == 0) {
            data->op |= DETECT_BYTETEST_OP_LT;
        } else if (strcmp(">", args[2]) == 0) {
            data->op |= DETECT_BYTETEST_OP_GT;
        } else if (strcmp("&", args[2]) == 0) {
            data->op |= DETECT_BYTETEST_OP_AND;
        } else if (strcmp("^", args[2]) == 0) {
            data->op |= DETECT_BYTETEST_OP_OR;
        } else if (strcmp(">=", args[2]) == 0) {
            data->op |= DETECT_BYTETEST_OP_GE;
        } else if (strcmp("<=", args[2]) == 0) {
            data->op |= DETECT_BYTETEST_OP_LE;
        } else {
            SCLogError(SC_ERR_INVALID_OPERATOR, "Invalid operator");
            goto error;
        }
    }

    /* Value */
    if (args[3][0] != '-' && isalpha((unsigned char)args[3][0])) {
        if (value == NULL) {
            SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
                       "var name for value.  \"value\" argument supplied to "
                       "this function has to be non-NULL");
            goto error;
        }
        *value = SCStrdup(args[3]);
        if (*value == NULL)
            goto error;
    } else {
        if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) {
            SCLogError(SC_ERR_INVALID_VALUE, "Malformed value: %s", str_ptr);
            goto error;
        }
    }

    /* Offset */
    if (args[4][0] != '-' && isalpha((unsigned char)args[4][0])) {
        if (offset == NULL) {
            SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
                       "var name for offset.  \"offset\" argument supplied to "
                       "this function has to be non-NULL");
            goto error;
        }
        *offset = SCStrdup(args[4]);
        if (*offset == NULL)
            goto error;
    } else {
        if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) {
            SCLogError(SC_ERR_INVALID_VALUE, " Malformed offset: %s", str_ptr);
            goto error;
        }
    }

    /* The remaining options are flags. */
    /** \todo Error on dups? */
    for (i = 5; i < (ret - 1); i++) {
        if (args[i] != NULL) {
            if (strcmp("relative", args[i]) == 0) {
                data->flags |= DETECT_BYTETEST_RELATIVE;
            } else if (strcasecmp("string", args[i]) == 0) {
                data->flags |= DETECT_BYTETEST_STRING;
            } else if (strcasecmp("dec", args[i]) == 0) {
                data->base |= DETECT_BYTETEST_BASE_DEC;
            } else if (strcasecmp("hex", args[i]) == 0) {
                data->base |= DETECT_BYTETEST_BASE_HEX;
            } else if (strcasecmp("oct", args[i]) == 0) {
                data->base |= DETECT_BYTETEST_BASE_OCT;
            } else if (strcasecmp("big", args[i]) == 0) {
                if (data->flags & DETECT_BYTETEST_LITTLE) {
                    data->flags ^= DETECT_BYTETEST_LITTLE;
                }
                data->flags |= DETECT_BYTETEST_BIG;
            } else if (strcasecmp("little", args[i]) == 0) {
                data->flags |= DETECT_BYTETEST_LITTLE;
            } else if (strcasecmp("dce", args[i]) == 0) {
                data->flags |= DETECT_BYTETEST_DCE;
            } else {
                SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"",
                        args[i]);
                goto error;
            }
        }
    }

    if (data->flags & DETECT_BYTETEST_STRING) {
        /* 23 - This is the largest string (octal, with a zero prefix) that
         *      will not overflow uint64_t.  The only way this length
         *      could be over 23 and still not overflow is if it were zero
         *      prefixed and we only support 1 byte of zero prefix for octal.
         *
         * "01777777777777777777777" = 0xffffffffffffffff
         */
        if (nbytes > 23) {
            SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 23 bytes with \"string\": %s",
                        optstr);
            goto error;
        }
    } else {
        if (nbytes > 8) {
            SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 8 bytes without \"string\": %s",
                        optstr);
            goto error;
        }
        if (data->base != DETECT_BYTETEST_BASE_UNSET) {
            SCLogError(SC_ERR_INVALID_VALUE, "Cannot use a base without \"string\": %s", optstr);
            goto error;
        }
    }

    /* This is max 23 so it will fit in a byte (see above) */
    data->nbytes = (uint8_t)nbytes;

    for (i = 0; i < (ret - 1); i++){
        if (args[i] != NULL) SCFree(args[i]);
    }
    return data;

error:
    for (i = 0; i < (ret - 1); i++){
        if (args[i] != NULL) SCFree(args[i]);
    }
    if (data != NULL) DetectBytetestFree(data);
    return NULL;
}
Exemplo n.º 7
0
qbool CL_SearchForReTriggers (const char *s, unsigned trigger_type)
{
	pcre_trigger_t *rt;
	pcre_internal_trigger_t *irt;
	cmd_alias_t *trig_alias;
	qbool removestr = false;
	int result;
	int offsets[99];
	int len = strlen(s);
 
	// internal triggers - always enabled
	if (trigger_type < RE_PRINT_ECHO) {
		allow_re_triggers = true;
		for (irt = internal_triggers; irt; irt = irt->next) {
			if (irt->flags & trigger_type) {
				result = pcre_exec (irt->regexp, irt->regexp_extra, s, len, 0, 0, offsets, 99);
				if (result >= 0) {
					Re_Trigger_Copy_Subpatterns (s, offsets, min(result,10), re_subi);
					irt->func (s);
				}
			}
		}
		if (!allow_re_triggers)
			return false;
	}
 
	// message triggers disabled
	if (!tp_msgtriggers.value)
		return false;
 
	// triggers banned by ruleset or FPD and we are a player
	if (((cl.fpd & FPD_NO_SOUNDTRIGGERS) || (cl.fpd & FPD_NO_TIMERS) ||
	        Rulesets_RestrictTriggers ()) && !cls.demoplayback && !cl.spectator)
		return false;
 
	// we are in spec/demo mode, so play triggers if user want it
	if ((cls.demoplayback || cl.spectator) && cl_restrictions.value)
		return false;
 
	// regexp triggers
	for (rt = re_triggers; rt; rt = rt->next)
		if ( (rt->flags & RE_ENABLED) &&	// enabled
		        (rt->flags & trigger_type) &&	// mask fits
		        rt->regexp &&					// regexp not empty
		        (rt->min_interval == 0.0 ||
		         cls.realtime >= rt->min_interval + rt->lasttime)) // not too fast.
			// TODO: disable it ^^^ for FPD_NO_TIMERS case.
			// probably it dont solve re_trigger timers problem
			// you always trigger on statusbar(TF) or wp_stats (KTPro/KTX) messages and get 0.5~1.5 accuracy for your timer
		{
			result = pcre_exec (rt->regexp, rt->regexp_extra, s, len, 0, 0, offsets, 99);
			if (result >= 0) {
				rt->lasttime = cls.realtime;
				rt->counter++;
				Re_Trigger_Copy_Subpatterns (s, offsets, min(result,10), re_sub);
 
				if (!(rt->flags & RE_NOACTION)) {
					trig_alias = Cmd_FindAlias (rt->name);
					Print_current++;
					if (trig_alias) {
						Cbuf_InsertTextEx (&cbuf_safe, "\nwait\n");
						Cbuf_InsertTextEx (&cbuf_safe, rt->name);
						Cbuf_ExecuteEx (&cbuf_safe);
					} else
						Com_Printf ("re_trigger \"%s\" has no matching alias\n", rt->name);
					Print_current--;
				}
 
				if (rt->flags & RE_REMOVESTR)
					removestr = true;
				if (rt->flags & RE_NOLOG)
					Print_flags[Print_current] |= PR_LOG_SKIP;
				if (rt->flags & RE_FINAL)
					break;
			}
		}
 
	if (removestr)
		Print_flags[Print_current] |= PR_SKIP;
 
	return removestr;
}
static ngx_int_t 
ngx_tcp_cmd_parse_ini_conf(ngx_cycle_t *cycle)
{
    ngx_str_t            cmdso_path = CMDSO_PATH_STR;
    ngx_str_t            cmdso_file = CMDSO_INI_FILE_STR;
    char                *path_file;
    FILE                *p_file;
    int                  lines;
    char                 line_buf[CMDSO_INI_FILE_LINE_MAXLEN];
#define PCRE_OVECTOR_SIZE 16
    int                  ovector[PCRE_OVECTOR_SIZE];
    ngx_regex_compile_t  re_section;
    ngx_regex_compile_t  re_line;
    int                  rc;
    ngx_str_t            ini_section = ngx_null_string;
    ngx_map_t           *section_map;

    cmdso_conf = ngx_map_create(NGX_MAP_STR_T, NGX_MAP_PTR_T, 
        cycle->pool, (ngx_palloc_pt)ngx_palloc, (ngx_pfree_pt)ngx_pfree);
    if (cmdso_conf == NULL) {
        ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
            "ngx_tcp_cmd_parse_ini_conf|cmdso_conf == NULL\n");
        return NGX_ERROR;
    }

    /* the cmdso_path->data will end with '\0' */
    ngx_conf_full_name(cycle, &cmdso_path, 0);
    path_file = ngx_tcp_cmd_concat_filename((const char *)cmdso_path.data, 
        (const char *)cmdso_file.data);
    p_file = fopen(path_file, "r");
    free(path_file);
    if (p_file == NULL) {
        ngx_log_error(NGX_LOG_WARN, cycle->log, 0, 
            "ngx_tcp_cmd_parse_ini_conf|%V has'n %V\n", &cmdso_path, &cmdso_file);
        ngx_map_destroy(cmdso_conf);
        cmdso_conf = NULL;
        return NGX_OK;
    }

    ngx_memset(&re_section, 0, sizeof(ngx_regex_compile_t));
    re_section.pool = cycle->pool;
    re_section.pattern.data = (u_char *)CMDSO_INI_SECTION_PATTERN;
    re_section.pattern.len = sizeof(CMDSO_INI_SECTION_PATTERN) - 1;
    if (ngx_regex_compile(&re_section) != NGX_OK) {
        ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
            "ngx_tcp_cmd_parse_ini_conf|pattern = %s|pcre_err is %V.\n", 
            CMDSO_INI_SECTION_PATTERN, &re_section.err);
        goto failed;
    }
    ngx_memset(&re_line, 0, sizeof(ngx_regex_compile_t));
    re_line.pool = cycle->pool;
    re_line.pattern.data = (u_char *)CMDSO_INI_LINE_PATTERN;
    re_line.pattern.len = sizeof(CMDSO_INI_LINE_PATTERN) - 1;
    if (ngx_regex_compile(&re_line) != NGX_OK) {
        ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
            "ngx_tcp_cmd_parse_ini_conf|pattern = %s|pcre_err is %V.\n", 
            CMDSO_INI_LINE_PATTERN, &re_line.err);
        goto failed;
    }

    lines = 0;
    while (fgets(line_buf, CMDSO_INI_FILE_LINE_MAXLEN, p_file) != NULL
        && !feof(p_file)) {
        int str_len;
        int i = 0;
        ++lines;
        while(line_buf[i] 
            && (line_buf[i] == ' ' || line_buf[i] == '\t' 
                || line_buf[i] == '\n')) {
            ++i;
        }
        if (!line_buf[i] || line_buf[i] == '#')
            continue;
        rc = pcre_exec(re_section.regex->code, NULL, line_buf, ngx_strlen(line_buf), 
                       0, 0, ovector, PCRE_OVECTOR_SIZE);
        if (rc < 0) {
            goto __pcre_exec_after_ini_section__;
        }
        if (ini_section.data != NULL ) {
            free(ini_section.data);
            ini_section.data = NULL;
        }
        str_len = ovector[3] - ovector[2];
        ini_section.data = (u_char *)strndup(&line_buf[0] + ovector[2], str_len);
        ini_section.len = str_len;
        section_map = ngx_map_create(NGX_MAP_NGXSTR_T, NGX_MAP_NGXSTR_T, 
            cycle->pool, (ngx_palloc_pt)ngx_palloc, (ngx_pfree_pt)ngx_pfree); 
        if (cmdso_conf == NULL) {
            ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
                "ngx_tcp_cmd_parse_ini_conf|cmdso_conf == NULL\n");
            goto failed;
        }
        if (ngx_map_set_str_ptr(cmdso_conf, (const char *)ini_section.data, section_map) 
            != NGX_OK) {
            ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
                "ngx_tcp_cmd_parse_ini_conf|ngx_map_set_str_ptr %s\n", 
                ini_section.data);
            goto failed;
        }
        section_map = NULL;
        continue;

__pcre_exec_after_ini_section__:
        rc = pcre_exec(re_line.regex->code, NULL, line_buf, ngx_strlen(line_buf), 
                       0, 0, ovector, PCRE_OVECTOR_SIZE);
        if (rc < 0) {
            ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
                "ngx_tcp_cmd_parse_ini_conf|pcre_exec %s, line number %d\n",
                line_buf, lines);
            goto failed;
        }
        if (ini_section.data == NULL ) {
            ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
                "ngx_tcp_cmd_parse_ini_conf|no section line %s, line number %d\n",
                line_buf, lines);
            goto failed;
        }
        if (ngx_map_find_str_ptr(cmdso_conf, (const char *)ini_section.data, 
            (void **)&section_map) != NGX_OK) {
            ngx_log_error(NGX_LOG_ERR, cycle->log, 0, 
                "ngx_tcp_cmd_parse_ini_conf|find section %s, line number %d\n",
                ini_section.data, lines);
            goto failed;
        }
        {
            ngx_str_t k,v;

            k.data = (u_char *)(line_buf + ovector[2]);
            k.len = ovector[3] - ovector[2];
            v.data = (u_char *)(line_buf + ovector[4]);
            v.len = ovector[5] - ovector[4];

            ngx_map_set_ngxstr_ngxstr(section_map, &k, &v);
        }
    } // end while
    fclose(p_file);

    return NGX_OK;

failed:
    if (ini_section.data != NULL ) {
        free(ini_section.data);
        ini_section.data = NULL;
    }
    if (p_file != NULL) {
        fclose(p_file);
        p_file = NULL;
    }
    return NGX_ERROR;
}
static int parse_image_info(void *conf)
{
	void *(*old_pcre_malloc)(size_t);
	void (*old_pcre_free)(void *);
	pcre *expr;//正则
	char *pattern;
	const char *error;//正则错误内容
	int pcre_state=0;//匹配图片规则状态,0为成功 -1为失败
	int erroffset;//正则错误位置
	int ovector[30];//识别器读取原图图片到GD对象
	int expr_res;//正则匹配指针
	int i=0;//循环用
	ngx_image_conf_t *info = conf;
	info->request_filename = NULL;
	old_pcre_malloc = pcre_malloc;
	old_pcre_free = pcre_free;
	pcre_malloc = malloc;
	pcre_free = free;
	if(strchr(info->dest_file,'!'))
	{
		info->pcre_type = 0;
		//pattern = "([^<]*)!([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式
		pattern = "([^<]*)\\/([^<]*)!([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式
	}
	else
	{
		info->pcre_type = 1;
		//pattern = "([^<]*).([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式
		pattern = "([^<]*)\\/([^<]*).([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式
	}
	expr = pcre_compile((const char *)pattern,0,&error,&erroffset,NULL);
	if(expr != NULL)
	{
		expr_res = pcre_exec(expr,NULL,(const char *)info->dest_file,ngx_strlen(info->dest_file),0,0,ovector,30);
		if(expr_res > 5)
		{
			for(i=0; i<expr_res; i++)
			{
				char *substring_start = info->dest_file + ovector[2*i];
				int substring_length = ovector[2*i+1] - ovector[2*i];
				sprintf(info->buffer[i],"%.*s",substring_length,substring_start);
				//printf("%d : %.*s\n",i,substring_length,substring_start);
			}
			info->source_file = info->buffer[1];
			if(info->pcre_type == 1)
			{
				/** combind source_file **/
				strcat(info->source_file,"/");
				strcat(info->source_file,info->buffer[2]);
				strcat(info->source_file,".");
				strcat(info->source_file,info->buffer[6]);
				/** combind request_filename **/
				info->request_filename = info->buffer[2];
				strcat(info->request_filename,".");
				strcat(info->request_filename,info->buffer[6]);
			}
			else
			{
				/** combind source_file **/
				strcat(info->source_file,"/");
				strcat(info->source_file,info->buffer[2]);
				/** combind request_filename **/
				info->request_filename = info->buffer[2];
			}
			info->local_dir = dirname(info->buffer[1]);
			info->dest_file = info->buffer[0];
			info->m_type = info->buffer[3];
			info->max_width = atoi(info->buffer[4]);
			info->max_height = atoi(info->buffer[5]);
			info->max_width = (info->max_width > 2000) ? 2000 : info->max_width;
                        info->max_height = (info->max_height > 2000) ? 2000 : info->max_height;
                        if(info->max_width <= 0 || info->max_height <=0 ){
                        	//如果图片小于等于0,则可以判断请求无效了
                        	pcre_free(expr);
				pcre_malloc = old_pcre_malloc;
				pcre_free = old_pcre_free;
                        	return -1;
                        }
			//printf("source_file:%s\n",info->source_file);
			if(file_exists(info->source_file) == -1)//原图不存在
			{
				download(conf);
			}
			if(file_exists(info->source_file) == 0)
			{
				pcre_state = calc_image_info(conf);
				pcre_free(expr);
				pcre_malloc = old_pcre_malloc;
				pcre_free = old_pcre_free;
				return pcre_state;
			}
		}
		pcre_free(expr);
		//恢复Nginx默认PCRE内存分配
		pcre_malloc = old_pcre_malloc;
		pcre_free = old_pcre_free;
		//END
	}
	return -1;
}
Exemplo n.º 10
0
static void external_log_results(noit_module_t *self, noit_check_t *check) {
  external_data_t *data;
  struct check_info *ci;
  stats_t current;
  struct timeval duration;

  noit_check_stats_clear(&current);

  data = noit_module_get_userdata(self);
  ci = (struct check_info *)check->closure;

  noitL(data->nldeb, "external(%s) (timeout: %d, exit: %x)\n",
        check->target, ci->timedout, ci->exit_code);

  gettimeofday(&current.whence, NULL);
  sub_timeval(current.whence, check->last_fire_time, &duration);
  current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
  if(ci->timedout) {
    current.available = NP_UNAVAILABLE;
    current.state = NP_BAD;
  }
  else if(WEXITSTATUS(ci->exit_code) == 3) {
    current.available = NP_UNKNOWN;
    current.state = NP_UNKNOWN;
  }
  else {
    current.available = NP_AVAILABLE;
    current.state = (WEXITSTATUS(ci->exit_code) == 0) ? NP_GOOD : NP_BAD;
  }

  /* Hack the output into metrics */
  if(ci->output && ci->matcher) {
    int rc, len, startoffset = 0;
    int ovector[30];
    len = strlen(ci->output);
    noitL(data->nldeb, "going to match output at %d/%d\n", startoffset, len);
    while((rc = pcre_exec(ci->matcher, NULL, ci->output, len, startoffset, 0,
                          ovector, sizeof(ovector)/sizeof(*ovector))) > 0) {
      char metric[128];
      char value[128];
      startoffset = ovector[1];
      noitL(data->nldeb, "matched at offset %d\n", rc);
      if(pcre_copy_named_substring(ci->matcher, ci->output, ovector, rc,
                                   "key", metric, sizeof(metric)) > 0 &&
         pcre_copy_named_substring(ci->matcher, ci->output, ovector, rc,
                                   "value", value, sizeof(value)) > 0) {
        /* We're able to extract something... */
        noit_stats_set_metric(&current, metric, METRIC_GUESS, value);
      }
      noitL(data->nldeb, "going to match output at %d/%d\n", startoffset, len);
    }
    noitL(data->nldeb, "match failed.... %d\n", rc);
  }

  current.status = ci->output;
  noit_check_set_stats(self, check, &current);

  /* If we didn't exit normally, or we core, or we have stderr to report...
   * provide a full report.
   */
  if((WTERMSIG(ci->exit_code) != SIGQUIT && WTERMSIG(ci->exit_code) != 0) ||
     WCOREDUMP(ci->exit_code) ||
     (ci->error && *ci->error)) {
    char uuid_str[37];
    uuid_unparse_lower(check->checkid, uuid_str);
    noitL(data->nlerr, "external/%s: (sig:%d%s) [%s]\n", uuid_str,
          WTERMSIG(ci->exit_code), WCOREDUMP(ci->exit_code)?", cored":"",
          ci->error ? ci->error : "");
  }
}
Exemplo n.º 11
0
re_err_t re_subs(const char *text, const char *regex, 
        const char *replace, const char *opts, char **result)
{
    int options;
    pcre *re;
    const char *error;
    int erroffset;
    int rc;
    int ovector[OVECT_SIZE];
    char *replace2;
    const char *rep_real;
    int posi;
    int len;
    char *result2;
    int offset;
    char *tmp;

    if (text == NULL || regex == NULL || replace == NULL || result == NULL)
        return CEPARAM;

    if ((options = parse_opts(opts)) < 0)
        return CEOPTION;

    if ((re = pcre_compile(regex, options, &error, &erroffset, NULL)) == NULL) {
        fprintf(stderr, "%s: pcre_compile: %s\n", __FUNCTION__, error);
        return CERECOMP;
    }

    if ((rc = pcre_exec(re, NULL, text, strlen(text), 0, 0,
                    ovector, NELEMS(ovector))) < 0) {
        pcre_free(re);
        return CEREEXEC;
    } else if (rc == 0) {
        pcre_free(re);
        return CENOSPACE;
    }

    /* process back-reference with replace text */
    if ((replace2 = expand_backref(text, replace, rc, ovector)) != NULL)
        rep_real = replace2;
    else
        rep_real = replace;

    len = strlen(text) - (ovector[1] - ovector[0]) + strlen(rep_real) + 1;
    if ((*result = calloc(1, len)) == NULL) {
        if (replace2 != NULL)
            free(replace2);
        pcre_free(re);
        return CENOMEM;
    }

    posi = 0;
    memcpy(*result + posi, text, ovector[0]);
    posi += ovector[0];
    memcpy(*result + posi, rep_real, strlen(rep_real));
    posi += strlen(rep_real);
    memcpy(*result + posi, text + ovector[1], strlen(text) - ovector[1]);

    if (replace2 != NULL)
        free(replace2);

    /* substitute successfully */
    save_match_info(text, rc, ovector);

    /* /g modifier */
    if (strchr(opts, 'g') != NULL) {
        if (ovector[1] == ovector[0]) {
            offset = ovector[1] + 1;
        } else {
            offset = ovector[1];
        }

        if (offset <= strlen(text)) {
            if (re_subs(text + offset, regex, 
                        replace, opts, &result2) == CESUCCESS) {
                (*result)[strlen(*result) - strlen(text) + offset] = '\0';
                tmp = *result;
                if ((*result = realloc(*result, 
                               strlen(*result) + strlen(result2) + 1)) == NULL) {
                    free(tmp);
                    pcre_free(re);
                    return CENOMEM;
                }
                strcat(*result, result2);
                free(result2);
            }
        }
    }

    pcre_free(re);
    return CESUCCESS;
}
Exemplo n.º 12
0
PCRE_DATA_SCOPE int
regexec(const regex_t *preg, const char *string, size_t nmatch,
  regmatch_t pmatch[], int eflags)
{
int rc;
int options = 0;
int *ovector = NULL;
int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
BOOL allocated_ovector = FALSE;
BOOL nosub =
  (((const pcre *)preg->re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0;

if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;

((regex_t *)preg)->re_erroffset = (size_t)(-1);  /* Only has meaning after compile */

/* When no string data is being returned, ensure that nmatch is zero.
Otherwise, ensure the vector for holding the return data is large enough. */

if (nosub) nmatch = 0;

else if (nmatch > 0)
  {
  if (nmatch <= POSIX_MALLOC_THRESHOLD)
    {
    ovector = &(small_ovector[0]);
    }
  else
    {
    if (nmatch > INT_MAX/(sizeof(int) * 3)) return REG_ESPACE;
    ovector = (int *)malloc(sizeof(int) * nmatch * 3);
    if (ovector == NULL) return REG_ESPACE;
    allocated_ovector = TRUE;
    }
  }

rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string),
  0, options, ovector, nmatch * 3);

if (rc == 0) rc = nmatch;    /* All captured slots were filled in */

if (rc >= 0)
  {
  size_t i;
  if (!nosub)
    {
    for (i = 0; i < (size_t)rc; i++)
      {
      pmatch[i].rm_so = ovector[i*2];
      pmatch[i].rm_eo = ovector[i*2+1];
      }
    if (allocated_ovector) free(ovector);
    for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
    }
  return 0;
  }

else
  {
  if (allocated_ovector) free(ovector);
  switch(rc)
    {
    case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
    case PCRE_ERROR_NULL: return REG_INVARG;
    case PCRE_ERROR_BADOPTION: return REG_INVARG;
    case PCRE_ERROR_BADMAGIC: return REG_INVARG;
    case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
    case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
    case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE;
    case PCRE_ERROR_BADUTF8: return REG_INVARG;
    case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG;
    default: return REG_ASSERT;
    }
  }
}
Exemplo n.º 13
0
static int CompareResult(const char *filename, const char *prev_file)
{
    Log(LOG_LEVEL_VERBOSE, "Comparing files  %s with %s", prev_file, filename);

    int rtn = 0;

    FILE *old_fp = safe_fopen(prev_file, "r");
    FILE *new_fp = safe_fopen(filename, "r");
    if (old_fp && new_fp)
    {
        const char *errptr;
        int erroffset;
        pcre_extra *regex_extra = NULL;
        // Match timestamps and remove them. Not Y21K safe! :-)
        pcre *regex = pcre_compile(LOGGING_TIMESTAMP_REGEX, PCRE_MULTILINE, &errptr, &erroffset, NULL);
        if (!regex)
        {
            UnexpectedError("Compiling regular expression failed");
            rtn = 1;
        }
        else
        {
            regex_extra = pcre_study(regex, 0, &errptr);
        }

        while (regex)
        {
            size_t old_line_size = CF_BUFSIZE;
            char *old_line = xmalloc(old_line_size);
            char *old_msg = NULL;
            if (CfReadLine(&old_line, &old_line_size, old_fp) >= 0)
            {
                old_msg = old_line;
            }

            size_t new_line_size = CF_BUFSIZE;
            char *new_line = xmalloc(new_line_size);
            char *new_msg = NULL;
            if (CfReadLine(&new_line, &new_line_size, new_fp) >= 0)
            {
                new_msg = new_line;
            }

            if (!old_msg || !new_msg)
            {
                if (old_msg != new_msg)
                {
                    rtn = 1;
                }
                free(old_line);
                free(new_line);
                break;
            }

            char *index;
            if (pcre_exec(regex, regex_extra, old_msg, strlen(old_msg), 0, 0, NULL, 0) >= 0)
            {
                index = strstr(old_msg, ": ");
                if (index != NULL)
                {
                    old_msg = index + 2;
                }
            }
            if (pcre_exec(regex, regex_extra, new_msg, strlen(new_msg), 0, 0, NULL, 0) >= 0)
            {
                index = strstr(new_msg, ": ");
                if (index != NULL)
                {
                    new_msg = index + 2;
                }
            }

            if (strcmp(old_msg, new_msg) != 0)
            {
                rtn = 1;
                free(old_line);
                free(new_line);
                break;
            }

            free(old_line);
            free(new_line);
        }

        if (regex_extra)
        {
            free(regex_extra);
        }
        pcre_free(regex);
    }
    else
    {
        /* no previous file */
        rtn = 1;
    }

    if (old_fp)
    {
        fclose(old_fp);
    }
    if (new_fp)
    {
        fclose(new_fp);
    }

    if (!ThreadLock(cft_count))
    {
        Log(LOG_LEVEL_ERR, "Severe lock error when mailing in exec");
        return 1;
    }

/* replace old file with new*/

    unlink(prev_file);

    if (!LinkOrCopy(filename, prev_file, true))
    {
        Log(LOG_LEVEL_INFO, "Could not symlink or copy '%s' to '%s'", filename, prev_file);
        rtn = 1;
    }

    ThreadUnlock(cft_count);
    return rtn;
}
Exemplo n.º 14
0
void event_message(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) {

    irc_ctx_t *ctx = (irc_ctx_t*)irc_get_ctx(session);
    irc_thread_data *self = (irc_thread_data*)ctx->self;

    // shutup compiler complaining about unused variables
    (void) event; (void) count;

    char *lin    = NULL;
    char *netid  = NULL;
    char *data   = NULL;
    char *nick   = malloc(sizeof(char)*256);

    char *st     = NULL;

    dbuf* buf = NULL;

    irc_target_get_nick(origin, nick, 255);

    if (self->d.id != 0) goto out;

    if (params[1]) {
        lin   = strdup(params[1]);
        netid = malloc(sizeof(char)*512);
        data  = malloc(sizeof(char)*512);

        //if (!netid || !data || !lin) goto clean;

        int vc[9];

        int rc = 0;

        // note: we assume the regex matches *always* the id and the data, for making the code smaller and simpler

        rc = pcre_exec(self->regex_final, NULL, lin, (int)strlen(lin), 0, 0, vc, 9);
        if (rc >= 0 && !parse)
                goto clean; // failed parsing

        if (rc >= 0) rc = DONE;

        if (rc < 0) {
            rc = pcre_exec(self->regex, NULL, lin, (int)strlen(lin), 0, 0, vc, 9);
            if (rc < 0 || !parse)
                goto clean; // no match with the final nor the "normal"
        }

        HASH_FIND_STR((ctx->ds), nick, buf);

        if (!buf) {
            irc_debug(self, "allocating a new buffer structure for %s", nick);
            buf = malloc(sizeof(dbuf));
            buf->dt = malloc(sizeof(char)*MTU*4);
            memset(buf->dt, 0, MTU*4);
            strncpy(buf->nick, nick, 127);
            HASH_ADD_STR((ctx->ds), nick, buf);
        }

        // ugly workaround to a bug that comes from nonwhere, try to know why it doesn't work somewhen
        {
            char buffer[MTU*4] = {0};
            snprintf(buffer, MTU*4-1, "%s%s", buf->dt, data);
            snprintf(buf->dt, MTU*4-1, "%s", buffer);
        }


        if (rc != DONE) goto clean; // data already added, but there is still more data to come

        int z, len = 0;
        len = debase64(buf->dt, &st);
        if (len < 1) {
            irc_debug(self, "error when decoding base64 buffer (%d)", len);
            goto iclean;
        }

        if ((z = zmq_send(ctx->data, st, len, 0)) < 0) {
                irc_debug(self, "error when trying to send a message to the tun (warning, this WILL result in missing packets!)", zmq_strerror(errno));
        }
        iclean:
        memset(buf->dt, 0, strlen(buf->dt));

        clean:
        if (lin) free(lin);
        if (netid) free(netid);
        if (data) free(data);
        if (st) free(st);
    }

    out:
    if (nick) free(nick);
}
Exemplo n.º 15
0
int sss_parse_name(TALLOC_CTX *memctx,
                   struct sss_names_ctx *snctx,
                   const char *orig, char **_domain, char **_name)
{
    pcre *re = snctx->re;
    const char *result;
    int ovec[30];
    int origlen;
    int ret, strnum;

    origlen = strlen(orig);

    ret = pcre_exec(re, NULL, orig, origlen, 0, PCRE_NOTEMPTY, ovec, 30);
    if (ret == PCRE_ERROR_NOMATCH) {
        return ERR_REGEX_NOMATCH;
    } else if (ret < 0) {
        DEBUG(SSSDBG_MINOR_FAILURE, "PCRE Matching error, %d\n", ret);
        return EINVAL;
    }

    if (ret == 0) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Too many matches, the pattern is invalid.\n");
    }

    strnum = ret;

    if (_name != NULL) {
        result = NULL;
        ret = pcre_get_named_substring(re, orig, ovec, strnum, "name", &result);
        if (ret < 0  || !result) {
            DEBUG(SSSDBG_OP_FAILURE, "Name not found!\n");
            return EINVAL;
        }
        *_name = talloc_strdup(memctx, result);
        pcre_free_substring(result);
        if (!*_name) return ENOMEM;
    }

    if (_domain != NULL) {
        result = NULL;
        ret = pcre_get_named_substring(re, orig, ovec, strnum, "domain",
                                       &result);
        if (ret < 0  || !result) {
            DEBUG(SSSDBG_CONF_SETTINGS, "Domain not provided!\n");
            *_domain = NULL;
        } else {
            /* ignore "" string */
            if (*result) {
                *_domain = talloc_strdup(memctx, result);
                pcre_free_substring(result);
                if (!*_domain) return ENOMEM;
            } else {
                pcre_free_substring(result);
                *_domain = NULL;
            }
        }
    }

    return EOK;
}
Exemplo n.º 16
0
PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_regexec(const pcre_regex_t *preg, const char *string, size_t nmatch,
  pcre_regmatch_t pmatch[], int eflags)
{
int rc, so, eo;
int options = 0;
int *ovector = NULL;
int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
BOOL allocated_ovector = FALSE;
BOOL nosub =
  (REAL_PCRE_OPTIONS((const pcre *)preg->re_pcre) & PCRE_NO_AUTO_CAPTURE) != 0;

if ((eflags & PCRE_REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
if ((eflags & PCRE_REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
if ((eflags & PCRE_REG_NOTEMPTY) != 0) options |= PCRE_NOTEMPTY;

((pcre_regex_t *)preg)->re_erroffset = (size_t)(-1);  /* Only has meaning after compile */

/* When no string data is being returned, or no vector has been passed in which
to put it, ensure that nmatch is zero. Otherwise, ensure the vector for holding
the return data is large enough. */

if (nosub || pmatch == NULL) nmatch = 0;

else if (nmatch > 0)
  {
  if (nmatch <= POSIX_MALLOC_THRESHOLD)
    {
    ovector = &(small_ovector[0]);
    }
  else
    {
    if (nmatch > INT_MAX/(sizeof(int) * 3)) return PCRE_REG_ESPACE;
    ovector = (int *)malloc(sizeof(int) * nmatch * 3);
    if (ovector == NULL) return PCRE_REG_ESPACE;
    allocated_ovector = TRUE;
    }
  }

/* REG_STARTEND is a BSD extension, to allow for non-NUL-terminated strings.
The man page from OS X says "REG_STARTEND affects only the location of the
string, not how it is matched". That is why the "so" value is used to bump the
start location rather than being passed as a PCRE "starting offset". */

if ((eflags & PCRE_REG_STARTEND) != 0)
  {
  if (pmatch == NULL) return PCRE_REG_INVARG;
  so = pmatch[0].rm_so;
  eo = pmatch[0].rm_eo;
  }
else
  {
  so = 0;
  eo = (int)strlen(string);
  }

rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string + so, (eo - so),
  0, options, ovector, (int)(nmatch * 3));

if (rc == 0) rc = (int)nmatch;    /* All captured slots were filled in */

/* Successful match */

if (rc >= 0)
  {
  size_t i;
  if (!nosub)
    {
    for (i = 0; i < (size_t)rc; i++)
      {
      pmatch[i].rm_so = (ovector[i*2] < 0)? -1 : ovector[i*2] + so;
      pmatch[i].rm_eo = (ovector[i*2+1] < 0)? -1: ovector[i*2+1] + so;
      }
    if (allocated_ovector) free(ovector);
    for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
    }
  return 0;
  }

/* Unsuccessful match */

if (allocated_ovector) free(ovector);
switch(rc)
  {
/* ========================================================================== */
  /* These cases are never obeyed. This is a fudge that causes a compile-time
  error if the vector eint, which is indexed by compile-time error number, is
  not the correct length. It seems to be the only way to do such a check at
  compile time, as the sizeof() operator does not work in the C preprocessor.
  As all the PCRE_ERROR_xxx values are negative, we can use 0 and 1. */

  case 0:
  case (sizeof(eint)/sizeof(int) == ERRCOUNT):
  return PCRE_REG_ASSERT;
/* ========================================================================== */

  case PCRE_ERROR_NOMATCH: return PCRE_REG_NOMATCH;
  case PCRE_ERROR_NULL: return PCRE_REG_INVARG;
  case PCRE_ERROR_BADOPTION: return PCRE_REG_INVARG;
  case PCRE_ERROR_BADMAGIC: return PCRE_REG_INVARG;
  case PCRE_ERROR_UNKNOWN_NODE: return PCRE_REG_ASSERT;
  case PCRE_ERROR_NOMEMORY: return PCRE_REG_ESPACE;
  case PCRE_ERROR_MATCHLIMIT: return PCRE_REG_ESPACE;
  case PCRE_ERROR_BADUTF8: return PCRE_REG_INVARG;
  case PCRE_ERROR_BADUTF8_OFFSET: return PCRE_REG_INVARG;
  case PCRE_ERROR_BADMODE: return PCRE_REG_INVARG;
  default: return PCRE_REG_ASSERT;
  }
}
Exemplo n.º 17
0
bool SearchContext::searchFile(int id, const std::string &filename, RegexList &filespecRegexes, pcre *matchRegex)
{
    bool matchesOneFilespec = false;
    for(RegexList::iterator it = filespecRegexes.begin(); it != filespecRegexes.end(); ++it)
    {
        pcre *regex = *it;
        if(pcre_exec(regex, NULL, filename.c_str(), filename.length(), 0, 0, NULL, 0) >= 0)
        {
            matchesOneFilespec = true;
            break;
        }
    }
    if(!matchesOneFilespec)
        return false;

    std::string contents;
    if(!readEntireFile(filename, contents, params_.maxFileSize))
        return false;

    std::string workBuffer = contents;
    std::string updatedContents;

    bool atLeastOneMatch = false;

    int lineNumber = 1;
    char *p = &workBuffer[0];
    char *line;
    while((line = nextToken(&p, '\n')) != NULL)
    {
        char *originalLine = line;
        std::string replacedLine;
		SearchEntry entry;
        int ovector[100];
        do
        {
            bool matches = false;
            int matchPos;
            int matchLen;

            if(matchRegex)
            {
                int rc;
                if(rc = pcre_exec(matchRegex, 0, line, strlen(line), 0, 0, ovector, sizeof(ovector)) >= 0)
                {
                    matches = true;
                    matchPos = ovector[0];
                    matchLen = ovector[1] - ovector[0];
                }
            }
            else
            {
                char *match;
                if(params_.flags & SF_MATCH_CASE_SENSITIVE)
                    match = strstr(line, params_.match.c_str());
                else
                    match = strstri(line, params_.match.c_str());
                if(match != NULL)
                {
                    matches = true;
                    matchPos = match - line;
                    matchLen = params_.match.length();
                }
            }

            if(params_.flags & SF_REPLACE)
            {
                if(matches)
                {
                    replacedLine.append(line, matchPos);
					entry.highlights_.push_back(Highlight(replacedLine.length(), params_.replace.length()));
                    replacedLine.append(params_.replace);
                    line += matchPos + matchLen;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if(matches)
                {
                    entry.filename_ = filename;
                    entry.match_ = originalLine;
                    entry.line_ = lineNumber;
					entry.highlights_.push_back(Highlight(matchPos + (line - originalLine), matchLen));
					line += matchPos + matchLen;
                }
				else
				{
					break;
				}
            }

            if(matches)
                hits_++;
        }
        while(*line);

        if(!entry.filename_.empty())
        {
            linesWithHits_++;
            atLeastOneMatch = true;
        }

        if(params_.flags & SF_REPLACE)
        {
            if(line && *line)
                replacedLine += line;
            if(replacedLine != originalLine)
            {
                entry.filename_ = filename;
                entry.match_ = replacedLine;
                entry.line_ = lineNumber;
                append(id, entry);
            }
            replacedLine += "\n";
            updatedContents += replacedLine;
        }
		else
		{
			if(!entry.filename_.empty())
				append(id, entry);
		}
		lineNumber++;
    }
    if(atLeastOneMatch)
        filesWithHits_++;
    if(params_.flags & SF_REPLACE)
    {
        if((contents != updatedContents))
        {
			bool overwriteFile = true;
			if(params_.flags & SF_BACKUP)
			{
				std::string backupFilename = filename;
				backupFilename += ".";
				backupFilename += params_.backupExtension;

				if(!writeEntireFile(backupFilename, contents))
				{
					std::string err = "WARNING: Couldn't write backup file (skipping replacement): ";
					err += backupFilename;
					err += "\n";
					poke(id, err.c_str(), HighlightList(), 0, false);

					overwriteFile = false;
				}
			}

			if(overwriteFile)
			{
				if(writeEntireFile(filename, updatedContents))
				{
					return true;
				}
				else
				{
					std::string err = "WARNING: Couldn't write to file: ";
					err += filename;
					err += "\n";
					poke(id, err.c_str(), HighlightList(), 0, false);
				}
			}
        }
        return false;
    }
    return true;
}
Exemplo n.º 18
0
static bool regex_match(const pcre *pattern, const char *subject) {
  int ovector[3];
  return pcre_exec(pattern, NULL, subject, strlen(subject), 0, 0, ovector,
                   3) >= 0;
}
Exemplo n.º 19
0
/**
 * \brief This function is used to parse fragoffset option passed via fragoffset: keyword
 *
 * \param fragoffsetstr Pointer to the user provided fragoffset options
 *
 * \retval fragoff pointer to DetectFragOffsetData on success
 * \retval NULL on failure
 */
DetectFragOffsetData *DetectFragOffsetParse (char *fragoffsetstr) {
    DetectFragOffsetData *fragoff = NULL;
    char *substr[3] = {NULL, NULL, NULL};
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];
    int i;
    const char *str_ptr;
    char *mode = NULL;

    ret = pcre_exec(parse_regex, parse_regex_study, fragoffsetstr, strlen(fragoffsetstr), 0, 0, ov, MAX_SUBSTRINGS);
    if (ret < 1 || ret > 4) {
        SCLogError(SC_ERR_PCRE_MATCH,"Parse error %s", fragoffsetstr);
        goto error;
    }

    for (i = 1; i < ret; i++) {
        res = pcre_get_substring((char *)fragoffsetstr, ov, MAX_SUBSTRINGS, i, &str_ptr);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_get_substring failed");
            goto error;
        }
        substr[i-1] = (char *)str_ptr;
    }

    fragoff = SCMalloc(sizeof(DetectFragOffsetData));
    if (unlikely(fragoff == NULL))
        goto error;

    fragoff->frag_off = 0;
    fragoff->mode = 0;

    mode = substr[0];

    if(mode != NULL)    {

        while(*mode != '\0')    {
            switch(*mode)   {
                case '>':
                    fragoff->mode = FRAG_MORE;
                    break;
                case '<':
                    fragoff->mode = FRAG_LESS;
                    break;
            }
            mode++;
        }
    }

    if (ByteExtractStringUint16(&fragoff->frag_off, 10, 0, substr[1]) < 0) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "specified frag offset %s is not "
                                        "valid", substr[1]);
        goto error;
    }

    for (i = 0; i < 3; i++) {
        if (substr[i] != NULL) SCFree(substr[i]);
    }

    return fragoff;

error:
    for (i = 0; i < 3; i++) {
        if (substr[i] != NULL) SCFree(substr[i]);
    }
    if (fragoff != NULL) DetectFragOffsetFree(fragoff);
    return NULL;

}
int filter_request_headers(request_rec *r, const char *value){

	/*
		Filters all request headers from the Internet request.  

			leave MOD_BUT_SESSION in request
			leave SESSION_STORE_FREE_COOKIES in request
			unset all other cookies the client is sending
							const char *insert_cookie = NULL;
							const char *new_cookie = NULL;
							const char *existing_cookie = NULL; 


	*/

	const char *insert_cookie = NULL;
	const char *new_cookie = NULL;
	const char *existing_cookie = NULL; 

	mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module);
	ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: FILTER REQUEST HEADER [%s]", value);


	/*
		First, we unset all headers here

	*/
	apr_table_unset(r->headers_in, "Cookie");
	ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: Unsetting all request headers");


	if(value){
		pcre *re;  					// the regular expression
		const char *error;				// error text for the failed regex compilation
		int error_offset;				// offset of the regex compilation error, if any
		int rc = 0;					// return code of pcre_exec
		int re_vector[3072];

		char *qa = (char *)apr_pstrdup(r->pool, value);
		char *p, *last;

		/*
			Loop through all a=b; c=d; e=f values
			Cookies are sent in a single line from the browser Cookie: jsessionid=1234; foo=3322;

		*/
		ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: REQUEST FILTER: COOKIES BEFORE PARSING: [%s]", value);
		ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: config->cookie_name [%s]", config->cookie_name);

		for(p = (char *)apr_strtok(qa, "; ", &last); p != NULL; p = (char *)apr_strtok(NULL, "; ", &last))
		{



			/*
				Make sure we insert the MOD_BUT_SESSION into headers_in, after we unset all
			*/
			char *p1 = strstr(p, config->cookie_name);
			if(p1){
				/*
					If we are here, we are analyzing the MOD_BUT_SESSION Cookie
				*/
				ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: MOD_BUT_SESSION FOUND [%s]", p1);

				p1 += strlen(config->cookie_name);

				if(*p1 == '=')
				{
					char *mod_but_session = (char *)apr_pstrdup(r->pool, p1+1);
					ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: MOD_BUT_SESSION (NOTES) [%s]", mod_but_session);
					apr_table_set(r->notes, config->cookie_name , mod_but_session);
				}
			}else{

				/*
					Now let's see the other cookies the client sends
				*/

				if (p == NULL){
					ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: P IS NULL [%s]", p);
				}else
				{
					if(config->session_store_free_cookies){
						re = pcre_compile(config->session_store_free_cookies, 0, &error, &error_offset, NULL);

						if (re == NULL) {
						ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: return code of pcre_compile in Cookie Store is NULL");
						}

						rc = pcre_exec(re, NULL, p, strlen(p), 0, 0, re_vector, 3072);


						if (rc < 0) {
							ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: REQUEST FILTER: INVALID COOKIE SENT BY CLIENT (POTENTIALLY HACKING ATTEMPT) [%s]", p);
						}


						if (rc == 0) {
							ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: PCRE output vector too small (%d)", 3072/3-1);
							ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: Problems with the following ARGS = %s", value);
							return DECLINED;
						}

						if (rc > 0) {
							ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: REQUEST FILTER: FREE COOKIE FOUND [%s]", p);
							/*
								Please note, apr_table_unset(r->hearders_in, "Cookie") was done in mod_but.c (CORE)
								Here we add our "wanted" cookies again into the request header.
							*/

							insert_cookie = (char *)apr_psprintf(r->pool, "%s;", p);
							existing_cookie = apr_table_get(r->notes, "REQUEST_COOKIES"); 
					
							if (insert_cookie != NULL){
								if (apr_table_get(r->notes, "REQUEST_COOKIES") == NULL) {
									new_cookie=apr_pstrcat(r->pool, insert_cookie, NULL);
					
								} else {
									new_cookie=apr_pstrcat(r->pool, existing_cookie, insert_cookie, NULL);
									
								}
								apr_table_set(r->notes, "REQUEST_COOKIES", new_cookie);
								ap_log_rerror(PC_LOG_INFO, r, "mod_but_cookiestore.c: ADD COOKIE [%s] into r->notes", apr_table_get(r->notes, "REQUEST_COOKIES"));
							}

							//apr_table_addn(r->headers_in, "Cookie", "dummycookie=dummy;" );
						}
					}
				}
			}

		}
	}
	return DECLINED;
}
Exemplo n.º 21
0
AP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string,
                           apr_size_t nmatch, ap_regmatch_t pmatch[],
                           int eflags)
{
int rc;
int options = 0;
int *ovector = NULL;
int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
int allocated_ovector = 0;

if ((eflags & AP_REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
if ((eflags & AP_REG_NOTEOL) != 0) options |= PCRE_NOTEOL;

((ap_regex_t *)preg)->re_erroffset = (apr_size_t)(-1);  /* Only has meaning after compile */

if (nmatch > 0)
  {
  if (nmatch <= POSIX_MALLOC_THRESHOLD)
    {
    ovector = &(small_ovector[0]);
    }
  else
    {
    ovector = (int *)malloc(sizeof(int) * nmatch * 3);
    if (ovector == NULL) return AP_REG_ESPACE;
    allocated_ovector = 1;
    }
  }

rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string),
  0, options, ovector, nmatch * 3);

if (rc == 0) rc = nmatch;    /* All captured slots were filled in */

if (rc >= 0)
  {
  apr_size_t i;
  for (i = 0; i < (apr_size_t)rc; i++)
    {
    pmatch[i].rm_so = ovector[i*2];
    pmatch[i].rm_eo = ovector[i*2+1];
    }
  if (allocated_ovector) free(ovector);
  for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
  return 0;
  }

else
  {
  if (allocated_ovector) free(ovector);
  switch(rc)
    {
    case PCRE_ERROR_NOMATCH: return AP_REG_NOMATCH;
    case PCRE_ERROR_NULL: return AP_REG_INVARG;
    case PCRE_ERROR_BADOPTION: return AP_REG_INVARG;
    case PCRE_ERROR_BADMAGIC: return AP_REG_INVARG;
    case PCRE_ERROR_UNKNOWN_NODE: return AP_REG_ASSERT;
    case PCRE_ERROR_NOMEMORY: return AP_REG_ESPACE;
#ifdef PCRE_ERROR_MATCHLIMIT
    case PCRE_ERROR_MATCHLIMIT: return AP_REG_ESPACE;
#endif
#ifdef PCRE_ERROR_BADUTF8
    case PCRE_ERROR_BADUTF8: return AP_REG_INVARG;
#endif
#ifdef PCRE_ERROR_BADUTF8_OFFSET
    case PCRE_ERROR_BADUTF8_OFFSET: return AP_REG_INVARG;
#endif
    default: return AP_REG_ASSERT;
    }
  }
}
Exemplo n.º 22
0
/**
 * \internal
 * \brief This function is used to parse dsize options passed via dsize: keyword
 *
 * \param rawstr Pointer to the user provided dsize options
 *
 * \retval dd pointer to DetectDsizeData on success
 * \retval NULL on failure
 */
DetectDsizeData *DetectDsizeParse (char *rawstr)
{
    DetectDsizeData *dd = NULL;
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];
    char mode[2] = "";
    char value1[6] = "";
    char value2[6] = "";
    char range[3] = "";

    ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
    if (ret < 3 || ret > 5) {
        SCLogError(SC_ERR_PCRE_MATCH,"Parse error %s", rawstr);
        goto error;
    }

    res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, mode, sizeof(mode));
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed");
        goto error;
    }
    SCLogDebug("mode \"%s\"", mode);

    res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, value1, sizeof(value1));
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed");
        goto error;
    }
    SCLogDebug("value1 \"%s\"", value1);

    if (ret > 3) {
        res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, range, sizeof(range));
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed");
            goto error;
        }
        SCLogDebug("range \"%s\"", range);

        if (ret > 4) {
            res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, value2, sizeof(value2));
            if (res < 0) {
                SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed");
                goto error;
            }
            SCLogDebug("value2 \"%s\"", value2);
        }
    }

    dd = SCMalloc(sizeof(DetectDsizeData));
    if (unlikely(dd == NULL))
        goto error;
    dd->dsize = 0;
    dd->dsize2 = 0;
    dd->mode = DETECTDSIZE_EQ; // default

    if (strlen(mode) > 0) {
        if (mode[0] == '<')
            dd->mode = DETECTDSIZE_LT;
        else if (mode[0] == '>')
            dd->mode = DETECTDSIZE_GT;
        else
            dd->mode = DETECTDSIZE_EQ;
    }

    if (strcmp("<>", range) == 0) {
        if (strlen(mode) != 0) {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set");
            goto error;
        }
        dd->mode = DETECTDSIZE_RA;
    }

    /** set the first dsize value */
    if (ByteExtractStringUint16(&dd->dsize,10,strlen(value1),value1) <= 0) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid size value1:\"%s\"", value1);
        goto error;
    }

    /** set the second dsize value if specified */
    if (strlen(value2) > 0) {
        if (dd->mode != DETECTDSIZE_RA) {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple dsize values specified but mode is not range");
            goto error;
        }

        if (ByteExtractStringUint16(&dd->dsize2,10,strlen(value2),value2) <= 0) {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size value2:\"%s\"",value2);
            goto error;
        }

        if (dd->dsize2 <= dd->dsize) {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"dsize2:%"PRIu16" <= dsize:%"PRIu16"",dd->dsize2,dd->dsize);
            goto error;
        }
    }

    SCLogDebug("dsize parsed successfully dsize: %"PRIu16" dsize2: %"PRIu16"",dd->dsize,dd->dsize2);
    return dd;

error:
    if (dd)
        SCFree(dd);
    return NULL;
}
Exemplo n.º 23
0
/**
 * \brief This function is used to parse fingerprint passed via keyword: "fingerprint"
 *
 * \param idstr Pointer to the user provided fingerprint option
 *
 * \retval pointer to DetectTlsData on success
 * \retval NULL on failure
 */
static DetectTlsData *DetectTlsFingerprintParse (const char *str, bool negate)
{
    DetectTlsData *tls = NULL;
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];
    const char *str_ptr;
    char *orig;
    char *tmp_str;
    uint32_t flag = 0;

    ret = pcre_exec(fingerprint_parse_regex, fingerprint_parse_regex_study, str, strlen(str), 0, 0,
                    ov, MAX_SUBSTRINGS);
    if (ret != 2) {
        SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.fingerprint option");
        goto error;
    }

    if (negate)
        flag = DETECT_CONTENT_NEGATED;

    res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }

    /* We have a correct id option */
    tls = SCMalloc(sizeof(DetectTlsData));
    if (unlikely(tls == NULL))
        goto error;
    tls->fingerprint = NULL;
    tls->flags = flag;

    orig = SCStrdup((char*)str_ptr);
    if (unlikely(orig == NULL)) {
        goto error;
    }
    pcre_free_substring(str_ptr);

    tmp_str=orig;

    /* Let's see if we need to escape "'s */
    if (tmp_str[0] == '"')
    {
        tmp_str[strlen(tmp_str) - 1] = '\0';
        tmp_str += 1;
    }

    tls->fingerprint = SCStrdup(tmp_str);
    if (tls->fingerprint == NULL) {
        SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate fingerprint");
    }

    SCFree(orig);

    SCLogDebug("will look for TLS fingerprint %s", tls->fingerprint);

    return tls;

error:
    if (tls != NULL)
        DetectTlsFingerprintFree(tls);
    return NULL;

}
Exemplo n.º 24
0
static spec_t *lookup_common(struct selabel_handle *rec,
			     const char *key,
			     int type,
			     bool partial)
{
	struct saved_data *data = (struct saved_data *)rec->data;
	spec_t *spec_arr = data->spec_arr;
	int i, rc, file_stem, pcre_options = 0;
	mode_t mode = (mode_t)type;
	const char *buf;
	spec_t *ret = NULL;
	char *clean_key = NULL;
	const char *prev_slash, *next_slash;
	unsigned int sofar = 0;

	if (!data->nspec) {
		errno = ENOENT;
		goto finish;
	}

	/* Remove duplicate slashes */
	if ((next_slash = strstr(key, "//"))) {
		clean_key = (char *) malloc(strlen(key) + 1);
		if (!clean_key)
			goto finish;
		prev_slash = key;
		while (next_slash) {
			memcpy(clean_key + sofar, prev_slash, next_slash - prev_slash);
			sofar += next_slash - prev_slash;
			prev_slash = next_slash + 1;
			next_slash = strstr(prev_slash, "//");
		}
		strcpy(clean_key + sofar, prev_slash);
		key = clean_key;
	}

	buf = key;
	file_stem = find_stem_from_file(data, &buf);
	mode &= S_IFMT;

	if (partial)
		pcre_options |= PCRE_PARTIAL_SOFT;

	/* 
	 * Check for matching specifications in reverse order, so that
	 * the last matching specification is used.
	 */
	for (i = data->nspec - 1; i >= 0; i--) {
		/* if the spec in question matches no stem or has the same
		 * stem as the file AND if the spec in question has no mode
		 * specified or if the mode matches the file mode then we do
		 * a regex check        */
		if ((spec_arr[i].stem_id == -1
		     || spec_arr[i].stem_id == file_stem)
		    && (!mode || !spec_arr[i].mode
			|| mode == spec_arr[i].mode)) {
			if (compile_regex(data, &spec_arr[i], NULL) < 0)
				goto finish;
			if (spec_arr[i].stem_id == -1)
				rc = pcre_exec(spec_arr[i].regex, spec_arr[i].sd, key, strlen(key), 0, pcre_options, NULL, 0);
			else
				rc = pcre_exec(spec_arr[i].regex, spec_arr[i].sd, buf, strlen(buf), 0, pcre_options, NULL, 0);

			if (rc == 0) {
				spec_arr[i].matches++;
				break;
			} else if (partial && rc == PCRE_ERROR_PARTIAL)
				break;

			if (rc == PCRE_ERROR_NOMATCH)
				continue;
			/* else it's an error */
			goto finish;
		}
	}

	if (i < 0 || strcmp(spec_arr[i].lr.ctx_raw, "<<none>>") == 0) {
		/* No matching specification. */
		errno = ENOENT;
		goto finish;
	}

	ret = &spec_arr[i];

finish:
	free(clean_key);
	return ret;
}
Exemplo n.º 25
0
static bool CompareResultEqualOrFiltered(const ExecConfig *config,
                                         const char *filename,
                                         const char *prev_file)
{
    Log(LOG_LEVEL_VERBOSE, "Comparing files  %s with %s", prev_file, filename);

    bool rtn = true;

    FILE *old_fp = safe_fopen(prev_file, "r");
    FILE *new_fp = safe_fopen(filename, "r");
    if (new_fp)
    {
        const char *errptr;
        int erroffset;
        pcre_extra *regex_extra = NULL;
        // Match timestamps and remove them. Not Y21K safe! :-)
        pcre *regex = pcre_compile(LOGGING_TIMESTAMP_REGEX, PCRE_MULTILINE, &errptr, &erroffset, NULL);
        if (!regex)
        {
            UnexpectedError("Compiling regular expression failed");
            rtn = false;
        }
        else
        {
            regex_extra = pcre_study(regex, 0, &errptr);
        }

        size_t old_line_size = CF_BUFSIZE;
        char *old_line = xmalloc(old_line_size);
        size_t new_line_size = CF_BUFSIZE;
        char *new_line = xmalloc(new_line_size);
        bool any_new_msg_present = false;
        while (regex)
        {
            char *old_msg = NULL;
            if (old_fp)
            {
                while (CfReadLine(&old_line, &old_line_size, old_fp) >= 0)
                {
                    if (!LineIsFiltered(config, old_line))
                    {
                        old_msg = old_line;
                        break;
                    }
                }
            }

            char *new_msg = NULL;
            while (CfReadLine(&new_line, &new_line_size, new_fp) >= 0)
            {
                if (!LineIsFiltered(config, new_line))
                {
                    any_new_msg_present = true;
                    new_msg = new_line;
                    break;
                }
            }

            if (!old_msg || !new_msg)
            {
                // Return difference in most cases, when there is a new
                // message line, but if there isn't one, return equal, even
                // if strictly speaking they aren't, since we don't want to
                // send an empty email.
                if (any_new_msg_present && old_msg != new_msg)
                {
                    rtn = false;
                }
                break;
            }

            // Remove timestamps from lines before comparison.
            char *index;
            if (pcre_exec(regex, regex_extra, old_msg, strlen(old_msg), 0, 0, NULL, 0) >= 0)
            {
                index = strstr(old_msg, ": ");
                if (index != NULL)
                {
                    old_msg = index + 2;
                }
            }
            if (pcre_exec(regex, regex_extra, new_msg, strlen(new_msg), 0, 0, NULL, 0) >= 0)
            {
                index = strstr(new_msg, ": ");
                if (index != NULL)
                {
                    new_msg = index + 2;
                }
            }

            if (strcmp(old_msg, new_msg) != 0)
            {
                rtn = false;
                break;
            }
        }

        free(old_line);
        free(new_line);

        if (regex_extra)
        {
            free(regex_extra);
        }
        pcre_free(regex);
    }
    else
    {
        /* no previous file */
        rtn = false;
    }

    if (old_fp)
    {
        fclose(old_fp);
    }
    if (new_fp)
    {
        fclose(new_fp);
    }

    if (!ThreadLock(cft_count))
    {
        Log(LOG_LEVEL_ERR, "Severe lock error when mailing in exec");
        return 1;
    }

/* replace old file with new*/

    unlink(prev_file);

    if (!LinkOrCopy(filename, prev_file, true))
    {
        Log(LOG_LEVEL_INFO, "Could not symlink or copy '%s' to '%s'", filename, prev_file);
        rtn = false;
    }

    ThreadUnlock(cft_count);
    return rtn;
}
Exemplo n.º 26
0
/* Split the string according to the regexp */
void f_pcre_split(INT32 args) 
{
  struct array *arr;	    /* Result array */ 
  struct pike_string *data; /* Data to split */
  pcre_extra *extra = NULL; /* result from study, if enabled */
  pcre *re = NULL;          /* compiled regexp */
  char *pp;                 /* Pointer... */
  int opts = 0;             /* Match options */
  int *ovector, ovecsize;   /* Subpattern storage */
  int ret;                  /* Result codes */
  int i, e;                 /* Counter variable */
  if(THIS->regexp == NULL)
    Pike_error("PCRE.Regexp not initialized.\n");
  get_all_args("PCRE.Regexp->split", args, "%S", &data);
  switch(args) {
  case 2:
    switch(Pike_sp[-1].type) {
    case T_STRING:
      opts = parse_options(Pike_sp[-1].u.string->str, NULL);
      if(opts < 0)
	Pike_error("PCRE.Regexp->split(): Unknown option modifier '%c'.\n", -opts);
      break;
    case T_INT:
      if(Pike_sp[-1].u.integer == 0) {
	break;
      }
      /* Fallthrough */
    default:
      Pike_error("Bad argument 2 to PCRE.Regexp->split() - expected string.\n");
      break;
    }
    /* Fallthrough */
  case 1:
    if(Pike_sp[-args].type != T_STRING || Pike_sp[-args].u.string->size_shift > 0) {
      Pike_error("PCRE.Regexp->match(): Invalid argument 1. Expected 8-bit string.\n");
    }
    data = Pike_sp[-args].u.string;
    break;
  default:
    Pike_error("PCRE.Regexp->match(): Invalid number of arguments. Expected 1 or 2.\n");    
  }
  re = THIS->regexp;
  extra = THIS->extra;

  /* Calculate the size of the offsets array, and allocate memory for it. */
  pcre_fullinfo(re, extra, PCRE_INFO_CAPTURECOUNT, &ovecsize);
  ovecsize = (ovecsize + 1) * 3;
  ovector = (int *)malloc(ovecsize * sizeof(int));
  if(ovector == NULL)
    Pike_error("PCRE.Regexp->split(): Out of memory.\n");

  /* Do the pattern matching */
  ret = pcre_exec(re, extra, data->str, data->len, 0,
		       opts, ovector, ovecsize);
  switch(ret) {
   case PCRE_ERROR_NOMATCH:   pop_n_elems(args); push_int(0);  break;
   case PCRE_ERROR_NULL:      Pike_error("Invalid argumens passed to pcre_exec.\n");
   case PCRE_ERROR_BADOPTION: Pike_error("Invalid options sent to pcre_exec.\n");
   case PCRE_ERROR_BADMAGIC:  Pike_error("Invalid magic number.\n");
   case PCRE_ERROR_UNKNOWN_NODE: Pike_error("Unknown node encountered. PCRE bug or memory error.\n");
   case PCRE_ERROR_NOMEMORY:  Pike_error("Out of memory during execution.\n");
   default:
    pop_n_elems(args);
    switch(ret) {
     case 1: /* No submatches, be Pike Regexp compatible */
      push_int(0);
      arr = aggregate_array(1);
      break;
     default: 
      e = ret * 2;
      for (i = 2; i < e ; i += 2) {
	push_string(make_shared_binary_string(data->str + ovector[i],
					      (int)(ovector[i+1] - ovector[i])));
      }
      arr = aggregate_array(ret-1);
    }
    push_array(arr);
    break;
  }
  free(ovector);
}
Exemplo n.º 27
0
static int
string_regexp_replace_get_matches(struct string_regexp_replace_data *mdata,
    off_t whence,
    int **match_vector,
    size_t *match_cnt)
{
    int r;
    size_t str_len, match_sz;
    pcre *compiled_re = NULL;
    pcre_extra *p_extra = NULL;
    int *matchv = NULL, sub_match_count = 0;

    *match_cnt = 0;
    *match_vector = NULL;

    //mdata->orig_string should never be NULL
    str_len = strlen(mdata->orig_string + whence);
    if (!str_len)
        return -EINVAL;

    r = pcre_compile_do(mdata->node, mdata->regexp, &compiled_re,
        &p_extra, &sub_match_count);
    SOL_INT_CHECK(r, < 0, -EINVAL);

    match_sz = (sub_match_count + 1) * 3;
    matchv = calloc(match_sz, sizeof(*matchv));
    if (!matchv) {
        r = -ENOMEM;
        goto err;
    }

    r = pcre_exec(compiled_re, p_extra, mdata->orig_string + whence,
        str_len, 0, 0, matchv, match_sz);
    if (r < 0)
        goto err;
    else {
        /* The value returned by pcre_exec() is one more than the
         * highest numbered pair that has been set. If the vector is
         * too small to hold all the captured substring offsets, it is
         * used as far as possible (up to two-thirds of its length),
         * and the function returns a value of zero.
         */
        if (r == 0) { // should not happen, but let's treat the case
            sol_flow_send_error_packet(mdata->node, EINVAL,
                "A memory overflow happened while executing"
                " regular expression '%s' on string %s",
                mdata->regexp, mdata->orig_string);
            r = -EINVAL;
            goto err;
        }
        *match_cnt = r;
        *match_vector = matchv;
    }

    if (p_extra != NULL)
        pcre_free(p_extra);
    pcre_free(compiled_re);

    return 0;

err:
    free(matchv);
    if (p_extra != NULL)
        pcre_free(p_extra);
    pcre_free(compiled_re);

    return r;
}
Exemplo n.º 28
0
static int http_list_directory(server *srv, connection *con, plugin_data *p, buffer *dir) {
	DIR *dp;
	buffer *out;
	struct dirent *dent;
	struct stat st;
	char *path, *path_file;
	size_t i;
	int hide_dotfiles = p->conf.hide_dot_files;
	dirls_list_t dirs, files, *list;
	dirls_entry_t *tmp;
	char sizebuf[sizeof("999.9K")];
	char datebuf[sizeof("2005-Jan-01 22:23:24")];
	size_t k;
	const char *content_type;
	long name_max;
#if defined(HAVE_XATTR) || defined(HAVE_EXTATTR)
	char attrval[128];
	int attrlen;
#endif
#ifdef HAVE_LOCALTIME_R
	struct tm tm;
#endif

	if (buffer_string_is_empty(dir)) return -1;

	i = buffer_string_length(dir);

#ifdef HAVE_PATHCONF
	if (0 >= (name_max = pathconf(dir->ptr, _PC_NAME_MAX))) {
		/* some broken fs (fuse) return 0 instead of -1 */
#ifdef NAME_MAX
		name_max = NAME_MAX;
#else
		name_max = 255; /* stupid default */
#endif
	}
#elif defined __WIN32
	name_max = FILENAME_MAX;
#else
	name_max = NAME_MAX;
#endif

	path = malloc(buffer_string_length(dir) + name_max + 1);
	force_assert(NULL != path);
	strcpy(path, dir->ptr);
	path_file = path + i;

	if (NULL == (dp = opendir(path))) {
		log_error_write(srv, __FILE__, __LINE__, "sbs",
			"opendir failed:", dir, strerror(errno));

		free(path);
		return -1;
	}

	dirs.ent   = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
	force_assert(dirs.ent);
	dirs.size  = DIRLIST_BLOB_SIZE;
	dirs.used  = 0;
	files.ent  = (dirls_entry_t**) malloc(sizeof(dirls_entry_t*) * DIRLIST_BLOB_SIZE);
	force_assert(files.ent);
	files.size = DIRLIST_BLOB_SIZE;
	files.used = 0;

	while ((dent = readdir(dp)) != NULL) {
		unsigned short exclude_match = 0;

		if (dent->d_name[0] == '.') {
			if (hide_dotfiles)
				continue;
			if (dent->d_name[1] == '\0')
				continue;
			if (dent->d_name[1] == '.' && dent->d_name[2] == '\0')
				continue;
		}

		if (p->conf.hide_readme_file) {
			if (strcmp(dent->d_name, "README.txt") == 0)
				continue;
		}
		if (p->conf.hide_header_file) {
			if (strcmp(dent->d_name, "HEADER.txt") == 0)
				continue;
		}

		/* compare d_name against excludes array
		 * elements, skipping any that match.
		 */
#ifdef HAVE_PCRE_H
		for(i = 0; i < p->conf.excludes->used; i++) {
			int n;
#define N 10
			int ovec[N * 3];
			pcre *regex = p->conf.excludes->ptr[i]->regex;

			if ((n = pcre_exec(regex, NULL, dent->d_name,
				    strlen(dent->d_name), 0, 0, ovec, 3 * N)) < 0) {
				if (n != PCRE_ERROR_NOMATCH) {
					log_error_write(srv, __FILE__, __LINE__, "sd",
						"execution error while matching:", n);

					/* aborting would require a lot of manual cleanup here.
					 * skip instead (to not leak names that break pcre matching)
					 */
					exclude_match = 1;
					break;
				}
			}
			else {
				exclude_match = 1;
				break;
			}
		}

		if (exclude_match) {
			continue;
		}
#endif

		i = strlen(dent->d_name);

		/* NOTE: the manual says, d_name is never more than NAME_MAX
		 *       so this should actually not be a buffer-overflow-risk
		 */
		if (i > (size_t)name_max) continue;

		memcpy(path_file, dent->d_name, i + 1);
		if (stat(path, &st) != 0)
			continue;

		list = &files;
		if (S_ISDIR(st.st_mode))
			list = &dirs;

		if (list->used == list->size) {
			list->size += DIRLIST_BLOB_SIZE;
			list->ent   = (dirls_entry_t**) realloc(list->ent, sizeof(dirls_entry_t*) * list->size);
			force_assert(list->ent);
		}

		tmp = (dirls_entry_t*) malloc(sizeof(dirls_entry_t) + 1 + i);
		tmp->mtime = st.st_mtime;
		tmp->size  = st.st_size;
		tmp->namelen = i;
		memcpy(DIRLIST_ENT_NAME(tmp), dent->d_name, i + 1);

		list->ent[list->used++] = tmp;
	}
	closedir(dp);

	if (dirs.used) http_dirls_sort(dirs.ent, dirs.used);

	if (files.used) http_dirls_sort(files.ent, files.used);

	out = buffer_init();
	buffer_copy_string_len(out, CONST_STR_LEN("<?xml version=\"1.0\" encoding=\""));
	if (buffer_string_is_empty(p->conf.encoding)) {
		buffer_append_string_len(out, CONST_STR_LEN("iso-8859-1"));
	} else {
		buffer_append_string_buffer(out, p->conf.encoding);
	}
	buffer_append_string_len(out, CONST_STR_LEN("\"?>\n"));
	http_list_directory_header(srv, con, p, out);

	/* directories */
	for (i = 0; i < dirs.used; i++) {
		tmp = dirs.ent[i];

#ifdef HAVE_LOCALTIME_R
		localtime_r(&(tmp->mtime), &tm);
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
#else
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
#endif

		buffer_append_string_len(out, CONST_STR_LEN("<tr><td class=\"n\"><a href=\""));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
		buffer_append_string_len(out, CONST_STR_LEN("/\">"));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
		buffer_append_string_len(out, CONST_STR_LEN("</a>/</td><td class=\"m\">"));
		buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">- &nbsp;</td><td class=\"t\">Directory</td></tr>\n"));

		free(tmp);
	}

	/* files */
	for (i = 0; i < files.used; i++) {
		tmp = files.ent[i];

		content_type = NULL;
#if defined(HAVE_XATTR)
		if (con->conf.use_xattr) {
			memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
			attrlen = sizeof(attrval) - 1;
			if (attr_get(path, "Content-Type", attrval, &attrlen, 0) == 0) {
				attrval[attrlen] = '\0';
				content_type = attrval;
			}
		}
#elif defined(HAVE_EXTATTR)
		if (con->conf.use_xattr) {
			memcpy(path_file, DIRLIST_ENT_NAME(tmp), tmp->namelen + 1);
			if(-1 != (attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, "Content-Type", attrval, sizeof(attrval)-1))) {
				attrval[attrlen] = '\0';
				content_type = attrval;
			}
		}
#endif

		if (content_type == NULL) {
			content_type = "application/octet-stream";
			for (k = 0; k < con->conf.mimetypes->used; k++) {
				data_string *ds = (data_string *)con->conf.mimetypes->data[k];
				size_t ct_len;

				if (buffer_is_empty(ds->key))
					continue;

				ct_len = buffer_string_length(ds->key);
				if (tmp->namelen < ct_len)
					continue;

				if (0 == strncasecmp(DIRLIST_ENT_NAME(tmp) + tmp->namelen - ct_len, ds->key->ptr, ct_len)) {
					content_type = ds->value->ptr;
					break;
				}
			}
		}

#ifdef HAVE_LOCALTIME_R
		localtime_r(&(tmp->mtime), &tm);
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", &tm);
#else
		strftime(datebuf, sizeof(datebuf), "%Y-%b-%d %H:%M:%S", localtime(&(tmp->mtime)));
#endif
		http_list_directory_sizefmt(sizebuf, tmp->size);

		buffer_append_string_len(out, CONST_STR_LEN("<tr><td class=\"n\"><a href=\""));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_REL_URI_PART);
		buffer_append_string_len(out, CONST_STR_LEN("\">"));
		buffer_append_string_encoded(out, DIRLIST_ENT_NAME(tmp), tmp->namelen, ENCODING_MINIMAL_XML);
		buffer_append_string_len(out, CONST_STR_LEN("</a></td><td class=\"m\">"));
		buffer_append_string_len(out, datebuf, sizeof(datebuf) - 1);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"s\">"));
		buffer_append_string(out, sizebuf);
		buffer_append_string_len(out, CONST_STR_LEN("</td><td class=\"t\">"));
		buffer_append_string(out, content_type);
		buffer_append_string_len(out, CONST_STR_LEN("</td></tr>\n"));

		free(tmp);
	}

	free(files.ent);
	free(dirs.ent);
	free(path);

	http_list_directory_footer(srv, con, p, out);

	/* Insert possible charset to Content-Type */
	if (buffer_string_is_empty(p->conf.encoding)) {
		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
	} else {
		buffer_copy_string_len(p->content_charset, CONST_STR_LEN("text/html; charset="));
		buffer_append_string_buffer(p->content_charset, p->conf.encoding);
		response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->content_charset));
	}

	con->file_finished = 1;
	chunkqueue_append_buffer(con->write_queue, out);
	buffer_free(out);

	return 0;
}
Exemplo n.º 29
0
/**
 * \brief This function is used to parse icode options passed via icode: keyword
 *
 * \param icodestr Pointer to the user provided icode options
 *
 * \retval icd pointer to DetectICodeData on success
 * \retval NULL on failure
 */
DetectICodeData *DetectICodeParse(char *icodestr)
{
    DetectICodeData *icd = NULL;
    char *args[3] = {NULL, NULL, NULL};
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(parse_regex, parse_regex_study, icodestr, strlen(icodestr), 0, 0, ov, MAX_SUBSTRINGS);
    if (ret < 1 || ret > 4) {
        SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, icodestr);
        goto error;
    }

    int i;
    const char *str_ptr;
    for (i = 1; i < ret; i++) {
        res = pcre_get_substring((char *)icodestr, ov, MAX_SUBSTRINGS, i, &str_ptr);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
            goto error;
        }
        args[i-1] = (char *)str_ptr;
    }

    icd = SCMalloc(sizeof(DetectICodeData));
    if (unlikely(icd == NULL))
        goto error;
    icd->code1 = 0;
    icd->code2 = 0;
    icd->mode = 0;

    /* we have either "<" or ">" */
    if (args[0] != NULL && strlen(args[0]) != 0) {
        /* we have a third part ("<> y"), therefore it's invalid */
        if (args[2] != NULL) {
            SCLogError(SC_ERR_INVALID_VALUE, "icode: invalid value");
            goto error;
        }
        /* we have only a comparison ("<", ">") */
        if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) {
            SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
                                        "valid", args[1]);
            goto error;
        }
        if ((strcmp(args[0], ">")) == 0) icd->mode = DETECT_ICODE_GT;
        else icd->mode = DETECT_ICODE_LT;
    } else { /* no "<", ">" */
        /* we have a range ("<>") */
        if (args[2] != NULL) {
            icd->mode = (uint8_t) DETECT_ICODE_RN;
            if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) {
                SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
                                            "valid", args[1]);
                goto error;
            }
            if (ByteExtractStringUint8(&icd->code2, 10, 0, args[2]) < 0) {
                SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
                                            "valid", args[2]);
                goto error;
            }
            /* we check that the first given value in the range is less than
               the second, otherwise we swap them */
            if (icd->code1 > icd->code2) {
                uint8_t temp = icd->code1;
                icd->code1 = icd->code2;
                icd->code2 = temp;
            }
        } else { /* we have an equality */
            icd->mode = DETECT_ICODE_EQ;
            if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) {
                SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
                                                    "valid", args[1]);
                goto error;
            }
        }
    }

    for (i = 0; i < (ret-1); i++) {
        if (args[i] != NULL)
            SCFree(args[i]);
    }
    return icd;

error:
    for (i = 0; i < (ret-1) && i < 3; i++) {
        if (args[i] != NULL)
            SCFree(args[i]);
    }
    if (icd != NULL)
        DetectICodeFree(icd);
    return NULL;
}
Exemplo n.º 30
0
pcre_error_code pcre_private(char *INPUT_LINE, char *INPUT_PAT, int *Output_Start, int *Output_End, char*** _pstCapturedString, int* _piCapturedStringCount)
{
    /* ALL strings are managed as UTF-8 by default */
    int options = PCRE_UTF8;
    int size_offsets = 45;
    int size_offsets_max;
    int *offsets = NULL;
    int all_use_dfa = 0;
    BOOL LOOP_PCRE_TST = FALSE;

    /* These vectors store, end-to-end, a list of captured substring names. Assume
    that 1024 is plenty long enough for the few names we'll be testing. */

    char copynames[1024];
    char getnames[1024];

    char *copynamesptr = NULL;
    char *getnamesptr = NULL;

    int rc = 0;
    (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
    if (rc != 1)
    {
        return UTF8_NOT_SUPPORTED;
    }

    /* bug 3891 */
    /* backslash characters are not interpreted for input */
    buffer = strsub(INPUT_LINE, "\\", "\\\\");

    size_offsets_max = size_offsets;
    offsets = (int *)MALLOC(size_offsets_max * sizeof(int));
    if (offsets == NULL)
    {
        if (buffer)
        {
            FREE(buffer);
            buffer = NULL;
        }
        return NOT_ENOUGH_MEMORY_FOR_VECTOR;
    }
    /* Main loop */
    LOOP_PCRE_TST = FALSE;
    while (!LOOP_PCRE_TST)
    {
        pcre *re = NULL;
        pcre_extra *extra = NULL;
        const char *error = NULL;
        char *back_p = NULL;
        char *p = NULL;
        char *pp = NULL;
        char *ppp = NULL;
        const unsigned char *tables = NULL;
        int do_G = 0;
        int do_g = 0;
        int erroroffset = 0, len = 0, delimiter;

        LOOP_PCRE_TST = TRUE;
        p = os_strdup(INPUT_PAT);
        back_p = p;
        while (isspace(*p))
        {
            p++;
        }
        if (*p == 0)
        {
            continue;
        }
        /* In-line pattern (the usual case). Get the delimiter and seek the end of
        the pattern; if is isn't complete, read more. */

        delimiter = *p++;

        if (isalnum(delimiter) || delimiter == '\\')
        {
            if (buffer)
            {
                FREE(buffer);
                buffer = NULL;
            }
            if (offsets)
            {
                FREE(offsets);
                offsets = NULL;
            }
            if (back_p)
            {
                FREE(back_p);
                back_p = NULL;
            }
            return DELIMITER_NOT_ALPHANUMERIC;
        }

        pp = p;

        while (*pp != 0)
        {
            if (*pp == '\\' && pp[1] != 0)
            {
                pp++;
            }
            else if (*pp == delimiter)
            {
                break;
            }
            pp++;
        }

        /* If the delimiter can't be found, it's a syntax error */
        if (*pp == 0)
        {
            if (buffer)
            {
                FREE(buffer);
                buffer = NULL;
            }
            if (offsets)
            {
                FREE(offsets);
                offsets = NULL;
            }
            if (back_p)
            {
                FREE(back_p);
                back_p = NULL;
            }
            if (offsets)
            {
                FREE(offsets);
            }
            return CAN_NOT_COMPILE_PATTERN;
        }

        /* If the first character after the delimiter is backslash, make
        the pattern end with backslash. This is purely to provide a way
        of testing for the error message when a pattern ends with backslash. */

        if (pp[1] == '\\')
        {
            *pp++ = '\\';
        }

        /* Terminate the pattern at the delimiter, and save a copy of the pattern
        for callouts. */

        *pp++ = 0;

        /* Look for options after final delimiter */

        //options = 8192;

        while (*pp != 0)
        {
            switch (*pp++)
            {
                case 'f':
                    options |= PCRE_FIRSTLINE;
                    break;
                case 'g':
                    do_g = 1;
                    break;
                case 'i':
                    options |= PCRE_CASELESS;
                    break;
                case 'm':
                    options |= PCRE_MULTILINE;
                    break;
                case 's':
                    options |= PCRE_DOTALL;
                    break;
                case 'x':
                    options |= PCRE_EXTENDED;
                    break;
                case '+':
                    break;
                case 'A':
                    options |= PCRE_ANCHORED;
                    break;
                case 'B':
                    break;
                case 'C':
                    options |= PCRE_AUTO_CALLOUT;
                    break;
                case 'D':
                    break;
                case 'E':
                    options |= PCRE_DOLLAR_ENDONLY;
                    break;
                case 'F':
                    break;
                case 'G':
                    do_G = 1;
                    break;
                case 'I':
                    break;
                case 'J':
                    options |= PCRE_DUPNAMES;
                    break;
                case 'M':
                    break;
                case 'N':
                    options |= PCRE_NO_AUTO_CAPTURE;
                    break;
                case 'S':
                    break;
                case 'U':
                    options |= PCRE_UNGREEDY;
                    break;
                case 'X':
                    options |= PCRE_EXTRA;
                    break;
                case 'Z':
                    break;
                case '8':
                {
                    int rc = 0;
                    (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
                    if (rc != 1)
                    {
                        if (buffer)
                        {
                            FREE(buffer);
                            buffer = NULL;
                        }
                        if (offsets)
                        {
                            FREE(offsets);
                        }
                        return UTF8_NOT_SUPPORTED;
                    }
                    options |= PCRE_UTF8;
                }
                break;
                case '?':
                    options |= PCRE_NO_UTF8_CHECK;
                    break;
                case 'L':
                    ppp = pp;
                    /* The '\r' test here is so that it works on Windows. */
                    /* The '0' test is just in case this is an unterminated line. */
                    while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ')
                    {
                        ppp++;
                    }
                    *ppp = 0;
                    if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
                    {
                        goto SKIP_DATA;
                    }

                    tables = pcre_maketables();
                    pp = ppp;
                    break;
                case '>':
                    while (*pp != 0)
                    {
                        pp++;
                    }
                    while (isspace(pp[-1]))
                    {
                        pp--;
                    }
                    *pp = 0;
                    break;
                case '<':
                {
                    while (*pp++ != '>')
                    {
                        ;
                    }
                }
                break;
                case '\r':                      /* So that it works in Windows */
                case '\n':
                case ' ':
                    break;

                default:
                    goto SKIP_DATA;
            }
        }

        /* Handle compiling via the POSIX interface, which doesn't support the
        timing, showing, or debugging options, nor the ability to pass over
        local character tables. */


        {
            re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
            /* Compilation failed; go back for another re, skipping to blank line
            if non-interactive. */
            if (re == NULL)
            {
SKIP_DATA:
                if (buffer)
                {
                    FREE(buffer);
                    buffer = NULL;
                }
                if (offsets)
                {
                    FREE(offsets);
                    offsets = NULL;
                }
                if (tables)
                {
                    (*pcre_free)((void*)tables);
                    tables = NULL;
                }
                if (extra)
                {
                    FREE(extra);
                    extra = NULL;
                }
                if (back_p)
                {
                    FREE(back_p);
                    back_p = NULL;
                }
                return CAN_NOT_COMPILE_PATTERN;
            }

        }        /* End of non-POSIX compile */

        /* Read data lines and test them */
        {
            char *q = NULL;
            char *bptr = NULL;
            int *use_offsets = offsets;
            int use_size_offsets = size_offsets;
            int callout_data = 0;
            int callout_data_set = 0;
            int count = 0;
            int c = 0;
            int copystrings = 0;
            int find_match_limit = 0;
            int getstrings = 0;
            int gmatched = 0;
            int start_offset = 0;
            int g_notempty = 0;
            int use_dfa = 0;

            options = 0;
            *copynames = 0;
            *getnames = 0;

            copynamesptr = copynames;
            getnamesptr = getnames;

            callout_count = 0;
            callout_fail_count = 999999;
            callout_fail_id = -1;

            if (extra != NULL)
            {
                extra->flags &= ~(PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION);
            }
            p = buffer;
            bptr = q = buffer;
            while ((c = *p++) != 0)
            {
                int i = 0;
                int n = 0;

                if (c == '\\') switch ((c = *p++))
                    {
                        case 'a':
                            c =    7;
                            break;
                        case 'b':
                            c = '\b';
                            break;
                        case 'e':
                            c =   27;
                            break;
                        case 'f':
                            c = '\f';
                            break;
                        case 'n':
                            c = '\n';
                            break;
                        case 'r':
                            c = '\r';
                            break;
                        case 't':
                            c = '\t';
                            break;
                        case 'v':
                            c = '\v';
                            break;
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                            c -= '0';
                            while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
                            {
                                c = c * 8 + *p++ - '0';
                            }
                            break;
                        case 'x':
                            /* Ordinary \x */
                            c = 0;
                            while (i++ < 2 && isxdigit(*p))
                            {
                                c = c * 16 + tolower(*p) - ((isdigit(*p)) ? '0' : 'W');
                                p++;
                            }
                            break;
                        case 0:   /* \ followed by EOF allows for an empty line */
                            p--;
                            continue;
                        case '>':
                            while (isdigit(*p))
                            {
                                start_offset = start_offset * 10 + *p++ - '0';
                            }
                            continue;
                        case 'A':  /* Option setting */
                            options |= PCRE_ANCHORED;
                            continue;
                        case 'B':
                            options |= PCRE_NOTBOL;
                            continue;
                        case 'C':
                            if (isdigit(*p))    /* Set copy string */
                            {
                                while (isdigit(*p))
                                {
                                    n = n * 10 + *p++ - '0';
                                }
                                copystrings |= 1 << n;
                            }
                            else if (isalnum(*p))
                            {
                                char *npp = copynamesptr;
                                while (isalnum(*p))
                                {
                                    *npp++ = *p++;
                                }
                                *npp++ = 0;
                                *npp = 0;
                                pcre_get_stringnumber(re, (char *)copynamesptr);
                                copynamesptr = npp;
                            }
                            else if (*p == '+')
                            {
                                p++;
                            }
                            else if (*p == '-')
                            {
                                p++;
                            }
                            else if (*p == '!')
                            {
                                callout_fail_id = 0;
                                p++;
                                while (isdigit(*p))
                                {
                                    callout_fail_id = callout_fail_id * 10 + *p++ - '0';
                                }
                                callout_fail_count = 0;
                                if (*p == '!')
                                {
                                    p++;
                                    while (isdigit(*p))
                                    {
                                        callout_fail_count = callout_fail_count * 10 + *p++ - '0';
                                    }
                                }
                            }
                            else if (*p == '*')
                            {
                                int sign = 1;
                                callout_data = 0;
                                if (*(++p) == '-')
                                {
                                    sign = -1;
                                    p++;
                                }
                                while (isdigit(*p))
                                {
                                    callout_data = callout_data * 10 + *p++ - '0';
                                }
                                callout_data *= sign;
                                callout_data_set = 1;
                            }
                            continue;
                        case 'G':
                            if (isdigit(*p))
                            {
                                while (isdigit(*p))
                                {
                                    n = n * 10 + *p++ - '0';
                                }
                                getstrings |= 1 << n;
                            }
                            else if (isalnum(*p))
                            {
                                char *npp = getnamesptr;
                                while (isalnum(*p))
                                {
                                    *npp++ = *p++;
                                }
                                *npp++ = 0;
                                *npp = 0;
                                pcre_get_stringnumber(re, (char *)getnamesptr);
                                getnamesptr = npp;
                            }
                            continue;
                        case 'L':
                            continue;
                        case 'M':
                            find_match_limit = 1;
                            continue;
                        case 'N':
                            options |= PCRE_NOTEMPTY;
                            continue;
                        case 'O':
                            while (isdigit(*p))
                            {
                                n = n * 10 + *p++ - '0';
                            }
                            if (n > size_offsets_max)
                            {
                                size_offsets_max = n;
                                if (offsets)
                                {
                                    FREE(offsets);
                                }
                                use_offsets = offsets = (int *)MALLOC(size_offsets_max * sizeof(int));
                            }
                            use_size_offsets = n;
                            if (n == 0)
                            {
                                use_offsets = NULL;    /* Ensures it can't write to it */
                            }
                            continue;
                        case 'P':
                            options |= PCRE_PARTIAL;
                            continue;
                        case 'Q':
                            while (isdigit(*p))
                            {
                                n = n * 10 + *p++ - '0';
                            }
                            if (extra == NULL)
                            {
                                extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                                extra->flags = 0;
                            }
                            extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
                            extra->match_limit_recursion = n;
                            continue;
                        case 'q':
                            while (isdigit(*p))
                            {
                                n = n * 10 + *p++ - '0';
                            }
                            if (extra == NULL)
                            {
                                extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                                extra->flags = 0;
                            }
                            extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
                            extra->match_limit = n;
                            continue;
#if !defined NODFA
                        case 'R':
                            options |= PCRE_DFA_RESTART;
                            continue;
#endif
                        case 'S':

                            continue;
                        case 'Z':
                            options |= PCRE_NOTEOL;
                            continue;
                        case '?':
                            options |= PCRE_NO_UTF8_CHECK;
                            continue;
                        case '<':
                        {
                            while (*p++ != '>')
                            {
                                ;
                            }
                        }
                        continue;
                    }
                *q++ = (char)c;
            }
            *q = 0;
            len = (int)(q - buffer);
            if ((all_use_dfa || use_dfa) && find_match_limit)
            {
                if (buffer)
                {
                    FREE(buffer);
                    buffer = NULL;
                }
                if (offsets)
                {
                    FREE(offsets);
                    offsets = NULL;
                }
                if (p)
                {
                    FREE(p);
                    p = NULL;
                }
                if (re)
                {
                    (*pcre_free)(re);
                    re = NULL;
                }
                if (tables)
                {
                    (*pcre_free)((void*)tables);
                    tables = NULL;
                }
                if (extra)
                {
                    FREE(extra);
                    extra = NULL;
                }
                return LIMIT_NOT_RELEVANT_FOR_DFA_MATCHING;
            }
            /* Handle matching via the POSIX interface, which does not
            support timing or playing with the match limit or callout data. */
            for (;; gmatched++)    /* Loop for /g or /G */
            {

                /* If find_match_limit is set, we want to do repeated matches with
                varying limits in order to find the minimum value for the match limit and
                for the recursion limit. */

                if (find_match_limit)
                {
                    if (extra == NULL)
                    {
                        extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                        extra->flags = 0;
                    }

                    (void)check_match_limit(re, extra, bptr, len, start_offset,
                                            options | g_notempty, use_offsets, use_size_offsets,
                                            PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
                                            PCRE_ERROR_MATCHLIMIT);

                    count = check_match_limit(re, extra, bptr, len, start_offset,
                                              options | g_notempty, use_offsets, use_size_offsets,
                                              PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion),
                                              PCRE_ERROR_RECURSIONLIMIT);
                }
                /* If callout_data is set, use the interface with additional data */
                else if (callout_data_set)
                {
                    if (extra == NULL)
                    {
                        extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                        extra->flags = 0;
                    }
                    extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
                    extra->callout_data = &callout_data;
                    count = pcre_exec(re, extra, (char *)bptr, len, start_offset,
                                      options | g_notempty, use_offsets, use_size_offsets);

                    extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
                }
                /* The normal case is just to do the match once, with the default
                value of match_limit. */
                else
                {
                    count = pcre_exec(re, extra, (char *)bptr, len,
                                      start_offset, options | g_notempty, use_offsets, use_size_offsets);
                    if (count == 0)
                    {
                        count = use_size_offsets / 3;
                    }

                    //to retrieve backref count and values
                    if (count > 0 && _pstCapturedString != NULL && _piCapturedStringCount != NULL)
                    {
                        int i = 0;
                        int iErr = 0;

                        iErr = pcre_fullinfo(re, extra, PCRE_INFO_CAPTURECOUNT, _piCapturedStringCount);
                        //sciprint("PCRE_INFO_CAPTURECOUNT %d\n", *_piCapturedStringCount);

                        if (*_piCapturedStringCount > 0)
                        {
                            *_pstCapturedString = (char**)MALLOC(sizeof(char*) * *_piCapturedStringCount);
                            for (i = 0 ; i < *_piCapturedStringCount ; i++)
                            {
                                const char* pstSubstring = NULL;
                                pcre_get_substring(bptr, use_offsets, count, i + 1, &pstSubstring);
                                if (pstSubstring != NULL)
                                {
                                    (*_pstCapturedString)[i] = os_strdup(pstSubstring);
                                }
                                else
                                {
                                    //empty string is matching, so create it
                                    (*_pstCapturedString)[i] = os_strdup("");
                                }

                                pcre_free_substring(pstSubstring);
                            }
                        }
                    }
                }
                /* Matched */
                if (count >= 0)
                {
                    int i, maxcount;
                    maxcount = use_size_offsets / 3;
                    /* This is a check against a lunatic return value. */
                    if (count > maxcount)
                    {
                        if (buffer)
                        {
                            FREE(buffer);
                            buffer = NULL;
                        }
                        if (offsets)
                        {
                            FREE(offsets);
                            offsets = NULL;
                        }
                        if (re)
                        {
                            (*pcre_free)(re);
                            re = NULL;
                        }
                        if (tables)
                        {
                            (*pcre_free)((void*)tables);
                            tables = NULL;
                        }
                        if (extra)
                        {
                            FREE(extra);
                            extra = NULL;
                        }
                        if (back_p)
                        {
                            FREE(back_p);
                            back_p = NULL;
                        }
                        return TOO_BIG_FOR_OFFSET_SIZE;
                    }

                    for (i = 0; i < count * 2; i += 2)
                    {
                        if (use_offsets[i] >= 0)
                        {
                            *Output_Start = use_offsets[i];
                            *Output_End = use_offsets[i + 1];
                            if (buffer)
                            {
                                FREE(buffer);
                            }

                            /* use_offsets = offsets no need to free use_offsets if we free offsets */
                            if (offsets)
                            {
                                FREE(offsets);
                            }

                            /* "re" allocated by pcre_compile (better to use free function associated)*/
                            if (re)
                            {
                                (*pcre_free)(re);
                            }

                            if (extra)
                            {
                                FREE(extra);
                            }
                            if (tables)
                            {
                                /* "tables" allocated by pcre_maketables (better to use free function associated to pcre)*/
                                (*pcre_free)((void *)tables);
                                tables = NULL;
                                setlocale(LC_CTYPE, "C");
                            }

                            if (back_p)
                            {
                                FREE(back_p);
                                back_p = NULL;
                            }
                            return PCRE_FINISHED_OK;
                        }
                    }

                    for (copynamesptr = copynames; *copynamesptr != 0; copynamesptr += (int)strlen((char*)copynamesptr) + 1)
                    {
                        char copybuffer[256];
                        pcre_copy_named_substring(re, (char *)bptr, use_offsets, count, (char *)copynamesptr, copybuffer, sizeof(copybuffer));
                    }

                    for (i = 0; i < 32; i++)
                    {
                        if ((getstrings & (1 << i)) != 0)
                        {
                            const char *substring;
                            pcre_get_substring((char *)bptr, use_offsets, count, i, &substring);
                        }
                    }

                    for (getnamesptr = getnames; *getnamesptr != 0; getnamesptr += (int)strlen((char*)getnamesptr) + 1)
                    {
                        const char *substring;
                        pcre_get_named_substring(re, (char *)bptr, use_offsets, count, (char *)getnamesptr, &substring);
                    }

                }
                /* Failed to match. If this is a /g or /G loop and we previously set
                g_notempty after a null match, this is not necessarily the end. We want
                to advance the start offset, and continue. We won't be at the end of the
                string - that was checked before setting g_notempty.
                Complication arises in the case when the newline option is "any" or
                "anycrlf". If the previous match was at the end of a line terminated by
                CRLF, an advance of one character just passes the \r, whereas we should
                prefer the longer newline sequence, as does the code in pcre_exec().
                Fudge the offset value to achieve this.

                Otherwise, in the case of UTF-8 matching, the advance must be one
                character, not one byte. */
                else
                {
                    if (count == PCRE_ERROR_NOMATCH)
                    {
                        if (gmatched == 0)
                        {
                            if (tables)
                            {
                                (*pcre_free)((void *)tables);
                                tables = NULL;
                            }
                            if (re)
                            {
                                (*pcre_free)((void *)re);
                                re = NULL;
                            }
                            if (buffer)
                            {
                                FREE(buffer);
                                buffer = NULL;
                            }
                            if (offsets)
                            {
                                FREE(offsets);
                            }
                            if (p)
                            {
                                FREE(back_p);
                                back_p = NULL;
                            }
                            return NO_MATCH;
                        }
                    }

                    if (count == PCRE_ERROR_MATCHLIMIT )
                    {
                        if (tables)
                        {
                            (*pcre_free)((void *)tables);
                            tables = NULL;
                        }
                        if (re)
                        {
                            (*pcre_free)((void *)re);
                            re = NULL;
                        }
                        if (buffer)
                        {
                            FREE(buffer);
                            buffer = NULL;
                        }
                        if (offsets)
                        {
                            FREE(offsets);
                            offsets = NULL;
                        }
                        if (back_p)
                        {
                            FREE(back_p);
                            back_p = NULL;
                        }
                        return MATCH_LIMIT;
                    }
                    break;  /* Out of loop */
                }

                /* If not /g or /G we are done */
                if (!do_g && !do_G)
                {
                    break;
                }

                /* If we have matched an empty string, first check to see if we are at
                the end of the subject. If so, the /g loop is over. Otherwise, mimic
                what Perl's /g options does. This turns out to be rather cunning. First
                we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the
                same point. If this fails (picked up above) we advance to the next
                character. */

                g_notempty = 0;

                if (use_offsets[0] == use_offsets[1])
                {
                    if (use_offsets[0] == len)
                    {
                        break;
                    }
                    g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;
                }

                /* For /g, update the start offset, leaving the rest alone */

                if (do_g)
                {
                    start_offset = use_offsets[1];
                }
                /* For /G, update the pointer and length */
                else
                {
                    bptr += use_offsets[1];
                    len -= use_offsets[1];
                }
            }  /* End of loop for /g and /G */

            if (re)
            {
                (*pcre_free)(re);
                re = NULL;
            }
            if (extra)
            {
                FREE(extra);
                extra = NULL;
            }
            if (tables)
            {
                (*pcre_free)((void *)tables);
                tables = NULL;
            }

            FREE(back_p);
            back_p = NULL;
            continue;
        }    /* End of loop for data lines */
    }

    if (buffer)
    {
        FREE(buffer);
        buffer = NULL;
    }
    if (offsets)
    {
        FREE(offsets);
        offsets = NULL;
    }

    return PCRE_EXIT;
}