|
@@ -33,9 +33,11 @@
|
|
|
#include "utils.h"
|
|
|
#include "../../core/mem/mem.h"
|
|
|
#include "../../core/data_lump.h"
|
|
|
+#include "../../core/basex.h"
|
|
|
#include "../../core/parser/hf.h"
|
|
|
#include "../../core/parser/parse_uri.h"
|
|
|
#include "../../core/parser/contact/parse_contact.h"
|
|
|
+#include "../../core/dset.h"
|
|
|
#include "../../core/ut.h"
|
|
|
|
|
|
#include <stdio.h>
|
|
@@ -628,3 +630,250 @@ int decode_uri(str uri, char separator, str *result)
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+int ki_contact_param_encode(sip_msg_t *msg, str *nparam, str *saddr)
|
|
|
+{
|
|
|
+ contact_body_t *cb;
|
|
|
+ contact_t *c;
|
|
|
+ str nuri;
|
|
|
+ char bval[MAX_URI_SIZE];
|
|
|
+ str pval;
|
|
|
+
|
|
|
+ if((msg->contact == NULL)
|
|
|
+ && ((parse_headers(msg, HDR_CONTACT_F, 0) == -1)
|
|
|
+ || (msg->contact == NULL))) {
|
|
|
+ LM_DBG("no Contact header present\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ cb = (contact_body_t *)msg->contact->parsed;
|
|
|
+ c = cb->contacts;
|
|
|
+ /* we visit each contact */
|
|
|
+ while(c != NULL) {
|
|
|
+ if(c->uri.len>4) {
|
|
|
+ pval.len = base64url_enc(c->uri.s, c->uri.len, bval, MAX_URI_SIZE-1);
|
|
|
+ if (pval.len < 0) {
|
|
|
+ LM_ERR("failed to encode contact uri [%.*s]\n",
|
|
|
+ c->uri.len, c->uri.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (pval.len>1 && bval[pval.len-1] == '=') {
|
|
|
+ pval.len--;
|
|
|
+ if (pval.len>1 && bval[pval.len-1] == '=') {
|
|
|
+ pval.len--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bval[pval.len] = '\0';
|
|
|
+ pval.s = bval;
|
|
|
+ nuri.s = (char*)pkg_malloc(MAX_URI_SIZE * sizeof(char));
|
|
|
+ if(nuri.s==NULL) {
|
|
|
+ PKG_MEM_ERROR;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ nuri.len = snprintf(nuri.s, MAX_URI_SIZE-1, "sip:%.*s;%.*s=%.*s",
|
|
|
+ saddr->len, saddr->s, nparam->len, nparam->s,
|
|
|
+ pval.len, pval.s);
|
|
|
+ if(nuri.len<=0 || nuri.len>=MAX_URI_SIZE) {
|
|
|
+ LM_ERR("failed to build the new contact for [%.*s] uri (%d)\n",
|
|
|
+ c->uri.len, c->uri.s, nuri.len);
|
|
|
+ pkg_free(nuri.s);
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ if(patch(msg, c->uri.s, c->uri.len, nuri.s, nuri.len) < 0) {
|
|
|
+ LM_ERR("failed to update contact uri [%.*s]\n",
|
|
|
+ c->uri.len, c->uri.s);
|
|
|
+ pkg_free(nuri.s);
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ c = c->next;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int ki_contact_param_decode(sip_msg_t *msg, str *nparam)
|
|
|
+{
|
|
|
+ contact_body_t *cb;
|
|
|
+ contact_t *c;
|
|
|
+ param_t* pit;
|
|
|
+ char boval[MAX_URI_SIZE];
|
|
|
+ char bnval[MAX_URI_SIZE];
|
|
|
+ str oval;
|
|
|
+ str nval;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if((msg->contact == NULL)
|
|
|
+ && ((parse_headers(msg, HDR_CONTACT_F, 0) == -1)
|
|
|
+ || (msg->contact == NULL))) {
|
|
|
+ LM_DBG("no Contact header present\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(msg->contact->parsed == NULL) {
|
|
|
+ if(parse_contact(msg->contact) < 0 || msg->contact->parsed == NULL) {
|
|
|
+ LM_ERR("contact parsing failed\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ cb = (contact_body_t *)msg->contact->parsed;
|
|
|
+ c = cb->contacts;
|
|
|
+ while(c != NULL) {
|
|
|
+ pit = c->params;
|
|
|
+ while(pit!=NULL) {
|
|
|
+ if(pit->name.len==nparam->len
|
|
|
+ && strncasecmp(pit->name.s, nparam->s, nparam->len)==0) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pit=pit->next;
|
|
|
+ }
|
|
|
+ if(pit!=NULL && pit->body.len>0) {
|
|
|
+ oval = pit->body;
|
|
|
+ if(oval.len % 4) {
|
|
|
+ if(oval.len + 4 >= MAX_URI_SIZE-1) {
|
|
|
+ LM_ERR("not enough space to insert padding [%.*s]\n",
|
|
|
+ c->uri.len, c->uri.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ memcpy(boval, oval.s, oval.len);
|
|
|
+ for(i=0; i < (4 - (oval.len % 4)); i++) {
|
|
|
+ boval[oval.len + i] = '=';
|
|
|
+ }
|
|
|
+ oval.s = boval;
|
|
|
+ oval.len += (4 - (oval.len % 4));
|
|
|
+ /* move to next buffer */
|
|
|
+ }
|
|
|
+ nval.len = base64url_dec(oval.s, oval.len, bnval, MAX_URI_SIZE-1);
|
|
|
+ if (nval.len <= 0) {
|
|
|
+ LM_ERR("failed to decode contact uri [%.*s]\n",
|
|
|
+ c->uri.len, c->uri.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ nval.s = (char*)pkg_malloc((nval.len+1)*sizeof(char));
|
|
|
+ if(nval.s==NULL) {
|
|
|
+ PKG_MEM_ERROR;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ memcpy(nval.s, bnval, nval.len);
|
|
|
+ nval.s[nval.len] = '\0';
|
|
|
+
|
|
|
+ LM_DBG("new uri [%.*s]\n", nval.len, nval.s);
|
|
|
+ if(patch(msg, c->uri.s, c->uri.len, nval.s, nval.len) < 0) {
|
|
|
+ LM_ERR("failed to update contact uri [%.*s]\n",
|
|
|
+ c->uri.len, c->uri.s);
|
|
|
+ pkg_free(nval.s);
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ c = c->next;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+int ki_contact_param_decode_ruri(sip_msg_t *msg, str *nparam)
|
|
|
+{
|
|
|
+ str uri;
|
|
|
+ sip_uri_t puri;
|
|
|
+ str sparams;
|
|
|
+ param_t* params = NULL;
|
|
|
+ param_hooks_t phooks;
|
|
|
+ param_t *pit=NULL;
|
|
|
+ char boval[MAX_URI_SIZE];
|
|
|
+ char bnval[MAX_URI_SIZE];
|
|
|
+ str oval;
|
|
|
+ str nval;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if((msg->new_uri.s == NULL) || (msg->new_uri.len == 0)) {
|
|
|
+ uri = msg->first_line.u.request.uri;
|
|
|
+ if(uri.s == NULL) {
|
|
|
+ LM_ERR("r-uri not found\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ uri = msg->new_uri;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parse_uri (uri.s, uri.len, &puri) < 0) {
|
|
|
+ LM_ERR("failed to parse r-uri [%.*s]\n", uri.len, uri.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(puri.sip_params.len>0) {
|
|
|
+ sparams = puri.sip_params;
|
|
|
+ } else if(puri.params.len>0) {
|
|
|
+ sparams = puri.params;
|
|
|
+ } else {
|
|
|
+ LM_DBG("no uri params [%.*s]\n", uri.len, uri.s);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parse_params2(&sparams, CLASS_ANY, &phooks, ¶ms, ';')<0) {
|
|
|
+ LM_ERR("failed to parse uri params [%.*s]\n", uri.len, uri.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ pit = params;
|
|
|
+ while(pit!=NULL) {
|
|
|
+ if(pit->name.len==nparam->len
|
|
|
+ && strncasecmp(pit->name.s, nparam->s, nparam->len)==0) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pit=pit->next;
|
|
|
+ }
|
|
|
+ if(pit==NULL || pit->body.len<=0) {
|
|
|
+ free_params(params);
|
|
|
+ LM_DBG("no uri param value [%.*s]\n", uri.len, uri.s);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ oval = pit->body;
|
|
|
+ if(oval.len % 4) {
|
|
|
+ if(oval.len + 4 >= MAX_URI_SIZE-1) {
|
|
|
+ LM_ERR("not enough space to insert padding [%.*s]\n",
|
|
|
+ uri.len, uri.s);
|
|
|
+ free_params(params);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ memcpy(boval, oval.s, oval.len);
|
|
|
+ for(i=0; i < (4 - (oval.len % 4)); i++) {
|
|
|
+ boval[oval.len + i] = '=';
|
|
|
+ }
|
|
|
+ oval.s = boval;
|
|
|
+ oval.len += (4 - (oval.len % 4));
|
|
|
+ /* move to next buffer */
|
|
|
+ }
|
|
|
+ nval.len = base64url_dec(oval.s, oval.len, bnval, MAX_URI_SIZE-1);
|
|
|
+ if (nval.len <= 0) {
|
|
|
+ free_params(params);
|
|
|
+ LM_ERR("failed to decode uri [%.*s]\n", uri.len, uri.s);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ nval.s = (char*)pkg_malloc((nval.len+1)*sizeof(char));
|
|
|
+ if(nval.s==NULL) {
|
|
|
+ free_params(params);
|
|
|
+ PKG_MEM_ERROR;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ memcpy(nval.s, bnval, nval.len);
|
|
|
+ nval.s[nval.len] = '\0';
|
|
|
+
|
|
|
+ LM_DBG("new uri [%.*s]\n", nval.len, nval.s);
|
|
|
+
|
|
|
+ if((msg->new_uri.s == NULL) || (msg->new_uri.len == 0)) {
|
|
|
+ msg->new_uri = nval;
|
|
|
+ } else {
|
|
|
+ pkg_free(msg->new_uri.s);
|
|
|
+ msg->new_uri = nval;
|
|
|
+ }
|
|
|
+ ruri_mark_new(); /* re-use uri for serial forking */
|
|
|
+
|
|
|
+ free_params(params);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|