コード例 #1
0
ファイル: stunsrv.c プロジェクト: SiteView/UDT-Core-Interface
int icem_stund_recv(struct icem_comp *comp, const struct sa *src,
		    struct stun_msg *req, size_t presz)
{
	struct icem *icem = comp->icem;
	struct ice *ice = icem->ice;
	struct stun_attr *attr;
	struct pl lu, ru;
	enum role rrole = ROLE_UNKNOWN;
	uint64_t tiebrk = 0;
	uint32_t prio_prflx;
	bool use_cand = false;
	int err;

	/* RFC 5389: Fingerprint errors are silently discarded */
	err = stun_msg_chk_fingerprint(req);
	if (err)
		return err;

	err = stun_msg_chk_mi(req, (uint8_t *)ice->lpwd, strlen(ice->lpwd));
	if (err) {
		if (err == EBADMSG)
			goto unauth;
		else
			goto badmsg;
	}

	attr = stun_msg_attr(req, STUN_ATTR_USERNAME);
	if (!attr)
		goto badmsg;

	err = re_regex(attr->v.username, strlen(attr->v.username),
		       "[^:]+:[^]+", &lu, &ru);
	if (err) {
		DEBUG_WARNING("could not parse USERNAME attribute (%s)\n",
			      attr->v.username);
		goto unauth;
	}
	if (pl_strcmp(&lu, ice->lufrag))
		goto unauth;
	if (str_isset(icem->rufrag) && pl_strcmp(&ru, icem->rufrag))
		goto unauth;

	attr = stun_msg_attr(req, STUN_ATTR_CONTROLLED);
	if (attr) {
		rrole = ROLE_CONTROLLED;
		tiebrk = attr->v.uint64;
	}

	attr = stun_msg_attr(req, STUN_ATTR_CONTROLLING);
	if (attr) {
		rrole = ROLE_CONTROLLING;
		tiebrk = attr->v.uint64;
	}

	if (rrole == ice->lrole) {
		if (ice->tiebrk >= tiebrk)
			ice_switch_local_role(ice);
		else
			goto conflict;
	}

	attr = stun_msg_attr(req, STUN_ATTR_PRIORITY);
	if (attr)
		prio_prflx = attr->v.uint32;
	else
		goto badmsg;

	attr = stun_msg_attr(req, STUN_ATTR_USE_CAND);
	if (attr)
		use_cand = true;

	err = handle_stun(ice, icem, comp, src, prio_prflx,
			  use_cand, presz > 0);
	if (err)
		goto badmsg;

	return stun_reply(icem->proto, comp->sock, src, presz, req,
			  (uint8_t *)ice->lpwd, strlen(ice->lpwd), true, 2,
			  STUN_ATTR_XOR_MAPPED_ADDR, src,
			  STUN_ATTR_SOFTWARE, sw);

 badmsg:
	return stunsrv_ereply(comp, src, presz, req, 400, "Bad Request");

 unauth:
	return stunsrv_ereply(comp, src, presz, req, 401, "Unauthorized");

 conflict:
	return stunsrv_ereply(comp, src, presz, req, 487, "Role Conflict");
}
コード例 #2
0
ファイル: test_udp_server.c プロジェクト: roxlu/krx_rtc
int krx_udp_receive(udp_conn* c) {

  socklen_t len = sizeof(c->client);
  ssize_t nread = recvfrom(c->sock, c->buf, KRX_UDP_BUF_LEN, 0, (struct sockaddr*)&c->client, &len);

  if(nread < 0) {
    printf("Error: cannot receive.\n");
    return -1;
  }
  if(nread < 2) { 
    printf("Only received 2 bytes?\n");
    return 0;
  }

  if((c->buf[0] == 0x00 || c->buf[0] == 0x01) && (c->buf[1] == 0x00 || c->buf[1] == 0x01) ) {
    handle_stun(c, c->buf, nread);
  }
  else {
    if(krx_dtls_is_handshake_done(&c->dtls) > 0) {
      if(c->state == KRX_STATE_NONE) {
        // when done, we pass on the data libsrtp

        c->state = KRX_STATE_SSL_INIT_READY;
        printf("---------------------- finished --------------------------\n");
        uint8_t material[KRX_SRTP_MASTER_LEN * 2];
        int r = SSL_export_keying_material(c->dtls.ssl, material, KRX_SRTP_MASTER_LEN * 2, 
                                           "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0);

        if(r == 0) {
          printf("Error: cannot export the SSL keying material.\n");
          exit(EXIT_FAILURE);
        }
        
        // extracking keying example https://github.com/traviscross/baresip/blob/8974d662c942b10a9bb05223ddc7881896dd4c2f/modules/dtls_srtp/tls_udp.c
        /* Keys:: http://tools.ietf.org/html/rfc5764#section-4.2, note: client <> server use different keying, we handle server for now. */
        uint8_t* remote_key = material;
        uint8_t* local_key = remote_key + KRX_SRTP_MASTER_KEY_LEN;
        uint8_t* remote_salt = local_key + KRX_SRTP_MASTER_KEY_LEN;
        uint8_t* local_salt = remote_salt + KRX_SRTP_MASTER_SALT_LEN;;

        memcpy(c->srtp.policy.key, remote_key, KRX_SRTP_MASTER_KEY_LEN);
        memcpy(c->srtp.policy.key + KRX_SRTP_MASTER_KEY_LEN, remote_salt, KRX_SRTP_MASTER_SALT_LEN);

        SRTP_PROTECTION_PROFILE *p = SSL_get_selected_srtp_profile(c->dtls.ssl);
        if(!p) {
          printf("Error: cannot extract the srtp_profile.\n");
          exit(EXIT_FAILURE);
        }
        printf(">>>>>>> %s <<<<<\n", p->name);

        // TLS_RSA_WITH_AES_128_CBC_SHA 
        printf("---> cipher: %s\n", SSL_CIPHER_get_name(SSL_get_current_cipher(c->dtls.ssl)));


        /* create SRTP session */
        err_status_t sr = srtp_create(&c->srtp.session, &c->srtp.policy);
        if(sr != err_status_ok) {
          printf("Error: cannot create srtp session: %d.\n", sr);
          exit(EXIT_FAILURE);
        }

        /* @TODO --- CLEANUP! - WE NEED TO UNPROTECT THIS DIRECTLY!!!  SEE "MARKER-MARKER" below*/
        int buflen = nread;
        sr = srtp_unprotect(c->srtp.session, c->buf, &buflen);
        
        if(sr != err_status_ok) {
          printf("Error: cannot unprotect, err: %d. len: %d <> %d\n", sr, len, buflen);
        }
        else {
          //printf("~ %zd bytes read // buflen: %d.\n", nread, buflen);
          krx_rtp_decode(&c->rtp, c->buf, buflen);
        }

      }
      else if(c->state == KRX_STATE_SSL_INIT_READY) {
        /* @TODO --- CLEANUP! duplicate, see a couple of line above */
        /* MARKER-MARKER */
        int buflen = nread;
        err_status_t sr = srtp_unprotect(c->srtp.session, c->buf, &buflen);
        
        if(sr != err_status_ok) {
          printf("Error: cannot unprotect, err: %d. len: %d <> %d\n", sr, len, buflen);
        }
        else {
          //printf("~ %zd bytes read // buflen: %d.\n", nread, buflen);
          krx_rtp_decode(&c->rtp, c->buf, buflen);
        }

      }
      
    }
    else {
      krx_dtls_handle_traffic(&c->dtls, c->buf, nread);
    }
  }
  return 0;
}