From 1827e342c54b79566e6270f764e14e01990633ab Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Sat, 2 Oct 2010 17:17:35 +0000 Subject: [PATCH] Copyright statements, whitespace, and other code formatting git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24415 dc483132-0cff-0310-8789-dd5450dbe970 --- src/plugins/preauth/securid_sam2/extern.h | 58 +- src/plugins/preauth/securid_sam2/securid2.c | 1096 +++++++++-------- .../preauth/securid_sam2/securid_sam2_main.c | 284 ++--- 3 files changed, 772 insertions(+), 666 deletions(-) diff --git a/src/plugins/preauth/securid_sam2/extern.h b/src/plugins/preauth/securid_sam2/extern.h index 8bea143bb..100c13230 100644 --- a/src/plugins/preauth/securid_sam2/extern.h +++ b/src/plugins/preauth/securid_sam2/extern.h @@ -1,18 +1,50 @@ - krb5_error_code sam_get_db_entry(krb5_context , krb5_principal, - int *, krb5_db_entry **); +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * plugins/preauth/securid_sam2/extern.h + * + * Copyright (C) 2010 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * Declarations for SecurID SAM2 plugin. + */ + +krb5_error_code sam_get_db_entry(krb5_context , krb5_principal, + int *, krb5_db_entry **); krb5_error_code -securid_make_sam_challenge_2_and_cksum (krb5_context context, - krb5_sam_challenge_2 *sc2, krb5_sam_challenge_2_body *sc2b, - krb5_keyblock *cksum_key); +securid_make_sam_challenge_2_and_cksum(krb5_context context, + krb5_sam_challenge_2 *sc2, + krb5_sam_challenge_2_body *sc2b, + krb5_keyblock *cksum_key); + krb5_error_code get_securid_edata_2(krb5_context context, - krb5_db_entry *client, - krb5_sam_challenge_2_body *sc2b, - krb5_sam_challenge_2 *sc2); + krb5_db_entry *client, + krb5_sam_challenge_2_body *sc2b, + krb5_sam_challenge_2 *sc2); krb5_error_code verify_securid_data_2(krb5_context context, - krb5_db_entry *client, - krb5_sam_response_2 *sr2, - krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *pa, - krb5_sam_challenge_2 **sc2_out); + krb5_db_entry *client, + krb5_sam_response_2 *sr2, + krb5_enc_tkt_part *enc_tkt_reply, + krb5_pa_data *pa, + krb5_sam_challenge_2 **sc2_out); diff --git a/src/plugins/preauth/securid_sam2/securid2.c b/src/plugins/preauth/securid_sam2/securid2.c index b7d744e60..b0012a15a 100644 --- a/src/plugins/preauth/securid_sam2/securid2.c +++ b/src/plugins/preauth/securid_sam2/securid2.c @@ -1,22 +1,46 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * plugins/preauth/securid_sam2/securid2.c + * + * Copyright (C) 2010 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ #include "k5-int.h" #include #include #include - - #include #include #include #include #include "extern.h" -#define KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC 0x5ec1d000 +#define KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC 0x5ec1d000 struct securid_track_data { - SDI_HANDLE handle; - char state; - char passcode[LENPRNST+1]; - long hostid; + SDI_HANDLE handle; + char state; + char passcode[LENPRNST+1]; + long hostid; }; #define SECURID_STATE_NEW_PIN 1 /* Ask for a new pin */ @@ -24,283 +48,293 @@ struct securid_track_data { #define SECURID_STATE_NEXT_CODE 3 /* Ask for the next pin code */ #define SECURID_STATE_INITIAL 4 - -static char *PASSCODE_message = "SecurID Passcode"; -static char *NEXT_PASSCODE_message = "Next Passcode"; -static char *NEW_PIN_AGAIN_message = "New PIN Again"; -static char PIN_message[64]; /* Max length should be 50 chars */ - -/* krb5_error_code get_securid_key(): - * inputs: context: from KDC process - * client: database entry of client executing - * SecurID SAM preauthentication - * outputs: client_securid_key: pointer to krb5_keyblock - * which is key for the client's SecurID - * database entry. - * returns: 0 on success - * KRB5 error codes otherwise +static char *PASSCODE_message = "SecurID Passcode"; +static char *NEXT_PASSCODE_message = "Next Passcode"; +static char *NEW_PIN_AGAIN_message = "New PIN Again"; +static char PIN_message[64]; /* Max length should be 50 chars */ + +/* + * krb5_error_code get_securid_key(): + * inputs: context: from KDC process + * client: database entry of client executing + * SecurID SAM preauthentication + * outputs: client_securid_key: pointer to krb5_keyblock + * which is key for the client's SecurID + * database entry. + * returns: 0 on success + * KRB5 error codes otherwise * - * builds pricipal name with final instance of "SECURID" and - * finds the database entry, decrypts the key out of the database - * and passes the key back to the calling process + * builds pricipal name with final instance of "SECURID" and + * finds the database entry, decrypts the key out of the database + * and passes the key back to the calling process */ -static krb5_error_code get_securid_key(krb5_context context, - krb5_db_entry *client, - krb5_keyblock *client_securid_key) +static krb5_error_code +get_securid_key(krb5_context context, krb5_db_entry *client, + krb5_keyblock *client_securid_key) { - krb5_db_entry *sam_securid_entry = NULL; + krb5_db_entry *sam_securid_entry = NULL; krb5_key_data *client_securid_key_data = NULL; int sam_type = PA_SAM_TYPE_SECURID; krb5_error_code retval = 0; - if (!client_securid_key) return(KRB5_PREAUTH_NO_KEY); + if (!client_securid_key) + return KRB5_PREAUTH_NO_KEY; retval = sam_get_db_entry(context, client->princ, - &sam_type, &sam_securid_entry); - + &sam_type, &sam_securid_entry); if (retval) - return(KRB5_PREAUTH_NO_KEY); - + return KRB5_PREAUTH_NO_KEY; - /* Find key with key_type = salt_type = kvno = -1. This finds the */ - /* latest kvno in the list. */ + /* Find key with key_type = salt_type = kvno = -1. This finds the */ + /* latest kvno in the list. */ retval = krb5_dbe_find_enctype(context, sam_securid_entry, - -1, -1, -1, &client_securid_key_data); + -1, -1, -1, &client_securid_key_data); if (retval) { - krb5_set_error_message(context, retval, - "while getting key from client's SAM SecurID entry"); - goto cleanup; + krb5_set_error_message(context, retval, + "while getting key from client's SAM SecurID " + "entry"); + goto cleanup; } - retval = krb5_dbe_decrypt_key_data(context, NULL, - client_securid_key_data, client_securid_key, NULL); + retval = krb5_dbe_decrypt_key_data(context, NULL, client_securid_key_data, + client_securid_key, NULL); if (retval) { - krb5_set_error_message(context, retval, - "while decrypting key from client's SAM SecurID entry "); - goto cleanup; + krb5_set_error_message(context, retval, + "while decrypting key from client's SAM " + "SecurID entry "); + goto cleanup; } - cleanup: +cleanup: if (sam_securid_entry) - krb5_db_free_principal(context, sam_securid_entry); + krb5_db_free_principal(context, sam_securid_entry); return retval; } krb5_error_code -securid_make_sam_challenge_2_and_cksum (krb5_context context, - krb5_sam_challenge_2 *sc2, krb5_sam_challenge_2_body *sc2b, - krb5_keyblock *cksum_key) +securid_make_sam_challenge_2_and_cksum(krb5_context context, + krb5_sam_challenge_2 *sc2, + krb5_sam_challenge_2_body *sc2b, + krb5_keyblock *cksum_key) { - krb5_error_code retval; - krb5_checksum **cksum_array = NULL; - krb5_checksum *cksum = NULL; - krb5_cksumtype cksumtype; - krb5_data *encoded_challenge_body = NULL; - - if (!cksum_key) return(KRB5_PREAUTH_NO_KEY); - if (!sc2 || !sc2b) return(KRB5KDC_ERR_PREAUTH_FAILED); - - retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body); - if (retval || !encoded_challenge_body) { - encoded_challenge_body = NULL; - goto cksum_cleanup; - } - - cksum_array = calloc(2, sizeof(krb5_checksum *)); - if (!cksum_array) { - retval = ENOMEM; - goto cksum_cleanup; - } - - cksum = (krb5_checksum *)k5alloc(sizeof(krb5_checksum), &retval); - if (retval) - goto cksum_cleanup; - cksum_array[0] = cksum; - cksum_array[1] = NULL; - - retval = krb5int_c_mandatory_cksumtype(context, cksum_key->enctype, &cksumtype); - if (retval) goto cksum_cleanup; - - retval = krb5_c_make_checksum(context, cksumtype, - cksum_key, KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM, - encoded_challenge_body, cksum); - if (retval) goto cksum_cleanup; - - sc2->sam_cksum = cksum_array; - sc2->sam_challenge_2_body = *encoded_challenge_body; - return(0); + krb5_error_code retval; + krb5_checksum **cksum_array = NULL; + krb5_checksum *cksum = NULL; + krb5_cksumtype cksumtype; + krb5_data *encoded_challenge_body = NULL; + + if (!cksum_key) + return KRB5_PREAUTH_NO_KEY; + if (!sc2 || !sc2b) + return KRB5KDC_ERR_PREAUTH_FAILED; + + retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body); + if (retval || !encoded_challenge_body) { + encoded_challenge_body = NULL; + goto cksum_cleanup; + } + + cksum_array = calloc(2, sizeof(krb5_checksum *)); + if (!cksum_array) { + retval = ENOMEM; + goto cksum_cleanup; + } + + cksum = (krb5_checksum *)k5alloc(sizeof(krb5_checksum), &retval); + if (retval) + goto cksum_cleanup; + cksum_array[0] = cksum; + cksum_array[1] = NULL; + + retval = krb5int_c_mandatory_cksumtype(context, cksum_key->enctype, + &cksumtype); + if (retval) + goto cksum_cleanup; + + retval = krb5_c_make_checksum(context, cksumtype, cksum_key, + KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM, + encoded_challenge_body, cksum); + if (retval) + goto cksum_cleanup; + + sc2->sam_cksum = cksum_array; + sc2->sam_challenge_2_body = *encoded_challenge_body; + return 0; cksum_cleanup: - if (encoded_challenge_body) krb5_free_data(context, encoded_challenge_body); - if (cksum_array) krb5_xfree(cksum_array); - if (cksum) krb5_xfree(cksum); - return (retval); + krb5_free_data(context, encoded_challenge_body); + free(cksum_array); + free(cksum); + return retval; } static krb5_error_code securid_decrypt_track_data_2(krb5_context context, krb5_db_entry *client, - krb5_data *enc_track_data, krb5_data *output) { + krb5_data *enc_track_data, krb5_data *output) +{ krb5_error_code retval; krb5_keyblock sam_key; krb5_enc_data tmp_enc_data; sam_key.contents = NULL; - if ((retval = get_securid_key(context, client, - &sam_key) ) != 0) - return(retval); + retval = get_securid_key(context, client, &sam_key); + if (retval != 0) + return retval; tmp_enc_data.ciphertext = *enc_track_data; tmp_enc_data.enctype = ENCTYPE_UNKNOWN; tmp_enc_data.kvno = 0; output->length = tmp_enc_data.ciphertext.length; - if (output->data) - free(output->data); + free(output->data); output->data = k5alloc(output->length, &retval); - if (retval) goto cleanup; + if (output->data == NULL) + goto cleanup; retval = krb5_c_decrypt(context, &sam_key, - KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, &tmp_enc_data, output); - cleanup: + KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, + &tmp_enc_data, output); +cleanup: krb5_free_keyblock_contents(context, &sam_key); if (retval) { - output->length = 0; - if (output->data) - free(output->data); - output->data = NULL; - return(retval); + output->length = 0; + free(output->data); + output->data = NULL; + return retval; } - return(0); + return 0; } static krb5_error_code securid_encrypt_track_data_2(krb5_context context, krb5_db_entry *client, - krb5_data *track_data, krb5_data *output) { + krb5_data *track_data, krb5_data *output) +{ krb5_error_code retval; size_t olen; krb5_keyblock sam_key; krb5_enc_data tmp_enc_data; + output->data = NULL; - if ((retval = get_securid_key(context,client, - &sam_key)) != 0) - return(retval); + retval = get_securid_key(context,client, &sam_key); + if (retval != 0) + return retval; - if ((retval = krb5_c_encrypt_length(context, sam_key.enctype, - track_data->length, &olen)) != 0) - goto cleanup; - assert (olen <= 65536); + retval = krb5_c_encrypt_length(context, sam_key.enctype, + track_data->length, &olen); + if (retval != 0) + goto cleanup; + assert(olen <= 65536); output->length = olen; output->data = k5alloc(output->length, &retval); if (retval) - goto cleanup; + goto cleanup; tmp_enc_data.ciphertext = *output; tmp_enc_data.enctype = sam_key.enctype; tmp_enc_data.kvno = 0; retval = krb5_c_encrypt(context, &sam_key, - KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, track_data, &tmp_enc_data); - cleanup: + KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, + track_data, &tmp_enc_data); +cleanup: krb5_free_keyblock_contents(context, &sam_key); if (retval) { - output->length = 0; - if (output->data) - krb5_xfree(output->data); - output->data = NULL; - return(retval); + output->length = 0; + free(output->data); + output->data = NULL; + return retval; } - return(0); + return 0; } -krb5_error_code get_securid_edata_2(krb5_context context, - krb5_db_entry *client, - krb5_sam_challenge_2_body *sc2b, - krb5_sam_challenge_2 *sc2) +krb5_error_code +get_securid_edata_2(krb5_context context, krb5_db_entry *client, + krb5_sam_challenge_2_body *sc2b, krb5_sam_challenge_2 *sc2) { - krb5_error_code retval; - krb5_data scratch; - krb5_keyblock client_key; - char *user = NULL; - char *def_user = ""; - struct securid_track_data sid_track_data; - krb5_data tmp_data; - client_key.contents = NULL; - scratch.data = NULL; - sc2b->sam_track_id.data = NULL; - - retval = krb5_unparse_name(context, client->princ, &user); - if (retval) - goto cleanup; - - - sc2b->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; - sc2b->sam_type_name.length = 0; - sc2b->sam_challenge_label.length = 0; - sc2b->sam_challenge.length = 0; - sc2b->sam_response_prompt.data = PASSCODE_message; - sc2b->sam_response_prompt.length = - strlen(sc2b->sam_response_prompt.data); - sc2b->sam_pk_for_sad.length = 0; - - sid_track_data.state = SECURID_STATE_INITIAL; - sid_track_data.hostid = gethostid(); - tmp_data.data = (char *) &sid_track_data; - tmp_data.length = sizeof(sid_track_data); - if((retval = securid_encrypt_track_data_2(context, client, - &tmp_data, - &sc2b->sam_track_id)) != 0) { - krb5_set_error_message(context, retval, "While encrypting nonce track data"); - goto cleanup; - } - - - scratch.data = (char *)&sc2b->sam_nonce; - scratch.length = sizeof(sc2b->sam_nonce); - retval = krb5_c_random_make_octets(context, &scratch); - if (retval) { - krb5_set_error_message(context, retval, - "while generating nonce data in get_securid_edata_2 (%s)", - user ? user : def_user); - goto cleanup; - } - - /* Get the client's key */ - if ((retval = get_securid_key(context, client, &client_key)) != 0) { - krb5_set_error_message(context, retval, - "while getting SecurID SAM key in get_securid_edata_2 (%s)", - user ? user : def_user); - goto cleanup; - } - sc2b->sam_etype = client_key.enctype; - - retval = securid_make_sam_challenge_2_and_cksum(context, - sc2, sc2b, &client_key); - if (retval) { - krb5_set_error_message(context, retval, - "while making SAM_CHALLENGE_2 checksum (%s)", - user ? user : def_user); - } - - cleanup: - krb5_free_keyblock_contents(context, &client_key); - if (user) krb5_xfree(user); - if (retval) { - krb5_free_data_contents(context, &sc2b->sam_track_id); - sc2b->sam_track_id.data = NULL; - } - return(retval); + krb5_error_code retval; + krb5_data scratch; + krb5_keyblock client_key; + char *user = NULL; + char *def_user = ""; + struct securid_track_data sid_track_data; + krb5_data tmp_data; + + client_key.contents = NULL; + scratch.data = NULL; + sc2b->sam_track_id.data = NULL; + + retval = krb5_unparse_name(context, client->princ, &user); + if (retval) + goto cleanup; + + sc2b->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + sc2b->sam_type_name.length = 0; + sc2b->sam_challenge_label.length = 0; + sc2b->sam_challenge.length = 0; + sc2b->sam_response_prompt.data = PASSCODE_message; + sc2b->sam_response_prompt.length = strlen(sc2b->sam_response_prompt.data); + sc2b->sam_pk_for_sad.length = 0; + + sid_track_data.state = SECURID_STATE_INITIAL; + sid_track_data.hostid = gethostid(); + tmp_data.data = (char *)&sid_track_data; + tmp_data.length = sizeof(sid_track_data); + retval = securid_encrypt_track_data_2(context, client, &tmp_data, + &sc2b->sam_track_id); + if (retval != 0) { + krb5_set_error_message(context, retval, + "While encrypting nonce track data"); + goto cleanup; + } + + scratch.data = (char *)&sc2b->sam_nonce; + scratch.length = sizeof(sc2b->sam_nonce); + retval = krb5_c_random_make_octets(context, &scratch); + if (retval) { + krb5_set_error_message(context, retval, + "while generating nonce data in " + "get_securid_edata_2 (%s)", + user ? user : def_user); + goto cleanup; + } + + /* Get the client's key */ + if ((retval = get_securid_key(context, client, &client_key)) != 0) { + krb5_set_error_message(context, retval, + "while getting SecurID SAM key in " + "get_securid_edata_2 (%s)", + user ? user : def_user); + goto cleanup; + } + sc2b->sam_etype = client_key.enctype; + + retval = securid_make_sam_challenge_2_and_cksum(context, + sc2, sc2b, &client_key); + if (retval) { + krb5_set_error_message(context, retval, + "while making SAM_CHALLENGE_2 checksum (%s)", + user ? user : def_user); + } + +cleanup: + krb5_free_keyblock_contents(context, &client_key); + free(user); + if (retval) { + krb5_free_data_contents(context, &sc2b->sam_track_id); + sc2b->sam_track_id.data = NULL; + } + return retval; } -krb5_error_code verify_securid_data_2(krb5_context context, - krb5_db_entry *client, - krb5_sam_response_2 *sr2, - krb5_enc_tkt_part *enc_tkt_reply, - krb5_pa_data *pa, - krb5_sam_challenge_2 **sc2_out) +krb5_error_code +verify_securid_data_2(krb5_context context, krb5_db_entry *client, + krb5_sam_response_2 *sr2, + krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa, + krb5_sam_challenge_2 **sc2_out) { krb5_error_code retval; int new_pin = 0; @@ -321,354 +355,386 @@ krb5_error_code verify_securid_data_2(krb5_context context, memset(&scratch, 0, sizeof(scratch)); *sc2_out = NULL; - if ((retval = krb5_unparse_name(context, client->princ, &user)) !=0 ) { - krb5_set_error_message(context, retval, - "while unparsing client name in verify_securid_data_2"); - return(retval); + retval = krb5_unparse_name(context, client->princ, &user); + if (retval != 0) { + krb5_set_error_message(context, retval, + "while unparsing client name in " + "verify_securid_data_2"); + return retval; } if ((sr2->sam_enc_nonce_or_sad.ciphertext.data == NULL) || - (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) { - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_set_error_message(context, retval, - "No preauth data supplied in verify_securid_data_2 (%s)", user); - goto cleanup; + (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) { + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_set_error_message(context, retval, + "No preauth data supplied in " + "verify_securid_data_2 (%s)", user); + goto cleanup; } retval = krb5_dbe_find_enctype(context, client, - sr2->sam_enc_nonce_or_sad.enctype, KRB5_KDB_SALTTYPE_NORMAL, - sr2->sam_enc_nonce_or_sad.kvno , &client_key_data); + sr2->sam_enc_nonce_or_sad.enctype, + KRB5_KDB_SALTTYPE_NORMAL, + sr2->sam_enc_nonce_or_sad.kvno, + &client_key_data); if (retval) { - krb5_set_error_message(context, retval, - "while getting client key in verify_securid_data_2 (%s)", user); - goto cleanup; + krb5_set_error_message(context, retval, + "while getting client key in " + "verify_securid_data_2 (%s)", user); + goto cleanup; } - if ((retval = krb5_dbe_decrypt_key_data(context, NULL, - client_key_data, &client_key, NULL)) != 0) { - krb5_set_error_message(context, retval, - "while decrypting client key in verify_securid_data_2 (%s)", - user); - goto cleanup; + retval = krb5_dbe_decrypt_key_data(context, NULL, client_key_data, + &client_key, NULL); + if (retval != 0) { + krb5_set_error_message(context, retval, + "while decrypting client key in " + "verify_securid_data_2 (%s)", + user); + goto cleanup; } scratch.length = sr2->sam_enc_nonce_or_sad.ciphertext.length; scratch.data = k5alloc(scratch.length, &retval); if (retval) - goto cleanup; + goto cleanup; retval = krb5_c_decrypt(context, &client_key, - KRB5_KEYUSAGE_PA_SAM_RESPONSE, 0, - &sr2->sam_enc_nonce_or_sad, &scratch); + KRB5_KEYUSAGE_PA_SAM_RESPONSE, 0, + &sr2->sam_enc_nonce_or_sad, &scratch); if (retval) { - krb5_set_error_message(context, retval, - "while decrypting SAD in verify_securid_data_2 (%s)", user); - goto cleanup; + krb5_set_error_message(context, retval, + "while decrypting SAD in " + "verify_securid_data_2 (%s)", user); + goto cleanup; } retval = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2); if (retval) { - krb5_set_error_message(context, retval, - "while decoding SAD in verify_securid_data_2 (%s)", user); - esre2 = NULL; - goto cleanup; + krb5_set_error_message(context, retval, + "while decoding SAD in " + "verify_securid_data_2 (%s)", user); + esre2 = NULL; + goto cleanup; } if (sr2->sam_nonce != esre2->sam_nonce) { - krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, - "while checking nonce in verify_securid_data_2 (%s)", user); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; + krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, + "while checking nonce in " + "verify_securid_data_2 (%s)", user); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; } - if ((esre2->sam_sad.length == 0) || (esre2->sam_sad.data == NULL)) { - krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, - "No SecurID passcode in verify_securid_data_2 (%s)", user); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; + if (esre2->sam_sad.length == 0 || esre2->sam_sad.data == NULL) { + krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, + "No SecurID passcode in " + "verify_securid_data_2 (%s)", user); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; } /* Copy out SAD to null-terminated buffer */ memset(passcode, 0, sizeof(passcode)); if (esre2->sam_sad.length > (sizeof(passcode) - 1)) { - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_set_error_message(context, retval, - "SecurID passcode/PIN too long (%d bytes) in verify_securid_data_2 (%s)", - esre2->sam_sad.length, user); - goto cleanup; + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_set_error_message(context, retval, + "SecurID passcode/PIN too long (%d bytes) in " + "verify_securid_data_2 (%s)", + esre2->sam_sad.length, user); + goto cleanup; } memcpy(passcode, esre2->sam_sad.data, esre2->sam_sad.length); securid_user = strdup(user); if (!securid_user) { - retval = ENOMEM; - krb5_set_error_message(context, ENOMEM, - "while copying user name in verify_securid_data_2 (%s)", user); - goto cleanup; + retval = ENOMEM; + krb5_set_error_message(context, ENOMEM, + "while copying user name in " + "verify_securid_data_2 (%s)", user); + goto cleanup; } - if ((cp = strchr(securid_user, '@'))) - *cp = (char)0; + cp = strchr(securid_user, '@'); + if (cp != NULL) + *cp = '\0'; - /* Check for any track_id data that may have state from a previous */ - /* attempt at SecurID authentication */ + /* Check for any track_id data that may have state from a previous attempt + * at SecurID authentication. */ if (sr2->sam_track_id.data && (sr2->sam_track_id.length > 0)) { - krb5_data track_id_data; - memset(&track_id_data, 0, sizeof(track_id_data)); - retval = securid_decrypt_track_data_2(context, client, - &sr2->sam_track_id, &track_id_data); - if (retval) { - krb5_set_error_message(context, retval, - "while decrypting SecurID trackID in verify_securid_data_2 (%s)", - user); - goto cleanup; - } - if (track_id_data.length <= sizeof (struct securid_track_data)) { - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_set_error_message(context, retval, "Length of track data incorrect"); - goto cleanup; - } - trackp = (struct securid_track_data *)track_id_data.data; - - if(trackp->hostid != gethostid()) { - krb5_klog_syslog(LOG_INFO, "Unexpected challenge response"); - retval = KRB5KDC_ERR_DISCARD; - goto cleanup; - } - - switch(trackp->state) { - case SECURID_STATE_INITIAL: - goto initial; - break; - case SECURID_STATE_NEW_PIN_AGAIN: - { - int pin1_len, pin2_len; - - trackp->handle = ntohl(trackp->handle); - pin2_len = strlen(passcode); - pin1_len = strlen(trackp->passcode); - - if ((pin1_len != pin2_len) || - (memcmp(passcode, trackp->passcode, pin1_len) != 0)) { - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_klog_syslog(LOG_INFO, - "New SecurID PIN Failed for user %s: PIN mis-match", - user); - break; - } - retval = SD_Pin(trackp->handle, passcode); - SD_Close(trackp->handle); - if (retval == ACM_NEW_PIN_ACCEPTED) { - enc_tkt_reply->flags|= TKT_FLG_HW_AUTH; - enc_tkt_reply->flags|= TKT_FLG_PRE_AUTH; - krb5_klog_syslog(LOG_INFO, - "SecurID PIN Accepted for %s in verify_securid_data_2", - securid_user); - retval = 0; - } else { - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_klog_syslog(LOG_INFO, - "SecurID PIN Failed for user %s (AceServer returns %d) in verify_securid_data_2", - user, retval); - } - break; - } - case SECURID_STATE_NEW_PIN: { - krb5_sam_challenge_2_body sc2b; - sc2p = k5alloc(sizeof *sc2p, &retval); - if (retval) - goto cleanup; - memset(sc2p, 0, sizeof(*sc2p)); - memset(&sc2b, 0, sizeof(sc2b)); - sc2b.sam_type = PA_SAM_TYPE_SECURID; - sc2b.sam_response_prompt.data = NEW_PIN_AGAIN_message; - sc2b.sam_response_prompt.length = - strlen(sc2b.sam_response_prompt.data); - sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; - sc2b.sam_etype = client_key.enctype; - - tmp_data.data = (char *)&sc2b.sam_nonce; - tmp_data.length = sizeof(sc2b.sam_nonce); - if ((retval = krb5_c_random_make_octets(context, &tmp_data))) { - krb5_set_error_message(context, retval, - "while making nonce for SecurID new PIN2 SAM_CHALLENGE_2 (%s)", user); - goto cleanup; - } - sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN; - sid_track_data.handle = trackp->handle; - sid_track_data.hostid = gethostid(); - /* Should we complain if sizes don't work ?? */ - memcpy(sid_track_data.passcode, passcode, - sizeof(sid_track_data.passcode)); - tmp_data.data = (char *)&sid_track_data; - tmp_data.length = sizeof(sid_track_data); - if ((retval = securid_encrypt_track_data_2(context, client, - &tmp_data, &sc2b.sam_track_id))) { - krb5_set_error_message(context, retval, - "while encrypting NEW PIN2 SecurID track data for SAM_CHALLENGE_2 (%s)", - securid_user); - goto cleanup; - } - retval = securid_make_sam_challenge_2_and_cksum(context, sc2p, - &sc2b, &client_key); - if (retval) { - krb5_set_error_message(context, retval, - "while making cksum for SAM_CHALLENGE_2 (new PIN2) (%s)", - securid_user); - goto cleanup; - } - krb5_klog_syslog(LOG_INFO, - "Requesting verification of new PIN for user %s", - securid_user); - *sc2_out = sc2p; - sc2p = NULL; - /*sc2_out may be set even on error path*/ - retval = KRB5KDC_ERR_PREAUTH_REQUIRED; - goto cleanup; - } - case SECURID_STATE_NEXT_CODE: - trackp->handle = ntohl(trackp->handle); - retval = SD_Next(trackp->handle, passcode); - SD_Close(trackp->handle); - if (retval == ACM_OK) { - enc_tkt_reply->flags |= TKT_FLG_HW_AUTH - | TKT_FLG_PRE_AUTH; - - krb5_klog_syslog(LOG_INFO, - "Next SecurID Code Accepted for user %s", securid_user); - retval = 0; - } else { - krb5_klog_syslog(LOG_INFO, - "Next SecurID Code Failed for user %s (AceServer returns %d) in verify_securid_data_2", - user, retval); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - } - break; - } - } else { /* No track data, this is first of N attempts */ -initial: - if ((retval = SD_Init(&sd_handle))) { - krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, - "SD_Init() returns error %d in verify_securid_data_2 (%s)", - retval, securid_user); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; - } - - if((retval = SD_Lock(sd_handle, securid_user)) != ACM_OK) { - SD_Close(sd_handle); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_klog_syslog(LOG_INFO, - "SD_Lock() failed (AceServer returns %d) for %s", - retval, securid_user); - goto cleanup; - } - - retval = SD_Check(sd_handle, passcode, securid_user); - switch (retval) { - case ACM_OK: - SD_Close(sd_handle); - enc_tkt_reply->flags|= TKT_FLG_HW_AUTH; - enc_tkt_reply->flags|= TKT_FLG_PRE_AUTH; - krb5_klog_syslog(LOG_INFO, - "SecurID passcode accepted for user %s", user); - retval = 0; - break; - case ACM_ACCESS_DENIED: - SD_Close(sd_handle); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - krb5_klog_syslog(LOG_INFO, - "AceServer returns Access Denied for user %s (SAM2)",user); - goto cleanup; - case ACM_NEW_PIN_REQUIRED: - new_pin = 1; - /*fall through*/ - case ACM_NEXT_CODE_REQUIRED: { - krb5_sam_challenge_2_body sc2b; - sc2p = k5alloc(sizeof *sc2p, &retval); - if (retval) - goto cleanup; - - memset(sc2p, 0, sizeof(*sc2p)); - memset(&sc2b, 0, sizeof(sc2b)); - - sc2b.sam_type = PA_SAM_TYPE_SECURID; - sc2b.sam_response_prompt.data = NEXT_PASSCODE_message; - sc2b.sam_response_prompt.length = - strlen(sc2b.sam_response_prompt.data); - sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; - sc2b.sam_etype = client_key.enctype; - if (new_pin) { - if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS) - && (AceGetMinPinLen(sd_handle, &min_pin_len) == ACE_SUCCESS) - && (AceGetAlphanumeric(sd_handle, &alpha_pin) == ACE_SUCCESS)) - { - sprintf(PIN_message, - "New PIN must contain %d to %d %sdigits", - min_pin_len, max_pin_len, - (alpha_pin == 0) ? "" : "alphanumeric "); - sc2b.sam_challenge_label.data = PIN_message; - sc2b.sam_challenge_label.length = - strlen(sc2b.sam_challenge_label.data); - } else { - sc2b.sam_challenge_label.length = 0; - } - } - - tmp_data.data = (char *)&sc2b.sam_nonce; - tmp_data.length = sizeof(sc2b.sam_nonce); - if ((retval = krb5_c_random_make_octets(context, &tmp_data))) { - krb5_set_error_message(context, retval, - "while making nonce for SecurID SAM_CHALLENGE_2 (%s)", user); - goto cleanup; - } - if (new_pin) - sid_track_data.state = SECURID_STATE_NEW_PIN; - else sid_track_data.state = SECURID_STATE_NEXT_CODE; - sid_track_data.handle = htonl(sd_handle); - sid_track_data.hostid = gethostid(); - tmp_data.data = (char *)&sid_track_data; - tmp_data.length = sizeof(sid_track_data); - if ((retval = securid_encrypt_track_data_2(context, client, - &tmp_data, &sc2b.sam_track_id))) { - krb5_set_error_message(context, retval, - "while encrypting SecurID track data for SAM_CHALLENGE_2 (%s)", - securid_user); - goto cleanup; - } - retval = securid_make_sam_challenge_2_and_cksum(context, sc2p, - &sc2b, &client_key); - if (retval) { - krb5_set_error_message(context, retval, - "while making cksum for SAM_CHALLENGE_2 (%s)", - securid_user); - } - if (new_pin) - krb5_klog_syslog(LOG_INFO, - "New SecurID PIN required for user %s", securid_user); - else krb5_klog_syslog(LOG_INFO, - "Next SecurID passcode required for user %s", securid_user); - *sc2_out = sc2p; - sc2p = NULL; - retval = KRB5KDC_ERR_PREAUTH_FAILED; - /*sc2_out is permitted as an output on error path*/ - goto cleanup; - } - default: - krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, - "AceServer returns unknown error code %d in verify_securid_data_2\n", retval); - retval = KRB5KDC_ERR_PREAUTH_FAILED; - goto cleanup; - } - } /* no track_id data */ + krb5_data track_id_data; + + memset(&track_id_data, 0, sizeof(track_id_data)); + retval = securid_decrypt_track_data_2(context, client, + &sr2->sam_track_id, + &track_id_data); + if (retval) { + krb5_set_error_message(context, retval, + "while decrypting SecurID trackID in " + "verify_securid_data_2 (%s)", user); + goto cleanup; + } + if (track_id_data.length <= sizeof (struct securid_track_data)) { + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_set_error_message(context, retval, + "Length of track data incorrect"); + goto cleanup; + } + trackp = (struct securid_track_data *)track_id_data.data; + + if(trackp->hostid != gethostid()) { + krb5_klog_syslog(LOG_INFO, "Unexpected challenge response"); + retval = KRB5KDC_ERR_DISCARD; + goto cleanup; + } + + switch(trackp->state) { + case SECURID_STATE_INITIAL: + goto initial; + break; + case SECURID_STATE_NEW_PIN_AGAIN: + { + int pin1_len, pin2_len; + + trackp->handle = ntohl(trackp->handle); + pin2_len = strlen(passcode); + pin1_len = strlen(trackp->passcode); + + if ((pin1_len != pin2_len) || + (memcmp(passcode, trackp->passcode, pin1_len) != 0)) { + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_klog_syslog(LOG_INFO, "New SecurID PIN Failed for user " + "%s: PIN mis-match", user); + break; + } + retval = SD_Pin(trackp->handle, passcode); + SD_Close(trackp->handle); + if (retval == ACM_NEW_PIN_ACCEPTED) { + enc_tkt_reply->flags|= TKT_FLG_HW_AUTH; + enc_tkt_reply->flags|= TKT_FLG_PRE_AUTH; + krb5_klog_syslog(LOG_INFO, "SecurID PIN Accepted for %s in " + "verify_securid_data_2", + securid_user); + retval = 0; + } else { + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_klog_syslog(LOG_INFO, + "SecurID PIN Failed for user %s (AceServer " + "returns %d) in verify_securid_data_2", + user, retval); + } + break; + } + case SECURID_STATE_NEW_PIN: { + krb5_sam_challenge_2_body sc2b; + sc2p = k5alloc(sizeof *sc2p, &retval); + if (retval) + goto cleanup; + memset(sc2p, 0, sizeof(*sc2p)); + memset(&sc2b, 0, sizeof(sc2b)); + sc2b.sam_type = PA_SAM_TYPE_SECURID; + sc2b.sam_response_prompt.data = NEW_PIN_AGAIN_message; + sc2b.sam_response_prompt.length = + strlen(sc2b.sam_response_prompt.data); + sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + sc2b.sam_etype = client_key.enctype; + + tmp_data.data = (char *)&sc2b.sam_nonce; + tmp_data.length = sizeof(sc2b.sam_nonce); + if ((retval = krb5_c_random_make_octets(context, &tmp_data))) { + krb5_set_error_message(context, retval, + "while making nonce for SecurID new " + "PIN2 SAM_CHALLENGE_2 (%s)", user); + goto cleanup; + } + sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN; + sid_track_data.handle = trackp->handle; + sid_track_data.hostid = gethostid(); + /* Should we complain if sizes don't work ?? */ + memcpy(sid_track_data.passcode, passcode, + sizeof(sid_track_data.passcode)); + tmp_data.data = (char *)&sid_track_data; + tmp_data.length = sizeof(sid_track_data); + if ((retval = securid_encrypt_track_data_2(context, client, + &tmp_data, + &sc2b.sam_track_id))) { + krb5_set_error_message(context, retval, + "while encrypting NEW PIN2 SecurID " + "track data for SAM_CHALLENGE_2 (%s)", + securid_user); + goto cleanup; + } + retval = securid_make_sam_challenge_2_and_cksum(context, sc2p, + &sc2b, + &client_key); + if (retval) { + krb5_set_error_message(context, retval, + "while making cksum for " + "SAM_CHALLENGE_2 (new PIN2) (%s)", + securid_user); + goto cleanup; + } + krb5_klog_syslog(LOG_INFO, + "Requesting verification of new PIN for user %s", + securid_user); + *sc2_out = sc2p; + sc2p = NULL; + /*sc2_out may be set even on error path*/ + retval = KRB5KDC_ERR_PREAUTH_REQUIRED; + goto cleanup; + } + case SECURID_STATE_NEXT_CODE: + trackp->handle = ntohl(trackp->handle); + retval = SD_Next(trackp->handle, passcode); + SD_Close(trackp->handle); + if (retval == ACM_OK) { + enc_tkt_reply->flags |= TKT_FLG_HW_AUTH | TKT_FLG_PRE_AUTH; + + krb5_klog_syslog(LOG_INFO, "Next SecurID Code Accepted for " + "user %s", securid_user); + retval = 0; + } else { + krb5_klog_syslog(LOG_INFO, "Next SecurID Code Failed for user " + "%s (AceServer returns %d) in " + "verify_securid_data_2", user, retval); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + } + break; + } + } else { /* No track data, this is first of N attempts */ + initial: + retval = SD_Init(&sd_handle); + if (retval) { + krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, + "SD_Init() returns error %d in " + "verify_securid_data_2 (%s)", + retval, securid_user); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + + retval = SD_Lock(sd_handle, securid_user); + if (retval != ACM_OK) { + SD_Close(sd_handle); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_klog_syslog(LOG_INFO, + "SD_Lock() failed (AceServer returns %d) for %s", + retval, securid_user); + goto cleanup; + } + + retval = SD_Check(sd_handle, passcode, securid_user); + switch (retval) { + case ACM_OK: + SD_Close(sd_handle); + enc_tkt_reply->flags|= TKT_FLG_HW_AUTH; + enc_tkt_reply->flags|= TKT_FLG_PRE_AUTH; + krb5_klog_syslog(LOG_INFO, "SecurID passcode accepted for user %s", + user); + retval = 0; + break; + case ACM_ACCESS_DENIED: + SD_Close(sd_handle); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + krb5_klog_syslog(LOG_INFO, "AceServer returns Access Denied for " + "user %s (SAM2)", user); + goto cleanup; + case ACM_NEW_PIN_REQUIRED: + new_pin = 1; + /*fall through*/ + case ACM_NEXT_CODE_REQUIRED: { + krb5_sam_challenge_2_body sc2b; + sc2p = k5alloc(sizeof *sc2p, &retval); + if (retval) + goto cleanup; + + memset(sc2p, 0, sizeof(*sc2p)); + memset(&sc2b, 0, sizeof(sc2b)); + + sc2b.sam_type = PA_SAM_TYPE_SECURID; + sc2b.sam_response_prompt.data = NEXT_PASSCODE_message; + sc2b.sam_response_prompt.length = + strlen(sc2b.sam_response_prompt.data); + sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD; + sc2b.sam_etype = client_key.enctype; + if (new_pin) { + if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS) + && (AceGetMinPinLen(sd_handle, + &min_pin_len) == ACE_SUCCESS) + && (AceGetAlphanumeric(sd_handle, + &alpha_pin) == ACE_SUCCESS)) { + sprintf(PIN_message, + "New PIN must contain %d to %d %sdigits", + min_pin_len, max_pin_len, + (alpha_pin == 0) ? "" : "alphanumeric "); + sc2b.sam_challenge_label.data = PIN_message; + sc2b.sam_challenge_label.length = + strlen(sc2b.sam_challenge_label.data); + } else { + sc2b.sam_challenge_label.length = 0; + } + } + + tmp_data.data = (char *)&sc2b.sam_nonce; + tmp_data.length = sizeof(sc2b.sam_nonce); + if ((retval = krb5_c_random_make_octets(context, &tmp_data))) { + krb5_set_error_message(context, retval, "while making nonce " + "for SecurID SAM_CHALLENGE_2 (%s)", + user); + goto cleanup; + } + if (new_pin) + sid_track_data.state = SECURID_STATE_NEW_PIN; + else + sid_track_data.state = SECURID_STATE_NEXT_CODE; + sid_track_data.handle = htonl(sd_handle); + sid_track_data.hostid = gethostid(); + tmp_data.data = (char *)&sid_track_data; + tmp_data.length = sizeof(sid_track_data); + retval = securid_encrypt_track_data_2(context, client, &tmp_data, + &sc2b.sam_track_id); + if (retval) { + krb5_set_error_message(context, retval, + "while encrypting SecurID track " + "data for SAM_CHALLENGE_2 (%s)", + securid_user); + goto cleanup; + } + retval = securid_make_sam_challenge_2_and_cksum(context, sc2p, + &sc2b, + &client_key); + if (retval) { + krb5_set_error_message(context, retval, "while making cksum " + "for SAM_CHALLENGE_2 (%s)", + securid_user); + } + if (new_pin) + krb5_klog_syslog(LOG_INFO, "New SecurID PIN required for " + "user %s", securid_user); + else + krb5_klog_syslog(LOG_INFO, "Next SecurID passcode required " + "for user %s", securid_user); + *sc2_out = sc2p; + sc2p = NULL; + retval = KRB5KDC_ERR_PREAUTH_FAILED; + /*sc2_out is permitted as an output on error path*/ + goto cleanup; + } + default: + krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, + "AceServer returns unknown error code %d " + "in verify_securid_data_2\n", retval); + retval = KRB5KDC_ERR_PREAUTH_FAILED; + goto cleanup; + } + } /* no track_id data */ cleanup: - if (client_key.contents) krb5_free_keyblock_contents(context, &client_key); - if (scratch.data) krb5_xfree(scratch.data); - if (esre2) krb5_free_enc_sam_response_enc_2(context, esre2); - if (user) krb5_xfree(user); - if (securid_user) krb5_xfree(securid_user); - if (trackp) krb5_xfree(trackp); - if (sc2p) - krb5_free_sam_challenge_2(context, sc2p); - return(retval); + krb5_free_keyblock_contents(context, &client_key); + free(scratch.data); + krb5_free_enc_sam_response_enc_2(context, esre2); + free(user); + free(securid_user); + free(trackp); + krb5_free_sam_challenge_2(context, sc2p); + return retval; } diff --git a/src/plugins/preauth/securid_sam2/securid_sam2_main.c b/src/plugins/preauth/securid_sam2/securid_sam2_main.c index f61414d54..695934cc4 100644 --- a/src/plugins/preauth/securid_sam2/securid_sam2_main.c +++ b/src/plugins/preauth/securid_sam2/securid_sam2_main.c @@ -1,6 +1,6 @@ /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* - * plugins/preauth/encrypted_challenge/encrypted_challenge.c + * plugins/preauth/securid_sam2/securid_sam2_main.c * * Copyright (C) 2009, 2010 by the Massachusetts Institute of Technology. * All rights reserved. @@ -42,54 +42,54 @@ #include #include "extern.h" - static struct { - char* name; - int sam_type; + char* name; + int sam_type; } *sam_ptr, sam_inst_map[] = { - { "SECURID", PA_SAM_TYPE_SECURID, }, - { "GRAIL", PA_SAM_TYPE_GRAIL, }, - { 0, 0 }, + { "SECURID", PA_SAM_TYPE_SECURID, }, + { "GRAIL", PA_SAM_TYPE_GRAIL, }, + { 0, 0 }, }; - krb5_error_code sam_get_db_entry( - krb5_context context, - krb5_principal client, - int *sam_type, - struct _krb5_db_entry_new **db_entry) +krb5_error_code +sam_get_db_entry(krb5_context context, krb5_principal client, + int *sam_type, struct _krb5_db_entry_new **db_entry) { struct _krb5_db_entry_new *assoc = NULL; - krb5_principal newp = NULL; - int probeslot; - void *ptr = NULL; - krb5_error_code retval; - if (db_entry) + krb5_principal newp = NULL; + int probeslot; + void *ptr = NULL; + krb5_error_code retval; + + if (db_entry) *db_entry = NULL; - retval = krb5_copy_principal(context, client, &newp); - if (retval) { - krb5_set_error_message(context, retval, "copying client name for preauth probe"); - return retval; - } + retval = krb5_copy_principal(context, client, &newp); + if (retval) { + krb5_set_error_message(context, retval, + "copying client name for preauth probe"); + return retval; + } - probeslot = krb5_princ_size(context, newp)++; - ptr = - realloc(krb5_princ_name(context, newp), - krb5_princ_size(context, newp) * sizeof(krb5_data)); + probeslot = krb5_princ_size(context, newp)++; + ptr = realloc(krb5_princ_name(context, newp), + krb5_princ_size(context, newp) * sizeof(krb5_data)); if (ptr == NULL) { retval = ENOMEM; goto cleanup; - } else krb5_princ_name(context, newp) = ptr; + } + krb5_princ_name(context, newp) = ptr; for(sam_ptr = sam_inst_map; sam_ptr->name; sam_ptr++) { - if (*sam_type && (*sam_type != sam_ptr->sam_type)) continue; + if (*sam_type && *sam_type != sam_ptr->sam_type) + continue; - krb5_princ_component(context,newp,probeslot)->data = sam_ptr->name; - krb5_princ_component(context,newp,probeslot)->length = - strlen(sam_ptr->name); - retval = krb5_db_get_principal(context, newp, 0, &assoc); - if(!retval ) - break; - } + krb5_princ_component(context,newp,probeslot)->data = sam_ptr->name; + krb5_princ_component(context,newp,probeslot)->length = + strlen(sam_ptr->name); + retval = krb5_db_get_principal(context, newp, 0, &assoc); + if (!retval) + break; + } cleanup: if (ptr) { krb5_princ_component(context,newp,probeslot)->data = 0; @@ -101,13 +101,16 @@ cleanup: if (retval) return retval; if (sam_ptr->sam_type) { - /* Found entry of type sam_ptr->sam_type */ - if (sam_type) *sam_type = sam_ptr->sam_type; - if (db_entry) *db_entry = assoc; - else krb5_db_free_principal( context, assoc); - return(0); + /* Found entry of type sam_ptr->sam_type */ + if (sam_type) + *sam_type = sam_ptr->sam_type; + if (db_entry) + *db_entry = assoc; + else + krb5_db_free_principal(context, assoc); + return 0; } else { - return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; } } @@ -118,62 +121,67 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request, preauth_get_entry_data_proc get_entry_proc, void *pa_module_context, krb5_pa_data *pa_data) { - krb5_error_code retval; - krb5_sam_challenge_2 sc2; - krb5_sam_challenge_2_body sc2b; - int sam_type = 0; /* unknown */ - krb5_db_entry *sam_db_entry = NULL; - krb5_data *encoded_challenge = NULL; - memset(&sc2, 0, sizeof(sc2)); - memset(&sc2b, 0, sizeof(sc2b)); - sc2b.magic = KV5M_SAM_CHALLENGE_2; - sc2b.sam_type = sam_type; + krb5_error_code retval; + krb5_sam_challenge_2 sc2; + krb5_sam_challenge_2_body sc2b; + int sam_type = 0; /* unknown */ + krb5_db_entry *sam_db_entry = NULL; + krb5_data *encoded_challenge = NULL; - retval = sam_get_db_entry(context, client->princ, &sam_type, - &sam_db_entry); - if (retval) return (retval); + memset(&sc2, 0, sizeof(sc2)); + memset(&sc2b, 0, sizeof(sc2b)); + sc2b.magic = KV5M_SAM_CHALLENGE_2; + sc2b.sam_type = sam_type; - if (sam_type == 0) { - retval = KRB5_PREAUTH_BAD_TYPE; - goto cleanup; - } + retval = sam_get_db_entry(context, client->princ, &sam_type, + &sam_db_entry); + if (retval) + return retval; - /* Defer getting the key for the SAM principal associated with the */ - /* client until the mechanism-specific code. The mechanism may want */ - /* to get a specific keytype */ + if (sam_type == 0) { + retval = KRB5_PREAUTH_BAD_TYPE; + goto cleanup; + } + /* + * Defer getting the key for the SAM principal associated with the client + * until the mechanism-specific code. The mechanism may want to get a + * specific keytype. + */ - switch (sam_type) { + switch (sam_type) { #ifdef ARL_SECURID_PREAUTH - case PA_SAM_TYPE_SECURID: - if ((retval = get_securid_edata_2(context, client, &sc2b, &sc2))) - goto cleanup; + case PA_SAM_TYPE_SECURID: + retval = get_securid_edata_2(context, client, &sc2b, &sc2); + if (retval) + goto cleanup; - retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge); - if (retval) { - krb5_set_error_message(context, retval,"while encoding SECURID SAM_CHALLENGE_2"); - goto cleanup; - } + retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge); + if (retval) { + krb5_set_error_message(context, retval, + "while encoding SECURID SAM_CHALLENGE_2"); + goto cleanup; + } - pa_data->magic = KV5M_PA_DATA; - pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2; - pa_data->contents = (krb5_octet *) encoded_challenge->data; - pa_data->length = encoded_challenge->length; + pa_data->magic = KV5M_PA_DATA; + pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2; + pa_data->contents = (krb5_octet *) encoded_challenge->data; + pa_data->length = encoded_challenge->length; encoded_challenge->data = NULL; - retval = 0; - break; + retval = 0; + break; #endif /* ARL_SECURID_PREAUTH */ - default: - retval = KRB5_PREAUTH_BAD_TYPE; - goto cleanup; - } + default: + retval = KRB5_PREAUTH_BAD_TYPE; + goto cleanup; + } cleanup: - krb5_free_data( context, encoded_challenge); - if (sam_db_entry) - krb5_db_free_principal(context, sam_db_entry); - return (retval); + krb5_free_data(context, encoded_challenge); + if (sam_db_entry) + krb5_db_free_principal(context, sam_db_entry); + return retval; } static krb5_error_code @@ -185,70 +193,70 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client, krb5_data **e_data, krb5_authdata ***authz_data) { krb5_error_code retval; - krb5_sam_response_2 *sr2 = NULL; - krb5_data scratch, *scratch2; + krb5_sam_response_2 *sr2 = NULL; + krb5_data scratch, *scratch2; char *client_name = NULL; krb5_sam_challenge_2 *out_sc2 = NULL; - scratch.data = (char *) pa_data->contents; - scratch.length = pa_data->length; + scratch.data = (char *) pa_data->contents; + scratch.length = pa_data->length; - retval = krb5_unparse_name(context, client->princ, &client_name); - if (retval) - goto cleanup; + retval = krb5_unparse_name(context, client->princ, &client_name); + if (retval) + goto cleanup; - retval = decode_krb5_sam_response_2(&scratch, &sr2); - if (retval) { - krb5_set_error_message(context, retval, - "while decoding SAM_RESPONSE_2 in verify_sam_response_2"); - sr2 = NULL; - goto cleanup; - } + retval = decode_krb5_sam_response_2(&scratch, &sr2); + if (retval) { + krb5_set_error_message(context, retval, "while decoding " + "SAM_RESPONSE_2 in verify_sam_response_2"); + sr2 = NULL; + goto cleanup; + } - switch (sr2->sam_type) { + switch (sr2->sam_type) { #ifdef ARL_SECURID_PREAUTH - case PA_SAM_TYPE_SECURID: - retval = verify_securid_data_2(context, client, sr2, - enc_tkt_reply, pa_data, &out_sc2); - if (retval) goto cleanup; - break; + case PA_SAM_TYPE_SECURID: + retval = verify_securid_data_2(context, client, sr2, enc_tkt_reply, + pa_data, &out_sc2); + if (retval) + goto cleanup; + break; #endif /* ARL_SECURID_PREAUTH */ - default: - retval = KRB5_PREAUTH_BAD_TYPE; - krb5_set_error_message(context , retval, "while verifying SAM 2 data"); - break; - } + default: + retval = KRB5_PREAUTH_BAD_TYPE; + krb5_set_error_message(context, retval, "while verifying SAM 2 data"); + break; + } - /* It is up to the method-specific verify routine to set the ticket flags */ - /* to indicate TKT_FLG_HW_AUTH and/or TKT_FLG_PRE_AUTH. Some methods */ - /* may require more than one round of dialog with the client and must */ - /* return successfully from their verify routine. If does not set the */ - /* TGT flags, the required_preauth conditions will not be met and it will */ - /* try again to get enough preauth data from the client. Do not set TGT */ - /* flags here. */ + /* + * It is up to the method-specific verify routine to set the ticket flags to + * indicate TKT_FLG_HW_AUTH and/or TKT_FLG_PRE_AUTH. Some methods may + * require more than one round of dialog with the client and must return + * successfully from their verify routine. If does not set the TGT flags, + * the required_preauth conditions will not be met and it will try again to + * get enough preauth data from the client. Do not set TGT flags here. + */ cleanup: - /*Note that e_data is an output even in error conditions.*/ - if (out_sc2) { - krb5_pa_data pa_out; - krb5_pa_data *pa_array[2]; - pa_array[0] = &pa_out; - pa_array[1] = NULL; - pa_out.pa_type = KRB5_PADATA_SAM_CHALLENGE_2; - retval = encode_krb5_sam_challenge_2(out_sc2, &scratch2); - krb5_free_sam_challenge_2(context, out_sc2); - if (retval) - goto encode_error; - pa_out.contents = (krb5_octet *) scratch2->data; - pa_out.length = scratch2->length; - retval = encode_krb5_padata_sequence(pa_array, e_data); - krb5_free_data(context, scratch2); - } -encode_error: if (sr2) - krb5_free_sam_response_2(context, sr2); - if (client_name) -free(client_name); - - return(retval); + /*Note that e_data is an output even in error conditions.*/ + if (out_sc2) { + krb5_pa_data pa_out; + krb5_pa_data *pa_array[2]; + pa_array[0] = &pa_out; + pa_array[1] = NULL; + pa_out.pa_type = KRB5_PADATA_SAM_CHALLENGE_2; + retval = encode_krb5_sam_challenge_2(out_sc2, &scratch2); + krb5_free_sam_challenge_2(context, out_sc2); + if (retval) + goto encode_error; + pa_out.contents = (krb5_octet *) scratch2->data; + pa_out.length = scratch2->length; + retval = encode_krb5_padata_sequence(pa_array, e_data); + krb5_free_data(context, scratch2); + } +encode_error: + krb5_free_sam_response_2(context, sr2); + free(client_name); + return retval; } -- 2.26.2