static int kerberosv4_encode(void *context, const struct iovec *invec, unsigned numiov, const char **output, unsigned *outputlen) { int len, ret; context_t *text = (context_t *)context; struct buffer_info *inblob, bufinfo; if(numiov > 1) { ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf); if(ret != SASL_OK) return ret; inblob = text->enc_in_buf; } else { bufinfo.data = invec[0].iov_base; bufinfo.curlen = invec[0].iov_len; inblob = &bufinfo; } ret = _plug_buf_alloc(text->utils, &(text->encode_buf), &text->encode_buf_len, inblob->curlen+40); if(ret != SASL_OK) return ret; KRB_LOCK_MUTEX(text->utils); if (text->sec_type == KRB_SEC_ENCRYPTION) { /* Type incompatibility on 4th arg probably means you're building against krb4 in MIT krb5, but got the OpenSSL headers in your way. You need to not use openssl/des.h with MIT kerberos. */ len=krb_mk_priv(inblob->data, (text->encode_buf+4), inblob->curlen, text->init_keysched, &text->session, &text->ip_local, &text->ip_remote); } else if (text->sec_type == KRB_SEC_INTEGRITY) { len=krb_mk_safe(inblob->data, (text->encode_buf+4), inblob->curlen, &text->session, &text->ip_local, &text->ip_remote); } else { len = -1; } KRB_UNLOCK_MUTEX(text->utils); /* returns -1 on error */ if (len==-1) return SASL_FAIL; /* now copy in the len of the buffer in network byte order */ *outputlen=len+4; len=htonl(len); memcpy(text->encode_buf, &len, 4); /* Setup the const pointer */ *output = text->encode_buf; return SASL_OK; }
static int krb4_encode(void *app_data, void *from, int length, int level, void **to) { struct krb4_data *d = app_data; *to = malloc(length + 31); if(level == prot_safe) return krb_mk_safe(from, *to, length, &d->key, (struct sockaddr_in *)LOCAL_ADDR, (struct sockaddr_in *)REMOTE_ADDR); else if(level == prot_private) return krb_mk_priv(from, *to, length, d->schedule, &d->key, (struct sockaddr_in *)LOCAL_ADDR, (struct sockaddr_in *)REMOTE_ADDR); else return -1; }
static int krb4_encode(void *app_data, const void *from, int length, int level, void **to, struct connectdata *conn) { struct krb4_data *d = app_data; *to = malloc(length + 31); if(!*to) return -1; if(level == prot_safe) /* NOTE that the void* cast is safe, krb_mk_safe/priv don't modify the * input buffer */ return krb_mk_safe((void*)from, *to, length, &d->key, (struct sockaddr_in *)LOCAL_ADDR, (struct sockaddr_in *)REMOTE_ADDR); else if(level == prot_private) return krb_mk_priv((void*)from, *to, length, d->schedule, &d->key, (struct sockaddr_in *)LOCAL_ADDR, (struct sockaddr_in *)REMOTE_ADDR); else return -1; }
int auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply) { AUTH_DAT adat = {0}; Key_schedule schedule; struct sockaddr_in local, foreign; char instance[INST_SZ]; socklen_t slen; u_int cksum; int r, s; s = packet_get_connection_in(); slen = sizeof(local); memset(&local, 0, sizeof(local)); if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) debug("getsockname failed: %.100s", strerror(errno)); slen = sizeof(foreign); memset(&foreign, 0, sizeof(foreign)); if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); fatal_cleanup(); } instance[0] = '*'; instance[1] = 0; /* Get the encrypted request, challenge, and session key. */ if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]); return (0); } des_key_sched((des_cblock *) adat.session, schedule); *client = xmalloc(MAX_K_NAME_SZ); (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, *adat.pinst ? "." : "", adat.pinst, adat.prealm); /* Check ~/.klogin authorization now. */ if (kuserok(&adat, authctxt->user) != KSUCCESS) { log("Kerberos v4 .klogin authorization failed for %s to " "account %s", *client, authctxt->user); xfree(*client); *client = NULL; return (0); } /* Increment the checksum, and return it encrypted with the session key. */ cksum = adat.checksum + 1; cksum = htonl(cksum); /* If we can't successfully encrypt the checksum, we send back an empty message, admitting our failure. */ if ((r = krb_mk_priv((u_char *) & cksum, reply->dat, sizeof(cksum) + 1, schedule, &adat.session, &local, &foreign)) < 0) { debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]); reply->dat[0] = 0; reply->length = 0; } else reply->length = r; /* Clear session key. */ memset(&adat.session, 0, sizeof(&adat.session)); return (1); }