|
Packit |
fd8b60 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit |
fd8b60 |
/* plugins/audit/kdc_j_encode.c - Utilities to json encode KDC audit stuff */
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Copyright (C) 2013 by the Massachusetts Institute of Technology.
|
|
Packit |
fd8b60 |
* All rights reserved.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
fd8b60 |
* modification, are permitted provided that the following conditions
|
|
Packit |
fd8b60 |
* are met:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* * Redistributions of source code must retain the above copyright
|
|
Packit |
fd8b60 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* * Redistributions in binary form must reproduce the above copyright
|
|
Packit |
fd8b60 |
* notice, this list of conditions and the following disclaimer in
|
|
Packit |
fd8b60 |
* the documentation and/or other materials provided with the
|
|
Packit |
fd8b60 |
* distribution.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
fd8b60 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
fd8b60 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
Packit |
fd8b60 |
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
Packit |
fd8b60 |
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
Packit |
fd8b60 |
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
Packit |
fd8b60 |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit |
fd8b60 |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
Packit |
fd8b60 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
Packit |
fd8b60 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
fd8b60 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
Packit |
fd8b60 |
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include <k5-int.h>
|
|
Packit |
fd8b60 |
#include <k5-json.h>
|
|
Packit |
fd8b60 |
#include "kdc_j_encode.h"
|
|
Packit |
fd8b60 |
#include "j_dict.h"
|
|
Packit |
fd8b60 |
#include <krb5/audit_plugin.h>
|
|
Packit |
fd8b60 |
#include <syslog.h>
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
string_to_value(const char *in, k5_json_object obj, const char *key);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
princ_to_value(krb5_principal princ, k5_json_object obj, const char *key);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
data_to_value(krb5_data *data, k5_json_object obj, const char *key);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
int32_to_value(krb5_int32 int32, k5_json_object obj, const char *key);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
bool_to_value(krb5_boolean b, k5_json_object obj, const char *key);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
addr_to_obj(krb5_address *a, k5_json_object obj);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
eventinfo_to_value(k5_json_object obj, const char *name,
|
|
Packit |
fd8b60 |
const int stage, const krb5_boolean ev_success);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
addr_to_value(const krb5_address *address, k5_json_object obj,
|
|
Packit |
fd8b60 |
const char *key);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
req_to_value(krb5_kdc_req *req, const krb5_boolean ev_success,
|
|
Packit |
fd8b60 |
k5_json_object obj);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
rep_to_value(krb5_kdc_rep *rep, const krb5_boolean ev_success,
|
|
Packit |
fd8b60 |
k5_json_object obj);
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
tkt_to_value(krb5_ticket *tkt, k5_json_object obj, const char *key);
|
|
Packit |
fd8b60 |
static char *map_patype(krb5_preauthtype pa_type);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#define NULL_STATE "state is NULL"
|
|
Packit |
fd8b60 |
#define T_RENEWED 1
|
|
Packit |
fd8b60 |
#define T_NOT_RENEWED 2
|
|
Packit |
fd8b60 |
#define T_VALIDATED 1
|
|
Packit |
fd8b60 |
#define T_NOT_VALIDATED 2
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* KDC server STOP. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_kdc_stop(const krb5_boolean ev_success, char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Audit event_ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = string_to_value("KDC_STOP", obj, AU_EVENT_NAME);
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = bool_to_value(ev_success, obj, AU_EVENT_STATUS);
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* KDC server START. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_kdc_start(const krb5_boolean ev_success, char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Audit event_ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = string_to_value("KDC_START", obj, AU_EVENT_NAME);
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = bool_to_value(ev_success, obj, AU_EVENT_STATUS);
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* AS-REQ. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_as_req(const krb5_boolean ev_success, krb5_audit_state *state,
|
|
Packit |
fd8b60 |
char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!state) {
|
|
Packit |
fd8b60 |
*jout = NULL_STATE;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
/* Audit event_ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = eventinfo_to_value(obj, "AS_REQ", state->stage, ev_success);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* TGT ticket ID */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Request ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->req_id, obj, AU_REQ_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Client's port and address. */
|
|
Packit |
fd8b60 |
ret = int32_to_value(state->cl_port, obj, AU_FROMPORT);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = addr_to_value(state->cl_addr, obj, AU_FROMADDR);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* KDC status msg */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->status, obj, AU_KDC_STATUS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* non-local client's referral realm. */
|
|
Packit |
fd8b60 |
ret = data_to_value(state->cl_realm, obj, AU_CREF_REALM);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Request. */
|
|
Packit |
fd8b60 |
ret = req_to_value(state->request, ev_success, obj);
|
|
Packit |
fd8b60 |
if (ret == ENOMEM)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Reply/ticket info. */
|
|
Packit |
fd8b60 |
ret = rep_to_value(state->reply, ev_success, obj);
|
|
Packit |
fd8b60 |
if (ret == ENOMEM)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* TGS-REQ. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_tgs_req(const krb5_boolean ev_success, krb5_audit_state *state,
|
|
Packit |
fd8b60 |
char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
krb5_kdc_req *req = state->request;
|
|
Packit |
fd8b60 |
int tkt_validated = 0, tkt_renewed = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!state) {
|
|
Packit |
fd8b60 |
*jout = NULL_STATE;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Audit Event ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = eventinfo_to_value(obj, "TGS_REQ", state->stage, ev_success);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Primary and derived ticket IDs. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Request ID */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->req_id, obj, AU_REQ_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* client’s address and port. */
|
|
Packit |
fd8b60 |
ret = int32_to_value(state->cl_port, obj, AU_FROMPORT);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = addr_to_value(state->cl_addr, obj, AU_FROMADDR);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Ticket was renewed, validated. */
|
|
Packit |
fd8b60 |
if ((ev_success == TRUE) && (req != NULL)) {
|
|
Packit |
fd8b60 |
tkt_renewed = (req->kdc_options & KDC_OPT_RENEW) ?
|
|
Packit |
fd8b60 |
T_RENEWED : T_NOT_RENEWED;
|
|
Packit |
fd8b60 |
tkt_validated = (req->kdc_options & KDC_OPT_VALIDATE) ?
|
|
Packit |
fd8b60 |
T_VALIDATED : T_NOT_VALIDATED;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = int32_to_value(tkt_renewed, obj, AU_TKT_RENEWED);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(tkt_validated, obj, AU_TKT_VALIDATED);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* KDC status msg, including "ISSUE". */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->status, obj, AU_KDC_STATUS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* request */
|
|
Packit |
fd8b60 |
ret = req_to_value(req, ev_success, obj);
|
|
Packit |
fd8b60 |
if (ret == ENOMEM)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* reply/ticket */
|
|
Packit |
fd8b60 |
ret = rep_to_value(state->reply, ev_success, obj);
|
|
Packit |
fd8b60 |
if (ret == ENOMEM)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* S4U2Self protocol extension. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_tgs_s4u2self(const krb5_boolean ev_success, krb5_audit_state *state,
|
|
Packit |
fd8b60 |
char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!state) {
|
|
Packit |
fd8b60 |
*jout = NULL_STATE;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Audit Event ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = eventinfo_to_value(obj, "S4U2SELF", state->stage, ev_success);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Front-end server's TGT ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* service "to self" ticket or referral TGT ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Request ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->req_id, obj, AU_REQ_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
if (ev_success == FALSE) {
|
|
Packit |
fd8b60 |
/* KDC status msg. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->status, obj, AU_KDC_STATUS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Local policy or S4U protocol constraints. */
|
|
Packit |
fd8b60 |
ret = int32_to_value(state->violation, obj, AU_VIOLATION);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Impersonated user. */
|
|
Packit |
fd8b60 |
ret = princ_to_value(state->s4u2self_user, obj, AU_REQ_S4U2S_USER);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* S4U2Proxy protocol extension. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_tgs_s4u2proxy(const krb5_boolean ev_success, krb5_audit_state *state,
|
|
Packit |
fd8b60 |
char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
krb5_kdc_req *req = state->request;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!state) {
|
|
Packit |
fd8b60 |
*jout = NULL_STATE;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Audit Event ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = eventinfo_to_value(obj, "S4U2PROXY", state->stage, ev_success);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Front-end server's TGT ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Resource service or referral TGT ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* User's evidence ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->evid_tkt_id, obj, AU_EVIDENCE_TKT_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Request ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->req_id, obj, AU_REQ_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (ev_success == FALSE) {
|
|
Packit |
fd8b60 |
/* KDC status msg. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->status, obj, AU_KDC_STATUS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Local policy or S4U protocol constraints. */
|
|
Packit |
fd8b60 |
ret = int32_to_value(state->violation, obj, AU_VIOLATION);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Delegated user. */
|
|
Packit |
fd8b60 |
if (req != NULL) {
|
|
Packit |
fd8b60 |
ret = princ_to_value(req->second_ticket[0]->enc_part2->client,
|
|
Packit |
fd8b60 |
obj, AU_REQ_S4U2P_USER);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* U2U. Returns 0 on success. */
|
|
Packit |
fd8b60 |
krb5_error_code
|
|
Packit |
fd8b60 |
kau_j_tgs_u2u(const krb5_boolean ev_success, krb5_audit_state *state,
|
|
Packit |
fd8b60 |
char **jout)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object obj = NULL;
|
|
Packit |
fd8b60 |
krb5_kdc_req *req = state->request;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!state) {
|
|
Packit |
fd8b60 |
*jout = NULL_STATE;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
*jout = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&obj))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
/* Audit Event ID and ev_success. */
|
|
Packit |
fd8b60 |
ret = eventinfo_to_value(obj, "U2U", state->stage, ev_success);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Front-end server's TGT ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Service ticket ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Request ID. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->req_id, obj, AU_REQ_ID);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (ev_success == FALSE) {
|
|
Packit |
fd8b60 |
/* KDC status msg. */
|
|
Packit |
fd8b60 |
ret = string_to_value(state->status, obj, AU_KDC_STATUS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Client in the second ticket. */
|
|
Packit |
fd8b60 |
if (req != NULL) {
|
|
Packit |
fd8b60 |
ret = princ_to_value(req->second_ticket[0]->enc_part2->client,
|
|
Packit |
fd8b60 |
obj, AU_REQ_U2U_USER);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Enctype of a session key of the second ticket. */
|
|
Packit |
fd8b60 |
ret = int32_to_value(req->second_ticket[0]->enc_part2->session->enctype,
|
|
Packit |
fd8b60 |
obj, AU_SRV_ETYPE);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_encode(obj, jout);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(obj);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Low level utilities */
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Converts string into a property of a JSON object. Returns 0 on success.*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
string_to_value(const char *in, k5_json_object obj, const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_string str = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (in == NULL)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_string_create(in, &str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, str);
|
|
Packit |
fd8b60 |
k5_json_release(str);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Converts a krb5_data struct into a property of a JSON object.
|
|
Packit |
fd8b60 |
* (Borrowed from preauth_otp.c)
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
data_to_value(krb5_data *data, k5_json_object obj, const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_string str = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (data == NULL || data->data == NULL || data->length < 1)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_string_create_len(data->data, data->length, &str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, str);
|
|
Packit |
fd8b60 |
k5_json_release(str);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Converts krb5_int32 into a property of a JSON object.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
int32_to_value(krb5_int32 int32, k5_json_object obj, const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_number num = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_number_create(int32, &num);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, num);
|
|
Packit |
fd8b60 |
k5_json_release(num);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Converts krb5_boolean into a property of a JSON object.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
bool_to_value(krb5_boolean in, k5_json_object obj, const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_bool b = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_bool_create(in, &b);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, b);
|
|
Packit |
fd8b60 |
k5_json_release(b);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Wrapper-level utilities */
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Wrapper for stage and event_status tags. Returns 0 on success. */
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
eventinfo_to_value(k5_json_object obj, const char *name,
|
|
Packit |
fd8b60 |
const int stage, const krb5_boolean ev_success)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = string_to_value(name, obj, AU_EVENT_NAME);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
ret = int32_to_value(stage, obj, AU_STAGE);
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = bool_to_value(ev_success, obj, AU_EVENT_STATUS);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Converts krb5_principal into a property of a JSON object.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
princ_to_value(krb5_principal princ, k5_json_object obj, const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object tmp = NULL;
|
|
Packit |
fd8b60 |
k5_json_array arr = NULL;
|
|
Packit |
fd8b60 |
k5_json_string str = NULL;
|
|
Packit |
fd8b60 |
int i = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (princ == NULL || princ->data == NULL)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&tmp))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_array_create(&arr;;
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
for (i = 0; i < princ->length; i++) {
|
|
Packit |
fd8b60 |
ret = k5_json_string_create_len((&princ->data[i])->data,
|
|
Packit |
fd8b60 |
(&princ->data[i])->length, &str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_array_add(arr, str);
|
|
Packit |
fd8b60 |
k5_json_release(str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(tmp, AU_COMPONENTS, arr);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = data_to_value(&princ->realm, tmp, AU_REALM);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(princ->length, tmp, AU_LENGTH);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(princ->type, tmp, AU_TYPE);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, tmp);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(tmp);
|
|
Packit |
fd8b60 |
k5_json_release(arr);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Helper for JSON encoding of krb5_address.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
addr_to_obj(krb5_address *a, k5_json_object obj)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_number num = NULL;
|
|
Packit |
fd8b60 |
k5_json_array arr = NULL;
|
|
Packit |
fd8b60 |
int i;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (a == NULL || a->contents == NULL || a->length <= 0)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = int32_to_value(a->addrtype, obj, AU_TYPE);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(a->length, obj, AU_LENGTH);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (a->addrtype == ADDRTYPE_INET || a->addrtype == ADDRTYPE_INET6) {
|
|
Packit |
fd8b60 |
ret = k5_json_array_create(&arr;;
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
for (i = 0; i < (int)a->length; i++) {
|
|
Packit |
fd8b60 |
ret = k5_json_number_create(a->contents[i], &num);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_array_add(arr, num);
|
|
Packit |
fd8b60 |
k5_json_release(num);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, AU_IP, arr);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(arr);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Converts krb5_fulladdr into a property of a JSON object.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
addr_to_value(const krb5_address *address, k5_json_object obj, const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object addr_obj = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (address == NULL)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = k5_json_object_create(&addr_obj);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
ret = addr_to_obj((krb5_address *)address, addr_obj);
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, addr_obj);
|
|
Packit |
fd8b60 |
k5_json_release(addr_obj);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Helper for JSON encoding of krb5_kdc_req.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
req_to_value(krb5_kdc_req *req, const krb5_boolean ev_success,
|
|
Packit |
fd8b60 |
k5_json_object obj)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_number num = NULL;
|
|
Packit |
fd8b60 |
k5_json_string str = NULL;
|
|
Packit |
fd8b60 |
k5_json_object tmpa = NULL;
|
|
Packit |
fd8b60 |
k5_json_array arr = NULL, arra = NULL, arrpa = NULL;
|
|
Packit |
fd8b60 |
krb5_pa_data **padata;
|
|
Packit |
fd8b60 |
int i = 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (req == NULL)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = princ_to_value(req->client, obj, AU_REQ_CLIENT);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = princ_to_value(req->server, obj, AU_REQ_SERVER);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
ret = int32_to_value(req->kdc_options, obj, AU_REQ_KDC_OPTIONS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(req->from, obj, AU_REQ_TKT_START);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(req->till, obj, AU_REQ_TKT_END);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(req->rtime, obj, AU_REQ_TKT_RENEW_TILL);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Available/requested enctypes. */
|
|
Packit |
fd8b60 |
ret = k5_json_array_create(&arr;;
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
for (i = 0; (i < req->nktypes); i++) {
|
|
Packit |
fd8b60 |
if (req->ktype[i] > 0) {
|
|
Packit |
fd8b60 |
ret = k5_json_number_create(req->ktype[i], &num);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_array_add(arr, num);
|
|
Packit |
fd8b60 |
k5_json_release(num);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, AU_REQ_AVAIL_ETYPES, arr);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Pre-auth types. */
|
|
Packit |
fd8b60 |
if (ev_success == TRUE && req->padata) {
|
|
Packit |
fd8b60 |
ret = k5_json_array_create(&arrpa);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
for (padata = req->padata; *padata; padata++) {
|
|
Packit |
fd8b60 |
if (strlen(map_patype((*padata)->pa_type)) > 1) {
|
|
Packit |
fd8b60 |
ret = k5_json_string_create(map_patype((*padata)->pa_type),
|
|
Packit |
fd8b60 |
&str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_array_add(arrpa, str);
|
|
Packit |
fd8b60 |
k5_json_release(str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, AU_REQ_PA_TYPE, arrpa);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* List of requested addresses. */
|
|
Packit |
fd8b60 |
if (req->addresses) {
|
|
Packit |
fd8b60 |
ret = k5_json_array_create(&arra);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
for (i = 0; req->addresses[i] != NULL; i++) {
|
|
Packit |
fd8b60 |
ret = k5_json_object_create(&tmpa);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = addr_to_obj(req->addresses[i], tmpa);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_array_add(arra, tmpa);
|
|
Packit |
fd8b60 |
k5_json_release(tmpa);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, AU_REQ_ADDRESSES, arra);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(arr);
|
|
Packit |
fd8b60 |
k5_json_release(arra);
|
|
Packit |
fd8b60 |
k5_json_release(arrpa);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Helper for JSON encoding of krb5_kdc_rep.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
rep_to_value(krb5_kdc_rep *rep, const krb5_boolean ev_success,
|
|
Packit |
fd8b60 |
k5_json_object obj)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
krb5_pa_data **padata;
|
|
Packit |
fd8b60 |
k5_json_array arrpa = NULL;
|
|
Packit |
fd8b60 |
k5_json_string str = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (rep == NULL)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (ev_success == TRUE) {
|
|
Packit |
fd8b60 |
ret = tkt_to_value(rep->ticket, obj, AU_REP_TICKET);
|
|
Packit |
fd8b60 |
/* Enctype of the reply-encrypting key. */
|
|
Packit |
fd8b60 |
ret = int32_to_value(rep->enc_part.enctype, obj, AU_REP_ETYPE);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (rep->padata) {
|
|
Packit |
fd8b60 |
ret = k5_json_array_create(&arrpa);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
for (padata = rep->padata; *padata; padata++) {
|
|
Packit |
fd8b60 |
if (strlen(map_patype((*padata)->pa_type)) > 1) {
|
|
Packit |
fd8b60 |
ret = k5_json_string_create(map_patype((*padata)->pa_type),
|
|
Packit |
fd8b60 |
&str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = k5_json_array_add(arrpa, str);
|
|
Packit |
fd8b60 |
k5_json_release(str);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, AU_REP_PA_TYPE, arrpa);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(arrpa);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Converts krb5_ticket into a property of a JSON object.
|
|
Packit |
fd8b60 |
* Returns 0 on success.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
static krb5_error_code
|
|
Packit |
fd8b60 |
tkt_to_value(krb5_ticket *tkt, k5_json_object obj,
|
|
Packit |
fd8b60 |
const char *key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
krb5_error_code ret = 0;
|
|
Packit |
fd8b60 |
k5_json_object tmp = NULL;
|
|
Packit |
fd8b60 |
krb5_enc_tkt_part *part2 = NULL;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (tkt == NULL)
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Main object. */
|
|
Packit |
fd8b60 |
if (k5_json_object_create(&tmp))
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* CNAME - potentially redundant data...
|
|
Packit |
fd8b60 |
* ...but it is part of the ticket. So, record it as such.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
ret = princ_to_value(tkt->server, tmp, AU_CNAME);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = princ_to_value(tkt->server, tmp, AU_SNAME);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Enctype of a long-term key of service. */
|
|
Packit |
fd8b60 |
if (tkt->enc_part.enctype)
|
|
Packit |
fd8b60 |
ret = int32_to_value(tkt->enc_part.enctype, tmp, AU_SRV_ETYPE);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
if (tkt->enc_part2)
|
|
Packit |
fd8b60 |
part2 = tkt->enc_part2;
|
|
Packit |
fd8b60 |
if (part2) {
|
|
Packit |
fd8b60 |
ret = princ_to_value(part2->client, tmp, AU_CNAME);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(part2->flags, tmp, AU_FLAGS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
/* Chosen by KDC session key enctype (short-term key). */
|
|
Packit |
fd8b60 |
ret = int32_to_value(part2->session->enctype, tmp, AU_SESS_ETYPE);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(part2->times.starttime, tmp, AU_START);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(part2->times.endtime, tmp, AU_END);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(part2->times.renew_till, tmp, AU_RENEW_TILL);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
ret = int32_to_value(part2->times.authtime, tmp, AU_AUTHTIME);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
if (part2->transited.tr_contents.length > 0) {
|
|
Packit |
fd8b60 |
ret = data_to_value(&part2->transited.tr_contents,
|
|
Packit |
fd8b60 |
tmp, AU_TR_CONTENTS);
|
|
Packit |
fd8b60 |
if (ret)
|
|
Packit |
fd8b60 |
goto error;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
} /* part2 != NULL */
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (!ret)
|
|
Packit |
fd8b60 |
ret = k5_json_object_set(obj, key, tmp);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
error:
|
|
Packit |
fd8b60 |
k5_json_release(tmp);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* Map preauth numeric type to the naming string. */
|
|
Packit |
fd8b60 |
struct _patype_str {
|
|
Packit |
fd8b60 |
krb5_preauthtype id;
|
|
Packit |
fd8b60 |
char *name;
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
struct _patype_str patype_str[] = {
|
|
Packit |
fd8b60 |
{KRB5_PADATA_ENC_TIMESTAMP, "ENC_TIMESTAMP"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_PW_SALT, "PW_SALT"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_ENC_UNIX_TIME, "ENC_UNIX_TIME"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_SAM_CHALLENGE, "SAM_CHALLENGE"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_SAM_RESPONSE, "SAM_RESPONSE"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_PK_AS_REQ_OLD, "PK_AS_REQ_OLD"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_PK_AS_REP_OLD, "PK_AS_REP_OLD"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_PK_AS_REQ, "PK_AS_REQ"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_PK_AS_REP, "PK_AS_REP"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_ETYPE_INFO2, "ETYPE_INFO2"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_SAM_CHALLENGE_2, "SAM_CHALLENGE_2"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_SAM_RESPONSE_2, "SAM_RESPONSE_2"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_PAC_REQUEST, "PAC_REQUEST"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_FOR_USER, "FOR_USER"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_S4U_X509_USER, "S4U_X509_USER"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_ENCRYPTED_CHALLENGE, "ENCRYPTED_CHALLENGE"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_OTP_CHALLENGE, "OTP_CHALLENGE"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_OTP_REQUEST, "OTP_REQUEST"},
|
|
Packit |
fd8b60 |
{KRB5_PADATA_OTP_PIN_CHANGE, "OTP_PIN_CHANGE"}
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static char *
|
|
Packit |
fd8b60 |
map_patype(krb5_preauthtype pa_type)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int i = 0;
|
|
Packit |
fd8b60 |
int n = sizeof(patype_str)/sizeof(patype_str[0]);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for (i = 0; i < n; i++) {
|
|
Packit |
fd8b60 |
if (pa_type == patype_str[i].id)
|
|
Packit |
fd8b60 |
return patype_str[i].name;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return "";
|
|
Packit |
fd8b60 |
}
|