~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjsip/src/pjsip/sip_auth_parser.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sip_auth_parser.c 3553 2011-05-05 06:14:19Z nanang $ */
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
 
#include <pjsip/sip_auth_parser.h>
21
 
#include <pjsip/sip_auth_msg.h>
22
 
#include <pjsip/sip_parser.h>
23
 
#include <pj/assert.h>
24
 
#include <pj/string.h>
25
 
#include <pj/except.h>
26
 
#include <pj/pool.h>
27
 
 
28
 
static pjsip_hdr* parse_hdr_authorization       ( pjsip_parse_ctx *ctx );
29
 
static pjsip_hdr* parse_hdr_proxy_authorization ( pjsip_parse_ctx *ctx );
30
 
static pjsip_hdr* parse_hdr_www_authenticate    ( pjsip_parse_ctx *ctx );
31
 
static pjsip_hdr* parse_hdr_proxy_authenticate  ( pjsip_parse_ctx *ctx );
32
 
 
33
 
static void parse_digest_credential ( pj_scanner *scanner, pj_pool_t *pool,
34
 
                                      pjsip_digest_credential *cred);
35
 
static void parse_pgp_credential    ( pj_scanner *scanner, pj_pool_t *pool,
36
 
                                      pjsip_pgp_credential *cred);
37
 
static void parse_digest_challenge  ( pj_scanner *scanner, pj_pool_t *pool,
38
 
                                      pjsip_digest_challenge *chal);
39
 
static void parse_pgp_challenge     ( pj_scanner *scanner, pj_pool_t *pool,
40
 
                                      pjsip_pgp_challenge *chal);
41
 
 
42
 
const pj_str_t  pjsip_USERNAME_STR =        { "username", 8 },
43
 
                pjsip_REALM_STR =           { "realm", 5},
44
 
                pjsip_NONCE_STR =           { "nonce", 5},
45
 
                pjsip_URI_STR =             { "uri", 3 },
46
 
                pjsip_RESPONSE_STR =        { "response", 8 },
47
 
                pjsip_ALGORITHM_STR =       { "algorithm", 9 },
48
 
                pjsip_DOMAIN_STR =          { "domain", 6 },
49
 
                pjsip_STALE_STR =           { "stale", 5},
50
 
                pjsip_QOP_STR =             { "qop", 3},
51
 
                pjsip_CNONCE_STR =          { "cnonce", 6},
52
 
                pjsip_OPAQUE_STR =          { "opaque", 6},
53
 
                pjsip_NC_STR =              { "nc", 2},
54
 
                pjsip_TRUE_STR =            { "true", 4},
55
 
                pjsip_QUOTED_TRUE_STR =     { "\"true\"", 6},
56
 
                pjsip_FALSE_STR =           { "false", 5},
57
 
                pjsip_QUOTED_FALSE_STR =    { "\"false\"", 7},
58
 
                pjsip_DIGEST_STR =          { "Digest", 6},
59
 
                pjsip_QUOTED_DIGEST_STR =   { "\"Digest\"", 8},
60
 
                pjsip_PGP_STR =             { "PGP", 3 },
61
 
                pjsip_QUOTED_PGP_STR =      { "\"PGP\"", 5 },
62
 
                pjsip_MD5_STR =             { "md5", 3 },
63
 
                pjsip_QUOTED_MD5_STR =      { "\"md5\"", 5},
64
 
                pjsip_AUTH_STR =            { "auth", 4},
65
 
                pjsip_QUOTED_AUTH_STR =     { "\"auth\"", 6 };
66
 
 
67
 
 
68
 
static void parse_digest_credential( pj_scanner *scanner, pj_pool_t *pool,
69
 
                                     pjsip_digest_credential *cred)
70
 
{
71
 
    pj_list_init(&cred->other_param);
72
 
 
73
 
    for (;;) {
74
 
        pj_str_t name, value;
75
 
 
76
 
        pjsip_parse_param_imp(scanner, pool, &name, &value,
77
 
                              PJSIP_PARSE_REMOVE_QUOTE);
78
 
 
79
 
        if (!pj_stricmp(&name, &pjsip_USERNAME_STR)) {
80
 
            cred->username = value;
81
 
 
82
 
        } else if (!pj_stricmp(&name, &pjsip_REALM_STR)) {
83
 
            cred->realm = value;
84
 
 
85
 
        } else if (!pj_stricmp(&name, &pjsip_NONCE_STR)) {
86
 
            cred->nonce = value;
87
 
 
88
 
        } else if (!pj_stricmp(&name, &pjsip_URI_STR)) {
89
 
            cred->uri = value;
90
 
 
91
 
        } else if (!pj_stricmp(&name, &pjsip_RESPONSE_STR)) {
92
 
            cred->response = value;
93
 
 
94
 
        } else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {
95
 
            cred->algorithm = value;
96
 
 
97
 
        } else if (!pj_stricmp(&name, &pjsip_CNONCE_STR)) {
98
 
            cred->cnonce = value;
99
 
 
100
 
        } else if (!pj_stricmp(&name, &pjsip_OPAQUE_STR)) {
101
 
            cred->opaque = value;
102
 
 
103
 
        } else if (!pj_stricmp(&name, &pjsip_QOP_STR)) {
104
 
            cred->qop = value;
105
 
 
106
 
        } else if (!pj_stricmp(&name, &pjsip_NC_STR)) {
107
 
            cred->nc = value;
108
 
 
109
 
        } else {
110
 
            pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
111
 
            p->name = name;
112
 
            p->value = value;
113
 
            pj_list_insert_before(&cred->other_param, p);
114
 
        }
115
 
 
116
 
        /* Eat comma */
117
 
        if (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')
118
 
            pj_scan_get_char(scanner);
119
 
        else
120
 
            break;
121
 
    }
122
 
}
123
 
 
124
 
static void parse_pgp_credential( pj_scanner *scanner, pj_pool_t *pool,
125
 
                                  pjsip_pgp_credential *cred)
126
 
{
127
 
    PJ_UNUSED_ARG(scanner);
128
 
    PJ_UNUSED_ARG(pool);
129
 
    PJ_UNUSED_ARG(cred);
130
 
 
131
 
    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
132
 
}
133
 
 
134
 
static void parse_digest_challenge( pj_scanner *scanner, pj_pool_t *pool,
135
 
                                    pjsip_digest_challenge *chal)
136
 
{
137
 
    pj_list_init(&chal->other_param);
138
 
 
139
 
    for (;;) {
140
 
        pj_str_t name, value;
141
 
 
142
 
        pjsip_parse_param_imp(scanner, pool, &name, &value,
143
 
                              PJSIP_PARSE_REMOVE_QUOTE);
144
 
 
145
 
        if (!pj_stricmp(&name, &pjsip_REALM_STR)) {
146
 
            chal->realm = value;
147
 
 
148
 
        } else if (!pj_stricmp(&name, &pjsip_DOMAIN_STR)) {
149
 
            chal->domain = value;
150
 
 
151
 
        } else if (!pj_stricmp(&name, &pjsip_NONCE_STR)) {
152
 
            chal->nonce = value;
153
 
 
154
 
        } else if (!pj_stricmp(&name, &pjsip_OPAQUE_STR)) {
155
 
            chal->opaque = value;
156
 
 
157
 
        } else if (!pj_stricmp(&name, &pjsip_STALE_STR)) {
158
 
            if (!pj_stricmp(&value, &pjsip_TRUE_STR) ||
159
 
                !pj_stricmp(&value, &pjsip_QUOTED_TRUE_STR))
160
 
            {
161
 
                chal->stale = 1;
162
 
            }
163
 
 
164
 
        } else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {
165
 
            chal->algorithm = value;
166
 
 
167
 
 
168
 
        } else if (!pj_stricmp(&name, &pjsip_QOP_STR)) {
169
 
            chal->qop = value;
170
 
 
171
 
        } else {
172
 
            pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
173
 
            p->name = name;
174
 
            p->value = value;
175
 
            pj_list_insert_before(&chal->other_param, p);
176
 
        }
177
 
 
178
 
        /* Eat comma */
179
 
        if (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')
180
 
            pj_scan_get_char(scanner);
181
 
        else
182
 
            break;
183
 
    }
184
 
}
185
 
 
186
 
static void parse_pgp_challenge( pj_scanner *scanner, pj_pool_t *pool,
187
 
                                 pjsip_pgp_challenge *chal)
188
 
{
189
 
    PJ_UNUSED_ARG(scanner);
190
 
    PJ_UNUSED_ARG(pool);
191
 
    PJ_UNUSED_ARG(chal);
192
 
 
193
 
    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
194
 
}
195
 
 
196
 
static void int_parse_hdr_authorization( pj_scanner *scanner, pj_pool_t *pool,
197
 
                                         pjsip_authorization_hdr *hdr)
198
 
{
199
 
    const pjsip_parser_const_t *pc = pjsip_parser_const();
200
 
 
201
 
    if (*scanner->curptr == '"') {
202
 
        pj_scan_get_quote(scanner, '"', '"', &hdr->scheme);
203
 
        hdr->scheme.ptr++;
204
 
        hdr->scheme.slen -= 2;
205
 
    } else {
206
 
        pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &hdr->scheme);
207
 
    }
208
 
 
209
 
    if (!pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR)) {
210
 
 
211
 
        parse_digest_credential(scanner, pool, &hdr->credential.digest);
212
 
 
213
 
    } else if (!pj_stricmp(&hdr->scheme, &pjsip_PGP_STR)) {
214
 
 
215
 
        parse_pgp_credential( scanner, pool, &hdr->credential.pgp);
216
 
 
217
 
    } else {
218
 
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
219
 
    }
220
 
 
221
 
    pjsip_parse_end_hdr_imp( scanner );
222
 
}
223
 
 
224
 
static void int_parse_hdr_authenticate( pj_scanner *scanner, pj_pool_t *pool,
225
 
                                        pjsip_www_authenticate_hdr *hdr)
226
 
{
227
 
    const pjsip_parser_const_t *pc = pjsip_parser_const();
228
 
 
229
 
    if (*scanner->curptr == '"') {
230
 
        pj_scan_get_quote(scanner, '"', '"', &hdr->scheme);
231
 
        hdr->scheme.ptr++;
232
 
        hdr->scheme.slen -= 2;
233
 
    } else {
234
 
        pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &hdr->scheme);
235
 
    }
236
 
 
237
 
    if (!pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR)) {
238
 
 
239
 
        parse_digest_challenge(scanner, pool, &hdr->challenge.digest);
240
 
 
241
 
    } else if (!pj_stricmp(&hdr->scheme, &pjsip_PGP_STR)) {
242
 
 
243
 
        parse_pgp_challenge(scanner, pool, &hdr->challenge.pgp);
244
 
 
245
 
    } else {
246
 
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
247
 
    }
248
 
 
249
 
    pjsip_parse_end_hdr_imp( scanner );
250
 
}
251
 
 
252
 
 
253
 
static pjsip_hdr* parse_hdr_authorization( pjsip_parse_ctx *ctx )
254
 
{
255
 
    pjsip_authorization_hdr *hdr = pjsip_authorization_hdr_create(ctx->pool);
256
 
    int_parse_hdr_authorization(ctx->scanner, ctx->pool, hdr);
257
 
    return (pjsip_hdr*)hdr;
258
 
}
259
 
 
260
 
static pjsip_hdr* parse_hdr_proxy_authorization( pjsip_parse_ctx *ctx )
261
 
{
262
 
    pjsip_proxy_authorization_hdr *hdr =
263
 
        pjsip_proxy_authorization_hdr_create(ctx->pool);
264
 
    int_parse_hdr_authorization(ctx->scanner, ctx->pool, hdr);
265
 
    return (pjsip_hdr*)hdr;
266
 
}
267
 
 
268
 
static pjsip_hdr* parse_hdr_www_authenticate( pjsip_parse_ctx *ctx )
269
 
{
270
 
    pjsip_www_authenticate_hdr *hdr =
271
 
        pjsip_www_authenticate_hdr_create(ctx->pool);
272
 
    int_parse_hdr_authenticate(ctx->scanner, ctx->pool, hdr);
273
 
    return (pjsip_hdr*)hdr;
274
 
}
275
 
 
276
 
static pjsip_hdr* parse_hdr_proxy_authenticate( pjsip_parse_ctx *ctx )
277
 
{
278
 
    pjsip_proxy_authenticate_hdr *hdr =
279
 
        pjsip_proxy_authenticate_hdr_create(ctx->pool);
280
 
    int_parse_hdr_authenticate(ctx->scanner, ctx->pool, hdr);
281
 
    return (pjsip_hdr*)hdr;
282
 
}
283
 
 
284
 
 
285
 
PJ_DEF(pj_status_t) pjsip_auth_init_parser()
286
 
{
287
 
    pj_status_t status;
288
 
 
289
 
    status = pjsip_register_hdr_parser( "Authorization", NULL,
290
 
                                        &parse_hdr_authorization);
291
 
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
292
 
    status = pjsip_register_hdr_parser( "Proxy-Authorization", NULL,
293
 
                                        &parse_hdr_proxy_authorization);
294
 
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
295
 
    status = pjsip_register_hdr_parser( "WWW-Authenticate", NULL,
296
 
                                        &parse_hdr_www_authenticate);
297
 
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
298
 
    status = pjsip_register_hdr_parser( "Proxy-Authenticate", NULL,
299
 
                                        &parse_hdr_proxy_authenticate);
300
 
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
301
 
 
302
 
    return PJ_SUCCESS;
303
 
}
304
 
 
305
 
PJ_DEF(void) pjsip_auth_deinit_parser()
306
 
{
307
 
}