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