1
/* $Id: sip_auth.h 4214 2012-07-25 14:29:28Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
20
#ifndef __PJSIP_AUTH_SIP_AUTH_H__
21
#define __PJSIP_AUTH_SIP_AUTH_H__
25
* @brief SIP Authorization Module.
28
#include <pjsip/sip_config.h>
29
#include <pjsip/sip_auth_msg.h>
34
* @addtogroup PJSIP_AUTH
36
* @brief Client and server side authentication framework.
40
* @defgroup PJSIP_AUTH_API Authentication API's
42
* @brief Structures and functions to perform authentication.
46
/** Length of digest string. */
47
#define PJSIP_MD5STRLEN 32
50
/** Type of data in the credential information in #pjsip_cred_info. */
51
typedef enum pjsip_cred_data_type
53
PJSIP_CRED_DATA_PLAIN_PASSWD=0, /**< Plain text password. */
54
PJSIP_CRED_DATA_DIGEST =1, /**< Hashed digest. */
56
PJSIP_CRED_DATA_EXT_AKA =16 /**< Extended AKA info is available */
58
} pjsip_cred_data_type;
60
/** Authentication's quality of protection (qop) type. */
61
typedef enum pjsip_auth_qop_type
63
PJSIP_AUTH_QOP_NONE, /**< No quality of protection. */
64
PJSIP_AUTH_QOP_AUTH, /**< Authentication. */
65
PJSIP_AUTH_QOP_AUTH_INT, /**< Authentication with integrity protection. */
66
PJSIP_AUTH_QOP_UNKNOWN /**< Unknown protection. */
67
} pjsip_auth_qop_type;
71
* Type of callback function to create authentication response.
72
* Application can specify this callback in \a cb field of the credential info
73
* (#pjsip_cred_info) and specifying PJSIP_CRED_DATA_DIGEST_CALLBACK as
74
* \a data_type. When this function is called, most of the fields in the
75
* \a auth authentication response will have been filled by the framework.
76
* Application normally should just need to calculate the response digest
77
* of the authentication response.
79
* @param pool Pool to allocate memory from if application needs to.
80
* @param chal The authentication challenge sent by server in 401
81
* or 401 response, in either Proxy-Authenticate or
82
* WWW-Authenticate header.
83
* @param cred The credential that has been selected by the framework
84
* to authenticate against the challenge.
85
* @param auth The authentication response which application needs to
86
* calculate the response digest.
88
* @return Application may return non-PJ_SUCCESS to abort the
89
* authentication process. When this happens, the
90
* framework will return failure to the original function
91
* that requested authentication.
93
typedef pj_status_t (*pjsip_cred_cb)(pj_pool_t *pool,
94
const pjsip_digest_challenge *chal,
95
const pjsip_cred_info *cred,
96
const pj_str_t *method,
97
pjsip_digest_credential *auth);
101
* This structure describes credential information.
102
* A credential information is a static, persistent information that identifies
103
* username and password required to authorize to a specific realm.
105
* Note that since PJSIP 0.7.0.1, it is possible to make a credential that is
106
* valid for any realms, by setting the realm to star/wildcard character,
107
* i.e. realm = pj_str("*");.
109
struct pjsip_cred_info
111
pj_str_t realm; /**< Realm. Use "*" to make a credential that
112
can be used to authenticate against any
114
pj_str_t scheme; /**< Scheme (e.g. "digest"). */
115
pj_str_t username; /**< User name. */
116
int data_type; /**< Type of data (0 for plaintext passwd). */
117
pj_str_t data; /**< The data, which can be a plaintext
118
password or a hashed digest. */
122
/** Digest AKA credential information. Note that when AKA credential
123
* is being used, the \a data field of this #pjsip_cred_info is
124
* not used, but it still must be initialized to an empty string.
125
* Please see \ref PJSIP_AUTH_AKA_API for more information.
128
pj_str_t k; /**< Permanent subscriber key. */
129
pj_str_t op; /**< Operator variant key. */
130
pj_str_t amf; /**< Authentication Management Field */
131
pjsip_cred_cb cb; /**< Callback to create AKA digest. */
138
* This structure describes cached value of previously sent Authorization
139
* or Proxy-Authorization header. The authentication framework keeps a list
140
* of this structure and will resend the same header to the same server
141
* as long as the method, uri, and nonce stays the same.
143
typedef struct pjsip_cached_auth_hdr
145
/** Standard list member */
146
PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth_hdr);
148
pjsip_method method; /**< To quickly see the method. */
149
pjsip_authorization_hdr *hdr; /**< The cached header. */
151
} pjsip_cached_auth_hdr;
155
* This structure describes authentication information for the specified
156
* realm. Each instance of this structure describes authentication "session"
157
* between this endpoint and remote server. This "session" information is
158
* usefull to keep information that persists for more than one challenge,
159
* such as nonce-count and cnonce value.
161
* Other than that, this structure also keeps the last authorization headers
162
* that have been sent in the cache list.
164
typedef struct pjsip_cached_auth
166
/** Standard list member */
167
PJ_DECL_LIST_MEMBER(struct pjsip_cached_auth);
169
pj_str_t realm; /**< Realm. */
170
pj_bool_t is_proxy; /**< Server type (401/407) */
171
pjsip_auth_qop_type qop_value; /**< qop required by server. */
172
unsigned stale_cnt; /**< Number of stale retry. */
173
#if PJSIP_AUTH_QOP_SUPPORT
174
pj_uint32_t nc; /**< Nonce count. */
175
pj_str_t cnonce; /**< Cnonce value. */
177
pjsip_www_authenticate_hdr *last_chal; /**< Last challenge seen. */
178
#if PJSIP_AUTH_HEADER_CACHING
179
pjsip_cached_auth_hdr cached_hdr;/**< List of cached header for
187
* This structure describes client authentication session preference.
188
* The preference can be set by calling #pjsip_auth_clt_set_prefs().
190
typedef struct pjsip_auth_clt_pref
193
* If this flag is set, the authentication client framework will
194
* send an empty Authorization header in each initial request.
197
pj_bool_t initial_auth;
200
* Specify the algorithm to use when empty Authorization header
201
* is to be sent for each initial request (see above)
205
} pjsip_auth_clt_pref;
209
* Duplicate a client authentication preference setting.
211
* @param pool The memory pool.
212
* @param dst Destination client authentication preference.
213
* @param src Source client authentication preference.
215
PJ_DECL(void) pjsip_auth_clt_pref_dup(pj_pool_t *pool,
216
pjsip_auth_clt_pref *dst,
217
const pjsip_auth_clt_pref *src);
221
* This structure describes client authentication sessions. It keeps
222
* all the information needed to authorize the client against all downstream
225
typedef struct pjsip_auth_clt_sess
227
pj_pool_t *pool; /**< Pool to use. */
228
pjsip_endpoint *endpt; /**< Endpoint where this belongs. */
229
pjsip_auth_clt_pref pref; /**< Preference/options. */
230
unsigned cred_cnt; /**< Number of credentials. */
231
pjsip_cred_info *cred_info; /**< Array of credential information*/
232
pjsip_cached_auth cached_auth; /**< Cached authorization info. */
234
} pjsip_auth_clt_sess;
238
* Duplicate a credential info.
240
* @param pool The memory pool.
241
* @param dst Destination credential.
242
* @param src Source credential.
244
PJ_DECL(void) pjsip_cred_info_dup(pj_pool_t *pool,
245
pjsip_cred_info *dst,
246
const pjsip_cred_info *src);
249
* Compare two credential infos.
251
* @param cred1 The credential info to compare.
252
* @param cred2 The credential info to compare.
254
* @return 0 if both credentials are equal.
256
PJ_DECL(int) pjsip_cred_info_cmp(const pjsip_cred_info *cred1,
257
const pjsip_cred_info *cred2);
261
* Type of function to lookup credential for the specified name.
263
* @param pool Pool to initialize the credential info.
264
* @param realm Realm to find the account.
265
* @param acc_name Account name to look for.
266
* @param cred_info The structure to put the credential when it's found.
268
* @return The function MUST return PJ_SUCCESS when it found
269
* a correct credential for the specified account and
270
* realm. Otherwise it may return PJSIP_EAUTHACCNOTFOUND
271
* or PJSIP_EAUTHACCDISABLED.
273
typedef pj_status_t pjsip_auth_lookup_cred( pj_pool_t *pool,
274
const pj_str_t *realm,
275
const pj_str_t *acc_name,
276
pjsip_cred_info *cred_info );
280
* This structure describes input param for credential lookup.
282
typedef struct pjsip_auth_lookup_cred_param
284
pj_str_t realm; /**< Realm to find the account. */
285
pj_str_t acc_name; /**< Account name to look for. */
286
pjsip_rx_data *rdata; /**< Incoming request to be authenticated. */
288
} pjsip_auth_lookup_cred_param;
292
* Type of function to lookup credential for the specified name.
294
* @param pool Pool to initialize the credential info.
295
* @param param The input param for credential lookup.
296
* @param cred_info The structure to put the credential when it's found.
298
* @return The function MUST return PJ_SUCCESS when it found
299
* a correct credential for the specified account and
300
* realm. Otherwise it may return PJSIP_EAUTHACCNOTFOUND
301
* or PJSIP_EAUTHACCDISABLED.
303
typedef pj_status_t pjsip_auth_lookup_cred2(
305
const pjsip_auth_lookup_cred_param *param,
306
pjsip_cred_info *cred_info );
309
/** Flag to specify that server is a proxy. */
310
#define PJSIP_AUTH_SRV_IS_PROXY 1
313
* This structure describes server authentication information.
315
typedef struct pjsip_auth_srv
317
pj_str_t realm; /**< Realm to serve. */
318
pj_bool_t is_proxy; /**< Will issue 407 instead of 401 */
319
pjsip_auth_lookup_cred *lookup; /**< Lookup function. */
320
pjsip_auth_lookup_cred2 *lookup2; /**< Lookup function with additional
321
info in its input param. */
326
* Initialize client authentication session data structure, and set the
327
* session to use pool for its subsequent memory allocation. The argument
328
* options should be set to zero for this PJSIP version.
330
* @param sess The client authentication session.
331
* @param endpt Endpoint where this session belongs.
332
* @param pool Pool to use.
333
* @param options Must be zero.
335
* @return PJ_SUCCESS on success.
337
PJ_DECL(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
338
pjsip_endpoint *endpt,
344
* Clone client initialization session.
346
* @param pool Pool to use.
347
* @param sess Structure to put the duplicated session.
348
* @param rhs The client session to be cloned.
350
* @return PJ_SUCCESS on success;
352
PJ_DECL(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
353
pjsip_auth_clt_sess *sess,
354
const pjsip_auth_clt_sess *rhs);
357
* Set the credentials to be used during the session. This will duplicate
358
* the specified credentials using client authentication's pool.
360
* @param sess The client authentication session.
361
* @param cred_cnt Number of credentials.
362
* @param c Array of credentials.
364
* @return PJ_SUCCESS on success.
366
PJ_DECL(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
368
const pjsip_cred_info *c);
372
* Set the preference for the client authentication session.
374
* @param sess The client authentication session.
375
* @param p Preference.
377
* @return PJ_SUCCESS on success.
379
PJ_DECL(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,
380
const pjsip_auth_clt_pref *p);
384
* Get the preference for the client authentication session.
386
* @param sess The client authentication session.
387
* @param p Pointer to receive the preference.
389
* @return PJ_SUCCESS on success.
391
PJ_DECL(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
392
pjsip_auth_clt_pref *p);
395
* Initialize new request message with authorization headers.
396
* This function will put Authorization/Proxy-Authorization headers to the
397
* outgoing request message. If caching is enabled (PJSIP_AUTH_HEADER_CACHING)
398
* and the session has previously sent Authorization/Proxy-Authorization header
399
* with the same method, then the same Authorization/Proxy-Authorization header
400
* will be resent from the cache only if qop is not present. If the stack is
401
* configured to automatically generate next Authorization/Proxy-Authorization
402
* headers (PJSIP_AUTH_AUTO_SEND_NEXT flag), then new Authorization/Proxy-
403
* Authorization headers are calculated and generated when they are not present
404
* in the case or if authorization session has qop.
406
* If both PJSIP_AUTH_HEADER_CACHING flag and PJSIP_AUTH_AUTO_SEND_NEXT flag
407
* are not set, this function will do nothing. The stack then will only send
408
* Authorization/Proxy-Authorization to respond 401/407 response.
410
* @param sess The client authentication session.
411
* @param tdata The request message to be initialized.
413
* @return PJ_SUCCESS if successfull.
415
PJ_DECL(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
416
pjsip_tx_data *tdata );
420
* Call this function when a transaction failed with 401 or 407 response.
421
* This function will reinitialize the original request message with the
422
* authentication challenge found in the response message, and add the
423
* new authorization header in the authorization cache.
425
* Note that upon return the reference counter of the new transmit data
428
* @param sess The client authentication session.
429
* @param rdata The response message containing 401/407 status.
430
* @param old_request The original request message, which will be re-
431
* created with authorization info.
432
* @param new_request Pointer to receive new request message which
433
* will contain all required authorization headers.
435
* @return PJ_SUCCESS if new request can be successfully
436
* created to respond all the authentication
439
PJ_DECL(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
440
const pjsip_rx_data *rdata,
441
pjsip_tx_data *old_request,
442
pjsip_tx_data **new_request );
445
* Initialize server authorization session data structure to serve the
446
* specified realm and to use lookup_func function to look for the credential
449
* @param pool Pool used to initialize the authentication server.
450
* @param auth_srv The authentication server structure.
451
* @param realm Realm to be served by the server.
452
* @param lookup Account lookup function.
453
* @param options Options, bitmask of:
454
* - PJSIP_AUTH_SRV_IS_PROXY: to specify that the server
455
* will authorize clients as a proxy server (instead of
456
* as UAS), which means that Proxy-Authenticate will
457
* be used instead of WWW-Authenticate.
459
* @return PJ_SUCCESS on success.
461
PJ_DECL(pj_status_t) pjsip_auth_srv_init( pj_pool_t *pool,
462
pjsip_auth_srv *auth_srv,
463
const pj_str_t *realm,
464
pjsip_auth_lookup_cred *lookup,
469
* This structure describes initialization settings of server authorization
472
typedef struct pjsip_auth_srv_init_param
475
* Realm to be served by the server.
477
const pj_str_t *realm;
480
* Account lookup function.
482
pjsip_auth_lookup_cred2 *lookup2;
485
* Options, bitmask of:
486
* - PJSIP_AUTH_SRV_IS_PROXY: to specify that the server will authorize
487
* clients as a proxy server (instead of as UAS), which means that
488
* Proxy-Authenticate will be used instead of WWW-Authenticate.
492
} pjsip_auth_srv_init_param;
496
* Initialize server authorization session data structure to serve the
497
* specified realm and to use lookup_func function to look for the credential
500
* @param pool Pool used to initialize the authentication server.
501
* @param auth_srv The authentication server structure.
502
* @param param The initialization param.
504
* @return PJ_SUCCESS on success.
506
PJ_DECL(pj_status_t) pjsip_auth_srv_init2(
508
pjsip_auth_srv *auth_srv,
509
const pjsip_auth_srv_init_param *param);
512
* Request the authorization server framework to verify the authorization
513
* information in the specified request in rdata.
515
* @param auth_srv The server authentication structure.
516
* @param rdata Incoming request to be authenticated.
517
* @param status_code When not null, it will be filled with suitable
518
* status code to be sent to the client.
520
* @return PJ_SUCCESS if request is successfully authenticated.
521
* Otherwise the function may return one of the
522
* following error codes:
523
* - PJSIP_EAUTHNOAUTH
524
* - PJSIP_EINVALIDAUTHSCHEME
525
* - PJSIP_EAUTHACCNOTFOUND
526
* - PJSIP_EAUTHACCDISABLED
527
* - PJSIP_EAUTHINVALIDREALM
528
* - PJSIP_EAUTHINVALIDDIGEST
530
PJ_DECL(pj_status_t) pjsip_auth_srv_verify( pjsip_auth_srv *auth_srv,
531
pjsip_rx_data *rdata,
536
* Add authentication challenge headers to the outgoing response in tdata.
537
* Application may specify its customized nonce and opaque for the challenge,
538
* or can leave the value to NULL to make the function fills them in with
541
* @param auth_srv The server authentication structure.
542
* @param qop Optional qop value.
543
* @param nonce Optional nonce value.
544
* @param opaque Optional opaque value.
545
* @param stale Stale indication.
546
* @param tdata The outgoing response message. The response must have
547
* 401 or 407 response code.
549
* @return PJ_SUCCESS on success.
551
PJ_DECL(pj_status_t) pjsip_auth_srv_challenge( pjsip_auth_srv *auth_srv,
553
const pj_str_t *nonce,
554
const pj_str_t *opaque,
556
pjsip_tx_data *tdata);
559
* Helper function to create MD5 digest out of the specified
562
* @param result String to store the response digest. This string
563
* must have been preallocated by caller with the
564
* buffer at least PJSIP_MD5STRLEN (32 bytes) in size.
565
* @param nonce Optional nonce.
566
* @param nc Nonce count.
567
* @param cnonce Optional cnonce.
568
* @param qop Optional qop.
570
* @param realm Realm.
571
* @param cred_info Credential info.
572
* @param method SIP method.
574
PJ_DECL(void) pjsip_auth_create_digest(pj_str_t *result,
575
const pj_str_t *nonce,
577
const pj_str_t *cnonce,
580
const pj_str_t *realm,
581
const pjsip_cred_info *cred_info,
582
const pj_str_t *method);
593
#endif /* __PJSIP_AUTH_SIP_AUTH_H__ */