示例#1
0
文件: zrtp.c 项目: dormclub/tjphone
static int ozrtp_rtcp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){
	ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
	OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;

	int rlen = rtp_session_rtp_recv_abstract(t->session->rtcp.socket,m,flags,from,fromlen);
	if (rlen<=0) {
		// nothing was received or error: pass the information to caller
		return rlen;
	}

	if (userData->srtpRecv != NULL && zrtp_inState(zrtpContext, SecureState)) {
		err_status_t err = srtp_unprotect_rtcp(userData->srtpRecv,m->b_wptr,&rlen);
		if (err != err_status_ok) {
			ortp_error("srtp_unprotect failed %d ; packet discarded (may be plain RTCP)", err);
			return 0;
		}
	}

	return rlen;
}
示例#2
0
/*
 * get_info() is called to get the transport addresses to be put
 * in SDP c= line and a=rtcp line.
 */
static pj_status_t transport_get_info(pjmedia_transport *tp,
                                      pjmedia_transport_info *info)
{
    struct tp_zrtp *zrtp = (struct tp_zrtp*)tp;
    pjmedia_zrtp_info zrtp_info;
    int spc_info_idx;

    PJ_ASSERT_RETURN(tp && info, PJ_EINVAL);
    PJ_ASSERT_RETURN(info->specific_info_cnt <
                     PJMEDIA_TRANSPORT_SPECIFIC_INFO_MAXCNT, PJ_ETOOMANY);

    zrtp_info.active = zrtp_inState(zrtp->zrtpCtx, SecureState) ? PJ_TRUE : PJ_FALSE;

    spc_info_idx = info->specific_info_cnt++;
    info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_ZRTP;

    pj_memcpy(&info->spc_info[spc_info_idx].buffer, &zrtp_info,
              sizeof(zrtp_info));

    return pjmedia_transport_get_info(zrtp->slave_tp, info);
}
示例#3
0
zrtp_state_info jzrtp_getInfoFromContext(struct jzrtp_allContext ac){
	zrtp_state_info info;
	info.sas.slen = 0;
	info.sas.ptr = "";
	info.sas_verified = PJ_FALSE;
	info.cipher.slen = 0;
	info.cipher.ptr = "";
	info.secure = PJ_FALSE;
	info.call_id = PJSUA_INVALID_ID;
	//PJ_LOG(4, (THIS_FILE, "jzrtp_getInfoFromContext : user data %x", ac.cbUserData));
	if(ac.zrtpContext != NULL){
		int32_t state = zrtp_inState(ac.zrtpContext, SecureState);
		info.secure = state ? PJ_TRUE : PJ_FALSE;
		if(ac.cbUserData){
			info.sas_verified = ac.cbUserData->sas_verified;
			info.call_id = ac.cbUserData->call_id;
			pj_strassign(&info.sas, &ac.cbUserData->sas);
			pj_strassign(&info.cipher, &ac.cbUserData->cipher);
		}

	}
	return info;
}
示例#4
0
static int ozrtp_generic_sendto(stream_type stream, RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){
	int slen;
	err_status_t err;
	ortp_socket_t socket;

	ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
	OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;


	if (stream == rtp_stream) {
		socket= t->session->rtp.socket;
	} else {
		socket= t->session->rtcp.socket;
	}

	if (userData->srtpSend == NULL || !zrtp_inState(zrtpContext, SecureState)) {
		int size;
		msgpullup(m,-1);
		size=msgdsize(m);
		return sendto(socket,(void*)m->b_rptr,size,flags,to,tolen);
	}
	slen=msgdsize(m);
	// Protect with srtp
	/* enlarge the buffer for srtp to write its data */
	msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES);
	if (stream == rtp_stream) {
		err=srtp_protect(userData->srtpSend,m->b_rptr,&slen);
	} else {
		err=srtp_protect_rtcp(userData->srtpSend,m->b_rptr,&slen);
	}
	if (err==err_status_ok){
		return sendto(socket,(void*)m->b_rptr,slen,flags,to,tolen);
	} else {
		ortp_error("srtp_protect() failed with status %d", err);
	}
	return -1;
}
示例#5
0
pj_str_t jzrtp_getInfo(pjmedia_transport* tp) {
    pj_str_t result;

    char msg[512];

    ZrtpContext *ctx = pjmedia_transport_zrtp_getZrtpContext(tp);
    int32_t state = zrtp_inState(ctx, SecureState);

    zrtp_cb_user_data* zrtp_cb_data = (zrtp_cb_user_data*) pjmedia_transport_zrtp_getUserData(tp);

    if (state) {
        pj_ansi_snprintf(msg, sizeof(msg), "ZRTP - %s\n%.*s\n%.*s", "OK",
                         zrtp_cb_data->sas.slen, zrtp_cb_data->sas.ptr,
                         zrtp_cb_data->cipher.slen, zrtp_cb_data->cipher.ptr);
    } else {
        pj_ansi_snprintf(msg, sizeof(msg), "");
    }
    pj_strdup2_with_null(css_var.pool, &result, msg);


    PJ_LOG(4, (THIS_FILE, "ZRTP getInfos : %s", msg));

    return result;
}
示例#6
0
static int ozrtp_rtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){
	int rlen;

	ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
	OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;


	// Do extra stuff first
	check_timer(zrtpContext, userData);


	// Check if something to receive
	rlen=rtp_session_rtp_recv_abstract(t->session->rtp.socket,m,flags,from,fromlen);
	if (rlen<=0) {
		// nothing was received or error: pass the information to caller
		return rlen;
	}

	uint8_t* rtp = m->b_rptr;
	int rtpVersion = ((rtp_header_t*)rtp)->version;

	// If plain or secured RTP
	if (rtpVersion == 2) {
		if (userData->srtpRecv != NULL && zrtp_inState(zrtpContext, SecureState)) {
			// probably srtp packet, unprotect
			err_status_t err = srtp_unprotect(userData->srtpRecv,m->b_wptr,&rlen);
			if (err != err_status_ok) {
				ortp_warning("srtp_unprotect failed; packet may be plain RTP");
			}
		}
		// in both cases (RTP plain and deciphered srtp)
		return rlen;
	}


	// if ZRTP packet, send to engine
	uint32_t *magicField=(uint32_t *)(rtp + 4);
	if (rlen >= ZRTP_MIN_MSG_LENGTH && rtpVersion==0 && ntohl(*magicField) == ZRTP_MAGIC) {
		print_zrtp_packet("received", rtp);
		uint8_t *ext_header = rtp+ZRTP_MESSAGE_OFFSET;
		uint16_t ext_length = get_zrtp_message_length(ext_header);
		char messageType[9];
		parseZrtpMessageType(messageType, ext_header);

		// Check max length
		if (rlen < 12 + ext_length + 4) {
			ortp_warning("Received malformed ZRTP-like packet: size %d (expected %d)", rlen, 12 + ext_length + 4);
			return 0;
		}

		// Check sequence number
		uint16_t seq_number = get_rtp_seqnumber(rtp);
		if (userData->last_recv_zrtp_seq_number != 0 && seq_number <= userData->last_recv_zrtp_seq_number) {
			// Discard out of order ZRTP packet
			ortp_message("Discarding received out of order zrtp packet: %d (expected >%d)",
					seq_number, userData->last_recv_zrtp_seq_number);
			return 0;
		}


		// Check packet checksum
		uint32_t rcv_crc = get_zrtp_packet_crc((uint32_t*)rtp, ext_length);
		uint32_t zrtp_total_packet_length = ZRTP_MESSAGE_OFFSET + 4*ext_length + 4;
		if (!zrtp_CheckCksum(rtp, zrtp_total_packet_length-CRC_SIZE, rcv_crc)) {
			ortp_warning("Bad ZRTP packet checksum %u total %u", rcv_crc, zrtp_total_packet_length);
			return 0;
		}

		uint32_t peerssrc = ntohl(*(uint32_t*)(rtp+8));
#if HAVE_zrtpcpp_with_len
		zrtp_processZrtpMessage(zrtpContext, ext_header, peerssrc,rlen);
#else
		zrtp_processZrtpMessage(zrtpContext, ext_header, peerssrc);
#endif
		userData->last_recv_zrtp_seq_number=seq_number;
		return 0;
		}
	else {
		// Not a ZRTP packet, accept it
		return rlen;
	}
}