mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 05:38:39 +00:00
Issue #1991 - Support TURN TLS Support in WebRTC Backport of Mozilla bug 1056934
This commit is contained in:
@@ -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');
|
||||
});
|
||||
@@ -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]
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ class NrIceMediaStream;
|
||||
|
||||
extern const char kNrIceTransportUdp[];
|
||||
extern const char kNrIceTransportTcp[];
|
||||
extern const char kNrIceTransportTls[];
|
||||
|
||||
class NrIceStunServer {
|
||||
public:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user