From: Nalin Dahyabhai Date: Mon, 8 Jul 2013 21:54:23 +0000 (-0400) Subject: Teach the responder test helper about OTP X-Git-Tag: krb5-1.12-alpha1~86 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6a2635d72a37eccbea4bbe260cb2c304302af3b;p=thirdparty%2Fkrb5.git Teach the responder test helper about OTP --- diff --git a/src/tests/responder.c b/src/tests/responder.c index 698e3975ac..57106ffc12 100644 --- a/src/tests/responder.c +++ b/src/tests/responder.c @@ -40,6 +40,7 @@ * "question=answer" * -c -> print the pkinit challenge * -p identity=pin -> provide a pkinit answer, in the form "identity=pin" + * -o index=value:pin -> provide an OTP answer, in the form "index=value:pin" * principal -> client principal name * * If the responder callback isn't called, that's treated as an error. @@ -68,13 +69,14 @@ struct responder_data { const char *challenge; const char *response; const char *pkinit_answer; + const char *otp_answer; }; static krb5_error_code responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) { krb5_error_code err; - char *key, *value, *encoded1, *encoded2; + char *key, *value, *pin, *encoded1, *encoded2; const char *challenge; k5_json_value decoded1, decoded2; k5_json_object ids; @@ -82,6 +84,7 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) krb5_int32 token_flags; struct responder_data *data = rawdata; krb5_responder_pkinit_challenge *chl; + krb5_responder_otp_challenge *ochl; unsigned int i, n; data->called = TRUE; @@ -161,14 +164,13 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) free(key); } - /* Read the challenge, formatted as a structure. */ - err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); - if (err != 0) { - fprintf(stderr, "error getting pkinit challenge\n"); - exit(1); - } - if (data->print_pkinit_challenge) { + /* Read the PKINIT challenge, formatted as a structure. */ + err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); + if (err != 0) { + fprintf(stderr, "error getting pkinit challenge\n"); + exit(1); + } if (chl != NULL) { for (n = 0; chl->identities[n] != NULL; n++) continue; @@ -183,10 +185,17 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) } } } + krb5_responder_pkinit_challenge_free(ctx, rctx, chl); } /* Provide a particular response for the PKINIT challenge. */ if (data->pkinit_answer != NULL) { + /* Read the PKINIT challenge, formatted as a structure. */ + err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); + if (err != 0) { + fprintf(stderr, "error getting pkinit challenge\n"); + exit(1); + } /* * In case order matters, if the identity starts with "FILE:", exercise * the set_answer function, with the real answer second. @@ -222,10 +231,9 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) if (strncmp(chl->identities[0]->identity, "PKCS12:", 5) == 0) krb5_responder_pkinit_set_answer(ctx, rctx, "foo", "bar"); } + krb5_responder_pkinit_challenge_free(ctx, rctx, chl); } - krb5_responder_pkinit_challenge_free(ctx, rctx, chl); - /* * Something we always check: read the PKINIT challenge, both as a * structure and in JSON form, reconstruct the JSON form from the @@ -273,6 +281,34 @@ responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) free(encoded1); } + /* Provide a particular response for an OTP challenge. */ + if (data->otp_answer != NULL) { + if (krb5_responder_otp_get_challenge(ctx, rctx, &ochl) == 0) { + key = strchr(data->otp_answer, '='); + if (key != NULL) { + /* Make a copy of the answer that we can chop up. */ + key = strdup(data->otp_answer); + if (key == NULL) + return ENOMEM; + /* Isolate the ti value. */ + value = strchr(key, '='); + *value++ = '\0'; + n = atoi(key); + /* Break the value and PIN apart. */ + pin = strchr(value, ':'); + if (pin != NULL) + *pin++ = '\0'; + err = krb5_responder_otp_set_answer(ctx, rctx, n, value, pin); + if (err != 0) { + fprintf(stderr, "error setting response\n"); + exit(1); + } + free(key); + } + krb5_responder_otp_challenge_free(ctx, rctx, ochl); + } + } + return 0; } @@ -347,6 +383,10 @@ main(int argc, char **argv) /* Set a PKINIT answer for a specific PKINIT identity. */ response.pkinit_answer = optarg; break; + case 'o': + /* Set an OTP answer for a specific OTP tokeninfo. */ + response.otp_answer = optarg; + break; } }