Beispiel #1
0
int
rxkad_GetChallenge(struct rx_securityClass *aobj, struct rx_connection *aconn,
		   struct rx_packet *apacket)
{
    struct rxkad_sconn *sconn;
    char *challenge;
    int challengeSize;
    struct rxkad_v2Challenge c_v2;	/* version 2 */
    struct rxkad_oldChallenge c_old;	/* old style */

    sconn = (struct rxkad_sconn *)aconn->securityData;
    if (rx_IsUsingPktCksum(aconn))
	sconn->cksumSeen = 1;

    if (sconn->cksumSeen) {
	memset(&c_v2, 0, sizeof(c_v2));
	c_v2.version = htonl(RXKAD_CHALLENGE_PROTOCOL_VERSION);
	c_v2.challengeID = htonl(sconn->challengeID);
	c_v2.level = htonl((afs_int32) sconn->level);
	c_v2.spare = 0;
	challenge = (char *)&c_v2;
	challengeSize = sizeof(c_v2);
    } else {
	memset(&c_old, 0, sizeof(c_old));
	c_old.challengeID = htonl(sconn->challengeID);
	c_old.level = htonl((afs_int32) sconn->level);
	challenge = (char *)&c_old;
	challengeSize = sizeof(c_old);
    }
    if (rx_MyMaxSendSize < challengeSize)
	return RXKADPACKETSHORT;	/* not enough space */

    rx_packetwrite(apacket, 0, challengeSize, challenge);
    rx_SetDataSize(apacket, challengeSize);
    sconn->tried = 1;
    INC_RXKAD_STATS(challengesSent);
    return 0;
}
Beispiel #2
0
int
rxkad_GetResponse(struct rx_securityClass *aobj, struct rx_connection *aconn,
		  struct rx_packet *apacket)
{
    struct rxkad_cprivate *tcp;
    char *tp;
    int v2;			/* whether server is old style or v2 */
    afs_int32 challengeID;
    rxkad_level level;
    char *response;
    int responseSize, missing;
    struct rxkad_v2ChallengeResponse r_v2;
    struct rxkad_oldChallengeResponse r_old;

    tcp = (struct rxkad_cprivate *)aobj->privateData;

    if (!(tcp->type & rxkad_client))
	return RXKADINCONSISTENCY;

    v2 = (rx_Contiguous(apacket) > sizeof(struct rxkad_oldChallenge));
    tp = rx_DataOf(apacket);

    if (v2) {			/* v2 challenge */
	struct rxkad_v2Challenge *c_v2;
	if (rx_GetDataSize(apacket) < sizeof(struct rxkad_v2Challenge))
	    return RXKADPACKETSHORT;
	c_v2 = (struct rxkad_v2Challenge *)tp;
	challengeID = ntohl(c_v2->challengeID);
	level = ntohl(c_v2->level);
    } else {			/* old format challenge */
	struct rxkad_oldChallenge *c_old;
	if (rx_GetDataSize(apacket) < sizeof(struct rxkad_oldChallenge))
	    return RXKADPACKETSHORT;
	c_old = (struct rxkad_oldChallenge *)tp;
	challengeID = ntohl(c_old->challengeID);
	level = ntohl(c_old->level);
    }

    if (level > tcp->level)
	return RXKADLEVELFAIL;
    INC_RXKAD_STATS(challenges[rxkad_LevelIndex(tcp->level)]);
    if (v2) {
	int i;
	afs_uint32 xor[2];
	memset((void *)&r_v2, 0, sizeof(r_v2));
	r_v2.version = htonl(RXKAD_CHALLENGE_PROTOCOL_VERSION);
	r_v2.spare = 0;
	(void)rxkad_SetupEndpoint(aconn, &r_v2.encrypted.endpoint);
	(void)rxi_GetCallNumberVector(aconn, r_v2.encrypted.callNumbers);
	for (i = 0; i < RX_MAXCALLS; i++) {
	    if (r_v2.encrypted.callNumbers[i] < 0)
		return RXKADINCONSISTENCY;
	    r_v2.encrypted.callNumbers[i] =
		htonl(r_v2.encrypted.callNumbers[i]);
	}
	r_v2.encrypted.incChallengeID = htonl(challengeID + 1);
	r_v2.encrypted.level = htonl((afs_int32) tcp->level);
	r_v2.kvno = htonl(tcp->kvno);
	r_v2.ticketLen = htonl(tcp->ticketLen);
	r_v2.encrypted.endpoint.cksum = rxkad_CksumChallengeResponse(&r_v2);
	memcpy((void *)xor, (void *)tcp->ivec, 2 * sizeof(afs_int32));
	fc_cbc_encrypt(&r_v2.encrypted, &r_v2.encrypted,
		       sizeof(r_v2.encrypted), tcp->keysched, xor, ENCRYPT);
	response = (char *)&r_v2;
	responseSize = sizeof(r_v2);
    } else {
	memset((void *)&r_old, 0, sizeof(r_old));
	r_old.encrypted.incChallengeID = htonl(challengeID + 1);
	r_old.encrypted.level = htonl((afs_int32) tcp->level);
	r_old.kvno = htonl(tcp->kvno);
	r_old.ticketLen = htonl(tcp->ticketLen);
	fc_ecb_encrypt(&r_old.encrypted, &r_old.encrypted, tcp->keysched,
		       ENCRYPT);
	response = (char *)&r_old;
	responseSize = sizeof(r_old);
    }

    if (RX_MAX_PACKET_DATA_SIZE < responseSize + tcp->ticketLen)
	return RXKADPACKETSHORT;	/* not enough space */

    rx_computelen(apacket, missing);
    missing = responseSize + tcp->ticketLen - missing;
    if (missing > 0)
	if (rxi_AllocDataBuf(apacket, missing, RX_PACKET_CLASS_SEND) > 0)
	    return RXKADPACKETSHORT;	/* not enough space */

    /* copy response and ticket into packet */
    rx_packetwrite(apacket, 0, responseSize, response);
    rx_packetwrite(apacket, responseSize, tcp->ticketLen, tcp->ticket);

    rx_SetDataSize(apacket, responseSize + tcp->ticketLen);
    return 0;
}