2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
/* MODULE HTAuth.c
|
|
|
|
** USER AUTHENTICATION
|
|
|
|
**
|
|
|
|
** AUTHORS:
|
|
|
|
** AL Ari Luotonen luotonen@dxcern.cern.ch
|
|
|
|
**
|
|
|
|
** HISTORY:
|
|
|
|
**
|
|
|
|
**
|
|
|
|
** BUGS:
|
|
|
|
**
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
#include "../config.h"
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#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'. */
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!authstring || !*authstring ||
|
2010-03-08 04:55:21 -06:00
|
|
|
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;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
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) {
|
2013-03-09 18:59:42 -06:00
|
|
|
if ( !(inet_addr =strchr(password, ':')) ||
|
2010-03-08 04:55:21 -06:00
|
|
|
(*(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
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|