1 /* 2 HTTP authentication routines 3 Copyright (C) 1999-2021, Joe Orton <joe@manyfish.co.uk> 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 18 MA 02111-1307, USA 19 20 */ 21 22 #ifndef NE_AUTH_H 23 #define NE_AUTH_H 24 25 #include "ne_session.h" /* for ne_session */ 26 27 NE_BEGIN_DECLS 28 29 /* Size of username/password buffers passed to ne_auth_creds 30 * callback. */ 31 #define NE_ABUFSIZ (256) 32 33 /* The callback used to request the username and password in the given 34 * realm. The username and password must be copied into the buffers 35 * which are both of size NE_ABUFSIZ. The 'attempt' parameter is zero 36 * on the first call to the callback, and increases by one for each 37 * invocation of the callback during an attempt to authenticate. 38 * 39 * The callback must return zero to indicate that authentication 40 * should be attempted with the username/password, or non-zero to 41 * cancel the request. (if non-zero, username and password are 42 * ignored.) 43 * 44 * IMPORTANT NOTE: The callback will be invoked repeatedly until 45 * either it returns non-zero, or authentication is successful. 46 * 47 * Hint: if you just wish to attempt authentication just once (even if 48 * the user gets the username/password wrong), have the callback 49 * function use 'attempt' value as the function return value. */ 50 typedef int (*ne_auth_creds)(void *userdata, const char *realm, int attempt, 51 char *username, char *password); 52 53 /* Set callbacks to provide credentials for server and proxy 54 * authentication, using the default set of authentication protocols. 55 * userdata is passed as the first argument to the callback. */ 56 void ne_set_server_auth(ne_session *sess, ne_auth_creds creds, void *userdata); 57 void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdata); 58 59 /* As an alternative to using ne_set_server_auth and 60 * ne_set_proxy_auth, the following interfaces may be used; these 61 * allow control over which authentication protocol is used. */ 62 63 /* NE_AUTH_BASIC: Basic authentication transmits the username and 64 * password unprotected over the channel; this allows a passive attack 65 * to steal the credentials if using an unsecured channel 66 * (i.e. non-SSL). */ 67 #define NE_AUTH_BASIC (0x0001) 68 69 /* NE_AUTH_DIGEST: Digest authentication uses a hash of the username, 70 * password, and certain aspects of the request, so prevents passive 71 * attackers from obtaining the credentials; active attackers can 72 * still modify most of the request/response if using an unsecured 73 * channel. Supports algorithms from RFC 2617 and RFC 7616. */ 74 #define NE_AUTH_DIGEST (0x0080) 75 76 /* NE_AUTH_LEGACY_DIGEST: Using this flag together with NE_AUTH_DIGEST 77 * enables support for the weaker, legacy version of the Digest 78 * algorithm specified in RFC 2069 (obsoleted by RFC 2617, which was 79 * published in June 1999). */ 80 #define NE_AUTH_LEGACY_DIGEST (0x0002) 81 82 /* NE_AUTH_NEGOTIATE: Negotiate uses GSSAPI/SSPI, or NTLM, to 83 * authenticate the user; an active attacker can modify any of the 84 * request/response at will, so this must not be used over an 85 * unsecured channel. NE_AUTH_NEGOTIATE is currently equivalent to 86 * use of (NE_AUTH_GSSAPI | NE_AUTH_NTLM). */ 87 #define NE_AUTH_NEGOTIATE (0x0004) 88 89 /* NE_AUTH_GSSAPI: Use GSSAPI or SSPI to authenticate the user; an 90 * active attacker can modify any of the request/response at will, so 91 * this must not be used over an unsecured channel. NE_AUTH_GSSAPI 92 * is currently equivalent to (NE_AUTH_GSSAPI_ONLY | NE_AUTH_SSPI). */ 93 #define NE_AUTH_GSSAPI (0x0008) 94 95 /* NE_AUTH_NTLM: Use NTLM to authenticate the user; an active attacker 96 * can modify any of the request/response at will, so this must not be 97 * used over an unsecured channel. */ 98 #define NE_AUTH_NTLM (0x0010) 99 100 /* NE_AUTH_SSPI: Use SSPI to authenticate the user; an 101 * active attacker can modify any of the request/response at will, so 102 * this must not be used over an unsecured channel. */ 103 #define NE_AUTH_SSPI (0x0020) 104 105 /* NE_AUTH_GSSAPI_ONLY: Use GSSAPI to authenticate the user; an 106 * active attacker can modify any of the request/response at will, so 107 * this must not be used over an unsecured channel. */ 108 #define NE_AUTH_GSSAPI_ONLY (0x0040) 109 110 /* 0x0080: legacy definition of NE_AUTH_DIGEST in 0.31 and earlier */ 111 112 /* The default set of supported protocols, as deemed appropriate for 113 * the given session scheme. The interpretation of this flag may 114 * change across versions, for example with older, less secure 115 * protocols being removed from the default set. */ 116 #define NE_AUTH_DEFAULT (0x1000) 117 118 /* All protocols supported by the library. The interpretation of this 119 * flag may change across versions. */ 120 #define NE_AUTH_ALL (0x2000) 121 122 /* If present in the protocol mask passed to ne_auth_provide, 123 * indicates that proxy authentication is requested. */ 124 #define NE_AUTH_PROXY (0x4000) 125 126 /* Add a callback to provide credentials for server and proxy 127 * authentication using a particular auth protocol or set of 128 * protocols. The protocol is supplied as a bitmask of NE_AUTH_* 129 * values. For NE_AUTH_NEGOTIATE, the creds and userdata arguments 130 * are ignored and may be NULL. 131 * 132 * These functions may be called multiple times per session to 133 * register callbacks for different protocols. If the server presents 134 * more than one protocol in an auth challenge, the following 135 * algorithm will be used to determine which callback is used: 136 * 137 * - iterate over the registered callbacks in the order registered 138 * - for each each callback, iterate over the known set of protocols 139 * in order of algorithm strength (strongest first). 140 * - if the protocol mask for that callback matches the protocol, 141 * attempt authentication using this protocol. 142 * 143 * Therefore, if multiple calls to ne_add_server_auth or 144 * ne_add_proxy_auth are used for a given session, the caller must 145 * ensure that the order in which those calls are made reflects the 146 * precedence of protocols to be used. */ 147 void ne_add_server_auth(ne_session *sess, unsigned protocol, 148 ne_auth_creds creds, void *userdata); 149 void ne_add_proxy_auth(ne_session *sess, unsigned protocol, 150 ne_auth_creds creds, void *userdata); 151 152 /* Alternative credentials provider callback, invoked when credentials 153 * are required to authenticate the client to either a server or 154 * proxy. 'protocol' is the authentication protocol number 155 * (NE_AUTH_*) of the challenge, bitwise-ORed with NE_AUTH_PROXY when 156 * the auth challenge is made by an HTTP proxy. 157 * 158 * 'realm' is the realm name. The 'attempt' counter reflects the 159 * number of attempts to provide credentials to the server 160 * (i.e. retried requests sent with a challenge response), NOT the 161 * number of times the callback is invoked, unlike the ne_auth_creds 162 * callback. 163 * 164 * The callback must return zero to indicate that authentication 165 * should be attempted with the username/password, or non-zero to 166 * cancel the request. (if non-zero, username and password are 167 * ignored.) 168 * 169 * The username and password buffers have length 'buflen', which is 170 * guaranteed to be >= NE_ABUFSIZ. The username must be provided as a 171 * NUL-terminated UTF-8 encoding only. The password must be provided 172 * as a NUL-terminated string. Additional protocol-specific 173 * restrictions apply, e.g. username cannot contain a colon for Basic 174 * auth. 175 * 176 * IMPORTANT NOTE: The callback will be invoked repeatedly until 177 * either it returns non-zero, or authentication is successful. 178 * 179 * Hint: if you just wish to attempt authentication just once (even if 180 * the user gets the username/password wrong), have the callback 181 * function use 'attempt' value as the function return value. */ 182 typedef int (*ne_auth_provide)(void *userdata, int attempt, 183 unsigned protocol, const char *realm, 184 char *username, char *password, size_t buflen); 185 186 void ne_add_auth(ne_session *sess, unsigned protocol, 187 ne_auth_provide creds, void *userdata); 188 189 /* Clear any cached authentication credentials for the given 190 * session. */ 191 void ne_forget_auth(ne_session *sess); 192 193 NE_END_DECLS 194 195 #endif /* NE_AUTH_H */ 196