Added CGI vars AUTH_TYPE, REMOTE_USER and TLS_CLIENT_HASH
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gemserv"
|
name = "gemserv"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
authors = ["int 80h <int@80h.dev>"]
|
authors = ["int 80h <int@80h.dev>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
6
README
6
README
@@ -69,3 +69,9 @@ config file under "cgienv"
|
|||||||
- REMOTE_PORT
|
- REMOTE_PORT
|
||||||
- QUERY_STRING
|
- QUERY_STRING
|
||||||
- PATH_INFO
|
- PATH_INFO
|
||||||
|
|
||||||
|
TLS variables
|
||||||
|
- AUTH_TYPE
|
||||||
|
- TLS_CLIENT_HASH
|
||||||
|
- REMOTE_USER
|
||||||
|
|
||||||
|
|||||||
28
src/cgi.rs
28
src/cgi.rs
@@ -19,9 +19,10 @@ use crate::config;
|
|||||||
use crate::conn;
|
use crate::conn;
|
||||||
use crate::logger;
|
use crate::logger;
|
||||||
use crate::status::Status;
|
use crate::status::Status;
|
||||||
|
use crate::util;
|
||||||
|
|
||||||
#[cfg(any(feature = "cgi", feature = "scgi"))]
|
#[cfg(any(feature = "cgi", feature = "scgi"))]
|
||||||
fn envs(peer_addr: SocketAddr, srv: &config::ServerCfg, url: &url::Url) -> HashMap<String, String> {
|
fn envs(peer_addr: SocketAddr, x509: Option<openssl::x509::X509>, srv: &config::ServerCfg, url: &url::Url) -> HashMap<String, String> {
|
||||||
let mut envs = HashMap::new();
|
let mut envs = HashMap::new();
|
||||||
envs.insert("GATEWAY_INTERFACE".to_string(), "CGI/1.1".to_string());
|
envs.insert("GATEWAY_INTERFACE".to_string(), "CGI/1.1".to_string());
|
||||||
envs.insert("GEMINI_URL".to_string(), url.to_string());
|
envs.insert("GEMINI_URL".to_string(), url.to_string());
|
||||||
@@ -38,6 +39,24 @@ fn envs(peer_addr: SocketAddr, srv: &config::ServerCfg, url: &url::Url) -> HashM
|
|||||||
envs.insert("QUERY_STRING".to_string(), q.to_string());
|
envs.insert("QUERY_STRING".to_string(), q.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match x509 {
|
||||||
|
Some(x) => {
|
||||||
|
envs.insert("AUTH_TYPE".to_string(), "Certificate".to_string());
|
||||||
|
|
||||||
|
let cn = x.subject_name().entries_by_nid(openssl::nid::Nid::COMMONNAME);
|
||||||
|
for c in cn {
|
||||||
|
let cd = match c.data().as_utf8() {
|
||||||
|
Ok(n) => n.to_string(),
|
||||||
|
_ => "".to_string(),
|
||||||
|
};
|
||||||
|
envs.insert("REMOTE_USER".to_string(), cd);
|
||||||
|
}
|
||||||
|
|
||||||
|
envs.insert("TLS_CLIENT_HASH".to_string(), util::fingerhex(&x));
|
||||||
|
},
|
||||||
|
None => {},
|
||||||
|
}
|
||||||
|
|
||||||
match &srv.server.cgienv {
|
match &srv.server.cgienv {
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
for (k, v) in c.iter() {
|
for (k, v) in c.iter() {
|
||||||
@@ -76,7 +95,9 @@ pub async fn cgi(
|
|||||||
script_name: String,
|
script_name: String,
|
||||||
path_info: String
|
path_info: String
|
||||||
) -> Result<(), io::Error> {
|
) -> Result<(), io::Error> {
|
||||||
let mut envs = envs(con.peer_addr, srv, &url);
|
|
||||||
|
let x509 = con.stream.ssl().peer_certificate();
|
||||||
|
let mut envs = envs(con.peer_addr, x509, srv, &url);
|
||||||
envs.insert("SCRIPT_NAME".into(), script_name);
|
envs.insert("SCRIPT_NAME".into(), script_name);
|
||||||
envs.insert("PATH_INFO".into(), path_info);
|
envs.insert("PATH_INFO".into(), path_info);
|
||||||
|
|
||||||
@@ -141,7 +162,8 @@ pub async fn scgi(addr: String, u: url::Url, mut con: conn::Connection, srv: &co
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let envs = envs(con.peer_addr, srv, &u);
|
let x509 = con.stream.ssl().peer_certificate();
|
||||||
|
let envs = envs(con.peer_addr, x509, srv, &u);
|
||||||
let len = 0usize;
|
let len = 0usize;
|
||||||
let mut byt = String::from(format!("CONTENT_LENGTH\x00{}\x00SCGI\x001\x00
|
let mut byt = String::from(format!("CONTENT_LENGTH\x00{}\x00SCGI\x001\x00
|
||||||
RQUEST_METHOD\x00POST\x00REQUEST_URI\x00{}\x00", len, u.path()));
|
RQUEST_METHOD\x00POST\x00REQUEST_URI\x00{}\x00", len, u.path()));
|
||||||
|
|||||||
@@ -432,6 +432,7 @@ fn main() -> io::Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let srv = match stream.ssl().servername(NameType::HOST_NAME) {
|
let srv = match stream.ssl().servername(NameType::HOST_NAME) {
|
||||||
Some(s) => match cmap.get(s) {
|
Some(s) => match cmap.get(s) {
|
||||||
Some(ss) => ss,
|
Some(ss) => ss,
|
||||||
|
|||||||
12
src/tls.rs
12
src/tls.rs
@@ -7,17 +7,19 @@ use openssl::ssl::NameType;
|
|||||||
use openssl::ssl::SniError;
|
use openssl::ssl::SniError;
|
||||||
use openssl::ssl::SslContextBuilder;
|
use openssl::ssl::SslContextBuilder;
|
||||||
use openssl::ssl::SslVersion;
|
use openssl::ssl::SslVersion;
|
||||||
|
use openssl::ssl::SslVerifyMode;
|
||||||
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
|
|
||||||
pub fn acceptor_conf(cfg: config::Config) -> Result<SslAcceptor, ErrorStack> {
|
pub fn acceptor_conf(cfg: config::Config) -> Result<SslAcceptor, ErrorStack> {
|
||||||
let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
|
let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls_server())?;
|
||||||
acceptor.set_min_proto_version(Some(SslVersion::TLS1_2))?;
|
acceptor.set_min_proto_version(Some(SslVersion::TLS1_2))?;
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
let mut num = 1;
|
let mut num = 1;
|
||||||
for server in cfg.server.iter() {
|
for server in cfg.server.iter() {
|
||||||
let mut ctx = SslContextBuilder::new(SslMethod::tls())?;
|
let mut ctx = SslContextBuilder::new(SslMethod::tls_server())?;
|
||||||
|
ctx.set_verify(SslVerifyMode::NONE);
|
||||||
match ctx.set_private_key_file(&server.key, SslFiletype::PEM) {
|
match ctx.set_private_key_file(&server.key, SslFiletype::PEM) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -55,7 +57,13 @@ pub fn acceptor_conf(cfg: config::Config) -> Result<SslAcceptor, ErrorStack> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.expect("Can't get sni");
|
.expect("Can't get sni");
|
||||||
|
// for client certs we don't have anything to verify right now?
|
||||||
|
ssl.set_verify_callback(SslVerifyMode::PEER, |_ver, _store| -> bool {
|
||||||
|
return true
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(acceptor.build())
|
Ok(acceptor.build())
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/util.rs
12
src/util.rs
@@ -6,3 +6,15 @@ pub fn url_decode(url: &[u8]) -> String {
|
|||||||
.collect();
|
.collect();
|
||||||
return decoded
|
return decoded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fingerhex(x509: &openssl::x509::X509) -> String {
|
||||||
|
let finger = match x509.digest(openssl::hash::MessageDigest::sha256()) {
|
||||||
|
Ok(f) => f,
|
||||||
|
_ => return "".to_string(),
|
||||||
|
};
|
||||||
|
let mut hex: String = String::from("SHA256:");
|
||||||
|
for f in finger.as_ref() {
|
||||||
|
hex.push_str(&format!("{:02X}", f));
|
||||||
|
}
|
||||||
|
hex
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user