/* * Check if uri belongs to a local user */ int does_uri_exist(struct sip_msg* _msg, char* _s1, char* _s2) { db_key_t keys[2]; db_val_t vals[2]; db_key_t cols[1]; db_res_t* res; if (parse_sip_msg_uri(_msg) < 0) { LOG(L_ERR, "does_uri_exist(): Error while parsing URI\n"); return -1; } if (use_uri_table) { if (db_use_table(db_handle, uri_table) < 0) { LOG(L_ERR, "does_uri_exist(): Error while trying to use uri table\n"); } keys[0] = uri_uriuser_col; keys[1] = uri_domain_col; cols[0] = uri_uriuser_col; } else { if (db_use_table(db_handle, subscriber_table) < 0) { LOG(L_ERR, "does_uri_exist(): Error while trying to use subscriber table\n"); } keys[0] = subscriber_user_col; keys[1] = subscriber_domain_col; cols[0] = subscriber_user_col; } VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB_STR; VAL_NULL(vals) = VAL_NULL(vals + 1) = 0; VAL_STR(vals) = _msg->parsed_uri.user; VAL_STR(vals + 1) = _msg->parsed_uri.host; if (db_query(db_handle, keys, 0, vals, cols, (use_domain ? 2 : 1), 1, 0, &res) < 0) { LOG(L_ERR, "does_uri_exist(): Error while querying database\n"); return -2; } if (RES_ROW_N(res) == 0) { DBG("does_uri_exit(): User in request uri does not exist\n"); db_free_query(db_handle, res); return -3; } else { DBG("does_uri_exit(): User in request uri does exist\n"); db_free_query(db_handle, res); return 1; } }
gint cmd_list(GSList* arglist, const struct cmd_options* opts, struct error* e) { g_assert(opts != 0); g_assert(e != 0); gint verbose = opts->verbosity > 2; db_query_type type = verbose ? DB_QUERY_PKGS_WITHOUT_FILES : DB_QUERY_NAMES; GSList* list = db_query((db_selector)_list_selector, arglist, type); if (!e_ok(e)) { e_set(E_ERROR, "Package database query failed!"); return 1; } GSList* i; for (i = list; i != 0; i = i->next) { if (verbose) { struct db_pkg* pkg = i->data; printf("+===================================================================+\n"); printf("| %-65s |\n", pkg->name); printf("+===================================================================+\n"); printf("NAME: %s\n", pkg->shortname); printf("VERSION: %s\n", pkg->version); printf("ARCH: %s\n", pkg->arch); printf("BUILD: %s\n", pkg->build); printf("DATE: %s\n", _get_date(pkg->time)); printf("CSIZE: %u kB\n", pkg->csize); printf("USIZE: %u kB\n", pkg->usize); if (pkg->desc) printf("%s", pkg->desc); } else printf("%s\n", (gchar*)i->data); } db_free_query(list, type); return 0; }
/** * dump message */ static int m_dump(struct sip_msg* msg, char* str1, char* str2) { struct to_body to, *pto = NULL; db_key_t db_keys[1] = { DB_KEY_RURI }; db_val_t db_vals[1]; db_key_t db_cols[] = { DB_KEY_MID, DB_KEY_FROM, DB_KEY_TO, DB_KEY_BODY, DB_KEY_CTYPE, DB_KEY_INC_TIME }; db_res_t* db_res = NULL; int i, db_no_cols = IDX_NO, db_no_keys = 1, *msg_id, mid, n; char hdr_buf[1024], body_buf[1024]; str str_vals[IDX_NO], hdr_str , body_str; time_t rtime; DBG("MSILO:m_dump: ------------ start ------------\n"); hdr_str.s=hdr_buf; hdr_str.len=1024; body_str.s=body_buf; body_str.len=1024; // check for TO header if(parse_headers(msg, HDR_TO, 0)==-1 || !msg->to || !msg->to->body.s) { LOG(L_ERR,"MSILO:m_dump: ERROR cannot find TO HEADER!\n"); goto error; } // check TO header if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; DBG("MSILO:m_dump: 'To' header ALREADY PARSED: <%.*s>\n", pto->uri.len, pto->uri.s ); } else { memset( &to , 0, sizeof(to) ); parse_to(msg->to->body.s, msg->to->body.s + msg->to->body.len + 1, &to); if(to.uri.len <= 0) // || to.error != PARSE_OK) { DBG("MSILO:m_dump: 'To' header NOT parsed\n"); goto error; } pto = &to; } /** * check if has expires=0 (REGISTER) */ if(parse_headers(msg, HDR_EXPIRES, 0) >= 0) { //check 'expires' > 0 if(msg->expires && msg->expires->body.len > 0) { i = atoi(msg->expires->body.s); if(i <= 0) { // user goes offline DBG("MSILO:m_dump: user <%.*s> goes offline - expires=%d\n", pto->uri.len, pto->uri.s, i); goto error; } else DBG("MSILO:m_dump: user <%.*s> online - expires=%d\n", pto->uri.len, pto->uri.s, i); } } else { DBG("MSILO:m_dump: 'exprires' threw error at parsing\n"); goto error; } db_vals[0].type = DB_STR; db_vals[0].nul = 0; db_vals[0].val.str_val.s = pto->uri.s; db_vals[0].val.str_val.len = pto->uri.len; if((db_query(db_con,db_keys,NULL,db_vals,db_cols,db_no_keys,db_no_cols, NULL,&db_res)==0) && (RES_ROW_N(db_res) > 0)) { DBG("MSILO:m_dump: dumping [%d] messages for <%.*s>!!!\n", RES_ROW_N(db_res), pto->uri.len, pto->uri.s); for(i = 0; i < RES_ROW_N(db_res); i++) { mid = RES_ROWS(db_res)[i].values[DUMP_IDX_MID].val.int_val; if(msg_list_check_msg(ml, mid)) { DBG("MSILO:m_dump: message[%d] mid=%d already sent.\n", i, mid); continue; } memset(str_vals, 0, IDX_NO*sizeof(str)); SET_STR_VAL(str_vals[STR_IDX_FROM], db_res, i, DUMP_IDX_FROM); SET_STR_VAL(str_vals[STR_IDX_TO], db_res, i, DUMP_IDX_TO); SET_STR_VAL(str_vals[STR_IDX_BODY], db_res, i, DUMP_IDX_BODY); SET_STR_VAL(str_vals[STR_IDX_CTYPE], db_res, i, DUMP_IDX_CTYPE); hdr_str.len = 1024; if(m_build_headers(&hdr_str, str_vals[STR_IDX_CTYPE], str_vals[STR_IDX_FROM]) < 0) { DBG("MSILO:m_dump: headers bulding failed!!!\n"); if (db_free_query(db_con, db_res) < 0) DBG("MSILO:m_dump: Error while freeing result of" " query\n"); msg_list_set_flag(ml, mid, MS_MSG_ERRO); goto error; } if((msg_id = shm_malloc(sizeof(int))) == 0) { DBG("MSILO:m_dump: no more share memory!"); if (db_free_query(db_con, db_res) < 0) DBG("MSILO:m_dump: Error while freeing result of" " query\n"); msg_list_set_flag(ml, mid, MS_MSG_ERRO); goto error; } *msg_id = mid; DBG("MSILO:m_dump: msg [%d-%d] for: %.*s\n", i+1, *msg_id, pto->uri.len, pto->uri.s); /** sending using TM function: t_uac */ body_str.len = 1024; rtime = (time_t)RES_ROWS(db_res)[i].values[DUMP_IDX_INC_TIME].val.int_val; n = m_build_body(&body_str, rtime, str_vals[STR_IDX_BODY]); if(n<0) DBG("MSILO:m_dump: sending simple body\n"); else DBG("MSILO:m_dump: sending composed body\n"); //tmb.t_uac(&msg_type, &pto->uri, &hdr_str, // &body_str, &str_vals[STR_IDX_FROM], // m_tm_callback, (void*)msg_id, 0 //); tmb.t_request(&msg_type, /* Type of the message */ &pto->uri, /* Request-URI */ &str_vals[STR_IDX_TO], /* To */ &str_vals[STR_IDX_FROM], /* From */ &hdr_str, /* Optional headers including CRLF */ (n<0)?&str_vals[STR_IDX_BODY]:&body_str, /* Message body */ m_tm_callback, /* Callback function */ (void*)msg_id /* Callback parameter */ ); } } else DBG("MSILO:m_dump: no stored message for <%.*s>!\n", pto->uri.len, pto->uri.s); /** * Free the result because we don't need it * anymore */ if (db_free_query(db_con, db_res) < 0) DBG("MSILO:m_dump: Error while freeing result of query\n"); return 1; error: return -1; }
/** * init module function */ static int mod_init(void) { db_res_t* db_res = NULL; code_t i, code; dc_t* cell; DBG("PDT: initializing...\n"); if(hs_two_pow<0) { LOG(L_ERR, "PDT: mod_init: hash_size_two_pow must be" " positive and less than %d\n", MAX_HSIZE_TWO_POW); return -1; } if(code_terminator>9 || code_terminator<0) { LOG(L_ERR, "PDT: mod_init: code_terminator must be a digit\n"); return -1; } if(!prefix_valid()) return -1; next_code = (code_t*)shm_malloc(sizeof(code_t)); if(!next_code) { LOG(L_ERR, "PDT: mod_init: cannot allocate next_code!\n"); return -1; } if(lock_init(&l) == 0) { shm_free(next_code); LOG(L_ERR, "PDT: mod_init: cannot init the lock\n"); return -1; } if(register_fifo_cmd(get_domainprefix, "get_domainprefix", 0)<0) { LOG(L_ERR, "PDT: mod_init: cannot register fifo command 'get_domaincode'\n"); goto error1; } /* binding to mysql module */ if(bind_dbmod()) { LOG(L_ERR, "PDT: mod_init: Database module not found\n"); goto error1; } /* open a connection with the database */ db_con = db_init(db_url); if(!db_con) { LOG(L_ERR, "PDT: mod_init: Error while connecting to database\n"); goto error1; } else { db_use_table(db_con, db_table); DBG("PDT: mod_init: Database connection opened successfully\n"); } /* init hashes in share memory */ if( (hash = init_double_hash(hs_two_pow)) == NULL) { LOG(L_ERR, "PDT: mod_init: hash could not be allocated\n"); goto error2; } /* loading all information from database */ *next_code = 0; if(db_query(db_con, NULL, NULL, NULL, NULL, 0, 0, "code", &db_res)==0) { for(i=0; i<RES_ROW_N(db_res); i++) { code = RES_ROWS(db_res)[i].values[0].val.int_val; if (!code_valid(code)) { LOG(L_ERR, "PDT: mod_init: existing code contains the terminator\n"); goto error; } if (*next_code < code) *next_code = code; cell=new_cell( (char*)(RES_ROWS(db_res)[i].values[1].val.string_val), code); if(cell == NULL) goto error; if(add_to_double_hash(hash, cell)<0) { LOG(L_ERR, "PDT: mod_init: could not add information from database" " into shared-memory hashes\n"); goto error; } } // clear up here //print_hash(hash->dhash, hash->hash_size); //print_hash(hash->chash, hash->hash_size); (*next_code)++; if (*next_code < start_range) *next_code = start_range; *next_code = apply_correction(*next_code); DBG("PDT: mod_init: next_code:%d\n", *next_code); /* free up the space allocated for response */ if(db_free_query(db_con, db_res)<0) { LOG(L_ERR, "PDT: mod_init: error when freeing" " up the response space\n"); } } else { /* query to database failed */ LOG(L_ERR, "PDT: mod_init: query to database failed\n"); goto error; } db_close(db_con); /* janakj - close the connection */ /* success code */ return 0; error: free_double_hash(hash); error2: db_close(db_con); error1: shm_free(next_code); lock_destroy(&l); return -1; }
/* * Check if a header field contains the same username * as digest credentials */ static inline int check_username(struct sip_msg* _m, str* _uri) { struct hdr_field* h; auth_body_t* c; struct sip_uri puri; db_key_t keys[3]; db_val_t vals[3]; db_key_t cols[1]; db_res_t* res; if (!_uri) { LOG(L_ERR, "check_username(): Bad parameter\n"); return -1; } /* Get authorized digest credentials */ get_authorized_cred(_m->authorization, &h); if (!h) { get_authorized_cred(_m->proxy_auth, &h); if (!h) { LOG(L_ERR, "check_username(): No authorized credentials found (error in scripts)\n"); LOG(L_ERR, "check_username(): Call {www,proxy}_authorize before calling check_* function !\n"); return -2; } } c = (auth_body_t*)(h->parsed); /* Parse To/From URI */ if (parse_uri(_uri->s, _uri->len, &puri) < 0) { LOG(L_ERR, "check_username(): Error while parsing URI\n"); return -3; } /* Make sure that the URI contains username */ if (!puri.user.len) { LOG(L_ERR, "check_username(): Username not found in URI\n"); return -4; } /* If use_uri_table is set, use URI table to determine if Digest username * and To/From username match. URI table is a table enumerating all allowed * usernames for a single, thus a user can have several different usernames * (which are different from digest username and it will still match) */ if (use_uri_table) { /* Make sure that From/To URI domain and digest realm are equal * FIXME: Should we move this outside this condition and make it general ? */ if (puri.host.len != c->digest.realm.len) { LOG(L_ERR, "check_username(): Digest realm and URI domain do not match\n"); return -5; } if (strncasecmp(puri.host.s, c->digest.realm.s, puri.host.len) != 0) { DBG("check_username(): Digest realm and URI domain do not match\n"); return -6; } if (db_use_table(db_handle, uri_table) < 0) { LOG(L_ERR, "check_username(): Error while trying to use uri table\n"); } keys[0] = uri_user_col; keys[1] = uri_domain_col; keys[2] = uri_uriuser_col; cols[0] = uri_user_col; VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB_STR; VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0; VAL_STR(vals) = c->digest.username.user; VAL_STR(vals + 1) = c->digest.realm; VAL_STR(vals + 2) = puri.user; if (db_query(db_handle, keys, 0, vals, cols, 3, 1, 0, &res) < 0) { LOG(L_ERR, "check_username(): Error while querying database\n"); return -7; } /* If the previous function returns at least one row, it means * there is an entry for given digest username and URI username * and thus this combination is allowed and the function will match */ if (RES_ROW_N(res) == 0) { DBG("check_username(): From/To user '%.*s' is spoofed\n", puri.user.len, ZSW(puri.user.s)); db_free_query(db_handle, res); return -8; } else { DBG("check_username(): From/To user '%.*s' and auth user match\n", puri.user.len, ZSW(puri.user.s)); db_free_query(db_handle, res); return 1; } } else { /* URI table not used, simply compare digest username and From/To * username, the comparison is case insensitive */ if (puri.user.len == c->digest.username.user.len) { if (!strncasecmp(puri.user.s, c->digest.username.user.s, puri.user.len)) { DBG("check_username(): Digest username and URI username match\n"); return 1; } } DBG("check_username(): Digest username and URI username do NOT match\n"); return -9; } }