00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "digest.h"
00032 #include "../../mem/mem.h"
00033 #include "../../dprint.h"
00034 #include <stdio.h>
00035 #include <string.h>
00036
00037
00038
00039
00040
00041 static inline int new_credentials(struct hdr_field* _h)
00042 {
00043 auth_body_t* b;
00044
00045 b = (auth_body_t*)pkg_malloc(sizeof(auth_body_t));
00046 if (b == 0) {
00047 LOG(L_ERR, "parse_credentials(): No memory left\n");
00048 return -1;
00049 }
00050
00051 init_dig_cred(&(b->digest));
00052 b->stale = 0;
00053 b->authorized = 0;
00054
00055 _h->parsed = (void*)b;
00056
00057 return 0;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 int parse_credentials(struct hdr_field* _h)
00069 {
00070 int res;
00071 void** ph_parsed;
00072
00073 if (_h->parsed) {
00074 return 0;
00075 }
00076
00077 if (new_credentials(_h) < 0) {
00078 LOG(L_ERR, "parse_credentials(): Can't create new credentials\n");
00079 return -1;
00080 }
00081
00082
00083
00084
00085
00086 res = parse_digest_cred(&(_h->body), &(((auth_body_t*)(_h->parsed))->digest));
00087
00088 if (res != 0) {
00089 ph_parsed=&_h->parsed;
00090 free_credentials((auth_body_t**)ph_parsed);
00091 }
00092
00093 return res;
00094 }
00095
00096
00097
00098
00099
00100 void free_credentials(auth_body_t** _b)
00101 {
00102 pkg_free(*_b);
00103 *_b = 0;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 dig_err_t check_dig_cred(dig_cred_t* _c)
00116 {
00117 dig_err_t res = E_DIG_OK;
00118
00119
00120 if (_c->username.user.s == 0) res |= E_DIG_USERNAME;
00121
00122
00123 if (_c->realm.s == 0) res |= E_DIG_REALM;
00124
00125
00126 if (_c->nonce.s == 0) res |= E_DIG_NONCE;
00127
00128
00129 if (_c->uri.s == 0) res |= E_DIG_URI;
00130
00131
00132 if (_c->response.s == 0) res |= E_DIG_RESPONSE;
00133
00134
00135
00136
00137 if ((_c->qop.qop_parsed == QOP_AUTH) || (_c->qop.qop_parsed == QOP_AUTHINT)) {
00138
00139 if (_c->cnonce.s == 0) res |= E_DIG_CNONCE;
00140
00141 if (_c->nc.s == 0) res |= E_DIG_NC;
00142 }
00143
00144 return res;
00145 }
00146
00147
00148
00149
00150
00151
00152 void print_cred(dig_cred_t* _c)
00153 {
00154 printf("===Digest credentials===\n");
00155 if (_c) {
00156 printf("Username\n");
00157 printf("+--whole = \'%.*s\'\n", _c->username.whole.len, _c->username.whole.s);
00158 printf("+--user = \'%.*s\'\n", _c->username.user.len, _c->username.user.s);
00159 printf("\\--domain = \'%.*s\'\n", _c->username.domain.len, _c->username.domain.s);
00160 printf("Realm = \'%.*s\'\n", _c->realm.len, _c->realm.s);
00161 printf("Nonce = \'%.*s\'\n", _c->nonce.len, _c->nonce.s);
00162 printf("URI = \'%.*s\'\n", _c->uri.len, _c->uri.s);
00163 printf("Response = \'%.*s\'\n", _c->response.len, _c->response.s);
00164 printf("Algorithm = \'%.*s\'\n", _c->alg.alg_str.len, _c->alg.alg_str.s);
00165 printf("\\--parsed = ");
00166
00167 switch(_c->alg.alg_parsed) {
00168 case ALG_UNSPEC: printf("ALG_UNSPEC\n"); break;
00169 case ALG_MD5: printf("ALG_MD5\n"); break;
00170 case ALG_MD5SESS: printf("ALG_MD5SESS\n"); break;
00171 case ALG_OTHER: printf("ALG_OTHER\n"); break;
00172 }
00173
00174 printf("Cnonce = \'%.*s\'\n", _c->cnonce.len, _c->cnonce.s);
00175 printf("Opaque = \'%.*s\'\n", _c->opaque.len, _c->opaque.s);
00176 printf("QOP = \'%.*s\'\n", _c->qop.qop_str.len, _c->qop.qop_str.s);
00177 printf("\\--parsed = ");
00178
00179 switch(_c->qop.qop_parsed) {
00180 case QOP_UNSPEC: printf("QOP_UNSPEC\n"); break;
00181 case QOP_AUTH: printf("QOP_AUTH\n"); break;
00182 case QOP_AUTHINT: printf("QOP_AUTHINT\n"); break;
00183 case QOP_OTHER: printf("QOP_OTHER\n"); break;
00184 }
00185 printf("NC = \'%.*s\'\n", _c->nc.len, _c->nc.s);
00186 }
00187 printf("===/Digest credentials===\n");
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197 int mark_authorized_cred(struct sip_msg* _m, struct hdr_field* _h)
00198 {
00199 struct hdr_field* f;
00200
00201 switch(_h->type) {
00202 case HDR_AUTHORIZATION_T: f = _m->authorization; break;
00203 case HDR_PROXYAUTH_T: f = _m->proxy_auth; break;
00204 default:
00205 LOG(L_ERR, "mark_authorized_cred(): Invalid header field type\n");
00206 return -1;
00207 }
00208
00209 if (!(f->parsed)) {
00210 if (new_credentials(f) < 0) {
00211 LOG(L_ERR, "mark_authorized_cred(): Error in new_credentials\n");
00212 return -1;
00213 }
00214 }
00215
00216 ((auth_body_t*)(f->parsed))->authorized = _h;
00217
00218 return 0;
00219 }
00220
00221
00222
00223
00224
00225
00226 int get_authorized_cred(struct hdr_field* _f, struct hdr_field** _h)
00227 {
00228 if (_f && _f->parsed) {
00229 *_h = ((auth_body_t*)(_f->parsed))->authorized;
00230 } else {
00231 *_h = 0;
00232 }
00233
00234 return 0;
00235 }
00236
00237
00238
00239
00240
00241 int find_credentials(struct sip_msg* msg, str* realm,
00242 hdr_types_t hftype, struct hdr_field** hdr)
00243 {
00244 struct hdr_field** hook, *ptr, *prev;
00245 hdr_flags_t hdr_flags;
00246 int res;
00247 str* r;
00248
00249
00250
00251
00252
00253
00254 switch(hftype) {
00255 case HDR_AUTHORIZATION_T:
00256 hook = &(msg->authorization);
00257 hdr_flags=HDR_AUTHORIZATION_F;
00258 break;
00259 case HDR_PROXYAUTH_T:
00260 hook = &(msg->proxy_auth);
00261 hdr_flags=HDR_PROXYAUTH_F;
00262 break;
00263 default:
00264 hook = &(msg->authorization);
00265 hdr_flags=HDR_T2F(hftype);
00266 break;
00267 }
00268
00269
00270
00271
00272 if (*hook == 0) {
00273
00274 if (parse_headers(msg, hdr_flags, 0) == -1) {
00275 LOG(L_ERR, "auth:find_credentials: Error while parsing headers\n");
00276 return -1;
00277 }
00278 }
00279
00280 ptr = *hook;
00281
00282
00283
00284
00285
00286 while(ptr) {
00287 res = parse_credentials(ptr);
00288 if (res < 0) {
00289 LOG(L_ERR, "auth:find_credentials: Error while parsing credentials\n");
00290 return (res == -1) ? -2 : -3;
00291 } else if (res == 0) {
00292 r = &(((auth_body_t*)(ptr->parsed))->digest.realm);
00293
00294 if (r->len == realm->len) {
00295 if (!strncasecmp(realm->s, r->s, r->len)) {
00296 *hdr = ptr;
00297 return 0;
00298 }
00299 }
00300 }
00301
00302 prev = ptr;
00303 if (parse_headers(msg, hdr_flags, 1) == -1) {
00304 LOG(L_ERR, "auth:find_credentials: Error while parsing headers\n");
00305 return -4;
00306 } else {
00307 if (prev != msg->last_header) {
00308 if (msg->last_header->type == hftype) ptr = msg->last_header;
00309 else break;
00310 } else break;
00311 }
00312 }
00313
00314
00315
00316
00317 return 1;
00318 }