| 154 | } |
| 155 | |
| 156 | int parse_authenticate_body( str body, struct authenticate_body *auth) |
| 157 | { |
| 158 | int n, ret = 0; |
| 159 | int state; |
| 160 | str name; |
| 161 | str val; |
| 162 | int quoted_val; |
| 163 | |
| 164 | if (body.len == 0) |
| 165 | { |
| 166 | LM_ERR("empty body\n"); |
| 167 | goto error; |
| 168 | } |
| 169 | |
| 170 | memset( auth, 0, sizeof(struct authenticate_body)); |
| 171 | |
| 172 | /* parse the "digest" */ |
| 173 | trim_leading(&body); |
| 174 | if (body.len <= AUTHENTICATE_DIGEST_LEN) |
| 175 | goto parse_error; |
| 176 | if (!TRB_SCASEMATCH(body.s, "digest")) |
| 177 | goto parse_error; |
| 178 | STR_ADVANCE_BY(&body, AUTHENTICATE_DIGEST_LEN); |
| 179 | if (!is_ws(*body.s)) |
| 180 | goto parse_error; |
| 181 | STR_ADVANCE(&body); |
| 182 | trim_leading(&body); |
| 183 | if (body.len == 0) |
| 184 | goto parse_error; |
| 185 | |
| 186 | while (body.len > 0) |
| 187 | { |
| 188 | state = OTHER_STATE; |
| 189 | quoted_val = 0; |
| 190 | /* get name */ |
| 191 | name.s = body.s; |
| 192 | if (body.len > 4) |
| 193 | { |
| 194 | n = LOWER4B( GET4B(body.s) ); |
| 195 | switch(n) |
| 196 | { |
| 197 | CASE_5B( 0x7265616c, 'm', REALM_STATE, 1); /*realm*/ |
| 198 | CASE_5B( 0x6e6f6e63, 'e', NONCE_STATE, 1); /*nonce*/ |
| 199 | CASE_5B( 0x7374616c, 'e', STALE_STATE, 0); /*stale*/ |
| 200 | CASE_6B( 0x646f6d62, 'i', 'n', DOMAIN_STATE, 1); /*domain*/ |
| 201 | CASE_6B( 0x6f706171, 'u', 'e', OPAQUE_STATE, 1); /*opaque*/ |
| 202 | case 0x616c676f: /*algo*/ |
| 203 | if (body.len > 9 && TRB_SCASEMATCH(body.s+4, "rithm")) |
| 204 | { |
| 205 | STR_ADVANCE_BY(&body, 9); |
| 206 | state = ALGORITHM_STATE; |
| 207 | } else { |
| 208 | STR_ADVANCE_BY(&body, 4); |
| 209 | } |
| 210 | break; |
| 211 | default: |
| 212 | if ((n|0xff)==0x716f70ff) /*qop*/ |
| 213 | { |