diff options
-rw-r--r-- | dom/media/tests/mochitest/addTurnsSelfsignedCert.js | 26 | ||||
-rw-r--r-- | dom/media/tests/mochitest/mochitest.ini | 3 | ||||
-rw-r--r-- | dom/media/tests/mochitest/pc.js | 30 | ||||
-rw-r--r-- | dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html | 38 | ||||
-rw-r--r-- | dom/network/TCPSocketParent.cpp | 15 | ||||
-rw-r--r-- | media/mtransport/nr_socket_prsock.cpp | 34 | ||||
-rw-r--r-- | media/mtransport/nr_socket_prsock.h | 3 | ||||
-rw-r--r-- | media/mtransport/nricectx.cpp | 9 | ||||
-rw-r--r-- | media/mtransport/nricectx.h | 1 | ||||
-rw-r--r-- | media/mtransport/test_nr_socket.cpp | 55 | ||||
-rw-r--r-- | media/mtransport/test_nr_socket.h | 3 | ||||
-rw-r--r-- | media/mtransport/third_party/nICEr/src/ice/ice_candidate.c | 8 | ||||
-rw-r--r-- | media/mtransport/third_party/nICEr/src/ice/ice_ctx.h | 1 | ||||
-rw-r--r-- | media/mtransport/third_party/nICEr/src/net/transport_addr.h | 1 | ||||
-rw-r--r-- | media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp | 9 | ||||
-rw-r--r-- | testing/tools/iceserver/iceserver.py | 72 |
16 files changed, 282 insertions, 26 deletions
diff --git a/dom/media/tests/mochitest/addTurnsSelfsignedCert.js b/dom/media/tests/mochitest/addTurnsSelfsignedCert.js new file mode 100644 index 0000000000..cad3d04465 --- /dev/null +++ b/dom/media/tests/mochitest/addTurnsSelfsignedCert.js @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +// This is only usable from the parent process, even for doing simple stuff like +// serializing a cert. +var gCertMaker = Cc["@mozilla.org/security/x509certdb;1"]. + getService(Ci.nsIX509CertDB); + +var gCertOverrides = Cc["@mozilla.org/security/certoverride;1"]. + getService(Ci.nsICertOverrideService); + + +addMessageListener('add-turns-certs', certs => { + var port = 5349; + certs.forEach(certDescription => { + var cert = gCertMaker.constructX509FromBase64(certDescription.cert); + gCertOverrides.rememberValidityOverride(certDescription.hostname, port, + cert, Ci.nsICertOverrideService.ERROR_UNTRUSTED, false); + }); + sendAsyncMessage('certs-added'); +}); diff --git a/dom/media/tests/mochitest/mochitest.ini b/dom/media/tests/mochitest/mochitest.ini index 22006ffa2f..948d938a30 100644 --- a/dom/media/tests/mochitest/mochitest.ini +++ b/dom/media/tests/mochitest/mochitest.ini @@ -13,6 +13,7 @@ support-files = blacksilence.js turnConfig.js sdpUtils.js + addTurnsSelfsignedCert.js !/dom/canvas/test/captureStream_common.js !/dom/canvas/test/webgl-mochitest/webgl-util.js !/dom/media/test/manifest.js @@ -98,6 +99,8 @@ skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217) skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217) [test_peerConnection_basicAudioNATRelayTCP.html] skip-if = toolkit == 'android' # websockets don't work on android (bug 1266217) +[test_peerConnection_basicAudioNATRelayTLS.html] +skip-if = true # need pyopenssl on builders, see bug 1323439 [test_peerConnection_basicAudioRequireEOC.html] skip-if = (android_version == '18' && debug) # android(Bug 1189784, timeouts on 4.3 emulator) [test_peerConnection_basicAudioPcmaPcmuOnly.html] diff --git a/dom/media/tests/mochitest/pc.js b/dom/media/tests/mochitest/pc.js index a9383358f9..2e9c7c63f1 100644 --- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -1822,6 +1822,33 @@ function createHTML(options) { var iceServerWebsocket; var iceServersArray = []; +var addTurnsSelfsignedCerts = () => { + var gUrl = SimpleTest.getTestFileURL('addTurnsSelfsignedCert.js'); + var gScript = SpecialPowers.loadChromeScript(gUrl); + var certs = []; + // If the ICE server is running TURNS, and includes a "cert" attribute in + // its JSON, we set up an override that will forgive things like + // self-signed for it. + iceServersArray.forEach(iceServer => { + if (iceServer.hasOwnProperty("cert")) { + iceServer.urls.forEach(url => { + if (url.startsWith("turns:")) { + // Assumes no port or params! + certs.push({"cert": iceServer.cert, "hostname": url.substr(6)}); + } + }); + } + }); + + return new Promise((resolve, reject) => { + gScript.addMessageListener('certs-added', () => { + resolve(); + }); + + gScript.sendAsyncMessage('add-turns-certs', certs); + }); +}; + var setupIceServerConfig = useIceServer => { // We disable ICE support for HTTP proxy when using a TURN server, because // mochitest uses a fake HTTP proxy to serve content, which will eat our STUN @@ -1863,7 +1890,8 @@ var setupIceServerConfig = useIceServer => { return enableHttpProxy(false) .then(spawnIceServer) - .then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); }); + .then(iceServersStr => { iceServersArray = JSON.parse(iceServersStr); }) + .then(addTurnsSelfsignedCerts); }; function runNetworkTest(testFunction, fixtureOptions) { diff --git a/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html new file mode 100644 index 0000000000..c295955d81 --- /dev/null +++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="pc.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> + createHTML({ + bug: "1231975", + title: "Basic audio-only peer connection with port dependent NAT that blocks STUN" + }); + + var test; + runNetworkTest(options => { + SpecialPowers.pushPrefEnv( + { + 'set': [ + ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'], + ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT'], + ['media.peerconnection.nat_simulator.block_udp', true], + ['media.peerconnection.nat_simulator.block_tcp', true] + ] + }, function (options) { + options = options || {}; + options.expectedLocalCandidateType = "relayed-tcp"; + options.expectedRemoteCandidateType = "relayed-tcp"; + // No reason to wait for gathering to complete like the other NAT tests, + // since relayed-tcp is the only thing that can work. + test = new PeerConnectionTest(options); + test.setMediaConstraints([{audio: true}], [{audio: true}]); + test.run(); + }) + }, { useIceServer: true }); +</script> +</pre> +</body> +</html> diff --git a/dom/network/TCPSocketParent.cpp b/dom/network/TCPSocketParent.cpp index 313d13f759..27d4d057e7 100644 --- a/dom/network/TCPSocketParent.cpp +++ b/dom/network/TCPSocketParent.cpp @@ -167,9 +167,18 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost, } nsCOMPtr<nsISocketTransport> socketTransport; - rv = sts->CreateTransport(nullptr, 0, - aRemoteHost, aRemotePort, - nullptr, getter_AddRefs(socketTransport)); + if (aUseSSL) { + const char* socketTypes[1]; + socketTypes[0] = "ssl"; + rv = sts->CreateTransport(socketTypes, 1, + aRemoteHost, aRemotePort, + nullptr, getter_AddRefs(socketTransport)); + } else { + rv = sts->CreateTransport(nullptr, 0, + aRemoteHost, aRemotePort, + nullptr, getter_AddRefs(socketTransport)); + } + if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; diff --git a/media/mtransport/nr_socket_prsock.cpp b/media/mtransport/nr_socket_prsock.cpp index 80e5ef51e4..3fd223349c 100644 --- a/media/mtransport/nr_socket_prsock.cpp +++ b/media/mtransport/nr_socket_prsock.cpp @@ -858,6 +858,10 @@ int NrSocket::connect(nr_transport_addr *addr) { PRNetAddr naddr; int32_t connect_status, getsockname_status; + // TODO: Add TLS layer with nsISocketProviderService? + if (addr->tls_host[0] != '\0') + ABORT(R_INTERNAL); + if ((r=nr_transport_addr_to_praddr(addr, &naddr))) ABORT(r); @@ -1840,7 +1844,7 @@ void NrTcpSocketIpc::close() { } int NrTcpSocketIpc::connect(nr_transport_addr *addr) { - nsCString remote_addr, local_addr; + nsCString remote_addr, local_addr, tls_host; int32_t remote_port, local_port; int r, _status; if ((r=nr_transport_addr_get_addrstring_and_port(addr, @@ -1856,6 +1860,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) { ABORT(r); } + tls_host = addr->tls_host; + state_ = mirror_state_ = NR_CONNECTING; RUN_ON_THREAD(io_thread_, mozilla::WrapRunnable(RefPtr<NrTcpSocketIpc>(this), @@ -1863,7 +1869,8 @@ int NrTcpSocketIpc::connect(nr_transport_addr *addr) { remote_addr, static_cast<uint16_t>(remote_port), local_addr, - static_cast<uint16_t>(local_port)), + static_cast<uint16_t>(local_port), + tls_host), NS_DISPATCH_NORMAL); // Make caller wait for ready to write. @@ -1939,7 +1946,8 @@ int NrTcpSocketIpc::accept(nr_transport_addr *addrp, nr_socket **sockp) { void NrTcpSocketIpc::connect_i(const nsACString &remote_addr, uint16_t remote_port, const nsACString &local_addr, - uint16_t local_port) { + uint16_t local_port, + const nsACString &tls_host) { ASSERT_ON_THREAD(io_thread_); mirror_state_ = NR_CONNECTING; @@ -1948,11 +1956,21 @@ void NrTcpSocketIpc::connect_i(const nsACString &remote_addr, // Bug 1285330: put filtering back in here - // XXX remove remote! - socket_child_->SendWindowlessOpenBind(this, - remote_addr, remote_port, - local_addr, local_port, - /* use ssl */ false); + if (tls_host.IsEmpty()) { + // XXX remove remote! + socket_child_->SendWindowlessOpenBind(this, + remote_addr, remote_port, + local_addr, local_port, + /* use ssl */ false, + /* reuse addr port */ true); + } else { + // XXX remove remote! + socket_child_->SendWindowlessOpenBind(this, + tls_host, remote_port, + local_addr, local_port, + /* use ssl */ true, + /* reuse addr port */ true); + } } void NrTcpSocketIpc::write_i(nsAutoPtr<InfallibleTArray<uint8_t>> arr, diff --git a/media/mtransport/nr_socket_prsock.h b/media/mtransport/nr_socket_prsock.h index 5ed9a6a219..7d372ccb16 100644 --- a/media/mtransport/nr_socket_prsock.h +++ b/media/mtransport/nr_socket_prsock.h @@ -369,7 +369,8 @@ private: void connect_i(const nsACString &remote_addr, uint16_t remote_port, const nsACString &local_addr, - uint16_t local_port); + uint16_t local_port, + const nsACString &tls_host); void write_i(nsAutoPtr<InfallibleTArray<uint8_t>> buf, uint32_t tracking_number); void close_i(); diff --git a/media/mtransport/nricectx.cpp b/media/mtransport/nricectx.cpp index be50f50169..75d3d2519d 100644 --- a/media/mtransport/nricectx.cpp +++ b/media/mtransport/nricectx.cpp @@ -108,6 +108,7 @@ MOZ_MTLOG_MODULE("mtransport") const char kNrIceTransportUdp[] = "udp"; const char kNrIceTransportTcp[] = "tcp"; +const char kNrIceTransportTls[] = "tls"; static bool initialized = false; @@ -210,6 +211,9 @@ nsresult NrIceStunServer::ToNicerStunStruct(nr_ice_stun_server *server) const { server->transport = IPPROTO_UDP; } else if (transport_ == kNrIceTransportTcp) { server->transport = IPPROTO_TCP; + } else if (transport_ == kNrIceTransportTls) { + server->transport = IPPROTO_TCP; + server->tls = 1; } else { MOZ_MTLOG(ML_ERROR, "Unsupported STUN server transport: " << transport_); return NS_ERROR_FAILURE; @@ -586,6 +590,7 @@ NrIceCtx::Initialize(const std::string& ufrag, nsCString mapping_type; nsCString filtering_type; bool block_udp = false; + bool block_tcp = false; nsresult rv; nsCOMPtr<nsIPrefService> pref_service = @@ -604,6 +609,9 @@ NrIceCtx::Initialize(const std::string& ufrag, rv = pref_branch->GetBoolPref( "media.peerconnection.nat_simulator.block_udp", &block_udp); + rv = pref_branch->GetBoolPref( + "media.peerconnection.nat_simulator.block_tcp", + &block_tcp); } } @@ -614,6 +622,7 @@ NrIceCtx::Initialize(const std::string& ufrag, test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get()); test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get()); test_nat->block_udp_ = block_udp; + test_nat->block_tcp_ = block_tcp; test_nat->enabled_ = true; SetNat(test_nat); } diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h index ce104ac317..87122121e5 100644 --- a/media/mtransport/nricectx.h +++ b/media/mtransport/nricectx.h @@ -90,6 +90,7 @@ class NrIceMediaStream; extern const char kNrIceTransportUdp[]; extern const char kNrIceTransportTcp[]; +extern const char kNrIceTransportTls[]; class NrIceStunServer { public: diff --git a/media/mtransport/test_nr_socket.cpp b/media/mtransport/test_nr_socket.cpp index e7dad79cd1..fb2de3096e 100644 --- a/media/mtransport/test_nr_socket.cpp +++ b/media/mtransport/test_nr_socket.cpp @@ -200,6 +200,7 @@ int TestNat::create_socket_factory(nr_socket_factory **factorypp) { TestNrSocket::TestNrSocket(TestNat *nat) : nat_(nat), + tls_(false), timer_handle_(nullptr) { nat_->insert_socket(this); } @@ -473,6 +474,10 @@ int TestNrSocket::connect(nr_transport_addr *addr) { return R_INTERNAL; } + if (addr->tls_host[0] != '\0') { + tls_ = true; + } + if (!nat_->enabled_ || addr->protocol==IPPROTO_UDP // Horrible hack to allow default address // discovery to work. Only works because @@ -508,6 +513,24 @@ int TestNrSocket::connect(nr_transport_addr *addr) { } int TestNrSocket::write(const void *msg, size_t len, size_t *written) { + UCHAR *buf = static_cast<UCHAR*>(const_cast<void*>(msg)); + if (nat_->block_stun_ && nr_is_stun_message(buf, len)) { + // Should cause this socket to be abandoned + r_log(LOG_GENERIC, LOG_DEBUG, + "TestNrSocket %s dropping outgoing TCP " + "because it is configured to drop STUN", + my_addr().as_string); + return R_INTERNAL; + } + + if (nat_->block_tcp_ && !tls_) { + // Should cause this socket to be abandoned + r_log(LOG_GENERIC, LOG_DEBUG, + "TestNrSocket %s dropping outgoing TCP " + "because it is configured to drop TCP", + my_addr().as_string); + return R_INTERNAL; + } if (port_mappings_.empty()) { // The no-nat case, just pass call through. @@ -518,7 +541,11 @@ int TestNrSocket::write(const void *msg, size_t len, size_t *written) { } else { destroy_stale_port_mappings(); if (port_mappings_.empty()) { - return -1; + r_log(LOG_GENERIC, LOG_DEBUG, + "TestNrSocket %s dropping outgoing TCP " + "because the port mapping was stale", + my_addr().as_string); + return R_INTERNAL; } // This is TCP only MOZ_ASSERT(port_mappings_.size() == 1); @@ -533,18 +560,34 @@ int TestNrSocket::write(const void *msg, size_t len, size_t *written) { } int TestNrSocket::read(void *buf, size_t maxlen, size_t *len) { + int r; if (port_mappings_.empty()) { - return internal_socket_->read(buf, maxlen, len); + r = internal_socket_->read(buf, maxlen, len); } else { MOZ_ASSERT(port_mappings_.size() == 1); - int bytesRead = - port_mappings_.front()->external_socket_->read(buf, maxlen, len); - if (bytesRead > 0 && nat_->refresh_on_ingress_) { + r = port_mappings_.front()->external_socket_->read(buf, maxlen, len); + if (!r && nat_->refresh_on_ingress_) { port_mappings_.front()->last_used_ = PR_IntervalNow(); } - return bytesRead; } + + if (r) { + return r; + } + + if (nat_->block_tcp_ && !tls_) { + // Should cause this socket to be abandoned + return R_INTERNAL; + } + + UCHAR *cbuf = static_cast<UCHAR*>(const_cast<void*>(buf)); + if (nat_->block_stun_ && nr_is_stun_message(cbuf, *len)) { + // Should cause this socket to be abandoned + return R_INTERNAL; + } + + return r; } int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg, diff --git a/media/mtransport/test_nr_socket.h b/media/mtransport/test_nr_socket.h index 91c9030f17..a47a88beb9 100644 --- a/media/mtransport/test_nr_socket.h +++ b/media/mtransport/test_nr_socket.h @@ -137,6 +137,7 @@ class TestNat { refresh_on_ingress_(false), block_udp_(false), block_stun_(false), + block_tcp_(false), delay_stun_resp_ms_(0), sockets_() {} @@ -168,6 +169,7 @@ class TestNat { bool refresh_on_ingress_; bool block_udp_; bool block_stun_; + bool block_tcp_; /* Note: this can only delay a single response so far (bug 1253657) */ uint32_t delay_stun_resp_ms_; @@ -319,6 +321,7 @@ class TestNrSocket : public NrSocketBase { // same nat. RefPtr<NrSocketBase> internal_socket_; RefPtr<TestNat> nat_; + bool tls_; // Since our comparison logic is different depending on what kind of NAT // we simulate, and the STL does not make it very easy to switch out the // comparison function at runtime, and these lists are going to be very diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c index e48b7b5e1a..879b77933e 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c +++ b/media/mtransport/third_party/nICEr/src/ice/ice_candidate.c @@ -666,6 +666,14 @@ static int nr_ice_candidate_resolved_cb(void *cb_arg, nr_transport_addr *addr) if(r=nr_transport_addr_copy(&cand->stun_server_addr,addr)) ABORT(r); + if (cand->stun_server->tls) { + /* Copy over the DNS name; needed for TLS. There is already a null at the + * end of the buffer, leave it there. */ + strncpy(cand->stun_server_addr.tls_host, + cand->stun_server->u.dnsname.host, + sizeof(cand->stun_server_addr.tls_host) - 1); + } + if (cand->tcp_type == TCP_TYPE_PASSIVE || cand->tcp_type == TCP_TYPE_SO){ if (r=nr_socket_multi_tcp_stun_server_connect(cand->osock, addr)) ABORT(r); diff --git a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h index cc79304f08..1e815ac2ac 100644 --- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h +++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h @@ -63,6 +63,7 @@ typedef struct nr_ice_stun_server_ { } u; int id; int transport; + int tls; /* Whether to use TLS or not */ } nr_ice_stun_server; typedef struct nr_ice_turn_server_ { diff --git a/media/mtransport/third_party/nICEr/src/net/transport_addr.h b/media/mtransport/third_party/nICEr/src/net/transport_addr.h index dfec633291..06c8b8c9c5 100644 --- a/media/mtransport/third_party/nICEr/src/net/transport_addr.h +++ b/media/mtransport/third_party/nICEr/src/net/transport_addr.h @@ -66,6 +66,7 @@ typedef struct nr_transport_addr_ { /* A string version. 56 = 5 ("IP6:[") + 39 (ipv6 address) + 2 ("]:") + 5 (port) + 4 (/UDP) + 1 (null) */ char as_string[56]; + char tls_host[256]; } nr_transport_addr; typedef struct nr_transport_addr_mask_ { diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index 3b4363a13c..7f3bb90d44 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -526,8 +526,8 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer) if (!(isStun || isStuns || isTurn || isTurns)) { return NS_ERROR_FAILURE; } - if (isTurns || isStuns) { - continue; // TODO: Support TURNS and STUNS (Bug 1056934) + if (isStuns) { + continue; // TODO: Support STUNS (Bug 1056934) } nsAutoCString spec; rv = url->GetSpec(spec); @@ -576,6 +576,11 @@ PeerConnectionConfiguration::AddIceServer(const RTCIceServer &aServer) if (port == -1) port = (isStuns || isTurns)? 5349 : 3478; + if (isStuns || isTurns) { + // Should we barf if transport is set to udp or something? + transport = "tls"; + } + // First check the known good ports for webrtc bool knownGoodPort = false; for (int i = 0; !knownGoodPort && gGoodWebrtcPortList[i]; i++) { diff --git a/testing/tools/iceserver/iceserver.py b/testing/tools/iceserver/iceserver.py index 2089301af8..85d0f3ee54 100644 --- a/testing/tools/iceserver/iceserver.py +++ b/testing/tools/iceserver/iceserver.py @@ -10,7 +10,9 @@ import passlib.utils # for saslprep import copy import random import operator +import os import platform +import string import time from string import Template from twisted.internet import reactor, protocol @@ -715,6 +717,38 @@ def prune_allocations(): del allocations[key] allocation.close() +CERT_FILE = "selfsigned.crt" +KEY_FILE = "private.key" + +def create_self_signed_cert(name): + from OpenSSL import crypto + if os.path.isfile(CERT_FILE) and os.path.isfile(KEY_FILE): + return + + # create a key pair + k = crypto.PKey() + k.generate_key(crypto.TYPE_RSA, 1024) + + # create a self-signed cert + cert = crypto.X509() + cert.get_subject().C = "US" + cert.get_subject().ST = "TX" + cert.get_subject().L = "Dallas" + cert.get_subject().O = "Mozilla test iceserver" + cert.get_subject().OU = "Mozilla test iceserver" + cert.get_subject().CN = name + cert.set_serial_number(1000) + cert.gmtime_adj_notBefore(0) + cert.gmtime_adj_notAfter(10*365*24*60*60) + cert.set_issuer(cert.get_subject()) + cert.set_pubkey(k) + cert.sign(k, 'sha1') + + open(CERT_FILE, "wt").write( + crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) + open(KEY_FILE, "wt").write( + crypto.dump_privatekey(crypto.FILETYPE_PEM, k)) + if __name__ == "__main__": random.seed() @@ -739,20 +773,48 @@ if __name__ == "__main__": except: pass + try: + from twisted.internet import ssl + from OpenSSL import SSL + create_self_signed_cert(hostname) + tls_context_factory = ssl.DefaultOpenSSLContextFactory(KEY_FILE, CERT_FILE, SSL.TLSv1_2_METHOD) + reactor.listenSSL(5349, TcpStunHandlerFactory(), tls_context_factory, interface=interface_4) + + try: + reactor.listenSSL(5349, TcpStunHandlerFactory(), tls_context_factory, interface=interface_6) + except: + pass + + f = open(CERT_FILE, 'r'); + lines = f.readlines(); + lines.pop(0); # Remove BEGIN CERTIFICATE + lines.pop(); # Remove END CERTIFICATE + lines = map(string.strip, lines); + certbase64 = string.join(lines, ''); + + turns_url = ', "turns:' + hostname + '"' + cert_prop = ', "cert":"' + certbase64 + '"' + except: + turns_url = '' + cert_prop = '' + pass + allocation_pruner = LoopingCall(prune_allocations) allocation_pruner.start(1) template = Template( '[\ -{"url":"stun:$hostname"}, \ -{"url":"stun:$hostname?transport=tcp"}, \ -{"username":"$user","credential":"$pwd","url":"turn:$hostname"}, \ -{"username":"$user","credential":"$pwd","url":"turn:$hostname?transport=tcp"}]' +{"urls":["stun:$hostname", "stun:$hostname?transport=tcp"]}, \ +{"username":"$user","credential":"$pwd","urls": \ +["turn:$hostname", "turn:$hostname?transport=tcp" $turns_url] \ +$cert_prop}]' # Hack to make it easier to override cert checks ) print(template.substitute(user=turn_user, pwd=turn_pass, - hostname=hostname)) + hostname=hostname, + turns_url=turns_url, + cert_prop=cert_prop)) reactor.run() |