From da6ce9252920c54b5ed9fa712010ee0ddb782dd7 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Tue, 2 Aug 2011 17:43:05 +0200 Subject: [PATCH] paying more attention to TLS --- .gitmodules | 2 +- world/default/de/plain.textdb | 9 +++++ world/default/en/plain.textdb | 9 +++++ world/default/it/plain.textdb | 9 +++++ world/net/jabber/active.c | 2 +- world/net/jabber/common.c | 3 +- world/net/jabber/gateway.c | 8 ++-- world/net/jabber/server.c | 1 + world/net/library/tls.c | 22 ++++++++++- world/net/psyc/circuit.c | 71 ++++++++++++++++------------------- world/net/spyc/circuit.c | 8 +++- world/net/user.c | 10 +++++ 12 files changed, 106 insertions(+), 48 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2d33dcf..8c4fa01 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "psyclpc"] path = psyclpc - url = git://git.tgbit.net/psyclpc + url = git://git.psyced.org/git/psyclpc diff --git a/world/default/de/plain.textdb b/world/default/de/plain.textdb index 3d2405e..74f4db2 100644 --- a/world/default/de/plain.textdb +++ b/world/default/de/plain.textdb @@ -1,6 +1,15 @@ ## vim:syntax=mail ## Check utf-8: Praise Atatürk! +_status_circuit_encryption_cipher +|Gratuliere! Deine Verbindung ist mit Folgenlosigkeit verschlüsselt. + +_warning_circuit_encryption_cipher +|Deine Verbindung ist leider ohne Folgenlosigkeit verschlüsselt. + +_error_circuit_encryption_cipher +|Deine Verbindung ist ohne Folgenlosigkeit verschlüsselt. + _failure_disabled_function_register |Registrierung ist auf diesem Server deaktiviert. diff --git a/world/default/en/plain.textdb b/world/default/en/plain.textdb index 552f0bc..151d789 100644 --- a/world/default/en/plain.textdb +++ b/world/default/en/plain.textdb @@ -1,6 +1,15 @@ ## vim:syntax=mail ## Check utf-8: Praise Atatürk! +_status_circuit_encryption_cipher +|Congratulations. Your connection is encrypted with forward secrecy. + +_warning_circuit_encryption_cipher +|Your cipher choice does not provide forward secrecy. + +_error_circuit_encryption_cipher +|Unfortunately your cipher choice does not provide forward secrecy. + _failure_disabled_function_register |Registration disabled on this server. diff --git a/world/default/it/plain.textdb b/world/default/it/plain.textdb index ce34307..d1a94cc 100644 --- a/world/default/it/plain.textdb +++ b/world/default/it/plain.textdb @@ -1,6 +1,15 @@ ## vim:syntax=mail ## tradotto al 30% ... cerca /TODO/ per continuare +_status_circuit_encryption_cipher +|Muy bueno! La tua connessione è crittata senza conseguenze. + +_warning_circuit_encryption_cipher +|La tua connessione non è crittata senza conseguenze. + +_error_circuit_encryption_cipher +|Purtroppo la tua connessione non è crittata senza conseguenze. + _failure_disabled_function_register |Registrazione di nuovi utenti disabilitata su questo server. diff --git a/world/net/jabber/active.c b/world/net/jabber/active.c index acfdc40..9754a7f 100644 --- a/world/net/jabber/active.c +++ b/world/net/jabber/active.c @@ -315,7 +315,7 @@ tls_logon(result) { mixed cert = tls_certificate(ME, 0); P3(("active::certinfo %O\n", cert)) if (mappingp(cert)) { - unless (certificate_check_name(hostname, cert, "xmpp-server")) { + unless (tls_check_certificate_data(cert, hostname, "xmpp-server")) { #ifdef _flag_report_bogus_certificates monitor_report("_error_invalid_certificate_identity", sprintf("%O presented a certificate that " diff --git a/world/net/jabber/common.c b/world/net/jabber/common.c index 0f2ab3a..569b714 100644 --- a/world/net/jabber/common.c +++ b/world/net/jabber/common.c @@ -393,7 +393,8 @@ xmpp_error(node, xmpperror) { return 0; } -// deprecated - use certificate_check_name from library/tls.c instead +// deprecated - use tls_check_certificate_data from library/tls.c instead +// is this being used at all? #ifdef WANT_S2S_TLS certificate_check_jabbername(name, cert) { mixed t; diff --git a/world/net/jabber/gateway.c b/world/net/jabber/gateway.c index c88c0b5..2e2a387 100644 --- a/world/net/jabber/gateway.c +++ b/world/net/jabber/gateway.c @@ -291,7 +291,7 @@ jabberMsg(XMLNode node) { // paranoia note: as with XEP 0178 we might want to check dns anyway to // protect against stolen certificates if (mappingp(certinfo) && certinfo[0] == 0 - && node["@from"] && certificate_check_name(node["@from"], certinfo, "xmpp-server")) { + && node["@from"] && tls_check_certificate_data(certinfo, node["@from"], "xmpp-server")) { P2(("dialback without dialback %O\n", certinfo)) verify_connection(node["@to"], node["@from"], "valid"); } else { @@ -414,7 +414,7 @@ jabberMsg(XMLNode node) { */ int success = 0; - success = certificate_check_name(t, certinfo, "xmpp-server"); + success = tls_check_certificate_data(certinfo, t, "xmpp-server"); if (success) { emitraw(""); P2(("successful sasl external authentication with " @@ -542,8 +542,8 @@ open_stream(XMLNode node) { // sasl external if we know that it will succeed // later on if (node["@from"] && - certificate_check_name(node["@from"], - certinfo, "xmpp-server")) { + tls_check_certificate_data(certinfo, node["@from"], + "xmpp-server")) { packet += ""; packet += "EXTERNAL"; packet += ""; diff --git a/world/net/jabber/server.c b/world/net/jabber/server.c index b1d1625..9cadc16 100644 --- a/world/net/jabber/server.c +++ b/world/net/jabber/server.c @@ -490,6 +490,7 @@ open_stream(XMLNode node) { #if __EFUN_DEFINED__(tls_available) if (tls_available() && tls_query_connection_state(ME) > 0 && mappingp(certinfo) && certinfo[0] == 0 + // why do we use the old one here? && certificate_check_jabbername(0, certinfo)) { features += "EXTERNAL"; } diff --git a/world/net/library/tls.c b/world/net/library/tls.c index bfad4bc..5d59f5a 100644 --- a/world/net/library/tls.c +++ b/world/net/library/tls.c @@ -1,4 +1,7 @@ #include // vim syntax=lpc +#include +#include + mapping tls_certificate(object who, int longnames) { mixed *extra, extensions; mapping cert; @@ -85,7 +88,7 @@ mapping tls_certificate(object who, int longnames) { // generalized variant of the old certificate_check_jabbername // RFC 6125 describes the process in more detail -int certificate_check_name(string name, mixed cert, string scheme) { +int tls_check_certificate_data(mixed cert, string name, string scheme) { mixed t; string idn; // FIXME: should probably be more careful about internationalized @@ -159,3 +162,20 @@ int certificate_check_name(string name, mixed cert, string scheme) { } return 0; } + +int tls_check_cipher(object sock, string scheme) { + string t; + mixed m = tls_query_connection_info(sock); + + P3(("%O is using the %O cipher.\n", sock, m[TLS_CIPHER])) + // shouldn't our negotiation have ensured we have PFS? + + if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) { + monitor_report("_warning_circuit_encryption_cipher_details", + object_name(sock) +" · using "+ t +" cipher"); + // we can't expect that degree of privacy from jabber, for now + if (scheme != "xmpp") return 0; + } + return 1; +} + diff --git a/world/net/psyc/circuit.c b/world/net/psyc/circuit.c index 0f82c61..97515a7 100644 --- a/world/net/psyc/circuit.c +++ b/world/net/psyc/circuit.c @@ -209,48 +209,41 @@ int logon(int neverfails) { #ifdef __TLS__ sAuthHosts(([ ])); // reset authhosts - if (tls_available() && tls_query_connection_state(ME) == 1 && mappingp(cert = tls_certificate(ME, 0))) { - if (cert[0] != 0) { - // log error 17 or 18 + cert here - P0(("%O encountered a cert verify error %O in %O\n", ME, - cert[0], cert)) - // and goodbye. + if (tls_available() && tls_query_connection_state(ME) == 1) { + unless (tls_check_cipher(ME, "psyc")) { + croak("_error_circuit_encryption_cipher", + "Your cipher choice does not provide forward secrecy."); + QUIT + } + if (mappingp(cert = tls_certificate(ME, 0))) { + if (cert[0] != 0) { + // log error 17 or 18 + cert here + P0(("%O encountered a cert verify error %O in %O\n", ME, + cert[0], cert)) + // and goodbye. # ifdef _flag_enable_certificate_any - remove_interactive(ME); - return 0; + remove_interactive(ME); + return 0; # endif - } - if (m = cert["2.5.29.17:dNSName"]) { - // FIXME: this does not yet handle wildcard DNS names - P1(("%O believing dNSName %O\n", ME, m)) - // probably also: register_target? - // but be careful never to register_target wildcards - if (stringp(m)) sAuthenticated(m); - else foreach(t : m) sAuthenticated(t); - } -//#ifdef _flag_allow_certificate_name_common // to be switched this year -# ifndef _flag_disallow_certificate_name_common - // assume that CN is a host - // as this is an assumption only, we may NEVER register_target it - // note: CN is deprecated for good reasons. - else if (t = cert["2.5.4.3"]) { - P1(("%O believing CN %O\n", ME, t)) - sAuthenticated(t); - } -# endif - if (m = tls_query_connection_info(ME)) { - P2(("%O is using the %O cipher.\n", ME, m[TLS_CIPHER])) - // shouldn't our negotiation have ensured we have PFS? - if (stringp(t = m[TLS_CIPHER]) &&! abbrev("DHE", t)) { -// croak("_warning_circuit_encryption_cipher", -// "Your cipher choice does not provide forward secrecy."); - monitor_report( - "_warning_circuit_encryption_cipher_details", - object_name(ME) +" · using "+ t +" cipher"); - //debug_message(sprintf( - // "TLS connection info for %O is %O\n", ME, m)); - //QUIT // are we ready for *this* !??? } + if (m = cert["2.5.29.17:dNSName"]) { + // FIXME: this does not yet handle wildcard DNS names + P1(("%O believing dNSName %O\n", ME, m)) + // probably also: register_target? + // but be careful never to register_target wildcards + if (stringp(m)) sAuthenticated(m); + else foreach(t : m) sAuthenticated(t); + } + //#ifdef _flag_allow_certificate_name_common // to be switched this year +# ifndef _flag_disallow_certificate_name_common + // assume that CN is a host + // as this is an assumption only, we may NEVER register_target it + // note: CN is deprecated for good reasons. + else if (t = cert["2.5.4.3"]) { + P1(("%O believing CN %O\n", ME, t)) + sAuthenticated(t); + } +# endif } } #endif diff --git a/world/net/spyc/circuit.c b/world/net/spyc/circuit.c index 33c536c..c9409a9 100644 --- a/world/net/spyc/circuit.c +++ b/world/net/spyc/circuit.c @@ -117,6 +117,12 @@ int logon(int failure) { } else if (tls_query_connection_state(ME) == 1) { certinfo = tls_certificate(ME, 0); P0(("certinfo: %O\n", certinfo)) + unless (tls_check_cipher(ME, "psyc")) { + croak("_error_circuit_encryption_cipher", + "Your cipher choice does not provide forward secrecy."); + //destruct(ME); + } + } } #endif @@ -207,7 +213,7 @@ void circuit_msg(string mc, mapping vars, string data) { } else if (tls_query_connection_state(ME) == 1 && mappingp(certinfo) && certinfo[0] == 0 - && certificate_check_name(su[UHost], certinfo, "psyc") == 1) { + && tls_check_certificate_data(certinfo, su[UHost], "psyc") == 1) { sAuthenticated(su[UHost]); if (flags & TCP_PENDING_TIMEOUT) { P0(("removing call out\n")) diff --git a/world/net/user.c b/world/net/user.c index 8544738..8c7aea0 100644 --- a/world/net/user.c +++ b/world/net/user.c @@ -1555,6 +1555,16 @@ logon() { return remove_interactive(ME); // and the object will deteriorate when user gives up.. } +#ifdef __TLS__ + if (tls_query_connection_state(ME) == 1) { + if (tls_check_cipher(ME, v("scheme"))) { + w("_status_circuit_encryption_cipher"); + } else { + w("_warning_circuit_encryption_cipher"); + //return remove_interactive(ME); + } + } +#endif // shouldn't this be qScheme() instead? little paranoid TODO // but then we would have to move qScheme() from the server.c's // into the common.c's .. well, we could do that some day