Example #1
0
static afs_int32
kvno_admin_key(void *rock, afs_int32 kvno, struct ktc_encryptionKey *key)
{
    return ka_LookupKvno(0, KA_ADMIN_NAME, KA_ADMIN_INST, kvno, key);

    /* we would like to start a Ubik transaction to fill the cache if that
     * fails, but may deadlock as Rx is now organized. */
}
Example #2
0
afs_int32
ka_FillKeyCache(struct ubik_trans *tt)
{
    int nfound;
    afs_int32 ko;
    int code;
    int i;
    struct ktc_encryptionKey k;
    struct kaOldKeys okeys;
    struct kaentry tentry;

    /* this is a little marginal, but... */
    if (keyCacheVersion == ntohl(cheader.specialKeysVersion))
	return 0;

    nfound = 0;
    for (ko = ntohl(cheader.kvnoPtr); ko; ko = ntohl(okeys.next)) {
	code = karead(tt, ko, (char *)&okeys, sizeof(okeys));
	if (code)
	    return KAIO;
	/* get name & instance */
	code =
	    karead(tt, ntohl(okeys.entry), (char *)&tentry, sizeof(tentry));
	if (code)
	    return KAIO;

	/* get all the old keys in this block */
	for (i = 0; i < NOLDKEYS; i++)
	    if (okeys.keys[i].superseded) {
		code =
		    ka_LookupKvno(tt, tentry.userID.name,
				  tentry.userID.instance,
				  ntohl(okeys.keys[i].version), &k);
		if (code)
		    return code;
	    }
    }
    if (++nfound > maxCachedKeys)
	return KADATABASEINCONSISTENT;
    return 0;
}
Example #3
0
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;
}