/** * returns x-mapped address buffer */ static char * stun_x_mapped(struct sockaddr_in *saddr) { uint16_t port; uint32_t ip; char *xmapped; ENTER; xmapped = (char *) x_memset(x_malloc(8), 0, 8); xmapped[0] = 0; xmapped[1] = 1; // ipv4 TRACE("MAPPING %s:%d\n", inet_ntoa(saddr->sin_addr), ntohs(saddr->sin_port)); ip = ntohl(saddr->sin_addr.s_addr); port = ntohs(saddr->sin_port); port ^= 0x2112; ip ^= STUN_M_COOKIE; port = htons(port); ip = htonl(ip); x_memcpy(xmapped + 2, &port, 2); x_memcpy(xmapped + 4, &ip, 4); EXIT; return xmapped; }
static char * jingle_get_hmac_sha1(const char *key, int keylen, char *data, int datalen) { unsigned char k_ipad[65]; unsigned char k_opad[65]; SHA1Context sha; SHA1Context sha2; int i; uint8_t Message_Digest[20]; uint8_t *Message_Digest2; md5_state_t state; md5_byte_t digest[16]; md5_byte_t *__key = (md5_byte_t *) key; int __keylen = keylen; x_memset(digest, 0, 16); if (__keylen > 64) { md5_init(&state); md5_append(&state, (const md5_byte_t *) __key, __keylen); md5_finish(&state, digest); __key = digest; __keylen = 16; } x_memset(k_ipad, 0, sizeof(k_ipad)); x_memset(k_opad, 0, sizeof(k_opad)); x_memcpy(k_ipad, __key, __keylen); x_memcpy(k_opad, __key, __keylen); /* XOR key with ipad and opad values */ for (i = 0; i < 64; i++) { k_ipad[i] ^= IPAD; k_opad[i] ^= OPAD; } SHA1Reset(&sha); SHA1Input(&sha, (const uint8_t *) k_ipad, 64); SHA1Input(&sha, (const uint8_t *) data, datalen); SHA1Result(&sha, Message_Digest); Message_Digest2 = x_malloc(20); SHA1Reset(&sha2); SHA1Input(&sha2, (const uint8_t *) k_opad, 64); SHA1Input(&sha2, (const uint8_t *) Message_Digest, 20); SHA1Result(&sha2, Message_Digest2); // TRACE("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n"); //TRACE("HMAC-SHA1: "); // hexdump((char *)Message_Digest2,20); //TRACE("\n"); return (char *) Message_Digest2; }
mib_object_t * MibRegister( ul32 *Id, u16 IdLen, mib_callback_t Rqs, u16 Type, u16 Support, void *Param ) { mib_object_t *object; object = (mib_object_t *)x_malloc(sizeof(mib_object_t)); if (object == 0) { x_dbg("XSNMP, MibRegister: object is 0\n", TRUE); return 0; } if( !IdLen ) x_dbg("XSNMP, MibRegister: Idlen == 0\n", TRUE); object->Id = (ul32 *)x_malloc(IdLen * sizeof(l32)); if (object->Id == 0) { x_dbg("XSNMP, MibRegister: object->ID is 0\n", TRUE); return 0; } x_memcpy(object->Id, Id, IdLen * sizeof(l32)); object->IdLen = IdLen; object->Rqs = Rqs; object->Type = Type; object->Support = Support; object->Param = Param; if (!MibObjectInsert(object)) { x_free(object->Id); x_free(object); x_dbg("XSNMP, MibRegister: MibObjectInsert fail\n", TRUE); return 0; } return object; }
/** * set attribute of type to malloc'ed value copy of val. */ static int stun_set_attr_d(stun_packet_t *pkt, int atype, int len, char *val) { int i; i = stun_attr_id(pkt, atype); //TRACE("))))))))))))))))) 2 i=%d, attrnum(%d)\n",i,(int)pkt->attrnum); if (i < 0) { pkt->attrs = x_realloc(pkt->attrs, sizeof(stun_attr_t) * (pkt->attrnum + 2)); i = pkt->attrnum; } //TRACE("))))))))))))))))) 3\n"); pkt->attrs[i].type = (uint16_t) atype; pkt->attrs[i].len = (uint16_t) len; if (pkt->attrs[pkt->attrnum].len) { // TRACE("))))))))))))))))) 4\n"); pkt->attrs[i].data = x_malloc(pkt->attrs[i].len); x_memcpy(pkt->attrs[pkt->attrnum].data, val, len); } else pkt->attrs[i].data = NULL; // end with NULL pkt->attrs[++pkt->attrnum].type = 0; // TRACE("))))))))))))))))) 5\n"); return 0; }
static stun_hdr_t * stun_add_integrity(stun_hdr_t *pkt, const char *key) { stun_hdr_t *hdr; char *ptr; char *msg_integrity; uint16_t mlen; char tdata[128]; ENTER; mlen = ntohs(pkt->mlen) + sizeof(stun_hdr_t); // TRACE("----------------------- %d (%d,%d) \n", mlen,ntohs(pkt->mlen), sizeof(stun_packet_t)); // add message integrity attribute hdr = x_realloc(pkt, mlen + 24); ptr = ((char *) hdr) + mlen; *(uint16_t*) ptr = htons(STUN_MSG_INTEGRITY); ptr += sizeof(uint16_t); *(uint16_t*) ptr = htons(20); ptr += sizeof(uint16_t); //TRACE("----------------------- %d\n",mlen); mlen += 24; //TRACE("----------------------- %d\n",mlen); hdr->mlen = htons(mlen - sizeof(stun_hdr_t)); //TRACE("----------------------- %d\n",ntohs(hdr->mlen)); x_memset(tdata, 0, sizeof(tdata)); x_memcpy(tdata, hdr, mlen - 24); // Calc Message integrity msg_integrity = jingle_get_hmac_sha1(key, strlen(key), (char *) tdata, mlen - 24); x_memcpy(ptr, msg_integrity, 20); if (msg_integrity) x_free(msg_integrity); EXIT; return hdr; }
virtual udx_address* create(void* addrin, u32 addrinlen) { udx_hash hash = compute_hash(addrin, addrinlen); udx_haddress* h = find_by_hash(hash); if (h == nullptr) { h = (udx_haddress*)m_allocator->alloc(sizeof(udx_haddress)); h->m_hash = hash; h->m_addrin.m_len = addrinlen; x_memcpy(h->m_addrin.m_data, addrin, addrinlen); add(h); } return h; }
static uint32_t stun_get_fingerprint(stun_hdr_t *pkt) { uint32_t crc; uint16_t mlen; unsigned char tdata[128]; ENTER; mlen = ntohs(pkt->mlen) + sizeof(stun_hdr_t); x_memset(tdata, 0, sizeof(tdata)); x_memcpy(tdata, pkt, mlen - 8); crc = chksum_crc32(tdata, mlen - 8); EXIT; return crc; }
/** * set attribute of type to x_malloc'ed value copy of val. */ static stun_hdr_t * stun_hdr_from_packet(stun_packet_t *pkt) { int i; stun_attr_t *attrs = NULL; stun_hdr_t *hdr = NULL; char *ptr = NULL; uint16_t mlen, alen; ENTER; mlen = sizeof(stun_hdr_t); hdr = x_malloc(mlen); x_memset(hdr, 0, mlen); for (attrs = pkt->attrs, i = 0; i < pkt->attrnum; i++) { alen = ADDRLEN_ALIGN(attrs[i].len); hdr = x_realloc(hdr, mlen + alen + 2 * sizeof(uint16_t)); ptr = ((char *) hdr) + mlen; // copy type *(uint16_t*) ptr = htons(attrs[i].type); ptr += sizeof(uint16_t); *(uint16_t*) ptr = htons(attrs[i].len); ptr += sizeof(uint16_t); // copy value x_memcpy(ptr, attrs[i].data, attrs[i].len); mlen += alen + 2 * sizeof(uint16_t); // TRACE("----------------------> %d\n",mlen); } TRACE("--------------------->> %d (%d)\n", mlen, mlen - sizeof(stun_hdr_t)); hdr->mlen = htons(mlen - sizeof(stun_hdr_t)); EXIT; return hdr; }
bool MibInit ( mib_element_t *mib, u16 mibsize ) { i32 commnr, i, n; agent_comm_t *comm; u16 support; mib_community_t *mibprf, *p; mibprf = NULL; commnr = 0; for( n=1, comm = AgentCommunity(n); comm != 0; comm=comm->next, n++) { if( !comm ) { x_dbg("XSNMP, MibInit: no community defined in agent\n", TRUE); } else { switch( comm->access ) { case XSNMP_READ_ONLY: support = MIB_READ; break; case XSNMP_WRITE_ONLY: support = MIB_WRITE; break; case XSNMP_READ_WRITE: support = MIB_READ | MIB_WRITE; break; default: x_dbg("XSNMP, mib: invalid access specified\n", TRUE); break; } if( mibprf ) p = (mib_community_t *)x_realloc(mibprf, (n+1)*sizeof(mib_community_t)); else p = (mib_community_t *)x_malloc(sizeof(mib_community_t)); if( !p ) { x_dbg("XSNMP, MibInit: out of community name space\n", TRUE); } else { mibprf = p; x_bzero( (i8 *)(mibprf[commnr].Comm), SNMP_SIZE_COMM ); x_memcpy((i8 *)mibprf[commnr].Comm, (i8*)comm->comm, comm->commLen); mibprf[commnr].CommLen = comm->commLen; mibprf[commnr].Support = support; commnr++; } } } if(commnr == 0) { x_dbg("XSNMP, mib: no external access possible\n", TRUE); return FALSE; } Mib.Prf = mibprf; Mib.PrfSze = commnr; Mib.Obj = mib; Mib.ObjSze = mibsize; x_qsort((void *)Mib.Prf, Mib.PrfSze, sizeof(mib_community_t), (void *)MibCmpProfil); x_qsort((void *)Mib.Obj, Mib.ObjSze, sizeof(mib_element_t), (void *)MibCmpObject); MibRoot = (mib_root_t *)x_malloc(sizeof(mib_root_t)); if( MibRoot == NULL ) x_dbg("XSNMP, MibInit: could not allocate MibRoot\n", TRUE); MibRoot->Size = 100/*67*/; MibRoot->Count = 0; if( !MibRoot->Size ) x_dbg("XSNMP, MibInit: MibRoot->Size == 0\n", TRUE); MibRoot->Table = (mib_object_t **)x_malloc(MibRoot->Size * sizeof(mib_object_t *)); if( MibRoot->Table == NULL ) x_dbg("XSNMP, MibInit: could not allocate MibRoot\n", TRUE); for (i=0; i<mibsize; i++) { if (!MibRegister(mib[i].Id, mib[i].IdLen, mib[i].Rqs, mib[i].Type, mib[i].Support, 0)) { x_dbg("XSNMP, MibInit: register failed\n", TRUE); break; } } return TRUE; }
static u16 Request( snmp_object_t *Obj, i32 *lastindex ) { i32 mindex, cmp; u16 error; if (MibRoot == NULL) { return SNMP_GENERROR; } error = SNMP_NOSUCHNAME; cmp = MibCmpObjId(MibRoot->Table[*lastindex]->Id, (u16)MibRoot->Table[*lastindex]->IdLen, Obj->Id, (u16)Obj->IdLen); if(cmp == -2 && Obj->Request == SNMP_PDU_NEXT && ++(*lastindex) < MibRoot->Count) { cmp = MibCmpObjId(MibRoot->Table[*lastindex]->Id, (u16)MibRoot->Table[*lastindex]->IdLen, Obj->Id, (u16)Obj->IdLen); } if ( (cmp == -1) || (cmp == 0) ) { mindex = *lastindex; } else { mindex = *lastindex = MibObjectFind(Obj->Id, Obj->IdLen, &cmp); } switch(Obj->Request) { case SNMP_PDU_GET: if( ((cmp != -1) && (cmp != 0)) || MibRoot->Table[mindex]->Rqs == NULL) { return error; } if(!(MibRoot->Table[mindex]->Support & MIB_READ)) { return error; } error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param); if(error == SNMP_NOERROR) { Obj->Type = MibRoot->Table[mindex]->Type; } return error; case SNMP_PDU_SET: if( ((cmp != -1) && (cmp != 0)) || MibRoot->Table[mindex]->Rqs == NULL) { return error; } if(!(MibRoot->Table[mindex]->Support & MIB_WRITE)) { return SNMP_BADVALUE; } if(Obj->Type == SNMP_OBJECTID && Obj->SyntaxLen > SNMP_SIZE_BUFINT) { return SNMP_BADVALUE; } if((Obj->Type == SNMP_OCTETSTR || Obj->Type == SNMP_DISPLAYSTR || Obj->Type == SNMP_OPAQUE) && (Obj->SyntaxLen > SNMP_SIZE_BUFCHR)) { return SNMP_BADVALUE; } error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param); return error; case SNMP_PDU_NEXT: switch(cmp) { case -2: return error; case -1: case 0: if(MibRoot->Table[mindex]->Support & MIB_READ && MibRoot->Table[mindex]->Rqs != NULL) { error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param); if (error == SNMP_NOERROR) { Obj->Type = MibRoot->Table[mindex]->Type; break; } } mindex++; break; } while(error == SNMP_NOSUCHNAME && mindex < MibRoot->Count) { x_memcpy(Obj->Id, MibRoot->Table[mindex]->Id, MibRoot->Table[mindex]->IdLen * sizeof(l32)); Obj->IdLen = MibRoot->Table[mindex]->IdLen; if(MibRoot->Table[mindex]->Support & MIB_READ && MibRoot->Table[mindex]->Rqs != NULL) { error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param); if(error == SNMP_NOERROR) { Obj->Type = MibRoot->Table[mindex]->Type; break; } } mindex++; } return error; case SNMP_PDU_COMMIT: case SNMP_PDU_UNDO: if( ((cmp != -1) && (cmp != 0)) || MibRoot->Table[mindex]->Rqs == NULL) { return error; } error = MibRoot->Table[mindex]->Rqs(Obj, MibRoot->Table[mindex]->IdLen, MibRoot->Table[mindex]->Param); return error; } return SNMP_GENERROR; }
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_rule_line(const Nlm_Char FAR PNTR str, size_t len, enumRuleLine method) { size_t str_len; size_t n_space; /* allocate and initialize the resulting string */ Nlm_CharPtr s = (Nlm_CharPtr) Nlm_MemNew(len + 1); Nlm_MemSet(s, SPACE, len); s[len] = '\0'; /* skip leading and trailing spaces */ while ( IS_WHITESP(*str) ) str++; if ( !*str ) return s; for (str_len = Nlm_StringLen( str ); IS_WHITESP(str[str_len-1]); str_len--) continue; /* truncate the original string if doesn't fit */ if (len <= str_len) { x_memcpy(s, str, len); return s; } n_space = len - str_len; switch ( method ) { case RL_Left: { x_memcpy(s, str, str_len); break; } case RL_Right: { x_memcpy(s + n_space, str, str_len); break; } case RL_Spread: { size_t n_gap = 0; int prev_space = 0; const Nlm_Char FAR PNTR _str = str; size_t i = str_len; for ( ; i--; _str++) { ASSERT ( *_str ); if ( IS_WHITESP(*_str) ) { if ( !prev_space ) { n_gap++; prev_space = 1; } n_space++; } else prev_space = 0; } ASSERT ( !prev_space ); if ( n_gap ) { size_t n_div = n_space / n_gap; size_t n_mod = n_space % n_gap; Nlm_CharPtr _s = s; for (_str = str; *_str; ) { if ( !IS_WHITESP( *_str ) ) *_s++ = *_str++; else if ( n_space ) { size_t n_add = n_div; if (n_mod > 0) { n_add++; n_mod--; } n_space -= n_add; while ( n_add-- ) *_s++ = SPACE; for (_str++; IS_WHITESP(*_str); _str++) continue; } else break; } ASSERT ( _s == s + len ); break; } /* else -- use RL_Center */ } case RL_Center: { x_memcpy(s + n_space/2, str, str_len); break; } default: ASSERT ( 0 ); Nlm_MemFree( s ); return 0; } return s; }
stun_packet_t * stun_packet_from_hdr(stun_hdr_t *req, const char *key) { stun_hdr_t *hdr; stun_packet_t *pkt = NULL; char *ptr = 0; uint16_t tmplen; uint32_t crc; char *msg_integrity; char tdata[128]; ENTER; if (!req) return NULL; pkt = x_malloc(sizeof(stun_packet_t)); pkt->hdr = req; pkt->len = sizeof(stun_hdr_t) + ntohs(req->mlen); TRACE("STUN PACKET: LEN[%d]\n", pkt->len); pkt->attrs = x_malloc(sizeof(stun_attr_t) * 1); pkt->attrnum = 0; pkt->attrs[0].type = 0; // parse attributes for (ptr = ((char *) req) + sizeof(stun_hdr_t); ptr < ((char *) req) + pkt->len;) { pkt->attrs = x_realloc(pkt->attrs, sizeof(stun_hdr_t) * (pkt->attrnum + 2)); pkt->attrs[pkt->attrnum].type = ntohs(*((uint16_t *) ptr)); /* check message integrity */ if (STUN_MSG_INTEGRITY == pkt->attrs[pkt->attrnum].type && key) { TRACE( "Calculating MESSAGE-INTEGRITY with key='%s',keylen(%d),datalen(%d)\n", key, (int)strlen(key), (int)(ptr-(char *)req + 4)); /* setup data */ // _req = (stun_hdr_t *)tdata; tmplen = ptr - (char *) req; x_memset(tdata, 0, sizeof(tdata)); x_memcpy(tdata, (char *) req, tmplen); hdr = (stun_hdr_t *) tdata; hdr->mlen = htons(tmplen - sizeof(stun_hdr_t) + 24); // Test print // hexdump(ptr+4,20); TRACE("MLEN(%d)(%d)(%d)\n", (int)sizeof(stun_hdr_t), (int)tmplen, (int)(tmplen - sizeof(stun_hdr_t) + 24)); // Calc Message integrity msg_integrity = jingle_get_hmac_sha1("1234", 4, (char *) tdata, tmplen); if (msg_integrity) x_free(msg_integrity); } ptr += sizeof(uint16_t); pkt->attrs[pkt->attrnum].len = ntohs(*((uint16_t *) ptr)); ptr += sizeof(uint16_t); // if attribute has value if (pkt->attrs[pkt->attrnum].len) { // copy data pkt->attrs[pkt->attrnum].data = x_malloc( pkt->attrs[pkt->attrnum].len); x_memcpy(pkt->attrs[pkt->attrnum].data, ptr, pkt->attrs[pkt->attrnum].len); ptr += ADDRLEN_ALIGN(pkt->attrs[pkt->attrnum].len); } else pkt->attrs[pkt->attrnum].data = NULL; TRACE("-- ATTRIBUTE, (%d): TYPE[0x%x],LEN[%d],DATA[%s]\n", pkt->attrnum, pkt->attrs[pkt->attrnum].type, pkt->attrs[pkt->attrnum].len, pkt->attrs[pkt->attrnum].data); pkt->attrs[++pkt->attrnum].type = 0; } crc = stun_get_fingerprint(req); TRACE("-- CRC (0x%x[0x%x])\n", crc, crc^STUN_FINGERPRINT_XOR); EXIT; return pkt; }
stun_hdr_t * stun_get_response(const char *stun_key, stun_hdr_t *req, struct sockaddr *saddr) { int i; char *ptr = 0; uint32_t crc; stun_packet_t *pkt, *pkt2; stun_hdr_t *resp = NULL; struct sockaddr_in _sai; ENTER; if (!stun_key || !req || !saddr) return NULL; pkt2 = stun_packet_from_hdr(req, stun_key); if (!pkt2) goto _ret_free_3; pkt = stun_pkt_new(); if (!pkt) goto _ret_free_2; x_memcpy(&_sai, saddr, sizeof(_sai)); // add xmapped // TRACE("\n"); if ((ptr = stun_x_mapped(&_sai))) { stun_set_attr_d(pkt, STUN_X_MAPPED_ADDRESS, 8, ptr); x_free(ptr); } // copy username i = stun_attr_id(pkt2, STUN_USERNAME); if (i >= 0) { TRACE("STUN PACKET ADDING ATTRIBUTE: [%s] %d bytes\n", pkt2->attrs[i].data, pkt2->attrs[i].len); stun_set_attr_d(pkt, STUN_USERNAME, pkt2->attrs[i].len, pkt2->attrs[i].data); } //TRACE("++++++++++=== > stun_hdr_from_packet()\n"); resp = stun_hdr_from_packet(pkt); //TRACE("++++++++++=== < stun_hdr_from_packet()\n"); resp->mcookie = STUN_NET_M_COOKIE; resp->ver_type.raw = htons(STUN_RESP); // copy transction id x_memcpy(resp->trans_id, req->trans_id, 12); resp = stun_add_integrity(resp, stun_key); // TRACE("REPLYING STUN2 HEADER: "); i = ntohs(resp->mlen); // hexdump((char *)resp,i + 20); // TRACE("\n"); // TRACE("STUN2 MLEN=%d\n",i); // _stun_packet_printf(pkt); // add CRC32 i = ntohs(resp->mlen) + sizeof(stun_hdr_t); resp = x_realloc(resp, i + 8); resp->mlen = htons(i + 8 - sizeof(stun_hdr_t)); crc = stun_get_fingerprint(resp); ptr = (char *) resp + i; *(uint16_t *) ptr = htons(STUN_FINGERPRINT); ptr += sizeof(uint16_t); *(uint16_t *) ptr = htons(4); ptr += sizeof(uint16_t); *(uint32_t *) ptr = htonl(crc ^ STUN_FINGERPRINT_XOR); if (pkt) stun_pkt_free(pkt); _ret_free_2: if (pkt2) stun_pkt_free(pkt2); _ret_free_3: EXIT; return resp; }