2010-03-08 04:55:21 -06:00
|
|
|
/* Ben Fried deserves credit for writing the code that upon which
|
2013-03-09 18:59:42 -06:00
|
|
|
* this source is based. ADC
|
2010-03-08 04:55:21 -06:00
|
|
|
*/
|
2013-03-09 18:59:42 -06:00
|
|
|
#include "../config.h"
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
#if defined(KRB4) || defined(KRB5)
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
|
|
|
|
#include "HTAAUtil.h" /* for HTAA_KERBEROS_Vx defines */
|
|
|
|
|
|
|
|
#ifdef KRB4
|
|
|
|
#include <krb.h>
|
|
|
|
#define MAX_KDATA_LEN MAX_KTXT_LEN
|
|
|
|
static des_cblock session; /* Our session key */
|
|
|
|
static des_key_schedule schedule; /* Schedule for our session key */
|
|
|
|
int k4checksum;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef KRB5
|
|
|
|
#include <krb5.h>
|
|
|
|
#include <krb_err.h>
|
|
|
|
#ifndef MAX_KDATA_LEN
|
|
|
|
#define MAX_KDATA_LEN 1250
|
|
|
|
#endif
|
|
|
|
#define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours */
|
|
|
|
krb5_auth_context *k5auth_context;
|
|
|
|
krb5_context k5context = 0;
|
|
|
|
krb5_ccache k5ccache;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* is all of this necessary? ADC */
|
|
|
|
|
|
|
|
char *getenv(), *getlogin(); /* *index(), *malloc(), *realloc(); */
|
|
|
|
struct passwd *getpwnam(), *getpwuid();
|
|
|
|
static char *envariables[] = { "USER", "LOGNAME" };
|
|
|
|
|
|
|
|
extern int useAFS; /* perhaps change name */
|
|
|
|
|
|
|
|
int doing_kerb_auth = 0;
|
|
|
|
char phost[1024];
|
|
|
|
char Hostname[1024];
|
|
|
|
|
|
|
|
#define NIL 0
|
|
|
|
#define T 1
|
|
|
|
|
|
|
|
/* Table for converting binary values to and from hexadecimal */
|
|
|
|
static char hex[] = "0123456789abcdef";
|
|
|
|
static char dec[256] = {
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 37 */
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ' ' - '/' */
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* '0' - '?' */
|
|
|
|
0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* '@' - 'O' */
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 'P' - '_' */
|
|
|
|
0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* '`' - 'o' */
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 'p' - DEL */
|
|
|
|
};
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* scheme_login -- lets user login for Kerberos TGT
|
|
|
|
*
|
|
|
|
* Returns 0 on success
|
|
|
|
* Returns 1 on failure (after reporting error to user)
|
|
|
|
***************************************************************************/
|
|
|
|
int scheme_login(scheme)
|
|
|
|
int scheme;
|
|
|
|
{
|
|
|
|
char *username, *password, buf[BUFSIZ], erbuf[BUFSIZ];
|
|
|
|
int code;
|
|
|
|
|
|
|
|
username = (char *) prompt_for_string("Kerberos Username:");
|
|
|
|
|
|
|
|
if (!username || !*username) {
|
|
|
|
application_user_info_wait("You did not enter a Username.\nCannot get Kerberos ticket-granting ticket\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(buf, "Password for %s:", username);
|
|
|
|
password = (char *) prompt_for_password(buf);
|
|
|
|
|
|
|
|
if (!password || !*password) {
|
|
|
|
application_user_info_wait("You did not enter a Password.\nCannot obtain ticket-granting ticket\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0) { /* just to get things started */
|
|
|
|
}
|
|
|
|
#ifdef KRB4
|
|
|
|
else if (scheme == HTAA_KERBEROS_V4) {
|
|
|
|
if (useAFS) {
|
|
|
|
code = AFSgetTGT(username, password, buf);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
code = k4getTGT(username, password, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef KRB5
|
|
|
|
else if (scheme == HTAA_KERBEROS_V5) {
|
|
|
|
code = k5getTGT(username, password, buf);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
memset(password, 0, sizeof(password));
|
|
|
|
|
|
|
|
if (code) {
|
|
|
|
sprintf(erbuf,"Kerberos login error:\n%s",buf);
|
|
|
|
application_user_info_wait(erbuf);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* AFSgetTGT() -- Uses klog to get the K4 TGT
|
|
|
|
*
|
|
|
|
* Returns 1 if pipe open fails
|
|
|
|
* Returns 0 otherwise (even if klog fails!)
|
|
|
|
***************************************************************************/
|
2013-03-09 18:59:42 -06:00
|
|
|
int AFSgetTGT(username, password, err_string)
|
2010-03-08 04:55:21 -06:00
|
|
|
char *err_string, *username, *password;
|
|
|
|
{
|
|
|
|
char reason[256];
|
|
|
|
register int code;
|
|
|
|
|
|
|
|
FILE *fp;
|
|
|
|
char lngbuf[BUFSIZ*2],buf[BUFSIZ];
|
|
|
|
char stop=0;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
sprintf(buf,"klog -tmp -pr %s -pa %s 2>&1",username,password);
|
|
|
|
if (!(fp=popen(buf,"r"))) {
|
|
|
|
application_user_info_wait("Error: Could not startup external klog command.\n");
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(buf," ");
|
|
|
|
strcpy(lngbuf," ");
|
|
|
|
n=1;
|
|
|
|
while (n>0) {
|
|
|
|
n=fread(buf,sizeof(char),BUFSIZ-1,fp);
|
|
|
|
if (n>0) {
|
|
|
|
if (!stop && (n+strlen(lngbuf))<BUFSIZ*2) {
|
|
|
|
buf[n]='\0';
|
|
|
|
strcat(lngbuf,buf);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
stop=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pclose(fp);
|
|
|
|
|
|
|
|
if (strlen(lngbuf)>1) {
|
|
|
|
application_user_info_wait(lngbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef KRB4
|
|
|
|
/****************************************************************************
|
|
|
|
* passwd_to_key -- convert users password to numeric key
|
|
|
|
*
|
|
|
|
* (cribbed from MIT's krb_get_in_tkt.c)
|
|
|
|
* this can probably be augmented to support Transarc's string-to-key
|
|
|
|
***************************************************************************/
|
|
|
|
static int passwd_to_key(user,instance,realm,passwd,key)
|
|
|
|
char *user, *instance, *realm, *passwd;
|
|
|
|
C_Block key;
|
|
|
|
{
|
|
|
|
string_to_key(passwd, key);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* k4getTGT() -- calls K4 libraries to get TGT (non-AFS)
|
|
|
|
*
|
|
|
|
* Returns 0 on success (err_string = "")
|
|
|
|
* Returns 1 on failure (err_string = something meaningful)
|
|
|
|
***************************************************************************/
|
|
|
|
int k4getTGT(username, password, err_string)
|
|
|
|
char *err_string, *username, *password;
|
|
|
|
{
|
|
|
|
char instance[INST_SZ], *sinstance;
|
|
|
|
char realm[REALM_SZ];
|
|
|
|
char pname[MAX_K_NAME_SZ];
|
|
|
|
int lifetime = DEFAULT_TKT_LIFE;
|
|
|
|
int code;
|
|
|
|
|
|
|
|
*instance = '\0'; /* assume client principal "user@realm" (no instance */
|
|
|
|
|
|
|
|
krb_get_lrealm(realm, 1); /* get local realm */
|
|
|
|
|
|
|
|
strcpy(pname, username);
|
|
|
|
strcat(pname, "@");
|
|
|
|
strncat(pname, realm, REALM_SZ);
|
|
|
|
|
|
|
|
sinstance = realm; /* assume tgt is for krbtgt.realm@realm */
|
|
|
|
|
|
|
|
in_tkt(pname, instance); /* to initialize ticket store */
|
|
|
|
|
|
|
|
code = krb_get_in_tkt(username, instance, realm, "krbtgt", sinstance,
|
|
|
|
lifetime, passwd_to_key , NULL, password);
|
|
|
|
|
|
|
|
if (code == INTK_BADPW) {
|
|
|
|
strcpy(err_string, "Wrong password");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (code != INTK_OK) {
|
|
|
|
strcpy(err_string, krb_err_txt[code]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* KRB4 */
|
|
|
|
#ifdef KRB5
|
|
|
|
/****************************************************************************
|
2013-03-09 18:59:42 -06:00
|
|
|
* k5getTGT() -- calls K5 libraries to get TGT (non-AFS)
|
2010-03-08 04:55:21 -06:00
|
|
|
* most of this was copied from the Krb5 kinit.c
|
|
|
|
*
|
|
|
|
* Returns 0 on success (err_string = "")
|
|
|
|
* Returns 1 on failure (err_string = something meaningful)
|
|
|
|
***************************************************************************/
|
|
|
|
int k5getTGT(username, password, err_string)
|
|
|
|
char *username, *password, *err_string;
|
|
|
|
{
|
|
|
|
int code, options = 0; /* KRB5_DEFAULT_OPTIONS = 0 */
|
|
|
|
krb5_creds my_creds;
|
|
|
|
krb5_timestamp now;
|
|
|
|
krb5_principal me, server;
|
|
|
|
krb5_preauthtype *preauth = NULL;
|
|
|
|
/* SWP -- For CodeCenter --
|
|
|
|
krb5_data tgtname = {
|
|
|
|
0,
|
|
|
|
KRB5_TGS_NAME_SIZE,
|
|
|
|
KRB5_TGS_NAME
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
krb5_data tgtname;
|
|
|
|
|
|
|
|
tgtname.magic = 0;
|
|
|
|
tgtname.length = KRB5_TGS_NAME_SIZE;
|
|
|
|
tgtname.data = KRB5_TGS_NAME;
|
|
|
|
|
|
|
|
if (code = krb5_timeofday(k5context, &now)) {
|
|
|
|
sprintf(err_string,"Wouldn't tell you the time of day");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code = krb5_parse_name(k5context, username, &me)) {
|
|
|
|
sprintf(err_string,"Couldn't find client principal name");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code = krb5_cc_initialize (k5context, k5ccache, me)) {
|
|
|
|
sprintf(err_string,"Couldn't initialize credentials cache");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset((char *)&my_creds, 0, sizeof(my_creds));
|
|
|
|
my_creds.client = me;
|
|
|
|
|
|
|
|
if (code = krb5_build_principal_ext(k5context, &server,
|
|
|
|
krb5_princ_realm(k5context, me)->length,
|
|
|
|
krb5_princ_realm(k5context, me)->data,
|
|
|
|
tgtname.length, tgtname.data,
|
|
|
|
krb5_princ_realm(kcontext, me)->length,
|
|
|
|
krb5_princ_realm(kcontext, me)->data,
|
|
|
|
0)) {
|
|
|
|
sprintf(err_string,"Couldn't build server principal name");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
my_creds.server = server;
|
2013-03-09 18:59:42 -06:00
|
|
|
my_creds.times.starttime = 0;
|
2010-03-08 04:55:21 -06:00
|
|
|
my_creds.times.endtime = 0; /* now + KRB5_DEFAULT_LIFE; */
|
|
|
|
my_creds.times.renew_till = 0;
|
|
|
|
|
|
|
|
code = krb5_get_in_tkt_with_password(k5context, options, 0,
|
|
|
|
NULL, preauth, password, k5ccache, &my_creds, 0);
|
|
|
|
|
|
|
|
/* eytpyes = NULL means use default etype for decoding tgt */
|
|
|
|
/* addrs = 0 means use default local (client machine) address */
|
|
|
|
|
|
|
|
if (code) {
|
|
|
|
sprintf(err_string,"krb5_get_in_tkt error: %s", error_message(code));
|
|
|
|
return 1;
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
else {
|
2013-03-09 18:59:42 -06:00
|
|
|
return 0;
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* kdata_to_str -- convert 8-bit char array to ascii string
|
|
|
|
*
|
|
|
|
* Accepts: input array and length
|
|
|
|
* Returns: a pointer to the result, or null pointer on malloc failure
|
|
|
|
* The caller is responsible for freeing the returned value.
|
|
|
|
*
|
|
|
|
* Changed to accomodate general strings with length, due to conflict between
|
|
|
|
* KTEXT and krb5_data types ( 6/28/95 ADC)
|
|
|
|
************************************************************************/
|
|
|
|
static char *kdata_to_str(in_data, length)
|
|
|
|
char *in_data; /* char FAR ?? */
|
|
|
|
int length;
|
|
|
|
{
|
|
|
|
char *result, *p;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
p = result = malloc(length*2+1);
|
|
|
|
if (!result) return (char *) NULL;
|
|
|
|
|
|
|
|
for (i=0; i < length; i++) {
|
|
|
|
*p++ = hex[(in_data[i]>>4)&0xf];
|
|
|
|
*p++ = hex[(in_data[i])&0xf];
|
|
|
|
}
|
|
|
|
*p++ = '\0';
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* str_to_kdata -- Converts ascii string to a (binary) char array
|
|
|
|
*
|
|
|
|
* Accepts: string to convert
|
|
|
|
* pointer to output array
|
|
|
|
* Returns: length of output array, NIL on failure
|
|
|
|
************************************************************************/
|
|
|
|
int str_to_kdata(in_str, out_str)
|
|
|
|
char *in_str;
|
|
|
|
char *out_str;
|
|
|
|
{
|
|
|
|
int inlen, outlen;
|
|
|
|
|
|
|
|
inlen = strlen(in_str);
|
|
|
|
if (inlen & 1) return NIL; /* must be even number, in this scheme */
|
|
|
|
inlen /= 2;
|
|
|
|
if (inlen > MAX_KDATA_LEN) return NIL;
|
|
|
|
|
|
|
|
for (outlen=0; *in_str; outlen++, in_str += 2) {
|
|
|
|
out_str[outlen] = (dec[in_str[0]]<<4) + dec[in_str[1]];
|
|
|
|
}
|
|
|
|
return outlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
2013-03-09 18:59:42 -06:00
|
|
|
* compose_kerberos_auth_string
|
2010-03-08 04:55:21 -06:00
|
|
|
*
|
|
|
|
* Accepts: scheme (one of the HTAA_KERBEROS values)
|
|
|
|
* hostname
|
|
|
|
* Returns: Authorization string (NULL, upon failure)
|
|
|
|
***************************************************************************/
|
|
|
|
char *compose_kerberos_auth_string(scheme, hostname)
|
|
|
|
HTAAScheme scheme;
|
|
|
|
char *hostname;
|
|
|
|
{
|
|
|
|
struct hostent *host_name;
|
|
|
|
char user[BUFSIZ], *inst, *pass, *tmp = 0;
|
|
|
|
int code, retval, firsttime = 1;
|
|
|
|
char buf[BUFSIZ], krb_err_str[BUFSIZ];
|
|
|
|
#ifdef KRB4
|
|
|
|
CREDENTIALS k4cr, k4c;
|
|
|
|
KTEXT_ST k4authent;
|
|
|
|
Key_schedule k4key_s;
|
|
|
|
char *krb_get_phost();
|
|
|
|
static char *better_err_str[] = { "Server principal unrecognized by KDC",
|
|
|
|
"System clocks out of sync" };
|
|
|
|
#endif
|
|
|
|
#ifdef KRB5
|
|
|
|
krb5_data k5ap_req;
|
|
|
|
krb5_principal k5clientp, k5serverp;
|
|
|
|
krb5_creds k5in_creds, *k5out_creds;
|
|
|
|
krb5_timestamp now;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
while (code || firsttime) {
|
|
|
|
|
|
|
|
#ifdef KRB4
|
|
|
|
if (scheme == HTAA_KERBEROS_V4) {
|
|
|
|
k4checksum = time(0) ^ getpid();
|
|
|
|
strcpy(phost, krb_get_phost(hostname));
|
|
|
|
code = krb_mk_req(&k4authent, "khttp", phost,
|
|
|
|
krb_realmofhost(hostname), k4checksum);
|
|
|
|
|
|
|
|
if (!code) { /* check for ticket expired */
|
|
|
|
|
|
|
|
code = krb_get_cred("khttp",phost,krb_realmofhost(hostname),&k4c);
|
|
|
|
|
|
|
|
if (!code) {
|
|
|
|
k4c.issue_date += ((unsigned char) k4c.lifetime) * 5 * 60;
|
|
|
|
if (time(0) >= k4c.issue_date) {
|
|
|
|
code=26;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!code) {
|
|
|
|
strcpy(user,k4c.pname);
|
|
|
|
pass = kdata_to_str(k4authent.dat, k4authent.length);
|
|
|
|
}
|
|
|
|
else if (code == 1) { /* normally "Principal Expired" */
|
|
|
|
strcpy(krb_err_str, better_err_str[0]);
|
|
|
|
}
|
|
|
|
else if (code == RD_AP_TIME) {
|
|
|
|
strcpy(krb_err_str, better_err_str[1]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
strcpy(krb_err_str, krb_err_txt[code]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef KRB5
|
|
|
|
if (scheme == HTAA_KERBEROS_V5) {
|
|
|
|
krb_err_str[0] = '\0';
|
|
|
|
|
|
|
|
if (!k5context) {
|
|
|
|
krb5_init_context(&k5context);
|
|
|
|
if (code) {
|
2013-03-09 18:59:42 -06:00
|
|
|
sprintf(krb_err_str,"Error initializing Kerb5 context: %s\n",error_message(code));
|
2010-03-08 04:55:21 -06:00
|
|
|
application_user_info_wait(krb_err_str);
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
krb5_init_ets(k5context);
|
|
|
|
|
|
|
|
code = krb5_cc_default(k5context, &k5ccache);
|
|
|
|
if (code) {
|
|
|
|
sprintf(krb_err_str,"Error initializing Credentials Cache: %s\n",error_message(code));
|
|
|
|
application_user_info_wait(krb_err_str);
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
code = krb5_mk_req(k5context, &k5auth_context, AP_OPTS_USE_SESSION_KEY,
|
|
|
|
"khttp", hostname, NULL, k5ccache, &k5ap_req);
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!code) {
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
/* get username from credentials cache */
|
|
|
|
|
|
|
|
code = krb5_cc_get_principal(k5context, k5ccache, &k5clientp);
|
|
|
|
if (code) {
|
|
|
|
sprintf(krb_err_str,"Error getting client principal: %s\n",error_message(code));
|
|
|
|
application_user_info_wait(krb_err_str);
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(user, k5clientp->data->data);
|
|
|
|
|
|
|
|
/* get server credentials to check for expiration */
|
|
|
|
|
|
|
|
code = krb5_timeofday(k5context, &now);
|
|
|
|
if (code) {
|
|
|
|
sprintf(krb_err_str,"Couldn't give ya the time of day: %s\n",error_message(code));
|
|
|
|
application_user_info_wait(krb_err_str);
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
krb5_sname_to_principal(k5context, hostname, "khttp",
|
2010-03-08 04:55:21 -06:00
|
|
|
KRB5_NT_SRV_HST, &k5serverp);
|
|
|
|
|
|
|
|
memset((char *)&k5in_creds, 0, sizeof(k5in_creds));
|
|
|
|
|
|
|
|
k5in_creds.server = k5serverp;
|
|
|
|
k5in_creds.client = k5clientp;
|
|
|
|
k5in_creds.times.endtime = now + KRB5_DEFAULT_LIFE;
|
|
|
|
k5in_creds.keyblock.keytype = 0;
|
|
|
|
k5in_creds.authdata = NULL;
|
|
|
|
|
|
|
|
code = krb5_get_credentials(k5context,KRB5_GC_CACHED,k5ccache,&k5in_creds,&k5out_creds);
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if ((code == KRB5_CC_NOTFOUND) || (now >= k5out_creds->times.endtime)) {
|
2010-03-08 04:55:21 -06:00
|
|
|
/* replace "Matching creds not found" */
|
|
|
|
sprintf(krb_err_str,"Kerberos ticket expired\n");
|
|
|
|
code = 666;
|
|
|
|
}
|
|
|
|
|
|
|
|
krb5_free_cred_contents(k5context, &k5in_creds);
|
|
|
|
krb5_free_cred_contents(k5context, &k5out_creds);
|
|
|
|
krb5_free_principal(k5context, k5clientp);
|
|
|
|
krb5_free_principal(k5context, k5serverp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code) {
|
|
|
|
if (!krb_err_str[0]) {
|
|
|
|
sprintf(krb_err_str,"krb5_mk_req: %s\n",error_message(code));
|
|
|
|
}
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
else {
|
2010-03-08 04:55:21 -06:00
|
|
|
pass = kdata_to_str(k5ap_req.data, k5ap_req.length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (code) {
|
|
|
|
sprintf(buf,"Error: %s\n\nWould you like to attempt to login\nto obtain a ticket-granting ticket?\n",krb_err_str);
|
|
|
|
|
|
|
|
if (!prompt_for_yes_or_no(buf)) {
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (scheme_login(scheme))
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
} /* if (code) */
|
|
|
|
firsttime = 0;
|
|
|
|
} /* while (code || firsttime) */
|
|
|
|
|
|
|
|
|
|
|
|
if (!pass) {
|
|
|
|
sprintf(buf,"Error: Couldn't convert kdata to string (out of memory)\nAborting...\n");
|
|
|
|
application_user_info_wait(buf);
|
|
|
|
return (char *) NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tmp)
|
|
|
|
tmp = malloc(strlen(pass)+strlen(user)+40);
|
|
|
|
else
|
|
|
|
tmp = realloc(tmp, strlen(pass)+strlen(user)+40);
|
|
|
|
|
|
|
|
if (!tmp) {
|
|
|
|
/* XXX out of memory */
|
|
|
|
fprintf(stderr,"out of memory!!\n");
|
|
|
|
fflush(stderr);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
doing_kerb_auth = 1;
|
|
|
|
strcpy(Hostname, hostname);
|
|
|
|
sprintf(tmp, "%s %s", user, pass);
|
|
|
|
free(pass);
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* validate_kerberos_server_auth
|
|
|
|
* Accepts: scheme (one of the HTAA_KERBEROS values)
|
|
|
|
* the Authorization line from the request
|
2013-03-09 18:59:42 -06:00
|
|
|
* Returns: NIL on success, T on failure
|
2010-03-08 04:55:21 -06:00
|
|
|
(currently return value not used)
|
|
|
|
************************************************************************/
|
|
|
|
int validate_kerberos_server_auth(scheme, str)
|
|
|
|
HTAAScheme scheme;
|
|
|
|
char *str;
|
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
char buf[256], *tmp;
|
|
|
|
|
|
|
|
|
|
|
|
if (!doing_kerb_auth) {
|
|
|
|
/* sprintf(buf, "Received kerberos credentials from server %s, but I'm not doing kerberos authentication!\n", Hostname);
|
|
|
|
application_user_info_wait(buf);
|
|
|
|
*/
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*str != '[') {
|
|
|
|
fprintf(stderr,"\n\nleft bracket not found: [%s]\n",str);
|
|
|
|
goto krb_server_validate_getout;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmp = index(str, ' ')) *tmp = NULL;
|
|
|
|
tmp = str + strlen(str) - 1;
|
|
|
|
if (*tmp != ']') {
|
|
|
|
fprintf(stderr,"\n\nright bracket not found\n\n");
|
|
|
|
goto krb_server_validate_getout;
|
|
|
|
}
|
|
|
|
*tmp = 0; /* end string where right bracket was */
|
|
|
|
str++; /* get rid of left bracket */
|
|
|
|
|
|
|
|
|
|
|
|
if (0) { /* just to get things started */
|
|
|
|
}
|
|
|
|
#ifdef KRB4
|
|
|
|
else if (scheme == HTAA_KERBEROS_V4) {
|
|
|
|
retval = k4validate_kerberos_server_auth(str);
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
#endif
|
2010-03-08 04:55:21 -06:00
|
|
|
#ifdef KRB5
|
|
|
|
else if (scheme == HTAA_KERBEROS_V5) {
|
|
|
|
retval = k5validate_kerberos_server_auth(str);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
else {
|
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset stupid global state variables for the next auth we do. */
|
|
|
|
|
|
|
|
krb_server_validate_getout:
|
|
|
|
|
|
|
|
if (retval) {
|
|
|
|
sprintf(buf, " Warning:\nAuthentication of server %s failed", Hostname);
|
|
|
|
application_user_info_wait(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
bzero(Hostname, sizeof(Hostname));
|
|
|
|
bzero(phost, sizeof(phost));
|
|
|
|
*/
|
|
|
|
memset(Hostname,0,sizeof(Hostname));
|
|
|
|
memset(phost,0,sizeof(phost));
|
|
|
|
|
|
|
|
doing_kerb_auth = 0;
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
/************************************************************************/
|
|
|
|
#ifdef KRB4
|
|
|
|
int k4validate_kerberos_server_auth(str)
|
|
|
|
char *str;
|
|
|
|
{
|
|
|
|
KTEXT_ST k4authent;
|
|
|
|
CREDENTIALS k4cr;
|
|
|
|
Key_schedule k4key_s;
|
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
k4authent.length = str_to_kdata(str, k4authent.dat);
|
|
|
|
|
|
|
|
if (k4authent.length == 0 || k4authent.length != 8) {
|
|
|
|
fprintf(stderr,"\n\nbad length\n\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (krb_get_cred("khttp", phost, krb_realmofhost(Hostname),&k4cr)) {
|
|
|
|
fprintf(stderr,"\n\ncouldn't get credentials");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
des_key_sched(k4cr.session, k4key_s);
|
|
|
|
des_ecb_encrypt(k4authent.dat, k4authent.dat, k4key_s, 0);
|
|
|
|
|
|
|
|
if (ntohl(*(long *)k4authent.dat) != k4checksum + 1) {
|
|
|
|
fprintf(stderr,"\n\nchecksum just doesn't check out\n\n");
|
2013-03-09 18:59:42 -06:00
|
|
|
return 1;
|
2010-03-08 04:55:21 -06:00
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
|
|
#ifdef KRB5
|
|
|
|
int k5validate_kerberos_server_auth(instr)
|
|
|
|
char *instr;
|
|
|
|
{
|
|
|
|
int code;
|
|
|
|
char buf[256];
|
|
|
|
char tmpstr[MAX_KDATA_LEN];
|
|
|
|
krb5_data k5ap_rep;
|
|
|
|
krb5_ap_rep_enc_part *k5ap_rep_result;
|
|
|
|
|
|
|
|
k5ap_rep.length = str_to_kdata(instr, tmpstr);
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if (k5ap_rep.length == 0)
|
2010-03-08 04:55:21 -06:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
k5ap_rep.data = tmpstr;
|
|
|
|
|
|
|
|
code = krb5_rd_rep(k5context, k5auth_context, &k5ap_rep, &k5ap_rep_result);
|
|
|
|
|
|
|
|
krb5_free_ap_rep_enc_part(k5context, k5ap_rep_result);
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if (code)
|
2010-03-08 04:55:21 -06:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* KRB5 */
|
|
|
|
/************************************************************************/
|
|
|
|
#endif /* KRB4 or KRB5 */
|
|
|
|
|