diff options
author | Karl Ramm <kcr@mit.edu> | 2007-12-25 00:56:08 +0000 |
---|---|---|
committer | Karl Ramm <kcr@mit.edu> | 2007-12-25 00:56:08 +0000 |
commit | 1a0e03eb19998ab496a6ea845ff2c42d9a02df0b (patch) | |
tree | 29b47c8532e1f1678063fbb1b851ee4208134626 /lib/ZMkAuth.c | |
parent | 3f120f880be9ae9aa1612ddc2412e9acb9a8e85e (diff) |
applied athena-update-branch patch
Diffstat (limited to 'lib/ZMkAuth.c')
-rw-r--r-- | lib/ZMkAuth.c | 188 |
1 files changed, 183 insertions, 5 deletions
diff --git a/lib/ZMkAuth.c b/lib/ZMkAuth.c index 5a6749c..92d0bd3 100644 --- a/lib/ZMkAuth.c +++ b/lib/ZMkAuth.c @@ -20,6 +20,10 @@ static const char rcsid_ZMakeAuthentication_c[] = "$Id$"; #include <krb_err.h> #endif +#if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA +#define krb5_free_data(ctx, dat) free((dat)->data) +#endif + Code_t ZResetAuthentication () { return ZERR_NONE; } @@ -30,15 +34,39 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len) int buffer_len; int *len; { -#ifdef HAVE_KRB4 +#if 1 + return ZMakeZcodeAuthentication(notice, buffer, buffer_len, len/*?XXX*/); +#else +#if defined(HAVE_KRB4) || defined(HAVE_KRB5) int result; time_t now; KTEXT_ST authent; char *cstart, *cend; ZChecksum_t checksum; CREDENTIALS cred; - extern unsigned long des_quad_cksum(); + C_Block *session; +#ifdef HAVE_KRB5 + krb5_creds *creds_out; + + result = ZGetCreds(&creds_out); + if (result) + return result; + + result = krb5_524_convert_creds(Z_krb5_ctx, creds_out, &cred); + /* krb5_free_creds(Z_krb5_ctx, creds_out);*/ + if (result) + return result; + /* HOLDING: creds_out */ + + if (creds_out->keyblock.enctype != ENCTYPE_DES_CBC_CRC) + return (KRB5_BAD_ENCTYPE); + session = (C_Block *)creds_out->keyblock.contents; + result = krb_mk_req_creds(&authent, &cred, 0); + if (result != MK_AP_OK) + return result + krb_err_base; +#endif +#ifndef HAVE_KRB5 result = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, __Zephyr_realm, 0); if (result != MK_AP_OK) @@ -48,6 +76,9 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len) if (result != KSUCCESS) return (result+krb_err_base); + session = (C_Block *)cred.session; +#endif + notice->z_auth = 1; notice->z_authent_len = authent.length; notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3); @@ -69,11 +100,11 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len) return(result); /* Compute a checksum over the header and message. */ - checksum = des_quad_cksum(buffer, NULL, cstart - buffer, 0, cred.session); + checksum = des_quad_cksum(buffer, NULL, cstart - buffer, 0, session); checksum ^= des_quad_cksum(cend, NULL, buffer + *len - cend, 0, - cred.session); + session); checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len, - 0, cred.session); + 0, session); notice->z_checksum = checksum; ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum); @@ -85,4 +116,151 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len) notice->z_ascii_authent = ""; return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL)); #endif +#endif } + +Code_t ZMakeZcodeAuthentication(notice, buffer, buffer_len, phdr_len) + register ZNotice_t *notice; + char *buffer; + int buffer_len; + int *phdr_len; +{ + return ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len, + __Zephyr_realm); +} + +Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len, + realm) + register ZNotice_t *notice; + char *buffer; + int buffer_len; + int *phdr_len; + char *realm; +{ +#ifdef HAVE_KRB5 + krb5_error_code result; + krb5_creds *creds; + krb5_keyblock *keyblock; + krb5_enctype enctype; + krb5_cksumtype cksumtype; + krb5_auth_context authctx; + krb5_data *authent; + char *svcinst, *x, *y; + char *cksum_start, *cstart, *cend, *asn1_data; + int i, cksum_len, zcode_len, asn1_len, phdr_adj; + + result = ZGetCredsRealm(&creds, realm); + if (result) + return result; + /* HOLDING: creds */ + + /* Figure out what checksum type to use */ + keyblock = Z_credskey(creds); + /* HOLDING: creds */ + + /* Create the authenticator */ + result = krb5_auth_con_init(Z_krb5_ctx, &authctx); + if (result) { + krb5_free_creds(Z_krb5_ctx, creds); + return (result); + } + + authent = (krb5_data *)malloc(sizeof(krb5_data)); + + /* HOLDING: creds, authctx */ + result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */, + 0 /* in_data */, creds, authent); + krb5_auth_con_free(Z_krb5_ctx, authctx); + if (result) { + krb5_free_creds(Z_krb5_ctx, creds); + return (result); + } + /* HOLDING: creds, authent */ + + /* Encode the authenticator */ + notice->z_auth = 1; + notice->z_authent_len = authent->length; + zcode_len = authent->length * 2 + 2; /* 2x growth plus Z and null */ + notice->z_ascii_authent = (char *)malloc(zcode_len); + if (!notice->z_ascii_authent) { + krb5_free_data(Z_krb5_ctx, authent); + krb5_free_creds(Z_krb5_ctx, creds); + return (ENOMEM); + } + /* HOLDING: creds, authent, notice->z_ascii_authent */ + result = ZMakeZcode(notice->z_ascii_authent, zcode_len, + authent->data, authent->length); + krb5_free_data(Z_krb5_ctx, authent); + if (result) { + free(notice->z_ascii_authent); + krb5_free_creds(Z_krb5_ctx, creds); + return (result); + } + /* HOLDING: creds, notice->z_ascii_authent */ + + /* format the notice header, with a zero checksum */ + result = Z_NewFormatRawHeader(notice, buffer, buffer_len, phdr_len, + &cksum_start, &cksum_len, &cstart, &cend); + free(notice->z_ascii_authent); + notice->z_authent_len = 0; + if (result) { + krb5_free_creds(Z_krb5_ctx, creds); + return (result); + } + result = Z_InsertZcodeChecksum(keyblock, notice, buffer, cksum_start, + cksum_len, cstart, cend, buffer_len, + &phdr_adj); + krb5_free_creds(Z_krb5_ctx, creds); + if (result) { + return result; + } + *phdr_len += phdr_adj; + + return (result); +#endif /* HAVE_KRB5 */ +} + +#ifdef HAVE_KRB5 +int ZGetCreds(krb5_creds **creds_out) { + return ZGetCredsRealm(creds_out, __Zephyr_realm); +} + +int ZGetCredsRealm(krb5_creds **creds_out, char *realm) { + krb5_creds creds_in; + krb5_ccache ccache; /* XXX make this a global or static?*/ + int result; + + result = krb5_cc_default(Z_krb5_ctx, &ccache); + if (result) + return result; + + memset((char *)&creds_in, 0, sizeof(creds_in)); + result = krb5_build_principal(Z_krb5_ctx, &creds_in.server, + strlen(realm), + realm, + SERVER_SERVICE, SERVER_INSTANCE, 0); + if (result) { + krb5_cc_close(Z_krb5_ctx, ccache); + return result; + } + + result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client); + if (result) { + krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */ + krb5_cc_close(Z_krb5_ctx, ccache); + return result; + } + +#ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE + creds_in.keyblock.enctype = ENCTYPE_DES_CBC_CRC; /* XXX? */ +#else + creds_in.session.keytype = KEYTYPE_DES; /* XXX? */ +#endif + + result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out); + krb5_cc_close(Z_krb5_ctx, ccache); + krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */ + + return result; +} +#endif |