static long GetTicket(long *versionP, struct ktc_encryptionKey *session, int *ticketLenP, char *ticket, char *cell) { long code; /* create random session key, using key for seed to good random */ des_init_random_number_generator(ktc_to_cblock(&serviceKey)); code = des_random_key(ktc_to_cblock(session)); if (code) return code; /* now create the actual ticket */ *ticketLenP = 0; code = tkt_MakeTicket(ticket, ticketLenP, &serviceKey, RXKST_CLIENT_NAME, RXKST_CLIENT_INST, cell, /*start,end */ 0, 0xffffffff, session, /*host */ 0, RXKST_SERVER_NAME, RXKST_SERVER_NAME); /* parms were buffer, ticketlen, key to seal ticket with, principal name, * instance and cell, start time, end time, session key to seal in ticket, * inet host, server name and server instance */ if (code) return code; *versionP = serviceKeyVersion; return 0; }
static afs_int32 GenericAuth(struct afsconf_dir *adir, struct rx_securityClass **astr, afs_int32 *aindex, rxkad_level enclevel) { char tbuffer[256]; struct ktc_encryptionKey key, session; struct rx_securityClass *tclass; afs_int32 kvno; afs_int32 ticketLen; register afs_int32 code; /* first, find the right key and kvno to use */ code = afsconf_GetLatestKey(adir, &kvno, &key); if (code) { return QuickAuth(astr, aindex); } /* next create random session key, using key for seed to good random */ des_init_random_number_generator(ktc_to_cblock(&key)); code = des_random_key(ktc_to_cblock(&session)); if (code) { return QuickAuth(astr, aindex); } /* now create the actual ticket */ ticketLen = sizeof(tbuffer); memset(tbuffer, '\0', sizeof(tbuffer)); code = tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0, 0xffffffff, &session, 0, "afs", ""); /* parms were buffer, ticketlen, key to seal ticket with, principal * name, instance and cell, start time, end time, session key to seal * in ticket, inet host, server name and server instance */ if (code) { return QuickAuth(astr, aindex); } /* Next, we have ticket, kvno and session key, authenticate the connection. * We use a magic # instead of a constant because of basic compilation * order when compiling the system from scratch (rx/rxkad.h isn't installed * yet). */ tclass = (struct rx_securityClass *) rxkad_NewClientSecurityObject(enclevel, &session, kvno, ticketLen, tbuffer); *astr = tclass; *aindex = RX_SECIDX_KAD; return 0; }
static int _GetLocalSecurityObject(struct afscp_cell *cell, char *aname, char *ainst) { int code = 0; char tbuffer[256]; struct ktc_encryptionKey key, session; struct rx_securityClass *tc; afs_int32 kvno; afs_int32 ticketLen; rxkad_level lev; struct afsconf_dir *tdir; tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!tdir) { code = AFSCONF_FAILURE; goto done; } code = afsconf_GetLatestKey(tdir, &kvno, &key); if (code) { goto done; } DES_init_random_number_generator((DES_cblock *)&key); code = DES_new_random_key((DES_cblock *)&session); if (code) { goto done; } ticketLen = sizeof(tbuffer); memset(tbuffer, 0, sizeof(tbuffer)); code = tkt_MakeTicket(tbuffer, &ticketLen, &key, aname, ainst, "", 0, 0xffffffff, &session, 0, "afs", ""); if (code) { goto done; } if (insecure) { lev = rxkad_clear; } else { lev = rxkad_crypt; } tc = (struct rx_securityClass *) rxkad_NewClientSecurityObject(lev, &session, kvno, ticketLen, tbuffer); if (!tc) { code = RXKADBADKEY; goto done; } cell->security = tc; cell->scindex = 2; done: if (tdir) { afsconf_Close(tdir); } return code; }
afs_int32 UDP_GetTicket(int ksoc, struct packet *pkt, afs_int32 kvno, char *authDomain, char *ticket, int ticketLen, char *auth, int authLen) { afs_int32 code; struct ktc_encryptionKey tgskey; char name[MAXKTCNAMELEN]; char inst[MAXKTCNAMELEN]; char cell[MAXKTCREALMLEN]; struct ktc_encryptionKey authSessionKey; afs_int32 host; Date start; Date authEnd; Date now = time(0); int celllen; int import; char *packet; int slen; int byteOrder = pkt->byteOrder; char sname[MAXKTCNAMELEN]; char sinst[MAXKTCNAMELEN]; afs_int32 time_ws; unsigned char life; struct ubik_trans *tt; afs_int32 to; struct kaentry caller; struct kaentry server; Date reqEnd; struct ktc_encryptionKey sessionKey; int newTicketLen; char newTicket[MAXKTCTICKETLEN]; char cipher[2 * MAXKTCTICKETLEN]; /* put encrypted part of answer here */ int cipherLen; struct packet ans; COUNT_REQ(UGetTicket); if ((code = InitAuthServ(&tt, LOCKREAD, this_op))) goto fail; code = ka_LookupKvno(tt, KA_TGS_NAME, ((strlen(authDomain) > 0) ? authDomain : lrealm), kvno, &tgskey); if (code) goto abort; code = tkt_DecodeTicket(ticket, ticketLen, &tgskey, name, inst, cell, &authSessionKey, &host, &start, &authEnd); pkt->name = name; pkt->inst = inst; pkt->realm = cell; if (code) { code = KERB_ERR_AUTH_EXP; /* was KANOAUTH */ goto abort; } save_principal(udptgsPrincipal, name, inst, cell); code = tkt_CheckTimes(start, authEnd, now); if (code <= 0) { if (code == -1) { code = KERB_ERR_SERVICE_EXP; /* was RXKADEXPIRED */ goto abort; } code = KERB_ERR_AUTH_EXP; /* was KANOAUTH */ goto abort; } celllen = strlen(cell); import = 0; if ((strlen(authDomain) > 0) && (strcmp(authDomain, lrealm) != 0)) import = 1; if (import && (celllen == 0)) { code = KERB_ERR_PKT_VER; /* was KABADTICKET */ goto abort; } if (celllen == 0) { strncpy(cell, lrealm, MAXKTCREALMLEN - 1); cell[MAXKTCREALMLEN - 1] = 0; }; if (!krb4_cross && strcmp(lrealm, cell) != 0) { code = KERB_ERR_PRINCIPAL_UNKNOWN; goto abort; } if (krb_udp_debug) { printf("UGetTicket: got ticket from '%s'.'%s'@'%s'\n", name, inst, cell); } code = check_auth(pkt, auth, authLen, &authSessionKey, name, inst, cell); if (code) goto abort; /* authenticator and all is OK so read actual request */ packet = pkt->rest; getint(time_ws); life = *(unsigned char *)packet++; getstr(sname); getstr(sinst); start = now; reqEnd = life_to_time(start, life); if (krb_udp_debug) { printf("UGetTicket: request for server '%s'.'%s'\n", sname, sinst); } save_principal(udptgsServerPrincipal, sname, sinst, 0); if (import) { strcpy(caller.userID.name, name); strcpy(caller.userID.instance, inst); caller.max_ticket_lifetime = htonl(MAXKTCTICKETLIFETIME); } else { code = FindBlock(tt, name, inst, &to, &caller); if (code) goto abort; if (to == 0) { ka_PrintUserID("GetTicket: User ", name, inst, " unknown.\n"); code = KERB_ERR_PRINCIPAL_UNKNOWN; /* KANOENT */ goto abort; } if (ntohl(caller.flags) & KAFNOTGS) { code = KERB_ERR_AUTH_EXP; /* was KABADUSER */ goto abort; } } code = FindBlock(tt, sname, sinst, &to, &server); /* get server's entry */ if (code) goto abort; if (to == 0) { /* entry not found */ ka_PrintUserID("GetTicket: Server ", sname, sinst, " unknown.\n"); code = KERB_ERR_PRINCIPAL_UNKNOWN; /* KANOENT */ goto abort; } code = ubik_EndTrans(tt); if (code) goto fail; if (ntohl(server.flags) & KAFNOSEAL) return KABADSERVER; code = DES_new_random_key(ktc_to_cblock(&sessionKey)); if (code) { code = KERB_ERR_NULL_KEY; /* was KANOKEYS */ goto fail; } reqEnd = umin(umin(reqEnd, authEnd), umin(start + ntohl(caller.max_ticket_lifetime), start + ntohl(server.max_ticket_lifetime))); code = tkt_MakeTicket(newTicket, &newTicketLen, &server.key, caller.userID.name, caller.userID.instance, cell, start, reqEnd, &sessionKey, htonl(pkt->from.sin_addr.s_addr), server.userID.name, server.userID.instance); if (code) goto fail; cipherLen = sizeof(cipher); code = create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, start, reqEnd, ntohl(server.key_version), newTicket, newTicketLen, &authSessionKey); if (code) goto fail; code = create_reply(&ans, name, inst, start, reqEnd, 0, cipher, cipherLen); if (code) goto fail; code = sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)&pkt->from, sizeof(pkt->from)); if (code != ans.len) { perror("calling sendto"); code = -1; goto fail; } if (cipherLen != 0) { KALOG(name, inst, sname, sinst, NULL, host, LOG_GETTICKET); } osi_audit(UDPGetTicketEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_STR, cell, AUD_STR, sname, AUD_STR, sinst, AUD_END); return 0; abort: ubik_AbortTrans(tt); fail: osi_audit(UDPGetTicketEvent, code, AUD_STR, name, AUD_STR, inst, AUD_STR, NULL, AUD_STR, NULL, AUD_STR, NULL, AUD_END); return code; }
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; }