diff options
author | Greg Hudson <ghudson@mit.edu> | 2015-08-03 11:44:58 -0400 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2015-08-09 13:58:48 -0400 |
commit | bd6a449f6591f75d0db6dbf3fb702268b92d7eb8 (patch) | |
tree | d93a0d9cb825a6a40e7232db713b549f47cab87f /src/plugins | |
parent | 25e0656fdf9862faf9aa91288023776e9a47caad (diff) | |
download | krb5-bd6a449f6591f75d0db6dbf3fb702268b92d7eb8.zip krb5-bd6a449f6591f75d0db6dbf3fb702268b92d7eb8.tar.gz krb5-bd6a449f6591f75d0db6dbf3fb702268b92d7eb8.tar.bz2 |
Support OTP auth indicators in string attribute
To better support integration with FreeIPA, allow authentication
indicators to be specified in the "otp" string attribute, overriding
any indicators in the token type.
ticket: 8157
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/preauth/otp/otp_state.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/src/plugins/preauth/otp/otp_state.c b/src/plugins/preauth/otp/otp_state.c index 79fbc4d..5ba3d91 100644 --- a/src/plugins/preauth/otp/otp_state.c +++ b/src/plugins/preauth/otp/otp_state.c @@ -58,6 +58,7 @@ typedef struct token_type_st { typedef struct token_st { const token_type *type; krb5_data username; + char **indicators; } token; typedef struct request_st { @@ -339,12 +340,61 @@ cleanup: return retval; } +/* Free a null-terminated array of strings. */ +static void +free_strings(char **list) +{ + char **p; + + for (p = list; p != NULL && *p != NULL; p++) + free(*p); + free(list); +} + /* Free the contents of a single token. */ static void token_free_contents(token *t) { - if (t != NULL) - free(t->username.data); + if (t == NULL) + return; + free(t->username.data); + free_strings(t->indicators); +} + +/* Decode a JSON array of strings into a null-terminated list of C strings. */ +static krb5_error_code +indicators_decode(krb5_context ctx, k5_json_value val, char ***indicators_out) +{ + k5_json_array arr; + k5_json_value obj; + char **indicators; + size_t len, i; + + *indicators_out = NULL; + + if (k5_json_get_tid(val) != K5_JSON_TID_ARRAY) + return EINVAL; + arr = val; + len = k5_json_array_length(arr); + indicators = calloc(len + 1, sizeof(*indicators)); + if (indicators == NULL) + return ENOMEM; + + for (i = 0; i < len; i++) { + obj = k5_json_array_get(arr, i); + if (k5_json_get_tid(obj) != K5_JSON_TID_STRING) { + free_strings(indicators); + return EINVAL; + } + indicators[i] = strdup(k5_json_string_utf8(obj)); + if (indicators[i] == NULL) { + free_strings(indicators); + return ENOMEM; + } + } + + *indicators_out = indicators; + return 0; } /* Decode a single token from a JSON token object. */ @@ -354,7 +404,7 @@ token_decode(krb5_context ctx, krb5_const_principal princ, { const char *typename = DEFAULT_TYPE_NAME; const token_type *type = NULL; - char *username = NULL; + char *username = NULL, **indicators = NULL; krb5_error_code retval; k5_json_value val; size_t i; @@ -386,8 +436,19 @@ token_decode(krb5_context ctx, krb5_const_principal princ, return retval; } + /* Get the authentication indicators if specified. */ + val = k5_json_object_get(obj, "indicators"); + if (val != NULL) { + retval = indicators_decode(ctx, val, &indicators); + if (retval != 0) { + free(username); + return retval; + } + } + out->type = type; out->username = string2data(username); + out->indicators = indicators; return 0; } @@ -563,7 +624,8 @@ 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; + token *tok = &req->tokens[req->index]; + char *const *indicators; req->index++; @@ -573,6 +635,9 @@ 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")) { + indicators = tok->indicators; + if (indicators == NULL) + indicators = tok->type->indicators; req->cb(req->data, retval, otp_response_success, indicators); request_free(req); return; |