aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2015-01-08 15:56:37 -0500
committerGreg Hudson <ghudson@mit.edu>2015-07-22 12:22:47 -0400
commite6e6e54e89bc9644144436c3f267796ed790f70c (patch)
treea9fa94aab192e9bf221e0f9d14305a9199b7dea3 /src/plugins
parente64140aba967e3d8a785d4f83b1477ed0bdc85bd (diff)
downloadkrb5-e6e6e54e89bc9644144436c3f267796ed790f70c.zip
krb5-e6e6e54e89bc9644144436c3f267796ed790f70c.tar.gz
krb5-e6e6e54e89bc9644144436c3f267796ed790f70c.tar.bz2
Add indicator support to OTP
Read an "indicator" profile variable for OTP token types and assert its values as indicators when that token type is used to authenticate. Add a test case in t_otp.py for this feature. ticket: 8157
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/preauth/otp/main.c13
-rw-r--r--src/plugins/preauth/otp/otp_state.c29
-rw-r--r--src/plugins/preauth/otp/otp_state.h3
3 files changed, 38 insertions, 7 deletions
diff --git a/src/plugins/preauth/otp/main.c b/src/plugins/preauth/otp/main.c
index 7941b4a..2649e9a 100644
--- a/src/plugins/preauth/otp/main.c
+++ b/src/plugins/preauth/otp/main.c
@@ -40,9 +40,12 @@ static krb5_preauthtype otp_pa_type_list[] =
{ KRB5_PADATA_OTP_REQUEST, 0 };
struct request_state {
+ krb5_context context;
krb5_kdcpreauth_verify_respond_fn respond;
void *arg;
krb5_enc_tkt_part *enc_tkt_reply;
+ krb5_kdcpreauth_callbacks preauth_cb;
+ krb5_kdcpreauth_rock rock;
};
static krb5_error_code
@@ -151,9 +154,11 @@ nonce_generate(krb5_context ctx, unsigned int length, krb5_data *nonce_out)
}
static void
-on_response(void *data, krb5_error_code retval, otp_response response)
+on_response(void *data, krb5_error_code retval, otp_response response,
+ char *const *indicators)
{
struct request_state rs = *(struct request_state *)data;
+ char *const *ind;
free(data);
@@ -163,6 +168,9 @@ on_response(void *data, krb5_error_code retval, otp_response response)
if (retval == 0)
rs.enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
+ for (ind = indicators; ind != NULL && *ind != NULL && retval == 0; ind++)
+ retval = rs.preauth_cb->add_auth_indicator(rs.context, rs.rock, *ind);
+
rs.respond(rs.arg, retval, NULL, NULL, NULL);
}
@@ -305,9 +313,12 @@ otp_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
rs = k5alloc(sizeof(struct request_state), &retval);
if (rs == NULL)
goto error;
+ rs->context = context;
rs->arg = arg;
rs->respond = respond;
rs->enc_tkt_reply = enc_tkt_reply;
+ rs->preauth_cb = cb;
+ rs->rock = rock;
/* Get the principal's OTP configuration string. */
retval = cb->get_string(context, rock, "otp", &config);
diff --git a/src/plugins/preauth/otp/otp_state.c b/src/plugins/preauth/otp/otp_state.c
index 7deb462..79fbc4d 100644
--- a/src/plugins/preauth/otp/otp_state.c
+++ b/src/plugins/preauth/otp/otp_state.c
@@ -52,6 +52,7 @@ typedef struct token_type_st {
int timeout;
size_t retries;
krb5_boolean strip_realm;
+ char **indicators;
} token_type;
typedef struct token_st {
@@ -133,6 +134,7 @@ token_type_free(token_type *type)
free(type->name);
free(type->server);
free(type->secret);
+ profile_free_list(type->indicators);
}
/* Construct the internal default token type. */
@@ -172,6 +174,8 @@ static krb5_error_code
token_type_decode(profile_t profile, const char *name, token_type *out)
{
char *server = NULL, *name_copy = NULL, *secret = NULL, *pstr = NULL;
+ char **indicators = NULL;
+ const char *keys[4];
int strip_realm, timeout, retries;
krb5_error_code retval;
@@ -241,18 +245,32 @@ token_type_decode(profile_t profile, const char *name, token_type *out)
if (retval != 0)
goto cleanup;
+ /* Get the authentication indicators to assert if this token is used. */
+ keys[0] = "otp";
+ keys[1] = name;
+ keys[2] = "indicator";
+ keys[3] = NULL;
+ retval = profile_get_values(profile, keys, &indicators);
+ if (retval == PROF_NO_RELATION)
+ retval = 0;
+ if (retval != 0)
+ goto cleanup;
+
out->name = name_copy;
out->server = server;
out->secret = secret;
out->timeout = timeout;
out->retries = retries;
out->strip_realm = strip_realm;
+ out->indicators = indicators;
name_copy = server = secret = NULL;
+ indicators = NULL;
cleanup:
free(name_copy);
free(server);
free(secret);
+ profile_free_list(indicators);
return retval;
}
@@ -545,6 +563,7 @@ callback(krb5_error_code retval, const krad_packet *rqst,
const krad_packet *resp, void *data)
{
request *req = data;
+ char *const *indicators = req->tokens[req->index].type->indicators;
req->index++;
@@ -554,7 +573,7 @@ callback(krb5_error_code retval, const krad_packet *rqst,
/* If we received an accept packet, success! */
if (krad_packet_get_code(resp) ==
krad_code_name2num("Access-Accept")) {
- req->cb(req->data, retval, otp_response_success);
+ req->cb(req->data, retval, otp_response_success, indicators);
request_free(req);
return;
}
@@ -567,7 +586,7 @@ callback(krb5_error_code retval, const krad_packet *rqst,
request_send(req);
error:
- req->cb(req->data, retval, otp_response_fail);
+ req->cb(req->data, retval, otp_response_fail, NULL);
request_free(req);
}
@@ -594,7 +613,7 @@ request_send(request *req)
return;
error:
- req->cb(req->data, retval, otp_response_fail);
+ req->cb(req->data, retval, otp_response_fail, NULL);
request_free(req);
}
@@ -615,7 +634,7 @@ otp_state_verify(otp_state *state, verto_ctx *ctx, krb5_const_principal princ,
rqst = calloc(1, sizeof(request));
if (rqst == NULL) {
- (*cb)(data, ENOMEM, otp_response_fail);
+ (*cb)(data, ENOMEM, otp_response_fail, NULL);
return;
}
rqst->state = state;
@@ -646,6 +665,6 @@ otp_state_verify(otp_state *state, verto_ctx *ctx, krb5_const_principal princ,
return;
error:
- (*cb)(data, retval, otp_response_fail);
+ (*cb)(data, retval, otp_response_fail, NULL);
request_free(rqst);
}
diff --git a/src/plugins/preauth/otp/otp_state.h b/src/plugins/preauth/otp/otp_state.h
index 4247d0b..da57ad9 100644
--- a/src/plugins/preauth/otp/otp_state.h
+++ b/src/plugins/preauth/otp/otp_state.h
@@ -43,7 +43,8 @@ typedef enum otp_response {
typedef struct otp_state_st otp_state;
typedef void
-(*otp_cb)(void *data, krb5_error_code retval, otp_response response);
+(*otp_cb)(void *data, krb5_error_code retval, otp_response response,
+ char *const *indicators);
krb5_error_code
otp_state_new(krb5_context ctx, otp_state **self);