#include <afsconfig.h>
#include <afs/param.h>
-RCSID("$Header$");
+RCSID
+ ("$Header$");
#include <afs/stds.h>
#include <sys/types.h>
#define MAXBUFF 1024
/* For caching */
-#include "apache_afs_cache.h"
+#include "apache_afs_cache.h"
/* the actual function that does all the work! */
int CommandProc();
* now I know why this was necessary! - it's a hokie thing -
* the call to ka_UserAuthenticateGeneral doesn't compile otherwise
*/
-int osi_audit()
+int
+osi_audit()
{
- return 0;
+ return 0;
}
-main (int argc, char **argv)
-{
- struct cmd_syndesc *ts;
- afs_int32 code;
+main(int argc, char **argv)
+{
+ struct cmd_syndesc *ts;
+ afs_int32 code;
#ifdef AFS_AIX32_ENV
- /*
- * The following signal action for AIX is necessary so that in case of a
- * crash (i.e. core is generated) we can include the user's data section
- * in the core dump. Unfortunately, by default, only a partial core is
- * generated which, in many cases, isn't too useful.
- */
- struct sigaction nsa;
-
- sigemptyset(&nsa.sa_mask);
- nsa.sa_handler = SIG_DFL;
- nsa.sa_flags = SA_FULLDUMP;
- sigaction(SIGABRT, &nsa, NULL);
- sigaction(SIGSEGV, &nsa, NULL);
+ /*
+ * The following signal action for AIX is necessary so that in case of a
+ * crash (i.e. core is generated) we can include the user's data section
+ * in the core dump. Unfortunately, by default, only a partial core is
+ * generated which, in many cases, isn't too useful.
+ */
+ struct sigaction nsa;
+
+ sigemptyset(&nsa.sa_mask);
+ nsa.sa_handler = SIG_DFL;
+ nsa.sa_flags = SA_FULLDUMP;
+ sigaction(SIGABRT, &nsa, NULL);
+ sigaction(SIGSEGV, &nsa, NULL);
#endif
-
+
/*
* we ignore SIGPIPE so that EPIPE is returned if there is no one reading
* data being written to the pipe
*/
-#ifdef AIX
- /* TODO - for AIX? */
+#ifdef AIX
+ /* TODO - for AIX? */
#else
- struct sigaction sa;
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
#endif
- zero_argc = argc;
- zero_argv = argv;
-
- ts = cmd_CreateSyntax(NULL, CommandProc, 0,
- "obtain Kerberos authentication for web servers");
+ zero_argc = argc;
+ zero_argv = argv;
-/* define the command line arguments */
+ ts = cmd_CreateSyntax(NULL, CommandProc, 0,
+ "obtain Kerberos authentication for web servers");
+
+/* define the command line arguments */
#define aREADPIPE 0
#define aWRITEPIPE 1
#define aCACHEEXPIRATION 2
#define aTOKENEXPIRATION 3
#define aSILENT 4
- cmd_AddParm(ts, "-readPipe", CMD_SINGLE, CMD_OPTIONAL, "inPipefd");
- cmd_AddParm(ts, "-writePipe", CMD_SINGLE, CMD_OPTIONAL, "outPipefd");
- cmd_AddParm(ts, "-cacheExpiration", CMD_SINGLE, CMD_OPTIONAL,
- "local cache expiration times for tokens");
- cmd_AddParm(ts, "-tokenExpiration", CMD_SINGLE, CMD_OPTIONAL,
- "cache manager expiration time for tokens");
- cmd_AddParm(ts, "-silent", CMD_FLAG, CMD_OPTIONAL, "silent operation");
-
- code = cmd_Dispatch(argc, argv);
-
- WEBLOGEXIT(code);
+ cmd_AddParm(ts, "-readPipe", CMD_SINGLE, CMD_OPTIONAL, "inPipefd");
+ cmd_AddParm(ts, "-writePipe", CMD_SINGLE, CMD_OPTIONAL, "outPipefd");
+ cmd_AddParm(ts, "-cacheExpiration", CMD_SINGLE, CMD_OPTIONAL,
+ "local cache expiration times for tokens");
+ cmd_AddParm(ts, "-tokenExpiration", CMD_SINGLE, CMD_OPTIONAL,
+ "cache manager expiration time for tokens");
+ cmd_AddParm(ts, "-silent", CMD_FLAG, CMD_OPTIONAL, "silent operation");
+
+ code = cmd_Dispatch(argc, argv);
+
+ WEBLOGEXIT(code);
}
/*
* send a buffer over the pipe
*/
-static int sendToken(int len, void *buf)
+static int
+sendToken(int len, void *buf)
{
- if(buf == NULL) {
- WEBLOGEXIT(NULLARGSERROR);
- }
- if (write(writePipe, buf, len) != len) {
+ if (buf == NULL) {
+ WEBLOGEXIT(NULLARGSERROR);
+ }
+ if (write(writePipe, buf, len) != len) {
#ifdef DEBUG
- perror("weblog: write to pipe error");
+ perror("weblog: write to pipe error");
#endif
- return -1;
- }
- return 0;
+ return -1;
+ }
+ return 0;
}
* read the incoming buffer from the pipe
*/
-static int readFromClient(char *buf)
+static int
+readFromClient(char *buf)
{
- int n;
- if(buf == NULL) {
- WEBLOGEXIT(NULLARGSERROR);
- }
- n = read(readPipe, buf, MAXBUFF);
- if(n < 0) {
+ int n;
+ if (buf == NULL) {
+ WEBLOGEXIT(NULLARGSERROR);
+ }
+ n = read(readPipe, buf, MAXBUFF);
+ if (n < 0) {
#ifdef DEBUG
- perror("weblog: pipe read error");
+ perror("weblog: pipe read error");
#endif
- return -1;
- }
- if (n == 0) {
+ return -1;
+ }
+ if (n == 0) {
#ifdef DEBUG
- perror("weblog: zero bytes read from pipe");
+ perror("weblog: zero bytes read from pipe");
#endif
- return -1;
- }
- return n;
+ return -1;
+ }
+ return n;
}
/*
* NOTE - the space seperated credentials failed for passwds with spaces, thus
* we use newline for seperators instead
*/
-static int getNullSepWord(char *buf, char sep, char *retBuf, int start)
+static int
+getNullSepWord(char *buf, char sep, char *retBuf, int start)
{
- int ret=0;
- int len=strlen(buf)-start;
-
- /* error checks */
- if ((buf == NULL) || (retBuf == NULL) || (start < 0)) {
- fprintf(stderr, "weblog (getWordSep):NULL args\n");
- return -1;
- }
-
- while ((buf[start] != sep) && (ret<=len)) {
- retBuf[ret]=buf[start];
- ret++;
- start++;
- }
- retBuf[ret]='\0';
- return (ret+1);
+ int ret = 0;
+ int len = strlen(buf) - start;
+
+ /* error checks */
+ if ((buf == NULL) || (retBuf == NULL) || (start < 0)) {
+ fprintf(stderr, "weblog (getWordSep):NULL args\n");
+ return -1;
+ }
+
+ while ((buf[start] != sep) && (ret <= len)) {
+ retBuf[ret] = buf[start];
+ ret++;
+ start++;
+ }
+ retBuf[ret] = '\0';
+ return (ret + 1);
}
* parses the NEWLINE seperated buffer giving the username, passwd and cell
* coming over the pipe from the clients and sets the variables accordingly
*/
-static int parseBuf(char *buf, char *user, char *pass, char *cell, char *type)
+static int
+parseBuf(char *buf, char *user, char *pass, char *cell, char *type)
{
- char *temp;
- int start=0, ret = 0;
+ char *temp;
+ int start = 0, ret = 0;
- if ((buf == NULL) || (user == NULL) || (pass == NULL) || (cell == NULL)
- || (type == NULL)) {
+ if ((buf == NULL) || (user == NULL) || (pass == NULL) || (cell == NULL)
+ || (type == NULL)) {
#ifdef DEBUG
- fprintf(stderr, "afs_Authenticator:parseBuf-an arg was NULL\n");
+ fprintf(stderr, "afs_Authenticator:parseBuf-an arg was NULL\n");
#endif
- return -1;
- }
- if ((ret = getNullSepWord(buf, '\n', type, start)) < 0) {
- return -1;
- }
- start += ret;
- if ((ret = getNullSepWord(buf, '\n', user, start)) < 0) {
- return -1;
- }
- start += ret;
- if ((ret = getNullSepWord(buf, '\n', cell, start)) < 0) {
- return -1;
- }
- start += ret;
- if ((ret = getNullSepWord(buf, '\n', pass, start)) < 0) {
- return -1;
- }
- return 0;
+ return -1;
+ }
+ if ((ret = getNullSepWord(buf, '\n', type, start)) < 0) {
+ return -1;
+ }
+ start += ret;
+ if ((ret = getNullSepWord(buf, '\n', user, start)) < 0) {
+ return -1;
+ }
+ start += ret;
+ if ((ret = getNullSepWord(buf, '\n', cell, start)) < 0) {
+ return -1;
+ }
+ start += ret;
+ if ((ret = getNullSepWord(buf, '\n', pass, start)) < 0) {
+ return -1;
+ }
+ return 0;
}
* Discard any authentication information held in trust by the Cache Manager
* for the calling process and all other processes in the same PAG
*/
-static int unlog()
+static int
+unlog()
{
- return do_pioctl(NULL, 0, NULL, 0, VIOCUNPAG, NULL, 0);
+ return do_pioctl(NULL, 0, NULL, 0, VIOCUNPAG, NULL, 0);
}
/* we can obtain a PAG by calling this system call */
-static int makeNewPAG()
+static int
+makeNewPAG()
{
- return do_setpag();
+ return do_setpag();
}
#ifdef ENABLE_DCE_DLOG
char *realm;
} kdc_as_reply_t;
-static char *makeString(char *sp)
+static char *
+makeString(char *sp)
{
- int len;
- char *new_string;
-
- if (sp == NULL) {
- fprintf(stderr, "weblog: makeString - NULL argument\n");
- return NULL;
- }
- len=strlen(sp);
- if (len < 0) {
- fprintf(stderr, "weblog: makeString. strlen error\n");
- return NULL;
- }
- new_string=(char *) malloc(len+1);
- if (new_string==NULL) {
- fprintf(stderr, "weblog: Out of memory - malloc failed\n");
- return NULL;
- }
- strncpy(new_string,sp,len);
- return new_string;
+ int len;
+ char *new_string;
+
+ if (sp == NULL) {
+ fprintf(stderr, "weblog: makeString - NULL argument\n");
+ return NULL;
+ }
+ len = strlen(sp);
+ if (len < 0) {
+ fprintf(stderr, "weblog: makeString. strlen error\n");
+ return NULL;
+ }
+ new_string = (char *)malloc(len + 1);
+ if (new_string == NULL) {
+ fprintf(stderr, "weblog: Out of memory - malloc failed\n");
+ return NULL;
+ }
+ strncpy(new_string, sp, len);
+ return new_string;
}
/*
* Store the returned credentials as an AFS "token" for the user
* "AFS ID <user_id>".
*/
-static int store_afs_token(unix_id, realm_p, tkt_type, ticket_p, ticket_len,
- session_key, starttime, endtime, set_pag)
- afs_int32 unix_id;
- char *realm_p;
- afs_int32 tkt_type;
- unsigned char *ticket_p;
- int ticket_len;
- des_cblock session_key;
- afs_int32 starttime;
- afs_int32 endtime;
- int set_pag;
+static int
+store_afs_token(unix_id, realm_p, tkt_type, ticket_p, ticket_len, session_key,
+ starttime, endtime, set_pag)
+ afs_int32 unix_id;
+ char *realm_p;
+ afs_int32 tkt_type;
+ unsigned char *ticket_p;
+ int ticket_len;
+ des_cblock session_key;
+ afs_int32 starttime;
+ afs_int32 endtime;
+ int set_pag;
{
struct ktc_token token;
struct ktc_principal client, server;
token.startTime = starttime;
token.endTime = endtime;
- memcpy((char *) &token.sessionKey, session_key, sizeof(token.sessionKey));
+ memcpy((char *)&token.sessionKey, session_key, sizeof(token.sessionKey));
token.kvno = tkt_type;
token.ticketLen = ticket_len;
if (ticket_len > MAXKTCTICKETLEN) {
- fprintf(stderr, "weblog: DCE ticket is too long (length %d)."
- "Maximum length accepted by AFS cache manager is %d\n", MAXKTCTICKETLEN);
+ fprintf(stderr,
+ "weblog: DCE ticket is too long (length %d)."
+ "Maximum length accepted by AFS cache manager is %d\n",
+ MAXKTCTICKETLEN);
return -1;
}
- memcpy((char *) token.ticket, (char *) ticket_p, ticket_len);
+ memcpy((char *)token.ticket, (char *)ticket_p, ticket_len);
sprintf(client.name, "AFS ID %d", unix_id);
strcpy(client.instance, "");
strcpy(server.instance, "");
strcpy(server.cell, realm_p);
- return (ktc_SetToken(&server, &token, &client,
- set_pag ? AFS_SETTOK_SETPAG : 0));
+ return (ktc_SetToken
+ (&server, &token, &client, set_pag ? AFS_SETTOK_SETPAG : 0));
}
-static char *make_string(s_p, length)
- char *s_p;
- int length;
+static char *
+make_string(s_p, length)
+ char *s_p;
+ int length;
{
- char *new_p = (char *) malloc(length + 1);
+ char *new_p = (char *)malloc(length + 1);
if (new_p == NULL) {
fprintf(stderr, "dlog: out of memory\n");
exit(1);
*
* NOTE: A test for this procedure is included at the end of this file.
*/
-static int decode_asn_time(buf, buflen, utime)
- char *buf;
- int buflen;
- afs_int32 *utime;
+static int
+decode_asn_time(buf, buflen, utime)
+ char *buf;
+ int buflen;
+ afs_int32 *utime;
{
int year, month, day, hour, mina, sec;
int leapyear, days;
- static mdays[11] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};
+ static mdays[11] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
int m;
- if (buflen != 15 ||
- sscanf(buf, "%4d%2d%2d%2d%2d%2dZ",
- &year, &month, &day, &hour, &mina, &sec) != 6) {
+ if (buflen != 15
+ || sscanf(buf, "%4d%2d%2d%2d%2d%2dZ", &year, &month, &day, &hour,
+ &mina, &sec) != 6) {
return 1;
}
leapyear = month > 2 ? (year + 1) : year; /* Account for feb 29 if
- current year is a leap year */
- for (days = 0, m = 0; m < month - 1; m++) days += mdays[m];
+ * current year is a leap year */
+ for (days = 0, m = 0; m < month - 1; m++)
+ days += mdays[m];
*utime =
- ((((((year - 1970) * 365 + (leapyear - 1970 + 1)/4
- + days + day - 1) * 24) + hour) * 60 + mina) * 60) + sec;
+ ((((((year - 1970) * 365 + (leapyear - 1970 + 1) / 4 + days + day -
+ 1) * 24) + hour) * 60 + mina) * 60) + sec;
return 0;
}
#define ASN_GENERAL_STRING 0x1b
#define KDC_REP 0x7a
-static int decode_reply(buf, buflen, reply_p)
- unsigned char *buf; /* encoded ASN.1 string */
- int buflen; /* length of encoded string */
- kdc_as_reply_t *reply_p; /* result */
+static int
+decode_reply(buf, buflen, reply_p)
+ unsigned char *buf; /* encoded ASN.1 string */
+ int buflen; /* length of encoded string */
+ kdc_as_reply_t *reply_p; /* result */
{
unsigned char *limit = buf + buflen;
char saw_realm = 0;
int context = -1; /* Initialize with invalid context */
-
+
reply_p->starttime = 0; /* This is optionally provided by kdc */
while (buf < limit) {
if ((op & 0x20) == 0) {
/* Primitive encoding */
if (len & 0x80) {
- return 1; /* Forget about long unspecified lengths */
+ return 1; /* Forget about long unspecified lengths */
}
/* Bounds check */
if (buf + len > limit)
}
switch (op) {
- case KDC_REP:
+ case KDC_REP:
saw_kdc_rep++;
break;
- case ASN_INTEGER:
+ case ASN_INTEGER:
{
/*
* Since non ANSI C doesn't recognize the "signed"
}
break;
- case ASN_OCTET_STRING:
+ case ASN_OCTET_STRING:
if (context == 1 && len == sizeof(reply_p->session_key)) {
saw_session_key++;
memcpy(reply_p->session_key, buf, len);
buf += len;
break;
- case ASN_GENERAL_STRING:
+ case ASN_GENERAL_STRING:
if (context == 9) {
saw_realm = 1;
- reply_p->realm = make_string(buf,len);
+ reply_p->realm = make_string(buf, len);
goto out; /* Best to terminate now, rather than
* continue--we don't know if the entire
* request is padded with zeroes, and if
buf += len;
break;
- case ASN_TIME:
+ case ASN_TIME:
switch (context) {
- case 5:
+ case 5:
saw_authtime++;
- if (decode_asn_time(buf, len, &reply_p->authtime))
+ if (decode_asn_time(buf, len, &reply_p->authtime))
return 1;
break;
- case 6:
+ case 6:
saw_starttime++;
if (decode_asn_time(buf, len, &reply_p->starttime))
return 1;
break;
-
- case 7:
+
+ case 7:
saw_endtime++;
if (decode_asn_time(buf, len, &reply_p->endtime))
return 1;
buf += len;
break;
- default:
+ default:
if ((op & 0xe0) == 0xa0) {
/* Remember last context label */
context = op & 0x1f;
}
out:
- return ! (saw_kdc_rep == 1 && saw_nonce == 1 && saw_session_key == 1 &&
- saw_authtime == 1 && (saw_starttime == 1 || saw_starttime == 0) &&
- saw_endtime == 1 && saw_realm == 1);
+ return !(saw_kdc_rep == 1 && saw_nonce == 1 && saw_session_key == 1
+ && saw_authtime == 1 && (saw_starttime == 1
+ || saw_starttime == 0)
+ && saw_endtime == 1 && saw_realm == 1);
}
-
+
/*
* Attempt to obtain a DFS ticket
*/
-static int getDFScreds(char *name, char *realm, char *passwd,
- afs_uint32 lifetime, char **reason)
+static int
+getDFScreds(char *name, char *realm, char *passwd, afs_uint32 lifetime,
+ char **reason)
{
- extern ADK_GetTicket();
- afs_int32 serverList[MAXSERVERS];
- struct rx_connection *serverconns[MAXSERVERS];
- struct ubik_client *ubik_handle=0;
- struct timeval now; /* current time */
- afs_int32 nonce; /* Kerberos V5 "nonce" */
- adk_error_ptr error_p; /* Error code from ktc intermediary */
- adk_reply_ptr reply_p; /* reply from ktc intermediary */
- des_cblock passwd_key; /* des key from user password */
- des_key_schedule schedule; /* Key schedule from key */
- kdc_as_reply_t kdcrep; /* Our own decoded version of
- ciphertext portion of kdc reply */
- int code;
- struct afsconf_dir *cdir; /* Open configuration structure */
- int i;
- struct afsconf_cell cellinfo; /* Info for specified cell */
-
- if ((name==NULL)||(realm==NULL)||(passwd==NULL)) {
- *reason=makeString("weblog: NULL Arguments to getDCEcreds");
- return -1;
- }
-
- cdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
- if (!cdir) {
- *reason=makeString("weblog: unable to read or open AFS client "
- "configuration file");
- return -1;
- }
-
- /*
- * Resolve full name of cell and get server list.
- */
- code = afsconf_GetCellInfo(cdir, realm, 0, &cellinfo);
- if (code) {
- *reason=makeString("-- unable to get cell info");
- return -1;
- }
-
- if (strcmp(realm, cellinfo.name)) {
- strncpy(realm, cellinfo.name, sizeof(realm) - 1);
- realm[sizeof(realm) - 1] = '\0';
- }
-
- for (i = 0; i < cellinfo.numServers && i < MAXSERVERS; i++) {
- serverList[i] = cellinfo.hostAddr[i].sin_addr.s_addr;
- }
- if (i < MAXSERVERS) serverList[i] = 0;
-
- /*
- * Make connections to all the servers.
- */
- rx_Init(0);
- for (i = 0; i < MAXSERVERS; i++) {
- if (! serverList[i]) {
- serverconns[i] = 0;
- break;
+ extern ADK_GetTicket();
+ afs_int32 serverList[MAXSERVERS];
+ struct rx_connection *serverconns[MAXSERVERS];
+ struct ubik_client *ubik_handle = 0;
+ struct timeval now; /* current time */
+ afs_int32 nonce; /* Kerberos V5 "nonce" */
+ adk_error_ptr error_p; /* Error code from ktc intermediary */
+ adk_reply_ptr reply_p; /* reply from ktc intermediary */
+ des_cblock passwd_key; /* des key from user password */
+ des_key_schedule schedule; /* Key schedule from key */
+ kdc_as_reply_t kdcrep; /* Our own decoded version of
+ * ciphertext portion of kdc reply */
+ int code;
+ struct afsconf_dir *cdir; /* Open configuration structure */
+ int i;
+ struct afsconf_cell cellinfo; /* Info for specified cell */
+
+ if ((name == NULL) || (realm == NULL) || (passwd == NULL)) {
+ *reason = makeString("weblog: NULL Arguments to getDCEcreds");
+ return -1;
+ }
+
+ cdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
+ if (!cdir) {
+ *reason =
+ makeString("weblog: unable to read or open AFS client "
+ "configuration file");
+ return -1;
+ }
+
+ /*
+ * Resolve full name of cell and get server list.
+ */
+ code = afsconf_GetCellInfo(cdir, realm, 0, &cellinfo);
+ if (code) {
+ *reason = makeString("-- unable to get cell info");
+ return -1;
+ }
+
+ if (strcmp(realm, cellinfo.name)) {
+ strncpy(realm, cellinfo.name, sizeof(realm) - 1);
+ realm[sizeof(realm) - 1] = '\0';
+ }
+
+ for (i = 0; i < cellinfo.numServers && i < MAXSERVERS; i++) {
+ serverList[i] = cellinfo.hostAddr[i].sin_addr.s_addr;
+ }
+ if (i < MAXSERVERS)
+ serverList[i] = 0;
+
+ /*
+ * Make connections to all the servers.
+ */
+ rx_Init(0);
+ for (i = 0; i < MAXSERVERS; i++) {
+ if (!serverList[i]) {
+ serverconns[i] = 0;
+ break;
+ }
+ serverconns[i] =
+ rx_NewConnection(serverList[i], htons(ADK_PORT), ADK_SERVICE,
+ rxnull_NewClientSecurityObject(), 0);
+ }
+
+ /*
+ * Initialize ubik client gizmo to randomize the calls for us.
+ */
+ ubik_ClientInit(serverconns, &ubik_handle);
+ /*
+ * Come up with an acceptable nonce. V5 doc says that we just need
+ * time of day. Actually, for this app, I don't think anything
+ * is really needed. Better safe than sorry (although I wonder if
+ * it might have been better to encode the AFS ID in the nonce
+ * reply field--that's the one field that the intermediate server
+ * has total control over, and which can be securely transmitted
+ * back to the client).
+ */
+ gettimeofday(&now, 0);
+ nonce = now.tv_sec;
+
+
+ /*
+ * Ask our agent to get us a Kerberos V5 ticket.
+ */
+ reply_p = (adk_reply_ptr) 0;
+ error_p = (adk_error_ptr) 0;
+ code = ubik_Call(ADK_GetTicket, ubik_handle, 0, /* Ubik flags */
+ name, /* IN: Principal: must be exact DCE principal */
+ nonce, /* IN: Input nonce */
+ lifetime, /* IN: lifetime */
+ &error_p, /* OUT: Error, if any */
+ &reply_p); /* OUT: KTC reply, if no error */
+
+ /*
+ * Destroy Rx connections on the off-chance this will allow less state
+ * to be preserved at the server.
+ */
+ ubik_ClientDestroy(ubik_handle);
+
+ /*
+ * Finalize Rx. This may allow connections at the server to wind down
+ * faster.
+ */
+ rx_Finalize();
+
+
+ /*
+ * Check for simple communication failures.
+ */
+ if (code) {
+ *reason = makeString("-- failed to contact authentication service");
+ return -1;
+ }
+
+ /*
+ * Also check for DCE errors, which are interpreted for us by
+ * the translator.
+ */
+ if (error_p && error_p->code) {
+ *reason = (char *)makeString(error_p->data);
+ fprintf(stderr, "weblog error:error_p->data:%s\n", error_p->data);
+ return -1;
+ }
+
+
+ /*
+ * Make sure the reply was filled in.
+ */
+ if (!reply_p) {
+ *reason = (char *)
+ makeString
+ ("weblog: unexpected error in server response; aborted");
+ return -1;
}
- serverconns[i] = rx_NewConnection
- (serverList[i], htons(ADK_PORT), ADK_SERVICE,
- rxnull_NewClientSecurityObject(), 0);
- }
-
- /*
- * Initialize ubik client gizmo to randomize the calls for us.
- */
- ubik_ClientInit(serverconns, &ubik_handle);
- /*
- * Come up with an acceptable nonce. V5 doc says that we just need
- * time of day. Actually, for this app, I don't think anything
- * is really needed. Better safe than sorry (although I wonder if
- * it might have been better to encode the AFS ID in the nonce
- * reply field--that's the one field that the intermediate server
- * has total control over, and which can be securely transmitted
- * back to the client).
- */
- gettimeofday(&now, 0);
- nonce = now.tv_sec;
-
-
- /*
- * Ask our agent to get us a Kerberos V5 ticket.
- */
- reply_p = (adk_reply_ptr) 0;
- error_p = (adk_error_ptr) 0;
- code = ubik_Call
- (ADK_GetTicket,
- ubik_handle,
- 0, /* Ubik flags */
- name, /* IN: Principal: must be exact DCE principal */
- nonce, /* IN: Input nonce */
- lifetime, /* IN: lifetime */
- &error_p, /* OUT: Error, if any */
- &reply_p); /* OUT: KTC reply, if no error */
-
- /*
- * Destroy Rx connections on the off-chance this will allow less state
- * to be preserved at the server.
- */
- ubik_ClientDestroy(ubik_handle);
-
- /*
- * Finalize Rx. This may allow connections at the server to wind down
- * faster.
- */
- rx_Finalize();
-
-
- /*
- * Check for simple communication failures.
- */
- if (code) {
- *reason=makeString("-- failed to contact authentication service");
- return -1;
- }
-
- /*
- * Also check for DCE errors, which are interpreted for us by
- * the translator.
- */
- if (error_p && error_p->code) {
- *reason=( char *) makeString(error_p->data);
- fprintf(stderr,"weblog error:error_p->data:%s\n", error_p->data);
- return -1;
- }
-
-
- /*
- * Make sure the reply was filled in.
- */
- if (!reply_p) {
- *reason=(char *) makeString("weblog: unexpected error in server response; aborted");
- return -1;
- }
-
-
- /*
- * Convert the password into the appropriate key block, given
- * the salt passed back from the ADK_GetTicket call, above. Destroy
- * the password.
- */
- if (strlen(passwd) + strlen(reply_p->salt) + 1 > BUFSIZ) {
- *reason=(char *) makeString("weblog: unexpectedly long passwd/salt combination");
- return -1;
- }
- strcat(passwd, reply_p->salt);
- des_string_to_key(passwd, passwd_key);
-
- /* Destroy the password. */
- memset(passwd, 0, strlen(passwd));
-
-
- /*
- * Decrypt the private data returned by the DCE KDC, and forwarded
- * to us by the translator.
- */
- code = des_key_sched (passwd_key, schedule);
- if (!code) {
- code = des_cbc_encrypt
- (reply_p->private.adk_code_val, reply_p->private.adk_code_val,
- reply_p->private.adk_code_len, schedule, passwd_key, DECRYPT);
- }
- if (code) {
- *reason=(char *) makeString("-- unable to decrypt reply from the DCE KDC");
- return -1;
- }
-
- /*
- * Destroy the key block: it's no longer needed.
- */
- memset(schedule, 0, sizeof(schedule));
- memset(passwd_key, 0, sizeof(passwd_key));
-
-
- /*
- * Do a very quick and dirty ASN.1 decode of the relevant parts
- * of the private data.
- *
- * The decrypted data contains a 12-byte header (confounder and CRC-32
- * checksum). We choose to ignore this.
- */
- code = decode_reply(reply_p->private.adk_code_val + 12, /* Skip header */
- reply_p->private.adk_code_len - 12, /* ditto */
- &kdcrep);
-
- if (code || kdcrep.nonce != nonce) {
- *reason=(char *)makeString("weblog: DCE authentication failed -- "
- "password is probably incorrect");
- return -1;
- }
-
-
- /*
- * Make an AFS token out of the ticket and session key, and install it
- * in the cache manager.
- */
- code = store_afs_token(reply_p->unix_id,
- realm,
- reply_p->tktype,
- reply_p->ticket.adk_code_val,
- reply_p->ticket.adk_code_len,
- kdcrep.session_key,
- kdcrep.starttime? kdcrep.starttime : kdcrep.authtime,
- kdcrep.endtime,
- 0);
-
- if (code) {
- *reason=(char *)makeString("weblog -- getDCEcreds:failed to store tickets");
- return -1;
- }
- return 0;
+
+
+ /*
+ * Convert the password into the appropriate key block, given
+ * the salt passed back from the ADK_GetTicket call, above. Destroy
+ * the password.
+ */
+ if (strlen(passwd) + strlen(reply_p->salt) + 1 > BUFSIZ) {
+ *reason = (char *)
+ makeString("weblog: unexpectedly long passwd/salt combination");
+ return -1;
+ }
+ strcat(passwd, reply_p->salt);
+ des_string_to_key(passwd, passwd_key);
+
+ /* Destroy the password. */
+ memset(passwd, 0, strlen(passwd));
+
+
+ /*
+ * Decrypt the private data returned by the DCE KDC, and forwarded
+ * to us by the translator.
+ */
+ code = des_key_sched(passwd_key, schedule);
+ if (!code) {
+ code =
+ des_cbc_encrypt(reply_p->private.adk_code_val,
+ reply_p->private.adk_code_val,
+ reply_p->private.adk_code_len, schedule,
+ passwd_key, DECRYPT);
+ }
+ if (code) {
+ *reason =
+ (char *)makeString("-- unable to decrypt reply from the DCE KDC");
+ return -1;
+ }
+
+ /*
+ * Destroy the key block: it's no longer needed.
+ */
+ memset(schedule, 0, sizeof(schedule));
+ memset(passwd_key, 0, sizeof(passwd_key));
+
+
+ /*
+ * Do a very quick and dirty ASN.1 decode of the relevant parts
+ * of the private data.
+ *
+ * The decrypted data contains a 12-byte header (confounder and CRC-32
+ * checksum). We choose to ignore this.
+ */
+ code = decode_reply(reply_p->private.adk_code_val + 12, /* Skip header */
+ reply_p->private.adk_code_len - 12, /* ditto */
+ &kdcrep);
+
+ if (code || kdcrep.nonce != nonce) {
+ *reason =
+ (char *)makeString("weblog: DCE authentication failed -- "
+ "password is probably incorrect");
+ return -1;
+ }
+
+
+ /*
+ * Make an AFS token out of the ticket and session key, and install it
+ * in the cache manager.
+ */
+ code =
+ store_afs_token(reply_p->unix_id, realm, reply_p->tktype,
+ reply_p->ticket.adk_code_val,
+ reply_p->ticket.adk_code_len, kdcrep.session_key,
+ kdcrep.starttime ? kdcrep.starttime : kdcrep.authtime,
+ kdcrep.endtime, 0);
+
+ if (code) {
+ *reason = (char *)
+ makeString("weblog -- getDCEcreds:failed to store tickets");
+ return -1;
+ }
+ return 0;
}
#endif /* ENABLE_DCE_DLOG */
* arrive through a pipe from the httpds, authenticates the user and
* returns a token (or a failure message) over the pipe
*/
-CommandProc (as, arock)
+CommandProc(as, arock)
char *arock;
struct cmd_syndesc *as;
-
+
{
- char name[MAXKTCNAMELEN];
- char cell[MAXKTCREALMLEN];
- char passwd[BUFSIZ];
+ char name[MAXKTCNAMELEN];
+ char cell[MAXKTCREALMLEN];
+ char passwd[BUFSIZ];
/* All the constant sizes for these arrays are taken from the code for klog */
-
- char cksum[SHA_HASH_BYTES]; /* for sha checksum for caching */
- afs_int32 expires=0; /* for cache expiration */
- afs_int32 cacheExpiration=0; /* configurable cmd line parameter */
- afs_int32 testExpires=0; /* cacheExpiration + current time */
-
- int authtype = 0; /* AFS or AFS-DFS Authentication */
- int code;
- int shutdown = 0; /* on getting shutdown from the pipe we GO */
- int gotToken = 0; /* did we get a token from the cache manager */
- afs_int32 i=0; /* for getting primary token held by CM */
- int dosetpag=1; /* not used */
- Date lifetime; /* requested ticket lifetime */
- char tbuffer[MAXBUFF]; /* for pioctl ops + pipe transfers */
- static char rn[] = "weblog"; /* Routine name */
- static int Silent = 0; /* Don't want error messages */
- afs_int32 password_expires = -1;
- char *reason; /* string describing errors */
- char type[10]; /* authentication type AFS or DFS */
-
- /* blow away command line arguments */
- for (i=1; i<zero_argc; i++) memset(zero_argv[i], 0, strlen(zero_argv[i]));
- zero_argc = 0;
-
- /* first determine quiet flag based on -silent switch */
- Silent = (as->parms[aSILENT].items ? 1 : 0);
-
- code = ka_Init(0);
- if (code) {
- if (!Silent) {
- fprintf(stderr, "%s:ka_Init FAILED\n", rn);
+
+ char cksum[SHA_HASH_BYTES]; /* for sha checksum for caching */
+ afs_int32 expires = 0; /* for cache expiration */
+ afs_int32 cacheExpiration = 0; /* configurable cmd line parameter */
+ afs_int32 testExpires = 0; /* cacheExpiration + current time */
+
+ int authtype = 0; /* AFS or AFS-DFS Authentication */
+ int code;
+ int shutdown = 0; /* on getting shutdown from the pipe we GO */
+ int gotToken = 0; /* did we get a token from the cache manager */
+ afs_int32 i = 0; /* for getting primary token held by CM */
+ int dosetpag = 1; /* not used */
+ Date lifetime; /* requested ticket lifetime */
+ char tbuffer[MAXBUFF]; /* for pioctl ops + pipe transfers */
+ static char rn[] = "weblog"; /* Routine name */
+ static int Silent = 0; /* Don't want error messages */
+ afs_int32 password_expires = -1;
+ char *reason; /* string describing errors */
+ char type[10]; /* authentication type AFS or DFS */
+
+ /* blow away command line arguments */
+ for (i = 1; i < zero_argc; i++)
+ memset(zero_argv[i], 0, strlen(zero_argv[i]));
+ zero_argc = 0;
+
+ /* first determine quiet flag based on -silent switch */
+ Silent = (as->parms[aSILENT].items ? 1 : 0);
+
+ code = ka_Init(0);
+ if (code) {
+ if (!Silent) {
+ fprintf(stderr, "%s:ka_Init FAILED\n", rn);
+ }
+ WEBLOGEXIT(KAERROR);
}
- WEBLOGEXIT(KAERROR);
- }
-
- /* Parse our arguments. */
- if (as->parms[aREADPIPE].items)
- /* there is a file descriptor instead of stdin */
- readPipe = atoi(as->parms[aREADPIPE].items->data);
- else
- readPipe = stdin;
-
- if (as->parms[aWRITEPIPE].items)
- /* there is a file descriptor instead of stdout */
- writePipe = atoi(as->parms[aWRITEPIPE].items->data);
- else
- writePipe = stdout;
-
- if (as->parms[aCACHEEXPIRATION].items)
- /* set configurable cache expiration time */
- cacheExpiration=atoi(as->parms[aCACHEEXPIRATION].items->data);
-
- if (as->parms[aTOKENEXPIRATION].items)
- /* set configurable token lifetime */
- lifetime = atoi(as->parms[aTOKENEXPIRATION].items->data);
-
- /*
- * Initialize the cache for tokens
- */
- token_cache_init();
-
- /*
- * discard any tokens held for this PAG -
- * should we create a seperate PAG for weblog first? makeNewPAG does that
- */
+
+ /* Parse our arguments. */
+ if (as->parms[aREADPIPE].items)
+ /* there is a file descriptor instead of stdin */
+ readPipe = atoi(as->parms[aREADPIPE].items->data);
+ else
+ readPipe = stdin;
+
+ if (as->parms[aWRITEPIPE].items)
+ /* there is a file descriptor instead of stdout */
+ writePipe = atoi(as->parms[aWRITEPIPE].items->data);
+ else
+ writePipe = stdout;
+
+ if (as->parms[aCACHEEXPIRATION].items)
+ /* set configurable cache expiration time */
+ cacheExpiration = atoi(as->parms[aCACHEEXPIRATION].items->data);
+
+ if (as->parms[aTOKENEXPIRATION].items)
+ /* set configurable token lifetime */
+ lifetime = atoi(as->parms[aTOKENEXPIRATION].items->data);
+
+ /*
+ * Initialize the cache for tokens
+ */
+ token_cache_init();
+
+ /*
+ * discard any tokens held for this PAG -
+ * should we create a seperate PAG for weblog first? makeNewPAG does that
+ */
#ifdef DEBUG
- fprintf(stderr, "%s:Before MAKENEWPAG\n", rn);
- printGroups();
- fprintf(stderr,"\nWEBLOG: before PAG:\t");
- printPAG();
+ fprintf(stderr, "%s:Before MAKENEWPAG\n", rn);
+ printGroups();
+ fprintf(stderr, "\nWEBLOG: before PAG:\t");
+ printPAG();
#endif
- if (makeNewPAG()) {
- fprintf(stderr, "WEBLOG: MakeNewPAG failed\n");
- }
+ if (makeNewPAG()) {
+ fprintf(stderr, "WEBLOG: MakeNewPAG failed\n");
+ }
#ifdef DEBUG
- fprintf(stderr,"weblog:AFTER do_setpag,PAG:\t");
- printPAG();
- fprintf(stderr, "%s:After MAKENEWPAG\n", rn);
- printGroups();
+ fprintf(stderr, "weblog:AFTER do_setpag,PAG:\t");
+ printPAG();
+ fprintf(stderr, "%s:After MAKENEWPAG\n", rn);
+ printGroups();
#endif
-
- if (unlog()) {
+
+ if (unlog()) {
#ifdef DEBUG
- fprintf(stderr, "WEBLOG: UNLOG FAILED\n");
+ fprintf(stderr, "WEBLOG: UNLOG FAILED\n");
#endif
- }
-
- while (!shutdown) {
- gotToken = 0;
- code = readFromClient(tbuffer);
- if (code > 0) {
- tbuffer[code]='\0';
- code =parseBuf(tbuffer, name, passwd, cell, type);
- if (code) {
- fprintf(stderr, "weblog: parseBuf FAILED\n");
- WEBLOGEXIT(PARSEERROR);
- }
}
- else {
+
+ while (!shutdown) {
+ gotToken = 0;
+ code = readFromClient(tbuffer);
+ if (code > 0) {
+ tbuffer[code] = '\0';
+ code = parseBuf(tbuffer, name, passwd, cell, type);
+ if (code) {
+ fprintf(stderr, "weblog: parseBuf FAILED\n");
+ WEBLOGEXIT(PARSEERROR);
+ }
+ } else {
#ifdef DEBUG
- fprintf(stderr, "%s: readFromClient FAILED:%d...exiting\n",rn,code);
+ fprintf(stderr, "%s: readFromClient FAILED:%d...exiting\n", rn,
+ code);
#endif
- WEBLOGEXIT(PIPEREADERROR);
- }
+ WEBLOGEXIT(PIPEREADERROR);
+ }
- if (strcasecmp(type, "AFS") == 0) {
- authtype=1;
- }
+ if (strcasecmp(type, "AFS") == 0) {
+ authtype = 1;
+ }
#ifdef ENABLE_DCE_DLOG
- else if (strcasecmp(type, "AFS-DFS")==0) {
- authtype=2;
- }
+ else if (strcasecmp(type, "AFS-DFS") == 0) {
+ authtype = 2;
+ }
#endif /* ENABLE_DCE_DLOG */
- else {
- authtype=0;
- }
+ else {
+ authtype = 0;
+ }
- if(!authtype) {
- reason=(char *)malloc(sizeof(tbuffer));
- sprintf(reason, "weblog: Unknown Authentication type:%s. AFS-DFS login "
- "may not be enabled - check compile flags for ENABLE_DCE_DLOG", type);
- goto reply_failure;
- }
+ if (!authtype) {
+ reason = (char *)malloc(sizeof(tbuffer));
+ sprintf(reason,
+ "weblog: Unknown Authentication type:%s. AFS-DFS login "
+ "may not be enabled - check compile flags for ENABLE_DCE_DLOG",
+ type);
+ goto reply_failure;
+ }
- memset((void *)&tbuffer, 0, sizeof(tbuffer));
+ memset((void *)&tbuffer, 0, sizeof(tbuffer));
- /* look up local cache */
- weblog_login_checksum(name, cell, passwd, cksum);
- code = weblog_login_lookup(name, cell, cksum, &tbuffer[0]);
+ /* look up local cache */
+ weblog_login_checksum(name, cell, passwd, cksum);
+ code = weblog_login_lookup(name, cell, cksum, &tbuffer[0]);
- if (!code) { /* local cache lookup failed */
- /* authenticate user */
+ if (!code) { /* local cache lookup failed */
+ /* authenticate user */
#ifdef DEBUG
- fprintf(stderr, "WEBLOG GROUPCHECK BEFORE KA_AUTH\n");
- printGroups();
+ fprintf(stderr, "WEBLOG GROUPCHECK BEFORE KA_AUTH\n");
+ printGroups();
#endif
-
- if (authtype==1) {
- code=ka_UserAuthenticateGeneral
- (
- KA_USERAUTH_VERSION+0, name, NULL, cell,
- passwd, lifetime, &password_expires,0,&reason
- );
- }
+
+ if (authtype == 1) {
+ code =
+ ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION + 0, name,
+ NULL, cell, passwd, lifetime,
+ &password_expires, 0, &reason);
+ }
#ifdef ENABLE_DCE_DLOG
- else if (authtype == 2) {
- unlog();
- code=getDFScreds(name,cell,passwd, lifetime, &reason);
- }
+ else if (authtype == 2) {
+ unlog();
+ code = getDFScreds(name, cell, passwd, lifetime, &reason);
+ }
#ifdef DEBUG_DCE
- printf("Code:%d\n",code);
- if (code) {
- if (reason) {
- printf("FAILURE:Reason:%s\n",reason);
- }
- }
+ printf("Code:%d\n", code);
+ if (code) {
+ if (reason) {
+ printf("FAILURE:Reason:%s\n", reason);
+ }
+ }
#endif
#endif /* ENABLE_DCE_DLOG */
- if (code) {
+ if (code) {
#ifdef DEBUG
- if (!Silent) {
- fprintf(stderr,"weblog:Unable to authenticate to AFS because "
- "%s\n", reason);
- }
+ if (!Silent) {
+ fprintf(stderr,
+ "weblog:Unable to authenticate to AFS because "
+ "%s\n", reason);
+ }
#endif
- goto reply_failure;
- }
- else {
+ goto reply_failure;
+ } else {
#ifdef DEBUG
- fprintf(stderr,"WEBLOG:After ka_UserAuthenticateGeneral GroupCheck\n");
- printGroups();
+ fprintf(stderr,
+ "WEBLOG:After ka_UserAuthenticateGeneral GroupCheck\n");
+ printGroups();
#endif
- /* get just the ONE token for this PAG from cache manager */
- i=0;
- memcpy((void *)&tbuffer[0], (void *)&i, sizeof(afs_int32));
- code = do_pioctl(tbuffer, sizeof(afs_int32), tbuffer, sizeof(tbuffer),
- VIOCGETTOK, NULL,0);
- if(code) {
- fprintf(stderr, "weblog: failed to get token:%d\n", code);
- strcpy(reason, "FAILED TO GET TOKEN FROM CACHE MANAGER\n");
- }
- else {
- gotToken = 1;
+ /* get just the ONE token for this PAG from cache manager */
+ i = 0;
+ memcpy((void *)&tbuffer[0], (void *)&i, sizeof(afs_int32));
+ code =
+ do_pioctl(tbuffer, sizeof(afs_int32), tbuffer,
+ sizeof(tbuffer), VIOCGETTOK, NULL, 0);
+ if (code) {
+ fprintf(stderr, "weblog: failed to get token:%d\n", code);
+ strcpy(reason,
+ "FAILED TO GET TOKEN FROM CACHE MANAGER\n");
+ } else {
+ gotToken = 1;
#ifdef DEBUG
- hexDump(tbuffer, sizeof(tbuffer));
- parseToken(tbuffer);
+ hexDump(tbuffer, sizeof(tbuffer));
+ parseToken(tbuffer);
#endif /* _DEBUG */
- /* put the token in local cache with the expiration date/time */
- expires = getExpiration(tbuffer);
- if (expires < 0 ) {
+ /* put the token in local cache with the expiration date/time */
+ expires = getExpiration(tbuffer);
+ if (expires < 0) {
#ifdef DEBUG
- fprintf(stderr, "Error getting expiration time\n");
+ fprintf(stderr, "Error getting expiration time\n");
#endif
- }
- else {
- weblog_login_checksum(name, cell, passwd, cksum);
- if (cacheExpiration == 0) {
- weblog_login_store(name, cell, cksum, &tbuffer[0],sizeof(tbuffer),expires);
- }
- else {
- testExpires = cacheExpiration+time(NULL);
- weblog_login_store(name, cell, cksum, &tbuffer[0],sizeof(tbuffer),
- MIN(expires,testExpires));
+ } else {
+ weblog_login_checksum(name, cell, passwd, cksum);
+ if (cacheExpiration == 0) {
+ weblog_login_store(name, cell, cksum, &tbuffer[0],
+ sizeof(tbuffer), expires);
+ } else {
+ testExpires = cacheExpiration + time(NULL);
+ weblog_login_store(name, cell, cksum, &tbuffer[0],
+ sizeof(tbuffer), MIN(expires,
+ testExpires));
+ }
+ }
+ }
}
- }
- }
- }
- }
- else {
- /* cache lookup succesful */
+ } else {
+ /* cache lookup succesful */
#ifdef DEBUG
- fprintf(stderr, "WEBLOG: Cache lookup succesful\n");
+ fprintf(stderr, "WEBLOG: Cache lookup succesful\n");
#endif
- gotToken = 1;
- }
+ gotToken = 1;
+ }
- /* prepare the reply buffer with this token */
- if (!gotToken) {
+ /* prepare the reply buffer with this token */
+ if (!gotToken) {
-reply_failure:
- /* respond with a reason why authentication failed */
- sprintf(tbuffer,"FAILURE:%s",reason);
- }
+ reply_failure:
+ /* respond with a reason why authentication failed */
+ sprintf(tbuffer, "FAILURE:%s", reason);
+ }
- /* send response to client */
- code = sendToken(sizeof(tbuffer), tbuffer);
- if (code) {
+ /* send response to client */
+ code = sendToken(sizeof(tbuffer), tbuffer);
+ if (code) {
#ifdef DEBUG
- fprintf(stderr,"sendToken FAILED\n");
+ fprintf(stderr, "sendToken FAILED\n");
#endif
- WEBLOGEXIT(PIPESENDERROR);
- }
- /* unlog after every request unconditionally */
- if (unlog()) {
+ WEBLOGEXIT(PIPESENDERROR);
+ }
+ /* unlog after every request unconditionally */
+ if (unlog()) {
#ifdef DEBUG
- fprintf(stderr, "WEBLOG: UNLOG FAILED\n");
+ fprintf(stderr, "WEBLOG: UNLOG FAILED\n");
#endif
- }
- } /* end - while */
- return 0;
+ }
+ } /* end - while */
+ return 0;
}