📄 htaabrow.c
字号:
HTList_delete(killme->valid_schemes); killme->valid_schemes = NULL; } for (scheme = 0; scheme < HTAA_MAX_SCHEMES; scheme++) if (killme->scheme_specifics[scheme]) HTAssocList_delete(killme->scheme_specifics[scheme]); FREE(killme->scheme_specifics); FREE(killme); }}/* PRIVATE HTAASetup_updateSpecifics()* COPY SCHEME SPECIFIC PARAMETERS** TO HTAASetup STRUCTURE** ON ENTRY:** setup destination setup structure.** specifics string array containing scheme** specific parameters for each scheme.** If NULL, all the scheme specific** parameters are set to NULL.**** ON EXIT:** returns nothing.*/PRIVATE void HTAASetup_updateSpecifics ARGS2( HTAASetup *, setup, HTAssocList **, specifics){ int scheme; if (setup) { if (setup->scheme_specifics) { for (scheme = 0; scheme < HTAA_MAX_SCHEMES; scheme++) { if (setup->scheme_specifics[scheme]) HTAssocList_delete(setup->scheme_specifics[scheme]); } FREE(setup->scheme_specifics); } setup->scheme_specifics = specifics; }}/*************************** HTAARealm **********************************//* PRIVATE HTAARealm_lookup()** LOOKUP HTAARealm STRUCTURE BY REALM NAME** ON ENTRY:** realm_table a list of realm objects.** realmname is the name of realm to look for.**** ON EXIT:** returns the realm. NULL, if not found.*/PRIVATE HTAARealm *HTAARealm_lookup ARGS2( HTList *, realm_table, CONST char *, realmname){ if (realm_table && realmname) { HTList *cur = realm_table; HTAARealm *realm; while (NULL != (realm = (HTAARealm*)HTList_nextObject(cur))) { if (0==strcmp(realm->realmname, realmname)) return realm; } } return NULL; /* No table, NULL param, or not found */}/* PRIVATE HTAARealm_new()** CREATE A NODE CONTAINING USERNAME AND** PASSWORD USED FOR THE GIVEN REALM.** IF REALM ALREADY EXISTS, CHANGE** USERNAME/PASSWORD.** ON ENTRY:** realm_table a list of realms to where to add** the new one, too.** realmname is the name of the password domain.** username and** password are what you can expect them to be.**** ON EXIT:** returns the created realm.*/PRIVATE HTAARealm *HTAARealm_new ARGS4( HTList *, realm_table, CONST char *, realmname, CONST char *, username, CONST char *, password){ HTAARealm *realm; realm = HTAARealm_lookup(realm_table, realmname); if (!realm) { if ((realm = typecalloc(HTAARealm)) == 0) outofmem(__FILE__, "HTAARealm_new"); realm->realmname = NULL; realm->username = NULL; realm->password = NULL; StrAllocCopy(realm->realmname, realmname); if (realm_table) HTList_addObject(realm_table, (void*)realm); } if (username) StrAllocCopy(realm->username, username); if (password) StrAllocCopy(realm->password, password); return realm;}/***************** Basic and Pubkey Authentication ************************//* PRIVATE compose_auth_string()**** COMPOSE Basic OR Pubkey AUTHENTICATION STRING;** PROMPTS FOR USERNAME AND PASSWORD IF NEEDED**** ON ENTRY:** scheme is either HTAA_BASIC or HTAA_PUBKEY.** setup is the current server setup.** IsProxy should be TRUE if this is a proxy.**** ON EXIT:** returns a newly composed authorization string,** (with, of course, a newly generated secret** key and fresh timestamp, if Pubkey-scheme** is being used).** NULL, if something fails.** NOTE:** Like throughout the entire AA package, no string or structure** returned by AA package needs to (or should) be freed.***/PRIVATE char *compose_auth_string ARGS3( HTAAScheme, scheme, HTAASetup *, setup, BOOL, IsProxy){ char *cleartext = NULL; /* Cleartext presentation */ char *ciphertext = NULL; /* Encrypted presentation */ int len; char *msg = NULL; char *username = NULL; char *password = NULL; char *realmname = NULL; char *theHost = NULL; char *proxiedHost = NULL; char *thePort = NULL; HTAARealm *realm; char *i_net_addr = "0.0.0.0"; /* Change... @@@@ */ char *timestamp = "42"; /* ... these @@@@ */ FREE(compose_auth_stringResult); /* From previous call */ if ((scheme != HTAA_BASIC && scheme != HTAA_PUBKEY) || !setup || !setup->scheme_specifics || !setup->scheme_specifics[scheme] || !setup->server || !setup->server->realms) return NULL; realmname = HTAssocList_lookup(setup->scheme_specifics[scheme], "realm"); if (!realmname) return NULL; realm = HTAARealm_lookup(setup->server->realms, realmname); if (!(realm && realm->username && *realm->username && realm->password) || setup->retry) { if (!realm) { CTRACE((tfp, "%s `%s' %s\n", "compose_auth_string: realm:", realmname, "not found -- creating")); realm = HTAARealm_new(setup->server->realms, realmname, NULL, NULL); } /* * The template should be either the '*' global * for everything on the server (always true for * proxy authorization setups), or a path for * the start of a protected limb, with no host * field, but we'll check for a host anyway in * case a WWW-Protection-Template header set an * absolute URL instead of a path. If we do get * a host from this, it will include the port. - FM */ if ((!IsProxy) && using_proxy && setup->template) { proxiedHost = HTParse(setup->template, "", PARSE_HOST); if (proxiedHost && *proxiedHost != '\0') { theHost = proxiedHost; } } /* * If we didn't get a host field from the * template, set up the host name and port * from the setup->server elements. - FM */ if (!theHost) theHost = setup->server->hostname; if (setup->server->portnumber > 0 && setup->server->portnumber != 80) { HTSprintf0(&thePort, ":%d", setup->server->portnumber); } /* * Set up the message for the username prompt, * and then issue the prompt. The default * username is included in the call to the * prompting function, but the password is * NULL-ed and always replaced. - FM */ len = strlen(realm->realmname) + strlen(theHost ? theHost : "??") + 50; HTSprintf0(&msg, gettext("Username for '%s' at %s '%s%s':"), realm->realmname, (IsProxy ? "proxy" : "server"), (theHost ? theHost : "??"), NonNull(thePort)); FREE(proxiedHost); FREE(thePort); username = realm->username; password = NULL; HTPromptUsernameAndPassword(msg, &username, &password, IsProxy); FREE(msg); FREE(realm->username); FREE(realm->password); realm->username = username; realm->password = password; if (!realm->username || !realm->password) { /* * Signals to retry. - FM */ return NULL; } else if (*realm->username == '\0') { /* * Signals to abort. - FM */ StrAllocCopy(compose_auth_stringResult, ""); return compose_auth_stringResult; } } len = strlen(NonNull(realm->username)) + strlen(NonNull(realm->password)) + 3; if (scheme == HTAA_PUBKEY) {#ifdef PUBKEY /* Generate new secret key */ StrAllocCopy(secret_key, HTAA_generateRandomKey());#endif /* PUBKEY */ /* Room for secret key, timestamp and inet address */ len += strlen(NonNull(secret_key)) + 30; } else { FREE(secret_key); } if ((cleartext = typecallocn(char, len)) == 0) outofmem(__FILE__, "compose_auth_string"); if (realm->username) strcpy(cleartext, realm->username); else *cleartext = '\0'; strcat(cleartext, ":"); if (realm->password) strcat(cleartext, realm->password); if (scheme == HTAA_PUBKEY) { strcat(cleartext, ":"); strcat(cleartext, i_net_addr); strcat(cleartext, ":"); strcat(cleartext, timestamp); strcat(cleartext, ":"); if (secret_key) strcat(cleartext, secret_key); if (!((ciphertext = typecallocn(char, 2 * len)) && (compose_auth_stringResult = typecallocn(char, 3 * len)))) outofmem(__FILE__, "compose_auth_string");#ifdef PUBKEY HTPK_encrypt(cleartext, ciphertext, server->public_key); HTUU_encode((unsigned char *)ciphertext, strlen(ciphertext), compose_auth_stringResult);#endif /* PUBKEY */ FREE(cleartext); FREE(ciphertext); } else { /* scheme == HTAA_BASIC */ if (!(compose_auth_stringResult = typecallocn(char, (4 * ((len+2)/3)) + 1))) outofmem(__FILE__, "compose_auth_string"); HTUU_encode((unsigned char *)cleartext, strlen(cleartext), compose_auth_stringResult); FREE(cleartext); } return compose_auth_stringResult;}/* BROWSER PRIVATE HTAA_selectScheme()** SELECT THE AUTHENTICATION SCHEME TO USE** ON ENTRY:** setup is the server setup structure which can** be used to make the decision about the** used scheme.**** When new authentication methods are added to library** this function makes the decision about which one to** use at a given time. This can be done by inspecting** environment variables etc.**** Currently only searches for the first valid scheme,** and if nothing found suggests Basic scheme;**** ON EXIT:** returns the authentication scheme to use.*/PRIVATE HTAAScheme HTAA_selectScheme ARGS1( HTAASetup *, setup){ HTAAScheme scheme; if (setup && setup->valid_schemes) { for (scheme = HTAA_BASIC; scheme < HTAA_MAX_SCHEMES; scheme++) if (-1 < HTList_indexOf(setup->valid_schemes, (void*)scheme)) return scheme; } return HTAA_BASIC;}/*** Purpose: Free off all module globals.** Arguments: void** Return Value: void** Remarks/Portability/Dependencies/Restrictions:** To be used at program exit.** Revision History:** 06-19-96 created - FM*/PRIVATE void free_HTAAGlobals NOARGS{ HTAAServer * server; int n, i; if (server_table != NULL) { n = HTList_count(server_table); for (i = (n - 1); i >= 0; i--) { if ((server = (HTAAServer*)HTList_objectAt(server_table, i)) != NULL) { HTAAServer_delete(server); server = NULL; } } HTList_delete(server_table); server_table = NULL; } HTAAForwardAuth_reset(); FREE(HTAA_composeAuthResult); FREE(current_hostname); FREE(current_docname); FREE(proxy_hostname); FREE(proxy_docname); FREE(compose_auth_stringResult); FREE(secret_key);}/* BROWSER PUBLIC HTAA_composeAuth()**** SELECT THE AUTHENTICATION SCHEME AND** COMPOSE THE ENTIRE AUTHORIZATION HEADER LINE** IF WE ALREADY KNOW THAT THE HOST REQUIRES AUTHENTICATION**** ON ENTRY:** hostname is the hostname of the server.** portnumber is the portnumber in which the server runs.** docname is the pathname of the document (as in URL)** IsProxy should be TRUE if this is a proxy.**** ON EXIT:** returns NULL, if no authorization seems to be needed, or** if it is the entire Authorization: line, e.g.**** "Authorization: Basic username:password"**** As usual, this string is automatically freed.*/PUBLIC char *HTAA_composeAuth ARGS4( CONST char *, hostname, CONST int, portnumber, CONST char *, docname, BOOL, IsProxy){ char *auth_string; BOOL retry; HTAAScheme scheme; int len; /* ** Setup atexit() freeing if not done already. - FM */ if (!free_HTAAGlobalsSet) {#ifdef LY_FIND_LEAKS atexit(free_HTAAGlobals);#endif free_HTAAGlobalsSet = TRUE; } /* ** Make gateway httpds pass authorization field as it was received. ** (This still doesn't really work because Authenticate: headers ** from remote server are not forwarded to client yet so it cannot ** really know that it should send authorization; I will not ** implement it yet because I feel we will soon change radically ** the way requests are represented to allow multithreading ** on server-side. Life is hard.) */ if (HTAAForwardAuth) { CTRACE((tfp, "HTAA_composeAuth: %s\n", "Forwarding received authorization")); StrAllocCopy(HTAA_composeAuthResult, HTAAForwardAuth); HTAAForwardAuth_reset(); /* Just a precaution */ return HTAA_composeAuthResult; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -