From: Chaskiel Grundman Date: Sat, 9 Feb 2013 17:01:37 +0000 (-0500) Subject: Add rxkad server hook function to decrypt more types of tokens X-Git-Tag: debian/1.6.1-3+deb7u1~16 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=0cbd20b45120e5e38aebe7b91cf2b428eb312bd9;p=packages%2Fo%2Fopenafs.git Add rxkad server hook function to decrypt more types of tokens Allow tokens to be encrypted with algorithms other than DES. The security object owner must provide an implementation by calling rxkad_SetAltDecryptProc. Make sure plainsiz is initialized before calling the alternate decrypt proc. --- diff --git a/src/rxkad/private_data.h b/src/rxkad/private_data.h index a26c603ff..1ad12cccd 100644 --- a/src/rxkad/private_data.h +++ b/src/rxkad/private_data.h @@ -82,6 +82,7 @@ struct rxkad_sprivate { char *, afs_int32); /* func called with new client name */ afs_uint32 flags; /* configuration flags */ + rxkad_alt_decrypt_func alt_decrypt; }; /* private data in server-side connection */ diff --git a/src/rxkad/rxkad.p.h b/src/rxkad/rxkad.p.h index 91d1f5208..45feaeb6c 100644 --- a/src/rxkad/rxkad.p.h +++ b/src/rxkad/rxkad.p.h @@ -93,6 +93,11 @@ typedef signed char rxkad_level; extern int rxkad_EpochWasSet; /* TRUE => we called rx_SetEpoch */ +/* An alternate decryption function for rxkad. Using the given kvno and + * enctype, decrypt the input data + length to output data + length. */ +typedef int (*rxkad_alt_decrypt_func)(int, int, void *, size_t, void *, + size_t *); + #include #endif /* OPENAFS_RXKAD_RXKAD_H */ diff --git a/src/rxkad/rxkad_prototypes.h b/src/rxkad/rxkad_prototypes.h index 1bd30a1bb..ddee6d542 100644 --- a/src/rxkad/rxkad_prototypes.h +++ b/src/rxkad/rxkad_prototypes.h @@ -130,6 +130,8 @@ extern afs_int32 rxkad_SetConfiguration(struct rx_securityClass *aobj, struct rx_connection *aconn, rx_securityConfigVariables atype, void * avalue, void **aresult); +extern int rxkad_SetAltDecryptProc(struct rx_securityClass *aobj, + rxkad_alt_decrypt_func alt_decrypt); /* ticket.c */ extern int tkt_DecodeTicket(char *asecret, afs_int32 ticketLen, @@ -159,7 +161,8 @@ extern int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len, char *get_key_rock, int serv_kvno, char *name, char *inst, char *cell, struct ktc_encryptionKey *session_key, afs_int32 * host, afs_uint32 * start, - afs_uint32 * end, afs_int32 disableDotCheck); + afs_uint32 * end, afs_int32 disableDotCheck, + rxkad_alt_decrypt_func alt_decrypt); #if !defined(NO_DES_H_INCLUDE) static_inline unsigned char * diff --git a/src/rxkad/rxkad_server.c b/src/rxkad/rxkad_server.c index 25467d3cf..63633d057 100644 --- a/src/rxkad/rxkad_server.c +++ b/src/rxkad/rxkad_server.c @@ -336,7 +336,8 @@ rxkad_CheckResponse(struct rx_securityClass *aobj, tkt_DecodeTicket5(tix, tlen, tsp->get_key, tsp->get_key_rock, kvno, client.name, client.instance, client.cell, &sessionkey, &host, &start, &end, - tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); + tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK, + tsp->alt_decrypt); if (code) return code; } @@ -484,3 +485,13 @@ afs_int32 rxkad_SetConfiguration(struct rx_securityClass *aobj, } return 0; } + +int rxkad_SetAltDecryptProc(struct rx_securityClass *aobj, + rxkad_alt_decrypt_func alt_decrypt) +{ + struct rxkad_sprivate *private = + (struct rxkad_sprivate *)aobj->privateData; + + private->alt_decrypt = alt_decrypt; + return 0; +} diff --git a/src/rxkad/ticket5.c b/src/rxkad/ticket5.c index 36a17379b..51d33d2c3 100644 --- a/src/rxkad/ticket5.c +++ b/src/rxkad/ticket5.c @@ -185,7 +185,8 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len, int (*get_key) (void *, int, struct ktc_encryptionKey *), char *get_key_rock, int serv_kvno, char *name, char *inst, char *cell, struct ktc_encryptionKey *session_key, afs_int32 * host, - afs_uint32 * start, afs_uint32 * end, afs_int32 disableCheckdot) + afs_uint32 * start, afs_uint32 * end, afs_int32 disableCheckdot, + rxkad_alt_decrypt_func alt_decrypt) { char plain[MAXKRB5TICKETLEN]; struct ktc_encryptionKey serv_key; @@ -226,33 +227,41 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len, v5_serv_kvno = *t5.enc_part.kvno; } - /* Check that the key type really fit into 8 bytes */ + /* check ticket */ + if (t5.enc_part.cipher.length > sizeof(plain)) + goto bad_ticket; switch (t5.enc_part.etype) { case ETYPE_DES_CBC_CRC: case ETYPE_DES_CBC_MD4: case ETYPE_DES_CBC_MD5: + /* Check that the key type really fit into 8 bytes */ + if (t5.enc_part.cipher.length % 8 != 0) + goto bad_ticket; + + code = (*get_key) (get_key_rock, v5_serv_kvno, &serv_key); + if (code) + goto unknown_key; + + /* Decrypt data here, save in plain, assume it will shrink */ + code = + krb5_des_decrypt(&serv_key, t5.enc_part.etype, + t5.enc_part.cipher.data, + t5.enc_part.cipher.length, plain, &plainsiz); + if (code != 0) + goto bad_ticket; break; default: - goto unknown_key; + if (alt_decrypt != NULL) { + plainsiz = sizeof(plain); + code = alt_decrypt(v5_serv_kvno, t5.enc_part.etype, + t5.enc_part.cipher.data, + t5.enc_part.cipher.length, plain, &plainsiz); + if (code != 0) + goto cleanup; + } else + goto unknown_key; } - /* check ticket */ - if (t5.enc_part.cipher.length > sizeof(plain) - || t5.enc_part.cipher.length % 8 != 0) - goto bad_ticket; - - code = (*get_key) (get_key_rock, v5_serv_kvno, &serv_key); - if (code) - goto unknown_key; - - /* Decrypt data here, save in plain, assume it will shrink */ - code = - krb5_des_decrypt(&serv_key, t5.enc_part.etype, - t5.enc_part.cipher.data, t5.enc_part.cipher.length, - plain, &plainsiz); - if (code != 0) - goto bad_ticket; - /* Decode ticket */ code = decode_EncTicketPart((unsigned char *)plain, plainsiz, &decr_part, &siz); if (code != 0)