|
64 | 64 | #include "parser/parse_pai.h"
|
65 | 65 | #include "parser/digest/digest.h"
|
66 | 66 | #include "parser/contact/parse_contact.h"
|
| 67 | +#include "parser/parse_authenticate.h" |
| 68 | +#include "lib/digest_auth/digest_auth.h" |
67 | 69 |
|
68 | 70 | #define is_in_str(p, in) (p<in->s+in->len && *p)
|
69 | 71 |
|
@@ -1816,6 +1818,66 @@ static int pv_get_authattr(struct sip_msg *msg, pv_param_t *param,
|
1816 | 1818 | }
|
1817 | 1819 |
|
1818 | 1820 |
|
| 1821 | +static int pv_get_cauthattr(struct sip_msg *msg, pv_param_t *param, |
| 1822 | + pv_value_t *res) |
| 1823 | +{ |
| 1824 | + struct authenticate_body *auth = NULL; |
| 1825 | + str *s; |
| 1826 | + |
| 1827 | + if(msg==NULL) |
| 1828 | + return -1; |
| 1829 | + |
| 1830 | + if (msg->first_line.type!=SIP_REPLY) { |
| 1831 | + LM_DBG("{Proxy,WWW}-Authenticate header should be only in replies\n"); |
| 1832 | + return pv_get_null(msg, param, res); |
| 1833 | + } |
| 1834 | + switch (msg->REPLY_STATUS) { |
| 1835 | + case 401: |
| 1836 | + parse_www_authenticate_header(msg, NULL, &auth); |
| 1837 | + break; |
| 1838 | + case 407: |
| 1839 | + parse_proxy_authenticate_header(msg, NULL, &auth); |
| 1840 | + break; |
| 1841 | + default: |
| 1842 | + LM_DBG("bad reply code for a challenge!\n"); |
| 1843 | + break; |
| 1844 | + } |
| 1845 | + if (!auth) { |
| 1846 | + LM_DBG("no {Proxy,WWW}-Authenticate header\n"); |
| 1847 | + return pv_get_null(msg, param, res); |
| 1848 | + } |
| 1849 | + |
| 1850 | + switch (param->pvn.u.isname.name.n) { |
| 1851 | + case 1: |
| 1852 | + s = (str *)print_digest_algorithm(auth->algorithm); |
| 1853 | + break; |
| 1854 | + case 2: |
| 1855 | + s = &auth->realm; |
| 1856 | + break; |
| 1857 | + case 3: |
| 1858 | + s = &auth->nonce; |
| 1859 | + break; |
| 1860 | + case 4: |
| 1861 | + s = &auth->opaque; |
| 1862 | + break; |
| 1863 | + case 5: |
| 1864 | + s = &auth->qop; |
| 1865 | + break; |
| 1866 | + case 6: |
| 1867 | + s = &auth->ik; |
| 1868 | + break; |
| 1869 | + case 7: |
| 1870 | + s = &auth->ck; |
| 1871 | + break; |
| 1872 | + default: |
| 1873 | + LM_BUG("unhandled mode %d\n", param->pvn.u.isname.name.n); |
| 1874 | + return pv_get_null(msg, param, res); |
| 1875 | + } |
| 1876 | + |
| 1877 | + return pv_get_strval(msg, param, res, s); |
| 1878 | +} |
| 1879 | + |
| 1880 | + |
1819 | 1881 | static inline str *cred_user(struct sip_msg *rq)
|
1820 | 1882 | {
|
1821 | 1883 | struct hdr_field* h;
|
@@ -3955,6 +4017,27 @@ const pv_export_t _pv_names_table[] = {
|
3955 | 4017 | {str_const_init("aU"), /* */
|
3956 | 4018 | PVT_AUTH_USERNAME_WHOLE, pv_get_authattr, 0,
|
3957 | 4019 | 0, 0, pv_init_iname, 99},
|
| 4020 | + {str_const_init("challenge.algorithm"), /* */ |
| 4021 | + PVT_AUTH_USERNAME, pv_get_cauthattr, 0, |
| 4022 | + 0, 0, pv_init_iname, 1}, |
| 4023 | + {str_const_init("challenge.realm"), |
| 4024 | + PVT_AUTH_REALM, pv_get_cauthattr, 0, |
| 4025 | + 0, 0, pv_init_iname, 2}, |
| 4026 | + {str_const_init("challenge.nonce"), |
| 4027 | + PVT_AUTH_DURI, pv_get_cauthattr, 0, |
| 4028 | + 0, 0, pv_init_iname, 3}, |
| 4029 | + {str_const_init("challenge.opaque"), |
| 4030 | + PVT_AUTH_DOMAIN, pv_get_cauthattr, 0, |
| 4031 | + 0, 0, pv_init_iname, 4}, |
| 4032 | + {str_const_init("challenge.qop"), |
| 4033 | + PVT_AUTH_NONCE, pv_get_cauthattr, 0, |
| 4034 | + 0, 0, pv_init_iname, 5}, |
| 4035 | + {str_const_init("challenge.ik"), /* */ |
| 4036 | + PVT_AUTH_NONCE, pv_get_cauthattr, 0, |
| 4037 | + 0, 0, pv_init_iname, 6}, |
| 4038 | + {str_const_init("challenge.ck"), /* */ |
| 4039 | + PVT_AUTH_RESPONSE, pv_get_cauthattr, 0, |
| 4040 | + 0, 0, pv_init_iname, 7}, |
3958 | 4041 | {str_const_init("Au"), /* */
|
3959 | 4042 | PVT_ACC_USERNAME, pv_get_acc_username, 0,
|
3960 | 4043 | 0, 0, pv_init_iname, 1},
|
|
0 commit comments