aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2015-08-03 11:44:58 -0400
committerGreg Hudson <ghudson@mit.edu>2015-08-09 13:58:48 -0400
commitbd6a449f6591f75d0db6dbf3fb702268b92d7eb8 (patch)
treed93a0d9cb825a6a40e7232db713b549f47cab87f /src/plugins
parent25e0656fdf9862faf9aa91288023776e9a47caad (diff)
downloadkrb5-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.c73
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;