Пример #1
0
static int l_siplua_pseudoVar(lua_State *L)
{
  struct sipapi_object *o;
  const char *name;
  str s;
  pv_elem_t *model;
  int buf_size = 4096;
  char *out;

  o = luaL_checkudata(L, 1, "siplua.api");
  name = luaL_checkstring(L, 2);
  s.s = (char *)name;
  s.len = strlen(name);
  if (pv_parse_format(&s, &model) < 0)
    {
      lua_pushnil(L);
      return 1;
    }
  out = pkg_malloc(buf_size);
  if (!out)
    {
      pv_elem_free_all(model);
      return luaL_error(L, "Not enough memory");
    }
  if (pv_printf(o->msg, model, out, &buf_size) < 0)
    lua_pushnil(L);
  else
    lua_pushstring(L, out);
  pkg_free(out);
  pv_elem_free_all(model);
  return 1;
}
Пример #2
0
/**
 * Compile a string with pseudo variables substituted by their values.
 * A string buffer is allocated. Deallocate afterwards!
 */
char *pv_sprintf(struct sip_msg *m, char *fmt) {
	int buf_size = 4096;
	pv_elem_t *model;
	str s;
	char *out = (char *)pkg_malloc(buf_size);
	char *ret = NULL;

	if (!out) {
		LM_ERR("pv_sprintf: Memory exhausted!\n");
		return NULL;
	}

	s.s = fmt; s.len = strlen(s.s);
	if(pv_parse_format(&s, &model) < 0) {
		LM_ERR("pv_sprintf: ERROR: wrong format[%s]!\n",
			fmt);
		return NULL;
	}

	if(pv_printf(m, model, out, &buf_size) < 0) {
		ret = NULL;
	} else {
		ret = strdup(out);
	}

	pv_elem_free_all(model);
	pkg_free(out);

	return ret;
}
Пример #3
0
static void destroy(void)
{
	if (auth_db_handle) {
		auth_dbf.close(auth_db_handle);
		auth_db_handle = 0;
	}
	if (credentials) {
		pv_elem_free_all(credentials);
		credentials = 0;
		credentials_n = 0;
	}
}
Пример #4
0
/** fparam_t free function.
 *  Frees the "content" of a fparam, but not the fparam itself.
 *  Note: it doesn't free fp->orig!
 *  Assumes pkg_malloc'ed content.
 *  @param fp -  fparam to be freed
 *
 */
void fparam_free_contents(fparam_t* fp)
{

	if (fp==0)
		return;
	switch(fp->type) {
		case FPARAM_UNSPEC:
		case FPARAM_STRING: /* asciiz string, not str */
		case FPARAM_INT:
		case FPARAM_STR:
			/* nothing to do */
			break;
		case FPARAM_REGEX:
			if (fp->v.regex){
				regfree(fp->v.regex);
				pkg_free(fp->v.regex);
				fp->v.regex=0;
			}
			break;
		case FPARAM_AVP:
			free_avp_name(&fp->v.avp.flags, &fp->v.avp.name);
			break;
		case FPARAM_SELECT:
			if (fp->v.select){
				free_select(fp->v.select);
				fp->v.select=0;
			}
			break;
		case FPARAM_SUBST:
			if (fp->v.subst){
				subst_expr_free(fp->v.subst);
				fp->v.subst=0;
			}
			break;
		case FPARAM_PVS:
			if (fp->v.pvs){
				pv_spec_free(fp->v.pvs);
				fp->v.pvs=0;
			}
			break;
		case FPARAM_PVE:
			if (fp->v.pve){
				pv_elem_free_all(fp->v.pve);
				fp->v.pve=0;
			}
			break;
	}
}
Пример #5
0
/*
 * Parse extra credentials list
 */
int parse_aaa_pvs(char *definition, pv_elem_t **pv_def, int *cnt)
{
	pv_elem_t *pve;
	str pv;
	char *p;
	char *end;
	char *sep;

	p = definition;
	if (p==0 || *p==0)
		return 0;

	*pv_def = 0;
	*cnt = 0;

	/* get element by element */
	while ( (end=strchr(p,';'))!=0 || (end=p+strlen(p))!=p ) {
		/* new pv_elem_t */
		if ( (pve=(pv_elem_t*)pkg_malloc(sizeof(pv_elem_t)))==0 ) {
			LM_ERR("no more pkg mem\n");
			goto error;
		}
		memset( pve, 0, sizeof(pv_elem_t));

		/* definition is between p and e */
		/* search backwards because PV definition may contain '=' characters */
		for (sep = end; sep >= p && *sep != '='; sep--);
		if (sep > p) {
			/* pv=column style */
			/* set column name */
			pve->text.s = sep + 1;
			pve->text.len = end - pve->text.s;
			trim(&pve->text);
			if (pve->text.len == 0) {
				goto parse_error;
			}
			/* set pv spec */
			pv.s = p;
			pv.len = sep - p;
			trim(&pv);
			if (pv.len == 0) {
				goto parse_error;
			}
		} else {
			/* no pv, only column name */
			pve->text.s = p;
			pve->text.len = end - pve->text.s;
			trim(&pve->text);
			if (pve->text.len == 0) {
				goto parse_error;
			}
			/* create an avp definition for the spec parser */
			pv.s = (char*)pkg_malloc(pve->text.len + 7);
			if (pv.s == NULL) {
				LM_ERR("no more pkg mem\n");
				goto parse_error;
			}
			pv.len = snprintf(pv.s, pve->text.len + 7, "$avp(%.*s)",
					pve->text.len, pve->text.s);
		}

		/* create a pv spec */
		LM_DBG("column: %.*s  pv: %.*s\n", pve->text.len, pve->text.s, pv.len, pv.s);
		pve->spec = pv_spec_lookup(&pv, NULL);
		if(pve->spec==NULL || pve->spec->setf == NULL) {
			LM_ERR("PV is not writeable: %.*s\n", pv.len, pv.s);
			goto parse_error;
		}

		/* link the element */
		pve->next = *pv_def;
		*pv_def = pve;
		(*cnt)++;
		pve = 0;
		/* go to the end */
		p = end;
		if (*p==';') {
			p++;
		}
		if (*p==0) {
			break;
		}
	}

	return 0;
parse_error:
	LM_ERR("parse failed in \"%s\" at pos %d(%s)\n",
		definition, (int)(long)(p-definition),p);
error:
	pkg_free( pve );
	pv_elem_free_all( *pv_def );
	*pv_def = 0;
	*cnt = 0;
	return -1;
}
Пример #6
0
int process_body(struct sip_msg* msg, str notify_body, udomain_t * domain) {
    xmlDocPtr doc = NULL;
    xmlNodePtr doc_root = NULL, registrations = NULL, contacts = NULL, uris = NULL;
    str aor = {0, 0};
    str callid = {0, 0};
    str contact_uri = {0, 0};
    str received = {0, 0};
    str path = {0, 0};
    str user_agent = {0, 0};
    int reg_state, contact_state, event, expires, result, final_result = RESULT_ERROR;
    char * expires_char=0, * cseq_char=0, *registration_state=0, *contact_state_s=0, *event_s=0;
    int cseq = 0;
    pv_elem_t *presentity_uri_pv;

    doc = xmlParseMemory(notify_body.s, notify_body.len);
    if (doc == NULL) {
        LM_ERR("Error while parsing the xml body message, Body is:\n%.*s\n",
                notify_body.len, notify_body.s);
        return -1;
    }
    doc_root = xmlGetNodeByName(doc->children, "reginfo");
    if (doc_root == NULL) {
        LM_ERR("while extracting the reginfo node\n");
        goto error;
    }
    registrations = doc_root->children;
    while (registrations) {
        /* Only process registration sub-items */
        if (xmlStrcasecmp(registrations->name, BAD_CAST "registration") != 0)
            goto next_registration;
		registration_state = xmlGetAttrContentByName(registrations, "state");
        reg_state = reginfo_parse_state(registration_state);
        if (reg_state == STATE_UNKNOWN) {
            LM_ERR("No state for this registration!\n");
            goto next_registration;
        }
        aor.s = xmlGetAttrContentByName(registrations, "aor");
        if (aor.s == NULL) {
            LM_ERR("No AOR for this registration!\n");
            goto next_registration;
        }
        aor.len = strlen(aor.s);
        LM_DBG("AOR %.*s has reg_state \"%d\"\n", aor.len, aor.s, reg_state);

        if (reg_state == STATE_TERMINATED) {
            //TODO we if there is a IMPU record state here we should delete all contacts associated to it
            //Right now we do it go through all the contacts

            LM_DBG("AOR %.*s is in state terminated so unsubscribing from reginfo\n", aor.len, aor.s);
            //we return a successful result here even if no contacts
            final_result = RESULT_TERMINATED_SUCCESS;

            if (pv_parse_format(&aor, &presentity_uri_pv) < 0) {
                LM_ERR("wrong format[%.*s] - failed unsubscribing to reginfo\n", aor.len, aor.s);
            }
            reginfo_subscribe_real(msg, presentity_uri_pv, 0, 0);
            pv_elem_free_all(presentity_uri_pv);
        }

        /* Now lets process the Contact's from this Registration: */
        contacts = registrations->children;
        while (contacts) {
            if (xmlStrcasecmp(contacts->name, BAD_CAST "contact") != 0)
                goto next_contact;
            callid.s = xmlGetAttrContentByName(contacts, "callid");
            if (callid.s == NULL) {
                LM_DBG("No Call-ID for this contact!\n");
                callid.len = 0;
            } else {
                callid.len = strlen(callid.s);
                LM_DBG("contact has callid <%.*s>\n", callid.len, callid.s);
            }

            received.s = xmlGetAttrContentByName(contacts, "received");
            if (received.s == NULL) {
                LM_DBG("No received for this contact!\n");
                received.len = 0;
            } else {
                received.len = strlen(received.s);
                LM_DBG("contact has received <%.*s>\n", received.len, received.s);
            }

            path.s = xmlGetAttrContentByName(contacts, "path");
            if (path.s == NULL) {
                LM_DBG("No path for this contact!\n");
                path.len = 0;
            } else {
                path.len = strlen(path.s);
                LM_DBG("contact has path <%.*s>\n", path.len, path.s);
            }

            user_agent.s = xmlGetAttrContentByName(contacts, "user_agent");
            if (user_agent.s == NULL) {
                LM_DBG("No user_agent for this contact!\n");
                user_agent.len = 0;
            } else {
                user_agent.len = strlen(user_agent.s);
                LM_DBG("contact has user_agent <%.*s>\n", user_agent.len, user_agent.s);
            }
			event_s = xmlGetAttrContentByName(contacts, "event");
            event = reginfo_parse_event(event_s);
            if (event == EVENT_UNKNOWN) {
                LM_ERR("No event for this contact - going to next contact!\n");
                goto next_contact;
            }
            expires_char = xmlGetAttrContentByName(contacts, "expires");
            if (expires_char == NULL) {
                LM_ERR("No expires for this contact - going to next contact!\n");
                goto next_contact;
            }
            expires = atoi(expires_char);
            if (expires < 0) {
                LM_ERR("No valid expires for this contact - going to next contact!\n");
                goto next_contact;
            }

			contact_state_s = xmlGetAttrContentByName(contacts, "state");
            contact_state = reginfo_parse_state(contact_state_s);
            if (contact_state == STATE_UNKNOWN) {
                LM_ERR("No state for this contact - going to next contact!\n");
                goto next_contact;
            }

            LM_DBG("Contact state %d: Event \"%d\", expires %d\n", contact_state, event, expires);



            cseq_char = xmlGetAttrContentByName(contacts, "cseq");
            if (cseq_char == NULL) {
                LM_DBG("No cseq for this contact!\n");
            } else {
                cseq = atoi(cseq_char);
                if (cseq < 0) {
                    LM_DBG("No valid cseq for this contact!\n");
                }
            }

            /* Now lets process the URI's from this Contact: */
            uris = contacts->children;
            while (uris) {
                if (xmlStrcasecmp(uris->name, BAD_CAST "uri") != 0)
                    goto next_uri;
                contact_uri.s = (char*) xmlNodeGetContent(uris);
                if (contact_uri.s == NULL) {
                    LM_ERR("No URI for this contact - going to next registration!\n");
                    goto next_registration;
                }
                contact_uri.len = strlen(contact_uri.s);
                LM_DBG("Contact: %.*s\n",
                        contact_uri.len, contact_uri.s);

                /* Add to Usrloc: */
                result = process_contact(domain, expires, contact_uri, contact_state);
				
				if (contact_uri.s && (strlen(contact_uri.s)>0)) {
					xmlFree(contact_uri.s);
					contact_uri.s = NULL;
				}

                /* Process the result */
                if (final_result != RESULT_CONTACTS_FOUND) final_result = result;
next_uri:
                uris = uris->next;
            }
next_contact:
			if (cseq_char && (strlen(cseq_char)>0)) {
				xmlFree(cseq_char);
				cseq_char=NULL;
			}
			if (expires_char && (strlen(expires_char)>0)) {
				xmlFree(expires_char);
				expires_char = NULL;
			}
			if (user_agent.s && (strlen(user_agent.s)>0)) { 
				xmlFree(user_agent.s);
				user_agent.s = NULL;
			}
			if (path.s && (strlen(path.s)>0)) { 
				xmlFree(path.s);
				path.s = NULL;
			}
			if (received.s && (strlen(received.s)>0)) {
				xmlFree(received.s);
				received.s = NULL;
			}
			if (callid.s && (strlen(callid.s)>0)) { 
				xmlFree(callid.s);
				callid.s = NULL;
			}
			if (contact_state_s && (strlen(contact_state_s)>0)) {
				xmlFree(contact_state_s); 
				contact_state_s = NULL;
			}
			if (event_s && (strlen(event_s)>0)) { 
				xmlFree(event_s); 
				event_s = NULL;
			}

            contacts = contacts->next;
        }

next_registration:
        // if (ul_record) ul.release_urecord(ul_record);		
        /* Unlock the domain for this AOR: */
        //if (aor_key.len > 0)
        //	ul.unlock_udomain(domain, &aor_key);
		if (registration_state && (strlen(registration_state)>0)) {
			xmlFree(registration_state);
			registration_state = NULL;
		}
		if (aor.len > 0 && aor.s) {
			xmlFree(aor.s);
			aor.s = NULL;
			aor.len = 0;
		}

        registrations = registrations->next;
    }
error:
    /* Free the XML-Document */
    if (doc) xmlFreeDoc(doc);
    return final_result;
}
Пример #7
0
int pv_parse_format(str *in, pv_elem_p *el)
{
	char *p, *p0;
	int n = 0;
	pv_elem_p e, e0;
	str s;
	int len;

	if(in==NULL || in->s==NULL || el==NULL)
		return -1;

	/*LM_DBG("parsing [%.*s]\n", in->len, in->s);*/

	if(in->len == 0)
	{
		*el = pkg_malloc(sizeof(pv_elem_t));
		if(*el == NULL)
			goto error;
		memset(*el, 0, sizeof(pv_elem_t));
		(*el)->text = *in;
		return 0;
	}

	p = in->s;
	*el = NULL;
	e = e0 = NULL;

	while(is_in_str(p,in))
	{
		e0 = e;
		e = pkg_malloc(sizeof(pv_elem_t));
		if(!e)
			goto error;
		memset(e, 0, sizeof(pv_elem_t));
		n++;
		if(*el == NULL)
			*el = e;
		if(e0)
			e0->next = e;

		e->text.s = p;
		while(is_in_str(p,in) && *p!=PV_MARKER)
			p++;
		e->text.len = p - e->text.s;

		if(*p == '\0' || !is_in_str(p,in))
			break;
		s.s = p;
		s.len = in->s+in->len-p;
		e->spec = pv_spec_lookup(&s, &len);
		if(e->spec==NULL)
			goto error;
		p0 = p + len;

		if(*p0 == '\0')
			break;
		p = p0;
	}
	/*LM_DBG("format parsed OK: [%d] items\n", n);*/

	if(*el == NULL)
		return -1;

	return 0;

error:
	pv_elem_free_all(*el);
	*el = NULL;
	return -1;
}
Пример #8
0
/**
 * Save the contacts and their associated public ids.
 * @param rpl - the SIP Register 200 OK response that contains the Expire and Contact and P-associated-uri headers
 * @param _d - domain
 * @param _cflags - flags
 * @returns #CSCF_RETURN_TRUE if OK, #CSCF_RETURN_ERROR on error
 */
int save(struct sip_msg* _m, udomain_t* _d, int _cflags) {
	struct sip_msg* req;
	int expires_hdr = 0;
	contact_body_t* cb = 0;
	str *public_ids=0;
	int num_public_ids = 0;
	str *service_routes=0;
	int num_service_routes = 0;
	pv_elem_t *presentity_uri_pv;
	
	//get request from reply
	req = get_request_from_reply(_m);
	if (!req) {
		LM_ERR("Unable to get request from reply for REGISTER. No transaction\n");
		goto error;
	}
	expires_hdr = cscf_get_expires_hdr(_m, 0);
	cb = cscf_parse_contacts(_m);
	if (!cb || (!cb->contacts && !cb->star)) {
		LM_DBG("No contact headers and not *\n");
		goto error;
	}
	cscf_get_p_associated_uri(_m, &public_ids, &num_public_ids, 1);
	service_routes = cscf_get_service_route(_m, &num_service_routes, 1);

	//update contacts
	if (!update_contacts(req, _m, _d, cb->star, expires_hdr, public_ids, num_public_ids, service_routes, num_service_routes, 0)) {
		LM_ERR("failed to update pcontact\n");
		goto error;
	}

	if(subscribe_to_reginfo == 1){
	    
	    //use the first p_associated_uri - i.e. the default IMPU
	    LM_DBG("Subscribe to reg event for primary p_associated_uri");
	    if(num_public_ids > 0){
		//find the first routable (not a tel: URI and use that that presentity)
		//if you can not find one then exit
		int i = 0;
		int found_presentity_uri=0;
		while (i < num_public_ids && found_presentity_uri == 0)
		{
		    //check if public_id[i] is NOT a tel URI - if it isn't then concert to pv format and set found presentity_uri to 1
		    if (strncasecmp(public_ids[i].s,"tel:",4)==0) {
			LM_DBG("This is a tel URI - it is not routable so we don't use it to subscribe");
			i++;
		    }
		    else {
			//convert primary p_associated_uri to pv_elem_t
			if(pv_parse_format(&public_ids[i], &presentity_uri_pv)<0) {
				LM_ERR("wrong format[%.*s]\n",public_ids[i].len, public_ids[i].s);
				goto error;
			}
			found_presentity_uri=1;
		    }
		}
		if(found_presentity_uri!=1){
		    LM_ERR("Could not find routable URI in p_assoiated_uri list - failed to subscribe");
		    goto error;
		}
	    }else{
		//Now some how check if there is a pua record and what the presentity uri is from there - if nothing there
		LM_DBG("No p_associated_uri in 200 OK this must be a de-register - we ignore this - will unsubscribe when the notify is received");
		goto done;
		
	    }
	    reginfo_subscribe_real(_m, presentity_uri_pv, service_routes, subscription_expires);
	    pv_elem_free_all(presentity_uri_pv);
	}
    
done:
	if (public_ids && public_ids->s) pkg_free(public_ids);
	if (service_routes && service_routes->s) pkg_free(service_routes);
	return 1;

error:
	if (public_ids && public_ids->s) pkg_free(public_ids);
	if (service_routes && service_routes->s) pkg_free(service_routes);
	return -1;

}
Пример #9
0
int do_acc_fixup(void** param, int param_no)
{
	str s;
	pv_elem_p el;

	unsigned long long ival;
	unsigned long long* ival_p;

	acc_type_param_t* acc_param;

	do_acc_parser parser;

	if (param_no < 1 || param_no > 3) {
		LM_ERR("invalid param_no <%d>!\n", param_no);
		return -1;
	}

	switch (param_no) {
	case 1:
		parser=do_acc_type_parser;
		s.s = *param;
		s.len = strlen(s.s);

		if (pv_parse_format(&s, &el) < 0) {
			LM_ERR("invalid format <%.*s>!\n", s.len, s.s);
			return -1;
		}

		acc_param=pkg_malloc(sizeof(acc_type_param_t));
		if (acc_param == NULL) {
			LM_ERR("no more pkg mem!\n");
			return -1;
		}

		memset(acc_param, 0, sizeof(acc_type_param_t));

		if (el->next == 0 && el->spec.getf == 0) {
			pv_elem_free_all(el);
			if ( (ival=do_acc_parse(&el->text, parser)) < 0) {
				LM_ERR("Invalid value <%.*s>!\n", el->text.len, el->text.s);
				return -1;
			}

			acc_param->t = DO_ACC_PARAM_TYPE_VALUE;
			acc_param->u.ival = ival;
		} else {
			acc_param->t = DO_ACC_PARAM_TYPE_PV;
			acc_param->u.pval = el;
		}

		*param = acc_param;

		break;

	case 2:
		parser=do_acc_flags_parser;
		s.s = *param;
		s.len = strlen(s.s);

		if ( (ival=do_acc_parse(&s, parser)) < 0) {
			LM_ERR("Invalid value <%.*s>!\n", s.len, s.s);
			return -1;
		}

		if ((ival_p=pkg_malloc(sizeof(unsigned long long))) == NULL) {
			LM_ERR("no more pkg mem!\n");
			return -1;
		}

		*ival_p = ival;

		*param = ival_p;
		break;
	case 3:
		return fixup_sgp(param);
	}

	return 0;
}