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_PLUGIN_H
26 /** Defined when <sofia-sip/auth_plugin.h> has been included. */
27 #define AUTH_PLUGIN_H
28 
29 /**@file sofia-sip/auth_plugin.h
30  * @brief Plugin interface for authentication verification modules.
31  *
32  * @author Pekka Pessi <Pekka.Pessi@nokia.com>
33  *
34  * @date Created: Tue Apr 27 15:22:07 2004 ppessi
35  */
36 
37 #ifndef AUTH_MODULE_H
38 #include "sofia-sip/auth_module.h"
39 #endif
40 
41 #ifndef AUTH_DIGEST_H
42 #include "sofia-sip/auth_digest.h"
43 #endif
44 
45 #ifndef AUTH_COMMON_H
46 #include "sofia-sip/auth_common.h"
47 #endif
48 
49 #ifndef MSG_DATE_H
50 #include <sofia-sip/msg_date.h>
51 #endif
52 
53 #ifndef SU_MD5_H
54 #include <sofia-sip/su_md5.h>
55 #endif
56 
57 #include <sofia-sip/htable.h>
58 
59 SOFIA_BEGIN_DECLS
60 
61 /* ====================================================================== */
62 /* Plugin interface for authentication */
63 
64 /** Authentication scheme */
65 struct auth_scheme
66 {
67   /** Name */
68   char const *asch_method;
69 
70   /** Size of module object */
71   usize_t asch_size;
72 
73   /** Initialize module. Invoked by auth_mod_create(). */
74   int (*asch_init)(auth_mod_t *am,
75 		   auth_scheme_t *base,
76 		   su_root_t *root,
77 		   tag_type_t tag, tag_value_t value, ...);
78 
79   /** Check authentication. Invoked by auth_mod_method(). */
80   void (*asch_check)(auth_mod_t *am,
81 		     auth_status_t *as,
82 		     msg_auth_t *auth,
83 		     auth_challenger_t const *ch);
84 
85   /** Create a challenge. Invoked by auth_mod_challenge(). */
86   void (*asch_challenge)(auth_mod_t *am,
87 			 auth_status_t *as,
88 			 auth_challenger_t const *ch);
89 
90   /** Cancel an asynchronous authentication request.
91    * Invoked by auth_mod_cancel().
92    */
93   void (*asch_cancel)(auth_mod_t *am,
94 		      auth_status_t *as);
95 
96   /** Reclaim resources an authentication module.
97    *
98    * Invoked by auth_mod_destroy()/auth_mod_unref().
99    */
100   void (*asch_destroy)(auth_mod_t *am);
101 
102 };
103 
104 /** User data structure */
105 typedef struct
106 {
107   unsigned        apw_index;	/**< Key to hash table */
108   void const     *apw_type;	/**< Magic identifier */
109 
110   char const   	 *apw_user;	/**< Username */
111   char const     *apw_realm;	/**< Realm */
112   char const   	 *apw_pass;	/**< Password */
113   char const     *apw_hash;	/**< MD5 of the username, realm and pass */
114   char const     *apw_ident;	/**< Identity information */
115   auth_uplugin_t *apw_extended;	/**< Method-specific extension */
116 } auth_passwd_t;
117 
118 
119 HTABLE_DECLARE_WITH(auth_htable, aht, auth_passwd_t, usize_t, unsigned);
120 
121 struct stat;
122 
123 /** Common data for authentication module */
124 struct auth_mod_t
125 {
126   su_home_t      am_home[1];
127   unsigned       _am_refcount;	/**< Not used */
128 
129   /* User database / cache */
130   char const    *am_db;		/**< User database file name */
131   struct stat   *am_stat;	/**< State of user file when read */
132   auth_htable_t  am_users[1];	/**< Table of users */
133 
134   void          *am_buffer;	/**< Buffer for database */
135   auth_passwd_t *am_locals;	/**< Entries from local user file */
136   size_t         am_local_count; /**< Number of entries from local user file */
137 
138   auth_passwd_t *am_anon_user;	/**< Special entry for anonymous user */
139 
140   /* Attributes */
141   url_t         *am_remote;	/**< Remote authenticator */
142   char const    *am_realm;	/**< Our realm */
143   char const    *am_opaque;	/**< Opaque identification data */
144   char const    *am_gssapi_data; /**< NTLM data */
145   char const    *am_targetname; /**< NTLM target name */
146   auth_scheme_t *am_scheme;	/**< Authentication scheme (Digest, Basic). */
147   char const   **am_allow;	/**< Methods to allow without authentication */
148   msg_param_t    am_algorithm;	/**< Defauilt algorithm */
149   msg_param_t    am_qop;	/**< Default qop (quality-of-protection) */
150   unsigned       am_expires;	/**< Nonce lifetime */
151   unsigned       am_next_exp;	/**< Next nonce lifetime */
152   unsigned       am_blacklist;	/**< Extra delay if bad credentials. */
153   unsigned       am_forbidden:1;/**< Respond with 403 if bad credentials */
154   unsigned       am_anonymous:1;/**< Allow anonymous access */
155   unsigned       am_challenge:1;/**< Challenge even if successful */
156   unsigned       am_nextnonce:1;/**< Send next nonce in responses */
157   unsigned       am_mutual:1;   /**< Mutual authentication */
158   unsigned       am_fake:1;	/**< Fake authentication */
159 
160   unsigned :0;			/**< Pad */
161   unsigned       am_count;	/**< Nonce counter */
162 
163   uint8_t        am_master_key[16]; /**< Private master key */
164 
165   su_md5_t       am_hmac_ipad;	/**< MD5 with inner pad */
166   su_md5_t       am_hmac_opad;	/**< MD5 with outer pad */
167 
168   unsigned       am_max_ncount:1; /**< If nonzero, challenge with new nonce after ncount */
169 };
170 
171 SOFIAPUBFUN
172 auth_passwd_t *auth_mod_getpass(auth_mod_t *am,
173 				char const *user,
174 				char const *realm);
175 
176 SOFIAPUBFUN
177 auth_passwd_t *auth_mod_addpass(auth_mod_t *am,
178 				char const *user,
179 				char const *realm);
180 
181 SOFIAPUBFUN int auth_readdb_if_needed(auth_mod_t *am);
182 
183 SOFIAPUBFUN int auth_readdb(auth_mod_t *am);
184 
185 SOFIAPUBFUN msg_auth_t *auth_mod_credentials(msg_auth_t *auth,
186 					     char const *scheme,
187 					     char const *realm);
188 
189 SOFIAPUBFUN auth_mod_t *auth_mod_alloc(auth_scheme_t *scheme,
190 				       tag_type_t, tag_value_t, ...);
191 
192 #define AUTH_PLUGIN(am) (auth_plugin_t *)((am) + 1)
193 
194 SOFIAPUBFUN
195 int auth_init_default(auth_mod_t *am,
196 		      auth_scheme_t *base,
197 		      su_root_t *root,
198 		      tag_type_t tag, tag_value_t value, ...);
199 
200 /** Default cancel method */
201 SOFIAPUBFUN void auth_cancel_default(auth_mod_t *am, auth_status_t *as);
202 
203 /** Default destroy method */
204 SOFIAPUBFUN void auth_destroy_default(auth_mod_t *am);
205 
206 /** Basic scheme */
207 SOFIAPUBFUN
208 void auth_method_basic(auth_mod_t *am,
209 		       auth_status_t *as,
210 		       msg_auth_t *auth,
211 		       auth_challenger_t const *ach);
212 
213 SOFIAPUBFUN
214 void auth_challenge_basic(auth_mod_t *am,
215 			  auth_status_t *as,
216 			  auth_challenger_t const *ach);
217 
218 /** Digest scheme */
219 SOFIAPUBFUN
220 msg_auth_t *auth_digest_credentials(msg_auth_t *auth,
221 				    char const *realm,
222 				    char const *opaque);
223 
224 SOFIAPUBFUN
225 void auth_method_digest(auth_mod_t *am,
226 			auth_status_t *as,
227 			msg_auth_t *au,
228 			auth_challenger_t const *ach);
229 
230 SOFIAPUBFUN
231 void auth_info_digest(auth_mod_t *am,
232 		      auth_status_t *as,
233 		      auth_challenger_t const *ach);
234 
235 SOFIAPUBFUN
236 void auth_check_digest(auth_mod_t *am,
237 		       auth_status_t *as,
238 		       auth_response_t *ar,
239 		       auth_challenger_t const *ach);
240 
241 SOFIAPUBFUN
242 void auth_challenge_digest(auth_mod_t *am,
243 			   auth_status_t *as,
244 			   auth_challenger_t const *ach);
245 
246 SOFIAPUBFUN
247 isize_t auth_generate_digest_nonce(auth_mod_t *am,
248 				   char buffer[],
249 				   size_t buffer_len,
250 				   int nextnonce,
251 				   msg_time_t now);
252 
253 SOFIAPUBFUN
254 int auth_validate_digest_nonce(auth_mod_t *am,
255 			       auth_status_t *as,
256 			       auth_response_t *ar,
257 			       msg_time_t now);
258 
259 SOFIAPUBFUN int auth_allow_check(auth_mod_t *am, auth_status_t *as);
260 
261 /** Init md5 for MD5-based HMAC */
262 SOFIAPUBFUN void auth_md5_hmac_init(auth_mod_t *am, su_md5_t *md5);
263 SOFIAPUBFUN void auth_md5_hmac_digest(auth_mod_t *am, su_md5_t *md5,
264 				      void *hmac, size_t size);
265 
266 SOFIA_END_DECLS
267 
268 #endif /* !defined AUTH_PLUGIN_H */
269