<div style="DIRECTION: ltr">
<div>Hello every one,</div>
<div>I change modules/auth_db/authorize.c to check pre-payed user's mount.It works,But I Get Memory leak.</div>
<div>I check the source many times,but I can't find the ploblem.</div>
<div>Can anyone else help me.</div>
<div>The following is my authorize,c file</div>
<div> </div>
<div> </div>
<div>##########################################################</div>
<div>
<p>#include <string.h><br>#include <stdlib.h><br>#include "../../ut.h"<br>#include "../../str.h"<br>#include "../../db/db.h"<br>#include "../../dprint.h"<br>#include "../../parser/digest/digest.h"
<br>#include "../../parser/parse_from.h"<br>#include "../../parser/parse_uri.h"<br>#include "../../parser/hf.h"<br>#include "../../parser/parser_f.h"<br>#include "../../usr_avp.h"
<br>#include "../../mem/mem.h"<br>#include "authdb_mod.h"<br>#include "rfc2617.h"</p>
<p><br>#define MESSAGE_500 "Server Internal Error"<br>#define MOUNT_COL "Amount"<br>#define MOUNT_COL_LEN (sizeof(MOUNT_COL)-1)<br>#define STATUS_COL "Status"<br>#define STATUS_COL_LEN (sizeof(STATUS_COL)-1)
<br>#define ACCT_CODE_COL "ACCT_CODE"<br>#define ACCT_CODE_COL_LEN (sizeof(ACCT_CODE_COL)-1)<br>#define AGENT_CODE "Agent_Code"<br>#define AGENT_CODE_LEN (sizeof(AGENT_CODE)-1)<br>#define ROOT_AGENT "Agent_Code_Root"
<br>#define ROOT_AGENT_LEN (sizeof(ROOT_AGENT)-1)<br>#define CARDNO "Card_No"<br>#define CARDNOLEN (sizeof(CARDNO)-1)<br>#define DOMAIN "domain"<br>#define DOMAINLEN (sizeof(DOMAIN)-1)<br>#define LOCALDOMAIN "
<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://xtox.org/" target="_blank">xtox.org</a>"</p>
<p>static db_con_t* db_handle=0; /* database connection handle */<br>static db_func_t auth_dbf;</p>
<p>/************************************************************<br> get user agent a mount from CASH_ACCT_INTO table</p>
<p> select Amount,Status from CASH_ACCT_INFO where acct_code = '10agent';<br> select Amount,Status from CASH_ACCT_INFO where acct_code_root = '10agentroor' </p>
<p> **********************************************************/</p>
<p>static inline int getagentmount(str agent)<br>{<br> db_key_t key[1];<br> db_val_t val[1];<br> db_key_t* col;<br> db_res_t* res;</p>
<p> double mount=0.0;<br> int status=3;<br> int n,nc;</p>
<p><br> str acct_code = {ACCT_CODE_COL,ACCT_CODE_COL_LEN}; //CASH_ACCT_INFO.ACCT_CODE<br> str mount_col = {MOUNT_COL,MOUNT_COL_LEN};//CASH_ACCT_INFO.Amount<br> str status_col = {STATUS_COL,STATUS_COL_LEN};//CASH_ACCT_INFO.Status
<br> col = pkg_malloc(sizeof(*col)*2);<br> if(col == NULL)<br> {<br> return -1;<br> }<br> col[0] = mount_col.s;<br> col[1] = status_col.s;</p>
<p> key[0] = acct_code.s;</p>
<p> char agentcode[2000];<br> bzero(agentcode,sizeof(agentcode));<br> strcpy(agentcode,"1000");<br> strncat(agentcode,agent.s,agent.len);</p>
<p> VAL_TYPE(val) = DB_STR;<br> VAL_NULL(val) = 0;<br> VAL_STR(val).s = (char*)agentcode;<br> VAL_STR(val).len = strlen(agentcode);<br> n=1;<br> nc=2;<br> if (auth_dbf.use_table(db_handle, "CASH_ACCT_INFO") < 0) {
<br> pkg_free(col);<br> return -1;<br> }<br> if (auth_dbf.query(db_handle, key, 0, val, col, n, nc, 0, &res) < 0) {<br> pkg_free(col);<br> auth_dbf.free_result(db_handle,res);<br> return -1;<br> }<br> if ((RES_ROW_N(res) == 0)) {
<br> pkg_free(col);<br> auth_dbf.free_result(db_handle,res);<br> return 1;<br> }<br> pkg_free(col);<br> mount = ROW_VALUES(RES_ROWS(res))[0].val.double_val;<br> status = ROW_VALUES(RES_ROWS(res))[1].val.int_val;</p>
<p><br> if((mount > 1)&&(status>0))<br> {<br> auth_dbf.free_result(db_handle,res);<br> return 2; <br> }<br> auth_dbf.free_result(db_handle,res);<br> return 0;<br>}</p>
<p><br>/*************************************************************<br> get username from tblDOMAIN_ACCT<br> Function name:getusername<br>Parameters: <br>str domain[in];<br>char* acct[in/out]:if get acct ,stored in this field
<br>Return Value:<br>if find domain from tblDOMAIN_ACCT AND GetAccount return 1;<br>if find no acct return 0;<br>IF SOME ERROR OCCORS RETURN -1;</p>
<p><br> ***********************************************************/</p>
<p>static inline int getusername(char* domain,char* acct)<br>{<br> db_key_t key[1];<br> db_val_t val[1];<br> db_key_t *col;<br> db_res_t *res;</p>
<p> str cardnocol = {CARDNO,CARDNOLEN};<br> str domaincol = {DOMAIN,DOMAINLEN};<br> col = pkg_malloc(sizeof(*col) * 1);//only one column (Card_No) to select from tblDOMAIN_ACCT<br> if(col == NULL)<br> {<br> return -1;<br>
}<br> col[0] = cardnocol.s;<br> key[0] = domaincol.s;<br> VAL_TYPE(val) = DB_STR;<br> VAL_NULL(val) = 0;<br> VAL_STR(val).s = domain;<br> VAL_STR(val).len = strlen(domain);</p>
<p> if (auth_dbf.use_table(db_handle, "tblDOMAIN_ACCT") < 0) {<br> pkg_free(col);<br> return -1;<br> }<br> if (auth_dbf.query(db_handle, key, 0, val, col, 1, 1, 0, &res) < 0) {<br> pkg_free(col);<br>
return -1;<br> }<br> if ((RES_ROW_N(res) == 0)) {<br> pkg_free(col);<br> auth_dbf.free_result(db_handle,res);<br> return 0;<br> }<br> pkg_free(col);</p>
<p> strcpy(acct,(char*)ROW_VALUES(RES_ROWS(res))[0].val.string_val);<br> auth_dbf.free_result(db_handle,res);<br> return 1;<br>}</p>
<p> </p>
<p>/**************************************************************<br> get user amount from CASH_ACCT_INFO table<br> it's sql is<br> select amount,status,Agent_Code,Agent_Code_Root from CASH_ACCT_INFO where acct_code = '20user'
<br> ************************************************************/<br>static inline int getmount(/*str username*/char* username,char* agent,char* agentroot)<br>{<br> db_key_t key[1];<br> db_val_t val[1];<br> db_key_t* col;
<br> db_res_t* res;</p>
<p> double mount;<br> int n,nc;<br> int status;</p>
<p> str mount_col = {MOUNT_COL,MOUNT_COL_LEN};//CASH_ACCT_INFO.AMOUNT<br> str status_col = {STATUS_COL,STATUS_COL_LEN};//CASH_ACCT_INFO.Status<br> str acct_code = {ACCT_CODE_COL,ACCT_CODE_COL_LEN}; //CASH_ACCT_INFO.ACCT_CODE
<br> str agent_code = {AGENT_CODE,AGENT_CODE_LEN};//CASH_ACCT_INFO.Agent_Code<br> str root_agent = {ROOT_AGENT,ROOT_AGENT_LEN};//CASH_ACCT_INFO.Agent_Code_Root</p>
<p> col = pkg_malloc(sizeof(*col) * 4 );//4 column to select Amout,Status,Agent_Code,Agent_Code_Root<br> if (col == NULL) {<br> LOG(L_ERR, "getmount: Error while allocating memory\n");<br> return -1;<br> }<br>
col[0] = mount_col.s;<br> col[1] = status_col.s;<br> col[2] = agent_code.s;<br> col[3] = root_agent.s;</p>
<p> key[0] = acct_code.s;</p>
<p> char user[2500];<br> bzero(user,sizeof(user));<br> strcpy(user,"2000");<br> strcat(user,username);<br> VAL_TYPE(val) = DB_STR;<br> VAL_NULL(val) = 0;<br> VAL_STR(val).s = (char*)user;<br> VAL_STR(val).len = strlen(user);
<br> n = 1;<br> //nc = credentials_n + 1;<br> nc = 4;<br> if (auth_dbf.use_table(db_handle, "CASH_ACCT_INFO") < 0) {<br> pkg_free(col);<br> return -1;<br> }<br> if (auth_dbf.query(db_handle, key, 0, val, col, n, nc, 0, &res) < 0) {
<br> pkg_free(col);<br> return -1;<br> }<br> if ((RES_ROW_N(res) == 0)) {<br> pkg_free(col);<br> auth_dbf.free_result(db_handle,res);<br> return 1;<br> }</p>
<p> pkg_free(col);<br> mount = ROW_VALUES(RES_ROWS(res))[0].val.double_val;<br> status = ROW_VALUES(RES_ROWS(res))[1].val.int_val;</p>
<p> if((mount > 1)&&(status>0))<br> { <br> str agent1,agentroot1;<br> agent1.s = (char*)ROW_VALUES(RES_ROWS(res))[2].val.string_val;<br> agent1.len = strlen(agent1.s);<br> agentroot1.s = (char*)ROW_VALUES(RES_ROWS(res))[3].val.string_val;
<br> agentroot1.len = strlen(agentroot1.s);<br> strncpy(agent,agent1.s,agent1.len);<br> strncpy(agentroot,agentroot1.s,agentroot1.len);<br> auth_dbf.free_result(db_handle,res);<br> return 2;<br> } <br> else<br> {<br>
auth_dbf.free_result(db_handle,res);<br> return 0;<br> }<br>}</p>
<p><br>/*<br> * Calculate the response and compare with the given response string<br> * Authorization is successful if this two strings are same<br> */<br>static inline int check_response(dig_cred_t* _cred, str* _method, char* _ha1)
<br>{<br> HASHHEX resp, hent;</p>
<p> /*<br> * First, we have to verify that the response received has<br> * the same length as responses created by us<br> */<br> if (_cred->response.len != 32) {<br> DBG("check_response(): Receive response len != 32\n");
<br> return 1;<br> }</p>
<p> /*<br> * Now, calculate our response from parameters received<br> * from the user agent<br> */<br> calc_response(_ha1, &(_cred->nonce), <br> &(_cred->nc), &(_cred->cnonce), <br> &(_cred->
qop.qop_str), _cred->qop.qop_parsed == QOP_AUTHINT,<br> _method, &(_cred->uri), hent, resp);</p>
<p> DBG("check_response(): Our result = \'%s\'\n", resp);</p>
<p> /*<br> * And simply compare the strings, the user is<br> * authorized if they match<br> */<br> if (!memcmp(resp, _cred->response.s, 32)) {<br> DBG("check_response(): Authorization is OK\n");<br> return 0;
<br> } else {<br> DBG("check_response(): Authorization failed\n");<br> return 2;<br> }<br>}</p>
<p><br>/*<br> * Authorize digest credentials<br> */<br>static inline int authorize(struct sip_msg* _m, str* _realm, char* _table, int _hftype)<br>{<br> char ha1[256];<br> int res, i;<br> struct hdr_field* h;<br> auth_body_t* cred;
<br> auth_result_t ret;<br> str domain, value;<br> int_str iname, ivalue;<br> db_res_t* result;<br> str rpid;<br> domain = *_realm;</p>
<p> </p>
<p> ret = pre_auth_func(_m, &domain, _hftype, &h);</p>
<p> switch(ret) {<br> case ERROR: return 0;<br> case NOT_AUTHORIZED: return -1;<br> case DO_AUTHORIZATION: break;<br> case AUTHORIZED: return 1;<br> }<br> str furi;<br> struct sip_uri puri;<br> if(parse_from_header(_m)<0)
<br> {<br> return -1;<br> }<br> furi = get_from(_m)->uri;<br> if(parse_uri(furi.s,furi.len,&puri) < 0)<br> {<br> return -1;<br> }</p>
<p> char msgdomain[2055];<br> bzero(msgdomain,sizeof(msgdomain));<br> strncpy(msgdomain,puri.host.s,puri.host.len);<br> int m,len;<br> int p=0;<br> len=strlen(msgdomain);<br> for(m=0;m<len;m++)<br> {<br> if(msgdomain[m]!='@')
<br> msgdomain[p++]=msgdomain[m];<br> }<br> msgdomain[p]='\0';</p>
<p> cred = (auth_body_t*)h->parsed;<br> char acct[2000];<br> bzero(acct,sizeof(acct));<br> struct username* tmp = &cred->digest.username;<br> if(strncmp(msgdomain,domain.s,strlen(msgdomain)))//domain is not local domain
<br> {<br> if((res = getusername(msgdomain,acct)) == 1)<br> {<br> tmp->user.s = (char*)acct;<br> tmp->user.len = strlen(acct);<br> }<br> else<br> {<br> return -1;<br> }<br> }<br> else<br> {<br> strncpy(acct,tmp->
user.s,tmp->user.len);<br> }</p>
<p><br> res = get_ha1(tmp, &domain, _table, ha1, &result);<br> //res = get_ha1(&cred->digest.username, &domain, _table, ha1, &result);<br> if (res < 0) {<br> /* Error while accessing the database */
<br> if (sl_reply(_m, (char*)500, MESSAGE_500) == -1) {<br> LOG(L_ERR, "authorize(): Error while sending 500 reply\n");<br> }<br> return 0;<br> }<br> if (res > 0) {<br> /* Username not found in the database */
<br> auth_dbf.free_result(db_handle, result);<br> return -1;<br> }</p>
<p><br> char agent[2000],agentroot[2000];<br> bzero(agent,sizeof(agent));<br> bzero(agentroot,sizeof(agentroot));</p>
<p><br> res = getmount(acct,agent,agentroot);<br> if(res < 0)<br> {<br> auth_dbf.free_result(db_handle, result);<br> return 0;<br> }<br> if(res == 0)<br> {<br> auth_dbf.free_result(db_handle, result);<br> return -1;
<br> }<br> if(res == 1)<br> {<br> auth_dbf.free_result(db_handle, result);<br> return -1;<br> }</p>
<p> if(res == 2)<br> {<br> str ll,ss;<br> ll.s = (char*)agent;<br> ll.len = strlen(ll.s);<br> ss.s = (char*)agentroot;<br> ss.len = strlen(ss.s);<br> if(getagentmount(ll) != 2)<br> {<br> auth_dbf.free_result(db_handle, result);
<br> return -1;<br> }<br> if(strcmp(agent,agentroot))<br> {<br> if(getagentmount(ss) != 2)<br> {<br> auth_dbf.free_result(db_handle, result);<br> return -1;<br> }<br> }<br> }</p>
<p><br> /* Recalculate response, it must be same to authorize successfully */<br> if (!check_response(&(cred->digest), &_m->first_line.u.request.method, ha1)) {<br> rpid.s = NULL;<br> rpid.len = 0;<br> for (i = 0; i < avps_str_n; i++) {
<br> if (avps_str[i].len != 4<br> || VAL_NULL(&(result->rows[0].values[1 + avps_int_n + i]))<br> || memcmp(avps_str[i].s, "rpid", 4) != 0)<br> continue;<br> rpid.s = (char*)VAL_STRING(&(result->rows[0].values[1 + avps_int_n + i]));
<br> if(rpid.s!=NULL)<br> rpid.len = strlen(rpid.s);<br> }<br> ret = post_auth_func(_m, h, &rpid);<br> switch(ret) {<br> case ERROR:<br> auth_dbf.free_result(db_handle, result);<br> return 0;<br> case NOT_AUTHORIZED:
<br> auth_dbf.free_result(db_handle, result);<br> return -1;<br> case AUTHORIZED:<br> for (i = 0; i < avps_int_n; i++) {<br> if(VAL_NULL(&(result->rows[0].values[1 + i])))<br> continue;<br>
iname.s = &(avps_int[i]);<br> ivalue.n = VAL_INT(&(result->rows[0].values[1 + i]));<br> add_avp(AVP_NAME_STR, iname, ivalue);<br> DBG("authorize(): set integer AVP \'%.*s = %d\'\n",<br>
iname.s->len, ZSW(iname.s->s), ivalue.n);<br> }<br> for (i = 0; i < avps_str_n; i++) {<br> value.s = (char*)VAL_STRING(&(result->rows[0].values[1 + avps_int_n + i]));<br> if(VAL_NULL(&(result->rows[0].values[1 + avps_int_n + i]))
<br> || value.s==NULL)<br> continue;<br> iname.s = &(avps_str[i]);<br> value.len = strlen(value.s);<br> ivalue.s = &value;<br> add_avp(AVP_NAME_STR | AVP_VAL_STR, iname, ivalue);<br> DBG("authorize(): set string AVP \'%.*s = %.*s\'\n",
<br> iname.s->len, ZSW(iname.s->s), value.len, ZSW(value.s));<br> }<br> auth_dbf.free_result(db_handle, result);<br> return 1;<br> default:<br> auth_dbf.free_result(db_handle, result);<br> return -1;
<br> }<br> }</p>
<p> auth_dbf.free_result(db_handle, result);<br> return -1;<br>}</p>
<p><br>/*<br> * Authorize using Proxy-Authorize header field<br> */<br>int proxy_authorize(struct sip_msg* _m, char* _realm, char* _table)<br>{<br> /* realm parameter is converted to str* in str_fixup */<br> return authorize(_m, (str*)_realm, _table, HDR_PROXYAUTH);
<br>}</p>
<p><br>/*<br> * Authorize using WWW-Authorize header field<br> */<br>int www_authorize(struct sip_msg* _m, char* _realm, char* _table)<br>{<br> return authorize(_m, (str*)_realm, _table, HDR_AUTHORIZATION);<br>}</p>
<p> </p>
<p>int auth_db_init(char* db_url)<br>{<br> if (auth_dbf.init==0){<br> LOG(L_CRIT, "BUG: auth_db_bind: null dbf\n");<br> goto error;<br> }<br> db_handle=auth_dbf.init(db_url);<br> if (db_handle==0){<br> LOG(L_ERR, "ERROR: auth_db_bind: unable to connect to the database\n");
<br> goto error;<br> }<br> return 0;<br>error:<br> return -1;<br>}</p>
<p><br>int auth_db_bind(char* db_url)<br>{<br> if (bind_dbmod(db_url, &auth_dbf)<0){<br> LOG(L_ERR, "ERROR: auth_db_bind: unable to bind to the database"<br> " module\n");<br> return -1;<br>
}<br> return 0;<br>}</p>
<p><br>void auth_db_close()<br>{<br> if (db_handle && auth_dbf.close){<br> auth_dbf.close(db_handle);<br> db_handle=0;<br> }<br>}</p>
<p><br>int auth_db_ver(char* db_url, str* name)<br>{<br> db_con_t* dbh;<br> int ver;</p>
<p> if (auth_dbf.init==0){<br> LOG(L_CRIT, "BUG: auth_db_ver: unbound database\n");<br> return -1;<br> }<br> dbh=auth_dbf.init(db_url);<br> if (dbh==0){<br> LOG(L_ERR, "ERROR: auth_db_ver: unable to open database connection\n");
<br> return -1;<br> }<br> ver=table_version(&auth_dbf, dbh, name);<br> auth_dbf.close(dbh);<br> return ver;<br>}<br>##########################################################</p></div></div>