Date: Fri, 01 May 2026 00:11:37 +0000 From: Cy Schubert <cy@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 736e411a737b - main - krb5: import MIT 1.22.2 Message-ID: <69f3efb9.308ec.599addf5@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by cy: URL: https://cgit.FreeBSD.org/src/commit/?id=736e411a737b9f57c1303e6d15c5afd4f63af0d3 commit 736e411a737b9f57c1303e6d15c5afd4f63af0d3 Merge: 6a0610cb5018 90c687295e2d Author: Cy Schubert <cy@FreeBSD.org> AuthorDate: 2026-04-30 19:24:20 +0000 Commit: Cy Schubert <cy@FreeBSD.org> CommitDate: 2026-05-01 00:10:53 +0000 krb5: import MIT 1.22.2 Merge commit '90c687295e2d62f9411fc5b571f5af4e8ee187a7' crypto/krb5/NOTICE | 2 +- crypto/krb5/README | 24 +++++++++++++++- crypto/krb5/src/configure | 20 ++++++------- crypto/krb5/src/lib/gssapi/krb5/acquire_cred.c | 1 + crypto/krb5/src/lib/gssapi/krb5/iakerb.c | 1 + crypto/krb5/src/lib/gssapi/spnego/spnego_mech.c | 2 +- crypto/krb5/src/lib/krad/packet.c | 2 +- crypto/krb5/src/lib/krb5/ccache/cc_file.c | 8 ++++++ crypto/krb5/src/lib/krb5/ccache/cc_mslsa.c | 37 ++++++++++--------------- crypto/krb5/src/man/k5identity.man | 4 +-- crypto/krb5/src/man/k5login.man | 4 +-- crypto/krb5/src/man/k5srvutil.man | 4 +-- crypto/krb5/src/man/kadm5.acl.man | 4 +-- crypto/krb5/src/man/kadmin.man | 4 +-- crypto/krb5/src/man/kadmind.man | 4 +-- crypto/krb5/src/man/kdb5_ldap_util.man | 4 +-- crypto/krb5/src/man/kdb5_util.man | 4 +-- crypto/krb5/src/man/kdc.conf.man | 4 +-- crypto/krb5/src/man/kdestroy.man | 4 +-- crypto/krb5/src/man/kerberos.man | 4 +-- crypto/krb5/src/man/kinit.man | 4 +-- crypto/krb5/src/man/klist.man | 4 +-- crypto/krb5/src/man/kpasswd.man | 4 +-- crypto/krb5/src/man/kprop.man | 4 +-- crypto/krb5/src/man/kpropd.man | 4 +-- crypto/krb5/src/man/kproplog.man | 4 +-- crypto/krb5/src/man/krb5-config.man | 4 +-- crypto/krb5/src/man/krb5.conf.man | 4 +-- crypto/krb5/src/man/krb5kdc.man | 4 +-- crypto/krb5/src/man/ksu.man | 4 +-- crypto/krb5/src/man/kswitch.man | 4 +-- crypto/krb5/src/man/ktutil.man | 4 +-- crypto/krb5/src/man/kvno.man | 4 +-- crypto/krb5/src/man/sclient.man | 4 +-- crypto/krb5/src/man/sserver.man | 4 +-- crypto/krb5/src/patchlevel.h | 6 ++-- crypto/krb5/src/po/mit-krb5.pot | 4 +-- crypto/krb5/src/prototype/prototype.c | 2 +- crypto/krb5/src/prototype/prototype.h | 2 +- crypto/krb5/src/windows/version.rc | 2 +- 40 files changed, 120 insertions(+), 97 deletions(-) diff --cc crypto/krb5/src/lib/krad/packet.c index ed19385f71a6,000000000000..22128350428c mode 100644,000000..100644 --- a/crypto/krb5/src/lib/krad/packet.c +++ b/crypto/krb5/src/lib/krad/packet.c @@@ -1,645 -1,0 +1,645 @@@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/krad/packet.c - Packet functions for libkrad */ +/* + * Copyright 2013 Red Hat, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "internal.h" + +#include <string.h> + +#include <arpa/inet.h> + +typedef unsigned char uchar; + +/* RFC 2865 */ +#define MSGAUTH_SIZE (2 + MD5_DIGEST_SIZE) +#define OFFSET_CODE 0 +#define OFFSET_ID 1 +#define OFFSET_LENGTH 2 +#define OFFSET_AUTH 4 +#define OFFSET_ATTR 20 +#define AUTH_FIELD_SIZE (OFFSET_ATTR - OFFSET_AUTH) + +#define offset(d, o) (&(d)->data[o]) +#define pkt_code_get(p) (*(krad_code *)offset(&(p)->pkt, OFFSET_CODE)) +#define pkt_code_set(p, v) (*(krad_code *)offset(&(p)->pkt, OFFSET_CODE)) = v +#define pkt_id_get(p) (*(uchar *)offset(&(p)->pkt, OFFSET_ID)) +#define pkt_id_set(p, v) (*(uchar *)offset(&(p)->pkt, OFFSET_ID)) = v +#define pkt_len_get(p) load_16_be(offset(&(p)->pkt, OFFSET_LENGTH)) +#define pkt_len_set(p, v) store_16_be(v, offset(&(p)->pkt, OFFSET_LENGTH)) +#define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH)) +#define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR)) + +struct krad_packet_st { + char buffer[KRAD_PACKET_SIZE_MAX]; + krad_attrset *attrset; + krb5_data pkt; +}; + +typedef struct { + uchar x[(UCHAR_MAX + 1) / 8]; +} idmap; + +/* Ensure the map is empty. */ +static inline void +idmap_init(idmap *map) +{ + memset(map, 0, sizeof(*map)); +} + +/* Set an id as already allocated. */ +static inline void +idmap_set(idmap *map, uchar id) +{ + map->x[id / 8] |= 1 << (id % 8); +} + +/* Determine whether or not an id is used. */ +static inline krb5_boolean +idmap_isset(const idmap *map, uchar id) +{ + return (map->x[id / 8] & (1 << (id % 8))) != 0; +} + +/* Find an unused id starting the search at the value specified in id. + * NOTE: For optimal security, the initial value of id should be random. */ +static inline krb5_error_code +idmap_find(const idmap *map, uchar *id) +{ + krb5_int16 i; + + for (i = *id; i >= 0 && i <= UCHAR_MAX; (*id % 2 == 0) ? i++ : i--) { + if (!idmap_isset(map, i)) + goto success; + } + + for (i = *id; i >= 0 && i <= UCHAR_MAX; (*id % 2 == 1) ? i++ : i--) { + if (!idmap_isset(map, i)) + goto success; + } + + return ERANGE; + +success: + *id = i; + return 0; +} + +/* Generate size bytes of random data into the buffer. */ +static inline krb5_error_code +randomize(krb5_context ctx, void *buffer, unsigned int size) +{ + krb5_data rdata = make_data(buffer, size); + return krb5_c_random_make_octets(ctx, &rdata); +} + +/* Generate a radius packet id. */ +static krb5_error_code +id_generate(krb5_context ctx, krad_packet_iter_cb cb, void *data, uchar *id) +{ + krb5_error_code retval; + const krad_packet *tmp; + idmap used; + uchar i; + + retval = randomize(ctx, &i, sizeof(i)); + if (retval != 0) { + if (cb != NULL) + (*cb)(data, TRUE); + return retval; + } + + if (cb != NULL) { + idmap_init(&used); + for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) + idmap_set(&used, tmp->pkt.data[1]); + + retval = idmap_find(&used, &i); + if (retval != 0) + return retval; + } + + *id = i; + return 0; +} + +/* Generate a random authenticator field. */ +static krb5_error_code +auth_generate_random(krb5_context ctx, uchar *rauth) +{ + krb5_ui_4 trunctime; + time_t currtime; + + /* Get the least-significant four bytes of the current time. */ + currtime = time(NULL); + if (currtime == (time_t)-1) + return errno; + trunctime = (krb5_ui_4)currtime; + memcpy(rauth, &trunctime, sizeof(trunctime)); + + /* Randomize the rest of the buffer. */ + return randomize(ctx, rauth + sizeof(trunctime), + AUTH_FIELD_SIZE - sizeof(trunctime)); +} + +/* Generate a response authenticator field. */ +static krb5_error_code +auth_generate_response(krb5_context ctx, const char *secret, + const krad_packet *response, const uchar *auth, + uchar *rauth) +{ + krb5_error_code retval; + krb5_checksum hash; + krb5_data data; + + /* Allocate the temporary buffer. */ + retval = alloc_data(&data, response->pkt.length + strlen(secret)); + if (retval != 0) + return retval; + + /* Encoded RADIUS packet with the request's + * authenticator and the secret at the end. */ + memcpy(data.data, response->pkt.data, response->pkt.length); + memcpy(data.data + OFFSET_AUTH, auth, AUTH_FIELD_SIZE); + memcpy(data.data + response->pkt.length, secret, strlen(secret)); + + /* Hash it. */ + retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data, + &hash); + free(data.data); + if (retval != 0) + return retval; + + memcpy(rauth, hash.contents, AUTH_FIELD_SIZE); + krb5_free_checksum_contents(ctx, &hash); + return 0; +} + +/* Create a new packet. */ +static krad_packet * +packet_new(void) +{ + krad_packet *pkt; + + pkt = calloc(1, sizeof(krad_packet)); + if (pkt == NULL) + return NULL; + pkt->pkt = make_data(pkt->buffer, sizeof(pkt->buffer)); + + return pkt; +} + +/* Set the attrset object by decoding the packet. */ +static krb5_error_code +packet_set_attrset(krb5_context ctx, const char *secret, krad_packet *pkt) +{ + krb5_data tmp; + + tmp = make_data(pkt_attr(pkt), pkt->pkt.length - OFFSET_ATTR); + return kr_attrset_decode(ctx, &tmp, secret, pkt_auth(pkt), &pkt->attrset); +} + +/* Determine if a packet requires a Message-Authenticator attribute. */ +static inline krb5_boolean +requires_msgauth(const char *secret, krad_code code) +{ + /* If no secret is provided, assume that the transport is a UNIX socket. + * Message-Authenticator is required only on UDP and TCP connections. */ + if (*secret == '\0') + return FALSE; + + /* + * Per draft-ietf-radext-deprecating-radius-03 sections 5.2.1 and 5.2.4, + * Message-Authenticator is required in Access-Request packets and all + * potential responses when UDP or TCP transport is used. + */ + return code == KRAD_CODE_ACCESS_REQUEST || + code == KRAD_CODE_ACCESS_ACCEPT || code == KRAD_CODE_ACCESS_REJECT || + code == KRAD_CODE_ACCESS_CHALLENGE; +} + +/* Check if the packet has a Message-Authenticator attribute. */ +static inline krb5_boolean +has_pkt_msgauth(const krad_packet *pkt) +{ + return krad_attrset_get(pkt->attrset, KRAD_ATTR_MESSAGE_AUTHENTICATOR, + 0) != NULL; +} + +/* Return the beginning of the Message-Authenticator attribute in pkt, or NULL + * if no such attribute is present. */ +static const uint8_t * +lookup_msgauth_addr(const krad_packet *pkt) +{ + size_t i; + uint8_t *p; + + i = OFFSET_ATTR; + while (i + 2 < pkt->pkt.length) { + p = (uint8_t *)offset(&pkt->pkt, i); + if (*p == KRAD_ATTR_MESSAGE_AUTHENTICATOR) + return p; + i += p[1]; + } + + return NULL; +} + +/* + * Calculate the message authenticator MAC for pkt as specified in RFC 2869 + * section 5.14, placing the result in mac_out. Use the provided authenticator + * auth, which may be from pkt or from a corresponding request. + */ +static krb5_error_code +calculate_mac(const char *secret, const krad_packet *pkt, + const uint8_t auth[AUTH_FIELD_SIZE], + uint8_t mac_out[MD5_DIGEST_SIZE]) +{ + const uint8_t *msgauth_attr, *msgauth_end, *pkt_end; + krb5_crypto_iov input[5]; + krb5_data ksecr, mac; + static const uint8_t zeroed_msgauth[MSGAUTH_SIZE] = { + KRAD_ATTR_MESSAGE_AUTHENTICATOR, MSGAUTH_SIZE + }; + + msgauth_attr = lookup_msgauth_addr(pkt); + if (msgauth_attr == NULL) + return EINVAL; + msgauth_end = msgauth_attr + MSGAUTH_SIZE; + pkt_end = (const uint8_t *)pkt->pkt.data + pkt->pkt.length; + + /* Read code, id, and length from the packet. */ + input[0].flags = KRB5_CRYPTO_TYPE_DATA; + input[0].data = make_data(pkt->pkt.data, OFFSET_AUTH); + + /* Read the provided authenticator. */ + input[1].flags = KRB5_CRYPTO_TYPE_DATA; + input[1].data = make_data((uint8_t *)auth, AUTH_FIELD_SIZE); + + /* Read any attributes before Message-Authenticator. */ + input[2].flags = KRB5_CRYPTO_TYPE_DATA; + input[2].data = make_data(pkt_attr(pkt), msgauth_attr - pkt_attr(pkt)); + + /* Read Message-Authenticator with the data bytes all set to zero, per RFC + * 2869 section 5.14. */ + input[3].flags = KRB5_CRYPTO_TYPE_DATA; + input[3].data = make_data((uint8_t *)zeroed_msgauth, MSGAUTH_SIZE); + + /* Read any attributes after Message-Authenticator. */ + input[4].flags = KRB5_CRYPTO_TYPE_DATA; + input[4].data = make_data((uint8_t *)msgauth_end, pkt_end - msgauth_end); + + mac = make_data(mac_out, MD5_DIGEST_SIZE); + ksecr = string2data((char *)secret); + return k5_hmac_md5(&ksecr, input, 5, &mac); +} + +ssize_t +krad_packet_bytes_needed(const krb5_data *buffer) +{ + size_t len; + + if (buffer->length < OFFSET_AUTH) + return OFFSET_AUTH - buffer->length; + + len = load_16_be(offset(buffer, OFFSET_LENGTH)); + if (len > KRAD_PACKET_SIZE_MAX) + return -1; + + return (buffer->length > len) ? 0 : len - buffer->length; +} + +void +krad_packet_free(krad_packet *pkt) +{ + if (pkt) + krad_attrset_free(pkt->attrset); + free(pkt); +} + +/* Create a new request packet. */ +krb5_error_code +krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code, + const krad_attrset *set, krad_packet_iter_cb cb, + void *data, krad_packet **request) +{ + krb5_error_code retval; + krad_packet *pkt; + uchar id; + size_t attrset_len; + krb5_boolean msgauth_required; + + pkt = packet_new(); + if (pkt == NULL) { + if (cb != NULL) + (*cb)(data, TRUE); + return ENOMEM; + } + + /* Generate the ID. */ + retval = id_generate(ctx, cb, data, &id); + if (retval != 0) + goto error; + pkt_id_set(pkt, id); + + /* Generate the authenticator. */ + retval = auth_generate_random(ctx, pkt_auth(pkt)); + if (retval != 0) + goto error; + + /* Determine if Message-Authenticator is required. */ + msgauth_required = (*secret != '\0' && code == KRAD_CODE_ACCESS_REQUEST); + + /* Encode the attributes. */ + retval = kr_attrset_encode(set, secret, pkt_auth(pkt), msgauth_required, + pkt_attr(pkt), &attrset_len); + if (retval != 0) + goto error; + + /* Set the code, ID and length. */ + pkt->pkt.length = attrset_len + OFFSET_ATTR; + pkt_code_set(pkt, code); + pkt_len_set(pkt, pkt->pkt.length); + + if (msgauth_required) { + /* Calculate and set the Message-Authenticator MAC. */ + retval = calculate_mac(secret, pkt, pkt_auth(pkt), pkt_attr(pkt) + 2); + if (retval != 0) + goto error; + } + + /* Copy the attrset for future use. */ + retval = packet_set_attrset(ctx, secret, pkt); + if (retval != 0) + goto error; + + *request = pkt; + return 0; + +error: + free(pkt); + return retval; +} + +/* Create a new request packet. */ +krb5_error_code +krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code, + const krad_attrset *set, const krad_packet *request, + krad_packet **response) +{ + krb5_error_code retval; + krad_packet *pkt; + size_t attrset_len; + krb5_boolean msgauth_required; + + pkt = packet_new(); + if (pkt == NULL) + return ENOMEM; + + /* Determine if Message-Authenticator is required. */ + msgauth_required = requires_msgauth(secret, code); + + /* Encode the attributes. */ + retval = kr_attrset_encode(set, secret, pkt_auth(request), + msgauth_required, pkt_attr(pkt), &attrset_len); + if (retval != 0) + goto error; + + /* Set the code, ID and length. */ + pkt->pkt.length = attrset_len + OFFSET_ATTR; + pkt_code_set(pkt, code); + pkt_id_set(pkt, pkt_id_get(request)); + pkt_len_set(pkt, pkt->pkt.length); + + /* Generate the authenticator. */ + retval = auth_generate_response(ctx, secret, pkt, pkt_auth(request), + pkt_auth(pkt)); + if (retval != 0) + goto error; + + if (msgauth_required) { + /* + * Calculate and replace the Message-Authenticator MAC. Per RFC 2869 + * section 5.14, use the authenticator from the request, not from the + * response. + */ + retval = calculate_mac(secret, pkt, pkt_auth(request), + pkt_attr(pkt) + 2); + if (retval != 0) + goto error; + } + + /* Copy the attrset for future use. */ + retval = packet_set_attrset(ctx, secret, pkt); + if (retval != 0) + goto error; + + *response = pkt; + return 0; + +error: + free(pkt); + return retval; +} + +/* Verify the Message-Authenticator value in pkt, using the provided + * authenticator (which may be from pkt or from a corresponding request). */ +static krb5_error_code +verify_msgauth(const char *secret, const krad_packet *pkt, + const uint8_t auth[AUTH_FIELD_SIZE]) +{ + uint8_t mac[MD5_DIGEST_SIZE]; + const krb5_data *msgauth; + krb5_error_code retval; + + msgauth = krad_packet_get_attr(pkt, KRAD_ATTR_MESSAGE_AUTHENTICATOR, 0); +/* XXX ENODATA does not exist in FreeBSD. The closest thing we have to */ +/* XXX ENODATA is ENOATTR. We use that instead. */ +#define ENODATA ENOATTR + if (msgauth == NULL) + return ENODATA; + + retval = calculate_mac(secret, pkt, auth, mac); + if (retval) + return retval; + + if (msgauth->length != MD5_DIGEST_SIZE) + return EMSGSIZE; + + if (k5_bcmp(mac, msgauth->data, MD5_DIGEST_SIZE) != 0) + return EBADMSG; + + return 0; +} + +/* Decode a packet. */ +static krb5_error_code +decode_packet(krb5_context ctx, const char *secret, const krb5_data *buffer, + krad_packet **pkt) +{ + krb5_error_code retval; + krad_packet *tmp; + krb5_ui_2 len; + + tmp = packet_new(); + if (tmp == NULL) { + retval = ENOMEM; + goto error; + } + + /* Ensure a proper message length. */ + retval = (buffer->length < OFFSET_ATTR) ? EMSGSIZE : 0; + if (retval != 0) + goto error; + len = load_16_be(offset(buffer, OFFSET_LENGTH)); + retval = (len < OFFSET_ATTR) ? EBADMSG : 0; + if (retval != 0) + goto error; + retval = (len > buffer->length || len > tmp->pkt.length) ? EBADMSG : 0; + if (retval != 0) + goto error; + + /* Copy over the buffer. */ + tmp->pkt.length = len; + memcpy(tmp->pkt.data, buffer->data, len); + + /* Parse the packet to ensure it is well-formed. */ + retval = packet_set_attrset(ctx, secret, tmp); + if (retval != 0) + goto error; + + *pkt = tmp; + return 0; + +error: + krad_packet_free(tmp); + return retval; +} + +krb5_error_code +krad_packet_decode_request(krb5_context ctx, const char *secret, + const krb5_data *buffer, krad_packet_iter_cb cb, + void *data, const krad_packet **duppkt, + krad_packet **reqpkt) +{ + const krad_packet *tmp = NULL; + krad_packet *req; + krb5_error_code retval; + + retval = decode_packet(ctx, secret, buffer, &req); + if (retval) + return retval; + + /* Verify Message-Authenticator if present. */ + if (has_pkt_msgauth(req)) { + retval = verify_msgauth(secret, req, pkt_auth(req)); + if (retval) { + krad_packet_free(req); + return retval; + } + } + + if (cb != NULL) { + for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) { - if (pkt_id_get(*reqpkt) == pkt_id_get(tmp)) ++ if (pkt_id_get(req) == pkt_id_get(tmp)) + break; + } + + if (tmp != NULL) + (*cb)(data, TRUE); + } + + *reqpkt = req; + *duppkt = tmp; + return 0; +} + +krb5_error_code +krad_packet_decode_response(krb5_context ctx, const char *secret, + const krb5_data *buffer, krad_packet_iter_cb cb, + void *data, const krad_packet **reqpkt, + krad_packet **rsppkt) +{ + uchar auth[AUTH_FIELD_SIZE]; + const krad_packet *tmp = NULL; + krb5_error_code retval; + + retval = decode_packet(ctx, secret, buffer, rsppkt); + if (cb != NULL && retval == 0) { + for (tmp = (*cb)(data, FALSE); tmp != NULL; tmp = (*cb)(data, FALSE)) { + if (pkt_id_get(*rsppkt) != pkt_id_get(tmp)) + continue; + + /* Response */ + retval = auth_generate_response(ctx, secret, *rsppkt, + pkt_auth(tmp), auth); + if (retval != 0) { + krad_packet_free(*rsppkt); + break; + } + + /* Verify the response authenticator. */ + if (k5_bcmp(pkt_auth(*rsppkt), auth, sizeof(auth)) != 0) + continue; + + /* Verify Message-Authenticator if present. */ + if (has_pkt_msgauth(*rsppkt)) { + if (verify_msgauth(secret, *rsppkt, pkt_auth(tmp)) != 0) + continue; + } + + break; + } + } + + if (cb != NULL && (retval != 0 || tmp != NULL)) + (*cb)(data, TRUE); + + *reqpkt = tmp; + return retval; +} + +const krb5_data * +krad_packet_encode(const krad_packet *pkt) +{ + return &pkt->pkt; +} + +krad_code +krad_packet_get_code(const krad_packet *pkt) +{ + if (pkt == NULL) + return 0; + + return pkt_code_get(pkt); +} + +const krb5_data * +krad_packet_get_attr(const krad_packet *pkt, krad_attr type, size_t indx) +{ + return krad_attrset_get(pkt->attrset, type, indx); +}home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f3efb9.308ec.599addf5>
