add nginx auth http
Seto committed
Oct 14, 2025 at 11:59 UTC
a4522363a93280251bef33374a25a8c90ff9d4e8
7 files changed
+109
-8
Cargo.lock
+13
@@ -47,6 +47,12 @@ dependencies = [
47
"windows-link",
48
]
49
50
+[[package]]
51
+name = "base64"
52
+version = "0.21.7"
53
+source = "registry+https://github.com/rust-lang/crates.io-index"
54
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
55
+
56
[[package]]
57
name = "bitflags"
58
version = "2.9.4"
@@ -313,6 +319,13 @@ dependencies = [
319
"tempfile",
320
]
321
322
+[[package]]
323
+name = "nginx_auth_http"
324
+version = "0.1.0"
325
+dependencies = [
326
+ "base64",
327
+]
328
+
329
[[package]]
330
name = "nu-ansi-term"
331
version = "0.50.3"
Cargo.toml
+3
@@ -1,3 +1,6 @@
1
+[workspace]
2
+members = ["./crates/*"]
3
+
4
[package]
5
name = "smbcloud-mail"
6
version = "1.0.0"
crates/.keep
crates/nginx-auth-http/Cargo.toml
new
+7
@@ -0,0 +1,7 @@
1
+[package]
2
+name = "nginx_auth_http"
3
+version = "0.1.0"
4
+edition = "2021"
5
+
6
+[dependencies]
7
+base64 = "0.21"
crates/nginx-auth-http/src/main.rs
new
+77
@@ -0,0 +1,77 @@
1
+use base64::{engine::general_purpose, Engine as _};
2
+use std::collections::HashMap;
3
+use std::io::prelude::*;
4
+use std::net::{TcpListener, TcpStream};
5
+
6
+struct AuthServer {
7
+ users: HashMap<String, String>,
8
+}
9
+
10
+impl AuthServer {
11
+ fn new() -> Self {
12
+ let mut users = HashMap::new();
13
+ users.insert("admin".to_string(), "your_admin_password".to_string());
14
+ users.insert("user".to_string(), "your_user_password".to_string());
15
+
16
+ AuthServer { users }
17
+ }
18
+
19
+ fn handle_request(&self, mut stream: TcpStream) {
20
+ let mut buffer = [0; 1024];
21
+ stream.read(&mut buffer).unwrap();
22
+
23
+ let request = String::from_utf8_lossy(&buffer[..]);
24
+ let lines: Vec<&str> = request.lines().collect();
25
+
26
+ // Find Authorization header
27
+ let auth_header = lines
28
+ .iter()
29
+ .find(|line| line.to_lowercase().starts_with("authorization:"))
30
+ .map(|line| line.split_once(": ").unwrap_or(("", "")).1);
31
+
32
+ let response = if let Some(auth) = auth_header {
33
+ if auth.starts_with("Basic ") {
34
+ match self.validate_credentials(&auth[6..]) {
35
+ true => "HTTP/1.1 200 OK\r\n\r\n",
36
+ false => "HTTP/1.1 401 Unauthorized\r\n\r\n",
37
+ }
38
+ } else {
39
+ "HTTP/1.1 401 Unauthorized\r\n\r\n"
40
+ }
41
+ } else {
42
+ "HTTP/1.1 401 Unauthorized\r\n\r\n"
43
+ };
44
+
45
+ stream.write_all(response.as_bytes()).unwrap();
46
+ stream.flush().unwrap();
47
+ }
48
+
49
+ fn validate_credentials(&self, encoded_creds: &str) -> bool {
50
+ if let Ok(decoded) = general_purpose::STANDARD.decode(encoded_creds) {
51
+ if let Ok(creds_str) = String::from_utf8(decoded) {
52
+ if let Some((username, password)) = creds_str.split_once(':') {
53
+ return self.users.get(username).map_or(false, |p| p == password);
54
+ }
55
+ }
56
+ }
57
+ false
58
+ }
59
+}
60
+
61
+fn main() {
62
+ let auth_server = AuthServer::new();
63
+ let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
64
+
65
+ println!("Auth server running on port 8080");
66
+
67
+ for stream in listener.incoming() {
68
+ match stream {
69
+ Ok(stream) => {
70
+ auth_server.handle_request(stream);
71
+ }
72
+ Err(e) => {
73
+ println!("Error: {}", e);
74
+ }
75
+ }
76
+ }
77
+}
docs/nginx/config.conf
+3
-8
@@ -2,6 +2,7 @@ worker_processes auto;
2
3
mail {
4
server_name smtp.thestablefoundation.org;
5
+ auth_http localhost:8080;
6
7
proxy_pass_error_message on;
8
@@ -14,19 +15,13 @@ mail {
15
ssl_session_timeout 10m;
16
17
server {
17
- listen 25;
18
+ listen 2525;
19
protocol smtp;
20
smtp_auth login plain cram-md5;
21
}
22
23
server {
23
- listen 110;
24
- protocol pop3;
25
- pop3_auth plain apop cram-md5;
26
- }
27
-
28
- server {
29
- listen 143;
24
+ listen 1143;
25
protocol imap;
26
}
27
}
docs/scripts/send-email.py
+6
@@ -6,6 +6,9 @@ from email.mime.text import MIMEText
6
7
smtp_server = "localhost"
8
smtp_port = 2525
9
+smtp_username = "your_username" # Add your SMTP username here
10
+smtp_password = "your_password" # Add your SMTP password here
11
+
12
from_email = "you@example.com"
13
to_email = "to@example.com"
14
subject = "Test Email"
@@ -37,6 +40,9 @@ with open(file_path, "rb") as attachment:
40
try:
41
with smtplib.SMTP(smtp_server, smtp_port) as server:
42
_ = server.starttls()
43
+ _ = server.login(
44
+ smtp_username, smtp_password
45
+ ) # Add this line for authentication
46
_ = server.sendmail(from_email, to_email, message.as_string())
47
print("Email sent successfully")
48
except Exception as e: