Browse code

core:zrtp: fix ZID, double ZRTP initialization; place ZRTP init after onStart

Stefan Sayer authored on 03/11/2014 13:04:24
Showing 5 changed files
... ...
@@ -755,9 +755,6 @@ int AmRtpStream::init(const AmSdp& local,
755 755
 
756 756
 #ifdef WITH_ZRTP  
757 757
   if (session && session->enable_zrtp) {
758
-    if (session->zrtp_session_state.initSession(session))
759
-      return -1;
760
-
761 758
     session->zrtp_session_state.startStreams(get_ssrc());
762 759
   }
763 760
 #endif
... ...
@@ -279,15 +279,6 @@ void AmSession::run() {
279 279
 #endif
280 280
 
281 281
 bool AmSession::startup() {
282
-#ifdef WITH_ZRTP
283
-  if (enable_zrtp) {
284
-    if (zrtp_session_state.initSession(this))
285
-      return -1;
286
-      
287
-      DBG("initialized ZRTP session context OK\n");
288
-  }
289
-#endif
290
-
291 282
   session_started();
292 283
 
293 284
   try {
... ...
@@ -295,6 +286,16 @@ bool AmSession::startup() {
295 286
 
296 287
       onStart();
297 288
 
289
+#ifdef WITH_ZRTP
290
+      if (enable_zrtp) {
291
+	if (zrtp_session_state.initSession(this)) {
292
+	  ERROR("initializing ZRTP session\n");
293
+	  throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
294
+	}
295
+	DBG("initialized ZRTP session context OK\n");
296
+      }
297
+#endif
298
+
298 299
     } 
299 300
     catch(const AmSession::Exception& e){ throw e; }
300 301
     catch(const string& str){
... ...
@@ -1322,9 +1323,9 @@ void AmSession::onZRTPProtocolEvent(zrtp_protocol_event_t event, zrtp_stream_t *
1322 1323
       break;
1323 1324
 
1324 1325
     case ZRTP_EVENT_IS_PASSIVE_RESTRICTION:
1325
-      INFO("ZRTP_EVENT_IS_PASSIVE_RESTRICTION\n");
1326
+     INFO("ZRTP_EVENT_IS_PASSIVE_RESTRICTION\n");
1326 1327
       break;
1327
-     
1328
+
1328 1329
     default: 
1329 1330
       INFO("unknown ZRTP_EVENT\n");
1330 1331
       break;
... ...
@@ -45,7 +45,7 @@ AmMutex AmZRTP::zrtp_cache_mut;
45 45
 
46 46
 zrtp_global_t* AmZRTP::zrtp_global;      // persistent storage for libzrtp data
47 47
 zrtp_config_t AmZRTP::zrtp_config;
48
-zrtp_zid_t AmZRTP::zrtp_instance_zid = {"defaultsems"}; // todo: generate one
48
+zrtp_zid_t AmZRTP::zrtp_instance_zid = {"defaultsems"}; // todo: generate one?
49 49
 
50 50
 void zrtp_log(int level, char *data, int len, int offset) {
51 51
   int sems_lvl = L_DBG;
... ...
@@ -68,25 +68,54 @@ int AmZRTP::init() {
68 68
   }
69 69
 
70 70
   cache_path = cfg.getParameter("cache_path");
71
-  string zid = cfg.getParameter("zid");
72
-  if (zid.length() != sizeof(zrtp_zid_t)) {
73
-    ERROR("ZID of this instance MUST be set for ZRTP.\n");
74
-    ERROR("ZID needs to be %lu characters long.\n", 
75
-	  sizeof(zrtp_zid_t));
76
-    return -1;
71
+  if (cfg.hasParameter("zid_hex")) {
72
+    string zid_hex = cfg.getParameter("zid_hex");
73
+    if (zid_hex.size() != 2*sizeof(zrtp_instance_zid)) {
74
+      ERROR("zid_hex config parameter in zrtp.conf must be %lu characters long.\n", 
75
+	    sizeof(zrtp_zid_t)*2);
76
+      return -1;
77
+    }
78
+
79
+    for (size_t i=0;i<sizeof(zrtp_instance_zid);i++) {
80
+      unsigned int h;
81
+      if (reverse_hex2int(zid_hex.substr(i*2, 2), h)) {
82
+	ERROR("in zid_hex in zrtp.conf: '%s' is no hex number\n", zid_hex.substr(i*2, 2).c_str());
83
+	return -1;
84
+      }
85
+
86
+      zrtp_instance_zid[i]=h % 0xff;
87
+    }
88
+
89
+  } else if (cfg.hasParameter("zid")) {
90
+    string zid = cfg.getParameter("zid");
91
+    WARN("zid parameter in zrtp.conf is only supported for backwards compatibility. Please use zid_hex\n");
92
+    if (zid.length() != sizeof(zrtp_zid_t)) {
93
+      ERROR("zid config parameter in zrtp.conf must be %lu characters long.\n", 
94
+	    sizeof(zrtp_zid_t));
95
+      return -1;
96
+    }
97
+    for (size_t i=0;i<zid.length();i++)
98
+      zrtp_instance_zid[i]=zid[i];
99
+  } else {
100
+    // generate one
101
+    string zid_hex;
102
+    for (size_t i=0;i<sizeof(zrtp_instance_zid);i++) {
103
+      zrtp_instance_zid[i]=get_random() % 0xff;
104
+      zid_hex+=char2hex(zrtp_instance_zid[i], true);
105
+    }
106
+
107
+    WARN("Generated random ZID. To support key continuity through key cache "
108
+	 "on the peers, add this to zrtp.conf: 'zid_hex=\"%s\"'", zid_hex.c_str());
77 109
   }
78 110
 
79
-  for (size_t i=0;i<zid.length();i++)
80
-    zrtp_instance_zid[i]=zid[i];
81 111
 
82
-  DBG("initializing ZRTP library with ZID '%s', cache path '%s'.\n",
83
-      zid.c_str(), cache_path.c_str());
112
+  DBG("initializing ZRTP library with cache path '%s'.\n", cache_path.c_str());
84 113
 
85 114
   zrtp_config_defaults(&zrtp_config);
86 115
 
87 116
   strcpy(zrtp_config.client_id, SEMS_CLIENT_ID);
117
+  memcpy((char*)zrtp_config.zid, (char*)zrtp_instance_zid, sizeof(zrtp_zid_t));
88 118
   zrtp_config.lic_mode = ZRTP_LICENSE_MODE_UNLIMITED;
89
-
90 119
   
91 120
   strncpy(zrtp_config.cache_file_cfg.cache_path, cache_path.c_str(), 256);
92 121
 
... ...
@@ -136,11 +165,9 @@ AmZRTPSessionState::AmZRTPSessionState()
136 165
 }
137 166
 
138 167
 int AmZRTPSessionState::initSession(AmSession* session) {
168
+  DBG("Initializing ZRTP stream...\n");
139 169
 
140
-  DBG("starting ZRTP stream...\n");
141
-  //
142
-  // Allocate zrtp session with default parameters
143
-  //
170
+  // Allocate zrtp session
144 171
   zrtp_status_t status =
145 172
     zrtp_session_init( AmZRTP::zrtp_global,
146 173
 		       &zrtp_profile,
... ...
@@ -154,9 +181,7 @@ int AmZRTPSessionState::initSession(AmSession* session) {
154 181
   // Set call-back pointer to our parent structure
155 182
   zrtp_session_set_userdata(zrtp_session, session);
156 183
 
157
-  // 
158
-  // Attach Audio and Video Streams
159
-  //
184
+  // Attach audio stream
160 185
   status = zrtp_stream_attach(zrtp_session, &zrtp_audio);
161 186
   if (zrtp_status_ok != status) {
162 187
     // Check error code and debug logs
... ...
@@ -272,32 +297,4 @@ void AmZRTP::on_zrtp_protocol_event(zrtp_stream_t *stream, zrtp_protocol_event_t
272 297
   sess->postEvent(new AmZRTPProtocolEvent(event, stream));
273 298
 }
274 299
 
275
-/*
276
-void zrtp_play_alert(zrtp_stream_t* ctx) {
277
-  INFO("zrtp_play_alert: ALERT!\n");
278
-  ctx->need_play_alert = zrtp_play_no;
279
-}
280
-*/
281
-
282
-// #define BUFFER_LOG_SIZE 256
283
-// void zrtp_print_log(log_level_t level, const char* format, ...)
284
-// {
285
-// 	char buffer[BUFFER_LOG_SIZE];
286
-//     va_list arg;
287
-
288
-//     va_start(arg, format);
289
-//     vsnprintf(buffer, BUFFER_LOG_SIZE, format, arg);
290
-//     va_end( arg );
291
-//     int sems_lvl = L_ERR;
292
-//     switch(level) {
293
-//     case ZRTP_LOG_DEBUG:   sems_lvl = L_DBG; break;
294
-//     case ZRTP_LOG_INFO:    sems_lvl = L_INFO; break;
295
-//     case ZRTP_LOG_WARNING: sems_lvl = L_WARN; break;
296
-//     case ZRTP_LOG_ERROR:   sems_lvl = L_ERR; break;
297
-//     case ZRTP_LOG_FATAL:   sems_lvl = L_ERR; break;
298
-//     case ZRTP_LOG_ALL:   sems_lvl = L_ERR; break;
299
-//     }
300
-//     _LOG(sems_lvl, "*** %s", buffer);
301
-// }
302
-
303 300
 #endif
... ...
@@ -4,9 +4,11 @@
4 4
 cache_path=zrtp_cache.dat
5 5
 
6 6
 #
7
-# ZID - must be set to a unique identifier on installation.
7
+# ZID - must be set to a unique random identifier on installation.
8
+# if none is provided, a random one will be generated - this should be
9
+# then taken into zrtp.conf to support key continuity. 
8 10
 #
9
-#zid=012345678901
11
+#zid_hex="d4d8bb2d7d3536244cb67598"
10 12
 
11 13
 # random_entropy_bytes - bytes to read from /dev/random to zrtp entropy pool
12 14
 # Warning: can stall the startup process if there's many bytes read. 
... ...
@@ -1,4 +1,4 @@
1
-/* \file info about ZRTP usage in SEMS
1
+/* \file info about using ZRTP with SEMS
2 2
  */
3 3
 
4 4
 /*!
... ...
@@ -15,7 +15,7 @@
15 15
  *  not supporting it are still possible, but unencrypted. The actual RTP encryption is done with 
16 16
  *  <a href="http://www.ietf.org/rfc/rfc3711.txt">SRTP</a>.
17 17
  *
18
- *  <p>ZRTP is one of the widest (if not the widest) supported end-to-end encryption methods for VoIP. 
18
+ *  <p>ZRTP is one of the most widely (if not the most widely) supported end-to-end encryption methods for VoIP. 
19 19
  *  Popular SIP clients that support ZRTP are <a href="http://www.jitsi.org">Jitsi</a>, CSipSimple, Twinkle, Linphone.</p>
20 20
  * 
21 21
  *  <p>For more information about ZRTP, see the