void ZMServer::handleHello() { // just send OK so the client knows all is well // followed by the protocol version we understand string outStr(""); ADD_STR(outStr, "OK"); ADD_STR(outStr, ZM_PROTOCOL_VERSION); send(outStr); }
static dpl_status_t get_delete_data_content(dpl_ctx_t *ctx, dpl_locators_t *locators, dpl_sbuf_t *buffer) { int i; dpl_status_t ret; #define DPL_FN(fn, args...) ({ \ ret = fn(args); \ if (ret != DPL_SUCCESS) \ return ret; \ }) #define ADD_STR(str) DPL_FN(dpl_sbuf_add_str, buffer, str) #define ADD_STR_FMT(fmt, args...) DPL_FN(dpl_sbuf_add_str_fmt, buffer, fmt, args) ADD_STR("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<Delete>\n" " <Quiet>false</Quiet>\n"); for (i = 0; i < locators->size; i++) { dpl_locator_t *locator = &locators->tab[i]; ADD_STR(" <Object>\n"); ADD_STR_FMT(" <Key>%s</Key>\n", locator->name); if (locator->version_id != NULL) ADD_STR_FMT(" <VersionId>%s</VersionId>\n", locator->version_id); ADD_STR(" </Object>\n"); } ADD_STR("</Delete>"); #undef DPL_FN #undef ADD_STR #undef ADD_STR_FMT return DPL_SUCCESS; }
void ZMServer::sendError(string error) { string outStr(""); ADD_STR(outStr, string("ERROR - ") + error); send(outStr); }
/* Caller has to free the return value. */ char *stack_trace(conf_object_t *cpu, int eip, int tid) { char *buf = MM_XMALLOC(MAX_TRACE_LEN, char); int pos = 0, old_pos; int stack_offset = 0; /* Counts by 1 - READ_STACK already multiplies */ ADD_STR(buf, pos, MAX_TRACE_LEN, "TID%d at 0x%.8x in ", tid, eip); ADD_FRAME(buf, pos, MAX_TRACE_LEN, eip); int stop_ebp = 0; int ebp = GET_CPU_ATTR(cpu, ebp); int rabbit = ebp; int frame_count = 0; while (ebp != 0 && (unsigned)ebp < USER_MEM_START && frame_count++ < 1024) { bool extra_frame; do { int eip_offset; bool iret_block = false; extra_frame = false; /* at the beginning or end of a function, there is no * frame, but a return address is still on the stack. */ if (function_eip_offset(eip, &eip_offset)) { if (eip_offset == 0) { extra_frame = true; } else if (eip_offset == 1 && READ_BYTE(cpu, eip - 1) == OPCODE_PUSH_EBP) { stack_offset++; extra_frame = true; } } if (!extra_frame) { int opcode = READ_BYTE(cpu, eip); if (opcode == OPCODE_RET) { extra_frame = true; } else if (opcode == OPCODE_IRET) { iret_block = true; extra_frame = true; } } if (extra_frame) { eip = READ_STACK(cpu, stack_offset); ADD_STR(buf, pos, MAX_TRACE_LEN, "%s0x%.8x in ", STACK_TRACE_SEPARATOR, eip); ADD_FRAME(buf, pos, MAX_TRACE_LEN, eip); if (iret_block) stack_offset += IRET_BLOCK_WORDS; else stack_offset++;; } } while (extra_frame); /* pushed return address behind the base pointer */ eip = READ_MEMORY(cpu, ebp + WORD_SIZE); stack_offset = ebp + 2; ADD_STR(buf, pos, MAX_TRACE_LEN, "%s0x%.8x in ", STACK_TRACE_SEPARATOR, eip); old_pos = pos; ADD_FRAME(buf, pos, MAX_TRACE_LEN, eip); /* special-case termination condition */ if (pos - old_pos >= strlen(ENTRY_POINT) && strncmp(buf + old_pos, ENTRY_POINT, strlen(ENTRY_POINT)) == 0) { break; } if (rabbit != stop_ebp) rabbit = READ_MEMORY(cpu, ebp); if (rabbit == ebp) stop_ebp = ebp; if (rabbit != stop_ebp) rabbit = READ_MEMORY(cpu, ebp); if (rabbit == ebp) stop_ebp = ebp; ebp = READ_MEMORY(cpu, ebp); } char *buf2 = MM_XSTRDUP(buf); /* truncate to save space */ MM_FREE(buf); return buf2; }
int CMakeSip::addAuth(char *un, char *pwd, SIP_MSG *psMsg) { HASHHEX HA1; HASHHEX HA2 = ""; HASHHEX respHex32; HDR_AUT * hdrAuth=&psMsg->hdrProxyAuthen; if (psMsg==NULL || un==NULL || pwd==NULL) return -1; DEBUG_T(0,"add proxy auth"); if(psMsg->sipHdr.dstrStatusCode.uiVal==401) { hdrAuth=&sMsg->hdrWWWAuth; } char *pCNonce=hdrAuth->dstrQOP.strVal?(char *)"6ad34fc1":NULL; char *pNC=(char *)"00000001"; if (false==DigestCalcHA1(hdrAuth,(unsigned char *)un,(unsigned char *)pwd, HA1)) return -2; if (false==DigestCalcResponse(HA1, hdrAuth,psMsg->hdrCSeq.uiMethodID,pCNonce,pNC, &strDstAddr, HA2, respHex32)) return -2; if(psMsg->sipHdr.dstrStatusCode.uiVal==407) { ADD_STR(buf,uiLen,"Proxy-Authorization: "); } else { ADD_STR(buf,uiLen,"Authorization: "); } //" //TODO add MD5 or MD5 sess uiLen+= (unsigned int)sprintf(buf+uiLen, "Digest username=\"%s\", realm=\"%.*s\", nonce=\"%.*s\", uri=\"%.*s\", response=\"%.*s\"" ,un ,D_STR(hdrAuth->dstrRealm) ,D_STR(hdrAuth->dstrNonce) ,strDstAddr.len,strDstAddr.s ,32,respHex32 ); if(hdrAuth->iFlag & 4) { uiLen+= (unsigned int)sprintf(buf+uiLen,", algorithm=%.*s",D_STR(hdrAuth->dstrAlgo)); } if(hdrAuth->iFlag & 128) { uiLen+= (unsigned int)sprintf(buf+uiLen,", opaque=\"%.*s\"",D_STR(hdrAuth->dstrOpaque)); } if(hdrAuth->iFlag & 32) { uiLen+= (unsigned int)sprintf(buf+uiLen,", qop=\"%.*s\"",D_STR(hdrAuth->dstrQOP)); if(pNC) { uiLen+= (unsigned int)sprintf(buf+uiLen,", nc=%s",pNC); } if(pCNonce) { uiLen+= (unsigned int)sprintf(buf+uiLen,", cnonce=%s",pCNonce); } } ADD_CRLF(buf,uiLen); return 0; }
int CMakeSip::makeReq(int id, PHONE_CFG * cfg, ADDR *addrExt,STR_64 *str64ExtADDR) { unsigned int iMeth=0; unsigned int uiFromLoc=0; unsigned int uiFromLen=0; strDstAddr.s=(unsigned char *)&spSes->dstSipAddr.strVal; strDstAddr.len=(int)spSes->dstSipAddr.uiLen; if(cfg){ if(strcmp(&cfg->szSipTransport[0],"TLS")==0){iIsTCP=0;iIsTLS=1;} else if(strcmp(&cfg->szSipTransport[0],"TCP")==0){iIsTCP=1;iIsTLS=0;} else if(strcmp(&cfg->szSipTransport[0],"UDP")==0){iIsTCP=0;iIsTLS=0;} else {iIsTCP=0;iIsTLS=0;} } char *s=buf; int iPrevId=spSes->cs.iSendS; spSes->cs.iSendS=id; if(id!=METHOD_ACK) { if(iPrevId!=spSes->cs.iSendS) { if(spSes->cs.iSendS==METHOD_OPTIONS){ spSes->sSendTo.setRetransmit(2,5*T_GT_SECOND); } else if(iIsTCP || iIsTLS) spSes->sSendTo.setRetransmit(7,5*T_GT_SECOND); else if(spSes->cs.iSendS==METHOD_REGISTER) spSes->sSendTo.setRetransmit(7,1*T_GT_SECOND); else if(spSes->cs.iSendS==METHOD_INVITE) spSes->sSendTo.setRetransmit(7,(cfg==NULL || cfg->iNetworkIsMobile)?(6*T_GT_SECOND):(3*T_GT_SECOND)); else spSes->sSendTo.setRetransmit(); } spSes->cs.iWaitS=200; } else { spSes->cs.iWaitS=0; } //TODO getITFromZZ unsigned int uiCSeq; #if 1 if(cfg && id==METHOD_REGISTER) { if(!cfg->uiSipCSeq){ //next reg should be with greater CSeq, even app restarts, if call-id is same //problem was with SIP Thor on OpenSIPS XS 1.4.5, but not with FreeSwitch int get_time(); cfg->uiSipCSeq=(unsigned int)get_time(); cfg->uiSipCSeq-=1000000000; } cfg->uiSipCSeq++; uiCSeq=(unsigned int)cfg->uiSipCSeq; } else if(spSes){ if(id!=METHOD_ACK && id!=METHOD_CANCEL)spSes->uiSipCseq++; uiCSeq=spSes->uiSipCseq; } else { uiCSeq=getTickCount(); while(uiCSeq>1000000000)uiCSeq-=1000000000; } #else static unsigned int ss=User::TickCount(); ss++; uiCSeq=ss; #endif if(!uiCSeq)uiCSeq=1; int iReplaceRoute=0; if(iContactId >(int)sMsg->hldContact.uiCount) iContactId=0; GET_METH(id,iMeth); //TODO do we need to send route with cancel msg #define METHOD_CANCEL_IGNORE 0 struct HOLDER_CONTACT *hc = &sMsg->hldContact; HLD_ROUTE *hrr = &sMsg->hldRecRoute; //do i need to check "&& spSes->sSIPMsg.hldRecRoute.uiCount"? if(hc->uiCount<1 && spSes && spSes->sSIPMsg.hldContact.uiCount && sMsg->sipHdr.dstrStatusCode.uiVal>=300){ hc = &spSes->sSIPMsg.hldContact; hrr = &spSes->sSIPMsg.hldRecRoute; } if(hc->x[iContactId].sipUri.dstrSipAddr.uiLen && (id & (METHOD_CANCEL_IGNORE|METHOD_REGISTER))==0) { if(hrr->uiCount)//TODO caller calle { iReplaceRoute=!hasRouteLR(hrr,0); } if(iReplaceRoute) { strDstAddr.s=(unsigned char *)hrr->x[0].sipUri.dstrSipAddr.strVal; strDstAddr.len=(int)hrr->x[0].sipUri.dstrSipAddr.uiLen; } else { strDstAddr.s=(unsigned char *)hc->x[iContactId].sipUri.dstrSipAddr.strVal; strDstAddr.len=(int)hc->x[iContactId].sipUri.dstrSipAddr.uiLen; } } //HDR ADD_DSTR(s,uiLen,sip_meth[iMeth]); ADD_CHAR(s,uiLen,' '); ADD_L_STR(s,uiLen,strDstAddr.s, strDstAddr.len);ADD_0_STR(s,uiLen," SIP/2.0\r\n"); switch(id) { case METHOD_INVITE: sMsg->hdrCSeq.dstrID.uiVal=uiCSeq; break; case METHOD_ACK: case METHOD_CANCEL: uiCSeq=sMsg->hdrCSeq.dstrID.uiVal; break; case METHOD_REFER: // ADD_STR(s,uiLen,"Refer-To: <"); //ADD_DSTR(s,uiLen,spSes->str32Forward); //ADD_0_STR(s,uiLen,">\r\n"); break; case METHOD_REGISTER: if(sMsg->hdrCSeq.dstrID.uiVal)uiCSeq=sMsg->hdrCSeq.dstrID.uiVal+1;//ast sMsg->hdrCSeq.dstrID.uiVal=uiCSeq; case METHOD_OPTIONS: ADD_STR(s,uiLen,"Allow: INVITE,ACK,CANCEL,OPTIONS,MESSAGE,BYE,INFO\r\n"); if(id==METHOD_OPTIONS) { ADD_STR(s,uiLen,"Accept: application/sdp, text/plain\r\n"); } break; } //TODO test asterisk add if((id & METHOD_REGISTER) && cfg && !cfg->reg.bUnReg && cfg->iUseOnlyNatIp==0 && sMsg && sMsg->hldVia.x[0].dstrRecived.uiLen<32) { if(sMsg->hldVia.x[0].dstrRecived.strVal && sMsg->hldVia.x[0].dstrRecived.uiLen){ //TODO hi addr if(str64ExtADDR) spSes->pIPVisble=str64ExtADDR; memcpy(spSes->pIPVisble->strVal ,sMsg->hldVia.x[0].dstrRecived.strVal ,sMsg->hldVia.x[0].dstrRecived.uiLen); spSes->pIPVisble->uiLen=sMsg->hldVia.x[0].dstrRecived.uiLen; if(sMsg->hldVia.x[0].dstrRPort.uiVal) spSes->uiUserVisibleSipPort=sMsg->hldVia.x[0].dstrRPort.uiVal; if(addrExt) { addrExt->ip=ipstr2long(sMsg->hldVia.x[0].dstrRecived.uiLen,sMsg->hldVia.x[0].dstrRecived.strVal); SWAP_INT(addrExt->ip); addrExt->setPort((unsigned int)spSes->uiUserVisibleSipPort); } } else if(sMsg->hldVia.x[0].dstrRPort.uiVal){ // printf("[reg rport=%d ]",sMsg->hldVia.x[0].dstrRPort.uiVal); spSes->uiUserVisibleSipPort=sMsg->hldVia.x[0].dstrRPort.uiVal; addrExt->setPort((unsigned int)spSes->uiUserVisibleSipPort); } } if(iIsTCP)ADD_STR(s,uiLen,"Via: SIP/2.0/TCP ") else if(iIsTLS)ADD_STR(s,uiLen,"Via: SIP/2.0/TLS ") else ADD_STR(s,uiLen,"Via: SIP/2.0/UDP ") ADD_DSTR(s,uiLen,(*spSes->pIPVisble)); if(spSes->uiUserVisibleSipPort!=DEAFULT_SIP_PORT) uiLen += sprintf(s + uiLen, ":%u", spSes->uiUserVisibleSipPort); ADD_STR(s,uiLen,";rport"); ADD_STR(s,uiLen,";branch=z9hG4bK"); ADD_L_STR(s,uiLen,sMsg->dstrCallID.strVal,4); if(id!=METHOD_CANCEL) { ADD_L_STR(s,uiLen,s,2); } else { ADD_STR(s,uiLen,"IN"); } uiLen += sprintf(s + uiLen, "%u",uiCSeq^0x123); ADD_CRLF(s,uiLen); uiLen += sprintf(s + uiLen, "CSeq: %u ", uiCSeq); ADD_DSTRCRLF(s,uiLen,sip_meth[iMeth]) if((id & (METHOD_REGISTER|METHOD_CANCEL)) || (spSes->cs.iCaller && (sMsg==NULL || sMsg->hdrCSeq.uiMethodID==0))) { ADD_FSTR(s,uiLen,"From: ",6); { uiFromLoc=uiLen; if(cfg->user.nick[0]){ ADD_CHAR(s,uiLen,'"'); ADD_0_STR(s,uiLen,cfg->user.nick); ADD_CHAR(s,uiLen,'"'); } uiLen+=sprintf(s+uiLen," <%.*s>",D_STR(spSes->userSipAddr)); uiFromLen=uiLen-uiFromLoc; if(spSes->str16Tag.uiLen) { ADD_0_STR(s,uiLen,";tag="); ADD_DSTRCRLF(s,uiLen,spSes->str16Tag); } else ADD_CRLF(s,uiLen); } { if((sMsg->hdrTo.dstrTag.uiLen==0 && id!=METHOD_REGISTER) || (id & METHOD_CANCEL) ) { // puts("a4"); ADD_FSTR(s,uiLen,"To: <",5); //vajag lai straadaatu 3xx vispaar sho laikam jau nevajag, //jo es jau iedoshu liidzi sMsg kuru saneemu if(spSes && spSes->sSIPMsg.hdrTo.sipUri.dstrSipAddr.uiLen==0) { spSes->sSIPMsg.hdrTo.sipUri.dstrSipAddr.strVal= (char *)&spSes->sSIPMsg.rawDataBuffer+spSes->sSIPMsg.uiOffset; ADD_DSTR((char *)&spSes->sSIPMsg.rawDataBuffer, spSes->sSIPMsg.uiOffset,spSes->dstSipAddr); spSes->sSIPMsg.hdrTo.sipUri.dstrSipAddr.uiLen=spSes->dstSipAddr.uiLen; //varbuut sho saglabaat pie get new ses } if(sMsg->hdrTo.sipUri.dstrSipAddr.strVal) { ADD_DSTR(s,uiLen,sMsg->hdrTo.sipUri.dstrSipAddr); } else { ADD_DSTR(s,uiLen,spSes->dstSipAddr); } ADD_FSTR(s,uiLen,">\r\n",3); // puts("a5"); } else if (id==METHOD_REGISTER) { // DEBUG(0,"make register---------") ADD_FSTR(s,uiLen,"To: ",4); memcpy(s+uiLen,s+uiFromLoc,uiFromLen); uiLen+=uiFromLen; ADD_CRLF(s,uiLen); } else { ADD_DSTRCRLF(s,uiLen,sMsg->hdrTo.dstrFullRow); // puts("a6"); } } } else { //TODO use full row // char *pMeth1; // char *pMeth2; DSTR *fromAddr; DSTR *toAddr; DSTR *tag; // puts("a7"); if(sMsg->sipHdr.dstrStatusCode.uiVal) { fromAddr=&sMsg->hdrFrom.sipUri.dstrSipAddr; toAddr=&sMsg->hdrTo.sipUri.dstrSipAddr; tag=&sMsg->hdrTo.dstrTag; // puts("a8"); } else { toAddr=&sMsg->hdrFrom.sipUri.dstrSipAddr; fromAddr=&sMsg->hdrTo.sipUri.dstrSipAddr; tag=&sMsg->hdrFrom.dstrTag; // puts("a9"); } uiLen+=sprintf(s+uiLen,"From: <%.*s>", D_STR(*fromAddr)); if(spSes->str16Tag.uiLen) { ADD_0_STR(s,uiLen,";tag="); ADD_DSTRCRLF(s,uiLen,spSes->str16Tag); } else ADD_CRLF(s,uiLen); uiLen+=sprintf(s+uiLen,"To: <%.*s>", D_STR(*toAddr)); if(tag->uiLen && !fToTagIgnore) { ADD_0_STR(s,uiLen,";tag="); ADD_DSTRCRLF(s,uiLen,(*tag)); } else ADD_CRLF(s,uiLen); } ADD_FSTR(s,uiLen,"Call-ID: ",9); ADD_DSTRCRLF(s,uiLen,sMsg->dstrCallID); ADD_STR(s,uiLen,"Max-Forwards: 70\r\n"); if(id==METHOD_REGISTER){ if(cfg && cfg->szUA[0]){ ADD_STR(s,uiLen,"User-Agent: "); ADD_0_STR(s,uiLen,cfg->szUA);ADD_CRLF(s,uiLen); } else{ ADD_STR(s,uiLen,USER_AGENT); } } if(id != METHOD_CANCEL_IGNORE && (hrr->uiCount || iReplaceRoute))//(toMake & (METHOD_BYE |METHOD_ACK)) && ??? { uiLen+=addRoute(s+uiLen, 255, hrr, "Route: ", !((sMsg->hdrCSeq.uiMethodID && sMsg->sipHdr.dstrStatusCode.uiVal) || (spSes->cs.iCaller && sMsg->hdrCSeq.uiMethodID==0)) ,iReplaceRoute, &hc->x[iContactId].sipUri.dstrSipAddr); } if(id & (METHOD_INVITE | METHOD_OPTIONS |METHOD_MESSAGE |METHOD_REGISTER|METHOD_REFER|METHOD_SUBSCRIBE|METHOD_PUBLISH|METHOD_UPDATE)) { //unsigned int uiPos; if(cfg && cfg->user.nick[0]){ uiLen+=sprintf(s+uiLen,"Contact: \"%s\" <sip:",cfg->user.nick);//sUserCfg.szUserName); } else {ADD_STR(s,uiLen,"Contact: <sip:");} //uiPos=uiLen; //TODO if register store contact addr and use it until next reg if(cfg && (cfg->isOnline() || (id & METHOD_REGISTER))) { if(*cfg->user.nr) uiLen+=sprintf(s+uiLen,"%s@",cfg->user.nr); else if(*cfg->user.un) uiLen+=sprintf(s+uiLen,"%s@",cfg->user.un); } ADD_DSTR(s,uiLen,(*spSes->pIPVisble)); if(spSes->uiUserVisibleSipPort!=DEAFULT_SIP_PORT) uiLen+=sprintf(s+uiLen,":%u",spSes->uiUserVisibleSipPort); if(iIsTCP) {ADD_STR(s,uiLen,";transport=tcp>")}else if(iIsTLS) {ADD_STR(s,uiLen,";transport=tls>")} else { ADD_FSTR(s,uiLen,">",1)}
/* * action_execve adds an exec node to the subgraph and sets WAITLESS_PARENT * to the hash of the arguments. The first node in the child process will * use WAITLESS_PARENT as its first parent node. Note that WAITLESS_PARENT * is intentionally _not_ the same as the exec node; this encodes the idea * that child processes depend on their parent processes only through the * arguments to execve (and the current directory). * * In the case of shared spines (due to pipes or other IPC mechanisms) the * exec node encodes only the path without argv and envp and WAITLESS_PARENT * has the format #id where id is a SYSV shared memory id. This allows further * subgraph nodes from child and parent to be interleaved. Since in the shared * case the child _does_ descend directly from the exec node, an explicit * record of argv and envp would be redundant. */ int action_execve(const char *path, const char *const argv[], const char *const envp[]) { fd_map_dump(); struct process *process = lock_master_process(); int linked = process != process_info(); wlog("exec: linked %d", linked); // Pack all the arguments into a single buffer. The format is // char path[]; // uint32_t argc; // char argv[argc][]; // char is_pipe; // uint32_t envc; // char envp[envc][]; // char cwd[]; // with all strings packed together with terminating nulls. char data[4096]; char *p = data; #define ADD_STR(s) p += strlcpy(p, (s), data+sizeof(data)-p) + 1 ADD_STR(path); // encode argv char *cp = p; p += sizeof(uint32_t); // skip 4 bytes for len(argv) uint32_t i; for (i = 0; argv[i]; i++) ADD_STR(argv[i]); memcpy(cp, &i, sizeof(uint32_t)); *p++ = linked; // encode envp cp = p; p += sizeof(uint32_t); // skip 4 bytes for len(envp) uint32_t count; for (i = 0; envp[i]; i++) if (!startswith(envp[i], "WAITLESS")) { ADD_STR(envp[i]); count++; } memcpy(cp, &count, sizeof(uint32_t)); // encode pwd if (!real_getcwd(p, data+sizeof(data)-p)) die("action_execve: getcwd failed: %s", strerror(errno)); int n = p - data + strlen(p) + 1; #undef ADD_STR // Store exec data and create a corresponding exec node struct hash data_hash; remember_hash_memory(&data_hash, data, n); new_node(process, SG_EXEC, &data_hash); // Add the program to the snapshot struct hash path_hash, program_hash; remember_hash_path(&path_hash, path); struct snapshot_entry *entry = snapshot_update(&program_hash, path, &path_hash, 1); if (entry->writing) die("can't exec '%s' while it is being written", path); // TODO: block instead of dying entry->read = 1; shared_map_unlock(&snapshot); // TODO: Run ldd/otool and hash all shared library dependencies as well // TODO: Complain if the program is statically linked // TODO: If we decide it's worth it, parse #! lines and hash interpreters // too. That seems easy enough to probably be worth it. // If not linked, set parents to the new child values if (!linked) { process->parents.n = 2; process->parents.p[0] = data_hash; process->parents.p[1] = program_hash; } unlock_master_process(); // Update process flags process = lock_process(); int old_flags = process->flags; process->flags = 0; p = rindex(path, '/'); const char *name = p ? p+1 : path; if (!strcmp(name, "as")) process->flags |= HACK_SKIP_O_STAT; else if (strstr(name, "-gcc-")) { for (i = 1; argv[i]; i++) if (!strcmp(argv[i], "-c")) { process->flags |= HACK_SKIP_O_STAT; break; } } unlock_process(); // Do the exec int ret = real_execve(path, argv, envp); // An error must have occurred; reset flags back to old value process = lock_process(); process->flags = old_flags; unlock_process(); return ret; }