Recheck and implement missing features in Acive-Passive logs

(closes #23)
This commit is contained in:
Viktor Krikun 2011-11-19 13:40:00 +00:00 committed by Travis Cross
parent fc97a91993
commit c74f85f7ab
12 changed files with 233 additions and 43 deletions

View File

@ -115,6 +115,24 @@ typedef enum zrtp_license_mode_t
ZRTP_LICENSE_MODE_UNLIMITED ZRTP_LICENSE_MODE_UNLIMITED
} zrtp_license_mode_t; } zrtp_license_mode_t;
/**
* @brief Enumeration to define Signaling initiator/responder roles.
*
* Used by libzrtp to optimize some internal processes and protocol handshake.
*
* @sas zrtp_stream_start().
*/
typedef enum zrtp_signaling_role_t
{
/** @brief Unknown Signaling role, should be used when the app can't determine the role. */
ZRTP_SIGNALING_ROLE_UNKNOWN = 0,
/** @brief Signaling Initiator. */
ZRTP_SIGNALING_ROLE_INITIATOR,
/** @brief Signaling Responder. */
ZRTP_SIGNALING_ROLE_RESPONDER,
ZRTP_SIGNALING_ROLE_COUNT
} zrtp_signaling_role_t;
/** @brief 12-byte ZID for unique ZRTP endpoint identification. */ /** @brief 12-byte ZID for unique ZRTP endpoint identification. */
typedef unsigned char zrtp_zid_t[12]; typedef unsigned char zrtp_zid_t[12];
@ -123,9 +141,9 @@ typedef unsigned char zrtp_zid_t[12];
typedef char zrtp_client_id_t[16]; typedef char zrtp_client_id_t[16];
/** /**
* \brief ZRTP global configuration options * @brief ZRTP global configuration options
* \ingroup zrtp_main_init * @ingroup zrtp_main_init
* \warning Use \ref zrtp_config_defaults() before start configuring this structure. * @warning Use \ref zrtp_config_defaults() before start configuring this structure.
*/ */
typedef struct zrtp_config_t typedef struct zrtp_config_t
{ {
@ -431,10 +449,9 @@ zrtp_status_t zrtp_down(zrtp_global_t* zrtp);
* \param profile - the session configuration profile. If value of this parameter is NULL, default * \param profile - the session configuration profile. If value of this parameter is NULL, default
* profile will be used. NULL profile usage is equivalent to calling zrtp_profile_defaults(). * profile will be used. NULL profile usage is equivalent to calling zrtp_profile_defaults().
* \param zid - ZRTP peer identificator. * \param zid - ZRTP peer identificator.
* \param is_initiator - identifies if the endpoint was the signaling initiator of the call. Used to * \param role - identifies if the endpoint was the signaling initiator of the call. Used to
* provide Passive Mode options to the developer. If your application doesn't control signaling * provide Passive Mode options to the developer. If your application doesn't control signaling
* or you don't want to support Passive Mode features - set this flag to 1. Check \ref XXX for * or you don't want to support Passive Mode features - set it to ZRTP_SIGNALING_ROLE_UNKNOWN.
* more information.
* \param session - allocated session structure. * \param session - allocated session structure.
* \return * \return
* - zrtp_status_ok if initialization is successful; * - zrtp_status_ok if initialization is successful;
@ -444,7 +461,7 @@ zrtp_status_t zrtp_down(zrtp_global_t* zrtp);
zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp, zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp,
zrtp_profile_t* profile, zrtp_profile_t* profile,
zrtp_zid_t zid, zrtp_zid_t zid,
uint8_t is_initiator, zrtp_signaling_role_t role,
zrtp_session_t **session); zrtp_session_t **session);
/** /**
* \brief ZRTP Session context deinitialization * \brief ZRTP Session context deinitialization
@ -461,8 +478,8 @@ void zrtp_session_down(zrtp_session_t *session);
/** /**
* \brief Obtain information about ZRTP session * \brief Obtain information about ZRTP session
* *
* Function initialize and fills all fields of zrtp_session_info_t structure accordint to * Function initialize and fills all fields of zrtp_session_info_t structure according to
* current state of ZRTP session. * the current state of ZRTP session.
* *
* \param session - zrtp session which parameters should be extracted; * \param session - zrtp session which parameters should be extracted;
* \param info - out structure to be initialized. * \param info - out structure to be initialized.
@ -530,7 +547,8 @@ zrtp_status_t zrtp_stream_attach(zrtp_session_t *session, zrtp_stream_t** stream
* - \ref XXX_GUIDE_CB \ref XXX_GUIDE_MANAGEMENT * - \ref XXX_GUIDE_CB \ref XXX_GUIDE_MANAGEMENT
* - zrtp_stream_stop() zrtp_stream_secure() zrtp_stream_clear() * - zrtp_stream_stop() zrtp_stream_secure() zrtp_stream_clear()
*/ */
zrtp_status_t zrtp_stream_start(zrtp_stream_t* stream, uint32_t ssrc); zrtp_status_t zrtp_stream_start(zrtp_stream_t* stream,
uint32_t ssrc);
/** /**
* \brief ZRTP protocol stopping * \brief ZRTP protocol stopping
@ -751,7 +769,7 @@ zrtp_status_t zrtp_process_srtcp( zrtp_stream_t *stream,
/* \} */ /* \} */
/** /**
* \defgroup zrtp_main_utils Utilites * \defgroup zrtp_main_utils Utilities
* \ingroup zrtp_api * \ingroup zrtp_api
* \{ * \{
*/ */
@ -768,7 +786,7 @@ zrtp_status_t zrtp_process_srtcp( zrtp_stream_t *stream,
* starting the protocol from the ZRTP_STATE_ACTIVE state. * starting the protocol from the ZRTP_STATE_ACTIVE state.
* *
* \param stream - stream for operating with; * \param stream - stream for operating with;
* \param hash_buff - signaling hash buffer. Function accpt string, not a binary value!; * \param hash_buff - signaling hash buffer. Function accepts string, not a binary value!;
* \param hash_buff_length - signaling hash length in bytes (must be 64 bytes); * \param hash_buff_length - signaling hash length in bytes (must be 64 bytes);
* \return: * \return:
* - zrtp_status_ok if the operation finished successfully * - zrtp_status_ok if the operation finished successfully

View File

@ -58,7 +58,7 @@ extern "C"
*/ */
#define ZRTP_PASSIVE2_TEST(stream) \ #define ZRTP_PASSIVE2_TEST(stream) \
( !((ZRTP_LICENSE_MODE_PASSIVE == stream->zrtp->lic_mode) && \ ( !((ZRTP_LICENSE_MODE_PASSIVE == stream->zrtp->lic_mode) && \
stream->session->is_initiator) ) (stream->session->signaling_role == ZRTP_SIGNALING_ROLE_INITIATOR)) )
/** /**
* @brief Test Passive Rule N3 * @brief Test Passive Rule N3
@ -128,7 +128,7 @@ zrtp_status_t _zrtp_protocol_decrypt( zrtp_protocol_t *self,
/*===========================================================================*/ /*===========================================================================*/
/* CRTPTO Utilites */ /* CRTPTO Utilities */
/*===========================================================================*/ /*===========================================================================*/
/** /**
@ -237,7 +237,7 @@ int _zrtp_can_start_stream( zrtp_stream_t* stream,
zrtp_stream_t** conc, zrtp_stream_t** conc,
zrtp_stream_mode_t mode); zrtp_stream_mode_t mode);
/** Return ZRTP Stream mode which sould be used for current stream. */ /** Return ZRTP Stream mode which should be used for current stream. */
zrtp_stream_mode_t _zrtp_define_stream_mode(zrtp_stream_t* stream); zrtp_stream_mode_t _zrtp_define_stream_mode(zrtp_stream_t* stream);
/*! /*!
@ -257,7 +257,7 @@ uint8_t _zrtp_choose_best_comp( zrtp_profile_t* profile,
/*! /*!
* \brief Computes replay timeouts * \brief Computes replay timeouts
* This function computes messages replays schedule. There are some recomended * This function computes messages replays schedule. There are some recommended
* values by ZRTP specification, but in some network environments values may be * values by ZRTP specification, but in some network environments values may be
* sligh different * sligh different
*/ */

View File

@ -143,6 +143,14 @@ const char* zrtp_log_mode2str(zrtp_stream_mode_t mode);
/** Returns symbolical name of the protocol and security events. */ /** Returns symbolical name of the protocol and security events. */
const char* zrtp_log_event2str(uint8_t event); const char* zrtp_log_event2str(uint8_t event);
/**
* Returns character name of the Signaling role.
*
* @param role One of zrtp_signaling_role_t values.
* @return character name of the \c role.
*/
const char* zrtp_log_sign_role2str(unsigned role);
/** Print out ZRTP environment configuration setting to log level 3. */ /** Print out ZRTP environment configuration setting to log level 3. */
void zrtp_print_env_settings(); void zrtp_print_env_settings();

View File

@ -91,6 +91,19 @@ zrtp_status_t zrtp_register_with_trusted_mitm(zrtp_stream_t* stream);
* \ref XXX_DRAFT, XXX_GUIDE * \ref XXX_DRAFT, XXX_GUIDE
*/ */
zrtp_status_t zrtp_resolve_mitm_call(zrtp_stream_t* stream1, zrtp_stream_t* stream2); zrtp_status_t zrtp_resolve_mitm_call(zrtp_stream_t* stream1, zrtp_stream_t* stream2);
/**
* @brief Links two lags of Trusted ZRTP MiTM call together.
*
* This function allows libzrtp2 to optimize protocol behavior of one leg depending on the state and
* parameters of the other lag. MitM boxes should use this API whenever possible.
*
* @param stream1 - one leg of the trusted MiTM call;
* @param stream2 - another leg of the trusted MiTM call.
*
* @return zrtp_status_ok in case of success.
*/
zrtp_status_t zrtp_link_mitm_calls(zrtp_stream_t* stream1, zrtp_stream_t* stream2);
/** /**
* \brief Updates remote-side SAS value and rendering scheme * \brief Updates remote-side SAS value and rendering scheme

View File

@ -282,7 +282,8 @@ typedef struct zrtp_packet_Hello
/** Signature support flag */ /** Signature support flag */
uint8_t sigflag:1; uint8_t sigflag:1;
uint8_t padding1:1;
uint8_t uflag:1;
/** Hash scheme count */ /** Hash scheme count */
uint8_t hc:4; uint8_t hc:4;
@ -300,7 +301,7 @@ typedef struct zrtp_packet_Hello
/** PK Type count */ /** PK Type count */
uint8_t kc:4; uint8_t kc:4;
#elif ZRTP_BYTE_ORDER == ZBO_BIG_ENDIAN #elif ZRTP_BYTE_ORDER == ZBO_BIG_ENDIAN
uint8_t padding1:1; uint8_t uflag:1;
uint8_t sigflag:1; uint8_t sigflag:1;
uint8_t mitmflag:1; uint8_t mitmflag:1;
uint8_t pasive:1; uint8_t pasive:1;
@ -400,7 +401,7 @@ typedef struct zrtp_packet_Confirm
/** Unused (Set to zero and ignored) */ /** Unused (Set to zero and ignored) */
uint8_t pad[2]; uint8_t pad[2];
/** Length of optionas signature field */ /** Length of optional signature field */
uint8_t sig_length; uint8_t sig_length;
/** boolean flags for allowclear, SAS verified and disclose */ /** boolean flags for allowclear, SAS verified and disclose */
@ -478,7 +479,7 @@ typedef struct
zrtp_msg_hdr_t hdr; zrtp_msg_hdr_t hdr;
zrtp_uchar4_t version; /** Zfone discovery protocol version */ zrtp_uchar4_t version; /** Zfone discovery protocol version */
zrtp_uchar8_t endpointhash; /** Zfone endpoint unique identifier */ zrtp_uchar8_t endpointhash; /** Zfone endpoint unique identifier */
zrtp_uchar8_t peerendpointhash; /** EndpointHash copied from Ping message */ zrtp_uchar8_t peerendpointhash; /** EndpointHash copied from Ping message */
uint32_t peerssrc; uint32_t peerssrc;
} zrtp_packet_zfonepingack_t; } zrtp_packet_zfonepingack_t;

View File

@ -51,7 +51,7 @@ typedef enum zrtp_state_t
ZRTP_STATE_PENDINGCLEAR, /** CLEAR request have been received */ ZRTP_STATE_PENDINGCLEAR, /** CLEAR request have been received */
ZRTP_STATE_INITIATINGERROR, /** Protocol ERROR detected on local side */ ZRTP_STATE_INITIATINGERROR, /** Protocol ERROR detected on local side */
ZRTP_STATE_PENDINGERROR, /** Protocol ERROR received from the remote peer */ ZRTP_STATE_PENDINGERROR, /** Protocol ERROR received from the remote peer */
ZRTP_STATE_ERROR, /** Protcol ERROR state. Check zrtp_stream_info#last_error*/ ZRTP_STATE_ERROR, /** Protocol ERROR state. Check zrtp_stream_info#last_error*/
#if (defined(ZRTP_BUILD_FOR_CSD) && (ZRTP_BUILD_FOR_CSD == 1)) #if (defined(ZRTP_BUILD_FOR_CSD) && (ZRTP_BUILD_FOR_CSD == 1))
ZRTP_STATE_DRIVEN_INITIATOR, ZRTP_STATE_DRIVEN_INITIATOR,
ZRTP_STATE_DRIVEN_RESPONDER, ZRTP_STATE_DRIVEN_RESPONDER,
@ -404,7 +404,7 @@ struct zrtp_global_t
/** This object is used to synchronize sessions list operations */ /** This object is used to synchronize sessions list operations */
zrtp_mutex_t* sessions_protector; zrtp_mutex_t* sessions_protector;
/** Set of feedback callbacks used by libzrtp to interact witrh the user-space.*/ /** Set of feedback callbacks used by libzrtp to interact with the user-space.*/
zrtp_callback_t cb; zrtp_callback_t cb;
}; };
@ -471,7 +471,7 @@ typedef struct zrtp_secrets_t
uint32_t wrongs; uint32_t wrongs;
uint32_t wrongs_curr; uint32_t wrongs_curr;
/** This flag equals one iff the secrets have been uploaded from the cache. */ /** This flag equals one if the secrets have been uploaded from the cache. */
uint8_t is_ready; uint8_t is_ready;
} zrtp_secrets_t; } zrtp_secrets_t;
@ -543,7 +543,7 @@ typedef struct zrtp_dh_crypto_context_t
/** DH public value */ /** DH public value */
struct BigNum pv; struct BigNum pv;
/** DH public value precalculated for remote side */ /** DH public value recalculated for remote side */
struct BigNum peer_pv; struct BigNum peer_pv;
/** DH shared secret. DHSS = hash(DHResult) */ /** DH shared secret. DHSS = hash(DHResult) */
@ -742,7 +742,7 @@ struct zrtp_stream_t
uint8_t allowclear; uint8_t allowclear;
/*! /*!
* This flag shows when remote side is "pasice" (has license mode PASSIVE) * This flag shows when remote side is "passive" (has license mode PASSIVE)
* Available for reading in CLEAR state. * Available for reading in CLEAR state.
*/ */
uint8_t peer_passive; uint8_t peer_passive;
@ -780,6 +780,11 @@ struct zrtp_stream_t
*/ */
uint8_t peer_mitm_flag; uint8_t peer_mitm_flag;
/**
* Duplicates U flag from peer Hello message
*/
uint8_t peer_super_flag;
/*! /*!
* \brief Pointer to the concurrent DH stream * \brief Pointer to the concurrent DH stream
* If Commit messages are sent by both ZRTP endpoints at the same time, but * If Commit messages are sent by both ZRTP endpoints at the same time, but
@ -796,7 +801,7 @@ struct zrtp_stream_t
/** Back-pointer to the ZRTP global data */ /** Back-pointer to the ZRTP global data */
zrtp_global_t *zrtp; zrtp_global_t *zrtp;
/** Pointer to paren t-session context. Used for back capability */ /** Pointer to parent session context. Used for back capability */
zrtp_session_t *session; zrtp_session_t *session;
/*!< Public key exchange component used within current stream */ /*!< Public key exchange component used within current stream */
@ -808,6 +813,12 @@ struct zrtp_stream_t
*/ */
void *usr_data; void *usr_data;
/*!
* Pointer to the peer stream during a trusted MiTM call.
* @sa zrtp_link_mitm_calls()
*/
zrtp_stream_t *linked_mitm;
/*! /*!
* \brief Stream data protector * \brief Stream data protector
* A mutex is used to avoid race conditions during asynchronous calls * A mutex is used to avoid race conditions during asynchronous calls
@ -846,11 +857,13 @@ struct zrtp_session_t
*/ */
zrtp_string16_t peer_zid; zrtp_string16_t peer_zid;
/*!< ZRTP profile, defined crypto options and behavior for every stream within cirrent session */ /*!< ZRTP profile, defined crypto options and behavior for every stream within current session */
zrtp_profile_t profile; zrtp_profile_t profile;
/** Define endpoint Signaling role. Different from ZRTP Initiator/Responder role */ /*
uint8_t is_initiator; * Signaling Role which protocol was started with, one of zrtp_signaling_role_t values.
*/
unsigned signaling_role;
/*! /*!
* \brief Set of retained secrets and flags for the current ZRTP session. * \brief Set of retained secrets and flags for the current ZRTP session.
@ -859,7 +872,7 @@ struct zrtp_session_t
*/ */
zrtp_secrets_t secrets; zrtp_secrets_t secrets;
/*!< ZRTP session key used to extand ZRTP session without additional DH exchange */ /*!< ZRTP session key used to extend ZRTP session without additional DH exchange */
zrtp_string64_t zrtpsess; zrtp_string64_t zrtpsess;
/** First SAS base32/256 string */ /** First SAS base32/256 string */

View File

@ -413,7 +413,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = { 08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 0410; LastUpgradeCheck = 0420;
}; };
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "libzrtp" */; buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "libzrtp" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";

View File

@ -72,7 +72,7 @@ zrtp_status_t zrtp_init(zrtp_config_t* config, zrtp_global_t** zrtp)
return zrtp_status_alloc_fail; return zrtp_status_alloc_fail;
} }
zrtp_memset(new_zrtp, 0, sizeof(zrtp_global_t)); zrtp_memset(new_zrtp, 0, sizeof(zrtp_global_t));
/* /*
* Apply configuration according to the config * Apply configuration according to the config
*/ */
@ -188,7 +188,7 @@ zrtp_status_t zrtp_down(zrtp_global_t* zrtp)
zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp, zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp,
zrtp_profile_t* profile, zrtp_profile_t* profile,
zrtp_zid_t zid, zrtp_zid_t zid,
uint8_t is_initiator, zrtp_signaling_role_t role,
zrtp_session_t **session) zrtp_session_t **session)
{ {
uint32_t i = 0; uint32_t i = 0;
@ -243,6 +243,7 @@ zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp,
ZRTP_LOG(3, (_ZTU_," allowclear: %s\n", profile->allowclear?"ON":"OFF")); ZRTP_LOG(3, (_ZTU_," allowclear: %s\n", profile->allowclear?"ON":"OFF"));
ZRTP_LOG(3, (_ZTU_," autosecure: %s\n", profile->autosecure?"ON":"OFF")); ZRTP_LOG(3, (_ZTU_," autosecure: %s\n", profile->autosecure?"ON":"OFF"));
ZRTP_LOG(3, (_ZTU_," disclose_bit: %s\n", profile->disclose_bit?"ON":"OFF")); ZRTP_LOG(3, (_ZTU_," disclose_bit: %s\n", profile->disclose_bit?"ON":"OFF"));
ZRTP_LOG(3, (_ZTU_," signal. role: %s\n", zrtp_log_sign_role2str(role)));
ZRTP_LOG(3, (_ZTU_," TTL: %u\n", profile->cache_ttl)); ZRTP_LOG(3, (_ZTU_," TTL: %u\n", profile->cache_ttl));
ZRTP_LOG(3, (_ZTU_," SAS schemes: ")); ZRTP_LOG(3, (_ZTU_," SAS schemes: "));
@ -280,7 +281,7 @@ zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp,
zrtp_zstrncpyc(ZSTR_GV(new_session->zid), (const char*)zid, sizeof(zrtp_zid_t)); zrtp_zstrncpyc(ZSTR_GV(new_session->zid), (const char*)zid, sizeof(zrtp_zid_t));
new_session->zrtp = zrtp; new_session->zrtp = zrtp;
new_session->is_initiator = is_initiator; new_session->signaling_role = role;
new_session->mitm_alert_detected = 0; new_session->mitm_alert_detected = 0;
/* /*
@ -356,7 +357,8 @@ void zrtp_session_down(zrtp_session_t *session)
/* Stop ZRTP engine and clear all crypto sources for every stream in the session. */ /* Stop ZRTP engine and clear all crypto sources for every stream in the session. */
zrtp_mutex_lock(session->streams_protector); zrtp_mutex_lock(session->streams_protector);
for(i=0; i<ZRTP_MAX_STREAMS_PER_SESSION; i++) { for(i=0; i<ZRTP_MAX_STREAMS_PER_SESSION; i++) {
zrtp_stream_stop(&session->streams[i]); zrtp_stream_t *the_stream = &session->streams[i];
zrtp_stream_stop(the_stream);
} }
zrtp_mutex_unlock(session->streams_protector); zrtp_mutex_unlock(session->streams_protector);
@ -437,7 +439,7 @@ zrtp_status_t zrtp_stream_attach(zrtp_session_t *session, zrtp_stream_t** stream
new_stream->dh_cc.initialized_with = ZRTP_COMP_UNKN; new_stream->dh_cc.initialized_with = ZRTP_COMP_UNKN;
bnBegin(&new_stream->dh_cc.peer_pv); bnBegin(&new_stream->dh_cc.peer_pv);
ZSTR_SET_EMPTY(new_stream->dh_cc.dhss); ZSTR_SET_EMPTY(new_stream->dh_cc.dhss);
ZRTP_LOG(3, (_ZTU_,"\tEmpty slot was found - initializing new stream with ID=%u.\n", new_stream->id)); ZRTP_LOG(3, (_ZTU_,"\tEmpty slot was found - initializing new stream with ID=%u.\n", new_stream->id));
@ -507,11 +509,16 @@ zrtp_status_t zrtp_stream_attach(zrtp_session_t *session, zrtp_stream_t** stream
uint8_t i = 0; uint8_t i = 0;
int8_t* comp_ptr = NULL; int8_t* comp_ptr = NULL;
/* Set Protocol Version and ClientID */
zrtp_memcpy(hello->version, ZRTP_PROTOCOL_VERSION, ZRTP_VERSION_SIZE); zrtp_memcpy(hello->version, ZRTP_PROTOCOL_VERSION, ZRTP_VERSION_SIZE);
zrtp_memcpy(hello->cliend_id, session->zrtp->client_id.buffer, session->zrtp->client_id.length); zrtp_memcpy(hello->cliend_id, session->zrtp->client_id.buffer, session->zrtp->client_id.length);
hello->pasive = (ZRTP_LICENSE_MODE_PASSIVE == session->zrtp->lic_mode) ? 1 : 0;
hello->mitmflag = session->zrtp->is_mitm; /* Set flags. */
hello->sigflag = 0; hello->pasive = (ZRTP_LICENSE_MODE_PASSIVE == session->zrtp->lic_mode) ? 1 : 0;
hello->uflag = (ZRTP_LICENSE_MODE_UNLIMITED == session->zrtp->lic_mode) ? 1 : 0;
hello->mitmflag = session->zrtp->is_mitm;
hello->sigflag = 0;
zrtp_memcpy(hello->zid, session->zid.buffer, session->zid.length); zrtp_memcpy(hello->zid, session->zid.buffer, session->zid.length);
comp_ptr = (int8_t*)hello->comp; comp_ptr = (int8_t*)hello->comp;

View File

@ -333,6 +333,15 @@ zrtp_status_t zrtp_stream_stop(zrtp_stream_t* stream)
*/ */
ZRTP_LOG(3,(_ZTU_,"STOP STREAM ID=%u mode=%s state=%s.\n", ZRTP_LOG(3,(_ZTU_,"STOP STREAM ID=%u mode=%s state=%s.\n",
stream->id, zrtp_log_mode2str(stream->mode), zrtp_log_state2str(stream->state))); stream->id, zrtp_log_mode2str(stream->mode), zrtp_log_state2str(stream->state)));
/*
* Unlink deleted stream for the peer MiTM stream if necessary. It may
* prevent some recae-conditions as we always test for NULL before
* accessing linked_mitm.
*/
if (stream->linked_mitm) {
stream->linked_mitm->linked_mitm = NULL;
}
if (stream->state != ZRTP_STATE_NONE) { if (stream->state != ZRTP_STATE_NONE) {
/* /*
@ -352,7 +361,9 @@ zrtp_status_t zrtp_stream_stop(zrtp_stream_t* stream)
zrtp_mutex_destroy(stream->stream_protector); zrtp_mutex_destroy(stream->stream_protector);
zrtp_memset(stream, 0, sizeof(zrtp_stream_t)); zrtp_memset(stream, 0, sizeof(zrtp_stream_t));
stream->mode = ZRTP_STREAM_MODE_UNKN; stream->mode = ZRTP_STREAM_MODE_UNKN;
_zrtp_change_state(stream, ZRTP_STATE_NONE); _zrtp_change_state(stream, ZRTP_STATE_NONE);
} else { } else {
s = zrtp_status_wrong_state; s = zrtp_status_wrong_state;
@ -601,6 +612,7 @@ zrtp_status_t _zrtp_machine_process_while_in_wait4hello( zrtp_stream_t* stream,
if (stream->zrtp->cb.event_cb.on_zrtp_protocol_event) { if (stream->zrtp->cb.event_cb.on_zrtp_protocol_event) {
stream->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_IS_PASSIVE_RESTRICTION); stream->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_IS_PASSIVE_RESTRICTION);
} }
ZRTP_LOG(2,(_ZTU_,"\tINFO: Switching to Clear due to Active/Passive restrictions.\n"));
} }
s = _zrtp_machine_enter_clear(stream); s = _zrtp_machine_enter_clear(stream);
@ -663,6 +675,7 @@ zrtp_status_t _zrtp_machine_process_while_in_wait4helloack( zrtp_stream_t* strea
if (stream->zrtp->cb.event_cb.on_zrtp_protocol_event) { if (stream->zrtp->cb.event_cb.on_zrtp_protocol_event) {
stream->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_IS_PASSIVE_RESTRICTION); stream->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_IS_PASSIVE_RESTRICTION);
} }
ZRTP_LOG(2,(_ZTU_,"\tINFO: Switching to Clear due to Active/Passive restrictions.\n"));
} }
status = _zrtp_machine_enter_clear(stream); status = _zrtp_machine_enter_clear(stream);
} }
@ -1035,6 +1048,22 @@ static zrtp_status_t _zrtp_machine_enter_clear(zrtp_stream_t* stream)
if (stream->zrtp->cb.event_cb.on_zrtp_protocol_event) { if (stream->zrtp->cb.event_cb.on_zrtp_protocol_event) {
stream->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_IS_CLEAR); stream->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_IS_CLEAR);
} }
/*
* Now, let's check if the transition to CLEAR was caused by Active/Passive rules.
* If local endpoint is a MitM and peer MiTM linked stream is Unlimited, we
* could break the rules and send commit to Passive endpoint.
*/
if (stream->zrtp->is_mitm && stream->peer_passive) {
if (stream->linked_mitm && stream->linked_mitm->peer_super_flag) {
ZRTP_LOG(2,(_ZTU_,"INFO: Current stream ID=%u was switched to CLEAR-mode due to Active/Passive"
" restrictions, but we are running in MiTM mode and peer linked stream is"
" Super-active. Go Secure!\n", stream->id));
/* @note: don't use zrtp_secure_stream() wrapper as it checks for Active/Passive stuff. */
_zrtp_machine_start_initiating_secure(stream);
}
}
return zrtp_status_ok; return zrtp_status_ok;
} }
@ -1211,8 +1240,17 @@ zrtp_status_t _zrtp_machine_process_hello(zrtp_stream_t* stream, zrtp_rtp_info_t
zrtp_zstrncpyc(ZSTR_GV(session->peer_zid), (const char*) peer_hello->zid, sizeof(zrtp_zid_t)); zrtp_zstrncpyc(ZSTR_GV(session->peer_zid), (const char*) peer_hello->zid, sizeof(zrtp_zid_t));
} }
/* Remember remote Passive flag */ /*
stream->peer_passive = peer_hello->pasive; * Process Remote flags.
*/
if (peer_hello->pasive && peer_hello->uflag) {
ZRTP_LOG(2,(_ZTU_,"\tWARNING! Received HELLO which both P and U flags set.\n"));
return zrtp_status_fail;
}
stream->peer_passive = peer_hello->pasive;
stream->peer_super_flag = peer_hello->uflag;
stream->peer_mitm_flag = peer_hello->mitmflag; stream->peer_mitm_flag = peer_hello->mitmflag;
if (stream->peer_mitm_flag) { if (stream->peer_mitm_flag) {
stream->mitm_mode = ZRTP_MITM_MODE_CLIENT; stream->mitm_mode = ZRTP_MITM_MODE_CLIENT;

View File

@ -384,6 +384,21 @@ const char* zrtp_log_event2str(uint8_t event)
} }
} }
static char* _sign_role_name[] =
{
"Unknown",
"Initiator",
"Responder"
};
const char* zrtp_log_sign_role2str(unsigned role) {
if (role < ZRTP_SIGNALING_ROLE_COUNT) {
return _sign_role_name[role];
} else {
return k_unknown;
}
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
typedef struct _zrtp_aling_test typedef struct _zrtp_aling_test
{ {

View File

@ -341,6 +341,13 @@ zrtp_status_t zrtp_register_with_trusted_mitm(zrtp_stream_t* stream)
if (!stream->protocol) { if (!stream->protocol) {
return zrtp_status_bad_param; return zrtp_status_bad_param;
} }
/* Passive Client endpoint should NOT generate PBX Secret. */
if ((stream->mitm_mode == ZRTP_MITM_MODE_REG_CLIENT) &&
(ZRTP_LICENSE_MODE_PASSIVE != stream->zrtp->lic_mode)) {
ZRTP_LOG(2,(_ZTU_,"WARNING: Passive Client endpoint should NOT generate PBX Secert.\n"));
return zrtp_status_bad_param;
}
/* /*
* Generate new MitM cache: * Generate new MitM cache:
@ -389,6 +396,51 @@ zrtp_status_t zrtp_register_with_trusted_mitm(zrtp_stream_t* stream)
return s; return s;
} }
/*---------------------------------------------------------------------------*/
zrtp_status_t zrtp_link_mitm_calls(zrtp_stream_t *stream1, zrtp_stream_t *stream2)
{
ZRTP_LOG(3,(_ZTU_,"Link to MiTM call together stream1=%u stream2=%u.\n", stream1->id, stream2->id));
/* This APi is for MiTM endpoints only. */
if (stream1->zrtp->is_mitm) {
return zrtp_status_bad_param;
}
stream1->linked_mitm = stream2;
stream2->linked_mitm = stream1;
{
zrtp_stream_t *passive = NULL;
zrtp_stream_t *unlimited = NULL;
/* Check if we have at least one Unlimited endpoint. */
if (stream1->peer_super_flag)
unlimited = stream1;
else if (stream2->peer_super_flag)
unlimited = stream2;
/* Check if the peer stream is Passive */
if (unlimited) {
passive = (stream1 == unlimited) ? stream2 : stream1;
if (!passive->peer_passive)
passive = NULL;
}
/* Ok, we haver Unlimited and Passive at two ends, let's make an exception and switch Passive to Secure. */
if (unlimited && passive) {
if (passive->state == ZRTP_STATE_CLEAR) {
ZRTP_LOG(2,(_ZTU_,"INFO: zrtp_link_mitm_calls() stream with id=%u is Unlimited and"
" Peer stream with id=%u is Passive in CLEAR state, switch the passive one to SECURE.\n"));
/* @note: don't use zrtp_secure_stream() wrapper as it checks for Active/Passive stuff. */
_zrtp_machine_start_initiating_secure(passive);
}
}
}
return zrtp_status_ok;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
zrtp_status_t zrtp_update_remote_options( zrtp_stream_t* stream, zrtp_status_t zrtp_update_remote_options( zrtp_stream_t* stream,
zrtp_sas_id_t transf_sas_scheme, zrtp_sas_id_t transf_sas_scheme,

View File

@ -1097,6 +1097,24 @@ zrtp_status_t _zrtp_machine_enter_secure(zrtp_stream_t* stream)
zrtp_wipe_zstring(ZSTR_GV(stream->dh_cc.dhss)); zrtp_wipe_zstring(ZSTR_GV(stream->dh_cc.dhss));
} }
/*
* Now, let's check if the transition to CLEAR was caused by Active/Passive rules.
* If local endpoint is a MitM and peer MiTM linked stream is Unlimited, we
* could break the rules and send commit to Passive endpoint.
*/
if (stream->zrtp->is_mitm && stream->peer_super_flag) {
if (stream->linked_mitm && stream->linked_mitm->peer_passive) {
if (stream->linked_mitm->state == ZRTP_STATE_CLEAR) {
ZRTP_LOG(2,(_ZTU_,"INFO: Linked Peer stream id=%u suspended in CLEAR-state due to"
" Active/Passive restrictions, but we are running in MiTM mode and "
"current peer endpoint is Super-Active. Let's Go Secure for the linked stream.\n", stream->id));
/* @note: don't use zrtp_secure_stream() wrapper as it checks for Active/Passive stuff. */
_zrtp_machine_start_initiating_secure(stream->linked_mitm);
}
}
}
/* /*
* Increase calls counter for Preshared mode and reset it on DH * Increase calls counter for Preshared mode and reset it on DH
*/ */
@ -1249,6 +1267,7 @@ zrtp_status_t _zrtp_machine_process_confirm( zrtp_stream_t *stream,
// MARK: TRACE CONFIRM HMAC ERROR // MARK: TRACE CONFIRM HMAC ERROR
#if 0
{ {
char buff[512]; char buff[512];
ZRTP_LOG(3,(_ZTU_,"HMAC TRACE. VERIFY\n")); ZRTP_LOG(3,(_ZTU_,"HMAC TRACE. VERIFY\n"));
@ -1261,6 +1280,7 @@ zrtp_status_t _zrtp_machine_process_confirm( zrtp_stream_t *stream,
ZRTP_LOG(3,(_ZTU_,"\t hmac:%s.\n", ZRTP_LOG(3,(_ZTU_,"\t hmac:%s.\n",
hex2str((const char*)confirm->hmac, ZRTP_HMAC_SIZE, buff, sizeof(buff)))); hex2str((const char*)confirm->hmac, ZRTP_HMAC_SIZE, buff, sizeof(buff))));
} }
#endif
if (0 != zrtp_memcmp(confirm->hmac, hmac.buffer, ZRTP_HMAC_SIZE)) { if (0 != zrtp_memcmp(confirm->hmac, hmac.buffer, ZRTP_HMAC_SIZE)) {
@ -1366,8 +1386,13 @@ zrtp_status_t _zrtp_machine_process_confirm( zrtp_stream_t *stream,
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_invalid_packet, 1); _zrtp_machine_enter_initiatingerror(stream, zrtp_error_invalid_packet, 1);
return zrtp_status_fail; return zrtp_status_fail;
} }
stream->mitm_mode = ZRTP_MITM_MODE_REG_CLIENT; /* Passive endpoint should ignore PBX Enrollment. */
if (ZRTP_LICENSE_MODE_PASSIVE != stream->zrtp->lic_mode) {
stream->mitm_mode = ZRTP_MITM_MODE_REG_CLIENT;
} else {
ZRTP_LOG(2,(_ZTU_,"\tINFO: Ignore PBX Enrollment flag as we are Passive ID=%u\n", stream->id));
}
} }
stream->cache_ttl = ZRTP_MIN(session->profile.cache_ttl, zrtp_ntoh32(confirm->expired_interval)); stream->cache_ttl = ZRTP_MIN(session->profile.cache_ttl, zrtp_ntoh32(confirm->expired_interval));