Include ticket forwarding stuff.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1240 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -67,6 +67,7 @@ RCSID("$Id$");
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <des.h> /* BSD wont include this in krb.h, so we do it here */
|
#include <des.h> /* BSD wont include this in krb.h, so we do it here */
|
||||||
#include <krb.h>
|
#include <krb.h>
|
||||||
|
#include <pwd.h>
|
||||||
#ifdef __STDC__
|
#ifdef __STDC__
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -83,10 +84,8 @@ RCSID("$Id$");
|
|||||||
int kerberos4_cksum (unsigned char *, int);
|
int kerberos4_cksum (unsigned char *, int);
|
||||||
extern int auth_debug_mode;
|
extern int auth_debug_mode;
|
||||||
|
|
||||||
static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
static unsigned char str_data[2048] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
|
||||||
AUTHTYPE_KERBEROS_V4, };
|
AUTHTYPE_KERBEROS_V4, };
|
||||||
static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
|
||||||
TELQUAL_NAME, };
|
|
||||||
|
|
||||||
#define KRB_AUTH 0 /* Authentication data follows */
|
#define KRB_AUTH 0 /* Authentication data follows */
|
||||||
#define KRB_REJECT 1 /* Rejected (reason might follow) */
|
#define KRB_REJECT 1 /* Rejected (reason might follow) */
|
||||||
@@ -94,6 +93,10 @@ static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
|
|||||||
#define KRB_CHALLENGE 3 /* Challenge for mutual auth. */
|
#define KRB_CHALLENGE 3 /* Challenge for mutual auth. */
|
||||||
#define KRB_RESPONSE 4 /* Response for mutual auth. */
|
#define KRB_RESPONSE 4 /* Response for mutual auth. */
|
||||||
|
|
||||||
|
#define KRB_FORWARD 5 /* */
|
||||||
|
#define KRB_FORWARD_ACCEPT 6 /* */
|
||||||
|
#define KRB_FORWARD_REJECT 7 /* */
|
||||||
|
|
||||||
#define KRB_SERVICE_NAME "rcmd"
|
#define KRB_SERVICE_NAME "rcmd"
|
||||||
|
|
||||||
static KTEXT_ST auth;
|
static KTEXT_ST auth;
|
||||||
@@ -102,6 +105,11 @@ static AUTH_DAT adat;
|
|||||||
static des_cblock session_key;
|
static des_cblock session_key;
|
||||||
static des_key_schedule sched;
|
static des_key_schedule sched;
|
||||||
static des_cblock challenge;
|
static des_cblock challenge;
|
||||||
|
static int auth_done; /* XXX */
|
||||||
|
|
||||||
|
static int pack_cred(CREDENTIALS *cred, unsigned char *buf);
|
||||||
|
static int unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred);
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Data(Authenticator *ap, int type, void *d, int c)
|
Data(Authenticator *ap, int type, void *d, int c)
|
||||||
@@ -295,9 +303,15 @@ kerberos4_is(Authenticator *ap, unsigned char *data, int cnt)
|
|||||||
memmove(session_key, adat.session, sizeof(adat.session));
|
memmove(session_key, adat.session, sizeof(adat.session));
|
||||||
krb_kntoln(&adat, name);
|
krb_kntoln(&adat, name);
|
||||||
|
|
||||||
if (UserNameRequested && !kuserok(&adat, UserNameRequested))
|
if (UserNameRequested && !kuserok(&adat, UserNameRequested)){
|
||||||
|
char ts[MaxPathLen];
|
||||||
|
struct passwd *pw = getpwnam(UserNameRequested);
|
||||||
|
if(pw){
|
||||||
|
sprintf(ts, "%s%d", TKT_ROOT, pw->pw_uid);
|
||||||
|
setenv("KRBTKFILE", ts);
|
||||||
|
}
|
||||||
Data(ap, KRB_ACCEPT, NULL, 0);
|
Data(ap, KRB_ACCEPT, NULL, 0);
|
||||||
else {
|
} else {
|
||||||
char *msg = malloc(ANAME_SZ + 1 + INST_SZ +
|
char *msg = malloc(ANAME_SZ + 1 + INST_SZ +
|
||||||
REALM_SZ +
|
REALM_SZ +
|
||||||
strlen(UserNameRequested) + 80);
|
strlen(UserNameRequested) + 80);
|
||||||
@@ -354,6 +368,47 @@ kerberos4_is(Authenticator *ap, unsigned char *data, int cnt)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case KRB_FORWARD:
|
||||||
|
{
|
||||||
|
des_key_schedule ks;
|
||||||
|
unsigned char netcred[sizeof(CREDENTIALS)];
|
||||||
|
char *msg;
|
||||||
|
CREDENTIALS cred;
|
||||||
|
int ret;
|
||||||
|
if(cnt > sizeof(cred))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
des_set_key(&session_key, ks);
|
||||||
|
des_pcbc_encrypt((void*)data, (void*)netcred, cnt,
|
||||||
|
ks, &session_key, DES_DECRYPT);
|
||||||
|
unpack_cred(netcred, cnt, &cred);
|
||||||
|
{
|
||||||
|
if(strcmp(cred.service, KRB_TICKET_GRANTING_TICKET) ||
|
||||||
|
strncmp(cred.instance, cred.realm, sizeof(cred.instance)) ||
|
||||||
|
cred.lifetime < 0 || cred.lifetime > 255 ||
|
||||||
|
cred.kvno < 0 || cred.kvno > 255 ||
|
||||||
|
cred.issue_date < 0 ||
|
||||||
|
cred.issue_date > time(0) + CLOCK_SKEW ||
|
||||||
|
strncmp(cred.pname, adat.pname, sizeof(cred.pname)) ||
|
||||||
|
strncmp(cred.pinst, adat.pinst, sizeof(cred.pname))){
|
||||||
|
Data(ap, KRB_FORWARD_REJECT, "Bad credentials", -1);
|
||||||
|
}else{
|
||||||
|
if((ret = tf_setup(&cred) == KSUCCESS)){
|
||||||
|
chown(tkt_string(), pw->pw_uid, pw->pw_gid);
|
||||||
|
Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
|
||||||
|
} else{
|
||||||
|
Data(ap, KRB_FORWARD_REJECT,
|
||||||
|
krb_get_err_text(ret), -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(data, 0, cnt);
|
||||||
|
memset(ks, 0, sizeof(ks));
|
||||||
|
memset(&cred, 0, sizeof(cred));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (auth_debug_mode)
|
if (auth_debug_mode)
|
||||||
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
||||||
@@ -371,27 +426,32 @@ kerberos4_reply(Authenticator *ap, unsigned char *data, int cnt)
|
|||||||
return;
|
return;
|
||||||
switch (*data++) {
|
switch (*data++) {
|
||||||
case KRB_REJECT:
|
case KRB_REJECT:
|
||||||
if (cnt > 0) {
|
if(auth_done){ /* XXX Ick! */
|
||||||
printf("[ Kerberos V4 refuses authentication because %.*s ]\r\n",
|
printf("[ Kerberos V4 received unknown opcode ]\r\n");
|
||||||
cnt, data);
|
}else{
|
||||||
} else
|
printf("[ Kerberos V4 refuses authentication ");
|
||||||
printf("[ Kerberos V4 refuses authentication ]\r\n");
|
if (cnt > 0)
|
||||||
|
printf("because %.*s ", cnt, data);
|
||||||
|
printf("]\r\n");
|
||||||
auth_send_retry();
|
auth_send_retry();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case KRB_ACCEPT:
|
case KRB_ACCEPT:
|
||||||
printf("[ Kerberos V4 accepts you ]\r\n");
|
printf("[ Kerberos V4 accepts you ]\r\n");
|
||||||
|
auth_done = 1;
|
||||||
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
|
||||||
/*
|
/*
|
||||||
* Send over the encrypted challenge.
|
* Send over the encrypted challenge.
|
||||||
*/
|
*/
|
||||||
Data(ap, KRB_CHALLENGE, session_key,
|
Data(ap, KRB_CHALLENGE, session_key,
|
||||||
sizeof(session_key));
|
sizeof(session_key));
|
||||||
#ifdef ENCRYPTION
|
|
||||||
des_ecb_encrypt(&session_key, &session_key, sched, 1);
|
des_ecb_encrypt(&session_key, &session_key, sched, 1);
|
||||||
skey.type = SK_DES;
|
skey.type = SK_DES;
|
||||||
skey.length = 8;
|
skey.length = 8;
|
||||||
skey.data = session_key;
|
skey.data = session_key;
|
||||||
encrypt_session_key(&skey, 0);
|
encrypt_session_key(&skey, 0);
|
||||||
|
#if 0
|
||||||
|
kerberos4_forward(ap);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -408,6 +468,13 @@ kerberos4_reply(Authenticator *ap, unsigned char *data, int cnt)
|
|||||||
printf("[ Kerberos V4 challenge successful ]\r\n");
|
printf("[ Kerberos V4 challenge successful ]\r\n");
|
||||||
auth_finished(ap, AUTH_USER);
|
auth_finished(ap, AUTH_USER);
|
||||||
break;
|
break;
|
||||||
|
case KRB_FORWARD_ACCEPT:
|
||||||
|
printf("[ Kerberos V4 accepted forwarded credentials ]\r\n");
|
||||||
|
break;
|
||||||
|
case KRB_FORWARD_REJECT:
|
||||||
|
printf("[ Kerberos V4 rejected forwarded credentials: `%.*s']\r\n",
|
||||||
|
cnt, data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (auth_debug_mode)
|
if (auth_debug_mode)
|
||||||
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
printf("Unknown Kerberos option %d\r\n", data[-1]);
|
||||||
@@ -518,18 +585,73 @@ kerberos4_cksum(unsigned char *d, int n)
|
|||||||
}
|
}
|
||||||
return(ck);
|
return(ck);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef notdef
|
static int
|
||||||
|
pack_cred(CREDENTIALS *cred, unsigned char *buf)
|
||||||
prkey(msg, key)
|
|
||||||
char *msg;
|
|
||||||
unsigned char *key;
|
|
||||||
{
|
{
|
||||||
int i;
|
int l;
|
||||||
printf("%s:", msg);
|
unsigned char *p = buf;
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
printf(" %3d", key[i]);
|
p += krb_put_nir(cred->service, cred->instance, cred->realm, p);
|
||||||
printf("\r\n");
|
memcpy(p, cred->session, 8);
|
||||||
|
p += 8;
|
||||||
|
*p++ = cred->lifetime;
|
||||||
|
*p++ = cred->kvno;
|
||||||
|
p += krb_put_int(cred->ticket_st.length);
|
||||||
|
memcpy(p, cred->ticket_st.dat, cred->ticket_st.length);
|
||||||
|
p += cred->ticket_st.length;
|
||||||
|
p += krb_put_int(cred->issue_date, p, 4);
|
||||||
|
p += krb_put_nir(cred->pname, cred->pinst, NULL, p);
|
||||||
|
return p - buf;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
static int
|
||||||
|
unpack_cred(unsigned char *buf, int len, CREDENTIALS *cred)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
p += krb_get_nir(p, cred->service, cred->instance, cred->realm);
|
||||||
|
memcpy(cred->session, p, 8);
|
||||||
|
p += 8;
|
||||||
|
cred->lifetime = *p++;
|
||||||
|
cred->kvno = *p++;
|
||||||
|
p += krb_get_int(p, &cred->ticket_st.length);
|
||||||
|
memcpy(cred->ticket_st.dat, p, cred->ticket_st.length);
|
||||||
|
cred->ticket_st.mbz = 0;
|
||||||
|
p += krb_get_int(p, &cred->issue_date, 4, 0);
|
||||||
|
p += krb_get_nir(p, cred->pname, cred->pinst, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
kerberos4_forward(Authenticator *ap)
|
||||||
|
{
|
||||||
|
CREDENTIALS cred;
|
||||||
|
char *realm;
|
||||||
|
des_key_schedule ks;
|
||||||
|
int len;
|
||||||
|
unsigned char netcred[sizeof(CREDENTIALS)];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
realm = krb_realmofhost(RemoteHostName);
|
||||||
|
if(realm == NULL)
|
||||||
|
return -1;
|
||||||
|
memset(&cred, 0, sizeof(cred));
|
||||||
|
ret = krb_get_cred(KRB_TICKET_GRANTING_TICKET,
|
||||||
|
realm,
|
||||||
|
realm,
|
||||||
|
&cred);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
des_set_key(&session_key, ks);
|
||||||
|
len = pack_cred(&cred, netcred);
|
||||||
|
des_pcbc_encrypt((void*)netcred, (void*)netcred, len,
|
||||||
|
ks, &session_key, DES_ENCRYPT);
|
||||||
|
memset(ks, 0, sizeof(ks));
|
||||||
|
Data(ap, KRB_FORWARD, netcred, len);
|
||||||
|
memset(netcred, 0, sizeof(netcred));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* KRB4 */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user