1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* lib/krad/internal.h - Internal declarations for libkrad */ 3 /* 4 * Copyright 2013 Red Hat, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef INTERNAL_H_ 31 #define INTERNAL_H_ 32 33 #include <k5-int.h> 34 #include "krad.h" 35 36 #include <errno.h> 37 38 #include <sys/types.h> 39 #include <sys/socket.h> 40 #include <netdb.h> 41 42 #ifndef UCHAR_MAX 43 #define UCHAR_MAX 255 44 #endif 45 46 #define MD5_DIGEST_SIZE 16 47 48 /* RFC 2865 */ 49 #define MAX_ATTRSIZE (UCHAR_MAX - 2) 50 #define MAX_ATTRSETSIZE (KRAD_PACKET_SIZE_MAX - 20) 51 52 typedef struct krad_remote_st krad_remote; 53 54 /* Validate constraints of an attribute. */ 55 krb5_error_code 56 kr_attr_valid(krad_attr type, const krb5_data *data); 57 58 /* Encode an attribute. */ 59 krb5_error_code 60 kr_attr_encode(krb5_context ctx, const char *secret, const unsigned char *auth, 61 krad_attr type, const krb5_data *in, 62 unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); 63 64 /* Decode an attribute. */ 65 krb5_error_code 66 kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth, 67 krad_attr type, const krb5_data *in, 68 unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen); 69 70 /* Encode set into outbuf. If add_msgauth is true, include a zeroed 71 * Message-Authenticator as the first attribute. */ 72 krb5_error_code 73 kr_attrset_encode(const krad_attrset *set, const char *secret, 74 const uint8_t *auth, krb5_boolean add_msgauth, 75 unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen); 76 77 /* Decode attributes from a buffer. */ 78 krb5_error_code 79 kr_attrset_decode(krb5_context ctx, const krb5_data *in, const char *secret, 80 const unsigned char *auth, krad_attrset **set); 81 82 /* Create a new remote object which manages a socket and the state of 83 * outstanding requests. */ 84 krb5_error_code 85 kr_remote_new(krb5_context kctx, verto_ctx *vctx, const struct addrinfo *info, 86 const char *secret, krad_remote **rr); 87 88 /* Free a remote object. */ 89 void 90 kr_remote_free(krad_remote *rr); 91 92 /* 93 * Send the packet to the remote. The cb will be called when a response is 94 * received, the request times out, the request is canceled or an error occurs. 95 * 96 * The timeout parameter is the total timeout across all retries in 97 * milliseconds. 98 * 99 * If the cb is called with a retval of ETIMEDOUT it indicates that the 100 * allotted time has elapsed. However, in the case of a timeout, we continue to 101 * listen for the packet until krad_remote_cancel() is called or a response is 102 * received. This means that cb will always be called twice in the event of a 103 * timeout. This permits you to pursue other remotes while still listening for 104 * a response from the first one. 105 */ 106 krb5_error_code 107 kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs, 108 krad_cb cb, void *data, int timeout, size_t retries, 109 const krad_packet **pkt); 110 111 /* Remove packet from the queue of requests awaiting responses. */ 112 void 113 kr_remote_cancel(krad_remote *rr, const krad_packet *pkt); 114 115 /* Cancel all requests awaiting responses. */ 116 void 117 kr_remote_cancel_all(krad_remote *rr); 118 119 /* Determine if this remote object refers to the remote resource identified 120 * by the addrinfo struct and the secret. */ 121 krb5_boolean 122 kr_remote_equals(const krad_remote *rr, const struct addrinfo *info, 123 const char *secret); 124 125 /* Adapted from lib/krb5/os/sendto_kdc.c. */ 126 static inline krb5_error_code 127 gai_error_code(int err) 128 { 129 switch (err) { 130 case 0: 131 return 0; 132 case EAI_BADFLAGS: 133 case EAI_FAMILY: 134 case EAI_SOCKTYPE: 135 case EAI_SERVICE: 136 #ifdef EAI_ADDRFAMILY 137 case EAI_ADDRFAMILY: 138 #endif 139 return EINVAL; 140 case EAI_AGAIN: 141 return EAGAIN; 142 case EAI_MEMORY: 143 return ENOMEM; 144 #if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME 145 case EAI_NODATA: 146 #endif 147 case EAI_NONAME: 148 return EADDRNOTAVAIL; 149 #ifdef EAI_OVERFLOW 150 case EAI_OVERFLOW: 151 return EOVERFLOW; 152 #endif 153 #ifdef EAI_SYSTEM 154 case EAI_SYSTEM: 155 return errno; 156 #endif 157 default: 158 return EINVAL; 159 } 160 } 161 162 #endif /* INTERNAL_H_ */ 163