blob: 97a8b3bacd3676ad90db4f64be007e899a1dc590 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __PJNATH_STUN_AUTH_H__
21#define __PJNATH_STUN_AUTH_H__
22
23/**
24 * @file stun_auth.h
25 * @brief STUN authentication.
26 */
27
28#include <pjnath/stun_msg.h>
29
30
31PJ_BEGIN_DECL
32
33
34/* **************************************************************************/
35/**
36 * @defgroup PJNATH_STUN_AUTH STUN Authentication
37 * @brief STUN authentication helper
38 * @ingroup PJNATH_STUN_BASE
39 * @{
40 */
41
42/**
43 * Type of authentication.
44 */
45typedef enum pj_stun_auth_type
46{
47 /**
48 * No authentication.
49 */
50 PJ_STUN_AUTH_NONE = 0,
51
52 /**
53 * Authentication using short term credential.
54 */
55 PJ_STUN_AUTH_SHORT_TERM = 1,
56
57 /**
58 * Authentication using long term credential.
59 */
60 PJ_STUN_AUTH_LONG_TERM = 2
61
62} pj_stun_auth_type;
63
64
65/**
66 * Type of authentication data in the credential.
67 */
68typedef enum pj_stun_auth_cred_type
69{
70 /**
71 * The credential data contains a static credential to be matched
72 * against the credential in the message. A static credential can be
73 * used as both client side or server side authentication.
74 */
75 PJ_STUN_AUTH_CRED_STATIC,
76
77 /**
78 * The credential data contains callbacks to be called to verify the
79 * credential in the message. A dynamic credential is suitable when
80 * performing server side authentication where server does not know
81 * in advance the identity of the user requesting authentication.
82 */
83 PJ_STUN_AUTH_CRED_DYNAMIC
84
85} pj_stun_auth_cred_type;
86
87
88/**
89 * Type of encoding applied to the password stored in the credential.
90 */
91typedef enum pj_stun_passwd_type
92{
93 /**
94 * Plain text password.
95 */
96 PJ_STUN_PASSWD_PLAIN = 0,
97
98 /**
99 * Hashed password, valid for long term credential only. The hash value
100 * of the password is calculated as MD5(USERNAME ":" REALM ":" PASSWD)
101 * with all quotes removed from the username and realm values.
102 */
103 PJ_STUN_PASSWD_HASHED = 1
104
105} pj_stun_passwd_type;
106
107
108/**
109 * This structure contains the descriptions needed to perform server side
110 * authentication. Depending on the \a type set in the structure, application
111 * may specify a static username/password combination, or to have callbacks
112 * called by the function to authenticate the credential dynamically.
113 */
114typedef struct pj_stun_auth_cred
115{
116 /**
117 * The type of authentication information in this structure.
118 */
119 pj_stun_auth_cred_type type;
120
121 /**
122 * This union contains the authentication data.
123 */
124 union
125 {
126 /**
127 * This structure contains static data for performing authentication.
128 * A non-empty realm indicates whether short term or long term
129 * credential is used.
130 */
131 struct
132 {
133 /**
134 * If not-empty, it indicates that this is a long term credential.
135 */
136 pj_str_t realm;
137
138 /**
139 * The username of the credential.
140 */
141 pj_str_t username;
142
143 /**
144 * Data type to indicate the type of password in the \a data field.
145 */
146 pj_stun_passwd_type data_type;
147
148 /**
149 * The data, which depends depends on the value of \a data_type
150 * field. When \a data_type is zero, this field will contain the
151 * plaintext password.
152 */
153 pj_str_t data;
154
155 /**
156 * Optional NONCE.
157 */
158 pj_str_t nonce;
159
160 } static_cred;
161
162 /**
163 * This structure contains callback to be called by the framework
164 * to authenticate the incoming message.
165 */
166 struct
167 {
168 /**
169 * User data which will be passed back to callback functions.
170 */
171 void *user_data;
172
173 /**
174 * This callback is called by pj_stun_verify_credential() when
175 * server needs to challenge the request with 401 response.
176 *
177 * @param user_data The user data as specified in the credential.
178 * @param pool Pool to allocate memory.
179 * @param realm On return, the function should fill in with
180 * realm if application wants to use long term
181 * credential. Otherwise application should set
182 * empty string for the realm.
183 * @param nonce On return, if application wants to use long
184 * term credential, it MUST fill in the nonce
185 * with some value. Otherwise if short term
186 * credential is wanted, it MAY set this value.
187 * If short term credential is wanted and the
188 * application doesn't want to include NONCE,
189 * then it must set this to empty string.
190 *
191 * @return The callback should return PJ_SUCCESS, or
192 * otherwise response message will not be
193 * created.
194 */
195 pj_status_t (*get_auth)(void *user_data,
196 pj_pool_t *pool,
197 pj_str_t *realm,
198 pj_str_t *nonce);
199
200 /**
201 * Get the credential to be put in outgoing request.
202 *
203 * @param msg The outgoing message where the credential is
204 * to be applied.
205 * @param user_data The user data as specified in the credential.
206 * @param pool Pool where the callback can allocate memory
207 * to fill in the credential.
208 * @param realm On return, the callback may specify the realm
209 * if long term credential is desired, otherwise
210 * this string must be set to empty.
211 * @param username On return, the callback must fill in with the
212 * username.
213 * @param nonce On return, the callback may optionally fill in
214 * this argument with NONCE value if desired,
215 * otherwise this argument must be set to empty.
216 * @param data_type On return, the callback must set this argument
217 * with the type of password in the data argument.
218 * @param data On return, the callback must set this with
219 * the password, encoded according to data_type
220 * argument.
221 *
222 * @return The callback must return PJ_SUCCESS, otherwise
223 * the message transmission will be cancelled.
224 */
225 pj_status_t (*get_cred)(const pj_stun_msg *msg,
226 void *user_data,
227 pj_pool_t *pool,
228 pj_str_t *realm,
229 pj_str_t *username,
230 pj_str_t *nonce,
231 pj_stun_passwd_type *data_type,
232 pj_str_t *data);
233
234 /**
235 * Get the password for the specified username. This function
236 * is also used to check whether the username is valid.
237 *
238 * @param msg The STUN message where the password will be
239 * applied to.
240 * @param user_data The user data as specified in the credential.
241 * @param realm The realm as specified in the message.
242 * @param username The username as specified in the message.
243 * @param pool Pool to allocate memory when necessary.
244 * @param data_type On return, application should fill up this
245 * argument with the type of data (which should
246 * be zero if data is a plaintext password).
247 * @param data On return, application should fill up this
248 * argument with the password according to
249 * data_type.
250 *
251 * @return The callback should return PJ_SUCCESS if
252 * username has been successfully verified
253 * and password was obtained. If non-PJ_SUCCESS
254 * is returned, it is assumed that the
255 * username is not valid.
256 */
257 pj_status_t (*get_password)(const pj_stun_msg *msg,
258 void *user_data,
259 const pj_str_t *realm,
260 const pj_str_t *username,
261 pj_pool_t *pool,
262 pj_stun_passwd_type *data_type,
263 pj_str_t *data);
264
265 /**
266 * This callback will be called to verify that the NONCE given
267 * in the message can be accepted. If this callback returns
268 * PJ_FALSE, 438 (Stale Nonce) response will be created.
269 *
270 * This callback is optional.
271 *
272 * @param msg The STUN message where the nonce was received.
273 * @param user_data The user data as specified in the credential.
274 * @param realm The realm as specified in the message.
275 * @param username The username as specified in the message.
276 * @param nonce The nonce to be verified.
277 *
278 * @return The callback MUST return non-zero if the
279 * NONCE can be accepted.
280 */
281 pj_bool_t (*verify_nonce)(const pj_stun_msg *msg,
282 void *user_data,
283 const pj_str_t *realm,
284 const pj_str_t *username,
285 const pj_str_t *nonce);
286
287 } dyn_cred;
288
289 } data;
290
291} pj_stun_auth_cred;
292
293
294/**
295 * This structure contains the credential information that is found and
296 * used to authenticate incoming requests. Application may use this
297 * information when generating authentication for the outgoing response.
298 */
299typedef struct pj_stun_req_cred_info
300{
301 /**
302 * The REALM value found in the incoming request. If short term
303 * credential is used, the value will be empty.
304 */
305 pj_str_t realm;
306
307 /**
308 * The USERNAME value found in the incoming request.
309 */
310 pj_str_t username;
311
312 /**
313 * Optional NONCE.
314 */
315 pj_str_t nonce;
316
317 /**
318 * Authentication key that was used to authenticate the incoming
319 * request. This key is created with #pj_stun_create_key(), and
320 * it can be used to encode the credential of the outgoing
321 * response.
322 */
323 pj_str_t auth_key;
324
325} pj_stun_req_cred_info;
326
327
328/**
329 * Duplicate authentication credential.
330 *
331 * @param pool Pool to be used to allocate memory.
332 * @param dst Destination credential.
333 * @param src Source credential.
334 */
335PJ_DECL(void) pj_stun_auth_cred_dup(pj_pool_t *pool,
336 pj_stun_auth_cred *dst,
337 const pj_stun_auth_cred *src);
338
339/**
340 * Duplicate request credential.
341 *
342 * @param pool Pool to be used to allocate memory.
343 * @param dst Destination credential.
344 * @param src Source credential.
345 */
346PJ_DECL(void) pj_stun_req_cred_info_dup(pj_pool_t *pool,
347 pj_stun_req_cred_info *dst,
348 const pj_stun_req_cred_info *src);
349
350
351/**
352 * Create authentication key to be used for encoding the message with
353 * MESSAGE-INTEGRITY. If short term credential is used (i.e. the realm
354 * argument is NULL or empty), the key will be copied from the password.
355 * If long term credential is used, the key will be calculated from the
356 * MD5 hash of the realm, username, and password.
357 *
358 * @param pool Pool to allocate memory for the key.
359 * @param key String to receive the key.
360 * @param realm The realm of the credential, if long term credential
361 * is to be used. If short term credential is wanted,
362 * application can put NULL or empty string here.
363 * @param username The username.
364 * @param data_type Password encoding.
365 * @param data The password.
366 */
367PJ_DECL(void) pj_stun_create_key(pj_pool_t *pool,
368 pj_str_t *key,
369 const pj_str_t *realm,
370 const pj_str_t *username,
371 pj_stun_passwd_type data_type,
372 const pj_str_t *data);
373
374/**
375 * Verify credential in the STUN request. Note that before calling this
376 * function, application must have checked that the message contains
377 * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
378 * function, because this function will reject the message with 401 error
379 * if it doesn't contain PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute.
380 *
381 * @param pkt The original packet which has been parsed into
382 * the message. This packet MUST NOT have been modified
383 * after the parsing.
384 * @param pkt_len The length of the packet.
385 * @param msg The parsed message to be verified.
386 * @param cred Pointer to credential to be used to authenticate
387 * the message.
388 * @param pool If response is to be created, then memory will
389 * be allocated from this pool.
390 * @param info Optional pointer to receive authentication information
391 * found in the request and the credential that is used
392 * to authenticate the request.
393 * @param p_response Optional pointer to receive the response message
394 * then the credential in the request fails to
395 * authenticate.
396 *
397 * @return PJ_SUCCESS if credential is verified successfully.
398 * If the verification fails and \a p_response is not
399 * NULL, an appropriate response will be returned in
400 * \a p_response.
401 */
402PJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
403 unsigned pkt_len,
404 const pj_stun_msg *msg,
405 pj_stun_auth_cred *cred,
406 pj_pool_t *pool,
407 pj_stun_req_cred_info *info,
408 pj_stun_msg **p_response);
409
410
411/**
412 * Determine if STUN message can be authenticated. Some STUN error
413 * responses cannot be authenticated since they cannot contain STUN
414 * MESSAGE-INTEGRITY attribute. STUN Indication messages also cannot
415 * be authenticated.
416 *
417 * @param msg The STUN message.
418 *
419 * @return Non-zero if the STUN message can be authenticated.
420 */
421PJ_DECL(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg);
422
423
424/**
425 * Verify credential in the STUN response. Note that before calling this
426 * function, application must have checked that the message contains
427 * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
428 * function, because otherwise this function will report authentication
429 * failure.
430 *
431 * @param pkt The original packet which has been parsed into
432 * the message. This packet MUST NOT have been modified
433 * after the parsing.
434 * @param pkt_len The length of the packet.
435 * @param msg The parsed message to be verified.
436 * @param key Authentication key to calculate MESSAGE-INTEGRITY
437 * value. Application can create this key by using
438 * #pj_stun_create_key() function.
439 *
440 * @return PJ_SUCCESS if credential is verified successfully.
441 */
442PJ_DECL(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt,
443 unsigned pkt_len,
444 const pj_stun_msg *msg,
445 const pj_str_t *key);
446
447
448/**
449 * @}
450 */
451
452
453PJ_END_DECL
454
455
456#endif /* __PJNATH_STUN_AUTH_H__ */
457