mirror of
https://github.com/warp-tech/warpgate.git
synced 2024-09-20 06:46:17 +08:00
added cranky and removed all .unwrap() usages
This commit is contained in:
parent
3c78ce4888
commit
47518c6253
8
Cranky.toml
Normal file
8
Cranky.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
deny = [
|
||||
"unsafe_code",
|
||||
"clippy::unwrap_used",
|
||||
"clippy::expect_used",
|
||||
"clippy::panic",
|
||||
# "clippy::indexing_slicing",
|
||||
# "clippy::integer_arithmetic",
|
||||
]
|
2
clippy.toml
Normal file
2
clippy.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
avoid-breaking-exported-api = false
|
||||
allow-unwrap-in-tests = true
|
2
justfile
2
justfile
|
@ -10,7 +10,7 @@ fix *ARGS:
|
|||
for p in {{projects}}; do cargo fix -p $p {{ARGS}}; done
|
||||
|
||||
clippy *ARGS:
|
||||
for p in {{projects}}; do cargo clippy -p $p {{ARGS}}; done
|
||||
for p in {{projects}}; do cargo cranky -p $p {{ARGS}}; done
|
||||
|
||||
yarn *ARGS:
|
||||
cd warpgate-web && yarn {{ARGS}}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2022-03-14"
|
||||
channel = "nightly-2022-07-22"
|
||||
|
|
|
@ -3,6 +3,7 @@ mod api;
|
|||
use poem_openapi::OpenApiService;
|
||||
use regex::Regex;
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
pub fn main() {
|
||||
let api_service =
|
||||
OpenApiService::new(api::get(), "Warpgate Web Admin", env!("CARGO_PKG_VERSION"))
|
||||
|
|
|
@ -47,11 +47,13 @@ fn _default_database_url() -> Secret<String> {
|
|||
|
||||
#[inline]
|
||||
fn _default_http_listen() -> ListenEndpoint {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
ListenEndpoint("0.0.0.0:8888".to_socket_addrs().unwrap().next().unwrap())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _default_mysql_listen() -> ListenEndpoint {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
ListenEndpoint("0.0.0.0:33306".to_socket_addrs().unwrap().next().unwrap())
|
||||
}
|
||||
|
||||
|
@ -77,7 +79,7 @@ pub struct TargetSSHOptions {
|
|||
pub auth: SSHTargetAuth,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
pub enum SSHTargetAuth {
|
||||
#[serde(rename = "password")]
|
||||
|
@ -182,7 +184,7 @@ pub enum TargetOptions {
|
|||
WebAdmin(TargetWebAdminOptions),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum UserAuthCredential {
|
||||
#[serde(rename = "password")]
|
||||
|
@ -221,6 +223,7 @@ pub struct Role {
|
|||
}
|
||||
|
||||
fn _default_ssh_listen() -> ListenEndpoint {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
ListenEndpoint("0.0.0.0:2222".to_socket_addrs().unwrap().next().unwrap())
|
||||
}
|
||||
|
||||
|
|
|
@ -232,15 +232,13 @@ impl ConfigProvider for FileConfigProvider {
|
|||
.roles
|
||||
.iter()
|
||||
.map(|x| config.store.roles.iter().find(|y| &y.name == x))
|
||||
.filter(|x| x.is_some())
|
||||
.map(|x| x.unwrap().to_owned())
|
||||
.filter_map(|x| x.to_owned())
|
||||
.collect::<HashSet<_>>();
|
||||
let target_roles = target
|
||||
.allow_roles
|
||||
.iter()
|
||||
.map(|x| config.store.roles.iter().find(|y| &y.name == x))
|
||||
.filter(|x| x.is_some())
|
||||
.map(|x| x.unwrap().to_owned())
|
||||
.filter_map(|x| x.to_owned())
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
let intersect = user_roles.intersection(&target_roles).count() > 0;
|
||||
|
|
|
@ -11,6 +11,8 @@ use crate::Secret;
|
|||
pub fn hash_password(password: &str) -> String {
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
let argon2 = Argon2::default();
|
||||
// Only panics for invalid hash parameters
|
||||
#[allow(clippy::unwrap_used)]
|
||||
argon2
|
||||
.hash_password(password.as_bytes(), &salt)
|
||||
.unwrap()
|
||||
|
|
|
@ -32,6 +32,7 @@ fn get_totp(key: &OtpSecretKey, label: Option<&str>) -> TOTP<OtpExposedSecretKey
|
|||
}
|
||||
|
||||
pub fn verify_totp(code: &str, key: &OtpSecretKey) -> bool {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let time = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
|
|
|
@ -32,7 +32,11 @@ where
|
|||
|
||||
pub fn install_database_logger(database: Arc<Mutex<DatabaseConnection>>) {
|
||||
tokio::spawn(async move {
|
||||
let mut receiver = LOG_SENDER.get().unwrap().subscribe();
|
||||
#[allow(clippy::expect_used)]
|
||||
let mut receiver = LOG_SENDER
|
||||
.get()
|
||||
.expect("Log sender not ready yet")
|
||||
.subscribe();
|
||||
loop {
|
||||
match receiver.recv().await {
|
||||
Err(_) => break,
|
||||
|
|
|
@ -49,9 +49,12 @@ where
|
|||
return
|
||||
};
|
||||
|
||||
let buffer = BytesMut::from(
|
||||
&serde_json::to_vec(&values).expect("Cannot serialize log entry, this is a bug")[..],
|
||||
);
|
||||
let Ok(serialized) = serde_json::to_vec(&values) else {
|
||||
eprintln!("Failed to serialize log entry {values:?}");
|
||||
continue
|
||||
};
|
||||
|
||||
let buffer = BytesMut::from(&serialized[..]);
|
||||
if let Err(error) = socket.send_to(buffer.as_ref(), socket_address).await {
|
||||
error!(%error, is_socket_logging_error=true, "Failed to forward log entry");
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use tracing_core::Field;
|
|||
|
||||
pub type SerializedRecordValuesInner = HashMap<&'static str, String>;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct SerializedRecordValues(SerializedRecordValuesInner);
|
||||
|
||||
impl SerializedRecordValues {
|
||||
|
|
|
@ -30,6 +30,9 @@ pub enum Error {
|
|||
|
||||
#[error("Disabled")]
|
||||
Disabled,
|
||||
|
||||
#[error("Invalid recording path")]
|
||||
InvalidPath,
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -71,7 +74,7 @@ impl SessionRecordings {
|
|||
}
|
||||
|
||||
let path = self.path_for(id, &name);
|
||||
tokio::fs::create_dir_all(&path.parent().unwrap()).await?;
|
||||
tokio::fs::create_dir_all(&path.parent().ok_or(Error::InvalidPath)?).await?;
|
||||
info!(%name, path=?path, "Recording session {}", id);
|
||||
|
||||
let model = {
|
||||
|
|
|
@ -30,7 +30,7 @@ fn test_catch() {
|
|||
let mut caught = false;
|
||||
try_block!({
|
||||
let _: u32 = "asdf".parse()?;
|
||||
panic!();
|
||||
assert!(false)
|
||||
} catch (e: anyhow::Error) {
|
||||
assert_eq!(e.to_string(), "asdf".parse::<i32>().unwrap_err().to_string());
|
||||
caught = true;
|
||||
|
@ -43,6 +43,6 @@ fn test_success() {
|
|||
try_block!({
|
||||
let _: u32 = "123".parse()?;
|
||||
} catch (_e: anyhow::Error) {
|
||||
panic!();
|
||||
assert!(false)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::helpers::rng::get_crypto_rng;
|
|||
pub type SessionId = Uuid;
|
||||
pub type ProtocolName = &'static str;
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct Secret<T>(T);
|
||||
|
||||
impl Secret<String> {
|
||||
|
@ -94,9 +94,7 @@ impl<'de> Deserialize<'de> for ListenEndpoint {
|
|||
})?
|
||||
.next()
|
||||
.ok_or_else(|| {
|
||||
return serde::de::Error::custom(format!(
|
||||
"failed to resolve {v} into a TCP endpoint"
|
||||
));
|
||||
serde::de::Error::custom(format!("failed to resolve {v} into a TCP endpoint"))
|
||||
})?;
|
||||
Ok(Self(v))
|
||||
}
|
||||
|
|
|
@ -151,39 +151,6 @@ pub trait DatabaseError: 'static + Send + Sync + StdError {
|
|||
}
|
||||
|
||||
impl dyn DatabaseError {
|
||||
/// Downcast a reference to this generic database error to a specific
|
||||
/// database error type.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the database error type is not `E`. This is a deliberate contrast from
|
||||
/// `Error::downcast_ref` which returns `Option<&E>`. In normal usage, you should know the
|
||||
/// specific error type. In other cases, use `try_downcast_ref`.
|
||||
pub fn downcast_ref<E: DatabaseError>(&self) -> &E {
|
||||
self.try_downcast_ref().unwrap_or_else(|| {
|
||||
panic!(
|
||||
"downcast to wrong DatabaseError type; original error: {}",
|
||||
self
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Downcast this generic database error to a specific database error type.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the database error type is not `E`. This is a deliberate contrast from
|
||||
/// `Error::downcast` which returns `Option<E>`. In normal usage, you should know the
|
||||
/// specific error type. In other cases, use `try_downcast`.
|
||||
pub fn downcast<E: DatabaseError>(self: Box<Self>) -> Box<E> {
|
||||
self.try_downcast().unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"downcast to wrong DatabaseError type; original error: {}",
|
||||
e
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Downcast a reference to this generic database error to a specific
|
||||
/// database error type.
|
||||
#[inline]
|
||||
|
@ -195,6 +162,7 @@ impl dyn DatabaseError {
|
|||
#[inline]
|
||||
pub fn try_downcast<E: DatabaseError>(self: Box<Self>) -> StdResult<Box<E>, Box<Self>> {
|
||||
if self.as_error().is::<E>() {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
Ok(self.into_error().downcast().unwrap())
|
||||
} else {
|
||||
Err(self)
|
||||
|
|
|
@ -41,7 +41,7 @@ impl BufExt for Bytes {
|
|||
|
||||
fn get_str_nul(&mut self) -> Result<String, Error> {
|
||||
self.get_bytes_nul().and_then(|bytes| {
|
||||
from_utf8(&*bytes)
|
||||
from_utf8(&bytes)
|
||||
.map(ToOwned::to_owned)
|
||||
.map_err(|err| err_protocol!("{}", err))
|
||||
})
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::err_protocol;
|
|||
use crate::error::Error;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
pub enum AuthPlugin {
|
||||
MySqlClearPassword,
|
||||
MySqlNativePassword,
|
||||
|
|
|
@ -31,7 +31,7 @@ impl Decode<'_, Capabilities> for ErrPacket {
|
|||
|
||||
if capabilities.contains(Capabilities::PROTOCOL_41) {
|
||||
// If the next byte is '#' then we have a SQL STATE
|
||||
if buf.get(0) == Some(&0x23) {
|
||||
if buf.first() == Some(&0x23) {
|
||||
buf.advance(1);
|
||||
sql_state = Some(buf.get_str(5)?);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ bitflags! {
|
|||
|
||||
// https://dev.mysql.com/doc/internals/en/com-query-response.html#column-type
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[repr(u8)]
|
||||
pub enum ColumnType {
|
||||
|
|
|
@ -6,6 +6,7 @@ mod session;
|
|||
mod session_handle;
|
||||
use poem_openapi::OpenApiService;
|
||||
|
||||
#[allow(clippy::unwrap_used)]
|
||||
pub fn main() {
|
||||
let api_service = OpenApiService::new(
|
||||
api::get(),
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use anyhow::Result;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use cookie::Cookie;
|
||||
use delegate::delegate;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
|
@ -7,9 +11,6 @@ use http::uri::{Authority, Scheme};
|
|||
use http::Uri;
|
||||
use poem::web::websocket::{CloseCode, Message, WebSocket};
|
||||
use poem::{Body, IntoResponse, Request, Response};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::str::FromStr;
|
||||
use tokio_tungstenite::{connect_async_with_config, tungstenite};
|
||||
use tracing::*;
|
||||
use warpgate_common::{try_block, TargetHTTPOptions};
|
||||
|
@ -75,33 +76,40 @@ lazy_static::lazy_static! {
|
|||
};
|
||||
}
|
||||
|
||||
fn construct_uri(req: &Request, options: &TargetHTTPOptions, websocket: bool) -> Uri {
|
||||
let target_uri = Uri::try_from(options.url.clone()).unwrap();
|
||||
fn construct_uri(req: &Request, options: &TargetHTTPOptions, websocket: bool) -> Result<Uri> {
|
||||
let target_uri = Uri::try_from(options.url.clone())?;
|
||||
let source_uri = req.uri().clone();
|
||||
|
||||
let authority = target_uri.authority().unwrap().to_string();
|
||||
let authority = authority.split("@").last().unwrap();
|
||||
let authority: Authority = authority.try_into().unwrap();
|
||||
let authority = target_uri
|
||||
.authority()
|
||||
.context("No authority in the URL")?
|
||||
.to_string();
|
||||
let authority = authority.split("@").last().context("Authority is empty")?;
|
||||
let authority: Authority = authority.try_into()?;
|
||||
let mut uri = http::uri::Builder::new()
|
||||
.authority(authority)
|
||||
.path_and_query(source_uri.path_and_query().unwrap().clone());
|
||||
.path_and_query(
|
||||
source_uri
|
||||
.path_and_query()
|
||||
.context("No path in the URL")?
|
||||
.clone(),
|
||||
);
|
||||
|
||||
uri = uri.scheme(target_uri.scheme().unwrap().clone());
|
||||
let scheme = target_uri.scheme().context("No scheme in the URL")?;
|
||||
uri = uri.scheme(scheme.clone());
|
||||
|
||||
if websocket {
|
||||
uri = uri.scheme(
|
||||
Scheme::from_str(
|
||||
if target_uri.scheme().unwrap() == &Scheme::from_str("http").unwrap() {
|
||||
"ws"
|
||||
} else {
|
||||
"wss"
|
||||
},
|
||||
)
|
||||
Scheme::from_str(if scheme == &Scheme::from_str("http").unwrap() {
|
||||
"ws"
|
||||
} else {
|
||||
"wss"
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
uri.build().unwrap()
|
||||
Ok(uri.build()?)
|
||||
}
|
||||
|
||||
fn copy_client_response<R: SomeResponse>(
|
||||
|
@ -131,20 +139,23 @@ fn rewrite_request<B: SomeRequestBuilder>(mut req: B, options: &TargetHTTPOption
|
|||
}
|
||||
|
||||
fn rewrite_response(resp: &mut Response, options: &TargetHTTPOptions) -> Result<()> {
|
||||
let target_uri = Uri::try_from(options.url.clone()).unwrap();
|
||||
let target_uri = Uri::try_from(options.url.clone())?;
|
||||
let headers = resp.headers_mut();
|
||||
|
||||
if let Some(value) = headers.get_mut(http::header::LOCATION) {
|
||||
let redirect_uri = Uri::try_from(value.as_bytes()).unwrap();
|
||||
let redirect_uri = Uri::try_from(value.as_bytes())?;
|
||||
if redirect_uri.authority() == target_uri.authority() {
|
||||
let old_value = value.clone();
|
||||
*value = Uri::builder()
|
||||
.path_and_query(redirect_uri.path_and_query().unwrap().clone())
|
||||
.build()
|
||||
.unwrap()
|
||||
.path_and_query(
|
||||
redirect_uri
|
||||
.path_and_query()
|
||||
.context("No path in URL")?
|
||||
.clone(),
|
||||
)
|
||||
.build()?
|
||||
.to_string()
|
||||
.parse()
|
||||
.unwrap();
|
||||
.parse()?;
|
||||
debug!("Rewrote a redirect from {:?} to {:?}", old_value, value);
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +185,8 @@ fn copy_server_request<B: SomeRequestBuilder>(req: &Request, mut target: B) -> B
|
|||
req.headers()
|
||||
.get_all(k)
|
||||
.iter()
|
||||
.map(|v| v.to_str().unwrap().to_string())
|
||||
.map(|v| v.to_str().map(|x| x.to_string()))
|
||||
.filter_map(|x| x.ok())
|
||||
.collect::<Vec<_>>()
|
||||
.join("; "),
|
||||
);
|
||||
|
@ -187,7 +199,7 @@ pub async fn proxy_normal_request(
|
|||
body: Body,
|
||||
options: &TargetHTTPOptions,
|
||||
) -> poem::Result<Response> {
|
||||
let uri = construct_uri(req, &options, false).to_string();
|
||||
let uri = construct_uri(req, &options, false)?.to_string();
|
||||
|
||||
tracing::debug!("URI: {:?}", uri);
|
||||
|
||||
|
@ -195,15 +207,18 @@ pub async fn proxy_normal_request(
|
|||
.redirect(reqwest::redirect::Policy::none())
|
||||
.connection_verbose(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
.context("Could not build request")?;
|
||||
let mut client_request = client.request(req.method().into(), uri.clone());
|
||||
|
||||
client_request = copy_server_request(&req, client_request);
|
||||
client_request = rewrite_request(client_request, options)?;
|
||||
client_request = client_request.body(reqwest::Body::wrap_stream(body.into_bytes_stream()));
|
||||
|
||||
let client_request = client_request.build().unwrap();
|
||||
let client_response = client.execute(client_request).await.unwrap();
|
||||
let client_request = client_request.build().context("Could not build request")?;
|
||||
let client_response = client
|
||||
.execute(client_request)
|
||||
.await
|
||||
.context("Could not execute request")?;
|
||||
let status = client_response.status().clone();
|
||||
|
||||
let mut response: Response = "".into();
|
||||
|
@ -275,7 +290,7 @@ pub async fn proxy_websocket_request(
|
|||
ws: WebSocket,
|
||||
options: &TargetHTTPOptions,
|
||||
) -> poem::Result<impl IntoResponse> {
|
||||
let uri = construct_uri(req, &options, true);
|
||||
let uri = construct_uri(req, &options, true)?;
|
||||
proxy_ws_inner(req, ws, uri.clone(), options)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
use crate::common::{PROTOCOL_NAME, SESSION_MAX_AGE};
|
||||
use crate::session_handle::{
|
||||
HttpSessionHandle, SessionHandleCommand, WarpgateServerHandleFromRequest,
|
||||
};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use poem::session::{Session, SessionStorage};
|
||||
use poem::web::{Data, RemoteAddr};
|
||||
use poem::{FromRequest, Request};
|
||||
use serde_json::Value;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::sync::Mutex;
|
||||
use tracing::*;
|
||||
use warpgate_common::{Services, SessionId, WarpgateServerHandle, SessionStateInit};
|
||||
use warpgate_common::{Services, SessionId, SessionStateInit, WarpgateServerHandle};
|
||||
|
||||
use crate::common::{PROTOCOL_NAME, SESSION_MAX_AGE};
|
||||
use crate::session_handle::{
|
||||
HttpSessionHandle, SessionHandleCommand, WarpgateServerHandleFromRequest,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SharedSessionStorage(pub Arc<Mutex<Box<dyn SessionStorage>>>);
|
||||
|
@ -124,7 +126,9 @@ impl SessionMiddleware {
|
|||
|
||||
session.set(SESSION_ID_SESSION_KEY, id);
|
||||
|
||||
let this = self.this.upgrade().unwrap();
|
||||
let Some(this) = self.this.upgrade() else {
|
||||
return Err(anyhow::anyhow!("Invalid session state").into())
|
||||
};
|
||||
tokio::spawn({
|
||||
let session_storage = (*session_storage).clone();
|
||||
let poem_session_id: Option<String> = session.get(POEM_SESSION_ID_SESSION_KEY);
|
||||
|
|
|
@ -125,9 +125,9 @@ impl MySqlClient {
|
|||
let Some(response) = stream.recv().await? else {
|
||||
return Err(MySqlError::Eof)
|
||||
};
|
||||
if response.get(0) == Some(&0) || response.get(0) == Some(&0xfe) {
|
||||
if response.first() == Some(&0) || response.first() == Some(&0xfe) {
|
||||
debug!("Authorized");
|
||||
} else if response.get(0) == Some(&0xff) {
|
||||
} else if response.first() == Some(&0xff) {
|
||||
let error = ErrPacket::decode_with(response, options.capabilities)?;
|
||||
return Err(MySqlError::ProtocolError(format!(
|
||||
"handshake failed: {:?}",
|
||||
|
@ -136,7 +136,7 @@ impl MySqlClient {
|
|||
} else {
|
||||
return Err(MySqlError::ProtocolError(format!(
|
||||
"unknown response type {:?}",
|
||||
response.get(0)
|
||||
response.first()
|
||||
)));
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ impl MySqlSession {
|
|||
return Err(MySqlError::Eof);
|
||||
};
|
||||
let password = Secret::new(response.clone().get_str_nul()?);
|
||||
return self.run_authorization(resp, password).await;
|
||||
self.run_authorization(resp, password).await
|
||||
}
|
||||
|
||||
async fn send_error(&mut self, code: u16, message: &str) -> Result<(), MySqlError> {
|
||||
|
@ -209,11 +209,9 @@ impl MySqlSession {
|
|||
);
|
||||
return fail(&mut self).await;
|
||||
}
|
||||
return self.run_authorized(handshake, username, target_name).await;
|
||||
}
|
||||
AuthResult::Rejected | AuthResult::OtpNeeded => {
|
||||
return fail(&mut self).await;
|
||||
self.run_authorized(handshake, username, target_name).await
|
||||
}
|
||||
AuthResult::Rejected | AuthResult::OtpNeeded => fail(&mut self).await,
|
||||
}
|
||||
}
|
||||
AuthSelector::Ticket { secret } => {
|
||||
|
@ -231,11 +229,10 @@ impl MySqlSession {
|
|||
.await
|
||||
.map_err(MySqlError::other)?;
|
||||
|
||||
return self
|
||||
.run_authorized(handshake, ticket.username, ticket.target)
|
||||
.await;
|
||||
self.run_authorized(handshake, ticket.username, ticket.target)
|
||||
.await
|
||||
}
|
||||
_ => return fail(&mut self).await,
|
||||
_ => fail(&mut self).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,10 +294,9 @@ impl MySqlSession {
|
|||
}
|
||||
|
||||
let span = self.make_logging_span();
|
||||
return self
|
||||
.run_authorized_inner(handshake, mysql_options)
|
||||
self.run_authorized_inner(handshake, mysql_options)
|
||||
.instrument(span)
|
||||
.await;
|
||||
.await
|
||||
}
|
||||
|
||||
async fn run_authorized_inner(
|
||||
|
@ -341,7 +337,7 @@ impl MySqlSession {
|
|||
};
|
||||
trace!(?payload, "server got packet");
|
||||
|
||||
let com = payload.get(0);
|
||||
let com = payload.first();
|
||||
|
||||
// COM_QUERY
|
||||
if com == Some(&0x03) {
|
||||
|
@ -359,7 +355,7 @@ impl MySqlSession {
|
|||
trace!(?response, "client got packet");
|
||||
self.stream.push(&&response[..], ())?;
|
||||
self.stream.flush().await?;
|
||||
if let Some(com) = response.get(0) {
|
||||
if let Some(com) = response.first() {
|
||||
if com == &0xfe {
|
||||
if self.capabilities.contains(Capabilities::DEPRECATE_EOF) {
|
||||
break;
|
||||
|
@ -415,7 +411,7 @@ impl MySqlSession {
|
|||
trace!(?response, "client got packet");
|
||||
self.stream.push(&&response[..], ())?;
|
||||
self.stream.flush().await?;
|
||||
if let Some(com) = response.get(0) {
|
||||
if let Some(com) = response.first() {
|
||||
if com == &0 || com == &0xff || com == &0xfe {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fs::{create_dir_all, File};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use russh_keys::key::{KeyPair, SignatureHash};
|
||||
use russh_keys::{encode_pkcs8_pem, load_secret_key};
|
||||
use tracing::*;
|
||||
|
@ -22,7 +22,7 @@ pub fn generate_host_keys(config: &WarpgateConfig) -> Result<()> {
|
|||
let key_path = path.join("host-ed25519");
|
||||
if !key_path.exists() {
|
||||
info!("Generating Ed25519 host key");
|
||||
let key = KeyPair::generate_ed25519().unwrap();
|
||||
let key = KeyPair::generate_ed25519().context("Failed to generate Ed25519 host key")?;
|
||||
let f = File::create(key_path)?;
|
||||
encode_pkcs8_pem(&key, f)?;
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ pub fn generate_host_keys(config: &WarpgateConfig) -> Result<()> {
|
|||
let key_path = path.join("host-rsa");
|
||||
if !key_path.exists() {
|
||||
info!("Generating RSA host key");
|
||||
let key = KeyPair::generate_rsa(4096, SignatureHash::SHA2_512).unwrap();
|
||||
let key = KeyPair::generate_rsa(4096, SignatureHash::SHA2_512)
|
||||
.context("Failed to generate RSA key")?;
|
||||
let f = File::create(key_path)?;
|
||||
encode_pkcs8_pem(&key, f)?;
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ pub fn generate_client_keys(config: &WarpgateConfig) -> Result<()> {
|
|||
let key_path = path.join("client-ed25519");
|
||||
if !key_path.exists() {
|
||||
info!("Generating Ed25519 client key");
|
||||
let key = KeyPair::generate_ed25519().unwrap();
|
||||
let key = KeyPair::generate_ed25519().context("Failed to generate Ed25519 client key")?;
|
||||
let f = File::create(key_path)?;
|
||||
encode_pkcs8_pem(&key, f)?;
|
||||
}
|
||||
|
@ -67,7 +68,8 @@ pub fn generate_client_keys(config: &WarpgateConfig) -> Result<()> {
|
|||
let key_path = path.join("client-rsa");
|
||||
if !key_path.exists() {
|
||||
info!("Generating RSA client key");
|
||||
let key = KeyPair::generate_rsa(4096, SignatureHash::SHA2_512).unwrap();
|
||||
let key = KeyPair::generate_rsa(4096, SignatureHash::SHA2_512)
|
||||
.context("Failed to generate RSA client key")?;
|
||||
let f = File::create(key_path)?;
|
||||
encode_pkcs8_pem(&key, f)?;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ impl ServerSession {
|
|||
pub async fn maybe_connect_remote(&mut self) -> Result<()> {
|
||||
match self.target.clone() {
|
||||
TargetSelection::None => {
|
||||
panic!("Target not set");
|
||||
anyhow::bail!("Invalid session state (target not set)")
|
||||
}
|
||||
TargetSelection::NotFound(name) => {
|
||||
self.emit_service_message(&format!("Selected target not found: {name}"))
|
||||
|
@ -585,6 +585,7 @@ impl ServerSession {
|
|||
.traffic_recorder_for(¶ms.host_to_connect, params.port_to_connect)
|
||||
.await;
|
||||
if let Some(recorder) = recorder {
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let mut recorder = recorder.connection(TrafficConnectionParams {
|
||||
dst_addr: Ipv4Addr::from_str("2.2.2.2").unwrap(),
|
||||
dst_port: params.port_to_connect as u16,
|
||||
|
@ -630,7 +631,7 @@ impl ServerSession {
|
|||
let _ = self
|
||||
.session_handle
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.context("Invalid session state")?
|
||||
.channel_success(server_channel_id.0)
|
||||
.await;
|
||||
self.pty_channels.push(channel_id);
|
||||
|
@ -790,7 +791,7 @@ impl ServerSession {
|
|||
let _ = self
|
||||
.session_handle
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.context("Invalid session state")?
|
||||
.channel_success(server_channel_id.0)
|
||||
.await;
|
||||
let _ = self.maybe_connect_remote().await;
|
||||
|
@ -1099,8 +1100,7 @@ impl ServerSession {
|
|||
let channels = all_channels
|
||||
.into_iter()
|
||||
.map(|x| self.map_channel_reverse(&x))
|
||||
.filter(|x| x.is_ok())
|
||||
.map(|x| x.unwrap())
|
||||
.filter_map(|x| x.ok())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let _ = self
|
||||
|
|
|
@ -29,7 +29,7 @@ pub fn load_config(path: &Path, secure: bool) -> Result<WarpgateConfig> {
|
|||
|
||||
let config = WarpgateConfig {
|
||||
store,
|
||||
paths_relative_to: path.parent().unwrap().to_path_buf(),
|
||||
paths_relative_to: path.parent().context("FS root reached")?.to_path_buf(),
|
||||
};
|
||||
|
||||
info!(
|
||||
|
@ -83,7 +83,7 @@ pub async fn watch_config<P: AsRef<Path>>(
|
|||
) -> Result<()> {
|
||||
let (tx, mut rx) = mpsc::channel(1);
|
||||
let mut watcher = RecommendedWatcher::new(move |res| {
|
||||
tx.blocking_send(res).unwrap();
|
||||
let _ = tx.blocking_send(res);
|
||||
})?;
|
||||
watcher.configure(notify::Config::PreciseEvents(true))?;
|
||||
watcher.watch(path.as_ref(), RecursiveMode::NonRecursive)?;
|
||||
|
|
|
@ -14,8 +14,7 @@ pub async fn init_logging(config: Option<&WarpgateConfig>) {
|
|||
std::env::set_var("RUST_LOG", "warpgate=info")
|
||||
}
|
||||
|
||||
let offset = UtcOffset::current_local_offset()
|
||||
.unwrap_or_else(|_| UtcOffset::from_whole_seconds(0).unwrap());
|
||||
let offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC);
|
||||
|
||||
let env_filter = Arc::new(EnvFilter::from_default_env());
|
||||
let enable_colors = console::user_attended();
|
||||
|
@ -40,6 +39,7 @@ pub async fn init_logging(config: Option<&WarpgateConfig>) {
|
|||
.with_ansi(enable_colors)
|
||||
.with_timer(OffsetTime::new(
|
||||
offset,
|
||||
#[allow(clippy::unwrap_used)]
|
||||
format_description::parse("[day].[month].[year] [hour]:[minute]:[second]")
|
||||
.unwrap(),
|
||||
))
|
||||
|
@ -56,6 +56,7 @@ pub async fn init_logging(config: Option<&WarpgateConfig>) {
|
|||
.with_target(false)
|
||||
.with_timer(OffsetTime::new(
|
||||
offset,
|
||||
#[allow(clippy::unwrap_used)]
|
||||
format_description::parse("[hour]:[minute]:[second]").unwrap(),
|
||||
))
|
||||
.with_filter(dynamic_filter_fn(move |m, c| {
|
||||
|
|
Loading…
Reference in a new issue