Beispiel #1
0
/* return each comma separated token, one at a time */
CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list,
                                           const char **str)
{
    apr_size_t i;
    const char *s;

    s = ap_strchr_c(list, ',');
    if (s != NULL) {
        i = s - list;
        do
            s++;
        while (apr_isspace(*s))
            ; /* noop */
    }
    else
        i = strlen(list);

    while (i > 0 && apr_isspace(list[i - 1]))
        i--;

    *str = s;
    if (i)
        return apr_pstrndup(p, list, i);
    else
        return NULL;
}
static int nextarg(apr_pool_t *p, const char *val, char **arg)
{
    char quote;
    int pos=0;
    char *tmp= (char*)apr_pstrdup(p, val);
    while (apr_isspace(*tmp)) {
        ++tmp;
        ++pos;
    }
    quote = (*tmp == '"' || *tmp == '\'') ? *tmp++ : '\0';
    *arg = tmp;
    for (; *tmp; ++tmp && ++pos ) {
        if ((apr_isspace(*tmp) && !quote) || (*tmp == quote)) {
            break;
        }
        if (*tmp == '\\' && apr_isspace(tmp[1])) {
            ++tmp;
            ++pos;
            continue;
        }
    }
    if (!*tmp) {
        return 0;
    }
    *tmp++ = '\0';
    pos++;
    return pos;
}
Beispiel #3
0
static void pm_norepeat_config(nx_module_t *module)
{
    const nx_directive_t *curr;
    nx_pm_norepeat_conf_t *modconf;
    const char *start, *ptr, *end;
    char *field = NULL;
    apr_size_t len;

    modconf = apr_pcalloc(module->pool, sizeof(nx_pm_norepeat_conf_t));
    module->config = modconf;

    curr = module->directives;
    while ( curr != NULL )
    {
	if ( nx_module_common_keyword(curr->directive) == TRUE )
	{
	}
	else if ( strcasecmp(curr->directive, "CheckFields") == 0 )
	{
	    if ( modconf->fields != NULL )
	    {
		nx_conf_error(curr, "CheckFields already defined");
	    }
	    ptr = curr->args;
	    for ( ; (ptr != NULL) && apr_isspace(*ptr); (ptr)++ );
	    if ( (curr->args == NULL) || (strlen(ptr) == 0) )
	    {
		nx_conf_error(curr, "value missing for CheckFields");
	    }
	    end = ptr + strlen(ptr);
	    modconf->fields = apr_array_make(module->pool, 5, sizeof(const char *));
	    while ( *ptr != '\0' )
	    {
		start = ptr;
		for ( ; !((*ptr == '\0') || apr_isspace(*ptr) || (*ptr == ',')); ptr++ );
		if ( ptr > start )
		{
		    len = (apr_size_t) (ptr - start + 1);
		    field = apr_palloc(module->pool, len);
		    apr_cpystrn(field, start, len);
		}
		*((const char **) apr_array_push(modconf->fields)) = field;
		for ( ; apr_isspace(*ptr) || (*ptr == ','); ptr++ );
	    }
	}
	else
	{
	    nx_conf_error(curr, "invalid pm_norepeat keyword: %s", curr->directive);
	}
	curr = curr->next;
    }

    modconf->pid = (int) getpid();
}
Beispiel #4
0
/*
  little helper function to get the original request path
  code borrowed from request.c and util_script.c
*/
static const char *ap_xsendfile_get_orginal_path(request_rec *rec) {
  const char
    *rv = rec->the_request,
    *last;

  int dir = 0;
  size_t uri_len;

  /* skip method && spaces */
  while (*rv && !apr_isspace(*rv)) {
    ++rv;
  }
  while (apr_isspace(*rv)) {
    ++rv;
  }
  /* first space is the request end */
  last = rv;
  while (*last && !apr_isspace(*last)) {
    ++last;
  }
  uri_len = last - rv;
  if (!uri_len) {
    return NULL;
  }

  /* alright, lets see if the request_uri changed! */
  if (strncmp(rv, rec->uri, uri_len) == 0) {
    rv = apr_pstrdup(rec->pool, rec->filename);
    dir = rec->finfo.filetype == APR_DIR;
  }
  else {
    /* need to lookup the url again as it changed */
    request_rec *sr = ap_sub_req_lookup_uri(
      apr_pstrmemdup(rec->pool, rv, uri_len),
      rec,
      NULL
      );
    if (!sr) {
      return NULL;
    }
    rv = apr_pstrdup(rec->pool, sr->filename);
    dir = rec->finfo.filetype == APR_DIR;
    ap_destroy_sub_req(sr);
  }

  /* now we need to truncate so we only have the directory */
  if (!dir && (last = ap_strrchr(rv, '/')) != NULL) {
    *((char*)last + 1) = '\0';
  }
  return rv;
}
Beispiel #5
0
/* Remove leading and trailing white space from a C string, in place. */
static void
trim_string(char **pstr)
{
  char *str = *pstr;
  int i;

  while (apr_isspace(*str))
    str++;
  *pstr = str;
  i = strlen(str);
  while ((i > 0) && apr_isspace(str[i-1]))
    i--;
  str[i] = '\0';
}
Beispiel #6
0
static int strnatcmp0(char const *a, char const *b, int fold_case)
{
     int ai, bi;
     char ca, cb;
     int fractional, result;
     ai = bi = 0;
     while (1) {
	  ca = a[ai]; cb = b[bi];

	  /* skip over leading spaces or zeros */
	  while (apr_isspace(ca))
	       ca = a[++ai];

	  while (apr_isspace(cb))
	       cb = b[++bi];

	  /* process run of digits */
	  if (apr_isdigit(ca)  &&  apr_isdigit(cb)) {
	       fractional = (ca == '0' || cb == '0');

	       if (fractional) {
		    if ((result = compare_left(a+ai, b+bi)) != 0)
			 return result;
	       } else {
		    if ((result = compare_right(a+ai, b+bi)) != 0)
			 return result;
	       }
	  }

	  if (!ca && !cb) {
	       /* The strings compare the same.  Perhaps the caller
                  will want to call strcmp to break the tie. */
	       return 0;
	  }

	  if (fold_case) {
	       ca = apr_toupper(ca);
	       cb = apr_toupper(cb);
	  }

	  if (ca < cb)
	       return -1;
	  else if (ca > cb)
	       return +1;

	  ++ai; ++bi;
     }
}
Beispiel #7
0
/*
 * get the authorization header that should contain a bearer token
 */
static apr_byte_t oidc_oauth_get_bearer_token(request_rec *r,
		const char **access_token) {

	/* get the authorization header */
	const char *auth_line;
	auth_line = apr_table_get(r->headers_in, "Authorization");
	if (!auth_line) {
		oidc_debug(r, "no authorization header found");
		return FALSE;
	}

	/* look for the Bearer keyword */
	if (apr_strnatcasecmp(ap_getword(r->pool, &auth_line, ' '), "Bearer")) {
		oidc_error(r, "client used unsupported authentication scheme: %s",
				r->uri);
		return FALSE;
	}

	/* skip any spaces after the Bearer keyword */
	while (apr_isspace(*auth_line)) {
		auth_line++;
	}

	/* copy the result in to the access_token */
	*access_token = apr_pstrdup(r->pool, auth_line);

	/* log some stuff */
	oidc_debug(r, "bearer token: %s", *access_token);

	return TRUE;
}
Beispiel #8
0
/**
 * find certain header line, return copy of first part (up to first ";")
 * @param p pool to allocate from
 * @param name name of the header
 * @param string input: pointer to pointer string where to find the header;
 *        output: pointer to the ";" or "\n" after the copied value
 * @param end pointer where to stop searching
 * @note string must be NUL-terminated (but the NUL may be after *end)
 * @return copy of the header value or NULL if not found
 */
static char *mbox_mime_get_header(apr_pool_t *p, const char *name,
                                  char **string, const char *end)
{
    char *ptr;
    int namelen = strlen(name);
    for (ptr = *string;
         ptr && *ptr && ptr < end ;
         ptr = ap_strchr(ptr + 1, '\n') + 1)
    {
        int l;
        if (strncasecmp(ptr, name, namelen) != 0)
            continue;
        ptr += namelen;
        if (*ptr != ':')
            continue;
        ptr++;
        while (*ptr == ' ')
            ptr++;
        if (ptr >= end)
            break;
        l = strcspn(ptr, ";\n");
        *string = ptr + l;
        while (apr_isspace(ptr[l]) && l > 0)
            l--;
        return apr_pstrndup(p, ptr, l);
    }
    return NULL;
}
Beispiel #9
0
static const char *
set_redirect_min_size(cmd_parms *cmd, void *config, const char *size_str)
{
    aclr_dir_config *cfg = (aclr_dir_config *)config;
    char *endptr;
    long size;

    size = strtol(size_str, &endptr, 10);
    while (apr_isspace(*endptr)) endptr++;
    if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
        ;
    }
    else if (*endptr == 'k' || *endptr == 'K') {
        size *= 1024;
    }
    else if (*endptr == 'm' || *endptr == 'M') {
        size *= 1048576;
    }
    else {
        return apr_pstrcat(cmd->pool, "Invalid size in AccelRedirectSize: ",
                           size_str, NULL);
    }

    cfg->fsize = (size >= 0) ? size : UNSET;
    return NULL;
}
static apr_status_t parse_status_line(response_context_t *ctx,
                                      serf_bucket_alloc_t *allocator)
{
    int res;
    char *reason; /* ### stupid APR interface makes this non-const */

    /* ctx->linebuf.line should be of form: HTTP/1.1 200 OK */
    res = apr_date_checkmask(ctx->linebuf.line, "HTTP/#.# ###*");
    if (!res) {
        /* Not an HTTP response?  Well, at least we won't understand it. */
        return SERF_ERROR_BAD_HTTP_RESPONSE;
    }

    ctx->sl.version = SERF_HTTP_VERSION(ctx->linebuf.line[5] - '0',
                                        ctx->linebuf.line[7] - '0');
    ctx->sl.code = apr_strtoi64(ctx->linebuf.line + 8, &reason, 10);

    /* Skip leading spaces for the reason string. */
    if (apr_isspace(*reason)) {
        reason++;
    }

    /* Copy the reason value out of the line buffer. */
    ctx->sl.reason = serf_bstrmemdup(allocator, reason,
                                     ctx->linebuf.used
                                     - (reason - ctx->linebuf.line));

    return APR_SUCCESS;
}
Beispiel #11
0
/*
 * Strips all of the RE: junk from the subject line.
 */
static char *strip_subject(apr_pool_t *p, Message *m)
{
    char *newVal, *match = m->subject, *tmp = NULL;

    /* Match the following cases: Re:, RE:, RE[1]:, Re: Re[2]: Re: */
    while (match && *match) {
        /* When we don't have a match, tmp contains the "real" subject. */
        tmp = newVal = match;
        match = NULL;
        if (*newVal == 'R' && (*++newVal == 'e' || *newVal == 'E')) {
            /* Note to self.  In pure compressed syntax, the famous dangling
             * else occurs.  Oh, well. */
            if (*++newVal == '[') {
                while (apr_isdigit(*++newVal)) {
                }
                if (*++newVal == ']' && *++newVal == ':')
                    match = ++newVal;
            }
            else if (*newVal == ':')
                match = ++newVal;
        }

        if (match)
            while (apr_isspace(*match))
                match++;
    }

    return apr_pstrdup(p, tmp);
}
Beispiel #12
0
static void fill_gmi(Ganglia_25metric* gmi, py_metric_init_t* minfo)
{
    char *s, *lasts;
    int i;
    const apr_array_header_t *arr = apr_table_elts(minfo->extra_data);
    const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts;

    /* gmi->key will be automatically assigned by gmond */
    gmi->name = apr_pstrdup (pool, minfo->mname);
    gmi->tmax = minfo->tmax;
    if (!strcasecmp(minfo->vtype, "string")) {
        gmi->type = GANGLIA_VALUE_STRING;
        gmi->msg_size = UDP_HEADER_SIZE+MAX_G_STRING_SIZE;
    }
    else if (!strcasecmp(minfo->vtype, "uint")) {
        gmi->type = GANGLIA_VALUE_UNSIGNED_INT;
        gmi->msg_size = UDP_HEADER_SIZE+8;
    }
    else if (!strcasecmp(minfo->vtype, "int")) {
        gmi->type = GANGLIA_VALUE_INT;
        gmi->msg_size = UDP_HEADER_SIZE+8;
    }
    else if (!strcasecmp(minfo->vtype, "float")) {
        gmi->type = GANGLIA_VALUE_FLOAT;
        gmi->msg_size = UDP_HEADER_SIZE+8;
    }
    else if (!strcasecmp(minfo->vtype, "double")) {
        gmi->type = GANGLIA_VALUE_DOUBLE;
        gmi->msg_size = UDP_HEADER_SIZE+16;
    }
    else {
        gmi->type = GANGLIA_VALUE_UNKNOWN;
        gmi->msg_size = UDP_HEADER_SIZE+8;
    }

    gmi->units = apr_pstrdup(pool, minfo->units);
    gmi->slope = apr_pstrdup(pool, minfo->slope);
    gmi->fmt = apr_pstrdup(pool, minfo->format);
    gmi->desc = apr_pstrdup(pool, minfo->desc);

    MMETRIC_INIT_METADATA(gmi, pool);
    for (s=(char *)apr_strtok(minfo->groups, ",", &lasts);
          s!=NULL; s=(char *)apr_strtok(NULL, ",", &lasts)) {
        char *d = s;
        /* Strip the leading white space */
        while (d && *d && apr_isspace(*d)) {
            d++;
        }
        MMETRIC_ADD_METADATA(gmi,MGROUP,d);
    }

    /* transfer any extra data as metric metadata */
    for (i = 0; i < arr->nelts; ++i) {
        if (elts[i].key == NULL)
            continue;
        MMETRIC_ADD_METADATA(gmi, elts[i].key, elts[i].val);
    }
}
static int clear_conn_headers(void *data, const char *key, const char *val)
{
    apr_table_t *headers = ((header_dptr*)data)->table;
    apr_pool_t *pool = ((header_dptr*)data)->pool;
    const char *name;
    char *next = apr_pstrdup(pool, val);
    while (*next) {
        name = next;
        while (*next && !apr_isspace(*next) && (*next != ',')) {
            ++next;
        }
        while (*next && (apr_isspace(*next) || (*next == ','))) {
            *next++ = '\0';
        }
        apr_table_unset(headers, name);
    }
    return 1;
}
Beispiel #14
0
/* Iterate through the cookies, isolate our cookie and then remove it.
 *
 * If our cookie appears two or more times, but with different values,
 * remove it twice and set the duplicated flag to true. Remove any
 * $path or other attributes following our cookie if present. If we end
 * up with an empty cookie, remove the whole header.
 */
static int extract_cookie_line(ap_cookie_do * v, const char *key, const char *val)
{
    char *last1, *last2;
    char *cookie = apr_pstrdup(v->r->pool, val);
    const char *name = apr_pstrcat(v->r->pool, v->name ? v->name : "", "=", NULL);
    apr_size_t len = strlen(name);
    const char *new_cookie = "";
    const char *comma = ",";
    char *next1;
    const char *semi = ";";
    char *next2;
    const char *sep = "";
    int cookies = 0;

    /* find the cookie called name */
    int eat = 0;
    next1 = apr_strtok(cookie, comma, &last1);
    while (next1) {
        next2 = apr_strtok(next1, semi, &last2);
        while (next2) {
            char *trim = next2;
            while (apr_isspace(*trim)) {
                trim++;
            }
            if (!strncmp(trim, name, len)) {
                if (v->encoded) {
                    if (strcmp(v->encoded, trim + len)) {
                        v->duplicated = 1;
                    }
                }
                v->encoded = apr_pstrdup(v->r->pool, trim + len);
                eat = 1;
            }
            else {
                if (*trim != '$') {
                    cookies++;
                    eat = 0;
                }
                if (!eat) {
                    new_cookie = apr_pstrcat(v->r->pool, new_cookie, sep, next2, NULL);
                }
            }
            next2 = apr_strtok(NULL, semi, &last2);
            sep = semi;
        }

        next1 = apr_strtok(NULL, comma, &last1);
        sep = comma;
    }

    /* any cookies left over? */
    if (cookies) {
        apr_table_addn(v->new_cookies, key, new_cookie);
    }

    return 1;
}
Beispiel #15
0
/* length of dest assumed >= length of src
 * collapse in place (src == dest) is legal.
 * returns terminating null ptr to dest string.
 */
APR_DECLARE(char *) apr_collapse_spaces(char *dest, const char *src)
{
    while (*src) {
        if (!apr_isspace(*src)) 
            *dest++ = *src;
        ++src;
    }
    *dest = 0;
    return (dest);
}
Beispiel #16
0
AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line) {

    const char *str = *line, *strend;
    char *res;
    char quote;

    while (*str && apr_isspace(*str))
        ++str;

    if (!*str) {
        *line = str;
        return "";
    }

    if ((quote = *str) == '"' || quote == '\'') {
        strend = str + 1;
        while (*strend && *strend != quote) {
            if (*strend == '\\' && strend[1] &&
                (strend[1] == quote || strend[1] == '\\')) {
                strend += 2;
            }
            else {
                ++strend;
            }
        }
        res = substring_conf(p, str + 1, strend - str - 1, quote);

        if (*strend == quote)
            ++strend;
    }
    else {
        strend = str;
        while (*strend && !apr_isspace(*strend))
            ++strend;

        res = substring_conf(p, str, strend - str, 0);
    }

    while (*strend && apr_isspace(*strend))
        ++strend;
    *line = strend;
    return res;
}
Beispiel #17
0
apr_int32_t util_timestring_to_seconds(char *string)
{
	
	char *character;
	apr_int32_t number = 0;

	if (string == NULL)		
		return 0;

	character = string;
	
	/* calculate number */
	while (apr_isdigit(*character) || apr_isspace(*character)) {
		if (apr_isdigit(*character)) {
			/* translate to number */
			unsigned digit = (unsigned) *character - (unsigned) '0';
			ap_assert(digit < 10);
			number = (number * (apr_int32_t) 10) + (apr_int32_t) digit; 
		}
		character += 1;
	}
	
	if (*character != '\0') {
		switch(*character) {
			case 'w':
			case 'W':
				number = number * SECONDS_IN_WEEK;
				break;
			case 'd':
			case 'D':
				number = number * SECONDS_IN_DAY;
				break;
			case 'h':
			case 'H':
				number = number * SECONDS_IN_HOUR;
				break;
			case 'm':
			case 'M':
				number = number * SECONDS_IN_MINUTE;
				break;
			case 's':
			case 'S':
			default:
				/* this is only here for clarity */
				number = number;
				break;
		}
	}
	
	if (number > MAX_CACHE_TIMEOUT)
		number = MAX_CACHE_TIMEOUT;
	return number;
}
Beispiel #18
0
AP_DECLARE(char *) ap_getword_white(apr_pool_t *p, const char **line) {

    const char *pos = *line;
    int len;
    char *res;

    while (!apr_isspace(*pos) && *pos) {
        ++pos;
    }

    len = pos - *line;
    res = calloc(1, len + 1);
    memcpy(res, *line, len);
    res[len] = 0;

    while (apr_isspace(*pos)) {
        ++pos;
    }

    *line = pos;

    return res;
}
Beispiel #19
0
static APR_INLINE apr_size_t
string_first_non_whitespace(const char *str, apr_size_t len)
{
  apr_size_t i;

  for (i = 0; i < len; i++)
    {
      if (! apr_isspace(str[i]))
        return i;
    }

  /* if we get here, then the string must be entirely whitespace */
  return len;
}
Beispiel #20
0
void
svn_cstring_split_append(apr_array_header_t *array,
                         const char *input,
                         const char *sep_chars,
                         svn_boolean_t chop_whitespace,
                         apr_pool_t *pool)
{
  char *last;
  char *pats;
  char *p;

  pats = apr_pstrdup(pool, input);  /* strtok wants non-const data */
  p = apr_strtok(pats, sep_chars, &last);

  while (p)
    {
      if (chop_whitespace)
        {
          while (apr_isspace(*p))
            p++;

          {
            char *e = p + (strlen(p) - 1);
            while ((e >= p) && (apr_isspace(*e)))
              e--;
            *(++e) = '\0';
          }
        }

      if (p[0] != '\0')
        APR_ARRAY_PUSH(array, const char *) = p;

      p = apr_strtok(NULL, sep_chars, &last);
    }

  return;
}
Beispiel #21
0
/**
 * find value for parameter with certain name
 * @param p pool to allocate from
 * @param name name of the attribute
 * @param string string with name=value pairs separated by ";",
 *        value may be a quoted string delimited by double quotes
 * @param end pointer where to stop searching
 * @note string must be NUL-terminated (but the NUL may be after *end)
 * @return copy of the value, NULL if not found
 */
static char *mbox_mime_get_parameter(apr_pool_t *p, const char *name,
                                     const char *string, const char *end)
{
    const char *ptr = string;
    int namelen = strlen(name);
    while (ptr && *ptr && ptr < end) {
        int have_match = 0;
        const char *val_end;
        while (*ptr && (apr_isspace(*ptr) || *ptr == ';'))
            ptr++;
        if (strncasecmp(ptr, name, namelen) == 0) {
            ptr += strlen(name);
            while (*ptr && apr_isspace(*ptr) && ptr < end)
                ptr++;
            if (*ptr == '=') {
                have_match = 1;
                ptr++;
                if (ptr >= end)
                    break;
                while (*ptr && apr_isspace(*ptr) && ptr < end)
                    ptr++;
            }
        }
        if (!have_match)
            ptr += strcspn(ptr, ";= \t");
        if (*ptr == '"')
            val_end = ap_strchr_c(++ptr, '"');
        else
            val_end = ptr + strcspn(ptr, ";\n ");
        if (!val_end || val_end > end)
            val_end = end;
        if (have_match)
            return apr_pstrmemdup(p, ptr, val_end - ptr);
        ptr = val_end + 1;
    }
    return NULL;
}
Beispiel #22
0
/* Obtain the Request-URI from the original request-line, returning
 * a new string from the request pool containing the URI or "".
 */
static char *original_uri(request_rec *r)
{
    char *first, *last;

    if (r->the_request == NULL) {
        return (char *) apr_pcalloc(r->pool, 1);
    }

    first = r->the_request;     /* use the request-line */

    while (*first && !apr_isspace(*first)) {
        ++first;                /* skip over the method */
    }
    while (apr_isspace(*first)) {
        ++first;                /*   and the space(s)   */
    }

    last = first;
    while (*last && !apr_isspace(*last)) {
        ++last;                 /* end at next whitespace */
    }

    return apr_pstrmemdup(r->pool, first, last - first);
}
Beispiel #23
0
static apr_status_t groups_for_user(apr_pool_t *p, char *user, char *grpfile,
                                    apr_table_t ** out)
{
    ap_configfile_t *f;
    apr_table_t *grps = apr_table_make(p, 15);
    apr_pool_t *sp;
    struct ap_varbuf vb;
    const char *group_name, *ll, *w;
    apr_status_t status;
    apr_size_t group_len;

    if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) {
        return status ;
    }

    apr_pool_create(&sp, p);
    ap_varbuf_init(p, &vb, VARBUF_INIT_LEN);

    while (!(ap_varbuf_cfg_getline(&vb, f, VARBUF_MAX_LEN))) {
        if ((vb.buf[0] == '#') || (!vb.buf[0])) {
            continue;
        }
        ll = vb.buf;
        apr_pool_clear(sp);

        group_name = ap_getword(sp, &ll, ':');
        group_len = strlen(group_name);

        while (group_len && apr_isspace(*(group_name + group_len - 1))) {
            --group_len;
        }

        while (ll[0]) {
            w = ap_getword_conf(sp, &ll);
            if (!strcmp(w, user)) {
                apr_table_setn(grps, apr_pstrmemdup(p, group_name, group_len),
                               "in");
                break;
            }
        }
    }
    ap_cfg_closefile(f);
    apr_pool_destroy(sp);
    ap_varbuf_free(&vb);

    *out = grps;
    return APR_SUCCESS;
}
Beispiel #24
0
void
svn_stringbuf_strip_whitespace(svn_stringbuf_t *str)
{
  /* Find first non-whitespace character */
  apr_size_t offset = svn_stringbuf_first_non_whitespace(str);

  /* Go ahead!  Waste some RAM, we've got pools! :)  */
  str->data += offset;
  str->len -= offset;
  str->blocksize -= offset;

  /* Now that we've trimmed the front, trim the end, wasting more RAM. */
  while ((str->len > 0) && apr_isspace(str->data[str->len - 1]))
    str->len--;
  str->data[str->len] = '\0';
}
/* This code should be replaced with header buckets. */
static apr_status_t fetch_headers(serf_bucket_t *bkt, response_context_t *ctx)
{
    apr_status_t status;

    /* RFC 2616 says that CRLF is the only line ending, but we can easily
     * accept any kind of line ending.
     */
    status = fetch_line(ctx, SERF_NEWLINE_ANY);
    if (SERF_BUCKET_READ_ERROR(status)) {
        return status;
    }
    /* Something was read. Process it. */

    if (ctx->linebuf.state == SERF_LINEBUF_READY && ctx->linebuf.used) {
        const char *end_key;
        const char *c;

        end_key = c = memchr(ctx->linebuf.line, ':', ctx->linebuf.used);
        if (!c) {
            /* Bad headers? */
            return SERF_ERROR_BAD_HTTP_RESPONSE;
        }

        /* Skip over initial ':' */
        c++;

        /* And skip all whitespaces. */
        for(; c < ctx->linebuf.line + ctx->linebuf.used; c++)
        {
            if (!apr_isspace(*c))
            {
              break;
            }
        }

        /* Always copy the headers (from the linebuf into new mem). */
        /* ### we should be able to optimize some mem copies */
        serf_bucket_headers_setx(
            ctx->headers,
            ctx->linebuf.line, end_key - ctx->linebuf.line, 1,
            c, ctx->linebuf.line + ctx->linebuf.used - c, 1);
    }

    return status;
}
static int get_basic_auth(request_rec *r, const char **user,
                          const char **pw)
{
    const char *auth_line;
    char *decoded_line;
    int length;

    /* Get the appropriate header */
    auth_line = apr_table_get(r->headers_in, (PROXYREQ_PROXY == r->proxyreq)
                                              ? "Proxy-Authorization"
                                              : "Authorization");

    if (!auth_line) {
        note_basic_auth_failure(r);
        return HTTP_UNAUTHORIZED;
    }

    if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
        /* Client tried to authenticate using wrong auth scheme */
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01614)
                      "client used wrong authentication scheme: %s", r->uri);
        note_basic_auth_failure(r);
        return HTTP_UNAUTHORIZED;
    }

    /* Skip leading spaces. */
    while (apr_isspace(*auth_line)) {
        auth_line++;
    }

    decoded_line = apr_palloc(r->pool, apr_base64_decode_len(auth_line) + 1);
    length = apr_base64_decode(decoded_line, auth_line);
    /* Null-terminate the string. */
    decoded_line[length] = '\0';

    *user = ap_getword_nulls(r->pool, (const char**)&decoded_line, ':');
    *pw = decoded_line;

    /* set the user, even though the user is unauthenticated at this point */
    r->user = (char *) *user;

    return OK;
}
Beispiel #27
0
static const char *log_cookie(request_rec *r, char *a)
{
    const char *cookies_entry;

    /*
     * This supports Netscape version 0 cookies while being tolerant to
     * some properties of RFC2109/2965 version 1 cookies:
     * - case-insensitive match of cookie names
     * - white space between the tokens
     * It does not support the following version 1 features:
     * - quoted strings as cookie values
     * - commas to separate cookies
     */

    if ((cookies_entry = apr_table_get(r->headers_in, "Cookie"))) {
        char *cookie, *last1, *last2;
        char *cookies = apr_pstrdup(r->pool, cookies_entry);

        while ((cookie = apr_strtok(cookies, ";", &last1))) {
            char *name = apr_strtok(cookie, "=", &last2);
            if (name) {
                char *value = name + strlen(name) + 1;
                apr_collapse_spaces(name, name);

                if (!strcasecmp(name, a)) {
                    char *last;
                    value += strspn(value, " \t");  /* Move past leading WS */
                    last = value + strlen(value) - 1;
                    while (last >= value && apr_isspace(*last)) {
                       *last = '\0';
                       --last;
                    }

                    return ap_escape_logitem(r->pool, value);
                }
            }
            cookies = NULL;
        }
    }
    return NULL;
}
Beispiel #28
0
/* Check if the cookie header value passed in (The Cookie: part has
 * already been stripped) contains a DumbHippo authorization cookie
 * for the server name found in the configuration.
 *
 * The reason we need to actually parse the DumbHippo authorization
 * cookies and check the server name is we have issues where 
 * a cookie from http://mugshot.org can be sent to
 * http://dogfood.mugshot.org, for example.
 **/
static int hippo_has_cookie(cache_server_conf *conf, const char *cookie_name, const char *header)
{
    /* The Cookie: header was defined successively in:
     *
     *  http://wp.netscape.com/newsref/std/cookie_spec.html
     *  http://www.ietf.org/rfc/rfc2109.txt
     *  http://www.ietf.org/rfc/rfc2965.txt
     *
     * With more elaborations in each, but all valid Cookie: headers
     * fit into the pattern:
     *
     *  Cookie: token "=" (token|quoted_string) (";"|",') 0*(token "=" (token|quoted_string))
     *
     * Though not all such strings are valid cookies (For example, the
     * first token is always supposed to be $Version, and ',' can only
     * be used to separate cookies, and cannot be used to separate a
     * a cookie from the following parameters.) We don't try to 
     * validate, but simply parse the header according to the above syntax, 
     * and look for:
     *  
     *   "auth" "=" (token | quoted_string)
     *
     * Similarly, we ignore the detailed HTTPD spec for token, and just look
     * for whitespace or the specific separator that follows.
     */
    const char *p = header;
    int cookie_name_len = strlen(cookie_name);

    while (*p) {
	const char *name_start;
	const char *name_end;
	const char *value_start;
	const char *value_end;
	
	/* Find the leading token, which is the cookie name (or
         * a reserved value like $Version or $Path)
	 */
	while (apr_isspace(*p))
	    ++p;

	name_start = p;
	while (*p && *p != '=' && !apr_isspace(*p))
	    ++p;
	name_end = p;

	while (apr_isspace(*p))
	    ++p;

	/* Look for and skip the separating "="
	 */
	if (*p != '=')
	    return 0; /* parse error */
	++p;

	while (apr_isspace(*p))
	    ++p;

	if (!*p)
	    return 0; /* parse error */

	/* Now we have the value, which is either a quoted string or a
	 * a token
	 */
	
	if (*p == '"') {
	    /* Quoted string follows */
	    
	    ++p;
	    value_start = p;
	    while (1) {
		if (!*p) {
		    return 0; /* parse error */
		} else if (*p == '\\') {
		    // We don't have to actually unescape here ...
		    // since it never matters to us whether a cookie
		    // has a " or a \" in it.
		    ++p;
		    if (!*p)
			return 0; /* parse error */
		    ++p;
		} else if (*p == '"') {
		    break;
		} else {
		    ++p;
		}
	    }
	    value_end = p;
	    ++p;
	} else {
	    /* Unquoted token */
	    
	    value_start = p;
	    while (*p && *p != ',' && *p != ';' && !apr_isspace(*p))
		++p;
	    value_end = p;
	}

	/* Did we find the cookie we were looking for? */

	if (name_end - name_start == cookie_name_len &&
	    strncmp(name_start, cookie_name, cookie_name_len) == 0 &&
	    hippo_auth_is_for_server(conf, value_start, value_end))
	    return 1;

	while (apr_isspace(*p))
	    ++p;

	if (*p) {
	    /* Look for and skip the separator between name=value pairs
	     */
	    if (*p != ',' && *p != ';')
		return 0; /* parse error */
	    ++p;
	    
	    while (apr_isspace(*p))
		++p;
	}
    }

    return 0;
}
Beispiel #29
0
static apr_status_t read_table(cache_handle_t *handle, request_rec *r,
                               apr_table_t *table, apr_file_t *file)
{
    char w[MAX_STRING_LEN];
    char *l;
    int p;
    apr_status_t rv;

    while (1) {

        /* ### What about APR_EOF? */
        rv = apr_file_gets(w, MAX_STRING_LEN - 1, file);
        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "Premature end of cache headers.");
            return rv;
        }

        /* Delete terminal (CR?)LF */

        p = strlen(w);
        /* Indeed, the host's '\n':
           '\012' for UNIX; '\015' for MacOS; '\025' for OS/390
           -- whatever the script generates.
        */
        if (p > 0 && w[p - 1] == '\n') {
            if (p > 1 && w[p - 2] == CR) {
                w[p - 2] = '\0';
            }
            else {
                w[p - 1] = '\0';
            }
        }

        /* If we've finished reading the headers, break out of the loop. */
        if (w[0] == '\0') {
            break;
        }

#if APR_CHARSET_EBCDIC
        /* Chances are that we received an ASCII header text instead of
         * the expected EBCDIC header lines. Try to auto-detect:
         */
        if (!(l = strchr(w, ':'))) {
            int maybeASCII = 0, maybeEBCDIC = 0;
            unsigned char *cp, native;
            apr_size_t inbytes_left, outbytes_left;

            for (cp = w; *cp != '\0'; ++cp) {
                native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp);
                if (apr_isprint(*cp) && !apr_isprint(native))
                    ++maybeEBCDIC;
                if (!apr_isprint(*cp) && apr_isprint(native))
                    ++maybeASCII;
            }
            if (maybeASCII > maybeEBCDIC) {
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                             "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)",
                             r->filename);
                inbytes_left = outbytes_left = cp - w;
                apr_xlate_conv_buffer(ap_hdrs_from_ascii,
                                      w, &inbytes_left, w, &outbytes_left);
            }
        }
#endif /*APR_CHARSET_EBCDIC*/

        /* if we see a bogus header don't ignore it. Shout and scream */
        if (!(l = strchr(w, ':'))) {
            return APR_EGENERAL;
        }

        *l++ = '\0';
        while (*l && apr_isspace(*l)) {
            ++l;
        }

        apr_table_add(table, w, l);
    }

    return APR_SUCCESS;
}
Beispiel #30
0
static apr_dbd_t *dbd_mysql_open(apr_pool_t *pool, const char *params,
                                 const char **error)
{
    static const char *const delims = " \r\n\t;|,";
    const char *ptr;
    int i;
    const char *key;
    size_t klen;
    const char *value;
    size_t vlen;
#if MYSQL_VERSION_ID >= 50013
    my_bool do_reconnect = 1;
#endif
    MYSQL *real_conn;
    unsigned long flags = 0;

    struct {
        const char *field;
        const char *value;
    } fields[] = {
        {"host", NULL},
        {"user", NULL},
        {"pass", NULL},
        {"dbname", NULL},
        {"port", NULL},
        {"sock", NULL},
        {"flags", NULL},
        {"fldsz", NULL},
        {"group", NULL},
#if MYSQL_VERSION_ID >= 50013
        {"reconnect", NULL},
        {"connecttimeout", NULL},
        {"readtimeout", NULL},
        {"writetimeout", NULL},
#endif
        {NULL, NULL}
    };
    unsigned int port = 0;
#if MYSQL_VERSION_ID >= 50013
    unsigned int timeout = 0;
#endif
    apr_dbd_t *sql = apr_pcalloc(pool, sizeof(apr_dbd_t));
    sql->fldsz = FIELDSIZE;
    sql->conn = mysql_init(sql->conn);
    if ( sql->conn == NULL ) {
        return NULL;
    }
    for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) {
        /* don't dereference memory that may not belong to us */
        if (ptr == params) {
            ++ptr;
            continue;
        }
        for (key = ptr-1; apr_isspace(*key); --key);
        klen = 0;
        while (apr_isalpha(*key)) {
            /* don't parse backwards off the start of the string */
            if (key == params) {
                --key;
                ++klen;
                break;
            }
            --key;
            ++klen;
        }
        ++key;
        for (value = ptr+1; apr_isspace(*value); ++value);
        vlen = strcspn(value, delims);
        for (i = 0; fields[i].field != NULL; i++) {
            if (!strncasecmp(fields[i].field, key, klen)) {
                fields[i].value = apr_pstrndup(pool, value, vlen);
                break;
            }
        }
        ptr = value+vlen;
    }
    if (fields[4].value != NULL) {
        port = atoi(fields[4].value);
    }
    if (fields[6].value != NULL &&
        !strcmp(fields[6].value, "CLIENT_FOUND_ROWS")) {
        flags |= CLIENT_FOUND_ROWS; /* only option we know */
    }
    if (fields[7].value != NULL) {
        sql->fldsz = atol(fields[7].value);
    }
    if (fields[8].value != NULL) {
         mysql_options(sql->conn, MYSQL_READ_DEFAULT_GROUP, fields[8].value);
    }
#if MYSQL_VERSION_ID >= 50013
    if (fields[9].value != NULL) {
         do_reconnect = atoi(fields[9].value) ? 1 : 0;
    }
    if (fields[10].value != NULL) {
        timeout = atoi(fields[10].value);
        mysql_options(sql->conn, MYSQL_OPT_CONNECT_TIMEOUT,
                      (const void *)&timeout);
    }
    if (fields[11].value != NULL) {
        timeout = atoi(fields[11].value);
        mysql_options(sql->conn, MYSQL_OPT_READ_TIMEOUT,
                      (const void *)&timeout);
    }
    if (fields[12].value != NULL) {
        timeout = atoi(fields[12].value);
        mysql_options(sql->conn, MYSQL_OPT_WRITE_TIMEOUT,
                      (const void *)&timeout);
    }
#endif

#if MYSQL_VERSION_ID >= 50013
    /* the MySQL manual says this should be BEFORE mysql_real_connect */
    mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect);
#endif

    real_conn = mysql_real_connect(sql->conn, fields[0].value,
                                   fields[1].value, fields[2].value,
                                   fields[3].value, port,
                                   fields[5].value, flags);

    if(real_conn == NULL) {
        if (error) {
            *error = apr_pstrdup(pool, mysql_error(sql->conn));
        }
        mysql_close(sql->conn);
        return NULL;
    }

#if MYSQL_VERSION_ID >= 50013
    /* Some say this should be AFTER mysql_real_connect */
    mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect);
#endif

    return sql;
}