static int pack_cred(CREDENTIALS *cred, unsigned char *buf) { unsigned char *p = buf; p += krb_put_nir(cred->service, cred->instance, cred->realm, p); memcpy(p, cred->session, 8); p += 8; *p++ = cred->lifetime; *p++ = cred->kvno; p += krb_put_int(cred->ticket_st.length, p, 4); memcpy(p, cred->ticket_st.dat, cred->ticket_st.length); p += cred->ticket_st.length; p += krb_put_int(cred->issue_date, p, 4); p += krb_put_nir(cred->pname, cred->pinst, NULL, p); return p - buf; }
int32_t krb_mk_priv(void *in, void *out, u_int32_t length, struct des_ks_struct *schedule, des_cblock *key, struct sockaddr_in *sender, struct sockaddr_in *receiver) { unsigned char *p = (unsigned char*)out; unsigned char *cipher; struct timeval tv; u_int32_t src_addr; u_int32_t len; p += krb_put_int(KRB_PROT_VERSION, p, 1, 1); p += krb_put_int(AUTH_MSG_PRIVATE, p, 1, 1); len = 4 + length + 1 + 4 + 4; len = (len + 7) & ~7; p += krb_put_int(len, p, 4, 4); cipher = p; p += krb_put_int(length, p, 4, 4); memcpy(p, in, length); p += length; krb_kdctimeofday(&tv); *p++ =tv.tv_usec / 5000; src_addr = sender->sin_addr.s_addr; p += krb_put_address(src_addr, p, 4); p += krb_put_int(lsb_time(tv.tv_sec, sender, receiver), p, 4, 4); memset(p, 0, 7); des_pcbc_encrypt((des_cblock *)cipher, (des_cblock *)cipher, len, schedule, key, DES_ENCRYPT); return (cipher - (unsigned char*)out) + len; }
static int build_request(KTEXT req, char *name, char *inst, char *realm, u_int32_t checksum) { struct timeval tv; unsigned char *p = req->dat; int tmp; size_t rem = sizeof(req->dat); tmp = krb_put_nir(name, inst, realm, p, rem); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; tmp = krb_put_int(checksum, p, rem, 4); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; /* Fill in the times on the request id */ krb_kdctimeofday(&tv); if (rem < 1) return KFAILURE; *p++ = tv.tv_usec / 5000; /* 5ms */ --rem; tmp = krb_put_int(tv.tv_sec, p, rem, 4); if (tmp < 0) return KFAILURE; p += tmp; rem -= tmp; /* Fill to a multiple of 8 bytes for DES */ req->length = ((p - req->dat + 7)/8) * 8; return 0; }
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 krb_put_address(u_int32_t addr, void *to, size_t rem) { return krb_put_int(ntohl(addr), to, rem, 4); }