📄 auth_basic.c
字号:
storeAppendPrintf(entry, "%s %s children %d\n", name, "basic", config->authenticateChildren); storeAppendPrintf(entry, "%s %s concurrency %d\n", name, "basic", config->authenticateConcurrency); storeAppendPrintf(entry, "%s %s credentialsttl %d seconds\n", name, "basic", (int) config->credentialsTTL); storeAppendPrintf(entry, "%s %s casesensitive %s\n", name, "basic", config->casesensitive ? "on" : "off"); storeAppendPrintf(entry, "%s %s blankpassword %s\n", name, "basic", config->blankpassword ? "on" : "off");}static voidauthBasicParse(authScheme * scheme, int n_configured, char *param_str){ if (scheme->scheme_data == NULL) { assert(basicConfig == NULL); /* this is the first param to be found */ scheme->scheme_data = xmalloc(sizeof(auth_basic_config)); memset(scheme->scheme_data, 0, sizeof(auth_basic_config)); basicConfig = scheme->scheme_data; basicConfig->basicAuthRealm = xstrdup("Squid proxy-caching web server"); basicConfig->authenticateChildren = 5; basicConfig->credentialsTTL = 2 * 60 * 60; /* two hours */ } basicConfig = scheme->scheme_data; if (strcasecmp(param_str, "program") == 0) { if (basicConfig->authenticate) wordlistDestroy(&basicConfig->authenticate); parse_wordlist(&basicConfig->authenticate); } else if (strcasecmp(param_str, "children") == 0) { parse_int(&basicConfig->authenticateChildren); } else if (strcasecmp(param_str, "concurrency") == 0) { parse_int(&basicConfig->authenticateConcurrency); } else if (strcasecmp(param_str, "realm") == 0) { parse_eol(&basicConfig->basicAuthRealm); } else if (strcasecmp(param_str, "credentialsttl") == 0) { parse_time_t(&basicConfig->credentialsTTL); } else if (strcasecmp(param_str, "casesensitive") == 0) { parse_onoff(&basicConfig->casesensitive); } else if (strcasecmp(param_str, "blankpassword") == 0) { parse_onoff(&basicConfig->blankpassword); } else { debug(29, 0) ("unrecognised basic auth scheme parameter '%s'\n", param_str); }}static voidauthBasicCheckConfig(authScheme * scheme){ auth_basic_config *config = scheme->scheme_data; requirePathnameExists("auth_param basic program", config->authenticate->key);}static voidauthenticateBasicStats(StoreEntry * sentry){ storeAppendPrintf(sentry, "Basic Authenticator Statistics:\n"); helperStats(sentry, basicauthenticators);}CBDATA_TYPE(authenticateStateData);/* authenticateBasicUsername: return a pointer to the username in the */char *authenticateBasicUsername(auth_user_t * auth_user){ basic_data *basic_auth = auth_user->scheme_data; if (basic_auth) return basic_auth->username; return NULL;}static basic_data *authBasicDataNew(void){ basic_data *temp; temp = memPoolAlloc(basic_data_pool); assert(temp != NULL); temp->username = NULL; temp->passwd = NULL; temp->auth_queue = NULL; return temp;}#if UNUSED_CODEstatic voidauthBasicDataFree(basic_data * basic_auth){}#endifstatic auth_user_t *authBasicAuthUserFindUsername(const char *username){ auth_user_hash_pointer *usernamehash; debug(29, 9) ("authBasicAuthUserFindUsername: Looking for user '%s'\n", username); if (username && (usernamehash = hash_lookup(proxy_auth_username_cache, username))) { while (usernamehash) { if ((usernamehash->auth_user->auth_type == AUTH_BASIC) && !strcmp(username, usernamehash->key)) return usernamehash->auth_user; usernamehash = usernamehash->next; } } return NULL;}/* * Decode a Basic [Proxy-]Auth string, linking the passed auth_user_request structure * to any existing user structure or creating one if needed. Note that just returning * will be treated as "cannot decode credentials". Use the message field to return a * descriptive message to the user. */static voidauthenticateBasicDecodeAuth(auth_user_request_t * auth_user_request, const char *proxy_auth){ char *sent_auth; char *cleartext; basic_data *basic_auth, local_basic; auth_user_t *auth_user; dlink_node *node; /* decode the username */ /* trim BASIC from string */ while (xisgraph(*proxy_auth)) proxy_auth++; local_basic.passwd = NULL; /* Trim leading whitespace before decoding */ while (xisspace(*proxy_auth)) proxy_auth++; /* username and password */ sent_auth = xstrdup(proxy_auth); /* Trim trailing \n before decoding */ strtok(sent_auth, "\n"); cleartext = uudecode(sent_auth); xfree(sent_auth); /* * Don't allow NL or CR in the credentials. * Oezguer Kesim <oec@codeblau.de> */ debug(29, 9) ("authenticateBasicDecodeAuth: cleartext = '%s'\n", cleartext); if (strcspn(cleartext, "\r\n") != strlen(cleartext)) { debug(29, 1) ("authenticateBasicDecodeAuth: bad characters in authorization header '%s'\n", proxy_auth); xfree(cleartext); return; } local_basic.username = cleartext; if ((cleartext = strchr(local_basic.username, ':')) != NULL) *(cleartext)++ = '\0'; local_basic.passwd = cleartext; if (cleartext == NULL) { debug(29, 4) ("authenticateBasicDecodeAuth: no password in proxy authorization header '%s'\n", proxy_auth); local_basic.passwd = NULL; auth_user_request->message = xstrdup("no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug"); } else if (*cleartext == '\0' && !basicConfig->blankpassword) { debug(29, 4) ("authenticateBasicDecodeAuth: Disallowing empty password," "user is '%s'\n", local_basic.username); local_basic.passwd = NULL; auth_user_request->message = xstrdup("Request denied because you provided an empty password. Users MUST have a password."); } /* special case: we have to free the strings for user and password * if we are not returning a filled out structure */ if (local_basic.passwd == NULL) { if (local_basic.username) { /* log the username */ debug(29, 9) ("authBasicDecodeAuth: Creating new user for logging '%s'\n", local_basic.username); /* new auth_user */ auth_user = authenticateAuthUserNew("basic"); /* new scheme data */ basic_auth = authBasicDataNew(); /* save the credentials */ basic_auth->username = local_basic.username; /* link the scheme data in */ auth_user->scheme_data = basic_auth; /* set the auth_user type */ auth_user->auth_type = AUTH_BROKEN; /* link the request to the user */ auth_user_request->auth_user = auth_user; /* lock for the auth_user_request link */ authenticateAuthUserLock(auth_user); node = dlinkNodeNew(); dlinkAdd(auth_user_request, node, &auth_user->requests); } return; } else { local_basic.passwd = xstrndup(cleartext, USER_IDENT_SZ); } if (!basicConfig->casesensitive) Tolower(local_basic.username); /* now lookup and see if we have a matching auth_user structure in memory. */ if ((auth_user = authBasicAuthUserFindUsername(local_basic.username)) == NULL) { /* the user doesn't exist in the username cache yet */ debug(29, 9) ("authBasicDecodeAuth: Creating new user '%s'\n", local_basic.username); /* new auth_user */ auth_user = authenticateAuthUserNew("basic"); /* new scheme data */ basic_auth = authBasicDataNew(); /* save the credentials */ basic_auth->username = local_basic.username; basic_auth->passwd = local_basic.passwd; /* link the scheme data in */ auth_user->scheme_data = basic_auth; /* set the auth_user type */ auth_user->auth_type = AUTH_BASIC; /* current time for timeouts */ auth_user->expiretime = current_time.tv_sec; /* this auth_user struct is the 'lucky one' to get added to the username cache */ /* the requests after this link to the auth_user */ /* store user in hash */ authenticateUserNameCacheAdd(auth_user); } else { debug(29, 9) ("authBasicDecodeAuth: Found user '%s' in the user cache as '%p'\n", local_basic.username, auth_user); xfree(local_basic.username); basic_auth = auth_user->scheme_data; if (strcmp(local_basic.passwd, basic_auth->passwd)) { debug(29, 4) ("authBasicDecodeAuth: new password found. Updating in user master record and resetting auth state to unchecked\n"); basic_auth->flags.credentials_ok = 0; xfree(basic_auth->passwd); basic_auth->passwd = local_basic.passwd; } else xfree(local_basic.passwd); if (basic_auth->flags.credentials_ok == 3) { debug(29, 4) ("authBasicDecodeAuth: last attempt to authenticate this user failed, resetting auth state to unchecked\n"); basic_auth->flags.credentials_ok = 0; } } /* link the request to the user */ auth_user_request->auth_user = auth_user; /* lock for the auth_user_request link */ authenticateAuthUserLock(auth_user); node = dlinkNodeNew(); dlinkAdd(auth_user_request, node, &auth_user->requests); return;}/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */static voidauthBasicInit(authScheme * scheme){ static int init = 0; if (basicConfig->authenticate) { if (!basic_data_pool) basic_data_pool = memPoolCreate("Basic Scheme User Data", sizeof(basic_data)); authbasic_initialised = 1; if (basicauthenticators == NULL) basicauthenticators = helperCreate("basicauthenticator"); basicauthenticators->cmdline = basicConfig->authenticate; basicauthenticators->n_to_start = basicConfig->authenticateChildren; basicauthenticators->concurrency = basicConfig->authenticateConcurrency; basicauthenticators->ipc_type = IPC_STREAM; helperOpenServers(basicauthenticators); if (!init) { cachemgrRegister("basicauthenticator", "Basic User Authenticator Stats", authenticateBasicStats, 0, 1); init++; } CBDATA_INIT_TYPE(authenticateStateData); }}/* send the initial data to a basic authenticator module */static voidauthenticateBasicStart(auth_user_request_t * auth_user_request, RH * handler, void *data){ authenticateStateData *r = NULL; char buf[8192]; char user[1024], pass[1024]; basic_data *basic_auth; assert(auth_user_request); assert(handler); assert(auth_user_request->auth_user->auth_type == AUTH_BASIC); assert(auth_user_request->auth_user->scheme_data != NULL); basic_auth = auth_user_request->auth_user->scheme_data; debug(29, 9) ("authenticateStart: '%s:%s'\n", basic_auth->username, basic_auth->passwd); if (basicConfig->authenticate == NULL) { handler(data, NULL); return; } /* check to see if the auth_user already has a request outstanding */ if (basic_auth->flags.credentials_ok == 2) { /* there is a request with the same credentials already being verified */ auth_basic_queue_node *node; node = xmalloc(sizeof(auth_basic_queue_node)); assert(node); /* save the details */ node->next = basic_auth->auth_queue; basic_auth->auth_queue = node; node->handler = handler; node->data = data; cbdataLock(data); return; } else { r = cbdataAlloc(authenticateStateData); r->handler = handler; cbdataLock(data); r->data = data; r->auth_user_request = auth_user_request; authenticateAuthUserRequestLock(r->auth_user_request); /* mark the user as haveing verification in progress */ basic_auth->flags.credentials_ok = 2; xstrncpy(user, rfc1738_escape(basic_auth->username), sizeof(user)); xstrncpy(pass, rfc1738_escape(basic_auth->passwd), sizeof(pass)); snprintf(buf, sizeof(buf), "%s %s\n", user, pass); helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -