digest_parser.xml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
  4. <section id="digest_parser" xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <sectioninfo>
  6. <revhistory>
  7. <revision>
  8. <revnumber>$Revision$</revnumber>
  9. <date>$Date$</date>
  10. </revision>
  11. </revhistory>
  12. </sectioninfo>
  13. <title>Digest Body Parser</title>
  14. <para>
  15. Purpose of this parser is to parse digest response. The parser can be
  16. found under <filename>parser/digest</filename> subdirectory. There
  17. might be several header fields containing digest response, for example
  18. Proxy-Authorization or WWW-Authorization. The parser can be used for
  19. all of them.
  20. </para>
  21. <para>
  22. The parser is not called automatically when by the main parser. It is
  23. your responsibility to call the parser when you want a digest response
  24. to be parsed.
  25. </para>
  26. <para>
  27. Main function is <function>parse_credentials</function> defined in
  28. <filename>digest.c</filename>. The function accepts one parameter which
  29. is header field to be parsed. As result the function will create an
  30. instance of <structname>auth_body_t</structname> structure which will
  31. represent the parsed digest credentials. Pointer to the structure will
  32. be put in <structfield>parsed</structfield> field of the
  33. <structname>hdr_field</structname> structure representing the parsed
  34. header field. It will be freed when the whole message is being
  35. destroyed.
  36. </para>
  37. <para>
  38. The digest parser contains 32-bit digest parameter parser. The parser
  39. was in detail described in section <link linkend="hfname_parser">Header
  40. Field Name Parser</link>. See that section for more details about the
  41. digest parameter parser algorithm, they work in the same way.
  42. </para>
  43. <para>
  44. Description of digest related structures follows:
  45. <programlisting>
  46. typedef struct auth_body {
  47. /* This is pointer to header field containing
  48. * parsed authorized digest credentials. This
  49. * pointer is set in sip_msg->{authorization,proxy_auth}
  50. * hooks.
  51. *
  52. * This is necessary for functions called after
  53. * {www,proxy}_authorize, these functions need to know
  54. * which credentials are authorized and they will simply
  55. * look into
  56. * sip_msg->{authorization,proxy_auth}->parsed->authorized
  57. */
  58. struct hdr_field* authorized;
  59. dig_cred_t digest; /* Parsed digest credentials */
  60. unsigned char stale; /* Flag is set if nonce is stale */
  61. int nonce_retries; /* How many times the nonce was used */
  62. } auth_body_t;
  63. </programlisting>
  64. </para>
  65. <para>
  66. This is the "main" structure. Pointer to the structure will be stored
  67. in <structfield>parsed</structfield> field of
  68. <structname>hdr_field</structname> structure. Detailed description of
  69. its fields follows:
  70. <itemizedlist>
  71. <listitem>
  72. <para>
  73. <structfield>authorized</structfield> - This is a hook to
  74. header field containing authorized credentials.
  75. </para>
  76. <para>
  77. A <acronym>SIP</acronym> message may contain several
  78. credentials. They are distinguished using realm
  79. parameter. When the server is trying to authorize the
  80. message, it must first find credentials with corresponding
  81. realm and than authorize the credentials. To authorize
  82. credentials server calculates response string and if the
  83. string matches to response string contained in the
  84. credentials, credentials are authorized (in fact it means
  85. that the user specified in the credentials knows password,
  86. nothing more, nothing less).
  87. </para>
  88. <para>
  89. It would be good idea to remember which credentials
  90. contained in the message are authorized, there might be
  91. other functions interested in knowing which credentials are
  92. authorized.
  93. </para>
  94. <para>
  95. That is what is this field for. A function that
  96. successfully authorized credentials (currently there is
  97. only one such function in the server, it is function
  98. <function>authorize</function> in auth module) will put
  99. pointer to header field containing the authorized
  100. credentials in this field. Because there might be several
  101. header field containing credentials, the pointer will be
  102. put in <structfield>authorized</structfield> field in the
  103. first header field in the message containing
  104. credentials. That means that it will be either header field
  105. whose pointer is in <structfield>www_auth</structfield> or
  106. <structfield>proxy_auth</structfield> field of
  107. <structname>sip_msg</structname> structure representing the
  108. message.
  109. </para>
  110. <para>
  111. When a function wants to find authorized credentials, it
  112. will simply look in
  113. <structfield>msg->www_auth->parsed->authorized</structfield>
  114. or
  115. <structfield>msg->proxy_auth->parsed->authorized</structfield>,
  116. where <structfield>msg</structfield> is variable containing
  117. pointer to <structname>sip_msg</structname> structure.
  118. </para>
  119. <para>
  120. To simplify the task of saving and retrieving pointer to
  121. authorized credentials, there are two convenience functions
  122. defined in <filename>digest.c</filename> file. They will
  123. be described later.
  124. </para>
  125. </listitem>
  126. <listitem>
  127. <para>
  128. <structfield>digest</structfield> - Structure containing
  129. parsed digest credentials. The structure will be described
  130. in detail later.
  131. </para>
  132. </listitem>
  133. <listitem>
  134. <para>
  135. <structfield>stale</structfield> - This field will be set
  136. to 1 if the server received a stale nonce. Next time when
  137. the server will be sending another challenge, it will use
  138. "stale=true" parameter. "stale=true" indicates to the
  139. client that username and password used to calculate
  140. response were correct, but nonce was stale. The client
  141. should recalculate response with the same username and
  142. password (without disturbing user) and new nonce. For more
  143. details see <acronym>RFC2617</acronym>.
  144. </para>
  145. </listitem>
  146. <listitem>
  147. <para>
  148. <structfield>nonce_retries</structfield> - This fields
  149. indicates number of authorization attempts with same nonce.
  150. </para>
  151. </listitem>
  152. </itemizedlist>
  153. </para>
  154. <programlisting>
  155. /*
  156. * Errors returned by check_dig_cred
  157. */
  158. typedef enum dig_err {
  159. E_DIG_OK = 0, /* Everything is OK */
  160. E_DIG_USERNAME = 1, /* Username missing */
  161. E_DIG_REALM = 2, /* Realm missing */
  162. E_DIG_NONCE = 4, /* Nonce value missing */
  163. E_DIG_URI = 8, /* URI missing */
  164. E_DIG_RESPONSE = 16, /* Response missing */
  165. E_DIG_CNONCE = 32, /* CNONCE missing */
  166. E_DIG_NC = 64, /* Nonce-count missing */
  167. } dig_err_t;
  168. </programlisting>
  169. <para>
  170. This is enum of all possible errors returned by
  171. <function>check_dig_cred</function> function.
  172. <itemizedlist>
  173. <listitem>
  174. <para><emphasis>E_DIG_OK</emphasis> - No error found.</para>
  175. </listitem>
  176. <listitem>
  177. <para>
  178. <emphasis>E_DIG_USERNAME</emphasis> - Username parameter
  179. missing in digest response.
  180. </para>
  181. </listitem>
  182. <listitem>
  183. <para><emphasis>E_DIG_REALM</emphasis> - Realm parameter
  184. missing in digest response.</para>
  185. </listitem>
  186. <listitem>
  187. <para><emphasis>E_DIG_NONCE</emphasis> - Nonce parameter
  188. missing in digest response.</para>
  189. </listitem>
  190. <listitem>
  191. <para><emphasis>E_DIG_URI</emphasis> - Uri parameter missing in
  192. digest response.</para>
  193. </listitem>
  194. <listitem>
  195. <para>
  196. <emphasis>E_DIG_RESPONSE</emphasis> - Response parameter
  197. missing in digest response.
  198. </para>
  199. </listitem>
  200. <listitem>
  201. <para><emphasis>E_DIG_CNONCE</emphasis> - Cnonce parameter
  202. missing in digest response.</para>
  203. </listitem>
  204. <listitem>
  205. <para><emphasis>E_DIG_NC</emphasis> - Nc parameter missing in
  206. digest response.</para>
  207. </listitem>
  208. </itemizedlist>
  209. </para>
  210. <programlisting>
  211. /* Type of algorithm used */
  212. typedef enum alg {
  213. ALG_UNSPEC = 0, /* Algorithm parameter not specified */
  214. ALG_MD5 = 1, /* MD5 - default value*/
  215. ALG_MD5SESS = 2, /* MD5-Session */
  216. ALG_OTHER = 4 /* Unknown */
  217. } alg_t;
  218. </programlisting>
  219. <para>
  220. This is enum of recognized algorithm types. (See description of
  221. <structname>algorithm</structname> structure for more details).
  222. <itemizedlist>
  223. <listitem>
  224. <para><emphasis>ALG_UNSPEC</emphasis> - Algorithm was not
  225. specified in digest response.</para>
  226. </listitem>
  227. <listitem>
  228. <para>
  229. <emphasis>ALG_MD5</emphasis> - "algorithm=MD5" was found in
  230. digest response.
  231. </para>
  232. </listitem>
  233. <listitem>
  234. <para>
  235. <emphasis>ALG_MD5SESS</emphasis> - "algorithm=MD5-Session"
  236. was found in digest response.
  237. </para>
  238. </listitem>
  239. <listitem>
  240. <para>
  241. <emphasis>ALG_OTHER</emphasis> - Unknown algorithm
  242. parameter value was found in digest response.
  243. </para>
  244. </listitem>
  245. </itemizedlist>
  246. </para>
  247. <programlisting>
  248. /* Quality Of Protection used */
  249. typedef enum qop_type {
  250. QOP_UNSPEC = 0, /* QOP parameter not present in response */
  251. QOP_AUTH = 1, /* Authentication only */
  252. QOP_AUTHINT = 2, /* Authentication with integrity checks */
  253. QOP_OTHER = 4 /* Unknown */
  254. } qop_type_t;
  255. </programlisting>
  256. <para>
  257. This enum lists all recognized qop parameter values.
  258. <itemizedlist>
  259. <listitem>
  260. <para>
  261. <emphasis>QOP_UNSPEC</emphasis> - qop parameter was not
  262. found in digest response.
  263. </para>
  264. </listitem>
  265. <listitem>
  266. <para>
  267. <emphasis>QOP_AUTH</emphasis> - "qop=auth" was found in
  268. digest response.
  269. </para>
  270. </listitem>
  271. <listitem>
  272. <para>
  273. <emphasis>QOP_AUTHINT</emphasis> - "qop=auth-int" was found
  274. in digest response.
  275. </para>
  276. </listitem>
  277. <listitem>
  278. <para>
  279. <emphasis>QOP_OTHER</emphasis> - Unknown qop parameter
  280. value was found in digest response.
  281. </para>
  282. </listitem>
  283. </itemizedlist>
  284. </para>
  285. <programlisting>
  286. /* Algorithm structure */
  287. struct algorithm {
  288. str alg_str; /* The original string representation */
  289. alg_t alg_parsed; /* Parsed value */
  290. };
  291. </programlisting>
  292. <para>
  293. The structure represents "algorithm" parameter of digest
  294. response. Description of fields follows:
  295. <itemizedlist>
  296. <listitem>
  297. <para>
  298. <structfield>alg_str</structfield> - Algorithm parameter
  299. value as string.
  300. </para>
  301. </listitem>
  302. <listitem>
  303. <para>
  304. <structfield>alg_parsed</structfield> - Parsed algorithm
  305. parameter value.
  306. </para>
  307. </listitem>
  308. </itemizedlist>
  309. </para>
  310. <programlisting>
  311. /* QOP structure */
  312. struct qp {
  313. str qop_str; /* The original string representation */
  314. qop_type_t qop_parsed; /* Parsed value */
  315. };
  316. </programlisting>
  317. <para>
  318. This structure represents "qop" parameter of digest
  319. response. Description of fields follows:
  320. <itemizedlist>
  321. <listitem>
  322. <para>
  323. <structfield>qop_str</structfield> - Qop parameter value as
  324. string.
  325. </para>
  326. </listitem>
  327. <listitem>
  328. <para>
  329. <structfield>qop_parsed</structfield> - Parsed "qop"
  330. parameter value.
  331. </para>
  332. </listitem>
  333. </itemizedlist>
  334. </para>
  335. <programlisting>
  336. /*
  337. * Parsed digest credentials
  338. */
  339. typedef struct dig_cred {
  340. str username; /* Username */
  341. str realm; /* Realm */
  342. str nonce; /* Nonce value */
  343. str uri; /* URI */
  344. str response; /* Response string */
  345. str algorithm; /* Algorithm in string representation */
  346. struct algorithm alg; /* Type of algorithm used */
  347. str cnonce; /* Cnonce value */
  348. str opaque; /* Opaque data string */
  349. struct qp qop; /* Quality Of Protection */
  350. str nc; /* Nonce count parameter */
  351. } dig_cred_t;
  352. </programlisting>
  353. <para>
  354. This structure represents set of digest credentials
  355. parameters. Description of field follows:
  356. <itemizedlist>
  357. <listitem>
  358. <para>
  359. <structfield>username</structfield> - Value of "username"
  360. parameter.
  361. </para>
  362. </listitem>
  363. <listitem>
  364. <para>
  365. <structfield>realm</structfield> - Value of "realm"
  366. parameter.
  367. </para>
  368. </listitem>
  369. <listitem>
  370. <para>
  371. <structfield>nonce</structfield> - Value of "nonce"
  372. parameter.
  373. </para>
  374. </listitem>
  375. <listitem>
  376. <para>
  377. <structfield>uri</structfield> - Value of "uri" parameter.
  378. </para>
  379. </listitem>
  380. <listitem>
  381. <para>
  382. <structfield>response</structfield> - Value of "response"
  383. parameter.
  384. </para>
  385. </listitem>
  386. <listitem>
  387. <para>
  388. <structfield>algorithm</structfield> - Value of "algorithm"
  389. parameter as string.
  390. </para>
  391. </listitem>
  392. <listitem>
  393. <para>
  394. <structfield>alg</structfield> - Parsed value of
  395. "algorithm" parameter.
  396. </para>
  397. </listitem>
  398. <listitem>
  399. <para>
  400. <structfield>cnonce</structfield> - Value of "cnonce"
  401. parameter.
  402. </para>
  403. </listitem>
  404. <listitem>
  405. <para>
  406. <structfield>opaque</structfield> - Value of "opaque"
  407. parameter.
  408. </para>
  409. </listitem>
  410. <listitem>
  411. <para>
  412. <structfield>qop</structfield> - Value of "qop" parameter.
  413. </para>
  414. </listitem>
  415. <listitem>
  416. <para>
  417. <structfield>nc</structfield> - Value of "nc" parameter.
  418. </para>
  419. </listitem>
  420. </itemizedlist>
  421. </para>
  422. <section id="other_functions">
  423. <title>Other Functions Of the Digest Parser</title>
  424. <para>
  425. There are some other mainly convenience functions defined in the
  426. parser. The function will be in detail described in this
  427. section. All the functions are defined in
  428. <filename>digest.c</filename> file.
  429. </para>
  430. <funcsynopsis>
  431. <funcprototype>
  432. <funcdef>dig_err_t <function>check_dig_cred</function></funcdef>
  433. <paramdef>dig_cred_t* <parameter>_c</parameter></paramdef>
  434. </funcprototype>
  435. </funcsynopsis>
  436. <para>
  437. This function performs some basic sanity check over parsed digest
  438. credentials. The following conditions must be met for the checks to
  439. be successful:
  440. <itemizedlist>
  441. <listitem>
  442. <para>
  443. There must be non-empty "username" parameter in the
  444. credentials.
  445. </para>
  446. </listitem>
  447. <listitem>
  448. <para>
  449. There must be non-empty "realm" parameter in the
  450. credentials.
  451. </para>
  452. </listitem>
  453. <listitem>
  454. <para>
  455. There must be non-empty "nonce" parameter in the
  456. credentials.
  457. </para>
  458. </listitem>
  459. <listitem>
  460. <para>
  461. There must be non-empty "uri" parameter in the
  462. credentials.
  463. </para>
  464. </listitem>
  465. <listitem>
  466. <para>
  467. There must be non-empty "response" parameter in the
  468. credentials.
  469. </para>
  470. </listitem>
  471. <listitem>
  472. <para>
  473. If qop parameter is set to QOP_AUTH or QOP_AUTHINT,
  474. then there must be also non-empty "cnonce" and "nc"
  475. parameters in the digest.
  476. </para>
  477. </listitem>
  478. </itemizedlist>
  479. </para>
  480. <note>
  481. <para>
  482. It is recommended to call <function>check_dig_cred</function>
  483. before you try to authorize the credentials. If the function
  484. fails, there is no need to try to authorize the credentials
  485. because the authorization will fail for sure.
  486. </para>
  487. </note>
  488. <funcsynopsis>
  489. <funcprototype>
  490. <funcdef>int <function>mark_authorized_cred</function></funcdef>
  491. <paramdef>struct sip_msg* <parameter>_m</parameter></paramdef>
  492. <paramdef>struct hdr_field* <parameter>_h</parameter></paramdef>
  493. </funcprototype>
  494. </funcsynopsis>
  495. <para>
  496. This is convenience function. The function saves pointer to the
  497. authorized credentials. For more info see description of
  498. <structfield>authorized</structfield> field in
  499. <structname>auth_body</structname> structure.
  500. </para>
  501. <funcsynopsis>
  502. <funcprototype>
  503. <funcdef>int <function>get_authorized_cred</function></funcdef>
  504. <paramdef>struct sip_msg* <parameter>_m</parameter></paramdef>
  505. <paramdef>struct hdr_field** <parameter>_h</parameter></paramdef>
  506. </funcprototype>
  507. </funcsynopsis>
  508. <para>
  509. This is convenience function. The function will retrieve pointer to
  510. authorized credentials previously saved using
  511. <function>mark_authorized_cred</function> function. If there is no
  512. such credentials, 0 will be stored in variable pointed to by the
  513. second parameter. The function returns always zero. For more
  514. information see description of
  515. <structfield>authorized</structfield> field in
  516. <structname>auth_body</structname> structure.
  517. </para>
  518. </section>
  519. </section>