struct rx_securityClass * get_sc(char *cellname) { #if 0 char realm[REALM_SZ]; CREDENTIALS c; #endif return rxnull_NewClientSecurityObject(); #if 0 ucstring(realm, cellname, REALM_SZ); if (krb_get_cred("afs", "", realm, &c)) { if (get_ad_tkt("afs", "", realm, DEFAULT_TKT_LIFE)) { return NULL; } else { if (krb_get_cred("afs", "", realm, &c)) { return NULL; } } } return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno, c.ticket_st.length, c.ticket_st.dat); #endif }
int krb_mk_req(KTEXT authent, char *service, char *instance, char *realm, int32_t checksum) #endif { CREDENTIALS cr; KTEXT_ST req; krb5_storage *sp; int code; /* XXX get user realm */ const char *myrealm = realm; krb5_data a; code = krb_get_cred(service, instance, realm, &cr); if(code || time(NULL) > krb_life_to_time(cr.issue_date, cr.lifetime)){ code = get_ad_tkt((char *)service, (char *)instance, (char *)realm, lifetime); if(code == KSUCCESS) code = krb_get_cred(service, instance, realm, &cr); } if(code) return code; sp = krb5_storage_emem(); krb5_store_int8(sp, KRB_PROT_VERSION); krb5_store_int8(sp, AUTH_MSG_APPL_REQUEST); krb5_store_int8(sp, cr.kvno); krb5_store_stringz(sp, realm); krb5_store_int8(sp, cr.ticket_st.length); build_request(&req, cr.pname, cr.pinst, myrealm, checksum); encrypt_ktext(&req, &cr.session, DES_ENCRYPT); krb5_store_int8(sp, req.length); krb5_storage_write(sp, cr.ticket_st.dat, cr.ticket_st.length); krb5_storage_write(sp, req.dat, req.length); krb5_storage_to_data(sp, &a); krb5_storage_free(sp); memcpy(authent->dat, a.data, a.length); authent->length = a.length; krb5_data_free(&a); memset(&cr, 0, sizeof(cr)); memset(&req, 0, sizeof(req)); return KSUCCESS; }
static int get_cred(char *name, char *inst, char *realm, CREDENTIALS *c) { int status; status = krb_get_cred(name, inst, realm, c); if (status != KSUCCESS) { status = get_ad_tkt(name, inst, realm, 255); if (status == KSUCCESS) status = krb_get_cred(name, inst, realm, c); } return (status); }
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; }
static int kvno4(krb5_context ctx, const char *host, krb5_principal sprinc) { krb5_error_code kerr; KTEXT_ST req; CREDENTIALS creds; int err = 0; char name[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; VERBOSE(1, (stderr, "initiating kvno4/udp ping to %s\n", host)); kerr = krb5_524_conv_principal(ctx, sprinc, name, instance, realm); if (kerr) { fail_msg("kvno4", SOCK_DGRAM, host, error_message(kerr)); goto bail; } err = krb_mk_req(&req, name, instance, realm, 0); if (err) goto bail; err = krb_get_cred(name, instance, realm, &creds); if (err) goto bail; VERBOSE(2, (stderr, "%s.%s@%s kvno = %d\n", name, instance, realm, creds.kvno)); bail: if (err) fail_msg("kvno4", SOCK_DGRAM, host, krb_get_err_text(err)); return err; }
static int get_cred(struct kafs_data *data, const char *name, const char *inst, const char *realm, uid_t uid, struct kafs_token *kt) { CREDENTIALS c; KTEXT_ST tkt; int ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, &c); if (ret) { ret = krb_mk_req(&tkt, (char*)name, (char*)inst, (char*)realm, 0); if (ret == KSUCCESS) ret = krb_get_cred((char*)name, (char*)inst, (char*)realm, &c); } if (ret == 0) ret = _kafs_v4_to_kt(&c, uid, kt); return ret; }
static int get_cred(char *name, char *inst, char *realm, CREDENTIALS *c) { int status; status = krb_get_cred(name, inst, realm, c); if (status != KSUCCESS) { #ifdef DONT_HAVE_GET_AD_TKT KTEXT_ST ticket; status = krb_mk_req(&ticket, name, inst, realm, 0); #else status = get_ad_tkt(name, inst, realm, 255); #endif if (status == KSUCCESS) status = krb_get_cred(name, inst, realm, c); } return (status); }
/* * * K4_auth_send - gets authentication bits we need to send to KDC. * * Result is left in auth * * Returns: 0 on failure, 1 on success */ static int k4_auth_send(kstream ks) { int r; /* Return value */ char instance[INST_SZ]; char *realm; char buf[256]; memset(instance, 0, sizeof(instance)); if (realm = krb_get_phost(szHostName)) lstrcpy(instance, realm); realm = krb_realmofhost(szHostName); if (!realm) { strcpy(buf, "Can't find realm for host \""); strncat(buf, szHostName, sizeof(buf) - 1 - strlen(buf)); strncat(buf, "\"", sizeof(buf) - 1 - strlen(buf)); auth_abort(ks, buf, 0); return KFAILURE; } r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0); if (r == 0) r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); if (r) { strcpy(buf, "Can't get \""); strncat(buf, KRB_SERVICE_NAME, sizeof(buf) - 1 - strlen(buf)); if (instance[0] != 0) { strncat(buf, ".", sizeof(buf) - 1 - strlen(buf)); lstrcat(buf, instance); } strncat(buf, "@", sizeof(buf) - 1 - strlen(buf)); lstrcat(buf, realm); strncat(buf, "\" ticket", sizeof(buf) - 1 - strlen(buf)); auth_abort(ks, buf, r); return r; } if (!szUserName[0]) /* Copy if not there */ strcpy(szUserName, cred.pname); return(1); }
/* * Function: Save the credentials for later restoration. * * Parameters: * c - Returned pointer to saved credential cache. * * pname - Returned as principal name of session. * * pinstance - Returned as principal instance of session. * * ncred - Returned number of credentials saved. */ static void push_credentials(CREDENTIALS **cp, char *pname, char *pinstance, int *ncred) { #ifdef KRB4 int i; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; CREDENTIALS *c; if (krb_get_tf_fullname(NULL, pname, pinstance, NULL) != KSUCCESS) { pname[0] = 0; pinstance[0] = 0; } *ncred = krb_get_num_cred(); if (*ncred <= 0) return; c= malloc(*ncred * sizeof(CREDENTIALS)); assert(c != NULL); if (c == NULL) { *ncred = 0; return; } for (i = 0; i < *ncred; i++) { krb_get_nth_cred(service, instance, realm, i + 1); krb_get_cred(service, instance, realm, &c[i]); } *cp = c; #endif #ifdef KRB5 /* FIXME */ return; #endif }
static int mk_auth(struct krb4_data *d, KTEXT adat, char *service, char *host, int checksum) { int ret; CREDENTIALS cred; char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ]; strlcpy(sname, service, sizeof(sname)); strlcpy(inst, krb_get_phost(host), sizeof(inst)); strlcpy(realm, krb_realmofhost(host), sizeof(realm)); ret = krb_mk_req(adat, sname, inst, realm, checksum); if(ret) return ret; strlcpy(sname, service, sizeof(sname)); strlcpy(inst, krb_get_phost(host), sizeof(inst)); strlcpy(realm, krb_realmofhost(host), sizeof(realm)); ret = krb_get_cred(sname, inst, realm, &cred); memmove(&d->key, &cred.session, sizeof(des_cblock)); des_key_sched(&d->key, d->schedule); memset(&cred, 0, sizeof(cred)); return ret; }
int krb_sendauth_udp(long options, int fd, KTEXT_FP ticket, const LPSTR service, const LPSTR inst, LPSTR realm, LONG checksum, MSG_DAT *msg_data, CREDENTIALS *cred, Key_schedule *schedule, struct sockaddr_in *laddr, struct sockaddr_in *faddr, LPSTR version, LPSTR buffer, int sz) { int rem, i, cc; char srv_inst[INST_SZ]; char krb_realm[REALM_SZ]; char buf[BUFSIZ]; long tkt_len; u_char priv_buf[1024]; u_long cksum; rem = KSUCCESS; /* get current realm if not passed in */ if (!realm) { rem = krb_get_lrealm(krb_realm,1); if (rem != KSUCCESS) return (rem); realm = krb_realm; } /* Copy instance into local storage, canonicalizing if desired */ if (options & KOPT_DONT_CANON) (void) strncpy(srv_inst, inst, INST_SZ); else (void) strncpy((LPSTR)srv_inst, (LPSTR)krb_get_phost(inst), INST_SZ); /* Get the ticket if desired */ if (!(options & KOPT_DONT_MK_REQ)) { rem = krb_mk_req(ticket, service, srv_inst, realm, checksum); if (rem != KSUCCESS) return (rem); } #ifdef ATHENA_COMPAT /* this is only for compatibility with old servers */ if (options & KOPT_DO_OLDSTYLE) { (void) sprintf(buf, "%d ", ticket->length); (void) write(fd, buf, strlen(buf)); (void) write(fd, (char *) ticket->dat, ticket->length); return (rem); } #endif /* ATHENA_COMPAT */ /* if the mutual auth, get credentials so we have service session * keys for decryption below */ if (options & KOPT_DO_MUTUAL) { /*if (cc == 1) *{ * krb_get_cred(service, srv_inst, realm, cred); * return (cc); *} */ krb_get_cred(service, srv_inst, realm, cred); } /* Zero the buffer */ (void) bzero(buf, BUFSIZ); /* insert version strings */ (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN); /* increment past version strings */ i = 2*KRB_SENDAUTH_VLEN; /* put ticket length into buffer */ tkt_len = htonl((unsigned long) ticket->length); (void) bcopy((char *) &tkt_len, buf+i, ticket->length); i += ticket->length; /* Normally, we write the request to the server ** For udp, esp. TechNotify type protocols, we ** just return the buffer. */ if (sz < i) return HEY_PAUL_WHAT_ERROR; /* Buffer not big enough */ bcopy(buf, buffer, i); return (KSUCCESS); }
static int try_krb4_authentication(void) { KTEXT_ST auth; /* Kerberos data */ char *reply; char inst[INST_SZ]; char *realm; CREDENTIALS cred; int r, type; socklen_t slen; Key_schedule schedule; u_long checksum, cksum; MSG_DAT msg_data; struct sockaddr_in local, foreign; struct stat st; /* Don't do anything if we don't have any tickets. */ if (stat(tkt_string(), &st) < 0) return 0; strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)), INST_SZ); realm = (char *)krb_realmofhost(get_canonical_hostname(1)); if (!realm) { debug("Kerberos v4: no realm for %s", get_canonical_hostname(1)); return 0; } /* This can really be anything. */ checksum = (u_long)getpid(); r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); if (r != KSUCCESS) { debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]); return 0; } /* Get session key to decrypt the server's reply with. */ r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); if (r != KSUCCESS) { debug("get_cred failed: %s", krb_err_txt[r]); return 0; } des_key_sched((des_cblock *) cred.session, schedule); /* Send authentication info to server. */ packet_start(SSH_CMSG_AUTH_KERBEROS); packet_put_string((char *) auth.dat, auth.length); packet_send(); packet_write_wait(); /* Zero the buffer. */ (void) memset(auth.dat, 0, MAX_KTXT_LEN); slen = sizeof(local); memset(&local, 0, sizeof(local)); if (getsockname(packet_get_connection_in(), (struct sockaddr *)&local, &slen) < 0) debug("getsockname failed: %s", strerror(errno)); slen = sizeof(foreign); memset(&foreign, 0, sizeof(foreign)); if (getpeername(packet_get_connection_in(), (struct sockaddr *)&foreign, &slen) < 0) { debug("getpeername failed: %s", strerror(errno)); cleanup_exit(255); } /* Get server reply. */ type = packet_read(); switch (type) { case SSH_SMSG_FAILURE: /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ debug("Kerberos v4 authentication failed."); return 0; break; case SSH_SMSG_AUTH_KERBEROS_RESPONSE: /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ debug("Kerberos v4 authentication accepted."); /* Get server's response. */ reply = packet_get_string((u_int *) &auth.length); if (auth.length >= MAX_KTXT_LEN) fatal("Kerberos v4: Malformed response from server"); memcpy(auth.dat, reply, auth.length); free(reply); packet_check_eom(); /* * If his response isn't properly encrypted with the session * key, and the decrypted checksum fails to match, he's * bogus. Bail out. */ r = krb_rd_priv(auth.dat, auth.length, (void *)schedule, &cred.session, &foreign, &local, &msg_data); if (r != KSUCCESS) { debug("Kerberos v4 krb_rd_priv failed: %s", krb_err_txt[r]); packet_disconnect("Kerberos v4 challenge failed!"); } /* Fetch the (incremented) checksum that we supplied in the request. */ memcpy((char *)&cksum, (char *)msg_data.app_data, sizeof(cksum)); cksum = ntohl(cksum); /* If it matches, we're golden. */ if (cksum == checksum + 1) { debug("Kerberos v4 challenge successful."); return 1; } else packet_disconnect("Kerberos v4 challenge failed!"); break; default: packet_disconnect("Protocol error on Kerberos v4 response: %d", type); } return 0; }
/* * Function: Process WM_TIMER messages */ static void kwin_timer(HWND hwnd, UINT timer_id) { HWND hwndfocus; time_t t; time_t expiration; BOOL expired; #ifdef KRB4 CREDENTIALS c; int ncred; int i; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; #endif #ifdef KRB5 krb5_error_code code; krb5_cc_cursor cursor; krb5_creds cred; int n; char *s; #endif if (timer_id != 1) { FORWARD_WM_TIMER(hwnd, timer_id, DefDlgProc); return; } expired = FALSE; ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); if (alerted) { if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } #ifdef KRB4 ncred = krb_get_num_cred(); for (i = 1; i <= ncred; i++) { krb_get_nth_cred(service, instance, realm, i); if (_stricmp(service, "krbtgt") == 0) { /* Warn if ticket will expire w/i TIME_BUFFER seconds */ krb_get_cred(service, instance, realm, &c); expiration = c.issue_date + (long)c.lifetime * 5L * 60L; t = TIME_BUFFER + time(NULL); if (t >= expiration) { expired = TRUE; /* Don't alert because of stale tickets */ if (t >= expiration + KWIN_UPDATE_PERIOD / 1000) { alerted = TRUE; if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } break; } } } #endif #ifdef KRB5 code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor); while (code == 0) { code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &cred); if (code) break; n = krb5_princ_component(k5_context, cred.server, 0)->length; s = krb5_princ_component(k5_context, cred.server, 0)->data; if (n != KRB5_TGS_NAME_SIZE) continue; if (memcmp(KRB5_TGS_NAME, s, KRB5_TGS_NAME_SIZE)) continue; /* Warn if ticket will expire w/i TIME_BUFFER seconds */ expiration = cred.times.endtime; t = TIME_BUFFER + time(NULL); if (t >= expiration) { expired = TRUE; /* Don't alert because of stale tickets */ if (t >= expiration + KWIN_UPDATE_PERIOD / 1000) { alerted = TRUE; if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } break; } } if (code == 0 || code == KRB5_CC_END) krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); #endif if (!expired) { if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); return; } alerted = TRUE; if (beep) MessageBeep(MB_ICONEXCLAMATION); if (alert) { if (IsIconic(hwnd)) { hwndfocus = GetFocus(); ShowWindow(hwnd, SW_RESTORE); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); SetFocus(hwndfocus); } SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); return; } if (IsIconic(hwnd)) InvalidateRect(hwnd, NULL, TRUE); }
/* * Function: Process WM_PAINT messages by displaying an * informative icon when we are iconic. */ static void kwin_paint(HWND hwnd) { HDC hdc; PAINTSTRUCT ps; HICON hicon; time_t expiration = 0; time_t dt; char buf[20]; RECT r; #ifdef KRB4 int i; int ncred; char service[ANAME_SZ]; char instance[INST_SZ]; char realm[REALM_SZ]; CREDENTIALS c; #endif #ifdef KRB5 krb5_error_code code; krb5_cc_cursor cursor; krb5_creds c; int n; char *service; #endif if (!IsIconic(hwnd)) { FORWARD_WM_PAINT(hwnd, DefDlgProc); return; } #ifdef KRB4 ncred = krb_get_num_cred(); for (i = 1; i <= ncred; i++) { krb_get_nth_cred(service, instance, realm, i); krb_get_cred(service, instance, realm, &c); if (_stricmp(c.service, "krbtgt") == 0) { expiration = c.issue_date - kwin_get_epoch() + (long)c.lifetime * 5L * 60L; break; } } #endif #ifdef KRB5 code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor); while (code == 0) { code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); if (code) break; n = krb5_princ_component(k5_context, c.server, 0)->length; service = krb5_princ_component(k5_context, c.server, 0)->data; if (n != KRB5_TGS_NAME_SIZE) continue; if (memcmp(KRB5_TGS_NAME, service, KRB5_TGS_NAME_SIZE)) continue; expiration = c.times.endtime; break; } if (code == 0 || code == KRB5_CC_END) krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); #endif hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &r); DefWindowProc(hwnd, WM_ICONERASEBKGND, (WPARAM)hdc, 0); if (expiration == 0) { strcpy(buf, KWIN_DIALOG_NAME); hicon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_KWIN)); } else { hicon = kwin_get_icon(expiration); dt = (expiration - time(NULL)) / 60; if (dt <= 0) sprintf(buf, "%s - %s", KWIN_DIALOG_NAME, "Expired"); else if (dt < 60) { dt %= 60; sprintf(buf, "%s - %ld min", KWIN_DIALOG_NAME, dt); } else { dt /= 60; sprintf(buf, "%s - %ld hr", KWIN_DIALOG_NAME, dt); } buf[sizeof(buf) - 1] = '\0'; if (dt > 1) strncat(buf, "s", sizeof(buf) - 1 - strlen(buf)); } DrawIcon(hdc, r.left, r.top, hicon); EndPaint(hwnd, &ps); SetWindowText(hwnd, buf); }
int krb_mk_req(KTEXT authent, char *service, char *instance, char *realm, int32_t checksum) { KTEXT_ST req_st; KTEXT req_id = &req_st; CREDENTIALS cr; /* Credentials used by retr */ KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */ int retval; /* Returned by krb_get_cred */ char myrealm[REALM_SZ]; unsigned char *p = authent->dat; int rem = sizeof(authent->dat); int tmp; tmp = krb_put_int(KRB_PROT_VERSION, p, rem, 1); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; tmp = krb_put_int(AUTH_MSG_APPL_REQUEST, p, rem, 1); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; /* Get the ticket and move it into the authenticator */ if (krb_ap_req_debug) krb_warning("Realm: %s\n", realm); retval = krb_get_cred(service,instance,realm,&cr); if (retval == RET_NOTKT) { retval = get_ad_tkt(service, instance, realm, lifetime); if (retval == KSUCCESS) retval = krb_get_cred(service, instance, realm, &cr); } if (retval != KSUCCESS) return retval; /* * With multi realm ticket files either find a matching TGT or * else use the first TGT for inter-realm authentication. * * In myrealm hold the realm of the principal "owning" the * corresponding ticket-granting-ticket. */ retval = krb_get_cred(KRB_TICKET_GRANTING_TICKET, realm, realm, 0); if (retval == KSUCCESS) { strcpy_truncate(myrealm, realm, REALM_SZ); } else retval = krb_get_tf_realm(TKT_FILE, myrealm); if (retval != KSUCCESS) return retval; if (krb_ap_req_debug) krb_warning("serv=%s.%s@%s princ=%s.%s@%s\n", service, instance, realm, cr.pname, cr.pinst, myrealm); tmp = krb_put_int(cr.kvno, p, rem, 1); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; tmp = krb_put_string(realm, p, rem); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; tmp = krb_put_int(ticket->length, p, rem, 1); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; retval = build_request(req_id, cr.pname, cr.pinst, myrealm, checksum); if (retval != KSUCCESS) return retval; encrypt_ktext(req_id, &cr.session, DES_ENCRYPT); tmp = krb_put_int(req_id->length, p, rem, 1); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; if (rem < ticket->length + req_id->length) return KFAILURE; memcpy(p, ticket->dat, ticket->length); p += ticket->length; rem -= ticket->length; memcpy(p, req_id->dat, req_id->length); p += req_id->length; rem -= req_id->length; authent->length = p - authent->dat; memset(&cr, 0, sizeof(cr)); memset(&req_st, 0, sizeof(req_st)); if (krb_ap_req_debug) krb_warning("Authent->length = %d\n", authent->length); return KSUCCESS; }
int do_GetSecret(char *hostname, const char **identity, int *ilen, const char **secret, int *slen) { struct ktext *authenticator = NULL; struct credentials *cred = NULL; char *host = NULL; int rc = -1; host = krb_canonicalize_host(hostname); if (!host) return -1; cred = malloc(sizeof(struct credentials)); if (!cred) { fprintf(stderr, "krb4: malloc(credentials) failed\n"); goto out; } authenticator = malloc(sizeof(struct ktext)); if (!authenticator) { fprintf(stderr, "krb4: malloc(ktext) failed\n"); goto out; } /* construct a new authenticator, or find an old one */ rc = krb_mk_req(authenticator, kerberos4service, host, kerberos4realm, 0); if (rc) { fprintf(stderr, "krb4: %s (%d)\n", krb_err_txt[rc], rc); rc = 1; goto out; } /* authenticator now contains authenticator */ /* pull out the shared secret for RPC2 to use in the bind */ rc = krb_get_cred(kerberos4service, host, kerberos4realm, cred); if (rc) { fprintf(stderr, "krb4: %s (%d)\n", krb_err_txt[rc], rc); rc = 1; goto out; } /* we now have the key in session_key */ HashSecret(cred->session, 8, *secret); *slen = RPC2_KEYSIZE; *identity = (char *)authenticator; *ilen = sizeof(struct ktext); rc = 0; authenticator = NULL; /* XXX ok, who is supposed to be freeing the authenticator now? -JH */ out: if (host) free(host); if (authenticator) free(authenticator); if (cred) free(cred); return rc; }
static int kerberos4_send(char *name, Authenticator *ap) { KTEXT_ST auth; char instance[INST_SZ]; char *realm; CREDENTIALS cred; int r; printf("[ Trying %s ... ]\r\n", name); if (!UserNameRequested) { if (auth_debug_mode) { printf("Kerberos V4: no user name supplied\r\n"); } return(0); } memset(instance, 0, sizeof(instance)); if ((realm = krb_get_phost(RemoteHostName))) strncpy(instance, realm, sizeof(instance)); instance[sizeof(instance)-1] = '\0'; realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName); if (!realm) { printf("Kerberos V4: no realm for %s\r\n", RemoteHostName); return(0); } r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L); if (r) { printf("mk_req failed: %s\r\n", krb_get_err_text(r)); return(0); } r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred); if (r) { printf("get_cred failed: %s\r\n", krb_get_err_text(r)); return(0); } if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { if (auth_debug_mode) printf("Not enough room for user name\r\n"); return(0); } if (auth_debug_mode) printf("Sent %d bytes of authentication data\r\n", auth.length); if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) { if (auth_debug_mode) printf("Not enough room for authentication data\r\n"); return(0); } #ifdef ENCRYPTION /* create challenge */ if ((ap->way & AUTH_HOW_MASK)==AUTH_HOW_MUTUAL) { int i; des_key_sched(&cred.session, sched); des_init_random_number_generator(&cred.session); des_new_random_key(&session_key); des_ecb_encrypt(&session_key, &session_key, sched, 0); des_ecb_encrypt(&session_key, &challenge, sched, 0); /* old code Some CERT Advisory thinks this is a bad thing... des_init_random_number_generator(&cred.session); des_new_random_key(&challenge); des_ecb_encrypt(&challenge, &session_key, sched, 1); */ /* * Increment the challenge by 1, and encrypt it for * later comparison. */ for (i = 7; i >= 0; --i) if(++challenge[i] != 0) /* No carry! */ break; des_ecb_encrypt(&challenge, &challenge, sched, 1); } #endif if (auth_debug_mode) { printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length)); printd(auth.dat, auth.length); printf("\r\n"); printf("Sent Kerberos V4 credentials to server\r\n"); } return(1); }
Code_t ZMakeAuthentication(register ZNotice_t *notice, char *buffer, int buffer_len, int *len) { #ifdef HAVE_KRB5 return ZMakeZcodeAuthentication(notice, buffer, buffer_len, len/*?XXX*/); #else #ifdef HAVE_KRB4 int result; KTEXT_ST authent; char *cstart, *cend; ZChecksum_t checksum; CREDENTIALS cred; C_Block *session; result = krb_mk_req(&authent, SERVER_SERVICE, SERVER_INSTANCE, __Zephyr_realm, 0); if (result != MK_AP_OK) return (result+krb_err_base); result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE, __Zephyr_realm, &cred); if (result != KSUCCESS) return (result+krb_err_base); session = (C_Block *)cred.session; notice->z_auth = 1; notice->z_authent_len = authent.length; notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3); /* zero length authent is an error, so malloc(0) is not a problem */ if (!notice->z_ascii_authent) return (ENOMEM); if ((result = ZMakeAscii(notice->z_ascii_authent, authent.length*3, authent.dat, authent.length)) != ZERR_NONE) { free(notice->z_ascii_authent); return (result); } result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart, &cend); free(notice->z_ascii_authent); notice->z_authent_len = 0; if (result) return(result); /* Compute a checksum over the header and message. */ checksum = des_quad_cksum((unsigned char *)buffer, NULL, cstart - buffer, 0, session); checksum ^= des_quad_cksum((unsigned char *)cend, NULL, buffer + *len - cend, 0, session); checksum ^= des_quad_cksum((unsigned char *)notice->z_message, NULL, notice->z_message_len, 0, session); notice->z_checksum = checksum; ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum); return (ZERR_NONE); #else notice->z_checksum = 0; notice->z_auth = 1; notice->z_authent_len = 0; notice->z_ascii_authent = ""; return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL)); #endif #endif }