2 The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3 Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <osipparser2/osip_port.h>
25 #include <osipparser2/osip_message.h>
26 #include <osipparser2/osip_parser.h>
30 osip_authorization_init (osip_authorization_t ** dest)
33 (osip_authorization_t *) osip_malloc (sizeof (osip_authorization_t));
36 (*dest)->auth_type = NULL;
37 (*dest)->username = NULL;
38 (*dest)->realm = NULL;
39 (*dest)->nonce = NULL;
41 (*dest)->response = NULL;
42 (*dest)->digest = NULL; /* DO NOT USE IT IN AUTHORIZATION_T HEADER?? */
43 (*dest)->algorithm = NULL; /* optionnal, default is "md5" */
44 (*dest)->cnonce = NULL; /* optionnal */
45 (*dest)->opaque = NULL; /* optionnal */
46 (*dest)->message_qop = NULL; /* optionnal */
47 (*dest)->nonce_count = NULL; /* optionnal */
48 (*dest)->auth_param = NULL; /* for other headers --NOT IMPLEMENTED-- */
52 /* fills the www-authenticate header of message. */
53 /* INPUT : char *hvalue | value of header. */
54 /* OUTPUT: osip_message_t *sip | structure to save results. */
55 /* returns -1 on error. */
57 osip_message_set_authorization (osip_message_t * sip, const char *hvalue)
59 osip_authorization_t *authorization;
62 if (hvalue == NULL || hvalue[0] == '\0')
65 if (sip == NULL || sip->authorizations == NULL)
67 i = osip_authorization_init (&authorization);
70 i = osip_authorization_parse (authorization, hvalue);
73 osip_authorization_free (authorization);
76 sip->message_property = 2;
77 osip_list_add (sip->authorizations, authorization, -1);
81 /* fills the www-authenticate structure. */
82 /* INPUT : char *hvalue | value of header. */
83 /* OUTPUT: osip_message_t *sip | structure to save results. */
84 /* returns -1 on error. */
86 digest-challenge tken has no order preference??
87 verify many situations (extra SP....)
90 osip_authorization_parse (osip_authorization_t * auth, const char *hvalue)
93 const char *next = NULL;
95 space = strchr (hvalue, ' '); /* SEARCH FOR SPACE */
99 if (space - hvalue < 1)
101 auth->auth_type = (char *) osip_malloc (space - hvalue + 1);
102 osip_strncpy (auth->auth_type, hvalue, space - hvalue);
108 if (__osip_quoted_string_set
109 ("username", space, &(auth->username), &next))
112 return 0; /* end of header detected! */
113 else if (next != space)
118 if (__osip_quoted_string_set ("realm", space, &(auth->realm), &next))
122 else if (next != space)
127 if (__osip_quoted_string_set ("nonce", space, &(auth->nonce), &next))
130 return 0; /* end of header detected! */
131 else if (next != space)
136 if (__osip_quoted_string_set ("uri", space, &(auth->uri), &next))
139 return 0; /* end of header detected! */
140 else if (next != space)
145 if (__osip_quoted_string_set
146 ("response", space, &(auth->response), &next))
149 return 0; /* end of header detected! */
150 else if (next != space)
155 if (__osip_quoted_string_set ("digest", space, &(auth->digest), &next))
158 return 0; /* end of header detected! */
159 else if (next != space)
164 if (__osip_token_set ("algorithm", space, &(auth->algorithm), &next))
167 return 0; /* end of header detected! */
168 else if (next != space)
173 if (__osip_quoted_string_set ("cnonce", space, &(auth->cnonce), &next))
176 return 0; /* end of header detected! */
177 else if (next != space)
182 if (__osip_quoted_string_set ("opaque", space, &(auth->opaque), &next))
185 return 0; /* end of header detected! */
186 else if (next != space)
191 if (__osip_token_set ("qop", space, &(auth->message_qop), &next))
194 return 0; /* end of header detected! */
195 else if (next != space)
200 if (__osip_token_set ("nc", space, &(auth->nonce_count), &next))
203 return 0; /* end of header detected! */
204 else if (next != space)
209 /* nothing was recognized:
210 here, we should handle a list of unknown tokens where:
211 token1 = ( token2 | quoted_text ) */
216 const char *quote1, *quote2, *tmp;
219 /* parameter not understood!!! I'm too lazy to handle IT */
220 /* let's simply bypass it */
221 if (strlen (space) < 1)
223 tmp = strchr (space + 1, ',');
224 if (tmp == NULL) /* it was the last header */
226 quote1 = __osip_quote_find (space);
227 if ((quote1 != NULL) && (quote1 < tmp)) /* this may be a quoted string! */
229 quote2 = __osip_quote_find (quote1 + 1);
231 return -1; /* bad header format... */
232 if (tmp < quote2) /* the comma is inside the quotes! */
233 space = strchr (quote2, ',');
236 if (space == NULL) /* it was the last header */
241 /* continue parsing... */
247 /* returns the authorization header. */
248 /* INPUT : osip_message_t *sip | sip message. */
249 /* returns null on error. */
251 osip_message_get_authorization (const osip_message_t * sip, int pos,
252 osip_authorization_t ** dest)
254 osip_authorization_t *authorization;
257 if (osip_list_size (sip->authorizations) <= pos)
258 return -1; /* does not exist */
260 (osip_authorization_t *) osip_list_get (sip->authorizations, pos);
261 *dest = authorization;
266 osip_authorization_get_auth_type (const osip_authorization_t * authorization)
268 return authorization->auth_type;
272 osip_authorization_set_auth_type (osip_authorization_t * authorization,
275 authorization->auth_type = (char *) auth_type;
279 osip_authorization_get_username (osip_authorization_t * authorization)
281 return authorization->username;
285 osip_authorization_set_username (osip_authorization_t * authorization,
288 authorization->username = (char *) username;
292 osip_authorization_get_realm (osip_authorization_t * authorization)
294 return authorization->realm;
298 osip_authorization_set_realm (osip_authorization_t * authorization,
301 authorization->realm = (char *) realm;
305 osip_authorization_get_nonce (osip_authorization_t * authorization)
307 return authorization->nonce;
311 osip_authorization_set_nonce (osip_authorization_t * authorization,
314 authorization->nonce = (char *) nonce;
318 osip_authorization_get_uri (osip_authorization_t * authorization)
320 return authorization->uri;
324 osip_authorization_set_uri (osip_authorization_t * authorization, char *uri)
326 authorization->uri = (char *) uri;
330 osip_authorization_get_response (osip_authorization_t * authorization)
332 return authorization->response;
336 osip_authorization_set_response (osip_authorization_t * authorization,
339 authorization->response = (char *) response;
343 osip_authorization_get_digest (osip_authorization_t * authorization)
345 return authorization->digest;
349 osip_authorization_set_digest (osip_authorization_t * authorization,
352 authorization->digest = (char *) digest;
356 osip_authorization_get_algorithm (osip_authorization_t * authorization)
358 return authorization->algorithm;
362 osip_authorization_set_algorithm (osip_authorization_t * authorization,
365 authorization->algorithm = (char *) algorithm;
369 osip_authorization_get_cnonce (osip_authorization_t * authorization)
371 return authorization->cnonce;
375 osip_authorization_set_cnonce (osip_authorization_t * authorization,
378 authorization->cnonce = (char *) cnonce;
382 osip_authorization_get_opaque (osip_authorization_t * authorization)
384 return authorization->opaque;
388 osip_authorization_set_opaque (osip_authorization_t * authorization,
391 authorization->opaque = (char *) opaque;
395 osip_authorization_get_message_qop (osip_authorization_t * authorization)
397 return authorization->message_qop;
401 osip_authorization_set_message_qop (osip_authorization_t * authorization,
404 authorization->message_qop = (char *) message_qop;
408 osip_authorization_get_nonce_count (osip_authorization_t * authorization)
410 return authorization->nonce_count;
414 osip_authorization_set_nonce_count (osip_authorization_t * authorization,
417 authorization->nonce_count = (char *) nonce_count;
421 /* returns the authorization header as a string. */
422 /* INPUT : osip_authorization_t *authorization | authorization header. */
423 /* returns null on error. */
425 osip_authorization_to_str (const osip_authorization_t * auth, char **dest)
431 /* DO NOT REALLY KNOW THE LIST OF MANDATORY PARAMETER: Please HELP! */
432 if ((auth == NULL) || (auth->auth_type == NULL) || (auth->realm == NULL)
433 || (auth->nonce == NULL))
436 len = strlen (auth->auth_type) + 1;
437 if (auth->username != NULL)
438 len = len + 10 + strlen (auth->username);
439 if (auth->realm != NULL)
440 len = len + 8 + strlen (auth->realm);
441 if (auth->nonce != NULL)
442 len = len + 8 + strlen (auth->nonce);
443 if (auth->uri != NULL)
444 len = len + 6 + strlen (auth->uri);
445 if (auth->response != NULL)
446 len = len + 11 + strlen (auth->response);
448 if (auth->digest != NULL)
449 len = len + strlen (auth->digest) + 9;
450 if (auth->algorithm != NULL)
451 len = len + strlen (auth->algorithm) + 12;
452 if (auth->cnonce != NULL)
453 len = len + strlen (auth->cnonce) + 9;
454 if (auth->opaque != NULL)
455 len = len + 9 + strlen (auth->opaque);
456 if (auth->nonce_count != NULL)
457 len = len + strlen (auth->nonce_count) + 5;
458 if (auth->message_qop != NULL)
459 len = len + strlen (auth->message_qop) + 6;
461 tmp = (char *) osip_malloc (len);
466 osip_strncpy (tmp, auth->auth_type, strlen (auth->auth_type));
467 tmp = tmp + strlen (tmp);
469 if (auth->username != NULL)
471 osip_strncpy (tmp, " username=", 10);
473 /* !! username-value must be a quoted string !! */
474 osip_strncpy (tmp, auth->username, strlen (auth->username));
475 tmp = tmp + strlen (tmp);
478 if (auth->realm != NULL)
480 osip_strncpy (tmp, ", realm=", 8);
482 /* !! realm-value must be a quoted string !! */
483 osip_strncpy (tmp, auth->realm, strlen (auth->realm));
484 tmp = tmp + strlen (tmp);
486 if (auth->nonce != NULL)
488 osip_strncpy (tmp, ", nonce=", 8);
490 /* !! nonce-value must be a quoted string !! */
491 osip_strncpy (tmp, auth->nonce, strlen (auth->nonce));
492 tmp = tmp + strlen (tmp);
495 if (auth->uri != NULL)
497 osip_strncpy (tmp, ", uri=", 6);
499 /* !! domain-value must be a list of URI in a quoted string !! */
500 osip_strncpy (tmp, auth->uri, strlen (auth->uri));
501 tmp = tmp + strlen (tmp);
503 if (auth->response != NULL)
505 osip_strncpy (tmp, ", response=", 11);
507 /* !! domain-value must be a list of URI in a quoted string !! */
508 osip_strncpy (tmp, auth->response, strlen (auth->response));
509 tmp = tmp + strlen (tmp);
512 if (auth->digest != NULL)
514 osip_strncpy (tmp, ", digest=", 9);
516 /* !! domain-value must be a list of URI in a quoted string !! */
517 osip_strncpy (tmp, auth->digest, strlen (auth->digest));
518 tmp = tmp + strlen (tmp);
520 if (auth->algorithm != NULL)
522 osip_strncpy (tmp, ", algorithm=", 12);
524 osip_strncpy (tmp, auth->algorithm, strlen (auth->algorithm));
525 tmp = tmp + strlen (tmp);
527 if (auth->cnonce != NULL)
529 osip_strncpy (tmp, ", cnonce=", 9);
531 osip_strncpy (tmp, auth->cnonce, strlen (auth->cnonce));
532 tmp = tmp + strlen (tmp);
534 if (auth->opaque != NULL)
536 osip_strncpy (tmp, ", opaque=", 9);
538 osip_strncpy (tmp, auth->opaque, strlen (auth->opaque));
539 tmp = tmp + strlen (tmp);
541 if (auth->message_qop != NULL)
543 osip_strncpy (tmp, ", qop=", 6);
545 osip_strncpy (tmp, auth->message_qop, strlen (auth->message_qop));
546 tmp = tmp + strlen (tmp);
548 if (auth->nonce_count != NULL)
550 osip_strncpy (tmp, ", nc=", 5);
552 osip_strncpy (tmp, auth->nonce_count, strlen (auth->nonce_count));
553 tmp = tmp + strlen (tmp);
558 /* deallocates a osip_authorization_t structure. */
559 /* INPUT : osip_authorization_t *authorization | authorization. */
561 osip_authorization_free (osip_authorization_t * authorization)
563 if (authorization == NULL)
565 osip_free (authorization->auth_type);
566 osip_free (authorization->username);
567 osip_free (authorization->realm);
568 osip_free (authorization->nonce);
569 osip_free (authorization->uri);
570 osip_free (authorization->response);
571 osip_free (authorization->digest);
572 osip_free (authorization->algorithm);
573 osip_free (authorization->cnonce);
574 osip_free (authorization->opaque);
575 osip_free (authorization->message_qop);
576 osip_free (authorization->nonce_count);
577 osip_free (authorization);
581 osip_authorization_clone (const osip_authorization_t * auth,
582 osip_authorization_t ** dest)
585 osip_authorization_t *au;
591 if (auth->auth_type==NULL) return -1;
592 if (auth->username==NULL) return -1;
593 if (auth->realm==NULL) return -1;
594 if (auth->nonce==NULL) return -1;
595 if (auth->uri==NULL) return -1;
596 if (auth->response==NULL) return -1;
597 if (auth->opaque==NULL) return -1;
600 i = osip_authorization_init (&au);
601 if (i == -1) /* allocation failed */
603 if (auth->auth_type != NULL)
605 au->auth_type = osip_strdup (auth->auth_type);
606 if (au->auth_type == NULL)
609 if (auth->username != NULL)
611 au->username = osip_strdup (auth->username);
612 if (au->username == NULL)
615 if (auth->realm != NULL)
617 au->realm = osip_strdup (auth->realm);
618 if (auth->realm == NULL)
621 if (auth->nonce != NULL)
623 au->nonce = osip_strdup (auth->nonce);
624 if (auth->nonce == NULL)
627 if (auth->uri != NULL)
629 au->uri = osip_strdup (auth->uri);
633 if (auth->response != NULL)
635 au->response = osip_strdup (auth->response);
636 if (auth->response == NULL)
639 if (auth->digest != NULL)
641 au->digest = osip_strdup (auth->digest);
642 if (au->digest == NULL)
645 if (auth->algorithm != NULL)
647 au->algorithm = osip_strdup (auth->algorithm);
648 if (auth->algorithm == NULL)
651 if (auth->cnonce != NULL)
653 au->cnonce = osip_strdup (auth->cnonce);
654 if (au->cnonce == NULL)
657 if (auth->opaque != NULL)
659 au->opaque = osip_strdup (auth->opaque);
660 if (auth->opaque == NULL)
663 if (auth->message_qop != NULL)
665 au->message_qop = osip_strdup (auth->message_qop);
666 if (auth->message_qop == NULL)
669 if (auth->nonce_count != NULL)
671 au->nonce_count = osip_strdup (auth->nonce_count);
672 if (auth->nonce_count == NULL)
680 osip_authorization_free (au);