added test-target support for HTTP and MySQL targets

This commit is contained in:
Eugene Pankov 2022-07-29 20:02:10 +02:00
parent 47e245f785
commit 112a6581f0
No known key found for this signature in database
GPG key ID: 5896FCBBDD1CF4F4
6 changed files with 63 additions and 8 deletions

View file

@ -24,5 +24,5 @@ pub enum TargetTestError {
#[async_trait]
pub trait ProtocolServer {
async fn run(self, address: SocketAddr) -> Result<()>;
async fn test_target(self, target: Target) -> Result<(), TargetTestError>;
async fn test_target(&self, target: Target) -> Result<(), TargetTestError>;
}

View file

@ -29,7 +29,7 @@ use tokio::sync::Mutex;
use tracing::*;
use warpgate_admin::admin_api_app;
use warpgate_common::{
ProtocolServer, Services, Target, TargetTestError, TlsCertificateAndPrivateKey,
ProtocolServer, Services, Target, TargetOptions, TargetTestError, TlsCertificateAndPrivateKey,
TlsCertificateBundle, TlsPrivateKey,
};
use warpgate_web::Assets;
@ -166,7 +166,16 @@ impl ProtocolServer for HTTPProtocolServer {
Ok(())
}
async fn test_target(self, _target: Target) -> Result<(), TargetTestError> {
async fn test_target(&self, target: Target) -> Result<(), TargetTestError> {
let TargetOptions::Http(options) = target.options else {
return Err(TargetTestError::Misconfigured("Not an HTTP target".to_owned()));
};
let request = poem::Request::builder().uri_str("http://host/").finish();
crate::proxy::proxy_normal_request(&request, poem::Body::empty(), &options)
.await
.map_err(|e| {
return TargetTestError::ConnectionError(format!("{e}"));
})?;
Ok(())
}
}

View file

@ -29,6 +29,30 @@ pub struct ConnectionOptions {
pub capabilities: Capabilities,
}
impl Default for ConnectionOptions {
fn default() -> Self {
ConnectionOptions {
collation: 33,
database: None,
max_packet_size: 0xffff_ffff,
capabilities: Capabilities::PROTOCOL_41
| Capabilities::PLUGIN_AUTH
| Capabilities::FOUND_ROWS
| Capabilities::LONG_FLAG
| Capabilities::NO_SCHEMA
| Capabilities::PLUGIN_AUTH_LENENC_DATA
| Capabilities::CONNECT_WITH_DB
| Capabilities::SESSION_TRACK
| Capabilities::IGNORE_SPACE
| Capabilities::INTERACTIVE
| Capabilities::TRANSACTIONS
| Capabilities::DEPRECATE_EOF
| Capabilities::SECURE_CONNECTION
| Capabilities::SSL,
}
}
}
impl MySqlClient {
pub async fn connect(
target: &TargetMySqlOptions,

View file

@ -12,12 +12,13 @@ use std::sync::Arc;
use anyhow::{Context, Result};
use async_trait::async_trait;
use client::{ConnectionOptions, MySqlClient};
use rustls::server::NoClientAuth;
use rustls::ServerConfig;
use tokio::net::TcpListener;
use tracing::*;
use warpgate_common::{
ProtocolServer, Services, SessionStateInit, Target, TargetTestError,
ProtocolServer, Services, SessionStateInit, Target, TargetOptions, TargetTestError,
TlsCertificateAndPrivateKey, TlsCertificateBundle, TlsPrivateKey,
};
@ -108,7 +109,13 @@ impl ProtocolServer for MySQLProtocolServer {
}
}
async fn test_target(self, _target: Target) -> Result<(), TargetTestError> {
async fn test_target(&self, target: Target) -> Result<(), TargetTestError> {
let TargetOptions::MySql(options) = target.options else {
return Err(TargetTestError::Misconfigured("Not a MySQL target".to_owned()));
};
MySqlClient::connect(&options, ConnectionOptions::default())
.await
.map_err(|e| TargetTestError::ConnectionError(format!("{e}")))?;
Ok(())
}
}

View file

@ -47,7 +47,7 @@ impl ProtocolServer for SSHProtocolServer {
run_server(self.services, address).await
}
async fn test_target(self, target: Target) -> Result<(), TargetTestError> {
async fn test_target(&self, target: Target) -> Result<(), TargetTestError> {
let TargetOptions::Ssh(ssh_options) = target.options else {
return Err(TargetTestError::Misconfigured("Not an SSH target".to_owned()));
};

View file

@ -1,6 +1,6 @@
use anyhow::Result;
use tracing::*;
use warpgate_common::{ProtocolServer, Services, Target, TargetTestError};
use warpgate_common::{ProtocolServer, Services, Target, TargetOptions, TargetTestError};
use crate::config::load_config;
@ -19,7 +19,22 @@ pub(crate) async fn command(cli: &crate::Cli, target_name: &String) -> Result<()
let services = Services::new(config.clone()).await?;
let s = warpgate_protocol_ssh::SSHProtocolServer::new(&services).await?;
let s: Box<dyn ProtocolServer> = match target.options {
TargetOptions::Ssh(_) => {
Box::new(warpgate_protocol_ssh::SSHProtocolServer::new(&services).await?)
}
TargetOptions::Http(_) => {
Box::new(warpgate_protocol_http::HTTPProtocolServer::new(&services).await?)
}
TargetOptions::MySql(_) => {
Box::new(warpgate_protocol_mysql::MySQLProtocolServer::new(&services).await?)
}
TargetOptions::WebAdmin(_) => {
error!("Unsupported target type");
return Ok(());
}
};
match s.test_target(target).await {
Err(TargetTestError::AuthenticationError) => {
error!("Authentication failed");