static int w_sdp_content_sloppy(sip_msg_t* msg, char* foo, char *bar) { str body; int mime; body.s = get_body(msg); if (body.s == NULL) return -1; body.len = msg->len - (int)(body.s - msg->buf); if (body.len == 0) return -1; mime = parse_content_type_hdr(msg); if (mime < 0) return -1; /* error */ if (mime == 0) return 1; /* default is application/sdp */ switch (((unsigned int)mime) >> 16) { case TYPE_APPLICATION: if ((mime & 0x00ff) == SUBTYPE_SDP) return 1; else return -1; case TYPE_MULTIPART: if ((mime & 0x00ff) == SUBTYPE_MIXED) { if (_strnistr(body.s, "application/sdp", body.len) == NULL) { return -1; } else { return 1; } } else { return -1; } default: return -1; } }
int mangle_message_cpim(struct sip_msg* _msg, char* _s1, char* _s2) { char *body = get_body(_msg); int parsed_content_type; struct hdr_field *content_type = _msg->content_type; int body_len = 0; parse_headers(_msg, HDR_CONTENTLENGTH_F|HDR_CONTENTTYPE_F, 0); parsed_content_type = parse_content_type_hdr(_msg); body_len = get_content_length(_msg); LOG(L_ERR, "mangle_message_cpim -1- content_type==%.*s %x (patching %x) bodylen=%d\n", content_type->body.len, content_type->body.s, parsed_content_type, MIMETYPE(MESSAGE,CPIM), body_len); if (body && (parsed_content_type == MIMETYPE(MESSAGE,CPIM))) { char *ptr = strstr(body, "\r\n\r\n"); char *new_content_type_str = strstr(body, "Content-Type: "); int new_content_type_len = 0; char *new_content_type_body; if (new_content_type_str) { char *new_content_type_end = strstr(new_content_type_str, "\r\n"); if (new_content_type_end) { new_content_type_str += 14; new_content_type_len = new_content_type_end - new_content_type_str; } else { new_content_type_len = 10; new_content_type_str = "text/plain"; } } else { new_content_type_len = 10; new_content_type_str = "text/plain"; } if (strncmp(new_content_type_str, "application/sip-iscomposing+xml", 31) == 0) { new_content_type_len = 30; new_content_type_str = "application/im-iscomposing+xml"; } new_content_type_body = pkg_malloc(new_content_type_len); strncpy(new_content_type_body, new_content_type_str, new_content_type_len); //LOG(L_ERR, "mangle_message_cpim -1- oldbody=%.*s\n", body_len, body); patch_msg(_msg, content_type->body.s, content_type->body.len, new_content_type_body, new_content_type_len); LOG(L_ERR, "mangle_message_cpim -1b- patched content-type=%.*s\n", new_content_type_len, new_content_type_str); if (ptr) { char *new_body = NULL; int new_body_len = body_len - (ptr + 4 - body); //LOG(L_ERR, "mangle_message_cpim -2- old_body_len=%d new_body_len=%d\n", body_len, new_body_len); new_body = pkg_malloc(new_body_len+1); strncpy(new_body, ptr+4, new_body_len+1); patch_msg(_msg, body, body_len, new_body, new_body_len); } } LOG(L_ERR, "mangle_message_cpim -3-\n"); return 1; }
/* * Parse all header fields that will be needed * to handle a PUBLISH request */ static int parse_publish_hfs(struct sip_msg* _m) { int rc = 0; if ((rc = parse_headers(_m, HDR_FROM_F | HDR_EVENT_F | HDR_EXPIRES_F | HDR_SIPIFMATCH_F | HDR_CONTENTTYPE_F | HDR_CONTENTLENGTH_F, 0)) == -1) { paerrno = PA_PARSE_ERR; LOG(L_ERR, "parse_publish_hfs(): Error while parsing headers\n"); return -1; } if (parse_from_header(_m) < 0) { paerrno = PA_FROM_ERR; LOG(L_ERR, "parse_publish_hfs(): From malformed or missing\n"); return -6; } if (_m->event) { if (parse_event(_m->event) < 0) { paerrno = PA_EVENT_PARSE; LOG(L_ERR, "parse_publish_hfs(): Error while parsing Event header field\n"); return -8; } } else { paerrno = PA_EVENT_PARSE; LOG(L_ERR, "parse_publish_hfs(): Missing Event header field\n"); return -7; } if (_m->expires) { if (parse_expires(_m->expires) < 0) { paerrno = PA_EXPIRES_PARSE; LOG(L_ERR, "parse_publish_hfs(): Error while parsing Expires header field\n"); return -9; } } /* patch from PIC-SER */ if (_m->sipifmatch) { if (parse_sipifmatch(_m->sipifmatch) < 0) { paerrno = PA_PARSE_ERR; LOG(L_ERR, "parse_hfs(): Error while parsing SIP-If-Match header field\n"); return -10; } } if (_m->content_type) { if (parse_content_type_hdr(_m) < 0) { LOG(L_ERR, "parse_hfs(): Can't parse Content-Type\n"); return -12; } } return 0; }
static int cmd_send_message(struct sip_msg* msg, char* _foo, char* _bar) { str body, from_uri, dst, tagid; int mime; LM_DBG("cmd_send_message\n"); /* extract body */ if (get_body(msg,&body)!=0 || body.len==0) { LM_ERR("failed to extract body\n"); return -1; } if ((mime = parse_content_type_hdr(msg)) < 1) { LM_ERR("failed parse content-type\n"); return -1; } if (mime != (TYPE_TEXT << 16) + SUBTYPE_PLAIN && mime != (TYPE_MESSAGE << 16) + SUBTYPE_CPIM) { LM_ERR("invalid content-type 0x%x\n", mime); return -1; } /* extract sender */ if (parse_headers(msg, HDR_TO_F | HDR_FROM_F, 0) == -1 || !msg->to || !msg->from) { LM_ERR("no To/From headers\n"); return -1; } if (parse_from_header(msg) < 0 || !msg->from->parsed) { LM_ERR("failed to parse From header\n"); return -1; } from_uri.s = uri_sip2xmpp(&((struct to_body *) msg->from->parsed)->uri); from_uri.len = strlen(from_uri.s); tagid = ((struct to_body *) msg->from->parsed)->tag_value; LM_DBG("message from <%.*s>\n", from_uri.len, from_uri.s); /* extract recipient */ dst.len = 0; if (msg->new_uri.len > 0) { LM_DBG("using new URI as destination\n"); dst = msg->new_uri; } else if (msg->first_line.u.request.uri.s && msg->first_line.u.request.uri.len > 0) { LM_DBG("using R-URI as destination\n"); dst = msg->first_line.u.request.uri; } else if (msg->to->parsed) { LM_DBG("using TO-URI as destination\n"); dst = ((struct to_body *) msg->to->parsed)->uri; } else { LM_ERR("failed to find a valid destination\n"); return -1; } dst.s = dst.s + 4; dst.len = dst.len - 4; if (!xmpp_send_pipe_cmd(XMPP_PIPE_SEND_MESSAGE, &from_uri, &dst, &body, &tagid)) return 1; return -1; }
/** * manage SIP message */ int xjab_manage_sipmsg(struct sip_msg *msg, int type) { str body, dst, from_uri; xj_sipmsg jsmsg; int pipe, fl; t_xj_jkey jkey, *p; int mime; body.len = 0; body.s = 0; // extract message body - after that whole SIP MESSAGE is parsed if (type==XJ_SEND_MESSAGE) { /* get the message's body */ body.s = get_body( msg ); if(body.s==0) { LM_ERR("cannot extract body from msg\n"); goto error; } /* content-length (if present) must be already parsed */ if(!msg->content_length) { LM_ERR("no Content-Length header found!\n"); goto error; } body.len = get_content_length(msg); /* parse the content-type header */ if((mime=parse_content_type_hdr(msg))<1) { LM_ERR("cannot parse Content-Type header\n"); goto error; } /* check the content-type value */ if(mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM) { LM_ERR("invalid content-type for" " a message request! type found=%d\n", mime); goto error; } } // check for TO and FROM headers - if is not SIP MESSAGE if(parse_headers(msg,HDR_TO_F|HDR_FROM_F,0)==-1 || !msg->to || !msg->from) { LM_ERR("cannot find TO or FROM HEADERS!\n"); goto error; } /* parsing from header */ if ( parse_from_header( msg )<0 || msg->from->parsed==NULL) { LM_DBG("cannot get FROM header\n"); goto error; } from_uri.s = ((struct to_body*)msg->from->parsed)->uri.s; from_uri.len = ((struct to_body*)msg->from->parsed)->uri.len; if(xj_extract_aor(&from_uri, 0)) { LM_DBG("cannot get AoR from FROM header\n"); goto error; } jkey.hash = xj_get_hash(&from_uri, NULL); jkey.id = &from_uri; // get the communication pipe with the worker switch(type) { case XJ_SEND_MESSAGE: case XJ_JOIN_JCONF: case XJ_GO_ONLINE: if((pipe = xj_wlist_get(jwl, &jkey, &p)) < 0) { LM_DBG("cannot find pipe of the worker!\n"); goto error; } break; case XJ_EXIT_JCONF: case XJ_GO_OFFLINE: if((pipe = xj_wlist_check(jwl, &jkey, &p)) < 0) { LM_DBG("no open Jabber session for" " <%.*s>!\n", from_uri.len, from_uri.s); goto error; } break; default: LM_DBG("ERROR:strange SIP msg type!\n"); goto error; } // if is for going ONLINE/OFFLINE we do not need the destination if(type==XJ_GO_ONLINE || type==XJ_GO_OFFLINE) goto prepare_job; // determination of destination // - try to get it from new_uri, r-uri or to hdr, but check it against // jdomain and aliases dst.len = 0; if( msg->new_uri.len > 0) { dst.s = msg->new_uri.s; dst.len = msg->new_uri.len; if(xj_wlist_check_aliases(jwl, &dst)) dst.len = 0; #ifdef XJ_EXTRA_DEBUG else LM_DBG("using NEW URI for destination\n"); #endif } if (dst.len == 0 && msg->first_line.u.request.uri.s != NULL && msg->first_line.u.request.uri.len > 0 ) { dst.s = msg->first_line.u.request.uri.s; dst.len = msg->first_line.u.request.uri.len; if(xj_wlist_check_aliases(jwl, &dst)) dst.len = 0; #ifdef XJ_EXTRA_DEBUG else LM_DBG("using R-URI for destination\n"); #endif } if(dst.len == 0 && msg->to->parsed) { dst.s = ((struct to_body*)msg->to->parsed)->uri.s; dst.len = ((struct to_body*)msg->to->parsed)->uri.len; if(dst.s == NULL || xj_wlist_check_aliases(jwl, &dst)) dst.len = 0; #ifdef XJ_EXTRA_DEBUG else LM_DBG("using TO-URI for destination\n"); #endif } if(dst.len == 0) { LM_DBG("destination not found in SIP message\n"); goto error; } /** skip 'sip:' and parameters in destination address */ if(xj_extract_aor(&dst, 1)) { LM_ERR("cannot get AoR for destination\n"); goto error; } #ifdef XJ_EXTRA_DEBUG LM_DBG("destination after correction [%.*s].\n", dst.len, dst.s); #endif prepare_job: //putting the SIP message parts in share memory to be accessible by workers jsmsg = (xj_sipmsg)shm_malloc(sizeof(t_xj_sipmsg)); memset(jsmsg, 0, sizeof(t_xj_sipmsg)); if(jsmsg == NULL) return -1; switch(type) { case XJ_SEND_MESSAGE: jsmsg->msg.len = body.len; if((jsmsg->msg.s = (char*)shm_malloc(jsmsg->msg.len+1)) == NULL) { shm_free(jsmsg); goto error; } strncpy(jsmsg->msg.s, body.s, jsmsg->msg.len); break; case XJ_GO_ONLINE: case XJ_GO_OFFLINE: dst.len = 0; dst.s = 0; case XJ_JOIN_JCONF: case XJ_EXIT_JCONF: jsmsg->msg.len = 0; jsmsg->msg.s = NULL; break; default: LM_DBG("this SHOULD NOT appear\n"); shm_free(jsmsg); goto error; } if(dst.len>0) { jsmsg->to.len = dst.len; if((jsmsg->to.s = (char*)shm_malloc(jsmsg->to.len+1))==NULL) { if(type == XJ_SEND_MESSAGE) shm_free(jsmsg->msg.s); shm_free(jsmsg); goto error; } strncpy(jsmsg->to.s, dst.s, jsmsg->to.len); } else { jsmsg->to.len = 0; jsmsg->to.s = 0; } jsmsg->jkey = p; jsmsg->type = type; //jsmsg->jkey->hash = jkey.hash; LM_DBG("sending <%p> to worker through <%d>\n", jsmsg, pipe); // sending the SHM pointer of SIP message to the worker fl = write(pipe, &jsmsg, sizeof(jsmsg)); if(fl != sizeof(jsmsg)) { LM_ERR("failed to write to worker pipe!\n"); if(type == XJ_SEND_MESSAGE) shm_free(jsmsg->msg.s); shm_free(jsmsg->to.s); shm_free(jsmsg); goto error; } return 1; error: return -1; }
/** * store message * mode = "0" -- look for outgoing URI starting with new_uri * = "1" -- look for outgoing URI starting with r-uri * = "2" -- look for outgoing URI only at to header */ static int m_store(struct sip_msg* msg, char* mode, char* str2) { str body, str_hdr, sruri, ctaddr; struct to_body to, *pto, *pfrom; db_key_t db_keys[NR_KEYS]; db_val_t db_vals[NR_KEYS]; int nr_keys = 0, val, lexpire; t_content_type ctype; char buf[512], buf1[1024], *p; int mime; DBG("MSILO: m_store: ------------ start ------------\n"); // extract message body - after that whole SIP MESSAGE is parsed /* get the message's body */ body.s = get_body( msg ); if (body.s==0) { LOG(L_ERR,"MSILO:m_store: ERROR cannot extract body from msg\n"); goto error; } /* content-length (if present) must be already parsed */ if (!msg->content_length) { LOG(L_ERR,"MSILO:m_store: ERROR no Content-Length header found!\n"); goto error; } body.len = get_content_length( msg ); // check if the body of message contains something if(body.len <= 0) { DBG("MSILO:m_store: body of the message is empty!\n"); goto error; } // check TO header if(!msg->to || !msg->to->body.s) { DBG("MSILO:m_store: cannot find 'to' header!\n"); goto error; } if(msg->to->parsed != NULL) { pto = (struct to_body*)msg->to->parsed; DBG("MSILO:m_store: 'To' header ALREADY PARSED: <%.*s>\n", pto->uri.len, pto->uri.s ); } else { DBG("MSILO:m_store: 'To' header NOT PARSED ->parsing ...\n"); memset( &to , 0, sizeof(to) ); parse_to(msg->to->body.s, msg->to->body.s+msg->to->body.len+1, &to); if(to.uri.len > 0) // && to.error == PARSE_OK) { DBG("MSILO:m_store: 'To' parsed OK <%.*s>.\n", to.uri.len, to.uri.s); pto = &to; } else { DBG("MSILO:m_store: ERROR 'To' cannot be parsed\n"); goto error; } } if(pto->uri.len == reg_addr.len && !strncasecmp(pto->uri.s, reg_addr.s, reg_addr.len)) { DBG("MSILO:m_store: message to MSILO REGISTRAR!\n"); goto error; } db_keys[nr_keys] = DB_KEY_TO; db_vals[nr_keys].type = DB_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = pto->uri.s; db_vals[nr_keys].val.str_val.len = pto->uri.len; nr_keys++; // check FROM header if(!msg->from || !msg->from->body.s) { DBG("MSILO:m_store: ERROR cannot find 'from' header!\n"); goto error; } if(msg->from->parsed != NULL) DBG("MSILO:m_store: 'From' header ALREADY PARSED\n"); else { DBG("MSILO:m_store: 'From' header NOT PARSED\n"); /* parsing from header */ if ( parse_from_header( msg )==-1 ) { DBG("MSILO:m_store: ERROR cannot parse FROM header\n"); goto error; } } pfrom = (struct to_body*)msg->from->parsed; DBG("MSILO:m_store: 'From' header: <%.*s>\n",pfrom->uri.len,pfrom->uri.s); if(reg_addr.s && pfrom->uri.len == reg_addr.len && !strncasecmp(pfrom->uri.s, reg_addr.s, reg_addr.len)) { DBG("MSILO:m_store: message from MSILO REGISTRAR!\n"); goto error; } db_keys[nr_keys] = DB_KEY_FROM; db_vals[nr_keys].type = DB_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = pfrom->uri.s; db_vals[nr_keys].val.str_val.len = pfrom->uri.len; nr_keys++; // chech for RURI sruri.len = 0; if(mode && mode[0]=='0' && msg->new_uri.len > 0) { DBG("MSILO:m_store: NEW R-URI found - check if is AoR!\n"); p = msg->new_uri.s; while((p < msg->new_uri.s+msg->new_uri.len) && *p!='@') p++; if(p < msg->new_uri.s+msg->new_uri.len && p > msg->new_uri.s) { DBG("MSILO:m_store: NEW R-URI used\n"); sruri.s = msg->new_uri.s; // check for parameters while((p < msg->new_uri.s+msg->new_uri.len) && *p!=';') p++; sruri.len = p - msg->new_uri.s; } } if(mode && mode[0]<='1' && sruri.len == 0 && msg->first_line.u.request.uri.len > 0 ) { DBG("MSILO:m_store: R-URI found - check if is AoR!\n"); p = msg->first_line.u.request.uri.s; while((p < msg->first_line.u.request.uri.s+ msg->first_line.u.request.uri.len) && *p!='@') p++; if(p<msg->first_line.u.request.uri.s+msg->first_line.u.request.uri.len && p > msg->first_line.u.request.uri.s) { DBG("MSILO:m_store: R-URI used\n"); sruri.s = msg->first_line.u.request.uri.s; // check for parameters while((p < msg->first_line.u.request.uri.s + msg->first_line.u.request.uri.len) && *p!=';') p++; sruri.len = p - msg->first_line.u.request.uri.s; } } if (sruri.len == 0) { DBG("MSILO:m_store: TO used as R-URI\n"); sruri.s = pto->uri.s; sruri.len = pto->uri.len; } db_keys[nr_keys] = DB_KEY_RURI; db_vals[nr_keys].type = DB_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = sruri.s; db_vals[nr_keys].val.str_val.len = sruri.len; nr_keys++; /* add the message's body in SQL query */ db_keys[nr_keys] = DB_KEY_BODY; db_vals[nr_keys].type = DB_BLOB; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.blob_val.s = body.s; db_vals[nr_keys].val.blob_val.len = body.len; nr_keys++; lexpire = expire_time; // add 'content-type' /* parse the content-type header */ if ((mime=parse_content_type_hdr(msg))<1 ) { LOG(L_ERR,"MSILO:m_store: ERROR cannot parse Content-Type header\n"); goto error; } /** check the content-type value */ if( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM ) { if(m_extract_content_type(msg->content_type->body.s, msg->content_type->body.len, &ctype, CT_TYPE) != -1) { DBG("MSILO:m_store: 'content-type' found\n"); db_keys[nr_keys] = DB_KEY_CTYPE; db_vals[nr_keys].type = DB_STR; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.str_val.s = ctype.type.s; db_vals[nr_keys].val.str_val.len = ctype.type.len; nr_keys++; } } // check 'expires' // no more parseing - already done by get_body() // if(parse_headers(msg, HDR_EXPIRES,0)!=-1) if(msg->expires && msg->expires->body.len > 0) { DBG("MSILO:m_store: 'expires' found\n"); val = atoi(msg->expires->body.s); if(val > 0) lexpire = (expire_time<=val)?expire_time:val; } /** current time */ val = (int)time(NULL); /** add expiration time */ db_keys[nr_keys] = DB_KEY_EXP_TIME; db_vals[nr_keys].type = DB_INT; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.int_val = val+lexpire; nr_keys++; /** add incoming time */ db_keys[nr_keys] = DB_KEY_INC_TIME; db_vals[nr_keys].type = DB_INT; db_vals[nr_keys].nul = 0; db_vals[nr_keys].val.int_val = val; nr_keys++; if(db_insert(db_con, db_keys, db_vals, nr_keys) < 0) { LOG(L_ERR, "MSILO:m_store: error storing message\n"); goto error; } DBG("MSILO:m_store: message stored. T:<%.*s> F:<%.*s>\n", pto->uri.len, pto->uri.s, pfrom->uri.len, pfrom->uri.s); if(reg_addr.len > 0 && reg_addr.len+33+2*CRLF_LEN < 1024) { DBG("MSILO:m_store: sending info message.\n"); strcpy(buf1,"Content-Type: text/plain"CRLF"Contact: "); str_hdr.len = 24 + CRLF_LEN + 9; strncat(buf1,reg_addr.s,reg_addr.len); str_hdr.len += reg_addr.len; strcat(buf1, CRLF); str_hdr.len += CRLF_LEN; str_hdr.s = buf1; strncpy(buf, "User [", 6); body.len = 6; if(pto->uri.len+75 < 512) { strncpy(buf+body.len, pto->uri.s, pto->uri.len); body.len += pto->uri.len; } strncpy(buf+body.len, "] is offline.", 13); body.len += 12; strncpy(buf+body.len, " The message will be delivered", 30); body.len += 30; strncpy(buf+body.len, " when user goes online.", 23); body.len += 23; body.s = buf; // look for Contact header ctaddr.s = NULL; if(use_contact && parse_headers(msg,HDR_CONTACT,0)!=-1 && msg->contact && msg->contact->body.s && msg->contact->body.len>0) { ctaddr.s = msg->contact->body.s; ctaddr.len = msg->contact->body.len; p = ctaddr.s; while(p<ctaddr.s+ctaddr.len && *p!='<') p++; if(*p == '<') { p++; ctaddr.s = p; while(p<ctaddr.s+ctaddr.len && *p!='>') p++; if(p<ctaddr.s+ctaddr.len) ctaddr.len = p-ctaddr.s; } if(!ctaddr.s || ctaddr.len < 6 || strncmp(ctaddr.s, "sip:", 4) || ctaddr.s[4]==' ') ctaddr.s = NULL; else DBG("MSILO:m_store: feedback contact [%.*s]\n", ctaddr.len,ctaddr.s); } // tmb.t_uac(&msg_type,&pfrom->uri,&str_hdr,&body,®_addr,0,0,0); tmb.t_request(&msg_type, /* Type of the message */ (ctaddr.s)?&ctaddr:&pfrom->uri, /* Request-URI */ &pfrom->uri, /* To */ ®_addr, /* From */ &str_hdr, /* Optional headers including CRLF */ &body, /* Message body */ NULL, /* Callback function */ NULL /* Callback parameter */ ); } return 1; error: return -1; }
int push_on_network(struct sip_msg *msg, int net) { str body; struct sip_uri uri; struct sms_msg *sms_messg; struct to_body *from; char *p; int len; int mime; /* get the message's body * anyhow we have to call this function, so let's do it at the beginning * to force the parsing of all the headers - like this we avoid separate * calls of parse_headers function for FROM, CONTENT_LENGTH, TO hdrs */ body.s = get_body( msg ); if (body.s==0) { LM_ERR("failed to extract body from msg!\n"); goto error; } /* content-length (if present) must be already parsed */ if (!msg->content_length) { LM_ERR("no Content-Length header found!\n"); goto error; } body.len = get_content_length( msg ); /* parse the content-type header */ if ( (mime=parse_content_type_hdr(msg))<1 ) { LM_ERR("failed to parse Content-Type header\n"); goto error; } /* check the content-type value */ if ( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM ) { LM_ERR("invalid content-type for a message request! type found=%d\n", mime); goto error; } /* we try to get the user name (phone number) first from the RURI (in our case means from new_uri or from first_line.u.request.uri); if it's missing there (like in requests generated by MSN MESSENGER), we go for "to" header */ LM_DBG("string to get user from new_uri\n"); if ( !msg->new_uri.s||parse_uri( msg->new_uri.s,msg->new_uri.len,&uri) || !uri.user.len ) { LM_DBG("string to get user from R_uri\n"); if ( parse_uri( msg->first_line.u.request.uri.s, msg->first_line.u.request.uri.len ,&uri)||!uri.user.len ) { LM_DBG("string to get user from To\n"); if ( (!msg->to&&((parse_headers(msg,HDR_TO_F,0)==-1) || !msg->to)) || parse_uri( get_to(msg)->uri.s, get_to(msg)->uri.len, &uri)==-1 || !uri.user.len) { LM_ERR("unable to extract user name from RURI and To header!\n"); goto error; } } } /* check the uri.user format = '+(inter code)(number)' */ if (uri.user.len<2 || uri.user.s[0]!='+' || uri.user.s[1]<'1' || uri.user.s[1]>'9') { LM_ERR("user tel number [%.*s] does not respect international format\n" ,uri.user.len,uri.user.s); goto error; } /* parsing from header */ if ( parse_from_header( msg )==-1 ) { LM_ERR("failed to get FROM header\n"); goto error; } from = (struct to_body*)msg->from->parsed; #if 0 /* adds contact header into reply */ if (add_contact(msg,&(uri.user))==-1) { LM_ERR("can't build contact for reply\n"); goto error; } #endif /*-------------BUILD AND FILL THE SMS_MSG STRUCTURE --------------------*/ /* computes the amount of memory needed */ len = SMS_HDR_BF_ADDR_LEN + from->uri.len + SMS_HDR_AF_ADDR_LEN + body.len + SMS_FOOTER_LEN /*text to send*/ + from->uri.len /* from */ + uri.user.len-1 /* to user (without '+') */ + sizeof(struct sms_msg) ; /* the sms_msg structure */ /* allocs a new sms_msg structure in shared memory */ sms_messg = (struct sms_msg*)shm_malloc(len); if (!sms_messg) { LM_ERR("failed to get shm memory!\n"); goto error; } p = (char*)sms_messg + sizeof(struct sms_msg); /* copy "from" into sms struct */ sms_messg->from.len = from->uri.len; sms_messg->from.s = p; append_str(p,from->uri.s,from->uri.len); /* copy "to.user" - we have to strip out the '+' */ sms_messg->to.len = uri.user.len-1; sms_messg->to.s = p; append_str(p,uri.user.s+1,sms_messg->to.len); /* copy (and composing) sms body */ sms_messg->text.len = SMS_HDR_BF_ADDR_LEN + sms_messg->from.len + SMS_HDR_AF_ADDR_LEN + body.len+SMS_FOOTER_LEN; sms_messg->text.s = p; append_str(p, SMS_HDR_BF_ADDR, SMS_HDR_BF_ADDR_LEN); append_str(p, sms_messg->from.s, sms_messg->from.len); append_str(p, SMS_HDR_AF_ADDR, SMS_HDR_AF_ADDR_LEN); append_str(p, body.s, body.len); append_str(p, SMS_FOOTER, SMS_FOOTER_LEN); if (*queued_msgs>MAX_QUEUED_MESSAGES) goto error; (*queued_msgs)++; if (write(net_pipes_in[net], &sms_messg, sizeof(sms_messg))!= sizeof(sms_messg) ) { LM_ERR("error when writing for net %d to pipe [%d] : %s\n", net,net_pipes_in[net],strerror(errno) ); shm_free(sms_messg); (*queued_msgs)--; goto error; } return 1; error: return -1; }
/* * This function encodes an arbitrary header into a chunk of bytes, * ready to be sent to the Application Server. * * The header codes start with this encoded-bytes: * 2: SIP-MSG-START based pointer to the header (including header name) * 2: length of the header * 1: length of the header name */ int encode_header(struct sip_msg *sipmsg,struct hdr_field *hdr,unsigned char *payload,int paylen) { int len=0; unsigned int integer,*methods=0; char *hdrstart,*tmp; unsigned short int ptr; struct to_body *tobody=0; struct via_body *viabody=0; struct cseq_body *cseqbody=0; char *msg,*myerror; int mlen; msg=sipmsg->buf; mlen=sipmsg->len; hdrstart = hdr->name.s; if(hdrstart-msg<0){ LM_ERR("header(%.*s) does not belong to sip_msg(hdrstart<msg)\n", hdr->name.len,hdr->name.s); return -1; } ptr=htons((short int)(hdrstart-msg)); if((hdrstart-msg)>mlen){ LM_ERR("out of the sip_msg bounds (%d>%d)\n",ntohs(ptr),mlen); return -1; } if(hdr->len>(1<<16)){ LM_ERR("length of header too long\n"); return -1; } memcpy(payload,&ptr,2); ptr=htons((short int)(hdr->len)); memcpy(payload+HEADER_LEN_IDX,&ptr,2); payload[HEADER_NAME_LEN_IDX]=(unsigned char)hdr->name.len; switch(hdr->type){ case HDR_FROM_T: case HDR_TO_T: case HDR_REFER_TO_T: case HDR_RPID_T: if(!hdr->parsed){ if((tobody=pkg_malloc(sizeof(struct to_body)))==0){ myerror="Out of memory !!\n"; goto error; } parse_to(hdr->body.s,hdr->body.s+hdr->body.len+1,tobody); if (tobody->error == PARSE_ERROR) { myerror="bad (REFER,TO,FROM,RPID) header\n"; pkg_free(tobody); return 5; goto error; } hdr->parsed=(struct to_body*)tobody; }else tobody=(struct to_body*)hdr->parsed; if((len=encode_to_body(hdr->name.s,hdr->len,tobody,payload+5))<0){ myerror="parsing from or to header\n"; goto error; }else{ return 5+len; } break; case HDR_CONTACT_T: if(!hdr->parsed) if(parse_contact(hdr)<0){ myerror="parsing contact\n"; goto error; } if((len=encode_contact_body(hdr->name.s,hdr->len,(contact_body_t*)hdr->parsed,payload+5))<0){ myerror="encoding contact header\n"; goto error; }else{ return 5+len; } break; case HDR_ROUTE_T: case HDR_RECORDROUTE_T: if(!hdr->parsed) if(parse_rr(hdr)<0){ myerror="encoding route or recordroute\n"; goto error; } if((len=encode_route_body(hdr->name.s,hdr->len,(rr_t*)hdr->parsed,payload+5))<0){ myerror="encoding route or recordroute header\n"; goto error; }else{ return 5+len; } break; case HDR_CONTENTLENGTH_T: if(!hdr->parsed){ tmp=parse_content_length(hdr->body.s,hdr->body.s+hdr->body.len+1,(int*)&integer); if (tmp==0){ myerror="bad content_length header\n"; goto error; } hdr->parsed=(void*)(long)integer; } if((len=encode_contentlength(hdr->name.s,hdr->len,(long int)hdr->parsed,(char*)(payload+5)))<0){ myerror="encoding content-length header\n"; goto error; }else{ return 5+len; } break; case HDR_VIA_T: if(!hdr->parsed){ if((viabody=pkg_malloc(sizeof(struct via_body)))==0){ myerror="out of memory\n"; goto error; } memset(viabody,0,sizeof(struct via_body)); if(parse_via(hdr->body.s,hdr->body.s+hdr->body.len+1,viabody)==0){ myerror="encoding via \n"; goto error; } hdr->parsed=viabody; } if((len=encode_via_body(hdr->name.s,hdr->len,(struct via_body*)hdr->parsed,payload+5))<0){ myerror="encoding via header\n"; goto error; }else{ return 5+len; } break; case HDR_ACCEPT_T: if(!hdr->parsed){ if(parse_accept_hdr(sipmsg)<0){ return 5; } } if((len=encode_accept(hdr->name.s,hdr->len,(unsigned int*)hdr->parsed,(char*)(payload+5)))<0){ myerror="encoding via header\n"; goto error; }else{ return 5+len; } break; case HDR_CONTENTTYPE_T: if(!hdr->parsed){ if(parse_content_type_hdr(sipmsg)<0){ myerror="encoding content-type header\n"; goto error; } } if((len=encode_content_type(hdr->name.s,hdr->len,(unsigned int)get_content_type(sipmsg),(char*)(payload+5)))<0){ myerror="encoding via header\n"; goto error; }else{ return 5+len; } break; case HDR_CSEQ_T: if(!hdr->parsed){ if((cseqbody=pkg_malloc(sizeof(struct cseq_body)))==0){ myerror="out of memory\n"; goto error; } memset(cseqbody,0,sizeof(struct cseq_body)); if(parse_cseq(hdr->name.s,hdr->body.s+hdr->body.len+1,cseqbody)==0){ myerror="encoding cseq header\n"; goto error; } hdr->parsed=cseqbody; } if((len=encode_cseq(hdr->name.s,hdr->len,(struct cseq_body*)hdr->parsed,payload+5))<0){ myerror="encoding via header\n"; goto error; }else{ return 5+len; } break; case HDR_EXPIRES_T: if(!hdr->parsed){ if(parse_expires(hdr)<0){ myerror="encoding expires header\n"; goto error; } } if((len=encode_expires(hdr->name.s,hdr->len,(exp_body_t *)hdr->parsed,payload+5))<0){ myerror="encoding expires header\n"; goto error; }else{ return 5+len; } break; case HDR_ALLOW_T: if(!hdr->parsed){ if((methods=pkg_malloc(sizeof(unsigned int)))==0){ myerror="out of memory\n"; goto error; } *methods=0; if(parse_methods(&hdr->body,methods)!=0){ myerror="encoding allow header\n"; pkg_free(methods); return 5; /*goto error;*/ } hdr->parsed=methods; } if((len=encode_allow(hdr->name.s,hdr->len,(unsigned int*)hdr->parsed,(char*)(payload+5)))<0){ myerror="encoding allow header\n"; goto error; }else{ return 5+len; } break; case HDR_AUTHORIZATION_T: case HDR_PROXYAUTH_T: if(!hdr->parsed){ if(parse_credentials(hdr)<0){ myerror="encoding a digest header\n"; goto error; } } if((len=encode_digest(hdr->name.s,hdr->len,(dig_cred_t*)(&(((auth_body_t*)hdr->parsed)->digest)),payload+5))<0){ myerror="encoding allow header\n"; goto error; }else{ return 5+len; } break; default: return 5; } return 1; error: if(tobody) pkg_free(tobody); if(cseqbody) pkg_free(cseqbody); if(viabody) free_via_list(viabody); if(methods) pkg_free(methods); LM_ERR("%s",myerror); return -1; }
static int cpl_process_register(struct sip_msg* msg, int no_rpl) { struct disposition *disp; struct disposition_param *param; int ret; int mime; int *mimes; /* make sure that is a REGISTER ??? */ /* here should be the CONTACT- hack */ /* is there a CONTENT-TYPE hdr ? */ mime = parse_content_type_hdr( msg ); if (mime==-1) goto error; /* check the mime type */ LM_DBG("Content-Type mime found %u, %u\n", mime>>16,mime&0x00ff); if ( mime && mime==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML ) { /* can be an upload or remove -> check for the content-purpose and * content-action headers */ LM_DBG("carrying CPL -> look at Content-Disposition\n"); if (parse_content_disposition( msg )!=0) { LM_ERR("Content-Disposition missing or corrupted\n"); goto error; } disp = get_content_disposition(msg); print_disposition( disp ); /* just for DEBUG */ /* check if the type of disposition is SCRIPT */ if (disp->type.len!=CPL_SCRIPT_LEN || strncasecmp(disp->type.s,CPL_SCRIPT,CPL_SCRIPT_LEN) ) { LM_ERR("bogus message - Content-Type" "says CPL_SCRIPT, but Content-Disposition something else\n"); goto error; } /* disposition type is OK -> look for action parameter */ for(param=disp->params;param;param=param->next) { if (param->name.len==ACTION_PARAM_LEN && !strncasecmp(param->name.s,ACTION_PARAM,ACTION_PARAM_LEN)) break; } if (param==0) { LM_ERR("bogus message - " "Content-Disposition has no action param\n"); goto error; } /* action param found -> check its value: store or remove */ if (param->body.len==STORE_ACTION_LEN && !strncasecmp( param->body.s, STORE_ACTION, STORE_ACTION_LEN)) { /* it's a store action -> get the script from body message and store * it into database (CPL and BINARY format) */ if (do_script_action( msg, STORE_SCRIPT)==-1) goto error; } else if (param->body.len==REMOVE_ACTION_LEN && !strncasecmp( param->body.s, REMOVE_ACTION, REMOVE_ACTION_LEN)) { /* it's a remove action -> remove the script from database */ if (do_script_action( msg, REMOVE_SCRIPT)==-1) goto error; } else { LM_ERR("unknown action <%.*s>\n", param->body.len,param->body.s); goto error; } /* do I have to send to reply? */ if (no_rpl) goto resume_script; /* send a 200 OK reply back */ cpl_fct.sigb.reply( msg, 200, &cpl_ok_rpl,NULL); /* I send the reply and I don't want to return to script execution, so * I return 0 to do break */ goto stop_script; } /* is there an ACCEPT hdr ? */ if ( (ret=parse_accept_hdr(msg))<0) goto error; if (ret==0 || (mimes=get_accept(msg))==0 ) /* accept header not present or no mimes found */ goto resume_script; /* looks if the REGISTER accepts cpl-xml or * */ while (*mimes) { LM_DBG("accept mime found %u, %u\n", (*mimes)>>16,(*mimes)&0x00ff); if (*mimes==(TYPE_ALL<<16)+SUBTYPE_ALL || *mimes==(TYPE_APPLICATION<<16)+SUBTYPE_CPLXML ) break; mimes++; } if (*mimes==0) /* no accept mime that matched cpl */ goto resume_script; /* get the user name from msg, retrieve the script from db * and appended to reply */ if (do_script_download( msg )==-1) goto error; /* do I have to send to reply? */ if (no_rpl) goto resume_script; /* send a 200 OK reply back */ cpl_fct.sigb.reply( msg, 200, &cpl_ok_rpl,NULL); stop_script: return 0; resume_script: return 1; error: /* send a error reply back */ cpl_fct.sigb.reply( msg, cpl_err->err_code, &cpl_err->err_msg, NULL); /* I don't want to return to script execution, so I return 0 to do break */ return 0; }