mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-18 16:16:28 +00:00
quinn: allow unsecure connections in WebTransport elements
WebTransport requires a secure connection, but certificates can have a validity of 2 weeks. For testing, a new property is added to allow unsecure connections. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1867>
This commit is contained in:
parent
be02c0e388
commit
a791cfff2b
5 changed files with 59 additions and 50 deletions
|
@ -57,6 +57,7 @@ struct Settings {
|
|||
bind_port: u16,
|
||||
certificate_file: Option<PathBuf>,
|
||||
keep_alive_interval: u64,
|
||||
secure_conn: bool,
|
||||
timeout: u32,
|
||||
transport_config: QuinnQuicTransportConfig,
|
||||
url: String,
|
||||
|
@ -77,6 +78,7 @@ impl Default for Settings {
|
|||
bind_port: DEFAULT_BIND_PORT,
|
||||
certificate_file: None,
|
||||
keep_alive_interval: 0,
|
||||
secure_conn: DEFAULT_SECURE_CONNECTION,
|
||||
timeout: DEFAULT_TIMEOUT,
|
||||
transport_config,
|
||||
url: DEFAULT_ADDR.to_string(),
|
||||
|
@ -131,6 +133,29 @@ impl ElementImpl for QuinnWebTransportClientSrc {
|
|||
|
||||
PAD_TEMPLATES.as_ref()
|
||||
}
|
||||
|
||||
fn change_state(
|
||||
&self,
|
||||
transition: gst::StateChange,
|
||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||
if transition == gst::StateChange::NullToReady {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
|
||||
/*
|
||||
* Fail the state change if a secure connection was requested but
|
||||
* no certificate path was provided.
|
||||
*/
|
||||
if settings.secure_conn && settings.certificate_file.is_none() {
|
||||
gst::error!(
|
||||
CAT,
|
||||
imp = self,
|
||||
"Certificate or private key file not provided for secure connection"
|
||||
);
|
||||
return Err(gst::StateChangeError);
|
||||
}
|
||||
}
|
||||
self.parent_change_state(transition)
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for QuinnWebTransportClientSrc {
|
||||
|
@ -175,6 +200,11 @@ impl ObjectImpl for QuinnWebTransportClientSrc {
|
|||
.blurb("Connection statistics")
|
||||
.read_only()
|
||||
.build(),
|
||||
glib::ParamSpecBoolean::builder("secure-connection")
|
||||
.nick("Use secure connection.")
|
||||
.blurb("Use certificates for QUIC connection. False: Insecure connection, True: Secure connection.")
|
||||
.default_value(DEFAULT_SECURE_CONNECTION)
|
||||
.build(),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -195,6 +225,9 @@ impl ObjectImpl for QuinnWebTransportClientSrc {
|
|||
"timeout" => {
|
||||
settings.timeout = value.get().expect("type checked upstream");
|
||||
}
|
||||
"secure-connection" => {
|
||||
settings.secure_conn = value.get().expect("type checked upstream");
|
||||
}
|
||||
"url" => {
|
||||
settings.url = value.get::<String>().expect("type checked upstream");
|
||||
}
|
||||
|
@ -217,6 +250,7 @@ impl ObjectImpl for QuinnWebTransportClientSrc {
|
|||
"timeout" => settings.timeout.to_value(),
|
||||
"url" => settings.url.to_value(),
|
||||
"use-datagram" => settings.use_datagram.to_value(),
|
||||
"secure-connection" => settings.secure_conn.to_value(),
|
||||
"stats" => {
|
||||
let state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
|
@ -471,7 +505,7 @@ impl QuinnWebTransportClientSrc {
|
|||
server_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 4443), // This will be filled in correctly later
|
||||
server_name: DEFAULT_SERVER_NAME.to_string(),
|
||||
client_addr: Some(client_addr),
|
||||
secure_conn: true,
|
||||
secure_conn: settings.secure_conn,
|
||||
alpns: vec![HTTP3_ALPN.to_string()],
|
||||
certificate_file: settings.certificate_file.clone(),
|
||||
private_key_file: None,
|
||||
|
|
|
@ -21,7 +21,6 @@ use futures::future;
|
|||
use gst::{glib, prelude::*, subclass::prelude::*};
|
||||
use gst_base::subclass::prelude::*;
|
||||
use quinn::{Connection, TransportConfig};
|
||||
use web_transport_quinn::{Request, SendStream, Session};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
use web_transport_quinn::{Request, SendStream, Session};
|
||||
|
@ -55,6 +54,7 @@ struct Settings {
|
|||
use_datagram: bool,
|
||||
certificate_file: Option<PathBuf>,
|
||||
private_key_file: Option<PathBuf>,
|
||||
secure_conn: bool,
|
||||
transport_config: QuinnQuicTransportConfig,
|
||||
drop_buffer_for_datagram: bool,
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ impl Default for Settings {
|
|||
use_datagram: false,
|
||||
certificate_file: None,
|
||||
private_key_file: None,
|
||||
secure_conn: DEFAULT_SECURE_CONNECTION,
|
||||
transport_config,
|
||||
drop_buffer_for_datagram: DEFAULT_DROP_BUFFER_FOR_DATAGRAM,
|
||||
}
|
||||
|
@ -133,11 +134,14 @@ impl ElementImpl for QuinnWebTransportServerSink {
|
|||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||
if transition == gst::StateChange::NullToReady {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
|
||||
/*
|
||||
* WebTransport requires a secure connection, fail the state change if
|
||||
* no certificate paths were provided.
|
||||
* Fail the state change if a secure connection was requested but
|
||||
* no certificate path was provided.
|
||||
*/
|
||||
if settings.certificate_file.is_none() || settings.private_key_file.is_none() {
|
||||
if settings.secure_conn
|
||||
&& (settings.certificate_file.is_none() || settings.private_key_file.is_none())
|
||||
{
|
||||
gst::error!(
|
||||
CAT,
|
||||
imp = self,
|
||||
|
@ -237,6 +241,11 @@ impl ObjectImpl for QuinnWebTransportServerSink {
|
|||
.blurb("Drop buffers when using datagram if buffer size > max datagram size")
|
||||
.default_value(DEFAULT_DROP_BUFFER_FOR_DATAGRAM)
|
||||
.build(),
|
||||
glib::ParamSpecBoolean::builder("secure-connection")
|
||||
.nick("Use secure connection.")
|
||||
.blurb("Use certificates for QUIC connection. False: Insecure connection, True: Secure connection.")
|
||||
.default_value(DEFAULT_SECURE_CONNECTION)
|
||||
.build(),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -299,6 +308,9 @@ impl ObjectImpl for QuinnWebTransportServerSink {
|
|||
"drop-buffer-for-datagram" => {
|
||||
settings.drop_buffer_for_datagram = value.get().expect("type checked upstream");
|
||||
}
|
||||
"secure-connection" => {
|
||||
settings.secure_conn = value.get().expect("type checked upstream");
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
@ -335,6 +347,7 @@ impl ObjectImpl for QuinnWebTransportServerSink {
|
|||
"datagram-send-buffer-size" => {
|
||||
(settings.transport_config.datagram_send_buffer_size as u64).to_value()
|
||||
}
|
||||
"secure-connection" => settings.secure_conn.to_value(),
|
||||
"stats" => {
|
||||
let state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
|
@ -564,6 +577,7 @@ impl QuinnWebTransportServerSink {
|
|||
let (use_datagram, endpoint_config) = {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
|
||||
let secure_conn = settings.secure_conn;
|
||||
let server_addr =
|
||||
make_socket_addr(format!("{}:{}", settings.address, settings.port).as_str())?;
|
||||
|
||||
|
@ -573,7 +587,7 @@ impl QuinnWebTransportServerSink {
|
|||
server_addr,
|
||||
server_name: settings.server_name.clone(),
|
||||
client_addr: None,
|
||||
secure_conn: true,
|
||||
secure_conn,
|
||||
alpns: vec![HTTP3_ALPN.to_string()],
|
||||
certificate_file: settings.certificate_file.clone(),
|
||||
private_key_file: settings.private_key_file.clone(),
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBZjCCAQ2gAwIBAgIUducmm59E2q/s87I6F8uymGvNuM4wCgYIKoZIzj0EAwIw
|
||||
FDESMBAGA1UEAwwJTG9jYWxob3N0MB4XDTI0MTAxNjA4MDExMFoXDTI0MTExNTA4
|
||||
MDExMFowFDESMBAGA1UEAwwJTG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0D
|
||||
AQcDQgAEEmItpfgNKextROvDh4+phcUP3s0jb1OeQHuHnYa5hw5O+FVQf6FtgL6U
|
||||
Zx5fdgl+NIW795ZR/Nt7y9D5H4fxP6M9MDswGgYDVR0RBBMwEYIJbG9jYWxob3N0
|
||||
hwR/AAABMB0GA1UdDgQWBBSLX7qrn+1oorVuolaoiKVBU6irfTAKBggqhkjOPQQD
|
||||
AgNHADBEAiASp7doLyxErcAfUJ3QLxQZ+Rav8+n/Xv7ukisxNr+UuAIgALEzXXsa
|
||||
mN1VcFcbHPcQoTwCFlv/MxKAmaOgJel43tc=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,8 +0,0 @@
|
|||
-----BEGIN EC PARAMETERS-----
|
||||
BggqhkjOPQMBBw==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEINlRLGfOFJfJFhcOYkW1PXw6OPM5qABO0FT158tiI25hoAoGCCqGSM49
|
||||
AwEHoUQDQgAEEmItpfgNKextROvDh4+phcUP3s0jb1OeQHuHnYa5hw5O+FVQf6Ft
|
||||
gL6UZx5fdgl+NIW795ZR/Nt7y9D5H4fxPw==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
use gst::prelude::*;
|
||||
use serial_test::serial;
|
||||
use std::{path::PathBuf, thread};
|
||||
use std::thread;
|
||||
|
||||
fn init() {
|
||||
use std::sync::Once;
|
||||
|
@ -27,40 +27,19 @@ fn make_buffer(content: &[u8]) -> gst::Buffer {
|
|||
buf
|
||||
}
|
||||
|
||||
fn get_certificates_paths() -> (String, String) {
|
||||
let mut certs_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
certs_dir.push("tests");
|
||||
certs_dir.push("certs");
|
||||
|
||||
(
|
||||
certs_dir
|
||||
.join("localhost.crt")
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap(),
|
||||
certs_dir
|
||||
.join("localhost.key")
|
||||
.into_os_string()
|
||||
.into_string()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
fn send_receive(src_pipeline_props: &str, sink_pipeline_props: &str) {
|
||||
init();
|
||||
|
||||
let content = "Hello, world!\n".as_bytes();
|
||||
|
||||
let (cert_path, key_path) = get_certificates_paths();
|
||||
|
||||
let src_pipeline = format!(
|
||||
"quinnwtclientsrc {} certificate-file={} caps=text/plain",
|
||||
src_pipeline_props, cert_path
|
||||
"quinnwtclientsrc {} secure-connection=false",
|
||||
src_pipeline_props
|
||||
);
|
||||
let sink_pipeline = format!(
|
||||
"quinnwtserversink {} server-name=localhost \
|
||||
address=127.0.0.1 certificate-file={} private-key-file={}",
|
||||
sink_pipeline_props, cert_path, key_path
|
||||
address=127.0.0.1 secure-connection=false",
|
||||
sink_pipeline_props
|
||||
);
|
||||
|
||||
thread::spawn(move || {
|
||||
|
|
Loading…
Reference in a new issue