/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* Copyright 2013 Red Hat, Inc. All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions are met:6*7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9*10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in12* the documentation and/or other materials provided with the13* distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS16* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED17* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A18* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER19* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,20* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,21* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR22* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF23* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING24* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.26*/2728/*29* This API is not considered as stable as the main krb5 API.30*31* - We may make arbitrary incompatible changes between feature releases32* (e.g. from 1.12 to 1.13).33* - We will make some effort to avoid making incompatible changes for34* bugfix releases, but will make them if necessary.35*/3637#ifndef KRAD_H_38#define KRAD_H_3940#include <krb5.h>41#include <verto.h>42#include <stddef.h>43#include <stdio.h>4445#define KRAD_PACKET_SIZE_MAX 40964647#define KRAD_SERVICE_TYPE_LOGIN 148#define KRAD_SERVICE_TYPE_FRAMED 249#define KRAD_SERVICE_TYPE_CALLBACK_LOGIN 350#define KRAD_SERVICE_TYPE_CALLBACK_FRAMED 451#define KRAD_SERVICE_TYPE_OUTBOUND 552#define KRAD_SERVICE_TYPE_ADMINISTRATIVE 653#define KRAD_SERVICE_TYPE_NAS_PROMPT 754#define KRAD_SERVICE_TYPE_AUTHENTICATE_ONLY 855#define KRAD_SERVICE_TYPE_CALLBACK_NAS_PROMPT 956#define KRAD_SERVICE_TYPE_CALL_CHECK 1057#define KRAD_SERVICE_TYPE_CALLBACK_ADMINISTRATIVE 115859#define KRAD_ATTR_USER_NAME 160#define KRAD_ATTR_USER_PASSWORD 261#define KRAD_ATTR_SERVICE_TYPE 662#define KRAD_ATTR_NAS_IDENTIFIER 3263#define KRAD_ATTR_PROXY_STATE 3364#define KRAD_ATTR_MESSAGE_AUTHENTICATOR 806566#define KRAD_CODE_ACCESS_REQUEST 167#define KRAD_CODE_ACCESS_ACCEPT 268#define KRAD_CODE_ACCESS_REJECT 369#define KRAD_CODE_ACCESS_CHALLENGE 117071typedef struct krad_attrset_st krad_attrset;72typedef struct krad_packet_st krad_packet;73typedef struct krad_client_st krad_client;74typedef unsigned char krad_code;75typedef unsigned char krad_attr;7677/* Called when a response is received or the request times out. */78typedef void79(*krad_cb)(krb5_error_code retval, const krad_packet *request,80const krad_packet *response, void *data);8182/*83* Called to iterate over a set of requests. Either the callback will be84* called until it returns NULL, or it will be called with cancel = TRUE to85* terminate in the middle of an iteration.86*/87typedef const krad_packet *88(*krad_packet_iter_cb)(void *data, krb5_boolean cancel);8990/*91* Code92*/9394/* Convert a code name to its number. Only works for codes defined95* by RFC 2875 or 2882. Returns 0 if the name was not found. */96krad_code97krad_code_name2num(const char *name);9899/* Convert a code number to its name. Only works for attributes defined100* by RFC 2865 or 2882. Returns NULL if the name was not found. */101const char *102krad_code_num2name(krad_code code);103104/*105* Attribute106*/107108/* Convert an attribute name to its number. Only works for attributes defined109* by RFC 2865. Returns 0 if the name was not found. */110krad_attr111krad_attr_name2num(const char *name);112113/* Convert an attribute number to its name. Only works for attributes defined114* by RFC 2865. Returns NULL if the name was not found. */115const char *116krad_attr_num2name(krad_attr type);117118/*119* Attribute set120*/121122/* Create a new attribute set. */123krb5_error_code124krad_attrset_new(krb5_context ctx, krad_attrset **set);125126/* Create a deep copy of an attribute set. */127krb5_error_code128krad_attrset_copy(const krad_attrset *set, krad_attrset **copy);129130/* Free an attribute set. */131void132krad_attrset_free(krad_attrset *set);133134/* Add an attribute to a set. */135krb5_error_code136krad_attrset_add(krad_attrset *set, krad_attr type, const krb5_data *data);137138/* Add a four-octet unsigned number attribute to the given set. */139krb5_error_code140krad_attrset_add_number(krad_attrset *set, krad_attr type, krb5_ui_4 num);141142/* Delete the specified attribute. */143void144krad_attrset_del(krad_attrset *set, krad_attr type, size_t indx);145146/* Get the specified attribute. */147const krb5_data *148krad_attrset_get(const krad_attrset *set, krad_attr type, size_t indx);149150/*151* Packet152*/153154/* Determine the bytes needed from the socket to get the whole packet. Don't155* cache the return value as it can change! Returns -1 on EBADMSG. */156ssize_t157krad_packet_bytes_needed(const krb5_data *buffer);158159/* Free a packet. */160void161krad_packet_free(krad_packet *pkt);162163/*164* Create a new request packet.165*166* This function takes the attributes specified in set and converts them into a167* radius packet. The packet will have a randomized id. If cb is not NULL, it168* will be called passing data as the argument to iterate over a set of169* outstanding requests. In this case, the id will be both random and unique170* across the set of requests.171*/172krb5_error_code173krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,174const krad_attrset *set, krad_packet_iter_cb cb,175void *data, krad_packet **request);176177/*178* Create a new response packet.179*180* This function is similar to krad_packet_new_requst() except that it crafts a181* packet in response to a request packet. This new packet will borrow values182* from the request such as the id and the authenticator.183*/184krb5_error_code185krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,186const krad_attrset *set, const krad_packet *request,187krad_packet **response);188189/*190* Decode a request radius packet from krb5_data.191*192* The resulting decoded packet will be a request packet stored in *reqpkt.193*194* If cb is NULL, *duppkt will always be NULL.195*196* If cb is not NULL, it will be called (with the data argument) to iterate197* over a set of requests currently being processed. In this case, if the198* packet is a duplicate of an already received request, the original request199* will be set in *duppkt.200*/201krb5_error_code202krad_packet_decode_request(krb5_context ctx, const char *secret,203const krb5_data *buffer, krad_packet_iter_cb cb,204void *data, const krad_packet **duppkt,205krad_packet **reqpkt);206207/*208* Decode a response radius packet from krb5_data.209*210* The resulting decoded packet will be a response packet stored in *rsppkt.211*212* If cb is NULL, *reqpkt will always be NULL.213*214* If cb is not NULL, it will be called (with the data argument) to iterate215* over a set of requests awaiting responses. In this case, if the response216* packet matches one of these requests, the original request will be set in217* *reqpkt.218*/219krb5_error_code220krad_packet_decode_response(krb5_context ctx, const char *secret,221const krb5_data *buffer, krad_packet_iter_cb cb,222void *data, const krad_packet **reqpkt,223krad_packet **rsppkt);224225/* Encode packet. */226const krb5_data *227krad_packet_encode(const krad_packet *pkt);228229/* Get the code for the given packet. */230krad_code231krad_packet_get_code(const krad_packet *pkt);232233/* Get the specified attribute. */234const krb5_data *235krad_packet_get_attr(const krad_packet *pkt, krad_attr type, size_t indx);236237/*238* Client239*/240241/* Create a new client. */242krb5_error_code243krad_client_new(krb5_context kctx, verto_ctx *vctx, krad_client **client);244245/* Free the client. */246void247krad_client_free(krad_client *client);248249/*250* Send a request to a radius server.251*252* The remote host may be specified by one of the following formats:253* - /path/to/unix.socket254* - IPv4255* - IPv4:port256* - IPv4:service257* - [IPv6]258* - [IPv6]:port259* - [IPv6]:service260* - hostname261* - hostname:port262* - hostname:service263*264* The timeout parameter (milliseconds) is the total timeout across all remote265* hosts (when DNS returns multiple entries) and all retries. For stream266* sockets, the retries parameter is ignored and no retries are performed.267*268* The cb function will be called with the data argument when either a response269* is received or the request times out on all possible remote hosts.270*/271krb5_error_code272krad_client_send(krad_client *rc, krad_code code, const krad_attrset *attrs,273const char *remote, const char *secret, int timeout,274size_t retries, krad_cb cb, void *data);275276#endif /* KRAD_H_ */277278279