Exemplo n.º 1
0
static char *get_pw(request_rec *r, char *user, char *auth_pwfile)
{
    ap_configfile_t *f;
    char l[MAX_STRING_LEN];
    const char *rpw, *w;
    apr_status_t status;

    if ((status = ap_pcfg_openfile(&f, r->pool, auth_pwfile)) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                      "Could not open password file: %s", auth_pwfile);
        return NULL;
    }
    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        if ((l[0] == '#') || (!l[0])) {
            continue;
        }
        rpw = l;
        w = ap_getword(r->pool, &rpw, ':');

        if (!strcmp(user, w)) {
            ap_cfg_closefile(f);
            return ap_getword(r->pool, &rpw, ':');
        }
    }
    ap_cfg_closefile(f);
    return NULL;
}
Exemplo n.º 2
0
static char *get_hash(request_rec *r, char *user, char *auth_pwfile)
{
    configfile_t *f;
    char l[MAX_STRING_LEN];
    const char *rpw;
    char *w, *x;

    if (!(f = ap_pcfg_openfile(r->pool, auth_pwfile))) {
	ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
		    "Could not open password file: %s", auth_pwfile);
	return NULL;
    }
    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
	if ((l[0] == '#') || (!l[0]))
	    continue;
	rpw = l;
	w = ap_getword(r->pool, &rpw, ':');
	x = ap_getword(r->pool, &rpw, ':');

	if (x && w && !strcmp(user, w) && !strcmp(ap_auth_name(r), x)) {
	    ap_cfg_closefile(f);
	    return ap_pstrdup(r->pool, rpw);
	}
    }
    ap_cfg_closefile(f);
    return NULL;
}
Exemplo n.º 3
0
static authn_status check_password(request_rec *r, const char *user,
                                   const char *password)
{
#ifndef APACHE2NGINX
    authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &authn_file_module);
    ap_configfile_t *f;
    char l[MAX_STRING_LEN];
    apr_status_t status;
    char *file_password = NULL;

    if (!conf->pwfile) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "AuthUserFile not specified in the configuration");
        return AUTH_GENERAL_ERROR;
    }

    status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);

    if (status != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                      "Could not open password file: %s", conf->pwfile);
        return AUTH_GENERAL_ERROR;
    }

    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        const char *rpw, *w;

        /* Skip # or blank lines. */
        if ((l[0] == '#') || (!l[0])) {
            continue;
        }

        rpw = l;
        w = ap_getword(r->pool, &rpw, ':');

        if (!strcmp(user, w)) {
            file_password = ap_getword(r->pool, &rpw, ':');
            break;
        }
    }
    ap_cfg_closefile(f);

    if (!file_password) {
        return AUTH_USER_NOT_FOUND;
    }

    status = apr_password_validate(password, file_password);
    if (status != APR_SUCCESS) {
        return AUTH_DENIED;
    }

#endif
    return AUTH_GRANTED;
}
Exemplo n.º 4
0
static authn_status get_realm_hash(request_rec *r, const char *user,
                                   const char *realm, char **rethash)
{
#ifndef APACHE2NGINX
    authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &authn_file_module);
    ap_configfile_t *f;
    char l[MAX_STRING_LEN];
    apr_status_t status;
    char *file_hash = NULL;

    if (!conf->pwfile) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "AuthUserFile not specified in the configuration");
        return AUTH_GENERAL_ERROR;
    }

    status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);

    if (status != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                      "Could not open password file: %s", conf->pwfile);
        return AUTH_GENERAL_ERROR;
    }

    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        const char *rpw, *w, *x;

        /* Skip # or blank lines. */
        if ((l[0] == '#') || (!l[0])) {
            continue;
        }

        rpw = l;
        w = ap_getword(r->pool, &rpw, ':');
        x = ap_getword(r->pool, &rpw, ':');

        if (x && w && !strcmp(user, w) && !strcmp(realm, x)) {
            /* Remember that this is a md5 hash of user:realm:password.  */
            file_hash = ap_getword(r->pool, &rpw, ':');
            break;
        }
    }
    ap_cfg_closefile(f);

    if (!file_hash) {
        return AUTH_USER_NOT_FOUND;
    }

    *rethash = file_hash;
#endif

    return AUTH_USER_FOUND;
}
Exemplo n.º 5
0
static int twms_handler(request_rec *r)

{
  twms_dir_conf *dcfg;
  const char *data;
  const char *val;
  apr_table_t *tab;
  apr_file_t *fh;
  apr_size_t nsend;
  apr_finfo_t info;


  if ((r->method_number != M_GET )||(r->args==0)) return DECLINED;
  data=r->args;
  // scfg=ap_get_module_config(r->server->module_config,&twms_module);
  dcfg=ap_get_module_config(r->per_dir_config,&twms_module);
  if (!dcfg) return DECLINED; // Does this ever happen?

  if (!ap_strstr(data,"GetTileService")) return DECLINED;
  // Do we have a config for this directory

//  ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS_handler: args %s, path %s scfg %x dcfg %x dir %s conf %s",
//    data,r->parsed_uri.path,scfg,dcfg,dcfg->path,dcfg->Config);
  if (!dcfg->Config) return DECLINED;


  // This is overkill here, but it works
  tab=apr_table_make(r->pool,0);

  while (*data && (val=ap_getword(r->pool, &data, '&'))) {
    char *key=apr_pstrdup(r->pool,ap_getword(r->pool, &val, '='));
    char *ival=apr_pstrdup(r->pool,val);
    ap_unescape_url(key);ap_unescape_url(ival);
    apr_table_merge(tab,key,ival);
  }

  if (!(val=apr_table_get(tab,"request"))) return DECLINED;
  if (apr_strnatcmp(val,"GetTileService")) return DECLINED;

  if (APR_SUCCESS!=apr_file_open(&fh,apr_pstrcat(r->pool,dcfg->path,dcfg->Config,0),
      APR_READ,APR_OS_DEFAULT,r->pool)) {
    ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS file can't be read");
    return HTTP_CONFLICT;
  }
  ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS Sending GTS file");
  apr_file_info_get(&info,APR_FINFO_SIZE,fh);

  ap_set_content_type(r,"text/xml");
  ap_send_fd(fh,r,0,info.size,&nsend);

  apr_file_close(fh);
  return OK;
}
Exemplo n.º 6
0
static int is_this_html(request_rec * r)
{
    int i = 0;
    const char *ctype_line_val =
	apr_table_get(r->headers_out, "Content-Type");

    if (!ctype_line_val) {
	if (r->content_type)
	    ctype_line_val = apr_pstrdup(r->pool, r->content_type);
	else
	    return 0;
    }

    const char *ctype = ap_getword(r->pool, &ctype_line_val, ';');
    if (!ctype)
	return 0;

    triger_conf_t *cfg =
	ap_get_module_config(r->per_dir_config, &triger_module);

    if (!cfg)
	return 0;

    for (i = 0; i < cfg->ctypes->nelts; i++)
	if (apr_strnatcasecmp
	    ((((triger_ctype_t *) (cfg->ctypes->elts))[i]).data,
	     ctype) == 0)
	    return 1;

    return 0;
}
Exemplo n.º 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;
}
Exemplo n.º 8
0
static apr_status_t ap_compile_output_filter(ap_filter_t *filter, apr_bucket_brigade *input_brigade) {
  request_rec *request = filter->r;
  if ( ! request->filename) {
    return ap_pass_brigade(filter->next, input_brigade);
  }
  const char       *resource_name;
  compile_config_t *directory_config = (compile_config_t*) ap_get_module_config(request->per_dir_config,        &compile_module);
  compile_config_t *server_config    = (compile_config_t*) ap_get_module_config(request->server->module_config, &compile_module);
  compile_config_t *config           = compile_merge_config(request->pool, server_config, directory_config);
  if (config->use_path_info) {
    resource_name = apr_pstrcat(request->pool, request->filename, request->path_info, NULL);
  } else {
    resource_name = request->filename;
  }
  const char *filename;
        char *extension;
  filename = ap_strrchr_c(resource_name, '/');
  if (filename == NULL) {
    filename = resource_name;
  } else {
    ++ filename;
  }
  extension = ap_getword(request->pool, &filename, '.');
  while (*filename && (extension = ap_getword(request->pool, &filename, '.'))) {
    if (*extension == '\0') {
      continue;
    }
    ap_str_tolower(extension);
    if (config->extension_commands != NULL) {
      const compile_extension_config_t *extension_config = NULL;
      extension_config = (compile_extension_config_t*) apr_hash_get(config->extension_commands, extension, APR_HASH_KEY_STRING);
      if (extension_config != NULL && extension_config->command_line) {
#ifdef _DEBUG
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, request->server, "ap_compile_output_filter('%s')", apr_psprintf(request->pool, extension_config->command_line, resource_name));
#endif
        // TODO: http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.6/modules/experimental/mod_case_filter.c
        // Collect buckets, save to disk, run command line and tail-insert result
        ap_set_content_type(request, "text/html;charset=utf-8");
        break;
      }
    }
  }
  return ap_pass_brigade(filter->next, input_brigade);
}
Exemplo n.º 9
0
static int digest_check_auth(request_rec *r)
{
    char *user = r->connection->user;
    int m = r->method_number;
    int method_restricted = 0;
    register int x;
    const char *t;
    char *w;
    array_header *reqs_arr;
    require_line *reqs;

    if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest"))
	return DECLINED;

    reqs_arr = ap_requires(r);
    /* If there is no "requires" directive, 
     * then any user will do.
     */
    if (!reqs_arr)
	return OK;
    reqs = (require_line *) reqs_arr->elts;

    for (x = 0; x < reqs_arr->nelts; x++) {

	if (!(reqs[x].method_mask & (1 << m)))
	    continue;

	method_restricted = 1;

	t = reqs[x].requirement;
	w = ap_getword(r->pool, &t, ' ');
	if (!strcmp(w, "valid-user"))
	    return OK;
	else if (!strcmp(w, "user")) {
	    while (t[0]) {
		w = ap_getword_conf(r->pool, &t);
		if (!strcmp(user, w))
		    return OK;
	    }
	}
	else
	    return DECLINED;
    }

    if (!method_restricted)
	return OK;

    ap_note_digest_auth_failure(r);
    return AUTH_REQUIRED;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
static void split_to_parms(ApacheRequest *req, const char *data)
{
    request_rec *r = req->r;
    const char *val;

    while (*data && (val = my_urlword(r->pool, &data))) {
	const char *key = ap_getword(r->pool, &val, '=');

	req_plustospace((char*)key);
	ap_unescape_url((char*)key);
	req_plustospace((char*)val);
	ap_unescape_url((char*)val);

	ap_table_add(req->parms, key, val);
    }

}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
/**
 *  get DSAME Cookie
 */
static char *get_cookie(request_rec *r, const char *name)
{
    static const char separators[] = { " ;\n\r\t\f" };
    char *cookie;
    char *part;
    char *marker = NULL;
    char *value = NULL;
    char *last_separator;

    if (!(cookie = (char *)ap_table_get(r->headers_in, "Cookie"))) {
	am_web_log_warning("in get_cookie: no cookie in ap_table");
	return NULL;
    }

    part = ap_pstrcat (r->pool, cookie, ";", NULL);
    am_web_log_debug("in get_cookie: part is  %s", part);

    // get the last IS cookie
    for (part = strtok_r(part, separators, &last_separator);
	part != NULL;
	part = strtok_r(NULL, separators, &last_separator))
    {
	while (part && !(marker = strchr(part, '='))) {
	    part = strtok_r(NULL, separators, &last_separator);
	}

	if (++marker) {
	    if (!strcasecmp(ap_getword(r->pool, (const char **)&part, '='),
		name))
	    {
		value = marker;
	    }
	}
    }

    if (value) {
	am_web_log_debug("in get_cookie: return cookie value of %s", value);
    }

    return value;
}
Exemplo n.º 14
0
static apr_table_t *groups_for_user(request_rec *r, char *user, char *grpfile)
{
    apr_pool_t *p = r->pool;
    ap_configfile_t *f;
    apr_table_t *grps = apr_table_make(p, 15);
    apr_pool_t *sp;
    char l[MAX_STRING_LEN];
    const char *group_name, *ll, *w;
    apr_status_t status;

    if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                       "Could not open group file: %s", grpfile);
        return NULL;
    }

    apr_pool_create(&sp, p);

    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        if ((l[0] == '#') || (!l[0])) {
            continue;
        }
        ll = l;
        apr_pool_clear(sp);

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

        while (ll[0]) {
            w = ap_getword_conf(sp, &ll);
            if (!strcmp(w, user)) {
                apr_table_setn(grps, apr_pstrdup(p, group_name), "in");
                break;
            }
        }
    }
    ap_cfg_closefile(f);
    apr_pool_destroy(sp);
    return grps;
}
Exemplo n.º 15
0
static const char *modperl_cmd_parse_args(apr_pool_t *p,
                                          const char *args,
                                          apr_table_t **t)
{
    const char *orig_args = args;
    char *pair, *key, *val;
    *t = apr_table_make(p, 2);

    while (*(pair = ap_getword(p, &args, ',')) != '\0') {
        key = ap_getword_nc(p, &pair, '=');
        val = pair;

        if (!(*key && *val)) {
            return apr_pstrcat(p, "invalid args spec: ",
                               orig_args, NULL);
        }

        apr_table_set(*t, key, val);
    }

    return NULL;
}
Exemplo n.º 16
0
static table *groups_for_user(pool *p, char *user, char *grpfile)
{
    configfile_t *f;
    table *grps = ap_make_table(p, 15);
    pool *sp;
    char l[MAX_STRING_LEN];
    const char *group_name, *ll, *w;

    if (!(f = ap_pcfg_openfile(p, grpfile))) {
/*add?	aplog_error(APLOG_MARK, APLOG_ERR, NULL,
		    "Could not open group file: %s", grpfile);*/
	return NULL;
    }

    sp = ap_make_sub_pool(p);

    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
	if ((l[0] == '#') || (!l[0]))
	    continue;
	ll = l;
	ap_clear_pool(sp);

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

	while (ll[0]) {
	    w = ap_getword_conf(sp, &ll);
	    if (!strcmp(w, user)) {
		ap_table_setn(grps, ap_pstrdup(p, group_name), "in");
		break;
	    }
	}
    }
    ap_cfg_closefile(f);
    ap_destroy_pool(sp);
    return grps;
}
Exemplo n.º 17
0
static osrfStringArray* apacheParseParms(request_rec* r) {

	if( r == NULL ) return NULL;
	//ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "got a valid request_rec");

	char* arg = NULL;
	apr_pool_t *p = r->pool;	/* memory pool */
	growing_buffer* buffer = buffer_init(1025);

	/* gather the post args and append them to the url query string */
	if( !strcmp(r->method,"POST") ) {

		ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
		
		//osrfLogDebug(OSRF_LOG_MARK, "gateway reading post data..");
	    //ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "idlchunk reading post data..");

		if(ap_should_client_block(r)) {


			/* Start with url query string, if any */
			
			if(r->args && r->args[0])
				buffer_add(buffer, r->args);

			char body[1025];

			//osrfLogDebug(OSRF_LOG_MARK, "gateway client has post data, reading...");

			/* Append POST data */
			
			long bread;
			while( (bread = ap_get_client_block(r, body, sizeof(body) - 1)) ) {

				if(bread < 0) {
					//osrfLogInfo(OSRF_LOG_MARK, 
					//	"ap_get_client_block(): returned error, exiting POST reader");
					break;
				}

				body[bread] = '\0';
				buffer_add( buffer, body );

				//osrfLogDebug(OSRF_LOG_MARK, 
				//	"gateway read %ld bytes: %d bytes of data so far", bread, buffer->n_used);

				if(buffer->n_used > APACHE_TOOLS_MAX_POST_SIZE) {
					//osrfLogError(OSRF_LOG_MARK, "gateway received POST larger "
					//	"than %d bytes. dropping request", APACHE_TOOLS_MAX_POST_SIZE);
					buffer_free(buffer);
					return NULL;
				}
			}

			//osrfLogDebug(OSRF_LOG_MARK, "gateway done reading post data");
		}

	} else { /* GET */

        if(r->args && r->args[0])
            buffer_add(buffer, r->args);
	    //ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "idlchunk read GET data..");
    }


    if(buffer->n_used > 0)
        arg = apr_pstrdup(p, buffer->buf);
    else
        arg = NULL; 
    buffer_free(buffer);

	if( !arg || !arg[0] ) { /* we received no request */
		return NULL;
	}

	//osrfLogDebug(OSRF_LOG_MARK, "parsing URL params from post/get request data: %s", arg);
	//ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "parsing URL params from post/get request data: %s", arg);
	
	osrfStringArray* sarray		= osrfNewStringArray(12); /* method parameters */
	int sanity = 0;
	char* key					= NULL;	/* query item name */
	char* val					= NULL;	/* query item value */

	/* Parse the post/get request data into a series of name/value pairs.   */
	/* Load each name into an even-numbered slot of an osrfStringArray, and */
	/* the corresponding value into the following odd-numbered slot.        */

	while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) {

		key = ap_getword(r->pool, (const char**) &val, '=');
		if(!key || !key[0])
			break;

		ap_unescape_url(key);
		ap_unescape_url(val);

		//osrfLogDebug(OSRF_LOG_MARK, "parsed URL params %s=%s", key, val);

		osrfStringArrayAdd(sarray, key);
		osrfStringArrayAdd(sarray, val);

		if( sanity++ > 1000 ) {
			//osrfLogError(OSRF_LOG_MARK, 
			//	"Parsing URL params failed sanity check: 1000 iterations");
			osrfStringArrayFree(sarray);
			return NULL;
		}

	}

	//osrfLogDebug(OSRF_LOG_MARK,
	//	"Apache tools parsed %d params key/values", sarray->size / 2 );

	return sarray;
}
static int ap_set_byterange(request_rec *r, apr_off_t clength,
                            apr_array_header_t **indexes)
{
    const char *range;
    const char *if_range;
    const char *match;
    const char *ct;
    char *cur;
    int num_ranges = 0, unsatisfiable = 0;
    apr_off_t sum_lengths = 0;
    indexes_t *idx;
    int ranges = 1;
    const char *it;

    if (r->assbackwards) {
        return 0;
    }

    /*
     * Check for Range request-header (HTTP/1.1) or Request-Range for
     * backwards-compatibility with second-draft Luotonen/Franks
     * byte-ranges (e.g. Netscape Navigator 2-3).
     *
     * We support this form, with Request-Range, and (farther down) we
     * send multipart/x-byteranges instead of multipart/byteranges for
     * Request-Range based requests to work around a bug in Netscape
     * Navigator 2-3 and MSIE 3.
     */

    if (!(range = apr_table_get(r->headers_in, "Range"))) {
        range = apr_table_get(r->headers_in, "Request-Range");
    }

    if (!range || strncasecmp(range, "bytes=", 6) || r->status != HTTP_OK) {
        return 0;
    }

    /* is content already a single range? */
    if (apr_table_get(r->headers_out, "Content-Range")) {
       return 0;
    }

    /* is content already a multiple range? */
    if ((ct = apr_table_get(r->headers_out, "Content-Type"))
        && (!strncasecmp(ct, "multipart/byteranges", 20)
            || !strncasecmp(ct, "multipart/x-byteranges", 22))) {
       return 0;
    }

    /*
     * Check the If-Range header for Etag or Date.
     * Note that this check will return false (as required) if either
     * of the two etags are weak.
     */
    if ((if_range = apr_table_get(r->headers_in, "If-Range"))) {
        if (if_range[0] == '"') {
            if (!(match = apr_table_get(r->headers_out, "Etag"))
                || (strcmp(if_range, match) != 0)) {
                return 0;
            }
        }
        else if (!(match = apr_table_get(r->headers_out, "Last-Modified"))
                 || (strcmp(if_range, match) != 0)) {
            return 0;
        }
    }

    range += 6;
    it = range;
    while (*it) {
        if (*it++ == ',') {
            ranges++;
        }
    }
    it = range;
    *indexes = apr_array_make(r->pool, ranges, sizeof(indexes_t));
    while ((cur = ap_getword(r->pool, &range, ','))) {
        char *dash;
        char *errp;
        apr_off_t number, start, end;

        if (!*cur)
            break;

        /*
         * Per RFC 2616 14.35.1: If there is at least one syntactically invalid
         * byte-range-spec, we must ignore the whole header.
         */

        if (!(dash = strchr(cur, '-'))) {
            return 0;
        }

        if (dash == cur) {
            /* In the form "-5" */
            if (apr_strtoff(&number, dash+1, &errp, 10) || *errp) {
                return 0;
            }
            if (number < 1) {
                return 0;
            }
            start = clength - number;
            end = clength - 1;
        }
        else {
            *dash++ = '\0';
            if (apr_strtoff(&number, cur, &errp, 10) || *errp) {
                return 0;
            }
            start = number;
            if (*dash) {
                if (apr_strtoff(&number, dash, &errp, 10) || *errp) {
                    return 0;
                }
                end = number;
                if (start > end) {
                    return 0;
                }
            }
            else {                  /* "5-" */
                end = clength - 1;
                /*
                 * special case: 0-
                 *   ignore all other ranges provided
                 *   return as a single range: 0-
                 */
                if (start == 0) {
                    (*indexes)->nelts = 0;
                    idx = (indexes_t *)apr_array_push(*indexes);
                    idx->start = start;
                    idx->end = end;
                    sum_lengths = clength;
                    num_ranges = 1;
                    break;
                }
            }
        }

        if (start < 0) {
            start = 0;
        }
        if (start >= clength) {
            unsatisfiable = 1;
            continue;
        }
        if (end >= clength) {
            end = clength - 1;
        }

        idx = (indexes_t *)apr_array_push(*indexes);
        idx->start = start;
        idx->end = end;
        sum_lengths += end - start + 1;
        /* new set again */
        num_ranges++;
    }

    if (num_ranges == 0 && unsatisfiable) {
        /* If all ranges are unsatisfiable, we should return 416 */
        return -1;
    }
    if (sum_lengths > clength) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      "Sum of ranges larger than file, ignoring.");
        return 0;
    }

    r->status = HTTP_PARTIAL_CONTENT;
    r->range = it;

    return num_ranges;
}
Exemplo n.º 19
0
static int pg_check_auth(request_rec * r)
{
	pg_auth_config_rec *sec =
		(pg_auth_config_rec *) ap_get_module_config(r->per_dir_config,
													&auth_pgsql_module);
	char *user = r->user;
	int m = r->method_number;
	int group_result = DECLINED;



	apr_array_header_t *reqs_arr = (apr_array_header_t *) ap_requires(r);
	require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL;

	register int x, res;
	const char *t;
	char *w;

	pg_errstr[0] = '\0';

#ifdef DEBUG_AUTH_PGSQL
	ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
				  "[mod_auth_pgsql.c] - pg_check_auth - going to check auth for user \"%s\" ",
				  user);
#endif							/* DEBUG_AUTH_PGSQL */



	/* if we cannot do it; leave it to some other guy 
	 */
	if ((!sec->auth_pg_grp_table) && (!sec->auth_pg_grp_group_field)
		&& (!sec->auth_pg_grp_user_field))
		return DECLINED;

	if (!reqs_arr) {
		if (sec->auth_pg_authoritative) {
			/* force error and access denied */
			apr_snprintf(pg_errstr, MAX_STRING_LEN,
						 "mod_auth_pgsql: user %s denied, no access rules specified (PG-Authoritative)",
						 user);
			ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr);
			ap_note_basic_auth_failure(r);
			res = HTTP_UNAUTHORIZED;
		} else {
			return DECLINED;
		}
	}

	for (x = 0; x < reqs_arr->nelts; x++) {

		if (!(reqs[x].method_mask & (1 << m)))
			continue;

		t = reqs[x].requirement;
		w = ap_getword(r->pool, &t, ' ');

		if (!strcmp(w, "valid-user"))
			return OK;

		if (!strcmp(w, "user")) {
			while (t[0]) {
				w = ap_getword_conf(r->pool, &t);
				if (!strcmp(user, w))
					return OK;
			}
			if (sec->auth_pg_authoritative) {
				/* force error and access denied */
				apr_snprintf(pg_errstr, MAX_STRING_LEN,
							 "mod_auth_pgsql: user %s denied, no access rules specified (PG-Authoritative)",
							 user);
				ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr);
				ap_note_basic_auth_failure(r);
				return HTTP_UNAUTHORIZED;
			}

		} else if (!strcmp(w, "group")) {
			/* look up the membership for each of the groups in the table */
			pg_errstr[0] = '\0';

			while (t[0]) {
				if (get_pg_grp(r, ap_getword(r->pool, &t, ' '), user, sec)) {
					group_result = OK;
				};
			};

			if (pg_errstr[0]) {
				ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr);
				return HTTP_INTERNAL_SERVER_ERROR;
			}

			if (group_result == OK)
				return OK;

			if (sec->auth_pg_authoritative) {
				apr_snprintf(pg_errstr, MAX_STRING_LEN,
							 "[mod_auth_pgsql.c] - user %s not in right groups (PG-Authoritative)",
							 user);
				ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr);
				ap_note_basic_auth_failure(r);
				return HTTP_UNAUTHORIZED;
			};
		}
	}

	return DECLINED;
}
Exemplo n.º 20
0
static char *parse_log_item(pool *p, log_format_item *it, const char **sa)
{
    const char *s = *sa;

    if (*s != '%') {
        return parse_log_misc_string(p, it, sa);
    }

    ++s;
    it->condition_sense = 0;
    it->conditions = NULL;
    it->want_orig = -1;
    it->arg = "";               /* For safety's sake... */

    while (*s) {
        int i;
        struct log_item_list *l;

        switch (*s) {
        case '!':
            ++s;
            it->condition_sense = !it->condition_sense;
            break;

        case '<':
            ++s;
            it->want_orig = 1;
            break;

        case '>':
            ++s;
            it->want_orig = 0;
            break;

        case ',':
            ++s;
            break;

        case '{':
            ++s;
            it->arg = ap_getword(p, &s, '}');
            break;

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            i = *s - '0';
            while (ap_isdigit(*++s)) {
                i = i * 10 + (*s) - '0';
            }
            if (!it->conditions) {
                it->conditions = ap_make_array(p, 4, sizeof(int));
            }
            *(int *) ap_push_array(it->conditions) = i;
            break;

        default:
            l = find_log_func(*s++);
            if (!l) {
                char dummy[2];

                dummy[0] = s[-1];
                dummy[1] = '\0';
                return ap_pstrcat(p, "Unrecognized LogFormat directive %",
                               dummy, NULL);
            }
            it->func = l->func;
            if (it->want_orig == -1) {
                it->want_orig = l->want_orig_default;
            }
            *sa = s;
            return NULL;
        }
    }

    return "Ran off end of LogFormat parsing args to some directive";
}
Exemplo n.º 21
0
static int dbm_check_auth(request_rec *r)
{
    dbm_auth_config_rec *sec =
    (dbm_auth_config_rec *) ap_get_module_config(r->per_dir_config,
					      &dbm_auth_module);
    char *user = r->connection->user;
    int m = r->method_number;

    array_header *reqs_arr = ap_requires(r);
    require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL;

    register int x;
    const char *t;
    char *w;

    if (!sec->auth_dbmgrpfile)
	return DECLINED;
    if (!reqs_arr)
	return DECLINED;

    for (x = 0; x < reqs_arr->nelts; x++) {

	if (!(reqs[x].method_mask & (1 << m)))
	    continue;

	t = reqs[x].requirement;
	w = ap_getword(r->pool, &t, ' ');

	if (!strcmp(w, "group") && sec->auth_dbmgrpfile) {
	    const char *orig_groups, *groups;
	    char *v;

	    if (!(groups = get_dbm_grp(r, user, sec->auth_dbmgrpfile))) {
		if (!(sec->auth_dbmauthoritative))
		    return DECLINED;
		ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
			    "user %s not in DBM group file %s: %s",
			    user, sec->auth_dbmgrpfile, r->filename);
		ap_note_basic_auth_failure(r);
		return AUTH_REQUIRED;
	    }
	    orig_groups = groups;
	    while (t[0]) {
		w = ap_getword(r->pool, &t, ' ');
		groups = orig_groups;
		while (groups[0]) {
		    v = ap_getword(r->pool, &groups, ',');
		    if (!strcmp(v, w))
			return OK;
		}
	    }
	    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
			"user %s not in right group: %s",
			user, r->filename);
	    ap_note_basic_auth_failure(r);
	    return AUTH_REQUIRED;
	}
    }

    return DECLINED;
}
Exemplo n.º 22
0
/**
 * The output filter routine. This one gets called whenever a response is
 * generated that passes this filter. Returns APR_SUCCESS if everything works
 * out.
 *
 * @param f     The filter definition.
 * @param bb    The bucket brigade containing the data.
 */
static apr_status_t replace_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    request_rec *r = f->r;
    conn_rec *c = r->connection;
    replace_ctx_t *ctx = f->ctx;
    apr_bucket *b;
    apr_size_t len;
    const char *data;
    const char *header;
    apr_status_t rv;
    int re_vector[RE_VECTOR_SIZE];  // 3 elements per matched pattern
    replace_pattern_t *next;
    header_replace_pattern_t *next_header;
    int modified = 0;               // flag to determine if a replacement has
                                    // occured.

    if (!ctx) {
        /* Initialize context */
        ctx = apr_pcalloc(f->r->pool, sizeof(replace_ctx_t));
        f->ctx = ctx;
        ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
    }

    /* parse config settings */
    
    /* look for the user-defined filter */
    ctx->filter = find_filter_def(f->r->server, f->frec->name);
    if (!ctx->filter) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
                      "couldn't find definition of filter '%s'",
                      f->frec->name);
        return APR_EINVAL;
    }
    ctx->p = f->r->pool;
    if (ctx->filter->intype &&
        ctx->filter->intype != INTYPE_ALL) {
        if (!f->r->content_type) {
            ctx->noop = 1;
        }
        else {
            const char *ctypes = f->r->content_type;
            const char *ctype = ap_getword(f->r->pool, &ctypes, ';');

            if (strcasecmp(ctx->filter->intype, ctype)) {
                /* wrong IMT for us; don't mess with the output */
                ctx->noop = 1;
            }
        }
    }

    /* exit immediately if there are indications that the filter shouldn't be
     * executed.
     */
    if (ctx->noop == 1) {
        ap_pass_brigade(f->next, bb);
        return APR_SUCCESS;
    }

    /**
     * Loop through the configured header patterns.
     */
    for (next_header = ctx->filter->header_pattern;
         next_header != NULL;
         next_header = next_header->next) {

        // create a separate table with the requested HTTP header entries and
        // unset those headers in the original request.
        apr_table_t *header_table;
        header_table = apr_table_make(r->pool, 2);
    	// create a data structure for the callback function
    	header_replace_cb_t *hrcb;
    	hrcb = apr_palloc(r->pool, sizeof(header_replace_cb_t));
    	hrcb->header_table = header_table;
	    hrcb->pattern = next_header->pattern;
    	hrcb->extra = next_header->extra;
	    hrcb->replacement = next_header->replacement;
    	hrcb->r = r;
	    // pass any header that is defined to be processed to the callback 
    	// function and unset those headers in the original outgoing record.
        apr_table_do(replace_header_cb, hrcb, r->headers_out, 
                     next_header->header, NULL);
        // only touch the header if the changed header table is not empty.
        if (!apr_is_empty_table(header_table)) {
            apr_table_unset(r->headers_out, next_header->header);
            // overlay the original header table with the new one to reintegrate
            // the changed headers.
            r->headers_out = apr_table_overlay(r->pool, r->headers_out, 
                                               header_table);
        }
    }

    /* Not nice but neccessary: Unset the ETag , because we cannot adjust the 
     * value correctly, because we do not know how.
     */
    apr_table_unset(f->r->headers_out, "ETag"); 

    int eos = 0;        // flag to check if an EOS bucket is in the brigade.
    apr_bucket *eos_bucket;
                        // Backup for the EOS bucket.

    /* Interate through the available data. Stop if there is an EOS */

   for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
        if (APR_BUCKET_IS_EOS(b)) {
            eos = 1;
            ap_save_brigade(f, &ctx->bb, &bb, ctx->p);
            APR_BUCKET_REMOVE(b);
            eos_bucket = b;
            break;
        }
    }


    /* If the iteration over the brigade hasn't found an EOS bucket, just save
     * the brigade and return.
     */
    if (eos != 1) {
        ap_save_brigade(f, &ctx->bb, &bb, ctx->p);
        return APR_SUCCESS;
    }

    if ((rv = apr_brigade_pflatten(ctx->bb, (char **)&data, &len, ctx->p)) 
        != APR_SUCCESS) { 
        /* Return if the flattening didn't work. */
        return rv;
    } else {
        /* Remove the original data from the bucket brigade. Otherwise it would
         * be passed twice (original data and the processed, flattened copy) to
         * the next filter.
         */
        apr_brigade_cleanup(ctx->bb);
    }

    /* Good cast, we just tested len isn't negative or zero */
    if (len > 0) {

        /* start checking for the regex's. */
        for (next = ctx->filter->pattern; 
             next != NULL; 
             next = next->next)
        {
            int rc = 0;
            int offset = 0;

            /* loop through the configured patterns */
            do {
                rc = pcre_exec(next->pattern, next->extra, data, 
                               len, offset, 0,
                               re_vector, RE_VECTOR_SIZE);
                               
                if (rc < 0 && rc != PCRE_ERROR_NOMATCH) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, 
                                  "Matching Error %d", rc);
                    return rc;
                }

                /* This shouldn´t happen */
                if (rc == 0) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r,
                                  "PCRE output vector too small (%d)", 
                                  RE_VECTOR_SIZE/3-1);
                }

                /* If the result count is greater than 0 then there are
                 * matches in the data string. Thus we try to replace those
                 * strings with the user provided string.
                 */
                if (rc > 0) {
                    char *prefix;   // the string before the matching part.
                    char *postfix;  // the string after the matching part.
                    char *newdata;  // the concatenated string of prefix,
                                    // the replaced string and postfix.
                    char *replacement;
                                    // the string with the data to replace
                                    // (after the subpattern processing has
                                    // been done).
                    char *to_replace[10];
                                    // the string array containing the
                                    // strings that are to be replaced.
                    int match_diff; // the difference between the matching
                                    // string and its replacement.
                    int x;          // a simple counter.
                    char *pos;      // the starting position within the
                                    // replacement string, where there is a
                                    // subpattern to replace.

                    /* start with building the replacement string */
                    replacement = apr_pstrcat(ctx->p, next->replacement,
                                              NULL);

                    /* look for the subpatterns \0 to \9 */

                    for (x = 0; x < rc && x < 10; x++) {
                        /* extract the x'ths subpattern */
                        to_replace[x] = substr(data, re_vector[x*2],
                                               re_vector[x*2+1] -
                                               re_vector[x*2], r); 

                        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                                      "Found match: %s", to_replace[x]);
                        
                        /* the token ( \0 to \9) we are looking for */
                        char *token = apr_pstrcat(ctx->p, "\\",
                                                apr_itoa(ctx->p, x), NULL);
                        /* allocate memory for the replacement operation */
                        char *tmp;
                        if (!to_replace[x] || strlen(to_replace[x]) < 2) {
                            tmp = malloc(strlen(replacement) + 1);
                        } else {
                            tmp = malloc(strlen(replacement) - 1 +
                                         strlen(to_replace[x]));
                        }
                        /* copy the replacement string to the new
                         * location.
                         */
                        memcpy(tmp, replacement, strlen(replacement) + 1);
                        replacement = tmp;
                        /* try to replace each occurence of the token with
                         * its matched subpattern. */
                        pos = ap_strstr(replacement, token);
                        while (pos) { 
                            if (!to_replace[x]) {
                                break;
                            }
                            substr_replace(pos, to_replace[x],
                                           strlen(pos), 
                                           strlen(to_replace[x]));
                            if (strlen(to_replace[x]) < 2) {
                                tmp = malloc(strlen(replacement) + 1);
                            } else {
                                tmp = malloc(strlen(replacement) - 1 + 
                                             strlen(to_replace[x]));
                            }
                            memcpy(tmp, replacement, 
                                   strlen(replacement) + 1);
                            /* clean up. */
                            free(replacement);
                            replacement = tmp; 
                            pos = ap_strstr(replacement, token);
                        }
                    }

                    match_diff = strlen(replacement) -
                                 (re_vector[1] - re_vector[0]);

                    /* Allocate memory for a buffer to copy the first part
                     * of the data string up to (but not including) the
                     * the matching pattern.
                     */
                    prefix = apr_pcalloc(ctx->p, re_vector[0] + 1);
                    if (prefix == NULL) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                            "Unable to allocate memory for prefix",
                            NULL);
                        return -1;
                    }

                    /* Copy the string from the offset (beginning of
                     * pattern matching) to the first occurence of the
                     * pattern and add a trailing \0.
                     */
                    memcpy(prefix, data, (size_t)re_vector[0]); 

                    /* Copy the string from the end of the pattern to the
                     * end of the data string itself.
                     */
                    postfix = apr_pcalloc(ctx->p, len);
                    if (postfix == NULL) {
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                            "Unable to allocate memory for postfix",
                            NULL);
                        return -1;
                    }
                    
                    memcpy(postfix, 
                           (data + re_vector[1]),
                           len - re_vector[1]);
                    
                    /* Create the new data string, replace the old one
                     * and clean up.
                     */
                    newdata = apr_pstrcat(ctx->p, prefix, 
                                          replacement, postfix, 
                                          NULL);
                    /* update the point of the data and free the allocated
                     * memory for the replacement string.
                     */
                    data = newdata;
                    free(replacement);

                    /* Calculate the new offset in the data string, where
                     * the new matching round is to begin.
                     */
                    offset = re_vector[1] + match_diff; 
                    len += match_diff;
                    modified = 1;
                }
            } while (rc > 0);
        }
        /* Adjust the real length of the processed data. */
        if (apr_table_get(f->r->headers_out, "Content-Length") != NULL) {
            apr_table_set(f->r->headers_out, "Content-Length",
                apr_itoa(ctx->p, len));
        }
        /* If an Entity Tag is set, change the mtime and generate a new ETag.*/
        if (apr_table_get(f->r->headers_out, "ETag") != NULL) {
           r->mtime = time(NULL);
           ap_set_etag(r);
        }
    }
    /* Create a new bucket with the processed data, insert that one into our
     * brigade, then insert the saved EOS bucket at the end of the brigade
     * and pass the brigade to the next filter.
     */
    APR_BRIGADE_INSERT_TAIL(ctx->bb, apr_bucket_transient_create(data, len, apr_bucket_alloc_create(ctx->p)));
    APR_BRIGADE_INSERT_TAIL(ctx->bb, eos_bucket);
    ap_pass_brigade(f->next, ctx->bb);

    return APR_SUCCESS;
}
Exemplo n.º 23
0
static int get_digest_rec(request_rec *r, digest_header_rec * response)
{
    const char *auth_line = ap_table_get(r->headers_in,
                                    r->proxyreq ? "Proxy-Authorization"
                                    : "Authorization");
    int l;
    int s, vk = 0, vv = 0;
    char *t, *key, *value;

    if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest"))
	return DECLINED;

    if (!ap_auth_name(r)) {
	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
		    "need AuthName: %s", r->uri);
	return SERVER_ERROR;
    }

    if (!auth_line) {
	ap_note_digest_auth_failure(r);
	return AUTH_REQUIRED;
    }

    if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Digest")) {
	/* Client tried to authenticate using wrong auth scheme */
	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
		    "client used wrong authentication scheme: %s", r->uri);
	ap_note_digest_auth_failure(r);
	return AUTH_REQUIRED;
    }

    l = strlen(auth_line);

    /* Note we don't allocate l + 1 bytes for these deliberately, because
     * there has to be at least one '=' character for either of these two
     * new strings to be terminated.  That takes care of the need for +1.
     */
    key = ap_palloc(r->pool, l);
    value = ap_palloc(r->pool, l);

    /* There's probably a better way to do this, but for the time being... */

#define D_KEY 0
#define D_VALUE 1
#define D_STRING 2
#define D_EXIT -1

    s = D_KEY;
    while (s != D_EXIT) {
	switch (s) {
	case D_STRING:
	    if (auth_line[0] == '\"') {
		s = D_VALUE;
	    }
	    else {
		value[vv] = auth_line[0];
		vv++;
	    }
	    auth_line++;
	    break;

	case D_VALUE:
	    if (isalnum(auth_line[0])) {
		value[vv] = auth_line[0];
		vv++;
	    }
	    else if (auth_line[0] == '\"') {
		s = D_STRING;
	    }
	    else {
		value[vv] = '\0';

		if (!strcasecmp(key, "username"))
		    response->username = ap_pstrdup(r->pool, value);
		else if (!strcasecmp(key, "realm"))
		    response->realm = ap_pstrdup(r->pool, value);
		else if (!strcasecmp(key, "nonce"))
		    response->nonce = ap_pstrdup(r->pool, value);
		else if (!strcasecmp(key, "uri"))
		    response->requested_uri = ap_pstrdup(r->pool, value);
		else if (!strcasecmp(key, "response"))
		    response->digest = ap_pstrdup(r->pool, value);

		vv = 0;
		s = D_KEY;
	    }
	    auth_line++;
	    break;

	case D_KEY:
	    if (isalnum(auth_line[0])) {
		key[vk] = auth_line[0];
		vk++;
	    }
	    else if (auth_line[0] == '=') {
		key[vk] = '\0';
		vk = 0;
		s = D_VALUE;
	    }
	    auth_line++;
	    break;
	}

	if (auth_line[-1] == '\0')
	    s = D_EXIT;
    }

    if (!response->username || !response->realm || !response->nonce ||
	!response->requested_uri || !response->digest) {
	ap_note_digest_auth_failure(r);
	return AUTH_REQUIRED;
    }

    r->connection->user = response->username;
    r->connection->ap_auth_type = "Digest";

    return OK;
}
Exemplo n.º 24
0
static int dbm_check_auth(request_rec *r)
{
    dbm_auth_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                     &auth_dbm_module);
    char *user = r->user;
    int m = r->method_number;

    const apr_array_header_t *reqs_arr = ap_requires(r);
    require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL;

    register int x;
    const char *t;
    char *w;

    if (!conf->auth_dbmgrpfile)
        return DECLINED;
    if (!reqs_arr)
        return DECLINED;

    for (x = 0; x < reqs_arr->nelts; x++) {

        if (!(reqs[x].method_mask & (AP_METHOD_BIT << m)))
            continue;

        t = reqs[x].requirement;
        w = ap_getword_white(r->pool, &t);

        if (!strcmp(w, "group") && conf->auth_dbmgrpfile) {
            const char *orig_groups, *groups;
            char *v;

            if (!(groups = get_dbm_grp(r, user, conf->auth_dbmgrpfile,
                                       conf->auth_dbmtype))) {
                if (!(conf->auth_dbmauthoritative))
                    return DECLINED;
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                            "user %s not in DBM group file %s: %s",
                            user, conf->auth_dbmgrpfile, r->filename);
                ap_note_basic_auth_failure(r);
                return HTTP_UNAUTHORIZED;
            }
            orig_groups = groups;
            while (t[0]) {
                w = ap_getword_white(r->pool, &t);
                groups = orig_groups;
                while (groups[0]) {
                    v = ap_getword(r->pool, &groups, ',');
                    if (!strcmp(v, w))
                        return OK;
                }
            }
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "user %s not in right group: %s",
                          user, r->filename);
            ap_note_basic_auth_failure(r);
            return HTTP_UNAUTHORIZED;
        }
    }

    return DECLINED;
}
Exemplo n.º 25
0
static int translate_userdir(request_rec *r)
{
    ap_conf_vector_t *server_conf;
    const userdir_config *s_cfg;
    const char *userdirs;
    const char *user, *dname;
    char *redirect;
    apr_finfo_t statbuf;

    /*
     * If the URI doesn't match our basic pattern, we've nothing to do with
     * it.
     */
    if (r->uri[0] != '/' || r->uri[1] != '~') {
        return DECLINED;
    }
    server_conf = r->server->module_config;
    s_cfg = ap_get_module_config(server_conf, &userdir_module);
    userdirs = s_cfg->userdir;
    if (userdirs == NULL) {
        return DECLINED;
    }

    dname = r->uri + 2;
    user = ap_getword(r->pool, &dname, '/');

    /*
     * The 'dname' funny business involves backing it up to capture the '/'
     * delimiting the "/~user" part from the rest of the URL, in case there
     * was one (the case where there wasn't being just "GET /~user HTTP/1.0",
     * for which we don't want to tack on a '/' onto the filename).
     */

    if (dname[-1] == '/') {
        --dname;
    }

    /*
     * If there's no username, it's not for us.  Ignore . and .. as well.
     */
    if (user[0] == '\0' ||
        (user[1] == '.' && (user[2] == '\0' ||
                            (user[2] == '.' && user[3] == '\0')))) {
        return DECLINED;
    }
    /*
     * Nor if there's an username but it's in the disabled list.
     */
    if (apr_table_get(s_cfg->disabled_users, user) != NULL) {
        return DECLINED;
    }
    /*
     * If there's a global interdiction on UserDirs, check to see if this
     * name is one of the Blessed.
     */
    if (s_cfg->globally_disabled == O_DISABLE
        && apr_table_get(s_cfg->enabled_users, user) == NULL) {
        return DECLINED;
    }

    /*
     * Special cases all checked, onward to normal substitution processing.
     */

    while (*userdirs) {
        const char *userdir = ap_getword_conf(r->pool, &userdirs);
        char *filename = NULL, *prefix = NULL;
        apr_status_t rv;
        int is_absolute = ap_os_is_path_absolute(r->pool, userdir);

        if (ap_strchr_c(userdir, '*'))
            prefix = ap_getword(r->pool, &userdir, '*');

        if (userdir[0] == '\0' || is_absolute) {
            if (prefix) {
#ifdef HAVE_DRIVE_LETTERS
                /*
                 * Crummy hack. Need to figure out whether we have been
                 * redirected to a URL or to a file on some drive. Since I
                 * know of no protocols that are a single letter, ignore
                 * a : as the first or second character, and assume a file
                 * was specified
                 */
                if (strchr(prefix + 2, ':'))
#else
                if (strchr(prefix, ':') && !is_absolute)
#endif /* HAVE_DRIVE_LETTERS */
                {
                    redirect = apr_pstrcat(r->pool, prefix, user, userdir,
                                           dname, NULL);
                    apr_table_setn(r->headers_out, "Location", redirect);
                    return HTTP_MOVED_TEMPORARILY;
                }
                else
                    filename = apr_pstrcat(r->pool, prefix, user, userdir,
                                           NULL);
            }
            else
                filename = apr_pstrcat(r->pool, userdir, "/", user, NULL);
        }
        else if (prefix && ap_strchr_c(prefix, ':')) {
            redirect = apr_pstrcat(r->pool, prefix, user, dname, NULL);
            apr_table_setn(r->headers_out, "Location", redirect);
            return HTTP_MOVED_TEMPORARILY;
        }
        else {
#if APR_HAS_USER
            char *homedir;

            if (apr_uid_homepath_get(&homedir, user, r->pool) == APR_SUCCESS) {
                filename = apr_pstrcat(r->pool, homedir, "/", userdir, NULL);
            }
#else
            return DECLINED;
#endif
        }

        /*
         * Now see if it exists, or we're at the last entry. If we are at the
         * last entry, then use the filename generated (if there is one)
         * anyway, in the hope that some handler might handle it. This can be
         * used, for example, to run a CGI script for the user.
         */
        if (filename && (!*userdirs
                      || ((rv = apr_stat(&statbuf, filename, APR_FINFO_MIN,
                                         r->pool)) == APR_SUCCESS
                                             || rv == APR_INCOMPLETE))) {
            r->filename = apr_pstrcat(r->pool, filename, dname, NULL);
            ap_set_context_info(r, apr_pstrmemdup(r->pool, r->uri,
                                                  dname - r->uri),
                                filename);
            /* XXX: Does this walk us around FollowSymLink rules?
             * When statbuf contains info on r->filename we can save a syscall
             * by copying it to r->finfo
             */
            if (*userdirs && dname[0] == 0)
                r->finfo = statbuf;

            /* For use in the get_suexec_identity phase */
            apr_table_setn(r->notes, "mod_userdir_user", user);

            return OK;
        }
    }

    return DECLINED;
}
Exemplo n.º 26
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 a handle to the directory config */
	oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
			&auth_openidc_module);

	*access_token = NULL;

	if ((dir_cfg->oauth_accept_token_in & OIDC_OAUTH_ACCEPT_TOKEN_IN_HEADER)
			|| (dir_cfg->oauth_accept_token_in
					== OIDC_OAUTH_ACCEPT_TOKEN_IN_DEFAULT)) {

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

			/* look for the Bearer keyword */
			if (apr_strnatcasecmp(ap_getword(r->pool, &auth_line, ' '),
					"Bearer") == 0) {

				/* 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);

			} else {
				oidc_warn(r,
						"client used unsupported authentication scheme: %s",
						r->uri);
			}
		}
	}

	if ((*access_token == NULL) && (r->method_number == M_POST)
			&& (dir_cfg->oauth_accept_token_in & OIDC_OAUTH_ACCEPT_TOKEN_IN_POST)) {
		apr_table_t *params = apr_table_make(r->pool, 8);
		if (oidc_util_read_post_params(r, params) == TRUE) {
			*access_token = apr_table_get(params, "access_token");
		}
	}

	if ((*access_token == NULL)
			&& (dir_cfg->oauth_accept_token_in
					& OIDC_OAUTH_ACCEPT_TOKEN_IN_QUERY)) {
		apr_table_t *params = apr_table_make(r->pool, 8);
		oidc_util_read_form_encoded_params(r, params, r->args);
		*access_token = apr_table_get(params, "access_token");
	}

	if ((*access_token == NULL)
			&& (dir_cfg->oauth_accept_token_in
					& OIDC_OAUTH_ACCEPT_TOKEN_IN_COOKIE)) {

		const char *cookie_name = apr_hash_get(
				dir_cfg->oauth_accept_token_options, "cookie-name",
				APR_HASH_KEY_STRING);
		const char *auth_line = oidc_util_get_cookie(r, cookie_name);
		if (auth_line != NULL) {

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

		} else {
			oidc_warn(r, "no cookie found with name: %s", cookie_name);
		}
	}

	if (*access_token == NULL) {
		oidc_debug(r,
				"no bearer token found in the allowed methods (authorization header, post, query parameter or cookie)");
		return FALSE;
	}

	/* log some stuff */
	oidc_debug(r, "bearer token: %s", *access_token);
	return TRUE;
}
Exemplo n.º 27
0
static authz_status dbmfilegroup_check_authorization(request_rec *r,
                                                     const char *require_args,
                                                     const void *parsed_require_args)
{
    authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                      &authz_dbm_module);
    char *user = r->user;
    const char *realm = ap_auth_name(r);
    const char *filegroup = NULL;
    const char *orig_groups = NULL;
    apr_status_t status;
    const char *groups;
    char *v;

    if (!user) {
        return AUTHZ_DENIED_NO_USER;
    }

    if (!conf->grpfile) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01802)
                        "No group file was specified in the configuration");
        return AUTHZ_DENIED;
    }

    /* fetch group data from dbm file. */
    status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, NULL),
                         user, conf->grpfile, conf->dbmtype, &groups);

    if (status != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01803)
                      "could not open dbm (type %s) group access "
                      "file: %s", conf->dbmtype, conf->grpfile);
        return AUTHZ_DENIED;
    }

    if (groups == NULL) {
        /* no groups available, so exit immediately */
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01804)
                      "Authorization of user %s to access %s failed, reason: "
                      "user doesn't appear in DBM group file (%s).",
                      r->user, r->uri, conf->grpfile);
        return AUTHZ_DENIED;
    }

    orig_groups = groups;

    filegroup = authz_owner_get_file_group(r);

    if (filegroup) {
        groups = orig_groups;
        while (groups[0]) {
            v = ap_getword(r->pool, &groups, ',');
            if (!strcmp(v, filegroup)) {
                return AUTHZ_GRANTED;
            }
        }
    }

    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01805)
                  "Authorization of user %s to access %s failed, reason: "
                  "user is not part of the 'require'ed group(s).",
                  r->user, r->uri);

    return AUTHZ_DENIED;
}
Exemplo n.º 28
0
static int isUserValid(const char *user, 
		       const char *password, 
		       yubiauth_dir_cfg *cfg, 
		       request_rec *r)
{

    ap_configfile_t *f;
    char l[MAX_STRING_LEN];
    apr_status_t status;
    char *file_password = NULL;
    char *yubiKeyId = NULL;
    char *userPassword = NULL;
    apr_size_t passwordLength = 0;
    char *realName = NULL;
    int userWasFound = FALSE;
    /* This is TRUE when we store a combination of yubikeyId:username:password,
     * we then have a two factor authentication.
     */
    int tokenHasPassword = FALSE;

    status = ap_pcfg_openfile(&f, r->pool, cfg->userAuthDbFilename);

    if (status != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                      LOG_PREFIX "Could not open AuthYkUserFile file: %s", 
		      cfg->userAuthDbFilename);
        return FALSE;
    }

    /* Do length check of at least the password part,
     * to be a yubikey token, it has to have at least 44
     * characters from where the first 12 are the ID of the user.
     */
    if (strlen(password) < YUBIKEY_TOKEN_LENGTH) {
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
		    LOG_PREFIX "The entered password cannot be a yubikey generated token");
      ap_cfg_closefile(f);
      return FALSE;
    }

    

    /* If the password is bigger then 44 characters, then we have an additional password
     * set into the field, since the produced token by the yubikey is 44 characters long
     */
    passwordLength = (apr_size_t) strlen(password) - YUBIKEY_TOKEN_LENGTH;
    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
		  LOG_PREFIX "The length of the entered password is: %d", passwordLength);

    /* We have to distinct between a 44 character string which is the
     * toke output only and a longer string, which would contain a
     * password at its beginning
     */
    if (strlen(password) > YUBIKEY_TOKEN_LENGTH) {
	/* copy off the password part from the password string */
	userPassword = apr_pstrndup(r->pool, password, passwordLength);
	ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
		  LOG_PREFIX "The entered password is: %s", userPassword);
    }

    /* Now move the password pointer forward the number of calculatd characters for the userPassword,
     * we move the pointer beyond the last read character (not -1), to start reading the real stuff
     */
     yubiKeyId = apr_pstrndup(r->pool, &password[passwordLength], (apr_size_t) YUBIKEY_ID_LENGTH);
     ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
		  LOG_PREFIX "The calculated YubiKey ID is: %s", yubiKeyId);

    /* Find the TokenID/UN:PW solution in the file */
    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        const char *rpw, *w;
	char *unPw = NULL;

        /* Skip # or blank lines. */
        if ((l[0] == '#') || (!l[0])) {
            continue;
        }

        rpw = l;
        w = ap_getword(r->pool, &rpw, ':');
        
	/* The first 12 chars are the ID which must be available in this file
	 * else the user might be a yubikey user, but possibly a user we don't
	 * want.
	 */
        if (!strncmp(yubiKeyId, w, 12)) {
	  /* This would fetch the real username,
	   * after the ID could be located
	   */
	  ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
			LOG_PREFIX "Could find the ID: %s", w);
	  /* remember, since we are working with the passwd
	   * utility, this realName is hashed
	   */
          realName = ap_getword(r->pool, &rpw, '\n');
          apr_table_set(r->headers_in, HDR_YK_AUTH_TYPE, YK_AUTH_TYPE_OF);
	  ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
			LOG_PREFIX "The looked up realname is: %s", realName);
	  ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
			LOG_PREFIX "The looked up userPassword is: %s", userPassword);
	  /* this results in username:password as it should be entered in the install dialog */
	  if (userPassword) {
	    unPw = apr_pstrcat(r->pool, user, ":", userPassword, NULL);
	    apr_table_set(r->headers_in, HDR_YK_AUTH_TYPE, YK_AUTH_TYPE_TF);
	    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
			LOG_PREFIX "The built un:pw combo is: %s", unPw);
	  }
	  /* If there is a password set, use the username:password combo,
	   * else just compare the username
	   */
	  status = apr_password_validate(userPassword?unPw:user, realName);

	  if (status == APR_SUCCESS) {
	    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
			    LOG_PREFIX "Could map ID %s to User: %s", w, user);
	    userWasFound = TRUE;
	    break;
	  }   
        }	
    }
    ap_cfg_closefile(f);

    return userWasFound;
}
Exemplo n.º 29
0
int ApacheRequest_parse_multipart(ApacheRequest *req)
{
    request_rec *r = req->r;
    int rc = OK;
    const char *ct = ap_table_get(r->headers_in, "Content-Type");
    long length;
    char *boundary;
    multipart_buffer *mbuff;
    ApacheUpload *upload = NULL;

    if (!ct) {
	ap_log_rerror(REQ_ERROR, "[libapreq] no Content-type header!");
	return HTTP_INTERNAL_SERVER_ERROR;
    }

    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
        return rc;
    }

    if (!ap_should_client_block(r)) {
	return rc;
    }

    if ((length = r->remaining) > req->post_max && req->post_max > 0) {
	ap_log_rerror(REQ_ERROR, "[libapreq] entity too large (%d, max=%d)",
		     (int)length, req->post_max);
	return HTTP_REQUEST_ENTITY_TOO_LARGE;
    }

    (void)ap_getword(r->pool, &ct, '=');
    boundary = ap_getword_conf(r->pool, &ct);

    if (!(mbuff = multipart_buffer_new(boundary, length, r))) {
	return DECLINED;
    }

    while (!multipart_buffer_eof(mbuff)) {
	table *header = multipart_buffer_headers(mbuff);
	const char *cd, *param=NULL, *filename=NULL;
	char buff[FILLUNIT];
	int blen, wlen;

	if (!header) {
#ifdef DEBUG
            ap_log_rerror(REQ_ERROR,
		      "[libapreq] silently drop remaining '%ld' bytes", r->remaining);
#endif
            ap_hard_timeout("[libapreq] parse_multipart", r);
            while ( ap_get_client_block(r, buff, sizeof(buff)) > 0 )
                /* wait for more input to ignore */ ;
            ap_kill_timeout(r);
	    return OK;
	}

	if ((cd = ap_table_get(header, "Content-Disposition"))) {
	    const char *pair;

	    while (*cd && (pair = ap_getword(r->pool, &cd, ';'))) {
		const char *key;

		while (ap_isspace(*cd)) {
		    ++cd;
		}
		if (ap_ind(pair, '=')) {
		    key = ap_getword(r->pool, &pair, '=');
		    if(strEQ(key, "name")) {
			param = ap_getword_conf(r->pool, &pair);
		    }
		    else if(strEQ(key, "filename")) {
			filename = ap_getword_conf(r->pool, &pair);
		    }
		}
	    }
	    if (!filename) {
	        char *value = multipart_buffer_read_body(mbuff);
	        ap_table_add(req->parms, param, value);
		continue;
	    }
	    if (!param) continue; /* shouldn't happen, but just in case. */

            if (req->disable_uploads) {
                ap_log_rerror(REQ_ERROR, "[libapreq] file upload forbidden");
                return HTTP_FORBIDDEN;
            }

	    ap_table_add(req->parms, param, filename);

	    if (upload) {
		upload->next = ApacheUpload_new(req);
		upload = upload->next;
	    }
	    else {
		upload = ApacheUpload_new(req);
		req->upload = upload;
	    }

	    if (! req->upload_hook && ! ApacheRequest_tmpfile(req, upload) ) {
		return HTTP_INTERNAL_SERVER_ERROR;
	    }

	    upload->info = header;
	    upload->filename = ap_pstrdup(req->r->pool, filename);
	    upload->name = ap_pstrdup(req->r->pool, param);

            /* mozilla empty-file (missing CRLF) hack */
            fill_buffer(mbuff);
            if( strEQN(mbuff->buf_begin, mbuff->boundary, 
                      strlen(mbuff->boundary)) ) {
                r->remaining -= 2;
                continue; 
            }

	    while ((blen = multipart_buffer_read(mbuff, buff, sizeof(buff)))) {
		if (req->upload_hook != NULL) {
		    wlen = req->upload_hook(req->hook_data, buff, blen, upload);
		} else {
		    wlen = fwrite(buff, 1, blen, upload->fp);
		}
		if (wlen != blen) {
		    return HTTP_INTERNAL_SERVER_ERROR;
		}
		upload->size += wlen;
	    }

	    if (upload->size > 0 && (upload->fp != NULL)) {
		fseek(upload->fp, 0, 0);
	    }
	}
    }

    return OK;
}
Exemplo n.º 30
0
/* This provides a simple UI for accessing the key database 
 * used to grant access to users owning a yubikey or not.
 *
 * This is primarily a web version of htaccess.
 */
static int authn_yubikey_handler(request_rec *r)
{
    ap_configfile_t *f;
    char l[MAX_STRING_LEN];
    apr_status_t status;
    char *file_password = NULL;
    char *yubiKeyId = NULL;
    char *realName = NULL;
    apr_file_t *dbFormFile = NULL;
    yubiauth_dir_cfg *cfg = ap_get_module_config(r->per_dir_config, &authn_yubikey_module);

    if (strcmp(r->handler, "authn_yubikey")) {
        return DECLINED;
    }
    r->content_type = "text/html";

    /* Post back */
    if (r->method_number == M_POST) {
      const char *postbackContent = NULL;
      char *tmp = NULL;
      char buffer[1024];
      //Read the POST data sent from the client
      ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);

      if ( ap_should_client_block(r) == 1 ) {
              while ( ap_get_client_block(r, buffer, 1024) > 0 ) {
		postbackContent = apr_pstrcat(r->pool, buffer, tmp, NULL);
		//tmp = apr_pstrdup(r->pool, postbackContent);
	          }
      }
      else {
	        ap_rputs("No POST data available",r);
      }
      //We have the data now, now process it and save it into the db
      

      ap_set_content_type(r, "text/plain;");
      ap_rprintf(r, "Postback content: %s", postbackContent);

      return OK;
    }

    /* Serve content if it's a GET request */
    if (!r->header_only) {
      ap_rputs("<html><head><title>YubiAuth user management</title></head><body>", r);
      ap_rputs("<h1>Welcome to the YubiAuth user Mgmt.</h1><br>", r);
      ap_rputs("The following users could be found inside the database:<br>", r);
      //Open userDb file for looped output
      status = ap_pcfg_openfile(&f, r->pool, cfg->userAuthDbFilename);
      if (status != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                      LOG_PREFIX "Could not open YubiAuthUserDb file: %s", 
		      cfg->userAuthDbFilename);
        return HTTP_INTERNAL_SERVER_ERROR;
      }
      ap_rputs("<table><thead><tr><th>TokenId</th><th>Real Name</th></tr></thead><tbody>\n", r);
      while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
        const char *rpw, *w;

        /* Skip # or blank lines. */
        if ((l[0] == '#') || (!l[0])) {
	  continue;
        }

        rpw = l;
        w = ap_getword(r->pool, &rpw, ':');
	//yubiKeyId = apr_pstrndup(r->pool, password, (apr_size_t) 12);
        //realName = ap_getword(r->pool, &rpw, ':');
	ap_rputs("<tr>", r);
	ap_rprintf(r, "<td>%s</td>", w);
	ap_rprintf(r, "<td>%s</td>\n", rpw);
	ap_rputs("</tr>", r);
      }
      ap_cfg_closefile(f);
      ap_rputs("</tbody></table>", r);
      ap_rputs("<h1>Want to add a user?</h1>.", r);
      ap_rputs("<form name=\"addUser\" method=\"POST\" action=\"/authme\">", r);
      ap_rputs("<input type=\"text\" name=\"tokenId\">", r);
      ap_rputs("<input type=\"text\" name=\"realUser\">", r);
      ap_rputs("<input type=\"submit\" value=\"Add User\">", r);
      ap_rputs("</form>", r);
      ap_rputs("</body></html>", r);
    }

    //If we receive a POST to this location, we probably want to update the userdb
    //be sure to check if there is a user set and that this user is allowed to change information
    // inside the userdb, we cn authenticate the user with the OTP token here too.
    //We should make the administrative user configurable, by specifying the token which is allowed
    // access ...
    return OK;
}