static int ki_prefix2domain(sip_msg_t* msg, int m, int s) { int f; str sdomain={"*",1}; sip_uri_t *furi; if(m!=1 && m!=2) m = 0; if(s!=1 && s!=2) s = 0; f = 0; if(s==1 || s==2) { /* take the domain from FROM uri as sdomain */ if((furi = parse_from_uri(msg))==NULL) { LM_ERR("cannot parse FROM header URI\n"); return -1; } sdomain = furi->host; if(s==2) f = 1; } return pd_translate(msg, &sdomain, m, f); }
/* * Return parsed To or From, host part of the parsed uri is realm */ int get_realm(struct sip_msg* _m, hdr_types_t _hftype, struct sip_uri** _u) { if(_u==NULL) return -1; if ((REQ_LINE(_m).method.len == 8) && !memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) && (_hftype == HDR_AUTHORIZATION_T) ) { if (!_m->to && ((parse_headers(_m, HDR_TO_F, 0)==-1) || (!_m->to))) { LM_ERR("failed to parse TO headers\n"); return -1; } /* Body of To header field is parsed automatically */ if((*_u = parse_to_uri(_m))==NULL) return -1; } else { if (parse_from_header(_m) < 0) { LM_ERR("failed to parse FROM headers\n"); return -2; } if((*_u = parse_from_uri(_m))==NULL) return -1; } return 0; }
static int l_sipwatch_getFlag(lua_State *L) { struct sipapi_object *o; struct sip_uri *myuri; o = luaL_checkudata(L, 1, "siplua.api"); myuri = parse_from_uri(o->msg); if (myuri) { if (sipwatch_getFlagFromExtension(myuri->user.s, myuri->user.len)) { lua_pushboolean(L, 1); return 1; } } myuri = parse_to_uri(o->msg); if (myuri) { if (sipwatch_getFlagFromExtension(myuri->user.s, myuri->user.len)) { lua_pushboolean(L, 1); return 1; } } lua_pushnil(L); return 1; }
/* * Check if host in From uri is local */ int is_from_local(struct sip_msg* _msg, char* _s1, char* _s2) { struct sip_uri *puri; if ((puri=parse_from_uri(_msg))==NULL) { LM_ERR("Error while parsing From header\n"); return -2; } return is_domain_local(_msg, &(puri->host), _s1); }
/* * Check if host in From uri is local */ int is_from_local(struct sip_msg* _msg, char* _s1, char* _s2) { struct sip_uri *puri; str did; struct attr_list *attrs; if ((puri=parse_from_uri(_msg))==NULL) { LM_ERR("Error while parsing From header\n"); return -2; } return hash_table_lookup(&(puri->host), &did, &attrs); }
/* * Check username part in From header field */ int check_from(struct sip_msg* _m, char* _s1, char* _s2) { if (parse_from_header(_m) < 0) { LM_ERR("Error while parsing From header field\n"); return ERR_INTERNAL; } if(parse_from_uri(_m)==NULL) { LM_ERR("Error while parsing From header URI\n"); return ERR_INTERNAL; } return check_username(_m, &get_from(_m)->parsed_uri); }
static inline int check_from(struct sip_msg *_m, str *_username) { if (parse_from_header(_m) < 0) { LM_ERR("parsing From: header\n"); return CHECK_ERROR; } if (parse_from_uri(_m) == NULL) { LM_ERR("parsing From: URI\n"); return CHECK_ERROR; } return check_username(_username, &get_from(_m)->parsed_uri); }
/* * Converts Request-URI, if it is tel URI, to SIP URI. Returns 1, if * conversion succeeded or if no conversion was needed, i.e., Request-URI * was not tel URI. Returns -1, if conversion failed. */ int tel2sip(struct sip_msg* _msg, char* _s1, char* _s2) { str *ruri; struct sip_uri *pfuri; str suri; char* at; ruri = GET_RURI(_msg); if (ruri->len < 4) return 1; if (strncasecmp(ruri->s, "tel:", 4) != 0){ return 1; } if ((pfuri=parse_from_uri(_msg))==NULL) { LM_ERR("parsing From header failed\n"); return -1; } suri.len = 4 + ruri->len - 4 + 1 + pfuri->host.len + 1 + 10; suri.s = pkg_malloc(suri.len); if (suri.s == 0) { LM_ERR("no more pkg memory\n"); return -1; } at = suri.s; memcpy(at, "sip:", 4); at = at + 4; memcpy(at, ruri->s + 4, ruri->len - 4); at = at + ruri->len - 4; *at = '@'; at = at + 1; memcpy(at, pfuri->host.s, pfuri->host.len); at = at + pfuri->host.len; *at = ';'; at = at + 1; memcpy(at, "user=phone", 10); if (set_ruri(_msg, &suri) == 1) { pkg_free(suri.s); return 1; } else { pkg_free(suri.s); return -1; } }
/** * handle RLS subscription */ int rls_handle_subscribe0(struct sip_msg* msg) { struct to_body *pfrom; if (parse_from_uri(msg) < 0) { LM_ERR("failed to find From header\n"); if (slb.freply(msg, 400, &pu_400_rpl) < 0) { LM_ERR("while sending 400 reply\n"); return -1; } return 0; } pfrom = (struct to_body *) msg->from->parsed; return rls_handle_subscribe(msg, pfrom->parsed_uri.user, pfrom->parsed_uri.host); }
static int send_smpp_msg(struct sip_msg *msg, str *name) { str body; smpp_session_t *session = NULL; session = smpp_session_get(name); if (!session) { LM_INFO("SMSc %.*s not found!\n", name->len, name->s); return -2; } if(msg->parsed_uri_ok==0) parse_sip_msg_uri(msg); get_body(msg, &body); send_submit_or_deliver_request(&body, &parse_from_uri(msg)->user, &msg->parsed_uri.user, session); return 0; }
static gchar *build_hdfs_path(const char *uri, const char *path){ HLOG_DEBUG("hdfs -- enter func %s", __func__); char *head = NULL; char *hostname = NULL; char *dir = NULL; char *fs_name = NULL; int port; int ret = parse_from_uri(uri, &head, &hostname, &dir, &fs_name, &port); if (ret != 0) { HLOG_ERROR("parse_from_uri error!"); return NULL; } gchar *full_path = g_build_filename(dir, fs_name, path, NULL); HLOG_DEBUG("full path is %s", full_path); g_free(head); g_free(hostname); //g_free(dir); HLOG_DEBUG("hdfs -- leave func %s", __func__); return full_path; }
/* * Extract URI depending on the request from To or From header */ static inline int get_uri_user(struct sip_msg* _m, str** _uri_user) { struct sip_uri *puri; if ((REQ_LINE(_m).method.len == 8) && (memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) == 0)) { if ((puri=parse_to_uri(_m))==NULL) { LM_ERR("failed to parse To header\n"); return -1; } } else { if ((puri=parse_from_uri(_m))==NULL) { LM_ERR("parsing From header\n"); return -1; } } *_uri_user = &(puri->user); return 0; }
int rls_handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_domain) { subs_t subs; pres_ev_t* event = NULL; int err_ret = -1; int ret = to_presence_code; str* contact = NULL; xmlDocPtr doc = NULL; xmlNodePtr service_node = NULL; unsigned int hash_code=0; int to_tag_gen = 0; event_t* parsed_event; param_t* ev_param = NULL; str reason; int rt; str rlsubs_did = {0, 0}; memset(&subs, 0, sizeof(subs_t)); /** sanity checks - parse all headers */ if (parse_headers(msg, HDR_EOH_F, 0)<-1) { LM_ERR("failed parsing all headers\n"); if (slb.freply(msg, 400, &pu_400_rpl) < 0) { LM_ERR("while sending 400 reply\n"); return -1; } return 0; } /* check for To and From headesr */ if(parse_to_uri(msg)<0 || parse_from_uri(msg)<0) { LM_ERR("failed to find To or From headers\n"); if (slb.freply(msg, 400, &pu_400_rpl) < 0) { LM_ERR("while sending 400 reply\n"); return -1; } return 0; } if(get_from(msg)->tag_value.s ==NULL || get_from(msg)->tag_value.len==0) { LM_ERR("no from tag value present\n"); return -1; } if(msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot find callid header\n"); return -1; } if(parse_sip_msg_uri(msg)<0) { LM_ERR("failed parsing Request URI\n"); return -1; } /* check for header 'Support: eventlist' */ if(msg->supported==NULL) { LM_DBG("supported header not found - not for rls\n"); goto forpresence; } if(parse_supported(msg)<0) { LM_ERR("failed to parse supported headers\n"); return -1; } if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST)) { LM_DBG("No support for 'eventlist' - not for rls\n"); goto forpresence; } /* inspecting the Event header field */ if(msg->event && msg->event->body.len > 0) { if (!msg->event->parsed && (parse_event(msg->event) < 0)) { LM_ERR("cannot parse Event header\n"); goto error; } if(! ( ((event_t*)msg->event->parsed)->type & rls_events) ) { goto forpresence; } } else { goto bad_event; } /* search event in the list */ parsed_event = (event_t*)msg->event->parsed; event = pres_search_event(parsed_event); if(event==NULL) { goto bad_event; } subs.event= event; /* extract the id if any*/ ev_param= parsed_event->params.list; while(ev_param) { if(ev_param->name.len==2 && strncmp(ev_param->name.s, "id", 2)==0) { subs.event_id = ev_param->body; break; } ev_param= ev_param->next; } /* extract dialog information from message headers */ if(pres_extract_sdialog_info(&subs, msg, rls_max_expires, &to_tag_gen, rls_server_address, watcher_user, watcher_domain)<0) { LM_ERR("bad subscribe request\n"); goto error; } hash_code = core_hash(&subs.callid, &subs.to_tag, hash_size); if (CONSTR_RLSUBS_DID(&subs, &rlsubs_did) < 0) { LM_ERR("cannot build rls subs did\n"); goto error; } subs.updated = core_hash(&rlsubs_did, NULL, 0) % (waitn_time * rls_notifier_poll_rate * rls_notifier_processes); if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0) { /* initial Subscribe */ /*verify if Request URI represents a list by asking xcap server*/ if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host, &subs.pres_uri)<0) { LM_ERR("while constructing uri from user and domain\n"); goto error; } if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user, &subs.watcher_domain, &service_node, &doc)<0) { LM_ERR("while attepmting to get a resource list\n"); goto error; } if(doc==NULL) { /* if not for RLS, pass it to presence serivce */ LM_DBG("list not found - searched for uri <%.*s>\n", subs.pres_uri.len, subs.pres_uri.s); goto forpresence; } /* if correct reply with 200 OK */ if(reply_200(msg, &subs.local_contact, subs.expires)<0) goto error; subs.local_cseq = 0; if(subs.expires != 0) { subs.version = 1; if (dbmode==RLS_DB_ONLY) { rt=insert_rlsdb( &subs ); } else { rt=pres_insert_shtable(rls_table, hash_code, &subs); } if (rt<0) { LM_ERR("while adding new subscription\n"); goto error; } } } else { /* search if a stored dialog */ if ( dbmode == RLS_DB_ONLY ) { if (rls_dbf.start_transaction) { if (rls_dbf.start_transaction(rls_db, DB_LOCKING_WRITE) < 0) { LM_ERR("in start_transaction\n"); goto error; } } rt = get_dialog_subscribe_rlsdb(&subs); if (rt <= 0) { LM_DBG("subscription dialog not found for <%.*s@%.*s>\n", subs.watcher_user.len, subs.watcher_user.s, subs.watcher_domain.len, subs.watcher_domain.s); if (rls_dbf.end_transaction) { if (rls_dbf.end_transaction(rls_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } goto forpresence; } else if(rt>=400) { reason = (rt==400)?pu_400_rpl:stale_cseq_rpl; if (slb.freply(msg, 400, &reason) < 0) { LM_ERR("while sending reply\n"); goto error; } if (rls_dbf.end_transaction) { if (rls_dbf.end_transaction(rls_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } ret = 0; goto stop; } /* if correct reply with 200 OK */ if(reply_200(msg, &subs.local_contact, subs.expires)<0) goto error; if (update_dialog_subscribe_rlsdb(&subs) < 0) { LM_ERR("while updating resource list subscription\n"); goto error; } if (rls_dbf.end_transaction) { if (rls_dbf.end_transaction(rls_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } } else { lock_get(&rls_table[hash_code].lock); if(pres_search_shtable(rls_table, subs.callid, subs.to_tag, subs.from_tag, hash_code)==NULL) { lock_release(&rls_table[hash_code].lock); LM_DBG("subscription dialog not found for <%.*s@%.*s>\n", subs.watcher_user.len, subs.watcher_user.s, subs.watcher_domain.len, subs.watcher_domain.s); goto forpresence; } lock_release(&rls_table[hash_code].lock); /* if correct reply with 200 OK */ if(reply_200(msg, &subs.local_contact, subs.expires)<0) goto error; rt = update_rlsubs(&subs, hash_code); if(rt<0) { LM_ERR("while updating resource list subscription\n"); goto error; } if(rt>=400) { reason = (rt==400)?pu_400_rpl:stale_cseq_rpl; if (slb.freply(msg, 400, &reason) < 0) { LM_ERR("while sending reply\n"); goto error; } ret = 0; goto stop; } } if(rls_get_service_list(&subs.pres_uri, &subs.watcher_user, &subs.watcher_domain, &service_node, &doc)<0) { LM_ERR("failed getting resource list\n"); goto error; } if(doc==NULL) { /* warning: no document returned?!?! */ LM_WARN("no document returned for uri <%.*s>\n", subs.pres_uri.len, subs.pres_uri.s); goto done; } } if (dbmode != RLS_DB_ONLY) { /* sending notify with full state */ if(send_full_notify(&subs, service_node, &subs.pres_uri, hash_code)<0) { LM_ERR("failed sending full state notify\n"); goto error; } } /* send subscribe requests for all in the list */ if(resource_subscriptions(&subs, service_node)< 0) { LM_ERR("failed sending subscribe requests to resources in list\n"); goto error; } if (dbmode !=RLS_DB_ONLY) remove_expired_rlsubs(&subs, hash_code); done: ret = 1; stop: forpresence: if(contact!=NULL) { if(contact->s!=NULL) pkg_free(contact->s); pkg_free(contact); } if(subs.pres_uri.s!=NULL) pkg_free(subs.pres_uri.s); if(subs.record_route.s!=NULL) pkg_free(subs.record_route.s); if(doc!=NULL) xmlFreeDoc(doc); if (rlsubs_did.s != NULL) pkg_free(rlsubs_did.s); return ret; bad_event: err_ret = 0; if(reply_489(msg)<0) { LM_ERR("failed sending 489 reply\n"); err_ret = -1; } error: LM_ERR("occured in rls_handle_subscribe\n"); if(contact!=NULL) { if(contact->s!=NULL) pkg_free(contact->s); pkg_free(contact); } if(subs.pres_uri.s!=NULL) pkg_free(subs.pres_uri.s); if(subs.record_route.s!=NULL) pkg_free(subs.record_route.s); if(doc!=NULL) xmlFreeDoc(doc); if (rlsubs_did.s != NULL) pkg_free(rlsubs_did.s); if (rls_dbf.abort_transaction) { if (rls_dbf.abort_transaction(rls_db) < 0) LM_ERR("in abort_transaction\n"); } return err_ret; }
int get_username_domain(struct sip_msg *msg, str *hf_s, str *username, str *domain) { struct sip_uri puri; struct sip_uri *turi; struct hdr_field* h; struct auth_body* c = 0; /* Makes gcc happy */ turi = NULL; switch( hf_type(hf_s) ) { case 1: /* Request-URI */ if(parse_sip_msg_uri(msg)<0) { LM_ERR("failed to get Request-URI\n"); return -1; } turi = &msg->parsed_uri; break; case 2: /* To */ if((turi=parse_to_uri(msg))==NULL) { LM_ERR("failed to get To URI\n"); return -1; } break; case 3: /* From */ if((turi=parse_from_uri(msg))==NULL) { LM_ERR("failed to get From URI\n"); return -1; } break; case 4: /* Credentials */ get_authorized_cred( msg->authorization, &h); if (!h) { get_authorized_cred( msg->proxy_auth, &h); if (!h) { LM_ERR("no authorized credentials found " "(error in scripts)\n"); return -1; } } c = (auth_body_t*)(h->parsed); break; default: /* string */ if (parse_uri(hf_s->s, hf_s->len, &puri) < 0) { LM_ERR("failed to parse URI <%.*s>\n",hf_s->len, hf_s->s); return -1; } turi = &puri; break; } if ( c==NULL ) { *username = turi->user; *domain = turi->host; } else { *username = c->digest.username.user; *domain = *(GET_REALM(&c->digest)); } return 0; }
/* * Check from AAA server if a user belongs to a group. User-Name is digest * username or digest username@realm, SIP-Group is group, and Service-Type * is Group-Check. SIP-Group is SER specific attribute and Group-Check is * SER specific service type value. */ int aaa_is_user_in(struct sip_msg* _m, char* _hf, char* _group) { str *grp, user_name, user, domain; dig_cred_t* cred = 0; int hf_type; uint32_t service; aaa_message *send = NULL, *received = NULL; struct hdr_field* h; struct sip_uri *turi; grp = (str*)_group; /* via fixup */ hf_type = (int)(long)_hf; turi = 0; switch(hf_type) { case 1: /* Request-URI */ if(parse_sip_msg_uri(_m)<0) { LM_ERR("failed to get Request-URI\n"); return -1; } turi = &_m->parsed_uri; break; case 2: /* To */ if((turi=parse_to_uri(_m))==NULL) { LM_ERR("failed to get To URI\n"); return -1; } break; case 3: /* From */ if((turi=parse_from_uri(_m))==NULL) { LM_ERR("failed to get From URI\n"); return -1; } break; case 4: /* Credentials */ get_authorized_cred(_m->authorization, &h); if (!h) { get_authorized_cred(_m->proxy_auth, &h); if (!h) { LM_ERR("no authorized" " credentials found (error in scripts)\n"); return -4; } } cred = &((auth_body_t*)(h->parsed))->digest; break; } if (hf_type != 4) { user = turi->user; domain = turi->host; } else { user = cred->username.user; domain = *GET_REALM(cred); } if (user.s == NULL || user.len == 0) { LM_DBG("no username part\n"); return -1; } if (use_domain) { user_name.len = user.len + domain.len + 1; user_name.s = (char*)pkg_malloc(user_name.len); if (!user_name.s) { LM_ERR("no pkg memory left\n"); return -6; } memcpy(user_name.s, user.s, user.len); user_name.s[user.len] = '@'; memcpy(user_name.s + user.len + 1, domain.s, domain.len); } else { user_name = user; } if ((send = proto.create_aaa_message(conn, AAA_AUTH)) == NULL) { LM_ERR("failed to create new aaa message for auth \n"); return -1; } if (proto.avp_add(conn, send, &attrs[A_USER_NAME], user_name.s, user_name.len, 0)) { proto.destroy_aaa_message(conn, send); if (use_domain) pkg_free(user_name.s); return -7; } if (use_domain) pkg_free(user_name.s); if (proto.avp_add(conn, send, &attrs[A_SIP_GROUP], grp->s, grp->len, 0)) { proto.destroy_aaa_message(conn, send); LM_ERR("failed to add Sip-Group attribute\n"); return -8; } service = vals[V_GROUP_CHECK].value; if (proto.avp_add(conn, send, &attrs[A_SERVICE_TYPE], &service, -1, 0)) { proto.destroy_aaa_message(conn, send); LM_ERR("failed to add Service-Type attribute\n"); return -8; } /* Add CALL-ID in Acct-Session-Id Attribute */ if ((parse_headers(_m, HDR_CALLID_F, 0) == -1 || _m->callid == NULL) && _m->callid == NULL) { proto.destroy_aaa_message(conn, send); LM_ERR("msg parsing failed or callid not present"); return -10; } if (proto.avp_add(conn, send, &attrs[A_ACCT_SESSION_ID], _m->callid->body.s, _m->callid->body.len, 0)) { proto.destroy_aaa_message(conn, send); LM_ERR("unable to add CALL-ID attribute\n"); return -11; } if (!proto.send_aaa_request(conn, send, &received)) { LM_DBG("Success\n"); proto.destroy_aaa_message(conn, send); proto.destroy_aaa_message(conn, received); return 1; } else { LM_DBG("Failure\n"); proto.destroy_aaa_message(conn, send); proto.destroy_aaa_message(conn, received); return -12; } }
static int w_handle_call(struct sip_msg *msg, char *flow_var) { struct cc_flow *flow; struct cc_call *call; str leg = {NULL,0}; str *dn; str val; int dec; int ret = -1; call = NULL; dec = 0; /* get the flow name */ if (fixup_get_svalue(msg, (gparam_p)flow_var, &val)!=0) { LM_ERR("failed to avaluate the flow name variable\n"); return -1; } /* parse FROM URI */ if (parse_from_uri(msg)==NULL) { LM_ERR("failed to parse from hdr\n"); return -2; } lock_get( data->lock ); /* get the flow ID */ flow = get_flow_by_name(data, &val); if (flow==NULL) { LM_ERR("flow <%.*s> does not exists\n", val.len, val.s); ret = -3; goto error; } LM_DBG("using call flow %p\n", flow); if (flow->logged_agents==0 /* no logged agents */ ) { LM_NOTICE("flow <%.*s> closed\n",flow->id.len,flow->id.s); ret = -4; goto error; } update_stat(stg_incalls, 1); update_stat(flow->st_incalls, 1); if (flow->cid.len) { dn = build_displayname(&flow->cid, get_from(msg)); } else if (get_from(msg)->display.len) { dn = &get_from(msg)->display; } else { dn = &get_from(msg)->parsed_uri.user; } LM_DBG("cid=<%.*s>\n",dn->len,dn->s); call = new_cc_call(data, flow, dn, &get_from(msg)->parsed_uri.user); if (call==NULL) { LM_ERR("failed to create new call\n"); ret = -5; goto error; } call->fst_flags |= FSTAT_INCALL; /* get estimated wait time */ call->eta = (unsigned int) (( flow->avg_call_duration * (float)get_stat_val(flow->st_queued_calls) ) / (float)flow->logged_agents); LM_DBG("avg_call_duration=%.2f queued_calls=%lu logedin_agents=%u\n", flow->avg_call_duration, get_stat_val(flow->st_queued_calls), flow->logged_agents); LM_DBG("ETA for new call(%p) is %d\n", call, call->eta); /* one more call to process */ flow->ongoing_calls++; /* there is no need to lock the call here as it is not * yet sharead at all - just we have a ref to it */ /* get the first state */ if (cc_call_state_machine( data, call, &leg )!=0) { LM_ERR("failed to get first call destination \n"); ret = -5; goto error; } lock_release( data->lock ); LM_DBG("new destination for call(%p) is %.*s (state=%d)\n", call, leg.len, leg.s, call->state); /* call still waits for agent ? */ if (call->state!=CC_CALL_TOAGENT) { LM_DBG("** onhold++ Not to agent [%p]\n", call); update_stat( stg_onhold_calls, +1); update_stat( flow->st_onhold_calls, +1); dec = 1; } /* send call to selected destination */ if (set_call_leg( msg, call, &leg)< 0 ) { LM_ERR("failed to set new destination for call\n"); if (dec) { LM_DBG("** onhold-- Error [%p]\n", call); update_stat( stg_onhold_calls, -1); update_stat( flow->st_onhold_calls, -1); } pkg_free(leg.s); goto error1; } pkg_free(leg.s); if(cc_db_insert_call(call) < 0) { LM_ERR("Failed to insert call record in db\n"); } return 1; error: lock_release( data->lock ); error1: if (call) { free_cc_call( data, call); flow->ongoing_calls--; } return ret; }
/* * Authenticate using WWW/Proxy-Authorize header field */ int auth_check(struct sip_msg* _m, char* _realm, char* _table, char *_flags) { str srealm; str stable; int iflags; int ret; hdr_field_t *hdr; sip_uri_t *uri = NULL; sip_uri_t *turi = NULL; sip_uri_t *furi = NULL; if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) { return AUTH_OK; } if(_m==NULL || _realm==NULL || _table==NULL || _flags==NULL) { LM_ERR("invalid parameters\n"); return AUTH_ERROR; } if (get_str_fparam(&srealm, _m, (fparam_t*)_realm) < 0) { LM_ERR("failed to get realm value\n"); return AUTH_ERROR; } if (srealm.len==0) { LM_ERR("invalid realm parameter - empty value\n"); return AUTH_ERROR; } if (get_str_fparam(&stable, _m, (fparam_t*)_table) < 0) { LM_ERR("failed to get realm value\n"); return AUTH_ERROR; } if (stable.len==0) { LM_ERR("invalid table parameter - empty value\n"); return AUTH_ERROR; } if(fixup_get_ivalue(_m, (gparam_p)_flags, &iflags)!=0) { LM_ERR("invalid flags parameter\n"); return -1; } LM_DBG("realm [%.*s] table [%.*s] flags [%d]\n", srealm.len, srealm.s, stable.len, stable.s, iflags); hdr = NULL; if(_m->REQ_METHOD==METHOD_REGISTER) ret = digest_authenticate_hdr(_m, &srealm, &stable, HDR_AUTHORIZATION_T, &_m->first_line.u.request.method, &hdr); else ret = digest_authenticate_hdr(_m, &srealm, &stable, HDR_PROXYAUTH_T, &_m->first_line.u.request.method, &hdr); if(ret==AUTH_OK && hdr!=NULL && (iflags&AUTH_CHECK_ID_F)) { srealm = ((auth_body_t*)(hdr->parsed))->digest.username.user; if((furi=parse_from_uri(_m))==NULL) return AUTH_ERROR; if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) { if((turi=parse_to_uri(_m))==NULL) return AUTH_ERROR; uri = turi; } else { uri = furi; } if(srealm.len!=uri->user.len || strncmp(srealm.s, uri->user.s, srealm.len)!=0) return AUTH_USER_MISMATCH; if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) { /* check from==to */ if(furi->user.len!=turi->user.len || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) return AUTH_USER_MISMATCH; if(use_domain!=0 && (furi->host.len!=turi->host.len || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) return AUTH_USER_MISMATCH; /* check r-uri==from for publish */ if(_m->REQ_METHOD==METHOD_PUBLISH) { if(parse_sip_msg_uri(_m)<0) return AUTH_ERROR; uri = &_m->parsed_uri; if(furi->user.len!=uri->user.len || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) return AUTH_USER_MISMATCH; if(use_domain!=0 && (furi->host.len!=uri->host.len || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) return AUTH_USER_MISMATCH; } } return AUTH_OK; } return ret; }
/* mkfs.lhfs -l http://<path> -s name */ int main(int argc, char *argv[]) { if (log4c_init()) { g_message("log4c_init failed!"); } GError *error = NULL; GOptionContext *context; context = g_option_context_new("- mkfs hlfs"); g_option_context_add_main_entries(context, entries, NULL); g_option_context_set_help_enabled(context, TRUE); g_option_group_set_error_hook(g_option_context_get_main_group(context), (GOptionErrorFunc)error_func); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_message("option parsing failed: %s", error->message); exit(EXIT_FAILURE); } //g_print("location is :%s\n",location); //g_print("fsname is :%s\n",fsname); //g_print("block size is :%d\n",block_size); //g_print("segment size is :%d\n",seg_size); // seg_size = SEGMENT_SIZE; if(seg_size <= 0 || seg_size%(1024*1024)!=0){ g_message("segsize <=0 or segment size must 1M margin"); return -1; } if(block_size <=0 || block_size%(512) != 0){ g_message("blocksize <=0 or block size must 512 margin"); return -1; } if(max_fs_size <=0){ g_message("max fs size <=0"); return -1; } struct back_storage *storage = init_storage_handler(uri); if(NULL ==storage){ g_message("can not get storage handler for uri:%s",uri); g_option_context_free(context); return -1; } if((0==storage->bs_file_is_exist(storage,NULL)) && (0==storage->bs_file_is_exist(storage,"superblock"))){ g_message("hlfs with uri:%s has exist",uri); g_option_context_free(context); return 1; } if( 0!=storage->bs_file_mkdir(storage,NULL)){ g_message("can not mkdir for our fs %s",uri); g_option_context_free(context); return -1; } GKeyFile *sb_keyfile= g_key_file_new(); g_key_file_set_string(sb_keyfile,"METADATA","uri",uri); g_key_file_set_integer(sb_keyfile,"METADATA","block_size",block_size); g_key_file_set_integer(sb_keyfile,"METADATA","segment_size",seg_size); g_key_file_set_uint64(sb_keyfile,"METADATA","max_fs_size",max_fs_size); gchar *data = g_key_file_to_data(sb_keyfile,NULL,NULL); g_message("key file data :%s",data); char *head,*hostname,*dir,*fs_name; int port; parse_from_uri(uri,&head,&hostname,&dir,&fs_name,&port); char *sb_file_path = g_build_filename(dir,fs_name,"superblock",NULL); g_message("sb file path %s",sb_file_path); bs_file_t file = storage->bs_file_create(storage,"superblock"); g_message("sb file path 1%s",sb_file_path); //bs_file_t file = storage->bs_file_open(storage,"superblock",BS_WRITEABLE); if (NULL == file) { g_message("open file :superblock failed"); g_free(sb_file_path); g_option_context_free(context); return -1; } g_message("sb file path 2%s",sb_file_path); int size = storage->bs_file_append(storage, file,(char*)data,strlen(data)+1); if(size != strlen(data)+1){ g_message("can not write superblock file"); g_free(sb_file_path); g_option_context_free(context); return -1; } g_message("append size:%d",size); storage->bs_file_flush(storage,file); storage->bs_file_close(storage,file); deinit_storage_handler(storage); if (log4c_fini()) { g_message("log4c_fini failed!"); } return 0; }
static int pv_auth_check(sip_msg_t *msg, char *realm, char *passwd, char *flags, char *checks) { int vflags = 0; int vchecks = 0; str srealm = {0, 0}; str spasswd = {0, 0}; int ret; hdr_field_t *hdr; sip_uri_t *uri = NULL; sip_uri_t *turi = NULL; sip_uri_t *furi = NULL; if(msg==NULL) { LM_ERR("invalid msg parameter\n"); return AUTH_ERROR; } if ((msg->REQ_METHOD == METHOD_ACK) || (msg->REQ_METHOD == METHOD_CANCEL)) { return AUTH_OK; } if(realm==NULL || passwd==NULL || flags==NULL || checks==NULL) { LM_ERR("invalid parameters\n"); return AUTH_ERROR; } if (get_str_fparam(&srealm, msg, (fparam_t*)realm) < 0) { LM_ERR("failed to get realm value\n"); return AUTH_ERROR; } if(srealm.len==0) { LM_ERR("invalid realm value - empty content\n"); return AUTH_ERROR; } if (get_str_fparam(&spasswd, msg, (fparam_t*)passwd) < 0) { LM_ERR("failed to get passwd value\n"); return AUTH_ERROR; } if(spasswd.len==0) { LM_ERR("invalid password value - empty content\n"); return AUTH_ERROR; } if (get_int_fparam(&vflags, msg, (fparam_t*)flags) < 0) { LM_ERR("invalid flags value\n"); return AUTH_ERROR; } if (get_int_fparam(&vchecks, msg, (fparam_t*)checks) < 0) { LM_ERR("invalid checks value\n"); return AUTH_ERROR; } LM_DBG("realm [%.*s] flags [%d] checks [%d]\n", srealm.len, srealm.s, vflags, vchecks); if(msg->REQ_METHOD==METHOD_REGISTER) ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_AUTHORIZATION_T, &msg->first_line.u.request.method); else ret = pv_authenticate(msg, &srealm, &spasswd, vflags, HDR_PROXYAUTH_T, &msg->first_line.u.request.method); if(ret==AUTH_OK && (vchecks&AUTH_CHECK_ID_F)) { hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth; srealm = ((auth_body_t*)(hdr->parsed))->digest.username.user; if((furi=parse_from_uri(msg))==NULL) return AUTH_ERROR; if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) { if((turi=parse_to_uri(msg))==NULL) return AUTH_ERROR; uri = turi; } else { uri = furi; } if(srealm.len!=uri->user.len || strncmp(srealm.s, uri->user.s, srealm.len)!=0) return AUTH_USER_MISMATCH; if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) { /* check from==to */ if(furi->user.len!=turi->user.len || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) return AUTH_USER_MISMATCH; if(auth_use_domain!=0 && (furi->host.len!=turi->host.len || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) return AUTH_USER_MISMATCH; /* check r-uri==from for publish */ if(msg->REQ_METHOD==METHOD_PUBLISH) { if(parse_sip_msg_uri(msg)<0) return AUTH_ERROR; uri = &msg->parsed_uri; if(furi->user.len!=uri->user.len || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) return AUTH_USER_MISMATCH; if(auth_use_domain!=0 && (furi->host.len!=uri->host.len || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) return AUTH_USER_MISMATCH; } } return AUTH_OK; } return ret; }
int sd_lookup(struct sip_msg* _msg, char* _table, char* _owner) { str user_s, table_s, uri_s; int nr_keys; struct sip_uri *puri; struct sip_uri turi; db_key_t db_keys[4]; db_val_t db_vals[4]; db_key_t db_cols[1]; db1_res_t* db_res = NULL; if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) { LM_ERR("invalid table parameter"); return -1; } /* init */ nr_keys = 0; db_cols[0]=&new_uri_column; if(_owner) { memset(&turi, 0, sizeof(struct sip_uri)); if(fixup_get_svalue(_msg, (gparam_p)_owner, &uri_s)!=0) { LM_ERR("invalid owner uri parameter"); return -1; } if(parse_uri(uri_s.s, uri_s.len, &turi)!=0) { LM_ERR("bad owner SIP address!\n"); goto err_server; } LM_DBG("using user id [%.*s]\n", uri_s.len, uri_s.s); puri = &turi; } else { /* take username@domain from From header */ if ( (puri = parse_from_uri(_msg ))==NULL ) { LM_ERR("failed to parse FROM header\n"); goto err_server; } } db_keys[nr_keys]=&user_column; db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = puri->user.s; db_vals[nr_keys].val.str_val.len = puri->user.len; nr_keys++; if(use_domain>=1) { db_keys[nr_keys]=&domain_column; db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = puri->host.s; db_vals[nr_keys].val.str_val.len = puri->host.len; nr_keys++; if (dstrip_s.s!=NULL && dstrip_s.len>0 && dstrip_s.len<puri->host.len && strncasecmp(puri->host.s,dstrip_s.s,dstrip_s.len)==0) { db_vals[nr_keys].val.str_val.s += dstrip_s.len; db_vals[nr_keys].val.str_val.len -= dstrip_s.len; } } /* take sd from r-uri */ if (parse_sip_msg_uri(_msg) < 0) { LM_ERR("failed to parsing Request-URI\n"); goto err_server; } db_keys[nr_keys]=&sd_user_column; db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.user.s; db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.user.len; nr_keys++; if(use_domain>=2) { db_keys[nr_keys]=&sd_domain_column; db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.host.s; db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.host.len; nr_keys++; if (dstrip_s.s!=NULL && dstrip_s.len>0 && dstrip_s.len<_msg->parsed_uri.host.len && strncasecmp(_msg->parsed_uri.host.s,dstrip_s.s,dstrip_s.len)==0) { db_vals[nr_keys].val.str_val.s += dstrip_s.len; db_vals[nr_keys].val.str_val.len -= dstrip_s.len; } } db_funcs.use_table(db_handle, &table_s); if(db_funcs.query(db_handle, db_keys, NULL, db_vals, db_cols, nr_keys /*no keys*/, 1 /*no cols*/, NULL, &db_res)!=0) { LM_ERR("failed to query database\n"); goto err_server; } if (RES_ROW_N(db_res)<=0 || RES_ROWS(db_res)[0].values[0].nul != 0) { LM_DBG("no sip addres found for R-URI\n"); if (db_res!=NULL && db_funcs.free_result(db_handle, db_res) < 0) LM_DBG("failed to free result of query\n"); return -1; } user_s.s = useruri_buf+4; switch(RES_ROWS(db_res)[0].values[0].type) { case DB1_STRING: strcpy(user_s.s, (char*)RES_ROWS(db_res)[0].values[0].val.string_val); user_s.len = strlen(user_s.s); break; case DB1_STR: strncpy(user_s.s, (char*)RES_ROWS(db_res)[0].values[0].val.str_val.s, RES_ROWS(db_res)[0].values[0].val.str_val.len); user_s.len = RES_ROWS(db_res)[0].values[0].val.str_val.len; user_s.s[user_s.len] = '\0'; break; case DB1_BLOB: strncpy(user_s.s, (char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s, RES_ROWS(db_res)[0].values[0].val.blob_val.len); user_s.len = RES_ROWS(db_res)[0].values[0].val.blob_val.len; user_s.s[user_s.len] = '\0'; default: LM_ERR("unknown type of DB new_uri column\n"); if (db_res != NULL && db_funcs.free_result(db_handle, db_res) < 0) { LM_DBG("failed to free result of query\n"); } goto err_server; } /* check 'sip:' */ if(user_s.len<4 || strncmp(user_s.s, "sip:", 4)) { memcpy(useruri_buf, "sip:", 4); user_s.s -= 4; user_s.len += 4; } /** * Free the result because we don't need it anymore */ if (db_res!=NULL && db_funcs.free_result(db_handle, db_res) < 0) LM_DBG("failed to free result of query\n"); /* set the URI */ LM_DBG("URI of sd from R-URI [%s]\n", user_s.s); if(rewrite_ruri(_msg, user_s.s)<0) { LM_ERR("failed to replace the R-URI\n"); goto err_server; } return 1; err_server: return -1; }
/* build some Uri to use in SUBSCRIBER request */ int get_uris_to_subscribe(struct sip_msg* msg, str* contact, str* notifier, str* subscriber ){ struct sip_uri *furi; int size_contact; int size_notifier; int size_subscriber; char *contact_aux; char *notifier_aux; char *subscriber_aux; int vsp_addr_len; char *vsp_addr = "@vsp.com"; int rp_addr_len; char *rp_addr = "@rp.com"; /* build contact uri to use in To header */ if ((furi = parse_from_uri(msg)) == NULL) { LM_ERR("****** ERROR PARSE FROM \n"); return 0; } size_contact= furi->user.len + furi->host.len + furi->port.len + 6; contact_aux = pkg_malloc (sizeof (char)* size_contact + 1); if (contact_aux == NULL) { LM_ERR("--------------------------------------------------no more pkg memory\n"); return 0; } memset(contact_aux, 0, size_contact + 1); contact->s = contact_aux; contact->len = size_contact; memcpy(contact_aux, "sip:", 4); contact_aux += 4; memcpy(contact_aux, furi->user.s, furi->user.len); contact_aux += furi->user.len; *contact_aux = '@'; contact_aux++; memcpy(contact_aux, furi->host.s, furi->host.len); contact_aux += furi->host.len; *contact_aux = ':'; contact_aux++; memcpy(contact_aux, furi->port.s, furi->port.len); LM_DBG("****** contact: %.*s\n", contact->len, contact->s); /* build notifier uri to use in R-URI */ if ((parse_sip_msg_uri(msg) < 0) || (!msg->parsed_uri.user.s) || (msg->parsed_uri.user.len > MAXNUMBERLEN)) { LM_ERR("cannot parse msg URI\n"); pkg_free(contact_aux); return 0; } // get source ip address that send INVITE vsp_addr = ip_addr2a(&msg->rcv.src_ip); vsp_addr_len = strlen(vsp_addr); size_notifier = vsp_addr_len + msg->parsed_uri.user.len + 5; notifier_aux = pkg_malloc(size_notifier + 1); if (notifier_aux == NULL) { LM_ERR("--------------------------------------------------no more pkg memory\n"); return 0; } memset(notifier_aux, 0, size_notifier + 1); notifier->s = notifier_aux; notifier->len = size_notifier; memcpy(notifier_aux, "sip:", 4); notifier_aux += 4; memcpy(notifier_aux, msg->parsed_uri.user.s, msg->parsed_uri.user.len); notifier_aux += msg->parsed_uri.user.len; *notifier_aux = '@'; notifier_aux++; memcpy(notifier_aux, vsp_addr, vsp_addr_len); LM_DBG("****** notifier: %.*s\n", notifier->len, notifier->s); /* build subscriber uri to use in From header */ // get ip address of opensips server in port that receive INVITE if (get_ip_socket(msg, &rp_addr) == -1){ pkg_free(contact_aux); pkg_free(notifier_aux); return 0; } rp_addr_len = strlen(rp_addr); size_subscriber = rp_addr_len + 21; subscriber_aux = pkg_malloc(size_subscriber + 1); if (subscriber_aux == NULL) { LM_ERR("--------------------------------------------------no more pkg memory\n"); return 0; } memset(subscriber_aux, 0, size_subscriber + 1); subscriber->s = subscriber_aux; subscriber->len = size_subscriber; memcpy(subscriber_aux, "sip:opensips_redirect", 21); subscriber_aux += 21; memcpy(subscriber_aux, rp_addr, rp_addr_len); LM_DBG("****** subscriber: %.*s\n", subscriber->len, subscriber->s); return 1; }
int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2) { struct to_body *pto, *pfrom = NULL; subs_t subs; pres_ev_t* event= NULL; str* contact= NULL; xmlDocPtr doc= NULL; xmlNodePtr service_node= NULL; unsigned int hash_code= 0; event_t* parsed_event; param_t* ev_param= NULL; int init_req; int reply_code; str reply_str; /*** filter: 'For me or for presence server?' */ reply_code = 400; reply_str = pu_400_rpl; memset(&subs, 0, sizeof(subs_t)); if ( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); goto error; } /* check for Support: eventlist header */ if(!msg->supported) { LM_DBG("no supported header found\n"); return to_presence_code; } if(parse_supported(msg) < 0) { LM_ERR("failed to parse supported headers\n"); reply_code = 500; reply_str = pu_500_rpl; goto error; } if(!(get_supported(msg) & F_SUPPORTED_EVENTLIST)) { LM_DBG("No 'Support: eventlist' header found\n"); return to_presence_code; } /* inspecting the Event header field */ if(msg->event && msg->event->body.len > 0) { if (!msg->event->parsed && (parse_event(msg->event) < 0)) { LM_ERR("cannot parse Event header\n"); reply_code = 500; reply_str = pu_500_rpl; goto error; } if(! ( ((event_t*)msg->event->parsed)->parsed & rls_events) ) { return to_presence_code; } } else { goto bad_event; } /* search event in the list */ parsed_event= (event_t*)msg->event->parsed; event= pres_search_event(parsed_event); if(event== NULL) { goto bad_event; } subs.event= event; /* extract the id if any*/ ev_param= parsed_event->params; while(ev_param) { if(ev_param->name.len== 2 && strncasecmp(ev_param->name.s, "id", 2)== 0) { subs.event_id= ev_param->body; break; } ev_param= ev_param->next; } pto = get_to(msg); if (pto == NULL || pto->error != PARSE_OK) { LM_ERR("parsing 'To' header failed\n"); goto error; } if(parse_from_uri(msg)<0) { LM_ERR("failed to parse From header\n"); goto error; } pfrom = (struct to_body*)msg->from->parsed; if(pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0) { LM_ERR("no from tag value present\n"); goto error; } /* verify if the presentity URI is a resource list */ if(pto->tag_value.s== NULL || pto->tag_value.len==0) /* if an initial Subscribe */ { struct sip_uri fu = ((struct to_body*)msg->from->parsed)->parsed_uri; if( parse_sip_msg_uri(msg)< 0) { LM_ERR("parsing Request URI failed\n"); goto error; } /*verify if Request URI represents a list by asking xcap server*/ if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host, &subs.pres_uri)< 0) { LM_ERR("while constructing uri from user and domain\n"); reply_code = 500; reply_str = pu_500_rpl; goto error; } if( get_resource_list(&subs.pres_uri, fu.user, fu.host, &service_node, &doc) < 0) { LM_ERR("failed to get resource list document\n"); reply_code = 500; reply_str = pu_500_rpl; goto error; } if(doc== NULL|| service_node==NULL) { LM_DBG("list not found - search for uri = %.*s\n",subs.pres_uri.len, subs.pres_uri.s); pkg_free(subs.pres_uri.s); return to_presence_code; } } else /* if request inside a dialog */ { if( msg->callid==NULL || msg->callid->body.s==NULL) { LM_ERR("cannot parse callid header\n"); goto error; } /* search if a stored dialog */ hash_code= core_hash(&msg->callid->body, &pto->tag_value, hash_size); lock_get(&rls_table[hash_code].lock); if(pres_search_shtable(rls_table,msg->callid->body, pto->tag_value, pfrom->tag_value, hash_code)== NULL) { lock_release(&rls_table[hash_code].lock); /* reply with Call/Transaction Does Not Exist */ LM_DBG("No dialog match found\n"); return to_presence_code; } lock_release(&rls_table[hash_code].lock); } /* extract dialog information from message headers */ if(pres_extract_sdialog_info(&subs, msg, rls_max_expires, &init_req, server_address)< 0) { LM_ERR("bad Subscribe request\n"); goto error; } reply_code = 500; reply_str = pu_500_rpl; if(init_req) /* if an initial subscribe */ { /** reply with 200 OK*/ if(reply_200(msg, &subs.local_contact, subs.expires, &subs.to_tag)< 0) goto error_free; hash_code= core_hash(&subs.callid, &subs.to_tag, hash_size); subs.local_cseq= 0; if(subs.expires!= 0) { subs.version= 1; if(pres_insert_shtable(rls_table, hash_code, &subs)< 0) { LM_ERR("while adding new subscription\n"); goto error_free; } } } else { if(update_rlsubs(&subs, hash_code, &reply_code, &reply_str) < 0) { LM_ERR("while updating resource list subscription\n"); goto error; } if(get_resource_list(&subs.pres_uri, subs.from_user, subs.from_domain, &service_node, &doc)< 0) { LM_ERR("when getting resource list\n"); goto error; } if(doc== NULL || service_node== NULL) { LM_DBG("list not found( in-dialog request)- search for uri = %.*s\n", subs.pres_uri.len, subs.pres_uri.s); reply_code = 404; reply_str = pu_404_rpl; goto error; } /** reply with 200 OK*/ if(reply_200(msg, &subs.local_contact, subs.expires, 0)< 0) goto error_free; } /*** send Subscribe requests for all in the list */ /* call sending Notify with full state */ if(send_full_notify(&subs, service_node, subs.version, &subs.pres_uri,hash_code)< 0) { LM_ERR("while sending full state Notify\n"); goto error_free; } if(resource_subscriptions(&subs, service_node)< 0) { LM_ERR("while sending Subscribe requests to resources in a list\n"); goto error_free; } if(contact) { if(contact->s) pkg_free(contact->s); pkg_free(contact); } pkg_free(subs.pres_uri.s); if(subs.record_route.s) pkg_free(subs.record_route.s); xmlFreeDoc(doc); return 1; bad_event: if(reply_489(msg)< 0) LM_ERR("failed to send 489 reply\n"); goto error_free; error: if (rls_sigb.reply(msg, reply_code, &reply_str, 0) == -1) { LM_ERR("failed to send 400 reply\n"); return -1; } error_free: if(contact) { if(contact->s) pkg_free(contact->s); pkg_free(contact); } if(subs.pres_uri.s) pkg_free(subs.pres_uri.s); if(subs.record_route.s) pkg_free(subs.record_route.s); if(doc) xmlFreeDoc(doc); return -1; }
/*! * \brief Extract the username and domain from the SIP message * * Set the username and domain depending on the value of the SIP * message and the group check structure. * \param msg SIP message * \param gcp group check structure * \param username stored username * \param domain stored domain * \return 0 on success, -1 on failure */ int get_username_domain(struct sip_msg *msg, group_check_p gcp, str *username, str *domain) { struct sip_uri puri; struct sip_uri *turi; struct hdr_field* h; struct auth_body* c = 0; pv_value_t value; turi = NULL; switch(gcp->id) { case 1: /* Request-URI */ if(parse_sip_msg_uri(msg)<0) { LM_ERR("failed to get Request-URI\n"); return -1; } turi = &msg->parsed_uri; break; case 2: /* To */ if((turi=parse_to_uri(msg))==NULL) { LM_ERR("failed to get To URI\n"); return -1; } break; case 3: /* From */ if((turi=parse_from_uri(msg))==NULL) { LM_ERR("failed to get From URI\n"); return -1; } break; case 4: /* Credentials */ get_authorized_cred( msg->authorization, &h); if (!h) { get_authorized_cred( msg->proxy_auth, &h); if (!h) { LM_ERR("no authorized credentials found " "(error in scripts)\n"); return -1; } } c = (auth_body_t*)(h->parsed); break; case 5: /* AVP spec */ if(pv_get_spec_value( msg, &gcp->sp, &value)!=0 || value.flags&PV_VAL_NULL || value.rs.len<=0) { LM_ERR("no AVP found (error in scripts)\n"); return -1; } if (parse_uri(value.rs.s, value.rs.len, &puri) < 0) { LM_ERR("failed to parse URI <%.*s>\n",value.rs.len, value.rs.s); return -1; } turi = &puri; break; default: { LM_ERR("incorrect check id %d\n", gcp->id); return -1; } } if (gcp->id != 4) { *username = turi->user; *domain = turi->host; } else { *username = c->digest.username.user; *domain = *(GET_REALM(&c->digest)); } return 0; }
int auth_check(sip_msg_t *_m, str *srealm, str *stable, int iflags) { int ret; hdr_field_t *hdr; sip_uri_t *uri = NULL; sip_uri_t *turi = NULL; sip_uri_t *furi = NULL; str suser; if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) { return AUTH_OK; } if (srealm->len<=0) { LM_ERR("invalid realm parameter - empty value\n"); return AUTH_ERROR; } if (stable->len==0) { LM_ERR("invalid table parameter - empty value\n"); return AUTH_ERROR; } LM_DBG("realm [%.*s] table [%.*s] flags [%d]\n", srealm->len, srealm->s, stable->len, stable->s, iflags); hdr = NULL; if(_m->REQ_METHOD==METHOD_REGISTER) ret = digest_authenticate_hdr(_m, srealm, stable, HDR_AUTHORIZATION_T, &_m->first_line.u.request.method, &hdr); else ret = digest_authenticate_hdr(_m, srealm, stable, HDR_PROXYAUTH_T, &_m->first_line.u.request.method, &hdr); if(ret==AUTH_OK && hdr!=NULL && (iflags&AUTH_CHECK_ID_F)) { suser = ((auth_body_t*)(hdr->parsed))->digest.username.user; if((furi=parse_from_uri(_m))==NULL) return AUTH_ERROR; if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) { if((turi=parse_to_uri(_m))==NULL) return AUTH_ERROR; uri = turi; } else { uri = furi; } if(!((iflags&AUTH_CHECK_SKIPFWD_F) && (_m->REQ_METHOD==METHOD_INVITE || _m->REQ_METHOD==METHOD_BYE || _m->REQ_METHOD==METHOD_PRACK || _m->REQ_METHOD==METHOD_UPDATE || _m->REQ_METHOD==METHOD_MESSAGE))) { if(suser.len!=uri->user.len || strncmp(suser.s, uri->user.s, suser.len)!=0) { LM_DBG("authentication username mismatch with from/to username\n"); return AUTH_USER_MISMATCH; } } if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) { /* check from==to */ if(furi->user.len!=turi->user.len || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) { LM_DBG("from username mismatch with to username\n"); return AUTH_USER_MISMATCH; } if(use_domain!=0 && (furi->host.len!=turi->host.len || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) { LM_DBG("from domain mismatch with to domain\n"); return AUTH_USER_MISMATCH; } /* check r-uri==from for publish */ if(_m->REQ_METHOD==METHOD_PUBLISH) { if(parse_sip_msg_uri(_m)<0) return AUTH_ERROR; uri = &_m->parsed_uri; if(furi->user.len!=uri->user.len || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) { LM_DBG("from username mismatch with r-uri username\n"); return AUTH_USER_MISMATCH; } if(use_domain!=0 && (furi->host.len!=uri->host.len || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) { LM_DBG("from domain mismatch with r-uri domain\n"); return AUTH_USER_MISMATCH; } } } return AUTH_OK; } return ret; }
/* * Check if from user is a valid enum based user, and check to make sure * that the src_ip == an srv record that maps to the enum from user. */ int is_from_user_enum_2(struct sip_msg* _msg, char* _suffix, char* _service) { struct ip_addr addr; struct hostent* he; unsigned short zp; unsigned short proto; char *user_s; int user_len, i, j; char name[MAX_DOMAIN_SIZE]; char uri[MAX_URI_SIZE]; struct sip_uri *furi; struct sip_uri luri; struct rdata* head; str* suffix; str* service; struct rdata* l; struct naptr_rdata* naptr; str pattern, replacement, result; char string[17]; if (parse_from_header(_msg) < 0) { LM_ERR("Failed to parse From header\n"); return -1; } if(_msg->from==NULL || get_from(_msg)==NULL) { LM_DBG("No From header\n"); return -1; } if ((furi = parse_from_uri(_msg)) == NULL) { LM_ERR("Failed to parse From URI\n"); return -1; } suffix = (str*)_suffix; service = (str*)_service; if (is_e164(&(furi->user)) == -1) { LM_ERR("From URI user is not an E164 number\n"); return -1; } /* assert: the from user is a valid formatted e164 string */ user_s = furi->user.s; user_len = furi->user.len; j = 0; for (i = user_len - 1; i > 0; i--) { name[j] = user_s[i]; name[j + 1] = '.'; j = j + 2; } memcpy(name + j, suffix->s, suffix->len + 1); head = get_record(name, T_NAPTR); if (head == 0) { LM_DBG("No NAPTR record found for %s.\n", name); return -3; } /* we have the naptr records, loop and find an srv record with */ /* same ip address as source ip address, if we do then true is returned */ for (l = head; l; l = l->next) { if (l->type != T_NAPTR) continue; /*should never happen*/ naptr = (struct naptr_rdata*)l->rdata; if (naptr == 0) { LM_ERR("Null rdata in DNS response\n"); free_rdata_list(head); return -4; } LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags " "'%.*s', slen %u, services '%.*s', rlen %u, " "regexp '%.*s'\n", name, naptr->order, naptr->pref, naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), naptr->services_len, (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, (int)(naptr->regexp_len), ZSW(naptr->regexp)); if (sip_match(naptr, service) != 0) { if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, &pattern, &replacement) < 0) { free_rdata_list(head); /*clean up*/ LM_ERR("Parsing of NAPTR regexp failed\n"); return -5; } #ifdef LATER if ((pattern.len == 4) && (strncmp(pattern.s, "^.*$", 4) == 0)) { LM_DBG("Resulted in replacement: '%.*s'\n", replacement.len, ZSW(replacement.s)); retval = set_uri(_msg, replacement.s, replacement.len); free_rdata_list(head); /*clean up*/ return retval; } #endif result.s = &(uri[0]); result.len = MAX_URI_SIZE; /* Avoid making copies of pattern and replacement */ pattern.s[pattern.len] = (char)0; replacement.s[replacement.len] = (char)0; /* We have already checked the size of _msg->parsed_uri.user.s */ memcpy(&(string[0]), user_s, user_len); string[user_len] = (char)0; if (reg_replace(pattern.s, replacement.s, &(string[0]), &result) < 0) { pattern.s[pattern.len] = '!'; replacement.s[replacement.len] = '!'; LM_ERR("Regexp replace failed\n"); free_rdata_list(head); /*clean up*/ return -6; } LM_DBG("Resulted in replacement: '%.*s'\n", result.len, ZSW(result.s)); if(parse_uri(result.s, result.len, &luri) < 0) { LM_ERR("Parsing of URI <%.*s> failed\n", result.len, result.s); free_rdata_list(head); /*clean up*/ return -7; } pattern.s[pattern.len] = '!'; replacement.s[replacement.len] = '!'; zp = 0; proto = PROTO_NONE; he = sip_resolvehost(&luri.host, &zp, &proto, (luri.type==SIPS_URI_T)?1:0 , 0); hostent2ip_addr(&addr, he, 0); if(ip_addr_cmp(&addr, &_msg->rcv.src_ip)) { free_rdata_list(head); return(1); } } } free_rdata_list(head); /*clean up*/ LM_DBG("FAIL\n"); /* must not have found the record */ return(-8); }
static int pv_auth_check(sip_msg_t *msg, str *srealm, str *spasswd, int vflags, int vchecks) { int ret; hdr_field_t *hdr; sip_uri_t *uri = NULL; sip_uri_t *turi = NULL; sip_uri_t *furi = NULL; str suser; if(msg->REQ_METHOD==METHOD_REGISTER) ret = pv_authenticate(msg, srealm, spasswd, vflags, HDR_AUTHORIZATION_T, &msg->first_line.u.request.method); else ret = pv_authenticate(msg, srealm, spasswd, vflags, HDR_PROXYAUTH_T, &msg->first_line.u.request.method); if(ret==AUTH_OK && (vchecks&AUTH_CHECK_ID_F)) { hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth; suser = ((auth_body_t*)(hdr->parsed))->digest.username.user; if((furi=parse_from_uri(msg))==NULL) return AUTH_ERROR; if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) { if((turi=parse_to_uri(msg))==NULL) return AUTH_ERROR; uri = turi; } else { uri = furi; } if(suser.len!=uri->user.len || strncmp(suser.s, uri->user.s, suser.len)!=0) return AUTH_USER_MISMATCH; if(msg->REQ_METHOD==METHOD_REGISTER || msg->REQ_METHOD==METHOD_PUBLISH) { /* check from==to */ if(furi->user.len!=turi->user.len || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) return AUTH_USER_MISMATCH; if(auth_use_domain!=0 && (furi->host.len!=turi->host.len || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) return AUTH_USER_MISMATCH; /* check r-uri==from for publish */ if(msg->REQ_METHOD==METHOD_PUBLISH) { if(parse_sip_msg_uri(msg)<0) return AUTH_ERROR; uri = &msg->parsed_uri; if(furi->user.len!=uri->user.len || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) return AUTH_USER_MISMATCH; if(auth_use_domain!=0 && (furi->host.len!=uri->host.len || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) return AUTH_USER_MISMATCH; } } return AUTH_OK; } return ret; }