From 86f6ec17493206710e1c21eefb87395dc6cef181 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Wed, 24 Aug 2011 09:13:43 +0200 Subject: [PATCH] general autodetect --- world/drivers/ldmud/master/accept.c | 172 +++++++++++++++------------- 1 file changed, 93 insertions(+), 79 deletions(-) diff --git a/world/drivers/ldmud/master/accept.c b/world/drivers/ldmud/master/accept.c index 60f087d..16c42dc 100644 --- a/world/drivers/ldmud/master/accept.c +++ b/world/drivers/ldmud/master/accept.c @@ -83,6 +83,13 @@ object connect(int uid, int port, string service) { } \ } +// doesn't work. at this point autodetect hasn't completed.. so to +// make sure TLS is enabled we need to check again later in the +// server object.. FIXME :( +#define TLS_ENFORCE \ + if (tls_query_connection_state(ME) == 0) \ + return (object) 0; + #if __EFUN_DEFINED__(tls_want_peer_certificate) // Specify that a subsequent call to tls_init_connection // should request a peer certificate. @@ -98,25 +105,81 @@ object connect(int uid, int port, string service) { # define TLS_INIT_GET_CERT TLS_INIT #endif -#if AUTODETECT -# define TLS_INIT_AUTODETECT TLS_INIT -#else -# define TLS_INIT_AUTODETECT // do nothing -#endif - - // we dont want the telnet machine most of the time - // but disabling and re-enabling it for telnet doesn't work + // in the first switch we handle ports that MUST not support + // immediate TLS (currently that's just 5269) or that want a + // peer certificate from the other side (PSYC). for all other + // ports the default is to attempt a TLS autodetection. switch(port) { -#if HAS_PORT(PSYC_PORT, PSYC_PATH) && AUTODETECT - case PSYC_PORT: - // make TLS available even on the default psyc port using the autodetection feature +#if HAS_PORT(JABBER_S2S_PORT, JABBER_PATH) + case JABBER_S2S_PORT: +# ifdef DRIVER_HAS_CALL_BY_REFERENCE + arg = ME; + query_ip_number(&arg); + // this assumes network byte order provided by driver + peerport = pointerp(arg) ? (arg[2]*256 + arg[3]) : 0; + if (peerport < 0) peerport = 65536 + peerport; + if (peerport == JABBER_S2S_SERVICE) peerport = 0; +# else + // as long as the object names don't collide, this is okay too + peerport = 65536 + random(9999999); +# endif +# if __EFUN_DEFINED__(enable_telnet) + enable_telnet(0); +# endif + t = "S:xmpp:"+query_ip_number(); + // it's just an object name, but let's be consequent minus peerport + if (peerport) t += ":-"+peerport; +# ifdef _flag_log_sockets_XMPP + SIMUL_EFUN_FILE -> log_file("RAW_XMPP", "\n\n%O: %O -> load(%O, %O)", + ME, t, +# ifdef _flag_log_hosts + query_ip_number(), +# else + "?", +# endif + -peerport); +# endif + P3(("%O -> load(%O, %O)\n", t, query_ip_number(), -peerport)) + return t -> load(query_ip_number(), -peerport); #endif #if HAS_PORT(PSYCS_PORT, PSYC_PATH) case PSYCS_PORT: // inofficial & temporary -#endif TLS_INIT_GET_CERT - // fall thru -#if HAS_PORT(PSYC_PORT, PSYC_PATH) &&! AUTODETECT + break; +#endif +#if HAS_PORT(PSYC_PORT, PSYC_PATH) && AUTODETECT + case PSYC_PORT: + // make TLS available on the default PSYC port + // using the autodetection feature (official approach) + TLS_INIT_GET_CERT + break; +#endif +#if HAS_PORT(SPYCS_PORT, SPYC_PATH) + case SPYCS_PORT: // even more inofficial + TLS_INIT_GET_CERT + break; +#endif +#if HAS_PORT(SPYC_PORT, SPYC_PATH) && AUTODETECT + case SPYC_PORT: // even more inofficial + TLS_INIT_GET_CERT + break; +#endif + default: +#if AUTODETECT + // if autodetect is available, let's check if this connection + // has TLS enabled and activate it, no matter which protocol. + TLS_INIT +#endif + break; + } + + // if we got here, we may have initialized TLS successfully + switch(port) { +#if HAS_PORT(PSYCS_PORT, PSYC_PATH) + case PSYCS_PORT: // inofficial & temporary + TLS_ENFORCE +#endif +#if HAS_PORT(PSYC_PORT, PSYC_PATH) case PSYC_PORT: #endif #if HAS_PORT(PSYC_PORT, PSYC_PATH) || HAS_PORT(PSYCS_PORT, PSYC_PATH) @@ -145,13 +208,10 @@ object connect(int uid, int port, string service) { return t -> load(query_ip_number(), -peerport); #endif -// dedicated SPYC port.. should not be used, we have AUTODETECT +// dedicated SPYC port.. should not be used #if HAS_PORT(SPYCS_PORT, SPYC_PATH) case SPYCS_PORT: // interim name for PSYC 1.0 according to SPEC -# if __EFUN_DEFINED__(tls_want_peer_certificate) - tls_want_peer_certificate(ME); -# endif - TLS_INIT + TLS_ENFORCE #endif // fall thru #if HAS_PORT(SPYC_PORT, SPYC_PATH) case SPYC_PORT: @@ -186,7 +246,7 @@ object connect(int uid, int port, string service) { #if HAS_PORT(POP3S_PORT, POP3_PATH) case POP3S_PORT: - TLS_INIT + TLS_ENFORCE return clone_object(POP3_PATH "server"); #endif #if HAS_PORT(POP3_PORT, POP3_PATH) @@ -196,7 +256,7 @@ object connect(int uid, int port, string service) { #if HAS_PORT(SMTPS_PORT, NNTP_PATH) case SMTPS_PORT: - TLS_INIT + TLS_ENFORCE return clone_object(SMTP_PATH "server"); #endif #if HAS_PORT(SMTP_PORT, SMTP_PATH) @@ -212,7 +272,7 @@ object connect(int uid, int port, string service) { #if HAS_PORT(NNTPS_PORT, NNTP_PATH) case NNTPS_PORT: - TLS_INIT + TLS_ENFORCE return clone_object(NNTP_PATH "server"); #endif #if HAS_PORT(NNTP_PORT, NNTP_PATH) @@ -222,50 +282,19 @@ object connect(int uid, int port, string service) { #if HAS_PORT(JABBERS_PORT, JABBER_PATH) case JABBERS_PORT: - TLS_INIT + TLS_ENFORCE return clone_object(JABBER_PATH "server"); #endif #if HAS_PORT(JABBER_PORT, JABBER_PATH) case JABBER_PORT: # if __EFUN_DEFINED__(enable_telnet) + // we dont want the telnet machine most of the time + // but disabling and re-enabling it for telnet doesn't work enable_telnet(0); // are you sure!??? # endif return clone_object(JABBER_PATH "server"); #endif -#if HAS_PORT(JABBER_S2S_PORT, JABBER_PATH) - case JABBER_S2S_PORT: -# ifdef DRIVER_HAS_CALL_BY_REFERENCE - arg = ME; - query_ip_number(&arg); - // this assumes network byte order provided by driver - peerport = pointerp(arg) ? (arg[2]*256 + arg[3]) : 0; - if (peerport < 0) peerport = 65536 + peerport; - if (peerport == JABBER_S2S_SERVICE) peerport = 0; -# else - // as long as the object names don't collide, this is okay too - peerport = 65536 + random(9999999); -# endif -# if __EFUN_DEFINED__(enable_telnet) - enable_telnet(0); -# endif - t = "S:xmpp:"+query_ip_number(); - // it's just an object name, but let's be consequent minus peerport - if (peerport) t += ":-"+peerport; -# ifdef _flag_log_sockets_XMPP - SIMUL_EFUN_FILE -> log_file("RAW_XMPP", "\n\n%O: %O -> load(%O, %O)", - ME, t, -# ifdef _flag_log_hosts - query_ip_number(), -# else - "?", -# endif - -peerport); -# endif - P3(("%O -> load(%O, %O)\n", t, query_ip_number(), -peerport)) - return t -> load(query_ip_number(), -peerport); -#endif - #if 0 //__EFUN_DEFINED__(enable_binary) // work in progress case 8888: @@ -280,12 +309,11 @@ object connect(int uid, int port, string service) { #if HAS_PORT(IRCS_PORT, IRC_PATH) case IRCS_PORT: - TLS_INIT + TLS_ENFORCE return clone_object(IRC_PATH "server"); #endif #if HAS_PORT(IRC_PORT, IRC_PATH) case IRC_PORT: - TLS_INIT_AUTODETECT return clone_object(IRC_PATH "server"); #endif @@ -299,14 +327,13 @@ object connect(int uid, int port, string service) { #if HAS_PORT(TELNETS_PORT, TELNET_PATH) case TELNETS_PORT: - TLS_INIT + TLS_ENFORCE // we could do the UID2NICK thing here, too, but why should we? // what do you need tls for on a localhost tcp link? return clone_object(TELNET_PATH "server"); #endif #if HAS_PORT(TELNET_PORT, TELNET_PATH) case TELNET_PORT: - TLS_INIT_AUTODETECT t = clone_object(TELNET_PATH "server"); # ifdef UID2NICK if (uid && (arg = UID2NICK(uid))) { t -> sName(arg); } @@ -316,42 +343,29 @@ object connect(int uid, int port, string service) { #if HAS_PORT(HTTPS_PORT, HTTP_PATH) case HTTPS_PORT: - t = tls_init_connection(this_object()); - if (t < 0) { - D1( if (t != ERR_TLS_NOT_DETECTED) PP(( "TLS(%O) on %O: %O\n", - t, port, tls_error(t) )); ) -#if !HAS_PORT(HTTP_PORT, HTTP_PATH) - // if we have no http port, it may be intentional - return (object)0; -#endif - } - D2( else if (t > 0) PP(( "Setting up TLS connection in the background.\n" )); ) - D2( else PP(( "Oh yeah, I'm initializing an https session!\n" )); ) + TLS_ENFORCE return clone_object(HTTP_PATH "server"); #endif - /* don't fall thru. allow for https: to be available without http: */ -#if HAS_PORT(HTTP_PORT, HTTP_PATH) &&! AUTODETECT + // don't fall thru. allow for https: to be available without http: +#if HAS_PORT(HTTP_PORT, HTTP_PATH) case HTTP_PORT: - TLS_INIT_AUTODETECT return clone_object(HTTP_PATH "server"); #endif #if HAS_PORT(MUDS_PORT, MUD_PATH) case MUDS_PORT: - TLS_INIT + TLS_ENFORCE return clone_object(MUD_PATH "login"); #endif #if HAS_PORT(MUD_PORT, MUD_PATH) default: // if you want to multiplex psyced with an LPMUD game - TLS_INIT_AUTODETECT // set_prompt("> "); return clone_object(MUD_PATH "login"); #endif } - - PP(("Received connection on port %O which isn't configured.\n", - port)); + + P0(("Received connection on port %O which isn't configured.\n", port)); return (object)0; }