1 /*
2  * This file is part of the Sofia-SIP package
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24 
25 #ifndef AUTH_MODULE_H
26 /** Defined when <sofia-sip/auth_module.h> has been included. */
27 #define AUTH_MODULE_H
28 
29 /**@file sofia-sip/auth_module.h
30  * @brief Authentication verification interface.
31  *
32  * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
33  *
34  * @date Created: Mon Jul 23 19:21:24 2001 ppessi
35  */
36 
37 #ifndef SU_TAG_H
38 #include <sofia-sip/su_tag.h>
39 #endif
40 #ifndef SU_WAIT_H
41 #include <sofia-sip/su_wait.h>
42 #endif
43 #ifndef MSG_TYPES_H
44 #include <sofia-sip/msg_types.h>
45 #endif
46 #ifndef URL_H
47 #include <sofia-sip/url.h>
48 #endif
49 #ifndef URL_TAG_H
50 #include <sofia-sip/url_tag.h>
51 #endif
52 
53 SOFIA_BEGIN_DECLS
54 
55 typedef struct auth_mod_t auth_mod_t;
56 /** Authentication operation. */
57 typedef struct auth_status_t auth_status_t;
58 
59 #ifdef  AUTH_MAGIC_T
60 typedef AUTH_MAGIC_T auth_magic_t;
61 #else
62 typedef void auth_magic_t;
63 #endif
64 
65 /** Virtual table for authentication plugin. */
66 typedef struct auth_scheme const auth_scheme_t;
67 
68 /** Opaque data used by authentication plugin module. */
69 typedef struct auth_plugin_t  auth_plugin_t;
70 /** Opaque user data used by plugin module. */
71 typedef struct auth_splugin_t auth_splugin_t;
72 /** Opaque authentication operation data used by plugin module. */
73 typedef struct auth_uplugin_t auth_uplugin_t;
74 
75 /** Callback from completeted asynchronous authentication operation. */
76 typedef void auth_callback_t(auth_magic_t *, auth_status_t *);
77 
78 /**Authentication operation result.
79  *
80  * The auth_status_t structure is used to store the status of the
81  * authentication operation and all the related data. The application
82  * verifying the authentication fills the auth_status_t structure, then
83  * calls auth_mod_method() (or auth_mod_challenge()). The operation result
84  * is stored in the structure.
85  *
86  * If the operation is asynchronous, only a preliminary result is stored in
87  * the auth_status_t structure when the call to auth_mod_method() returns.
88  * In that case, the application @b must assign a callback function to the
89  * structure. The callback function is invoked when the authentication
90  * operation is completed.
91  *
92  * It is recommended that the auth_status_t structure is allocated with
93  * auth_status_new() or initialized with auth_status_init() or
94  * auth_status_init_with() functions.
95  */
96 struct auth_status_t
97 {
98   su_home_t       as_home[1];	/**< Memory home for authentication */
99 
100   int          	  as_status;	/**< Return authorization status [out] */
101   char const   	 *as_phrase;	/**< Return response phrase [out] */
102   char const   	 *as_user;	/**< Authenticated username [in/out] */
103   char const   	 *as_display;	/**< Return user's real name [in/out] */
104 
105   url_t const    *as_user_uri;	/* Return user's identity [in/out] */
106   char const     *as_ident;	/**< Identities [out] */
107   unsigned        as_profile;	/**< User profile (group) [out] */
108 
109   su_addrinfo_t  *as_source;	/**< Source address [in] */
110 
111   char const   	 *as_realm;	/**< Authentication realm [in] */
112   char const  	 *as_domain;	/**< Hostname [in] */
113   char const  	 *as_uri;	/**< Request-URI [in] */
114   char const     *as_pdomain;	/**< Domain parameter [in] (ignored). */
115   char const   	 *as_method;	/**< Method name to authenticate [in] */
116 
117   void const   	 *as_body;	/**< Message body to protect [in] */
118   isize_t      	  as_bodylen;	/**< Length of message body [in] */
119 
120   msg_time_t      as_nonce_issued; /**< Nonce issue time [out] */
121   unsigned   	  as_blacklist; /**< Blacklist time [out] */
122   unsigned        as_anonymous:1;/**< Return true if user is anonymous [out] */
123   unsigned        as_stale:1;	/**< Credentials were stale [out] */
124   unsigned        as_allow:1;	/**< Method cannot be challenged [out] */
125   unsigned        as_nextnonce:1; /**< Client used nextnonce [out] */
126   unsigned :0;
127 
128   msg_header_t 	 *as_response;	/**< Authentication challenge [out] */
129   msg_header_t   *as_info;	/**< Authentication-Info [out] */
130   msg_header_t 	 *as_match;	/**< Used authentication header [out] */
131 
132   /** @defgroup Callback information for asynchronous operation.  */
133   /** @{ */
134   auth_magic_t   *as_magic;	/**< Application data [in] */
135   auth_callback_t*as_callback;	/**< Completion callback [in] */
136   /** @} */
137 
138   /** Pointer to extended state, used exclusively by plugin modules. */
139   auth_splugin_t *as_plugin;
140 };
141 
142 /** Authentication challenge.
143  *
144  * This structure defines what kind of response and challenge header is
145  * returned to the user. For example, a server authentication is implemented
146  * with 401 response code and phrase along with header class for
147  * @b WWW-Authenticate header in the @a ach structure.
148  */
149 typedef struct auth_challenger
150 {
151   int           ach_status;	/**< Response status for challenge response */
152   char const   *ach_phrase;	/**< Response phrase for challenge response */
153   msg_hclass_t *ach_header;	/**< Header class for challenge header */
154   msg_hclass_t *ach_info;
155 } auth_challenger_t;
156 
157 SOFIAPUBVAR char const auth_internal_server_error[];
158 
159 #define AUTH_STATUS_INIT \
160   {{ SU_HOME_INIT(auth_status_t) }, 500, auth_internal_server_error, NULL }
161 
162 #define AUTH_STATUS_DEINIT(as) \
163   su_home_deinit(as->as_home)
164 
165 #define AUTH_RESPONSE_INIT(as) AUTH_STATUS_INIT
166 #define AUTH_RESPONSE_DEINIT(as) AUTH_STATUS_DEINIT(as)
167 
168 SOFIAPUBFUN int auth_mod_register_plugin(auth_scheme_t *asch);
169 
170 SOFIAPUBFUN auth_mod_t *auth_mod_create(su_root_t *root,
171 					tag_type_t, tag_value_t, ...);
172 SOFIAPUBFUN void auth_mod_destroy(auth_mod_t *);
173 
174 SOFIAPUBFUN auth_mod_t *auth_mod_ref(auth_mod_t *am);
175 SOFIAPUBFUN void auth_mod_unref(auth_mod_t *am);
176 
177 SOFIAPUBFUN char const *auth_mod_name(auth_mod_t *am);
178 
179 SOFIAPUBFUN auth_status_t *auth_status_init(void *, isize_t size);
180 SOFIAPUBFUN auth_status_t *auth_status_init_with(void *, isize_t size,
181 						 int status,
182 						 char const *phrase);
183 
184 SOFIAPUBFUN auth_status_t *auth_status_new(su_home_t *);
185 
186 SOFIAPUBFUN auth_status_t *auth_status_ref(auth_status_t *as);
187 
188 SOFIAPUBFUN void auth_status_unref(auth_status_t *as);
189 
190 SOFIAPUBFUN void auth_mod_verify(auth_mod_t *am,
191 				 auth_status_t *as,
192 				 msg_auth_t *credentials,
193 				 auth_challenger_t const *ach);
194 
195 SOFIAPUBFUN void auth_mod_challenge(auth_mod_t *am,
196 				    auth_status_t *as,
197 				    auth_challenger_t const *ach);
198 
199 SOFIAPUBFUN void auth_mod_authorize(auth_mod_t *am,
200 				    auth_status_t *as,
201 				    auth_challenger_t const *ach);
202 
203 SOFIAPUBFUN void auth_mod_cancel(auth_mod_t *am, auth_status_t *as);
204 
205 /* ====================================================================== */
206 /* Deprecated functions */
207 
208 typedef enum {
209   auth_server,
210   auth_proxy,
211   auth_proxy_consume,
212   auth_consume
213 } auth_kind_t;
214 
215 SOFIAPUBFUN void auth_mod_method(auth_mod_t *am,
216 				 auth_status_t *as,
217 				 msg_auth_t *credentials,
218 				 auth_challenger_t const *ach);
219 
220 SOFIAPUBFUN void auth_mod_check_client(auth_mod_t *am,
221 				       auth_status_t *as,
222 				       msg_auth_t *credentials,
223 				       auth_challenger_t const *ach);
224 
225 SOFIAPUBFUN void auth_mod_challenge_client(auth_mod_t *am,
226 					   auth_status_t *as,
227 					   auth_challenger_t const *ach);
228 
229 #ifdef SIP_H
230 SOFIAPUBFUN void auth_mod_check(auth_mod_t *am,
231 				auth_status_t *as,
232 				sip_t const *sip,
233 				auth_kind_t proxy);
234 #endif
235 
236 #ifdef HTTP_H
237 SOFIAPUBFUN const char *auth_mod_check_http(auth_mod_t *am,
238 					    auth_status_t *as,
239 					    http_t const *http,
240 					    auth_kind_t proxy);
241 #endif
242 
243 /* ====================================================================== */
244 /* Tags */
245 
246 #define AUTHTAG_ANY()         authtag_any, ((tag_value_t)0)
247 SOFIAPUBVAR tag_typedef_t authtag_any;
248 
249 /** Pointer to an authentication server (auth_mod_t). */
250 #define AUTHTAG_MODULE(x)	authtag_module, authtag_module_v((x))
251 SOFIAPUBVAR tag_typedef_t authtag_module;
252 
253 #define AUTHTAG_MODULE_REF(x)	authtag_module_ref, authtag_module_vr((&x))
254 SOFIAPUBVAR tag_typedef_t authtag_module_ref;
255 
256 #if SU_INLINE_TAG_CAST
authtag_module_v(auth_mod_t * v)257 su_inline tag_value_t authtag_module_v(auth_mod_t *v) {
258   return (tag_value_t)v;
259 }
authtag_module_vr(auth_mod_t ** vp)260 su_inline tag_value_t authtag_module_vr(auth_mod_t **vp) {
261   return (tag_value_t)vp;
262 }
263 #else
264 #define authtag_module_v(v)   ((tag_value_t)(v))
265 #define authtag_module_vr(v)  ((tag_value_t)(v))
266 #endif
267 
268 /** Authentication scheme used by authentication module. */
269 #define AUTHTAG_METHOD(x)	authtag_method, tag_str_v((x))
270 SOFIAPUBVAR tag_typedef_t authtag_method;
271 
272 #define AUTHTAG_METHOD_REF(x)	authtag_method_ref, tag_str_vr((&x))
273 SOFIAPUBVAR tag_typedef_t authtag_method_ref;
274 
275 /** Authentication realm used by authentication server. */
276 #define AUTHTAG_REALM(x)	authtag_realm, tag_str_v((x))
277 SOFIAPUBVAR tag_typedef_t authtag_realm;
278 
279 #define AUTHTAG_REALM_REF(x)	authtag_realm_ref, tag_str_vr((&x))
280 SOFIAPUBVAR tag_typedef_t authtag_realm_ref;
281 
282 /** Opaque authentication data always included in challenge. */
283 #define AUTHTAG_OPAQUE(x)	authtag_opaque, tag_str_v((x))
284 SOFIAPUBVAR tag_typedef_t authtag_opaque;
285 
286 #define AUTHTAG_OPAQUE_REF(x)	authtag_opaque_ref, tag_str_vr((&x))
287 SOFIAPUBVAR tag_typedef_t authtag_opaque_ref;
288 
289 /** Name of authentication database used by authentication server. */
290 #define AUTHTAG_DB(x)		authtag_db, tag_str_v((x))
291 SOFIAPUBVAR tag_typedef_t authtag_db;
292 
293 #define AUTHTAG_DB_REF(x)		authtag_db_ref, tag_str_vr((&x))
294 SOFIAPUBVAR tag_typedef_t authtag_db_ref;
295 
296 /** Quality-of-protection used by digest authentication. */
297 #define AUTHTAG_QOP(x)	        authtag_qop, tag_str_v((x))
298 SOFIAPUBVAR tag_typedef_t authtag_qop;
299 
300 #define AUTHTAG_QOP_REF(x)	        authtag_qop_ref, tag_str_vr((&x))
301 SOFIAPUBVAR tag_typedef_t authtag_qop_ref;
302 
303 /** Algorithm used by digest authentication. */
304 #define AUTHTAG_ALGORITHM(x)    authtag_algorithm, tag_str_v((x))
305 SOFIAPUBVAR tag_typedef_t authtag_algorithm;
306 
307 #define AUTHTAG_ALGORITHM_REF(x)    authtag_algorithm_ref, tag_str_vr((&x))
308 SOFIAPUBVAR tag_typedef_t authtag_algorithm_ref;
309 
310 /** Nonce lifetime. */
311 #define AUTHTAG_EXPIRES(x)    authtag_expires, tag_uint_v((x))
312 SOFIAPUBVAR tag_typedef_t authtag_expires;
313 
314 #define AUTHTAG_EXPIRES_REF(x)    authtag_expires_ref, tag_uint_vr((&x))
315 SOFIAPUBVAR tag_typedef_t authtag_expires_ref;
316 
317 /** Lifetime for nextnonce, 0 disables nextnonce. */
318 #define AUTHTAG_NEXT_EXPIRES(x)    authtag_next_expires, tag_uint_v((x))
319 SOFIAPUBVAR tag_typedef_t authtag_next_expires;
320 
321 #define AUTHTAG_NEXT_EXPIRES_REF(x)  \
322   authtag_next_expires_ref, tag_uint_vr((&x))
323 SOFIAPUBVAR tag_typedef_t authtag_next_expires_ref;
324 
325 /** Maximum nonce count allowed. */
326 #define AUTHTAG_MAX_NCOUNT(x)    authtag_max_ncount, tag_uint_v((x))
327 SOFIAPUBVAR tag_typedef_t authtag_max_ncount;
328 
329 #define AUTHTAG_MAX_NCOUNT_REF(x)    authtag_max_ncount_ref, tag_uint_vr((&x))
330 SOFIAPUBVAR tag_typedef_t authtag_max_ncount_ref;
331 
332 /** Extra delay when responding if provided invalid credentials or nonce. */
333 #define AUTHTAG_BLACKLIST(x)    authtag_blacklist, tag_uint_v((x))
334 SOFIAPUBVAR tag_typedef_t authtag_blacklist;
335 
336 #define AUTHTAG_BLACKLIST_REF(x)    authtag_blacklist_ref, tag_uint_vr((&x))
337 SOFIAPUBVAR tag_typedef_t authtag_blacklist_ref;
338 
339 /** Respond with 403 Forbidden if given invalid credentials. */
340 #define AUTHTAG_FORBIDDEN(x)    authtag_forbidden, tag_bool_v((x))
341 SOFIAPUBVAR tag_typedef_t authtag_forbidden;
342 
343 #define AUTHTAG_FORBIDDEN_REF(x)    authtag_forbidden_ref, tag_bool_vr((&x))
344 SOFIAPUBVAR tag_typedef_t authtag_forbidden_ref;
345 
346 /** Allow anonymous access. */
347 #define AUTHTAG_ANONYMOUS(x)    authtag_anonymous, tag_bool_v((x))
348 SOFIAPUBVAR tag_typedef_t authtag_anonymous;
349 
350 #define AUTHTAG_ANONYMOUS_REF(x)    authtag_anonymous_ref, tag_bool_vr((&x))
351 SOFIAPUBVAR tag_typedef_t authtag_anonymous_ref;
352 
353 /** HSS client structure. */
354 #define AUTHTAG_HSS(x)        authtag_hss, tag_ptr_v((x))
355 SOFIAPUBVAR tag_typedef_t authtag_hss;
356 
357 #define AUTHTAG_HSS_REF(x)    authtag_hss_ref, tag_ptr_vr((&x), (x))
358 SOFIAPUBVAR tag_typedef_t authtag_hss_ref;
359 
360 /** Remote authenticator URL. */
361 #define AUTHTAG_REMOTE(x)     authtag_remote, urltag_url_v((x))
362 SOFIAPUBVAR tag_typedef_t authtag_remote;
363 
364 #define AUTHTAG_REMOTE_REF(x) authtag_remote_ref, urltag_url_vr((&x))
365 SOFIAPUBVAR tag_typedef_t authtag_remote_ref;
366 
367 /** Comma-separated list of methods never challenged. */
368 #define AUTHTAG_ALLOW(x)      authtag_allow, tag_str_v((x))
369 SOFIAPUBVAR tag_typedef_t authtag_allow;
370 
371 #define AUTHTAG_ALLOW_REF(x)  authtag_allow_ref, tag_str_vr((&x))
372 SOFIAPUBVAR tag_typedef_t authtag_allow_ref;
373 
374 /** Check that user exists, don't do authentication. */
375 #define AUTHTAG_FAKE(x)	authtag_fake, tag_bool_v((x))
376 SOFIAPUBVAR tag_typedef_t authtag_fake;
377 
378 #define AUTHTAG_FAKE_REF(x) authtag_fake_ref, tag_bool_vr((&x))
379 SOFIAPUBVAR tag_typedef_t authtag_fake_ref;
380 
381 /** Master key in base64 for the authentication module. */
382 #define AUTHTAG_MASTER_KEY(x)	authtag_master_key, tag_str_v((x))
383 SOFIAPUBVAR tag_typedef_t authtag_master_key;
384 
385 #define AUTHTAG_MASTER_KEY_REF(x) authtag_master_key_ref, tag_str_vr((&x))
386 SOFIAPUBVAR tag_typedef_t authtag_master_key_ref;
387 
388 /** Cache time for authentication data. */
389 #define AUTHTAG_CACHE_USERS(x)	authtag_cache_users, tag_uint_v((x))
390 SOFIAPUBVAR tag_typedef_t authtag_cache_users;
391 
392 #define AUTHTAG_CACHE_USERS_REF(x) authtag_cache_users_ref, tag_uint_vr((&x))
393 SOFIAPUBVAR tag_typedef_t authtag_cache_users_ref;
394 
395 /** Cache time for errors. */
396 #define AUTHTAG_CACHE_ERRORS(x)	authtag_cache_errors, tag_uint_v((x))
397 SOFIAPUBVAR tag_typedef_t authtag_cache_errors;
398 
399 #define AUTHTAG_CACHE_ERRORS_REF(x) authtag_cache_errors_ref, tag_uint_vr((&x))
400 SOFIAPUBVAR tag_typedef_t authtag_cache_errors_ref;
401 
402 SOFIA_END_DECLS
403 
404 #endif
405