Pass tunnel info into sec-websocket-protocol header
This commit is contained in:
parent
f752ce67fb
commit
259da14d4d
3 changed files with 29 additions and 24 deletions
|
@ -1,4 +1,4 @@
|
|||
use super::{to_host_port, JwtTunnelConfig, JWT_KEY};
|
||||
use super::{to_host_port, JwtTunnelConfig, JWT_HEADER_PREFIX, JWT_KEY};
|
||||
use crate::{LocalToRemote, WsClientConfig};
|
||||
use anyhow::{anyhow, Context};
|
||||
|
||||
|
@ -8,7 +8,7 @@ use fastwebsockets::WebSocket;
|
|||
use futures_util::pin_mut;
|
||||
use http_body_util::Empty;
|
||||
use hyper::body::Incoming;
|
||||
use hyper::header::{AUTHORIZATION, COOKIE, SEC_WEBSOCKET_VERSION, UPGRADE};
|
||||
use hyper::header::{AUTHORIZATION, COOKIE, SEC_WEBSOCKET_PROTOCOL, SEC_WEBSOCKET_VERSION, UPGRADE};
|
||||
use hyper::header::{CONNECTION, HOST, SEC_WEBSOCKET_KEY};
|
||||
use hyper::upgrade::Upgraded;
|
||||
use hyper::{Request, Response};
|
||||
|
@ -42,16 +42,16 @@ pub async fn connect(
|
|||
|
||||
let mut req = Request::builder()
|
||||
.method("GET")
|
||||
.uri(format!(
|
||||
"/{}/events?bearer={}",
|
||||
&client_cfg.http_upgrade_path_prefix,
|
||||
tunnel_to_jwt_token(request_id, tunnel_cfg)
|
||||
))
|
||||
.uri(format!("/{}/events", &client_cfg.http_upgrade_path_prefix,))
|
||||
.header(HOST, &client_cfg.http_header_host)
|
||||
.header(UPGRADE, "websocket")
|
||||
.header(CONNECTION, "upgrade")
|
||||
.header(SEC_WEBSOCKET_KEY, fastwebsockets::handshake::generate_key())
|
||||
.header(SEC_WEBSOCKET_VERSION, "13")
|
||||
.header(
|
||||
SEC_WEBSOCKET_PROTOCOL,
|
||||
format!("v1, {}{}", JWT_HEADER_PREFIX, tunnel_to_jwt_token(request_id, tunnel_cfg)),
|
||||
)
|
||||
.version(hyper::Version::HTTP_11);
|
||||
|
||||
for (k, v) in &client_cfg.http_headers {
|
||||
|
|
|
@ -49,6 +49,7 @@ impl JwtTunnelConfig {
|
|||
}
|
||||
}
|
||||
|
||||
static JWT_HEADER_PREFIX: &str = "authorization.bearer.";
|
||||
static JWT_SECRET: &[u8; 15] = b"champignonfrais";
|
||||
static JWT_KEY: Lazy<(Header, EncodingKey)> =
|
||||
Lazy::new(|| (Header::new(Algorithm::HS256), EncodingKey::from_secret(JWT_SECRET)));
|
||||
|
|
|
@ -10,10 +10,10 @@ use std::pin::Pin;
|
|||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use super::{JwtTunnelConfig, JWT_DECODE};
|
||||
use super::{JwtTunnelConfig, JWT_DECODE, JWT_HEADER_PREFIX};
|
||||
use crate::{socks5, tcp, tls, udp, LocalProtocol, WsServerConfig};
|
||||
use hyper::body::Incoming;
|
||||
use hyper::header::COOKIE;
|
||||
use hyper::header::{COOKIE, SEC_WEBSOCKET_PROTOCOL};
|
||||
use hyper::http::HeaderValue;
|
||||
use hyper::server::conn::http1;
|
||||
use hyper::service::service_fn;
|
||||
|
@ -221,22 +221,23 @@ fn validate_url(
|
|||
|
||||
#[inline]
|
||||
fn extract_tunnel_info(req: &Request<Incoming>) -> Result<TokenData<JwtTunnelConfig>, Response<String>> {
|
||||
let jwt: TokenData<JwtTunnelConfig> = match req.uri().query().unwrap_or_default().split_once('=') {
|
||||
Some(("bearer", jwt)) => {
|
||||
let (validation, decode_key) = JWT_DECODE.deref();
|
||||
match jsonwebtoken::decode(jwt, decode_key, validation) {
|
||||
Ok(jwt) => jwt,
|
||||
err => {
|
||||
error!("error while decoding jwt for tunnel info {:?}", err);
|
||||
return Err(http::Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body("Invalid upgrade request".to_string())
|
||||
.unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
let jwt = req
|
||||
.headers()
|
||||
.get(SEC_WEBSOCKET_PROTOCOL)
|
||||
.and_then(|header| header.to_str().ok())
|
||||
.and_then(|header| header.split_once(JWT_HEADER_PREFIX))
|
||||
.map(|(_prefix, jwt)| jwt)
|
||||
.unwrap_or_default();
|
||||
|
||||
let (validation, decode_key) = JWT_DECODE.deref();
|
||||
let jwt = match jsonwebtoken::decode(jwt, decode_key, validation) {
|
||||
Ok(jwt) => jwt,
|
||||
err => {
|
||||
error!("Missing jwt tunnel config from request {:?}", err);
|
||||
warn!(
|
||||
"error while decoding jwt for tunnel info {:?} header {:?}",
|
||||
err,
|
||||
req.headers().get(SEC_WEBSOCKET_PROTOCOL)
|
||||
);
|
||||
return Err(http::Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body("Invalid upgrade request".to_string())
|
||||
|
@ -358,6 +359,9 @@ async fn server_upgrade(server_config: Arc<WsServerConfig>, mut req: Request<Inc
|
|||
};
|
||||
response.headers_mut().insert(COOKIE, header_val);
|
||||
}
|
||||
response
|
||||
.headers_mut()
|
||||
.insert(SEC_WEBSOCKET_PROTOCOL, HeaderValue::from_static("v1"));
|
||||
|
||||
Response::from_parts(response.into_parts().0, "".to_string())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue