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 /server/bdump.c | |
parent | 3f120f880be9ae9aa1612ddc2412e9acb9a8e85e (diff) |
applied athena-update-branch patch
Diffstat (limited to 'server/bdump.c')
-rw-r--r-- | server/bdump.c | 229 |
1 files changed, 226 insertions, 3 deletions
diff --git a/server/bdump.c b/server/bdump.c index 22bf518..d997672 100644 --- a/server/bdump.c +++ b/server/bdump.c @@ -66,6 +66,12 @@ static int setup_file_pointers __P((void)); static void shutdown_file_pointers __P((void)); static void cleanup __P((Server *server)); +#ifdef HAVE_KRB5 +static long ticket5_time; +#define TKT5LIFETIME 8*60*60 +#define tkt5_lifetime(val) (val) +#endif + #ifdef HAVE_KRB4 static long ticket_time; @@ -272,7 +278,12 @@ bdump_send() } /* Now begin the brain dump. */ - +#ifdef HAVE_KRB5 + { /* "server" side */ + krb5_auth_context actx; + + } +#else /* HAVE_KRB5 */ #ifdef HAVE_KRB4 /* receive the authenticator */ retval = GetKerberosData(live_socket, from.sin_addr, &kdata, @@ -311,6 +322,7 @@ bdump_send() return; } #endif /* HAVE_KRB4 */ +#endif /* HAVE_KRB5 */ retval = setup_file_pointers(); if (retval != 0) { @@ -450,6 +462,109 @@ bdump_get_v12 (notice, auth, who, server) /* Now begin the brain dump. */ +#ifdef HAVE_KRB5 + if (get_tgt()) { + cleanup(server); + return; + } + { /* "client" side */ + krb5_auth_context actx; + krb5_creds creds; + krb5_creds *credsp; + krb5_principal principal; + krb5_data data; + krb5_ap_rep_enc_part *rep; + + memset((char *)&creds, 0, sizeof(creds)); + + retval = krb5_build_principal(Z_krb5_ctx, &principal, + strlen(ZGetRealm()), + ZGetRealm(), + SERVER_KRB5_SERVICE, SERVER_INSTANCE, + 0); + if (retval) { + syslog(LOG_ERR, "bdump_get: krb5_build_principal: %s", error_message(retval)); + cleanup(server); + return; + } + + retval = krb5_copy_principal(Z_krb5_ctx, principal, &creds.server); + if (retval) { + syslog(LOG_ERR, "bdump_get: krb5_copy_principal (server): %s", error_message(retval)); + krb5_free_principal(Z_krb5_ctx, principal); + cleanup(server); + return; + } + + retval = krb5_copy_principal(Z_krb5_ctx, principal, &creds.client); + krb5_free_principal(Z_krb5_ctx, principal); + if (retval) { + syslog(LOG_ERR, "bdump_get: krb5_copy_principal (client): %s", error_message(retval)); + krb5_free_cred_contents(Z_krb5_ctx, &creds); + cleanup(server); + return; + } + + retval = krb5_get_credentials(Z_krb5_ctx, 0, Z_krb5_ccache, + &creds, &credsp); + krb5_free_cred_contents(Z_krb5_ctx, &creds); + if (retval) { + syslog(LOG_ERR, "bdump_get: krb5_get_credentials: %s", error_message(retval)); + cleanup(server); + return; + } + + retval = krb5_auth_con_init(Z_krb5_ctx, &actx); + if (retval) { + syslog(LOG_ERR, "bdump_get: krb5_auth_con_init: %s", error_message(retval)); + krb5_free_creds(Z_krb5_ctx, credsp); + cleanup(server); + return; + } + + memset((char *)&data, 0, sizeof(krb5_data)); + retval = krb5_mk_req_extended(Z_krb5_ctx, &actx, AP_OPTS_MUTUAL_REQUIRED|AP_OPTS_USE_SUBKEY, + NULL, credsp, &data); + if (retval) { + syslog(LOG_ERR, "bdump_get: krb5_mk_req_ext: %s", error_message(retval)); + krb5_auth_con_free(Z_krb5_ctx, actx); + krb5_free_creds(Z_krb5_ctx, credsp); + cleanup(server); + return; + } + retval = SendKrb5Data(live_socket, &data); + krb5_free_creds(Z_krb5_ctx, credsp); + if (retval) { + syslog(LOG_ERR, "bdump_get: cannot send authenticator: %s", + error_message(retval)); + krb5_free_data_contents(Z_krb5_ctx, &data); + krb5_auth_con_free(Z_krb5_ctx, actx); + cleanup(server); + return; + } + krb5_free_data_contents(Z_krb5_ctx, &data); + memset((char *)&data, 0, sizeof(krb5_data)); + retval = GetKrb5Data(live_socket, &data); + if (retval) { + syslog(LOG_ERR, "bdump_get: cannot get auth response: %s", + error_message(retval)); + krb5_auth_con_free(Z_krb5_ctx, actx); + cleanup(server); + return; + } + retval = krb5_rd_rep(Z_krb5_ctx, actx, &data, &rep); + free(data.data); + memset((char *)&data, 0, sizeof(krb5_data)); + if (retval) { + syslog(LOG_ERR, "bdump_get: mutual authentication failed: %s", + error_message(retval)); + krb5_auth_con_free(Z_krb5_ctx, actx); + cleanup(server); + return; + } + + } +#else #ifdef HAVE_KRB4 /* send an authenticator */ if (get_tgt()) { @@ -485,6 +600,7 @@ bdump_get_v12 (notice, auth, who, server) return; } #endif /* HAVE_KRB4 */ +#endif retval = setup_file_pointers(); if (retval != 0) { syslog(LOG_WARNING, "bdump_get: can't set up file pointers: %s", @@ -728,6 +844,54 @@ get_tgt() des_key_sched(serv_key, serv_ksched.s); #endif /* !NOENCRYPTION */ } +#ifdef HAVE_KRB5 + /* XXX */ + if (ticket5_time < NOW - tkt5_lifetime(TKT5LIFETIME) + (15L * 60L)) { + krb5_keytab kt; + krb5_get_init_creds_opt opt; + krb5_creds cred; + krb5_principal principal; + + memset(&cred, 0, sizeof(cred)); + + retval = krb5_build_principal(Z_krb5_ctx, &principal, + strlen(ZGetRealm()), + ZGetRealm(), + SERVER_KRB5_SERVICE, SERVER_INSTANCE, + 0); + if (retval) { + krb5_free_principal(Z_krb5_ctx, principal); + return(1); + } + + krb5_get_init_creds_opt_init (&opt); + krb5_get_init_creds_opt_set_tkt_life (&opt, TKT5LIFETIME); + + retval = krb5_kt_resolve(Z_krb5_ctx, keytab_file, &kt); + if (retval) return(1); + + retval = krb5_get_init_creds_keytab (Z_krb5_ctx, + &cred, + principal, + kt, + 0, + NULL, + &opt); + krb5_free_principal(Z_krb5_ctx, principal); + krb5_kt_close(Z_krb5_ctx, kt); + if (retval) return(1); + + retval = krb5_cc_initialize (Z_krb5_ctx, Z_krb5_ccache, cred.client); + if (retval) return(1); + + retval = krb5_cc_store_cred (Z_krb5_ctx, Z_krb5_ccache, &cred); + if (retval) return(1); + + ticket5_time = NOW; + + krb5_free_cred_contents (Z_krb5_ctx, &cred); + } +#endif return(0); } #endif /* HAVE_KRB4 */ @@ -771,11 +935,17 @@ bdump_recv_loop(server) Code_t retval; Client *client = NULL; struct sockaddr_in who; -#ifdef HAVE_KRB4 +#ifdef HAVE_KRB5 + char buf[512]; + int blen; +#endif +#if defined(HAVE_KRB4) || defined(HAVE_KRB5) char *cp; +#endif +#ifdef HAVE_KRB4 C_Block cblock; #endif /* HAVE_KRB4 */ - Realm *realm = NULL; + ZRealm *realm = NULL; #if 1 zdbug((LOG_DEBUG, "bdump recv loop")); @@ -853,6 +1023,52 @@ bdump_recv_loop(server) syslog(LOG_ERR,"brl failed: %s", error_message(retval)); return retval; } +#ifdef HAVE_KRB5 + client->session_keyblock = NULL; + if (*notice.z_class_inst) { + /* check out this session key I found */ + cp = notice.z_message + strlen(notice.z_message) + 1; + if (*cp == '0') { + /* ****ing netascii; this is an encrypted DES keyblock + XXX this code should be conditionalized for server + transitions */ + retval = krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC, + sizeof(C_Block), + &client->session_keyblock); + if (retval) { + syslog(LOG_ERR, "brl failed to allocate DES keyblock: %s", + error_message(retval)); + return retval; + } + retval = ZReadAscii(cp, strlen(cp), cblock, sizeof(C_Block)); + if (retval != ZERR_NONE) { + syslog(LOG_ERR,"brl bad cblk read: %s (%s)", + error_message(retval), cp); + } else { + des_ecb_encrypt(cblock, client->session_keyblock->contents, + serv_ksched.s, DES_DECRYPT); + } + } else if (*cp == 'Z') { /* Zcode! Long live the new flesh! */ + retval = ZReadZcode(cp, buf, sizeof(buf), &blen); + if (retval != ZERR_NONE) { + syslog(LOG_ERR,"brl bad cblk read: %s (%s)", + error_message(retval), cp); + } else { + retval = krb5_init_keyblock(Z_krb5_ctx, + ntohl(*(krb5_enctype *)&buf[0]), + ntohl(*(krb5_ui_4 *)&buf[4]), + &client->session_keyblock); + if (retval) { + syslog(LOG_ERR, "brl failed to allocate keyblock: %s", + error_message(retval)); + return retval; + } + memcpy(client->session_keyblock->contents, &buf[8], + client->session_keyblock->length); + } + } + } +#else #ifdef HAVE_KRB4 memset(client->session_key, 0, sizeof(C_Block)); if (*notice.z_class_inst) { @@ -872,6 +1088,7 @@ bdump_recv_loop(server) } } #endif /* HAVE_KRB4 */ +#endif } else if (strcmp(notice.z_opcode, CLIENT_SUBSCRIBE) == 0) { /* a subscription packet */ if (!client) { @@ -1138,7 +1355,13 @@ net_read(f, buf, len) errno = 0; cc = fread(buf, 1, len, f); if (cc == 0) + { + if (feof(f)) + return len2; + if (errno == 0) + errno = EIO; return -1; + } buf += cc; len2 += cc; len -= cc; |