diff -ur stunnel-4.21/doc/stunnel.pod stunnel/doc/stunnel.pod --- stunnel-4.21/doc/stunnel.pod 2007-09-23 18:28:48.000000000 +0300 +++ stunnel/doc/stunnel.pod 2007-11-06 18:21:39.000000000 +0200 @@ -422,7 +422,7 @@ application protocol to negotiate SSL -currently supported: cifs, connect, imap, nntp, pop3, smtp +currently supported: cifs, connect, imap, nntp, pop3, smtp, pgsql =item B = auth_type diff -ur stunnel-4.21/src/protocol.c stunnel/src/protocol.c --- stunnel-4.21/src/protocol.c 2007-09-23 23:19:27.000000000 +0300 +++ stunnel/src/protocol.c 2007-11-06 18:24:25.000000000 +0200 @@ -39,6 +39,8 @@ /* protocol-specific function prototypes */ static void cifs_client(CLI *); static void cifs_server(CLI *); +static void pgsql_client(CLI *); +static void pgsql_server(CLI *); static void smtp_client(CLI *); static void smtp_server(CLI *); static void pop3_client(CLI *); @@ -72,6 +74,8 @@ nntp_client(c); else if(!strcmp(c->opt->protocol, "connect")) connect_client(c); + else if(!strcmp(c->opt->protocol, "pgsql")) + pgsql_client(c); else { s_log(LOG_ERR, "Protocol %s not supported in client mode", c->opt->protocol); @@ -86,6 +90,8 @@ pop3_server(c); else if(!strcmp(c->opt->protocol, "imap")) imap_server(c); + else if(!strcmp(c->opt->protocol, "pgsql")) + pgsql_server(c); else { s_log(LOG_ERR, "Protocol %s not supported in server mode", c->opt->protocol); @@ -137,6 +143,34 @@ write_blocking(c, c->local_wfd.fd, response_use_ssl, 5); } +static void pgsql_client(CLI *c) { + u8 buffer[1]; + u8 ssl_request[8] = { 0, 0, 0, 8, 0x04, 0xd2, 0x16, 0x2f }; + + write_blocking(c, c->remote_fd.fd, ssl_request, sizeof(ssl_request)); + read_blocking(c, c->remote_fd.fd, buffer, 1); + /* S - accepted, N - rejected, non-SSL preferred */ + if(buffer[0] != 'S') { + s_log(LOG_ERR, "PostgreSQL server rejected SSL"); + longjmp(c->err, 1); + } +} + +static void pgsql_server(CLI *c) { + u8 buffer[8]; + u8 ssl_request[8] = { 0, 0, 0, 8, 0x04, 0xd2, 0x16, 0x2f }; + u8 ssl_ok[1] = { 'S' }; + + memset(buffer, 0, sizeof(buffer)); + read_blocking(c, c->local_rfd.fd, buffer, sizeof(buffer)); + if (memcmp(buffer, ssl_request, sizeof(ssl_request)) != 0) { + s_log(LOG_ERR, "PostgreSQL client did not request SSL, rejecting"); + /* no way to send error on startup, so just drop client */ + longjmp(c->err, 1); + } + write_blocking(c, c->local_wfd.fd, ssl_ok, sizeof(ssl_ok)); +} + static void smtp_client(CLI *c) { char line[STRLEN];