parse_privacy.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * $Id: parse_privacy.c 4720 2008-08-23 10:56:15Z henningw $
  3. *
  4. * Copyright (c) 2006 Juha Heinanen
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * History:
  23. * -------
  24. * 2006-12-18 Introduced parsing of Privacy header (RFC 3323)
  25. */
  26. /*!
  27. * \file
  28. * \brief Privacy value parser
  29. * \ingroup parser
  30. */
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "../../dprint.h"
  34. #include "../../trim.h"
  35. #include "parse_privacy.h"
  36. #include "../../parser/msg_parser.h"
  37. /*!
  38. * Parse a privacy value pointed by start that can be at most max_len long.
  39. * \return length of matched privacy value on success or NULL otherwise
  40. */
  41. unsigned int parse_priv_value(char* start, unsigned int max_len,
  42. unsigned int* value)
  43. {
  44. unsigned int len;
  45. if (!start || !value) {
  46. LM_ERR("invalid parameter value\n");
  47. return 0;
  48. }
  49. switch (start[0]) {
  50. case 'c':
  51. case 'C':
  52. if(max_len < 8)
  53. return 0;
  54. if (strncasecmp(start, "critical", 8) == 0) {
  55. *value = PRIVACY_CRITICAL;
  56. len = 8;
  57. break;
  58. } else {
  59. return 0;
  60. }
  61. case 'h':
  62. case 'H':
  63. if (max_len < 6)
  64. return 0;
  65. if (strncasecmp(start, "header", 6) == 0) {
  66. *value = PRIVACY_HEADER;
  67. len = 6;
  68. break;
  69. }
  70. if (max_len < 7)
  71. return 0;
  72. if (strncasecmp(start, "history", 7) == 0) {
  73. *value = PRIVACY_HISTORY;
  74. len = 7;
  75. break;
  76. } else {
  77. return 0;
  78. }
  79. case 'i':
  80. case 'I':
  81. if(max_len < 2)
  82. return 0;
  83. if (start[1] == 'd' || start[1] == 'D') {
  84. *value = PRIVACY_ID;
  85. len = 2;
  86. break;
  87. } else {
  88. return 0;
  89. }
  90. case 'n':
  91. case 'N':
  92. if(max_len < 4)
  93. return 0;
  94. if (strncasecmp(start, "none", 4) == 0) {
  95. *value = PRIVACY_NONE;
  96. len = 4;
  97. break;
  98. } else {
  99. return 0;
  100. }
  101. case 's':
  102. case 'S':
  103. if(max_len < 7)
  104. return 0;
  105. if (strncasecmp(start, "session", 7) == 0) {
  106. *value = PRIVACY_SESSION;
  107. len = 7;
  108. break;
  109. } else {
  110. return 0;
  111. }
  112. case 'u':
  113. case 'U':
  114. if(max_len < 4)
  115. return 0;
  116. if (strncasecmp(start, "user", 4) == 0) {
  117. *value = PRIVACY_USER;
  118. len = 4;
  119. break;
  120. } else {
  121. return 0;
  122. }
  123. default:
  124. return 0;
  125. }
  126. if(len < max_len) {
  127. if(start[len] != '\0' && start[len] != ';' && start[len] != ' '
  128. && start[len] != '\t' && start[len] != '\r' && start[len] != '\n')
  129. return 0;
  130. }
  131. return len;
  132. }
  133. /*!
  134. * This method is used to parse Privacy HF body, which consist of
  135. * comma separated list of priv-values. After parsing, msg->privacy->parsed
  136. * contains enum bits of privacy values defined in parse_privacy.h.
  137. * \return 0 on success and -1 on failure.
  138. */
  139. int parse_privacy(struct sip_msg *msg)
  140. {
  141. unsigned int val_len, value, values, len;
  142. str next;
  143. char *p, *beyond;
  144. /* maybe the header is already parsed! */
  145. if (msg->privacy && msg->privacy->parsed)
  146. return 0;
  147. /* parse Privacy HF (there should be only one) */
  148. if (!msg->privacy &&
  149. (parse_headers(msg, HDR_PRIVACY_F, 0) == -1 || !msg->privacy)) {
  150. return -1;
  151. }
  152. next.len = msg->privacy->body.len;
  153. next.s = msg->privacy->body.s;
  154. trim_leading(&next);
  155. if (next.len == 0) {
  156. LM_ERR("no values\n");
  157. return -1;
  158. }
  159. values = 0;
  160. p = next.s;
  161. len = next.len;
  162. beyond = p + len;
  163. while (p < beyond) {
  164. if((val_len = parse_priv_value(p, len, &value)) != 0) {
  165. values |= value;
  166. p = p + val_len;
  167. len = len - val_len;
  168. } else {
  169. LM_ERR("invalid privacy value\n");
  170. return -1;
  171. }
  172. while(p < beyond && (*p == ' ' || *p == '\t'
  173. || *p == '\r' || *p == '\n'))
  174. p++;
  175. if(p >= beyond) break;
  176. if (*p == ';') {
  177. p++;
  178. while(p < beyond && (*p == ' ' || *p == '\t'
  179. || *p == '\r' || *p == '\n'))
  180. p++;
  181. if(p >= beyond) {
  182. LM_ERR("no privacy value after comma\n");
  183. return -1;
  184. }
  185. } else {
  186. LM_ERR("semicolon expected\n");
  187. return -1;
  188. }
  189. }
  190. if ((values & PRIVACY_NONE) && (values ^ PRIVACY_NONE)) {
  191. LM_ERR("no other privacy values allowed with 'none'\n");
  192. return -1;
  193. }
  194. msg->privacy->parsed = (void *)(long)values;
  195. return 0;
  196. }