static afs_int32 create_cipher(char *cipher, int *cipherLen, struct ktc_encryptionKey *sessionKey, char *sname, char *sinst, Date start, Date end, afs_int32 kvno, char *ticket, int ticketLen, struct ktc_encryptionKey *key) { char *answer; int slen; unsigned char life = time_to_life(start, end); int len; DES_key_schedule schedule; afs_int32 code; answer = cipher; len = sizeof(*sessionKey) + strlen(sname) + strlen(sinst) + strlen(lrealm) + 3 /*nulls */ + 3 + ticketLen + sizeof(Date); if (len > *cipherLen) return KAANSWERTOOLONG; if (ticketLen > 255) return KAANSWERTOOLONG; if (kvno > 255) return KAANSWERTOOLONG; memcpy(answer, sessionKey, sizeof(*sessionKey)); answer += sizeof(*sessionKey); putstr(sname); putstr(sinst); putstr(lrealm); *answer++ = life; *answer++ = (unsigned char)kvno; *answer++ = (unsigned char)ticketLen; memcpy(answer, ticket, ticketLen); answer += ticketLen; putint(start); if (krb_udp_debug) { printf("Printing ticket (%d) and date: ", ticketLen); ka_PrintBytes(ticket, ticketLen); ka_PrintBytes(answer - 4, 4); printf("\n"); } if ((code = DES_key_sched(ktc_to_cblock(key), &schedule))) printf("In KAAuthenticate: key_sched returned %d\n", code); DES_pcbc_encrypt(cipher, cipher, len, &schedule, ktc_to_cblockptr(key), ENCRYPT); *cipherLen = round_up_to_ebs(len); if (krb_udp_debug) { printf("Printing cipher (%d): ", *cipherLen); ka_PrintBytes(cipher, *cipherLen); printf("\n"); } return 0; }
int main(int argc, char *argv[]) { struct ktc_principal client; struct ktc_encryptionKey sessionkey; Date start, end; afs_int32 host; char key[8]; char ticket[MAXKTCTICKETLEN]; afs_int32 ticketLen; afs_int32 code; char bob[KA_TIMESTR_LEN]; whoami = argv[0]; initialize_RXK_error_table(); initialize_KA_error_table(); if (argc != 3) { printf("Usage is %s key ticket\n", whoami); exit(1); } if (ka_ReadBytes(argv[1], key, sizeof(key)) != 8) printf("Key must be 8 bytes long\n"); if (!des_check_key_parity(key) || des_is_weak_key(key)) { afs_com_err(whoami, KABADKEY, "server's key for decoding ticket is bad"); exit(1); } ticketLen = ka_ReadBytes(argv[2], ticket, sizeof(ticket)); printf("Ticket length is %d\n", ticketLen); code = tkt_DecodeTicket(ticket, ticketLen, key, client.name, client.instance, client.cell, &sessionkey, &host, &start, &end); if (code) { afs_com_err(whoami, code, "decoding ticket"); if (code = tkt_CheckTimes(start, end, time(0)) <= 0) afs_com_err(whoami, 0, "because of start or end times"); exit(1); } if (!des_check_key_parity(&sessionkey) || des_is_weak_key(&sessionkey)) { afs_com_err(whoami, KABADKEY, "checking ticket's session key"); exit(1); } ka_PrintUserID("Client is ", client.name, client.instance, 0); if (strlen(client.cell)) printf("@%s", client.cell); printf("\nSession key is "); ka_PrintBytes(&sessionkey, 8); ka_timestr(start, bob, KA_TIMESTR_LEN); printf("\nGood from %s", bob); ka_timestr(end, bob, KA_TIMESTR_LEN); printf(" till %s\n", bob); }
static void * SocketListener(void *unused) { fd_set rfds; struct timeval tv; struct packet packet; socklen_t fromLen; afs_int32 code; char hoststr[16]; printf("Starting to listen for UDP packets\n"); while (1) { FD_ZERO(&rfds); if (sock_kerb >= 0) FD_SET(sock_kerb, &rfds); if (sock_kerb5 >= 0) FD_SET(sock_kerb5, &rfds); tv.tv_sec = 100; tv.tv_usec = 0; /* write and exception fd_set's are null */ code = IOMGR_Select(32, &rfds, NULL, NULL, &tv); if (code == 0) { /* timeout */ /* printf ("Timeout\n"); */ continue; } else if (code < 0) { perror("calling IOMGR_Select"); break; } fromLen = sizeof(packet.from); if ((sock_kerb >= 0) && FD_ISSET(sock_kerb, &rfds)) { code = recvfrom(sock_kerb, packet.data, sizeof(packet.data), 0, (struct sockaddr *)&packet.from, &fromLen); if (code < 0) { if (errno == EAGAIN || errno == ECONNREFUSED) goto try_kerb5; perror("calling recvfrom"); break; } packet.len = code; if (krb_udp_debug) { printf("Kerb:udp: Got %d bytes from addr %s which are '", code, afs_inet_ntoa_r(packet.from.sin_addr.s_addr, hoststr)); ka_PrintBytes(packet.data, packet.len); printf("'\n"); } packet.name = packet.inst = packet.realm = ""; packet.time = 0; process_udp_request(sock_kerb, &packet); } try_kerb5: if ((sock_kerb5 >= 0) && FD_ISSET(sock_kerb5, &rfds)) { code = recvfrom(sock_kerb5, packet.data, sizeof(packet.data), 0, (struct sockaddr *)&packet.from, &fromLen); if (code < 0) { if (errno == EAGAIN || errno == ECONNREFUSED) continue; perror("calling recvfrom"); break; } packet.len = code; if (krb_udp_debug) { printf("Kerb5:udp: Got %d bytes from addr %s which are '", code, afs_inet_ntoa_r(packet.from.sin_addr.s_addr, hoststr)); ka_PrintBytes(packet.data, packet.len); printf("'\n"); } packet.name = packet.inst = packet.realm = ""; packet.time = 0; process_udp_request(sock_kerb5, &packet); } } if (sock_kerb >= 0) { closesocket(sock_kerb); sock_kerb = -1; } if (sock_kerb5 >= 0) { closesocket(sock_kerb5); sock_kerb5 = -1; } printf("UDP SocketListener exiting due to error\n"); return NULL; }
afs_int32 UDP_Authenticate(int ksoc, struct sockaddr_in *client, char *name, char *inst, Date startTime, Date endTime, char *sname, char *sinst) { struct ubik_trans *tt; afs_int32 to; /* offset of block */ struct kaentry tentry; afs_int32 tgskvno; /* key version of service key */ struct ktc_encryptionKey tgskey; /* service key for encrypting ticket */ int tgt; Date now = time(0); afs_int32 code; char ticket[MAXKTCTICKETLEN]; /* our copy of the ticket */ int ticketLen; struct ktc_encryptionKey sessionKey; /* we have to invent a session key */ char cipher[2 * MAXKTCTICKETLEN]; /* put encrypted part of answer here */ int cipherLen; struct packet ans; COUNT_REQ(UAuthenticate); if (!name_instance_legal(name, inst)) return KERB_ERR_NAME_EXP; /* KABADNAME */ if ((code = InitAuthServ(&tt, LOCKREAD, this_op))) return code; code = FindBlock(tt, name, inst, &to, &tentry); if (code) goto abort; if (to) { /* if user exists check other stuff */ afs_int32 sto; struct kaentry sentry; save_principal(udpAuthPrincipal, name, inst, 0); tgt = ((strcmp(sname, KA_TGS_NAME) == 0) && (strcmp(sinst, lrealm) == 0)); if ((ntohl(tentry.user_expiration) < now) || (tgt && (ntohl(tentry.flags) & KAFNOTGS))) { code = KERB_ERR_NAME_EXP; /* KABADUSER */ goto abort; } code = FindBlock(tt, KA_TGS_NAME, lrealm, &sto, &sentry); if (code) goto abort; if (sto == 0) { code = KANOENT; goto abort; } if ((ntohl(sentry.user_expiration) < now)) { code = KERB_ERR_NAME_EXP; /* XXX Could use another error code XXX */ goto abort; } if (abs(startTime - now) > KTC_TIME_UNCERTAINTY) { code = KERB_ERR_SERVICE_EXP; /* was KABADREQUEST */ goto abort; } if (tentry.misc_auth_bytes) { unsigned char misc_auth_bytes[4]; afs_uint32 temp; /* unsigned for safety */ afs_uint32 pwexpires; memcpy(&temp, tentry.misc_auth_bytes, sizeof(afs_uint32)); temp = ntohl(temp); unpack_long(temp, misc_auth_bytes); pwexpires = misc_auth_bytes[0]; if (pwexpires) { pwexpires = ntohl(tentry.change_password_time) + 24 * 60 * 60 * pwexpires; if (pwexpires < now) { code = KERB_ERR_AUTH_EXP; /* was KAPWEXPIRED */ goto abort; } } } /* make the ticket */ code = DES_new_random_key(ktc_to_cblock(&sessionKey)); if (code) { code = KERB_ERR_NULL_KEY; /* was KANOKEYS */ goto abort; } endTime = umin(endTime, startTime + ntohl(tentry.max_ticket_lifetime)); if ((code = ka_LookupKey(tt, sname, sinst, &tgskvno, &tgskey)) || (code = tkt_MakeTicket(ticket, &ticketLen, &tgskey, name, inst, lrealm, startTime, endTime, &sessionKey, htonl(client->sin_addr.s_addr), sname, sinst))) goto abort; cipherLen = sizeof(cipher); code = create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, startTime, endTime, tgskvno, ticket, ticketLen, &tentry.key); if (code) goto abort; } else { /* no such user */ cipherLen = 0; tentry.key_version = 0; } code = ubik_EndTrans(tt); if (code) goto fail; code = create_reply(&ans, name, inst, startTime, endTime, ntohl(tentry.key_version), cipher, cipherLen); if (code) goto fail; if (krb_udp_debug) { printf("Sending %d bytes ending in: ", ans.len); ka_PrintBytes(ans.data + ans.len - 8, 8); printf("\n"); } code = sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)client, sizeof(*client)); if (code != ans.len) { perror("calling sendto"); code = -1; goto fail; } KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr, LOG_AUTHENTICATE); if (cipherLen != 0) { KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr, LOG_TGTREQUEST); } osi_audit(UDPAuthenticateEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_END); return 0; abort: COUNT_ABO; ubik_AbortTrans(tt); fail: osi_audit(UDPAuthenticateEvent, code, AUD_STR, name, AUD_STR, inst, AUD_END); return code; }
void PrintEntry(afs_int32 index, struct kaentry *entry) { int i; char Time[100]; struct tm *tm_p; time_t tt; time_t modification_time = entry->modification_time; time_t change_password_time = entry->change_password_time; time_t max_ticket_lifetime = entry->max_ticket_lifetime; printf("\n"); i = (index - sizeof(struct kaheader)) / sizeof(struct kaentry); printf("Entry %5d (%u):\n", i, index); if (entry->flags & KAFNORMAL) { printf(" Name = %s", entry->userID.name); if (strlen(entry->userID.instance) > 0) { printf(".%s", entry->userID.instance); } printf("\n"); } printf(" flags = "); if (entry->flags & KAFNORMAL) printf("NORMAL "); if (entry->flags & KAFADMIN) printf("ADMIN "); if (entry->flags & KAFNOTGS) printf("NOTGS "); if (entry->flags & KAFNOSEAL) printf("NOSEAL "); if (entry->flags & KAFNOCPW) printf("NOCPW "); if (entry->flags & KAFNEWASSOC) printf("CR-ASSOC "); if (entry->flags & KAFFREE) printf("FREE "); if (entry->flags & KAFOLDKEYS) printf("OLDKEYS "); if (entry->flags & KAFSPECIAL) printf("SPECIAL "); if (entry->flags & KAFASSOCROOT) printf("ROOT-ASSOC "); if (entry->flags & KAFASSOC) printf("AN-ASSOC "); printf("\n"); printf(" Next = %u\n", entry->next); if (entry->flags & KAFFREE) return; if (entry->flags & KAFOLDKEYS) return; tt = entry->user_expiration; tm_p = localtime(&tt); if (tm_p) strftime(Time, 100, "%m/%d/%Y %H:%M", tm_p); printf(" User Expiration = %s\n", (entry->user_expiration == 0xffffffff) ? "never" : Time); printf(" Password Expiration = %u days %s\n", entry->misc_auth_bytes[EXPIRES], (entry->misc_auth_bytes[EXPIRES] ? "" : "(never)")); printf(" Password Attempts before lock = "); if (!entry->misc_auth_bytes[ATTEMPTS]) printf("unlimited\n"); else printf("%d\n", entry->misc_auth_bytes[ATTEMPTS]); printf(" Password lockout time = "); if (!entry->misc_auth_bytes[LOCKTIME]) printf("unlimited\n"); else printf("%.1f min\n", (entry->misc_auth_bytes[LOCKTIME] * 8.5)); printf(" Is entry locked = %s\n", (entry->misc_auth_bytes[REUSEFLAGS] == KA_ISLOCKED) ? "yes" : "no"); printf(" Permit password reuse = %s\n", (!entry->pwsums[0] && !entry->pwsums[1]) ? "yes" : "no"); printf(" Mod Time = %u: %s", entry->modification_time, ctime(&modification_time)); printf(" Mod ID = %u\n", entry->modification_id); printf(" Change Password Time = %u: %s", entry->change_password_time, ctime(&change_password_time)); printf(" Ticket lifetime = %u: %s", entry->max_ticket_lifetime, ctime(&max_ticket_lifetime)); printf(" Key Version = %d\n", entry->key_version); printf(" Key = "); ka_PrintBytes((char *)&entry->key, sizeof(entry->key)); printf("\n"); /* What about asServer structs and such and misc_ath_bytes */ }