Path: blob/main/crypto/krb5/src/plugins/audit/kdc_j_encode.c
34878 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* plugins/audit/kdc_j_encode.c - Utilities to json encode KDC audit stuff */2/*3* Copyright (C) 2013 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9*10* * Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in15* the documentation and/or other materials provided with the16* distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS21* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE22* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,23* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES24* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR25* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,27* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED29* OF THE POSSIBILITY OF SUCH DAMAGE.30*/3132#include <k5-int.h>33#include <k5-json.h>34#include "kdc_j_encode.h"35#include "j_dict.h"36#include <krb5/audit_plugin.h>37#include <syslog.h>3839static krb5_error_code40string_to_value(const char *in, k5_json_object obj, const char *key);41static krb5_error_code42princ_to_value(krb5_principal princ, k5_json_object obj, const char *key);43static krb5_error_code44data_to_value(krb5_data *data, k5_json_object obj, const char *key);45static krb5_error_code46int32_to_value(krb5_int32 int32, k5_json_object obj, const char *key);47static krb5_error_code48bool_to_value(krb5_boolean b, k5_json_object obj, const char *key);49static krb5_error_code50addr_to_obj(krb5_address *a, k5_json_object obj);51static krb5_error_code52eventinfo_to_value(k5_json_object obj, const char *name,53const int stage, const krb5_boolean ev_success);54static krb5_error_code55addr_to_value(const krb5_address *address, k5_json_object obj,56const char *key);57static krb5_error_code58req_to_value(krb5_kdc_req *req, const krb5_boolean ev_success,59k5_json_object obj);60static krb5_error_code61rep_to_value(krb5_kdc_rep *rep, const krb5_boolean ev_success,62k5_json_object obj);63static krb5_error_code64tkt_to_value(krb5_ticket *tkt, k5_json_object obj, const char *key);65static char *map_patype(krb5_preauthtype pa_type);6667#define NULL_STATE "state is NULL"68#define T_RENEWED 169#define T_NOT_RENEWED 270#define T_VALIDATED 171#define T_NOT_VALIDATED 27273/* KDC server STOP. Returns 0 on success. */74krb5_error_code75kau_j_kdc_stop(const krb5_boolean ev_success, char **jout)76{77krb5_error_code ret = 0;78k5_json_object obj = NULL;7980*jout = NULL;8182/* Main object. */83if (k5_json_object_create(&obj))84return ENOMEM;8586/* Audit event_ID and ev_success. */87ret = string_to_value("KDC_STOP", obj, AU_EVENT_NAME);88if (!ret)89ret = bool_to_value(ev_success, obj, AU_EVENT_STATUS);90if (!ret)91ret = k5_json_encode(obj, jout);92k5_json_release(obj);9394return ret;95}9697/* KDC server START. Returns 0 on success. */98krb5_error_code99kau_j_kdc_start(const krb5_boolean ev_success, char **jout)100{101krb5_error_code ret = 0;102k5_json_object obj = NULL;103104*jout = NULL;105106/* Main object. */107if (k5_json_object_create(&obj))108return ENOMEM;109110/* Audit event_ID and ev_success. */111ret = string_to_value("KDC_START", obj, AU_EVENT_NAME);112if (!ret)113ret = bool_to_value(ev_success, obj, AU_EVENT_STATUS);114if (!ret)115ret = k5_json_encode(obj, jout);116k5_json_release(obj);117118return ret;119}120121/* AS-REQ. Returns 0 on success. */122krb5_error_code123kau_j_as_req(const krb5_boolean ev_success, krb5_audit_state *state,124char **jout)125{126krb5_error_code ret = 0;127k5_json_object obj = NULL;128129*jout = NULL;130131if (!state) {132*jout = NULL_STATE;133return 0;134}135136/* Main object. */137if (k5_json_object_create(&obj))138return ENOMEM;139/* Audit event_ID and ev_success. */140ret = eventinfo_to_value(obj, "AS_REQ", state->stage, ev_success);141if (ret)142goto error;143/* TGT ticket ID */144ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);145if (ret)146goto error;147/* Request ID. */148ret = string_to_value(state->req_id, obj, AU_REQ_ID);149if (ret)150goto error;151/* Client's port and address. */152ret = int32_to_value(state->cl_port, obj, AU_FROMPORT);153if (ret)154goto error;155ret = addr_to_value(state->cl_addr, obj, AU_FROMADDR);156if (ret)157goto error;158/* KDC status msg */159ret = string_to_value(state->status, obj, AU_KDC_STATUS);160if (ret)161goto error;162/* non-local client's referral realm. */163ret = data_to_value(state->cl_realm, obj, AU_CREF_REALM);164if (ret)165goto error;166/* Request. */167ret = req_to_value(state->request, ev_success, obj);168if (ret == ENOMEM)169goto error;170/* Reply/ticket info. */171ret = rep_to_value(state->reply, ev_success, obj);172if (ret == ENOMEM)173goto error;174ret = k5_json_encode(obj, jout);175176error:177k5_json_release(obj);178return ret;179}180181/* TGS-REQ. Returns 0 on success. */182krb5_error_code183kau_j_tgs_req(const krb5_boolean ev_success, krb5_audit_state *state,184char **jout)185{186krb5_error_code ret = 0;187k5_json_object obj = NULL;188krb5_kdc_req *req = state->request;189int tkt_validated = 0, tkt_renewed = 0;190191*jout = NULL;192193if (!state) {194*jout = NULL_STATE;195return 0;196}197198/* Main object. */199if (k5_json_object_create(&obj))200return ENOMEM;201202/* Audit Event ID and ev_success. */203ret = eventinfo_to_value(obj, "TGS_REQ", state->stage, ev_success);204if (ret)205goto error;206/* Primary and derived ticket IDs. */207ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);208if (ret)209goto error;210ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);211if (ret)212goto error;213/* Request ID */214ret = string_to_value(state->req_id, obj, AU_REQ_ID);215if (ret)216goto error;217/* client’s address and port. */218ret = int32_to_value(state->cl_port, obj, AU_FROMPORT);219if (ret)220goto error;221ret = addr_to_value(state->cl_addr, obj, AU_FROMADDR);222if (ret)223goto error;224/* Ticket was renewed, validated. */225if ((ev_success == TRUE) && (req != NULL)) {226tkt_renewed = (req->kdc_options & KDC_OPT_RENEW) ?227T_RENEWED : T_NOT_RENEWED;228tkt_validated = (req->kdc_options & KDC_OPT_VALIDATE) ?229T_VALIDATED : T_NOT_VALIDATED;230}231ret = int32_to_value(tkt_renewed, obj, AU_TKT_RENEWED);232if (ret)233goto error;234ret = int32_to_value(tkt_validated, obj, AU_TKT_VALIDATED);235if (ret)236goto error;237/* KDC status msg, including "ISSUE". */238ret = string_to_value(state->status, obj, AU_KDC_STATUS);239if (ret)240goto error;241/* request */242ret = req_to_value(req, ev_success, obj);243if (ret == ENOMEM)244goto error;245/* reply/ticket */246ret = rep_to_value(state->reply, ev_success, obj);247if (ret == ENOMEM)248goto error;249ret = k5_json_encode(obj, jout);250251error:252k5_json_release(obj);253return ret;254}255256/* S4U2Self protocol extension. Returns 0 on success. */257krb5_error_code258kau_j_tgs_s4u2self(const krb5_boolean ev_success, krb5_audit_state *state,259char **jout)260{261krb5_error_code ret = 0;262k5_json_object obj = NULL;263264*jout = NULL;265266if (!state) {267*jout = NULL_STATE;268return 0;269}270271/* Main object. */272if (k5_json_object_create(&obj))273return ENOMEM;274275/* Audit Event ID and ev_success. */276ret = eventinfo_to_value(obj, "S4U2SELF", state->stage, ev_success);277if (ret)278goto error;279/* Front-end server's TGT ticket ID. */280ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);281if (ret)282goto error;283/* service "to self" ticket or referral TGT ticket ID. */284ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);285if (ret)286goto error;287/* Request ID. */288ret = string_to_value(state->req_id, obj, AU_REQ_ID);289if (ret)290goto error;291if (ev_success == FALSE) {292/* KDC status msg. */293ret = string_to_value(state->status, obj, AU_KDC_STATUS);294if (ret)295goto error;296/* Local policy or S4U protocol constraints. */297ret = int32_to_value(state->violation, obj, AU_VIOLATION);298if (ret)299goto error;300}301/* Impersonated user. */302ret = princ_to_value(state->s4u2self_user, obj, AU_REQ_S4U2S_USER);303if (ret)304goto error;305306ret = k5_json_encode(obj, jout);307308error:309k5_json_release(obj);310return ret;311}312313/* S4U2Proxy protocol extension. Returns 0 on success. */314krb5_error_code315kau_j_tgs_s4u2proxy(const krb5_boolean ev_success, krb5_audit_state *state,316char **jout)317{318krb5_error_code ret = 0;319k5_json_object obj = NULL;320krb5_kdc_req *req = state->request;321322*jout = NULL;323324if (!state) {325*jout = NULL_STATE;326return 0;327}328329/* Main object. */330if (k5_json_object_create(&obj))331return ENOMEM;332333/* Audit Event ID and ev_success. */334ret = eventinfo_to_value(obj, "S4U2PROXY", state->stage, ev_success);335if (ret)336goto error;337/* Front-end server's TGT ticket ID. */338ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);339if (ret)340goto error;341/* Resource service or referral TGT ticket ID. */342ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);343if (ret)344goto error;345/* User's evidence ticket ID. */346ret = string_to_value(state->evid_tkt_id, obj, AU_EVIDENCE_TKT_ID);347if (ret)348goto error;349/* Request ID. */350ret = string_to_value(state->req_id, obj, AU_REQ_ID);351if (ret)352goto error;353354if (ev_success == FALSE) {355/* KDC status msg. */356ret = string_to_value(state->status, obj, AU_KDC_STATUS);357if (ret)358goto error;359/* Local policy or S4U protocol constraints. */360ret = int32_to_value(state->violation, obj, AU_VIOLATION);361if (ret)362goto error;363}364/* Delegated user. */365if (req != NULL) {366ret = princ_to_value(req->second_ticket[0]->enc_part2->client,367obj, AU_REQ_S4U2P_USER);368if (ret)369goto error;370}371ret = k5_json_encode(obj, jout);372373error:374k5_json_release(obj);375return ret;376}377378/* U2U. Returns 0 on success. */379krb5_error_code380kau_j_tgs_u2u(const krb5_boolean ev_success, krb5_audit_state *state,381char **jout)382{383krb5_error_code ret = 0;384k5_json_object obj = NULL;385krb5_kdc_req *req = state->request;386387if (!state) {388*jout = NULL_STATE;389return 0;390}391392*jout = NULL;393394/* Main object. */395if (k5_json_object_create(&obj))396return ENOMEM;397/* Audit Event ID and ev_success. */398ret = eventinfo_to_value(obj, "U2U", state->stage, ev_success);399if (ret)400goto error;401/* Front-end server's TGT ticket ID. */402ret = string_to_value(state->tkt_in_id, obj, AU_TKT_IN_ID);403if (ret)404goto error;405/* Service ticket ID. */406ret = string_to_value(state->tkt_out_id, obj, AU_TKT_OUT_ID);407if (ret)408goto error;409/* Request ID. */410ret = string_to_value(state->req_id, obj, AU_REQ_ID);411if (ret)412goto error;413414if (ev_success == FALSE) {415/* KDC status msg. */416ret = string_to_value(state->status, obj, AU_KDC_STATUS);417if (ret)418goto error;419}420/* Client in the second ticket. */421ret = princ_to_value(req->second_ticket[0]->enc_part2->client,422obj, AU_REQ_U2U_USER);423if (ret)424goto error;425/* Enctype of a session key of the second ticket. */426ret = int32_to_value(req->second_ticket[0]->enc_part2->session->enctype,427obj, AU_SRV_ETYPE);428if (ret)429goto error;430431ret = k5_json_encode(obj, jout);432433error:434k5_json_release(obj);435return ret;436}437438/* Low level utilities */439440/* Converts string into a property of a JSON object. Returns 0 on success.*/441static krb5_error_code442string_to_value(const char *in, k5_json_object obj, const char *key)443{444krb5_error_code ret = 0;445k5_json_string str = NULL;446447if (in == NULL)448return 0;449450ret = k5_json_string_create(in, &str);451if (ret)452return ret;453ret = k5_json_object_set(obj, key, str);454k5_json_release(str);455456return ret;457}458459/*460* Converts a krb5_data struct into a property of a JSON object.461* (Borrowed from preauth_otp.c)462* Returns 0 on success.463*/464static krb5_error_code465data_to_value(krb5_data *data, k5_json_object obj, const char *key)466{467krb5_error_code ret = 0;468k5_json_string str = NULL;469470if (data == NULL || data->data == NULL || data->length < 1)471return 0;472473ret = k5_json_string_create_len(data->data, data->length, &str);474if (ret)475return ret;476ret = k5_json_object_set(obj, key, str);477k5_json_release(str);478479return ret;480}481482/*483* Converts krb5_int32 into a property of a JSON object.484* Returns 0 on success.485*/486static krb5_error_code487int32_to_value(krb5_int32 int32, k5_json_object obj, const char *key)488{489krb5_error_code ret = 0;490k5_json_number num = NULL;491492ret = k5_json_number_create(int32, &num);493if (ret)494return ENOMEM;495ret = k5_json_object_set(obj, key, num);496k5_json_release(num);497498return ret;499}500501/*502* Converts krb5_boolean into a property of a JSON object.503* Returns 0 on success.504*/505static krb5_error_code506bool_to_value(krb5_boolean in, k5_json_object obj, const char *key)507{508krb5_error_code ret = 0;509k5_json_bool b = 0;510511ret = k5_json_bool_create(in, &b);512if (ret)513return ENOMEM;514515ret = k5_json_object_set(obj, key, b);516k5_json_release(b);517518return ret;519}520521/* Wrapper-level utilities */522523/* Wrapper for stage and event_status tags. Returns 0 on success. */524static krb5_error_code525eventinfo_to_value(k5_json_object obj, const char *name,526const int stage, const krb5_boolean ev_success)527{528krb5_error_code ret = 0;529530ret = string_to_value(name, obj, AU_EVENT_NAME);531if (ret)532return ret;533ret = int32_to_value(stage, obj, AU_STAGE);534if (!ret)535ret = bool_to_value(ev_success, obj, AU_EVENT_STATUS);536537return ret;538}539540/*541* Converts krb5_principal into a property of a JSON object.542* Returns 0 on success.543*/544static krb5_error_code545princ_to_value(krb5_principal princ, k5_json_object obj, const char *key)546{547krb5_error_code ret = 0;548k5_json_object tmp = NULL;549k5_json_array arr = NULL;550k5_json_string str = NULL;551int i = 0;552553if (princ == NULL || princ->data == NULL)554return 0;555556/* Main object. */557if (k5_json_object_create(&tmp))558return ENOMEM;559560ret = k5_json_array_create(&arr);561if (ret)562goto error;563for (i = 0; i < princ->length; i++) {564ret = k5_json_string_create_len((&princ->data[i])->data,565(&princ->data[i])->length, &str);566if (ret)567goto error;568ret = k5_json_array_add(arr, str);569k5_json_release(str);570if (ret)571goto error;572}573ret = k5_json_object_set(tmp, AU_COMPONENTS, arr);574if (ret)575goto error;576ret = data_to_value(&princ->realm, tmp, AU_REALM);577if (ret)578goto error;579ret = int32_to_value(princ->length, tmp, AU_LENGTH);580if (ret)581goto error;582ret = int32_to_value(princ->type, tmp, AU_TYPE);583if (ret)584goto error;585586ret = k5_json_object_set(obj, key, tmp);587588error:589k5_json_release(tmp);590k5_json_release(arr);591return ret;592}593594/*595* Helper for JSON encoding of krb5_address.596* Returns 0 on success.597*/598static krb5_error_code599addr_to_obj(krb5_address *a, k5_json_object obj)600{601krb5_error_code ret = 0;602k5_json_number num = NULL;603k5_json_array arr = NULL;604int i;605606if (a == NULL || a->contents == NULL || a->length <= 0)607return 0;608609ret = int32_to_value(a->addrtype, obj, AU_TYPE);610if (ret)611goto error;612ret = int32_to_value(a->length, obj, AU_LENGTH);613if (ret)614goto error;615616if (a->addrtype == ADDRTYPE_INET || a->addrtype == ADDRTYPE_INET6) {617ret = k5_json_array_create(&arr);618if (ret)619goto error;620for (i = 0; i < (int)a->length; i++) {621ret = k5_json_number_create(a->contents[i], &num);622if (ret)623goto error;624ret = k5_json_array_add(arr, num);625k5_json_release(num);626if (ret)627goto error;628}629ret = k5_json_object_set(obj, AU_IP, arr);630if (ret)631goto error;632} else if (a->addrtype == ADDRTYPE_UNIXSOCK) {633k5_json_string str = NULL;634635ret = k5_json_string_create_len(a->contents, a->length, &str);636if (ret)637return ret;638639ret = k5_json_object_set(obj, AU_PATH, str);640k5_json_release(str);641if (ret)642goto error;643}644645error:646k5_json_release(arr);647return ret;648}649650/*651* Converts krb5_fulladdr into a property of a JSON object.652* Returns 0 on success.653*/654static krb5_error_code655addr_to_value(const krb5_address *address, k5_json_object obj, const char *key)656{657krb5_error_code ret = 0;658k5_json_object addr_obj = NULL;659660if (address == NULL)661return 0;662663ret = k5_json_object_create(&addr_obj);664if (ret)665return ret;666ret = addr_to_obj((krb5_address *)address, addr_obj);667if (!ret)668ret = k5_json_object_set(obj, key, addr_obj);669k5_json_release(addr_obj);670671return ret;672}673674/*675* Helper for JSON encoding of krb5_kdc_req.676* Returns 0 on success.677*/678static krb5_error_code679req_to_value(krb5_kdc_req *req, const krb5_boolean ev_success,680k5_json_object obj)681{682krb5_error_code ret = 0;683k5_json_number num = NULL;684k5_json_string str = NULL;685k5_json_object tmpa = NULL;686k5_json_array arr = NULL, arra = NULL, arrpa = NULL;687krb5_pa_data **padata;688int i = 0;689690if (req == NULL)691return 0;692693ret = princ_to_value(req->client, obj, AU_REQ_CLIENT);694if (ret)695goto error;696ret = princ_to_value(req->server, obj, AU_REQ_SERVER);697if (ret)698goto error;699700ret = int32_to_value(req->kdc_options, obj, AU_REQ_KDC_OPTIONS);701if (ret)702goto error;703ret = int32_to_value(req->from, obj, AU_REQ_TKT_START);704if (ret)705goto error;706ret = int32_to_value(req->till, obj, AU_REQ_TKT_END);707if (ret)708goto error;709ret = int32_to_value(req->rtime, obj, AU_REQ_TKT_RENEW_TILL);710if (ret)711goto error;712/* Available/requested enctypes. */713ret = k5_json_array_create(&arr);714if (ret)715goto error;716for (i = 0; (i < req->nktypes); i++) {717if (req->ktype[i] > 0) {718ret = k5_json_number_create(req->ktype[i], &num);719if (ret)720goto error;721ret = k5_json_array_add(arr, num);722k5_json_release(num);723if (ret)724goto error;725}726}727ret = k5_json_object_set(obj, AU_REQ_AVAIL_ETYPES, arr);728if (ret)729goto error;730/* Pre-auth types. */731if (ev_success == TRUE && req->padata) {732ret = k5_json_array_create(&arrpa);733if (ret)734goto error;735for (padata = req->padata; *padata; padata++) {736if (strlen(map_patype((*padata)->pa_type)) > 1) {737ret = k5_json_string_create(map_patype((*padata)->pa_type),738&str);739if (ret)740goto error;741ret = k5_json_array_add(arrpa, str);742k5_json_release(str);743if (ret)744goto error;745}746}747ret = k5_json_object_set(obj, AU_REQ_PA_TYPE, arrpa);748}749/* List of requested addresses. */750if (req->addresses) {751ret = k5_json_array_create(&arra);752if (ret)753goto error;754for (i = 0; req->addresses[i] != NULL; i++) {755ret = k5_json_object_create(&tmpa);756if (ret)757goto error;758ret = addr_to_obj(req->addresses[i], tmpa);759if (!ret)760ret = k5_json_array_add(arra, tmpa);761k5_json_release(tmpa);762if (ret)763goto error;764}765ret = k5_json_object_set(obj, AU_REQ_ADDRESSES, arra);766if (ret)767goto error;768}769error:770k5_json_release(arr);771k5_json_release(arra);772k5_json_release(arrpa);773return ret;774}775776/*777* Helper for JSON encoding of krb5_kdc_rep.778* Returns 0 on success.779*/780static krb5_error_code781rep_to_value(krb5_kdc_rep *rep, const krb5_boolean ev_success,782k5_json_object obj)783{784krb5_error_code ret = 0;785krb5_pa_data **padata;786k5_json_array arrpa = NULL;787k5_json_string str = NULL;788789if (rep == NULL)790return 0;791792if (ev_success == TRUE) {793ret = tkt_to_value(rep->ticket, obj, AU_REP_TICKET);794/* Enctype of the reply-encrypting key. */795ret = int32_to_value(rep->enc_part.enctype, obj, AU_REP_ETYPE);796if (ret)797goto error;798} else {799800if (rep->padata) {801ret = k5_json_array_create(&arrpa);802if (ret)803goto error;804for (padata = rep->padata; *padata; padata++) {805if (strlen(map_patype((*padata)->pa_type)) > 1) {806ret = k5_json_string_create(map_patype((*padata)->pa_type),807&str);808if (ret)809goto error;810ret = k5_json_array_add(arrpa, str);811k5_json_release(str);812if (ret)813goto error;814}815}816}817ret = k5_json_object_set(obj, AU_REP_PA_TYPE, arrpa);818}819error:820k5_json_release(arrpa);821return ret;822}823824/*825* Converts krb5_ticket into a property of a JSON object.826* Returns 0 on success.827*/828static krb5_error_code829tkt_to_value(krb5_ticket *tkt, k5_json_object obj,830const char *key)831{832krb5_error_code ret = 0;833k5_json_object tmp = NULL;834krb5_enc_tkt_part *part2 = NULL;835836if (tkt == NULL)837return 0;838839/* Main object. */840if (k5_json_object_create(&tmp))841return ENOMEM;842843/*844* CNAME - potentially redundant data...845* ...but it is part of the ticket. So, record it as such.846*/847ret = princ_to_value(tkt->server, tmp, AU_CNAME);848if (ret)849goto error;850ret = princ_to_value(tkt->server, tmp, AU_SNAME);851if (ret)852goto error;853/* Enctype of a long-term key of service. */854if (tkt->enc_part.enctype)855ret = int32_to_value(tkt->enc_part.enctype, tmp, AU_SRV_ETYPE);856if (ret)857goto error;858if (tkt->enc_part2)859part2 = tkt->enc_part2;860if (part2) {861ret = princ_to_value(part2->client, tmp, AU_CNAME);862if (ret)863goto error;864ret = int32_to_value(part2->flags, tmp, AU_FLAGS);865if (ret)866goto error;867/* Chosen by KDC session key enctype (short-term key). */868ret = int32_to_value(part2->session->enctype, tmp, AU_SESS_ETYPE);869if (ret)870goto error;871ret = int32_to_value(part2->times.starttime, tmp, AU_START);872if (ret)873goto error;874ret = int32_to_value(part2->times.endtime, tmp, AU_END);875if (ret)876goto error;877ret = int32_to_value(part2->times.renew_till, tmp, AU_RENEW_TILL);878if (ret)879goto error;880ret = int32_to_value(part2->times.authtime, tmp, AU_AUTHTIME);881if (ret)882goto error;883if (part2->transited.tr_contents.length > 0) {884ret = data_to_value(&part2->transited.tr_contents,885tmp, AU_TR_CONTENTS);886if (ret)887goto error;888}889} /* part2 != NULL */890891if (!ret)892ret = k5_json_object_set(obj, key, tmp);893894error:895k5_json_release(tmp);896return ret;897}898899/* Map preauth numeric type to the naming string. */900struct _patype_str {901krb5_preauthtype id;902char *name;903};904struct _patype_str patype_str[] = {905{KRB5_PADATA_ENC_TIMESTAMP, "ENC_TIMESTAMP"},906{KRB5_PADATA_PW_SALT, "PW_SALT"},907{KRB5_PADATA_ENC_UNIX_TIME, "ENC_UNIX_TIME"},908{KRB5_PADATA_SAM_CHALLENGE, "SAM_CHALLENGE"},909{KRB5_PADATA_SAM_RESPONSE, "SAM_RESPONSE"},910{KRB5_PADATA_PK_AS_REQ_OLD, "PK_AS_REQ_OLD"},911{KRB5_PADATA_PK_AS_REP_OLD, "PK_AS_REP_OLD"},912{KRB5_PADATA_PK_AS_REQ, "PK_AS_REQ"},913{KRB5_PADATA_PK_AS_REP, "PK_AS_REP"},914{KRB5_PADATA_ETYPE_INFO2, "ETYPE_INFO2"},915{KRB5_PADATA_SAM_CHALLENGE_2, "SAM_CHALLENGE_2"},916{KRB5_PADATA_SAM_RESPONSE_2, "SAM_RESPONSE_2"},917{KRB5_PADATA_PAC_REQUEST, "PAC_REQUEST"},918{KRB5_PADATA_FOR_USER, "FOR_USER"},919{KRB5_PADATA_S4U_X509_USER, "S4U_X509_USER"},920{KRB5_PADATA_ENCRYPTED_CHALLENGE, "ENCRYPTED_CHALLENGE"},921{KRB5_PADATA_OTP_CHALLENGE, "OTP_CHALLENGE"},922{KRB5_PADATA_OTP_REQUEST, "OTP_REQUEST"},923{KRB5_PADATA_OTP_PIN_CHANGE, "OTP_PIN_CHANGE"}924};925926927static char *928map_patype(krb5_preauthtype pa_type)929{930int i = 0;931int n = sizeof(patype_str)/sizeof(patype_str[0]);932933for (i = 0; i < n; i++) {934if (pa_type == patype_str[i].id)935return patype_str[i].name;936}937return "";938}939940941