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; }
Code_t SendKerberosData(int fd, /* file descriptor to write onto */ KTEXT ticket, /* where to put ticket (return) */ char *service, /* service name, foreign host */ char *host) { int rem; char p[32]; size_t written; size_t size_to_write; rem = krb_mk_req(ticket, service, host, (char *)ZGetRealm(), (u_long) 0); if (rem != KSUCCESS) return rem + krb_err_base; (void) sprintf(p,"%d ",ticket->length); size_to_write = strlen (p); if ((written = write(fd, p, size_to_write)) != size_to_write) return ((ssize_t)written < 0) ? errno : ZSRV_PKSHORT; if ((written = write(fd, ticket->dat, ticket->length)) != ticket->length) return ((ssize_t)written < 0) ? errno : ZSRV_PKSHORT; return 0; }
char * ldap_get_kerberosv4_credentials( LDAP *ld, LDAP_CONST char *who, LDAP_CONST char *service, ber_len_t *len ) { KTEXT_ST ktxt; int err; char realm[REALM_SZ], *cred, *krbinstance; Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 ); if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) { Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: " "krb_get_tf_realm failed: %s\n", krb_err_txt[err], 0, 0 ); ld->ld_errno = LDAP_AUTH_UNKNOWN; return( NULL ); } err = 0; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); #endif if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) { /* not connected yet */ err = ldap_open_defconn( ld ); } #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); #endif if ( err < 0 ) return NULL; krbinstance = ld->ld_defconn->lconn_krbinstance; if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 )) != KSUCCESS ) { Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: " "krb_mk_req failed (%s)\n", krb_err_txt[err], 0, 0 ); ld->ld_errno = LDAP_AUTH_UNKNOWN; return( NULL ); } if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( NULL ); } *len = ktxt.length; AC_MEMCPY( cred, ktxt.dat, ktxt.length ); return( cred ); }
int mr_auth(char *prog) { #ifdef HAVE_KRB4 int status; mr_params params, reply; char *args[2]; int argl[2]; char realm[REALM_SZ], host[BUFSIZ], *p; KTEXT_ST auth; CHECK_CONNECTED; if ((status = mr_host(host, sizeof(host) - 1))) return status; strcpy(realm, krb_realmofhost(host)); for (p = host; *p && *p != '.'; p++) { if (isupper(*p)) *p = tolower(*p); } *p = '\0'; status = krb_mk_req(&auth, MOIRA_SNAME, host, realm, 0); if (status != KSUCCESS) { status += ERROR_TABLE_BASE_krb; return status; } params.u.mr_procno = MR_AUTH; params.mr_argc = 2; params.mr_argv = args; params.mr_argl = argl; params.mr_argv[0] = (char *)auth.dat; params.mr_argl[0] = auth.length; params.mr_argv[1] = prog; params.mr_argl[1] = strlen(prog) + 1; if ((status = mr_do_call(¶ms, &reply)) == MR_SUCCESS) status = reply.u.mr_status; mr_destroy_reply(reply); return status; #else return MR_NO_KRB4; #endif }
/* * * 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); }
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); }
char * get_kerberosv4_credentials( LDAP *ld, char *who, char *service, int *len ) { KTEXT_ST ktxt; int err; char realm[REALM_SZ], *cred, *krbinstance; Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 191, "get_kerberosv4_credentials\n"), 0, 0, 0 ); if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) { #ifndef NO_USERINTERFACE fprintf( stderr, "krb_get_tf_realm failed (%s)\n", krb_err_txt[err] ); #endif /* NO_USERINTERFACE */ ld->ld_errno = LDAP_INVALID_CREDENTIALS; return( NULL ); } #ifdef LDAP_REFERRALS krbinstance = ld->ld_defconn->lconn_krbinstance; #else /* LDAP_REFERRALS */ krbinstance = ld->ld_host; #endif /* LDAP_REFERRALS */ if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 )) != KSUCCESS ) { #ifndef NO_USERINTERFACE fprintf( stderr, "krb_mk_req failed (%s)\n", krb_err_txt[err] ); #endif /* NO_USERINTERFACE */ ld->ld_errno = LDAP_INVALID_CREDENTIALS; return( NULL ); } if ( ( cred = malloc( ktxt.length )) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( NULL ); } *len = ktxt.length; memcpy( cred, ktxt.dat, ktxt.length ); return( cred ); }
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 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; }
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); }
char * /* R: allocated response string */ auth_krb4 ( /* PARAMETERS */ const char *login, /* I: plaintext authenticator */ const char *password, /* I: plaintext password */ const char *service, const char *realm_in /* END PARAMETERS */ ) { /* VARIABLES */ char aname[ANAME_SZ]; /* Kerberos principal */ const char *realm; /* Kerberos realm to authenticate in */ int rc; /* return code */ char tf_name[TF_NAME_LEN]; /* Ticket file name */ char *instance, *user_specified; KTEXT_ST ticket; AUTH_DAT kdata; /* END VARIABLES */ /* * Make sure we have a password. If this is NULL the call * to krb_get_pw_in_tkt below would try to prompt for * one interactively. */ if (password == NULL) { syslog(LOG_ERR, "auth_krb4: NULL password?"); return strdup("NO saslauthd internal error"); } if (krbtf_name(tf_name, sizeof(tf_name)) != 0) { syslog(LOG_ERR, "auth_krb4: could not generate ticket file name"); return strdup("NO saslauthd internal error"); } krb_set_tkt_string(tf_name); strncpy(aname, login, ANAME_SZ-1); aname[ANAME_SZ-1] = '\0'; instance = ""; if (config) { char keyname[1024]; snprintf(keyname, sizeof(keyname), "krb4_%s_instance", service); instance = cfile_getstring(config, keyname, ""); } user_specified = strchr(aname, '.'); if (user_specified) { if (instance && instance[0]) { /* sysadmin specified a (mandatory) instance */ if (strcmp(user_specified + 1, instance)) { return strdup("NO saslauthd principal name error"); } /* nuke instance from "aname"-- matches what's already in "instance" */ *user_specified = '\0'; } else { /* sysadmin has no preference, so we shift * instance name from "aname" to "instance" */ *user_specified = '\0'; instance = user_specified + 1; } } if(realm_in && *realm_in != '\0') { realm = realm_in; } else { realm = default_realm; } rc = krb_get_pw_in_tkt(aname, instance, realm, KRB_TICKET_GRANTING_TICKET, realm, 1, password); if (rc == INTK_BADPW || rc == KDC_PR_UNKNOWN) { return strdup("NO"); } else if (rc != KSUCCESS) { syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s", krb_get_err_text(rc)); return strdup("NO saslauthd internal error"); } /* if the TGT wasn't spoofed, it should entitle us to an rcmd ticket... */ rc = krb_mk_req(&ticket, verify_principal, myhostname, default_realm, 0); if (rc != KSUCCESS) { syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s", krb_get_err_text(rc)); dest_tkt(); return strdup("NO saslauthd internal error"); } /* .. and that ticket should match our secret host key */ rc = krb_rd_req(&ticket, verify_principal, myhostname, 0, &kdata, srvtabname); if (rc != RD_AP_OK) { syslog(LOG_ERR, "ERROR: auth_krb4: krb_rd_req:%s", krb_get_err_text(rc)); dest_tkt(); return strdup("NO saslauthd internal error"); } dest_tkt(); return strdup("OK"); }
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); }
/* * try krb4 authentication, * return 1 on success, 0 on failure, -1 if krb4 is not available */ int auth_krb4_password(Authctxt *authctxt, const char *password) { AUTH_DAT adata; KTEXT_ST tkt; struct hostent *hp; struct passwd *pw; char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ]; u_int32_t faddr; int r; if ((pw = authctxt->pw) == NULL) return (0); /* * Try Kerberos password authentication only for non-root * users and only if Kerberos is installed. */ if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { /* Set up our ticket file. */ if (!krb4_init(authctxt)) { log("Couldn't initialize Kerberos ticket file for %s!", pw->pw_name); goto failure; } /* Try to get TGT using our password. */ r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm, "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password); if (r != INTK_OK) { debug("Kerberos v4 password authentication for %s " "failed: %s", pw->pw_name, krb_err_txt[r]); goto failure; } /* Successful authentication. */ chown(tkt_string(), pw->pw_uid, pw->pw_gid); /* * Now that we have a TGT, try to get a local * "rcmd" ticket to ensure that we are not talking * to a bogus Kerberos server. */ gethostname(localhost, sizeof(localhost)); strlcpy(phost, (char *)krb_get_phost(localhost), sizeof(phost)); r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); if (r == KSUCCESS) { if ((hp = gethostbyname(localhost)) == NULL) { log("Couldn't get local host address!"); goto failure; } memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); /* Verify our "rcmd" ticket. */ r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, faddr, &adata, ""); if (r == RD_AP_UNDEC) { /* * Probably didn't have a srvtab on * localhost. Disallow login. */ log("Kerberos v4 TGT for %s unverifiable, " "no srvtab installed? krb_rd_req: %s", pw->pw_name, krb_err_txt[r]); goto failure; } else if (r != KSUCCESS) { log("Kerberos v4 %s ticket unverifiable: %s", KRB4_SERVICE_NAME, krb_err_txt[r]); goto failure; } } else if (r == KDC_PR_UNKNOWN) { /* * Disallow login if no rcmd service exists, and * log the error. */ log("Kerberos v4 TGT for %s unverifiable: %s; %s.%s " "not registered, or srvtab is wrong?", pw->pw_name, krb_err_txt[r], KRB4_SERVICE_NAME, phost); goto failure; } else { /* * TGT is bad, forget it. Possibly spoofed! */ debug("WARNING: Kerberos v4 TGT possibly spoofed " "for %s: %s", pw->pw_name, krb_err_txt[r]); goto failure; } /* Authentication succeeded. */ return (1); } else /* Logging in as root or no local Kerberos realm. */ debug("Unable to authenticate to Kerberos."); failure: krb4_cleanup_proc(authctxt); if (!options.kerberos_or_local_passwd) return (0); /* Fall back to ordinary passwd authentication. */ return (-1); }
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; }
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 }