static void json_db_iter_f(heim_object_t key, heim_object_t value, void *arg) { struct json_db_iter_ctx *ctx = arg; const char *key_string; heim_data_t key_data; key_string = heim_string_get_utf8((heim_string_t)key); key_data = heim_data_ref_create(key_string, strlen(key_string), NULL); ctx->iter_f(key_data, (heim_object_t)value, ctx->iter_ctx); heim_release(key_data); }
static heim_dict_t parse_dict(struct parse_ctx *ctx) { heim_dict_t dict; size_t count = 0; int ret; heim_assert(*ctx->p == '{', "string doesn't start with {"); dict = heim_dict_create(11); if (dict == NULL) { ctx->error = heim_error_create_enomem(); return NULL; } ctx->p += 1; /* safe because parse_pair() calls white_spaces() first */ while ((ret = parse_pair(dict, ctx)) > 0) count++; if (ret < 0) { heim_release(dict); return NULL; } if (count == 1 && !(ctx->flags & HEIM_JSON_F_NO_DATA_DICT)) { heim_object_t v = heim_dict_copy_value(dict, heim_tid_data_uuid_key); /* * Binary data encoded as a dict with a single magic key with * base64-encoded value? Decode as heim_data_t. */ if (v != NULL && heim_get_tid(v) == HEIM_TID_STRING) { void *buf; size_t len; buf = malloc(strlen(heim_string_get_utf8(v))); if (buf == NULL) { heim_release(dict); heim_release(v); ctx->error = heim_error_create_enomem(); return NULL; } len = base64_decode(heim_string_get_utf8(v), buf); heim_release(v); if (len == -1) { free(buf); return dict; /* assume aliasing accident */ } heim_release(dict); return (heim_dict_t)heim_data_ref_create(buf, len, free); } } return dict; }
static heim_data_t from_base64(heim_string_t s, heim_error_t *error) { void *buf; size_t len; heim_data_t d; buf = malloc(strlen(heim_string_get_utf8(s))); if (buf == NULL) goto enomem; len = rk_base64_decode(heim_string_get_utf8(s), buf); d = heim_data_ref_create(buf, len, free); if (d == NULL) goto enomem; return d; enomem: free(buf); if (error) *error = heim_error_create_enomem(); return NULL; }
static krb5_error_code an2ln_def_plug_an2ln(void *plug_ctx, krb5_context context, const char *rule, krb5_const_principal aname, set_result_f set_res_f, void *set_res_ctx) { krb5_error_code ret; const char *an2ln_db_fname; heim_db_t dbh = NULL; heim_dict_t db_options; heim_data_t k, v; heim_error_t error; char *unparsed = NULL; char *value = NULL; _krb5_load_db_plugins(context); heim_base_once_f(&sorted_text_db_init_once, NULL, sorted_text_db_init_f); if (strncmp(rule, "DB:", strlen("DB:") != 0)) return KRB5_PLUGIN_NO_HANDLE; an2ln_db_fname = &rule[strlen("DB:")]; if (!*an2ln_db_fname) return KRB5_PLUGIN_NO_HANDLE; ret = krb5_unparse_name(context, aname, &unparsed); if (ret) return ret; db_options = heim_dict_create(11); if (db_options != NULL) heim_dict_set_value(db_options, HSTR("read-only"), heim_number_create(1)); dbh = heim_db_create(NULL, an2ln_db_fname, db_options, &error); if (dbh == NULL) { krb5_set_error_message(context, heim_error_get_code(error), N_("Couldn't open aname2lname-text-db", "")); ret = KRB5_PLUGIN_NO_HANDLE; goto cleanup; } /* Binary search; file should be sorted (in C locale) */ k = heim_data_ref_create(unparsed, strlen(unparsed), NULL); if (k == NULL) return krb5_enomem(context); v = heim_db_copy_value(dbh, NULL, k, &error); heim_release(k); if (v == NULL && error != NULL) { krb5_set_error_message(context, heim_error_get_code(error), N_("Lookup in aname2lname-text-db failed", "")); ret = heim_error_get_code(error); goto cleanup; } else if (v == NULL) { ret = KRB5_PLUGIN_NO_HANDLE; goto cleanup; } else { /* found */ if (heim_data_get_length(v) == 0) { krb5_set_error_message(context, ret, N_("Principal mapped to empty username", "")); ret = KRB5_NO_LOCALNAME; goto cleanup; } ret = set_res_f(set_res_ctx, heim_data_get_ptr(v)); heim_release(v); } cleanup: heim_release(dbh); free(unparsed); free(value); return ret; }
static heim_string_t parse_string(struct parse_ctx *ctx) { const uint8_t *start; int quote = 0; if (ctx->flags & HEIM_JSON_F_STRICT_STRINGS) { ctx->error = heim_error_create(EINVAL, "Strict JSON string encoding " "not yet supported"); return NULL; } if (*ctx->p != '"') { ctx->error = heim_error_create(EINVAL, "Expected a JSON string but " "found something else at line %lu", ctx->lineno); return NULL; } start = ++ctx->p; while (ctx->p < ctx->pend) { if (*ctx->p == '\n') { ctx->lineno++; } else if (*ctx->p == '\\') { if (ctx->p + 1 == ctx->pend) goto out; ctx->p++; quote = 1; } else if (*ctx->p == '"') { heim_object_t o; if (quote) { char *p0, *p; p = p0 = malloc(ctx->p - start); if (p == NULL) goto out; while (start < ctx->p) { if (*start == '\\') { start++; /* XXX validate quoted char */ } *p++ = *start++; } o = heim_string_create_with_bytes(p0, p - p0); free(p0); } else { o = heim_string_create_with_bytes(start, ctx->p - start); if (o == NULL) { ctx->error = heim_error_create_enomem(); return NULL; } /* If we can decode as base64, then let's */ if (ctx->flags & HEIM_JSON_F_TRY_DECODE_DATA) { void *buf; size_t len; const char *s; s = heim_string_get_utf8(o); len = strlen(s); if (len >= 4 && strspn(s, base64_chars) >= len - 2) { buf = malloc(len); if (buf == NULL) { heim_release(o); ctx->error = heim_error_create_enomem(); return NULL; } len = base64_decode(s, buf); if (len == -1) { free(buf); return o; } heim_release(o); o = heim_data_ref_create(buf, len, free); } } } ctx->p += 1; return o; } ctx->p += 1; } out: ctx->error = heim_error_create(EINVAL, "ran out of string"); return NULL; }