summaryrefslogtreecommitdiffstats
path: root/src/bin/client/connection.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-10-29 22:22:27 +0100
committersalmonik <salmonik@tuta.io>2026-10-29 22:22:27 +0100
commitf30b1a519771ac49e2b03640e742fdb0a246bd81 (patch)
treeb9a78039ba55a364e73df5dc174320dc8222f5c3 /src/bin/client/connection.rs
parentformatting (diff)
downloadzagan-bet-f30b1a519771ac49e2b03640e742fdb0a246bd81.tar.gz
zagan-bet-f30b1a519771ac49e2b03640e742fdb0a246bd81.zip
v2.4.0: key stored credentials by certificate fingerprint
Diffstat (limited to 'src/bin/client/connection.rs')
-rw-r--r--src/bin/client/connection.rs34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/bin/client/connection.rs b/src/bin/client/connection.rs
index 44cfea9..ec5642c 100644
--- a/src/bin/client/connection.rs
+++ b/src/bin/client/connection.rs
@@ -56,10 +56,10 @@ pub fn connect(
56 56
57 // TOFU: persist the fingerprint on first contact. 57 // TOFU: persist the fingerprint on first contact.
58 if !unsafe_mode { 58 if !unsafe_mode {
59 if let Some(fp) = observed { 59 if let Some(fp) = observed.as_deref() {
60 if database::get_fingerprint(conn, addr).is_none() { 60 if database::get_fingerprint(conn, addr).is_none() {
61 database::save_fingerprint(conn, addr, &fp)?; 61 database::save_fingerprint(conn, addr, fp)?;
62 for line in first_contact_lines(addr, &fp) { 62 for line in first_contact_lines(addr, fp) {
63 println!("{}", line); 63 println!("{}", line);
64 } 64 }
65 } 65 }
@@ -80,21 +80,25 @@ pub fn connect(
80 elapsed.as_secs_f64() * 1000.0 80 elapsed.as_secs_f64() * 1000.0
81 ); 81 );
82 82
83 if let Some((username, password)) = database::get_credentials(conn, addr) { 83 // Credentials are stored per server identity, so any address presenting
84 let auth_msg = format!("AUTH {} {}", username, password); 84 // this certificate key can log in with the same stored account.
85 tls.write_line(&auth_msg)?; 85 let identity = observed
86 let mut auth_response = String::new(); 86 .clone()
87 tls.read_line(&mut auth_response)?; 87 .or_else(|| database::get_fingerprint(conn, addr));
88 if auth_response.trim().starts_with("OK") { 88 if let Some(identity) = identity {
89 println!("Authenticated as {}", username); 89 if let Some((username, password)) = database::get_credentials(conn, &identity) {
90 Ok((tls, Some(username))) 90 let auth_msg = format!("AUTH {} {}", username, password);
91 } else { 91 tls.write_line(&auth_msg)?;
92 let mut auth_response = String::new();
93 tls.read_line(&mut auth_response)?;
94 if auth_response.trim().starts_with("OK") {
95 println!("Authenticated as {}", username);
96 return Ok((tls, Some(username)));
97 }
92 println!("Authentication failed: {}", auth_response.trim()); 98 println!("Authentication failed: {}", auth_response.trim());
93 Ok((tls, None))
94 } 99 }
95 } else {
96 Ok((tls, None))
97 } 100 }
101 Ok((tls, None))
98} 102}
99 103
100/// Wrapper so TLS handshake failures surface as errors with their message 104/// Wrapper so TLS handshake failures surface as errors with their message