/* MODULE HTAuth.c ** USER AUTHENTICATION ** ** AUTHORS: ** AL Ari Luotonen luotonen@dxcern.cern.ch ** ** HISTORY: ** ** ** BUGS: ** ** */ #include "../config.h" #include #include "HTUtils.h" #include "HTPasswd.h" /* Password file routines */ #include "HTAssoc.h" #include "HTAuth.h" /* Implemented here */ #include "HTUU.h" /* Uuencoding and uudecoding */ #ifndef DISABLE_TRACE extern int www2Trace; #endif /* PRIVATE decompose_auth_string() ** DECOMPOSE AUTHENTICATION STRING ** FOR BASIC OR PUBKEY SCHEME ** ON ENTRY: ** authstring is the authorization string received ** from browser. ** ** ON EXIT: ** returns a node representing the user information ** (as always, this is automatically freed ** by AA package). */ PRIVATE HTAAUser *decompose_auth_string ARGS2(char *, authstring, HTAAScheme, scheme) { static HTAAUser *user = NULL; static char *cleartext = NULL; char *username = NULL; char *password = NULL; char *inet_addr = NULL; char *timestamp = NULL; char *browsers_key = NULL; char *extras = NULL; if (!user && !(user = (HTAAUser*)malloc(sizeof(HTAAUser)))) /* Allocated */ outofmem(__FILE__, "decompose_auth_string"); /* only once */ user->scheme = scheme; user->username = NULL; /* Not freed, because freeing */ user->password = NULL; /* cleartext also frees these */ user->inet_addr = NULL; /* See below: || */ user->timestamp = NULL; /* || */ user->secret_key = NULL; /* || */ /* \/ */ FREE(cleartext); /* From previous call. */ /* NOTE: parts of this memory are pointed to by */ /* pointers in HTAAUser structure. Therefore, */ /* this also frees all the strings pointed to */ /* by the static 'user'. */ if (!authstring || !*authstring || scheme != HTAA_BASIC || scheme == HTAA_PUBKEY) return NULL; if (scheme == HTAA_PUBKEY) { /* Decrypt authentication string */ int bytes_decoded; char *ciphertext; int len = strlen(authstring) + 1; if (!(ciphertext = (char*)malloc(len)) || !(cleartext = (char*)malloc(len))) outofmem(__FILE__, "decompose_auth_string"); bytes_decoded = HTUU_decode(authstring, ciphertext, len); ciphertext[bytes_decoded] = (char)0; #ifdef PUBKEY HTPK_decrypt(ciphertext, cleartext, private_key); #endif free(ciphertext); } else { /* Just uudecode */ int bytes_decoded; int len = strlen(authstring) + 1; if (!(cleartext = (char*)malloc(len))) outofmem(__FILE__, "decompose_auth_string"); bytes_decoded = HTUU_decode(authstring, cleartext, len); cleartext[bytes_decoded] = (char)0; } /* ** Extract username and password (for both schemes) */ username = cleartext; if (!(password = strchr(cleartext, ':'))) { #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "%s %s\n", "decompose_auth_string: password field", "missing in authentication string.\n"); #endif return NULL; } *(password++) = '\0'; /* ** Extract rest of the fields */ if (scheme == HTAA_PUBKEY) { if ( !(inet_addr =strchr(password, ':')) || (*(inet_addr++) ='\0'), !(timestamp =strchr(inet_addr,':')) || (*(timestamp++) ='\0'), !(browsers_key=strchr(timestamp,':')) || (*(browsers_key++)='\0')) { #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "%s %s\n", "decompose_auth_string: Pubkey scheme", "fields missing in authentication string"); #endif return NULL; } extras = strchr(browsers_key, ':'); } else extras = strchr(password, ':'); if (extras) { *(extras++) = '\0'; #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "%s `%s' %s `%s'\n", "decompose_auth_string: extra field(s) in", (scheme==HTAA_BASIC ? "Basic" : "Pubkey"), "authorization string ignored:", extras); #endif } /* ** Set the fields into the result */ user->username = username; user->password = password; user->inet_addr = inet_addr; user->timestamp = timestamp; user->secret_key = browsers_key; #ifndef DISABLE_TRACE if (www2Trace) { if (scheme==HTAA_BASIC) fprintf(stderr, "decompose_auth_string: %s (%s,%s)\n", "Basic scheme authentication string:", username, password); else fprintf(stderr, "decompose_auth_string: %s (%s,%s,%s,%s,%s)\n", "Pubkey scheme authentication string:", username, password, inet_addr, timestamp, browsers_key); } #endif return user; } PRIVATE BOOL HTAA_checkTimeStamp ARGS1(WWW_CONST char *, timestamp) { return NO; /* This is just a stub */ } PRIVATE BOOL HTAA_checkInetAddress ARGS1(WWW_CONST char *, inet_addr) { return NO; /* This is just a stub */ } /* SERVER PUBLIC HTAA_authenticate() ** AUTHENTICATE USER ** ON ENTRY: ** scheme used authentication scheme. ** scheme_specifics the scheme specific parameters ** (authentication string for Basic and ** Pubkey schemes). ** prot is the protection information structure ** for the file. ** ** ON EXIT: ** returns NULL, if authentication failed. ** Otherwise a pointer to a structure ** representing authenticated user, ** which should not be freed. */ PUBLIC HTAAUser *HTAA_authenticate ARGS3(HTAAScheme, scheme, char *, scheme_specifics, HTAAProt *, prot) { if (HTAA_UNKNOWN == scheme || !prot || -1 == HTList_indexOf(prot->valid_schemes, (void*)scheme)) return NULL; switch (scheme) { case HTAA_BASIC: case HTAA_PUBKEY: { HTAAUser *user = decompose_auth_string(scheme_specifics, scheme); /* Remember, user is auto-freed */ if (user && HTAA_checkPassword(user->username, user->password, HTAssocList_lookup(prot->values, "passw")) && (HTAA_BASIC == scheme || (HTAA_checkTimeStamp(user->timestamp) && HTAA_checkInetAddress(user->inet_addr)))) return user; else return NULL; } break; default: /* Other authentication routines go here */ return NULL; } }