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
00032
00033
00034
00035
00036 #include <string.h>
00037 #include "../../ut.h"
00038 #include "../../str.h"
00039 #include "../../db/db.h"
00040 #include "../../dprint.h"
00041 #include "../../parser/digest/digest.h"
00042 #include "../../parser/hf.h"
00043 #include "../../parser/parser_f.h"
00044 #include "../../usr_avp.h"
00045 #include "../../mod_fix.h"
00046 #include "../../mem/mem.h"
00047 #include "aaa_avps.h"
00048 #include "authdb_mod.h"
00049
00050
00051 static str auth_500_err = str_init("Server Internal Error");
00052
00053
00054 static inline int get_ha1(struct username* _username, str* _domain,
00055 const str* _table, char* _ha1, db_res_t** res)
00056 {
00057 struct aaa_avp *cred;
00058 db_key_t keys[2];
00059 db_val_t vals[2];
00060 db_key_t *col;
00061 str result;
00062
00063 int n, nc;
00064
00065 col = pkg_malloc(sizeof(*col) * (credentials_n + 1));
00066 if (col == NULL) {
00067 LM_ERR("no more pkg memory\n");
00068 return -1;
00069 }
00070
00071 keys[0] = &user_column;
00072 keys[1] = &domain_column;
00073
00074 col[0] = (_username->domain.len && !calc_ha1) ?
00075 (&pass_column_2) : (&pass_column);
00076
00077 for (n = 0, cred=credentials; cred ; n++, cred=cred->next) {
00078 col[1 + n] = &cred->attr_name;
00079 }
00080
00081 VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB_STR;
00082 VAL_NULL(vals) = VAL_NULL(vals + 1) = 0;
00083
00084 VAL_STR(vals).s = _username->user.s;
00085 VAL_STR(vals).len = _username->user.len;
00086
00087 if (_username->domain.len) {
00088 VAL_STR(vals + 1) = _username->domain;
00089 } else {
00090 VAL_STR(vals + 1) = *_domain;
00091 }
00092
00093 n = (use_domain ? 2 : 1);
00094 nc = 1 + credentials_n;
00095 if (auth_dbf.use_table(auth_db_handle, _table) < 0) {
00096 LM_ERR("failed to use_table\n");
00097 pkg_free(col);
00098 return -1;
00099 }
00100
00101 if (auth_dbf.query(auth_db_handle, keys, 0, vals, col, n, nc, 0, res) < 0) {
00102 LM_ERR("failed to query database\n");
00103 pkg_free(col);
00104 return -1;
00105 }
00106 pkg_free(col);
00107
00108 if (RES_ROW_N(*res) == 0) {
00109 LM_DBG("no result for user \'%.*s@%.*s\'\n",
00110 _username->user.len, ZSW(_username->user.s),
00111 (use_domain ? (_domain->len) : 0), ZSW(_domain->s));
00112 return 1;
00113 }
00114
00115 result.s = (char*)ROW_VALUES(RES_ROWS(*res))[0].val.string_val;
00116 result.len = strlen(result.s);
00117
00118 if (calc_ha1) {
00119
00120
00121 auth_api.calc_HA1(HA_MD5, &_username->whole, _domain, &result,
00122 0, 0, _ha1);
00123 LM_DBG("HA1 string calculated: %s\n", _ha1);
00124 } else {
00125 memcpy(_ha1, result.s, result.len);
00126 _ha1[result.len] = '\0';
00127 }
00128
00129 return 0;
00130 }
00131
00132
00133
00134
00135
00136 static int generate_avps(db_res_t* result)
00137 {
00138 struct aaa_avp *cred;
00139 int_str ivalue;
00140 int i;
00141
00142 for (cred=credentials, i=1; cred; cred=cred->next, i++) {
00143 switch (result->col.types[i]) {
00144 case DB_STR:
00145 ivalue.s = VAL_STR(&(result->rows[0].values[i]));
00146
00147 if (VAL_NULL(&(result->rows[0].values[i])) ||
00148 ivalue.s.s == NULL || ivalue.s.len==0)
00149 continue;
00150
00151 if (add_avp(cred->avp_type|AVP_VAL_STR,cred->avp_name,ivalue)!=0){
00152 LM_ERR("failed to add AVP\n");
00153 return -1;
00154 }
00155
00156 LM_DBG("set string AVP \"%s\"/%d = \"%.*s\"\n",
00157 (cred->avp_type&AVP_NAME_STR)?cred->avp_name.s.s:"",
00158 (cred->avp_type&AVP_NAME_STR)?0:cred->avp_name.n,
00159 ivalue.s.len, ZSW(ivalue.s.s));
00160 break;
00161 case DB_STRING:
00162 ivalue.s.s = (char*)VAL_STRING(&(result->rows[0].values[i]));
00163
00164 if (VAL_NULL(&(result->rows[0].values[i])) ||
00165 ivalue.s.s == NULL || (ivalue.s.len=strlen(ivalue.s.s))==0 )
00166 continue;
00167
00168 if (add_avp(cred->avp_type|AVP_VAL_STR,cred->avp_name,ivalue)!=0){
00169 LM_ERR("failed to add AVP\n");
00170 return -1;
00171 }
00172
00173 LM_DBG("set string AVP \"%s\"/%d = \"%.*s\"\n",
00174 (cred->avp_type&AVP_NAME_STR)?cred->avp_name.s.s:"",
00175 (cred->avp_type&AVP_NAME_STR)?0:cred->avp_name.n,
00176 ivalue.s.len, ZSW(ivalue.s.s));
00177 break;
00178 case DB_INT:
00179 if (VAL_NULL(&(result->rows[0].values[i])))
00180 continue;
00181
00182 ivalue.n = (int)VAL_INT(&(result->rows[0].values[i]));
00183
00184 if (add_avp(cred->avp_type, cred->avp_name, ivalue)!=0) {
00185 LM_ERR("failed to add AVP\n");
00186 return -1;
00187 }
00188
00189 LM_DBG("set int AVP \"%s\"/%d = %d\n",
00190 (cred->avp_type&AVP_NAME_STR)?cred->avp_name.s.s:"",
00191 (cred->avp_type&AVP_NAME_STR)?0:cred->avp_name.n,
00192 ivalue.n);
00193 break;
00194 default:
00195 LM_ERR("subscriber table column `%.*s' has unsuported type. "
00196 "Only string/str or int columns are supported by"
00197 "load_credentials.\n", result->col.names[i]->len, result->col.names[i]->s);
00198 break;
00199 }
00200 }
00201
00202 return 0;
00203 }
00204
00205
00206
00207
00208
00209 static inline int authorize(struct sip_msg* _m, gparam_p _realm,
00210 char* _table, hdr_types_t _hftype)
00211 {
00212 char ha1[256];
00213 int res;
00214 struct hdr_field* h;
00215 auth_body_t* cred;
00216 auth_result_t ret;
00217 str domain, table;
00218 db_res_t* result = NULL;
00219
00220 if(!_table) {
00221 LM_ERR("invalid table parameter\n");
00222 return -1;
00223 }
00224
00225 table.s = _table;
00226 table.len = strlen(_table);
00227
00228 if(fixup_get_svalue(_m, _realm, &domain)!=0)
00229 {
00230 LM_ERR("invalid realm parameter\n");
00231 return AUTH_ERROR;
00232 }
00233
00234 if (domain.len==0)
00235 domain.s = 0;
00236
00237 ret = auth_api.pre_auth(_m, &domain, _hftype, &h);
00238
00239 if (ret != DO_AUTHORIZATION)
00240 return ret;
00241
00242 cred = (auth_body_t*)h->parsed;
00243
00244 res = get_ha1(&cred->digest.username, &domain, &table, ha1, &result);
00245 if (res < 0) {
00246
00247 if (slb.send_reply(_m, 500, &auth_500_err) == -1) {
00248 LM_ERR("failed to send 500 reply\n");
00249 }
00250 return ERROR;
00251 }
00252 if (res > 0) {
00253
00254 auth_dbf.free_result(auth_db_handle, result);
00255 return USER_UNKNOWN;
00256 }
00257
00258
00259 if (!auth_api.check_response(&(cred->digest),
00260 &_m->first_line.u.request.method, ha1)) {
00261 ret = auth_api.post_auth(_m, h);
00262 if (ret == AUTHORIZED)
00263 generate_avps(result);
00264 auth_dbf.free_result(auth_db_handle, result);
00265 return ret;
00266 }
00267
00268 auth_dbf.free_result(auth_db_handle, result);
00269 return INVALID_PASSWORD;
00270 }
00271
00272
00273
00274
00275
00276 int proxy_authorize(struct sip_msg* _m, char* _realm, char* _table)
00277 {
00278 return authorize(_m, (gparam_p)_realm, _table, HDR_PROXYAUTH_T);
00279 }
00280
00281
00282
00283
00284
00285 int www_authorize(struct sip_msg* _m, char* _realm, char* _table)
00286 {
00287 return authorize(_m, (gparam_p)_realm, _table, HDR_AUTHORIZATION_T);
00288 }