From: Thadeu Lima de Souza Cascardo Date: Thu, 14 Apr 2011 02:47:07 +0000 (-0300) Subject: Proxy para ReceitaNET. X-Git-Url: http://git.cascardo.info/?p=cascardo%2Frnetproxy.git;a=commitdiff_plain;h=cf309ca41249b88d93bf6ae0b927e6c9ac6527bb Proxy para ReceitaNET. Algumas mudanças de nome no software para se alinhar mais ao seu novo propósito, de ser um proxy para realizar a engenharia reversa do protocolo do ReceitaNET. --- diff --git a/AUTHORS b/AUTHORS index 66739c0..73d4cfb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Thadeu Lima de Souza Cascardo +Thadeu Lima de Souza Cascardo diff --git a/Makefile.am b/Makefile.am index f234338..10089d4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,6 @@ -bin_PROGRAMS = popproxy ppmanager -popproxy_SOURCES = popproxy.c log.c log.h \ +bin_PROGRAMS = rnetproxy +rnetproxy_SOURCES = rnetproxy.c log.c log.h \ tcp_connect.h tcp_connect.c tcp_server.c \ - hcconn.c hcconn.h hcconn_internal.h hcconn_ssl.c hcconn_ssl.h \ - pop.c pop.h usermap.c usermap.h -dist_sysconf_DATA = popproxy.conf -ppmanager = ppmanager.c -EXTRA_DIST = popproxy.init popproxy.spec + hcconn.c hcconn.h hcconn_internal.h hcconn_ssl.c hcconn_ssl.h +dist_sysconf_DATA = rnetproxy.conf +EXTRA_DIST = rnetproxy.init rnetproxy.spec diff --git a/NEWS b/NEWS index 8626204..5a5f00c 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ -NEWS for popproxy +NEWS for rnetproxy -* Version NOT 0.1 +* Version 0.1 -- This is our first non-release. +- This is our first release. diff --git a/README b/README index 9a4aca8..de0adf9 100644 --- a/README +++ b/README @@ -1,7 +1,4 @@ -popproxy is a POP3 proxy. +rnetproxy is proxy for Receitanet. -It may be used as a reverse proxy mainly, but extending it to work as a -gateway proxy based on username is possible. - -It currently is able to control access based in username and has some -SSL support. +Its main purpose is to decode the messages used by the non-libre client +to reverse engineer the protocol and create a libre client. diff --git a/TODO b/TODO index be02e02..c74cc00 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,5 @@ Immediately: -* Remove connection/socket leaks. -* Support server-side (client-to-proxy) SSL connections. -* Configuring SSL support, like certificates and keys. -* Configuring access control policy. - -Some easy protocol support: -* Support APOP. -* Support STLS. - -Some extensibility support: -* Support gateway proxies based on username maps. - -Some sysadmin cake: -* Configuration interface besides CLI. +* Support handshake protocol from Receitanet. +* Support SSL after handshake. +* Make it build, creating rnet_layer. +* SSL must be used both ways. diff --git a/configure.ac b/configure.ac index ac97b25..8b97ffe 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(popproxy,0.1.3,cascardo@holoscopio.com) +AC_INIT(rnetproxy,0.1,cascardo@minaslivre.org) AM_INIT_AUTOMAKE(AC_PACKAGE_NAME,AC_PACKAGE_VERSION) AC_PROG_CC AC_PROG_INSTALL diff --git a/hcconn.c b/hcconn.c index 10d01a8..c15256f 100644 --- a/hcconn.c +++ b/hcconn.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Thadeu Lima de Souza Cascardo + * Copyright (C) 2009 Thadeu Lima de Souza Cascardo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/hcconn.h b/hcconn.h index 85bdd38..d861959 100644 --- a/hcconn.h +++ b/hcconn.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Thadeu Lima de Souza Cascardo + * Copyright (C) 2009 Thadeu Lima de Souza Cascardo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/hcconn_internal.h b/hcconn_internal.h index 6bb9730..914ecab 100644 --- a/hcconn_internal.h +++ b/hcconn_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Thadeu Lima de Souza Cascardo + * Copyright (C) 2009 Thadeu Lima de Souza Cascardo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/hcconn_ssl.c b/hcconn_ssl.c index f1e98fb..fdff9ef 100644 --- a/hcconn_ssl.c +++ b/hcconn_ssl.c @@ -1,6 +1,6 @@ /* ** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo +** Copyright (C) 2009 Thadeu Lima de Souza Cascardo ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by diff --git a/hcconn_ssl.h b/hcconn_ssl.h index b471963..6096f0c 100644 --- a/hcconn_ssl.h +++ b/hcconn_ssl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Thadeu Lima de Souza Cascardo + * Copyright (C) 2009 Thadeu Lima de Souza Cascardo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/log.c b/log.c index 8560fa5..87a7a28 100644 --- a/log.c +++ b/log.c @@ -44,9 +44,9 @@ static void log_func (const gchar* domain, syslog (map_level (level), "%s", message); } -void pop_log_init () +void rnet_log_init () { - openlog ("popproxy", LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON); + openlog ("rnetproxy", LOG_NDELAY | LOG_NOWAIT, LOG_DAEMON); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, log_func, NULL); } diff --git a/log.h b/log.h index 2e472c9..ce8ec00 100644 --- a/log.h +++ b/log.h @@ -20,6 +20,6 @@ #ifndef LOG_H #define LOG_H -void pop_log_init (); +void rnet_log_init (); #endif diff --git a/pop.c b/pop.c index 4cd2f39..89e9c8c 100644 --- a/pop.c +++ b/pop.c @@ -1,6 +1,6 @@ /* ** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo +** Copyright (C) 2009 Thadeu Lima de Souza Cascardo ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by diff --git a/pop.h b/pop.h index a740f12..aaba7da 100644 --- a/pop.h +++ b/pop.h @@ -1,6 +1,6 @@ /* ** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo +** Copyright (C) 2009 Thadeu Lima de Souza Cascardo ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by diff --git a/popproxy.c b/popproxy.c deleted file mode 100644 index 47c2e94..0000000 --- a/popproxy.c +++ /dev/null @@ -1,368 +0,0 @@ -/* -** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "log.h" -#include "pop.h" - -#include "hcconn.h" -#include "hcconn_ssl.h" -#include "tcp_connect.h" - -#include "usermap.h" - -#define CONFFILE SYSCONFDIR "/popproxy.conf" - -struct pop_address -{ - char *server; - char *port; - int ssl; - char *priority; -}; - -static HCConn * -server_conn_new (char *server, char *port, int ssl) -{ - int fd; - HCConn *conn; - HCConn *ssl_conn; - int r; - fd = hc_tcp_connect (server, port); - if (fd < 0) - { - g_warning ("Could not connect to server at %s:%s.", server, port); - return NULL; - } - conn = hc_conn_new (NULL, NULL); - r = hc_conn_set_driver_channel (conn, fd); - if (r != 0) - { - hc_conn_close (conn); - close (fd); - return NULL; - } - if (!ssl) - return conn; - ssl_conn = hc_conn_new (NULL, NULL); - r = hc_conn_set_driver_ssl_client (ssl_conn, conn); - if (r != 0) - { - hc_conn_close (ssl_conn); - hc_conn_close (conn); - return NULL; - } - return ssl_conn; -} - -static HCConn * -client_conn_new (int fd, struct pop_address *address) -{ - HCConn *conn; - HCConn *ssl_conn; - HCConn *pop_conn; - int r; - conn = hc_conn_new (NULL, NULL); - r = hc_conn_set_driver_channel (conn, fd); - if (r != 0) - { - hc_conn_close (conn); - close (fd); - return NULL; - } - - ssl_conn = hc_conn_new (NULL, NULL); - hc_conn_set_driver_ssl_server (ssl_conn, conn); - if (address && address->priority) - hc_conn_ssl_server_set_priority (ssl_conn, address->priority); - - if (r != 0) - { - hc_conn_close (ssl_conn); - hc_conn_close (conn); - return NULL; - } - pop_conn = hc_conn_new (NULL, NULL); - r = hc_conn_set_driver_pop (pop_conn, ssl_conn); - if (r != 0) - { - hc_conn_close (pop_conn); - hc_conn_close (ssl_conn); - return NULL; - } - return pop_conn; -} - -static void -push_other (HCConn *conn, HCEvent event, gpointer data) -{ - char buffer[4096]; - int r; - switch (event) - { - case HC_EVENT_READ: - while ((r = hc_conn_read (conn, buffer, sizeof (buffer))) > 0) - hc_conn_write (data, buffer, r); - break; - case HC_EVENT_CLOSE: - hc_conn_close (conn); - hc_conn_close (data); - break; - } -} - -static void -ssl_connected (HCConn *client_conn, HCEvent event, gpointer data) -{ - struct pop_address *address = data; - HCConn *server_conn; - if (event != HC_EVENT_CONNECT) - { - g_debug ("Did not get connect event when trying to handshake:" - " got %d", event); - hc_conn_close (client_conn); - return; - } - server_conn = server_conn_new (address->server, address->port, - address->ssl); - if (server_conn == NULL) - { - g_debug ("Failure to create connection to server."); - hc_conn_close (client_conn); - return; - } - hc_conn_set_callback (client_conn, push_other, server_conn); - hc_conn_set_callback (server_conn, push_other, client_conn); -} - -static void -new_client (int fd, struct sockaddr *addr, socklen_t saddr, gpointer data) -{ - HCConn *client_conn; - struct pop_address *address = data; - if (fd < 0) - { - g_critical ("Server has received an error event."); - return; - } - - /* FIXME: Should be independent of address type. */ - g_message ("Received connection from %s.", - inet_ntoa (((struct sockaddr_in *) addr)->sin_addr)); - - client_conn = client_conn_new (fd, address); - if (client_conn == NULL) - { - return; - } - - hc_conn_set_callback (client_conn, ssl_connected, address); - -} - -static gchar *configfile; -static gboolean foreground; - -static GOptionEntry opt_entries[] = - { - { "config-file", 'c', 0, G_OPTION_ARG_FILENAME, &configfile, - "Configuration file location", "file" }, - { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, - "Run in foreground", 0 }, - { NULL } - }; - -int main (int argc, char **argv) -{ - - GOptionContext *opt_ctx; - GKeyFile *keyfile; - GError *error; - int server_fd; - gchar *conf_address; - gchar *port; - gchar *server_address; - gchar *server_port; - int server_ssl; - gchar *server_priority; - gchar *certfile; - gchar *ssl_keyfile; - gchar *policy; - struct pop_address pop_address; - - signal (SIGPIPE, SIG_IGN); - - gnutls_global_init (); - - configfile = CONFFILE; - opt_ctx = g_option_context_new (""); - g_option_context_add_main_entries (opt_ctx, opt_entries, NULL); - - error = NULL; - if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) - { - g_critical ("Could not parse command line options: %s.", - error->message); - g_error_free (error); - exit (1); - } - g_option_context_free (opt_ctx); - - keyfile = g_key_file_new (); - - error = NULL; - if (g_key_file_load_from_file (keyfile, configfile, - G_KEY_FILE_NONE, &error) == FALSE) - { - g_critical ("Could not load configuration file %s: %s.", - configfile, error->message); - g_error_free (error); - exit (1); - } - - error = NULL; - certfile = g_key_file_get_string (keyfile, "global", "certfile", - &error); - if (certfile == NULL && error != NULL) - { - g_critical ("No certification file specified: %s.", - error->message); - g_error_free (error); - exit (1); - } - error = NULL; - ssl_keyfile = g_key_file_get_string (keyfile, "global", "keyfile", - &error); - if (ssl_keyfile == NULL && error != NULL) - { - ssl_keyfile = g_strdup (certfile); - g_error_free (error); - } - - - error = NULL; - conf_address = g_key_file_get_string (keyfile, "global", "address", - &error); - if (conf_address == NULL && error != NULL) - { - conf_address = g_strdup ("0.0.0.0"); - g_error_free (error); - } - error = NULL; - port = g_key_file_get_string (keyfile, "global", "port", &error); - if (port == NULL && error != NULL) - { - port = g_strdup ("110"); - g_error_free (error); - } - error = NULL; - server_address = g_key_file_get_string (keyfile, "global", "server", - &error); - if (server_address == NULL && error != NULL) - { - server_address = g_strdup ("127.0.0.1"); - g_error_free (error); - } - error = NULL; - server_port = g_key_file_get_string (keyfile, "global", "server_port", - &error); - if (server_port == NULL && error != NULL) - { - server_port = g_strdup ("995"); - g_error_free (error); - } - error = NULL; - server_ssl = g_key_file_get_boolean (keyfile, "global", "server_ssl", - &error); - if (server_ssl == 0 && error != NULL) - { - server_ssl = 0; - g_error_free (error); - } - error = NULL; - server_priority = g_key_file_get_string (keyfile, "global", "priority", - &error); - if (server_priority == NULL && error != NULL) - { - server_priority = g_strdup ("NORMAL"); - g_error_free (error); - } - - error = NULL; - policy = g_key_file_get_string (keyfile, "global", "policy", - &error); - if (policy == NULL && error != NULL) - { - policy = g_strdup ("deny"); - g_error_free (error); - } - - if (!strcmp (policy, "allow")) - ACCESS_DEFAULT = ACCESS_ALLOW; - g_free (policy); - - - pop_address.server = server_address; - pop_address.port = server_port; - pop_address.ssl = server_ssl; - pop_address.priority = server_priority; - - server_fd = hc_tcp_server (port); - if (server_fd < 0) - { - g_critical ("Could not create server."); - exit (1); - } - hc_server_add_watch (server_fd, new_client, &pop_address); - - pop_log_init (); - - g_message ("Listening at %s:%s.", conf_address, port); - if (ACCESS_DEFAULT == ACCESS_ALLOW) - g_message ("Authorizing users by default."); - - if (!foreground) - daemon (0, 0); - - g_free (conf_address); - g_free (port); - - hc_conn_ssl_server_init_credentials (certfile, ssl_keyfile); - - g_free (certfile); - g_free (ssl_keyfile); - - g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE)); - - gnutls_global_deinit (); - - g_free (server_address); - g_free (server_port); - - return 0; - -} diff --git a/popproxy.conf b/popproxy.conf deleted file mode 100644 index 6cea4b2..0000000 --- a/popproxy.conf +++ /dev/null @@ -1,11 +0,0 @@ -[global] - -address = 0.0.0.0 -port = 1100 -server = 127.0.0.1 -server_port = 995 -server_ssl = 1 -certfile = cert.pem -keyfile = key.pem -policy = allow -priority = NORMAL diff --git a/popproxy.init b/popproxy.init deleted file mode 100644 index 372f3ec..0000000 --- a/popproxy.init +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: popproxy -# Required-Start: -# Required-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 1 -# Short-Description: POP Proxy -### END INIT INFO - -POPPROXY_BIN=/usr/sbin/popproxy - -if [ -f /etc/init.d/functions ] - . /etc/init.d/functions -fi - -case $1 in - start) - daemon $POPPROXY_BIN - ;; - stop) - killproc $POPPROXY_BIN - ;; - restart) - $0 stop - $0 start - ;; - *) - echo Not implemented. Use one of start, stop or restart. - exit 1 - ;; -esac - diff --git a/popproxy.spec b/popproxy.spec deleted file mode 100644 index 099c97b..0000000 --- a/popproxy.spec +++ /dev/null @@ -1,55 +0,0 @@ -Name: popproxy -Version: 0.1.3 -Release: 1 -License: GPL -Group: System Environment/Daemons -Summary: POP3 Proxy -Vendor: Holoscópio Tecnologia Ltda. -URL: http://holoscopio.com/ -Source: popproxy-%{version}.tar.gz -BuildRequires: glib2-devel gnutls-devel gdbm-devel -Buildroot: %{_tmppath}/%{name}-%{version}-root -%description -POP3 Proxy with SSL support and user access control. - -%define _sysconfdir /etc -%prep -%setup -q - -%build -%configure -make - -%install -rm -rf %{buildroot} -%makeinstall -install -D -m 755 popproxy.init %{buildroot}/etc/init.d/popproxy - -%clean -rm -rf %{buildroot} - -%files -%defattr(-,root,root) -%{_bindir}/popproxy -%{_bindir}/ppmanager -%config /etc/popproxy.conf -/etc/init.d/popproxy -%dir /etc/pki/popproxy/ - -%post -mkdir /var/lib/popproxy -chkconfig --add popproxy - -%preun -if [ "$1" == 0 ]; then - /sbin/service popproxy stop > /dev/null 2>&1 -fi - -%postun -if [ "$1" -ge 1 ]; then - /sbin/service popproxy condrestart > /dev/null 2>&1 -fi - -%changelog -* Tue Jul 07 2009 Thadeu Lima de Souza Cascardo -- Added remove and upgrade scripts diff --git a/ppmanager.c b/ppmanager.c deleted file mode 100644 index f67714b..0000000 --- a/ppmanager.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -*/ - -#include -#include -#include -#include -#include - -enum -{ - ACTION_ADD, - ACTION_DEL, - ACTION_LIST -}; - -void -pp_dblistkeys (GDBM_FILE db) -{ - datum key; - datum oldkey; - key = gdbm_firstkey (db); - while (key.dptr != NULL) - { - printf ("%s\n", key.dptr); - oldkey = key; - key = gdbm_nextkey (db, oldkey); - free (oldkey.dptr); - } -} - -void -usage (char *programname) -{ - fprintf (stderr, "%s {allow | deny} {add | del | list} [user]\n", - programname); - exit (1); -} - -int -main (int argc, char **argv) -{ - GDBM_FILE db; - int action; - char *db_fn; - char *username; - datum key; - datum data; - int r = 0; - if (argc < 3) - usage (argv[0]); - if (!strcmp (argv[1], "deny")) - db_fn = "/var/lib/popproxy/deny.db"; - else if (!strcmp (argv[1], "allow")) - db_fn = "/var/lib/popproxy/allow.db"; - else - usage (argv[0]); - if (!strcmp (argv[2], "add")) - action = ACTION_ADD; - else if (!strcmp (argv[2], "del")) - action = ACTION_DEL; - else if (!strcmp (argv[2], "list")) - action = ACTION_LIST; - else - usage (argv[0]); - if ((action == ACTION_ADD || action == ACTION_DEL) && argc < 4) - usage (argv[0]); - if (action != ACTION_LIST) - { - username = argv[3]; - key.dptr = username; - key.dsize = strlen (username); - data.dptr = ""; - data.dsize = 1; - } - db = gdbm_open (db_fn, 0, GDBM_WRCREAT, 0600, NULL); - if (db == NULL) - { - fprintf (stderr, "Could not create database.\n"); - exit (1); - } - switch (action) - { - case ACTION_ADD: - r = gdbm_store (db, key, data, GDBM_REPLACE); - break; - case ACTION_DEL: - r = gdbm_delete (db, key); - break; - case ACTION_LIST: - pp_dblistkeys (db); - r = 0; - break; - default: - fprintf (stderr, "Action unrecognized.\n"); - r = 1; - } - gdbm_close (db); - return r; -} diff --git a/rnetproxy.c b/rnetproxy.c new file mode 100644 index 0000000..7e87455 --- /dev/null +++ b/rnetproxy.c @@ -0,0 +1,367 @@ +/* +** Copyright (C) 2006 Thadeu Lima de Souza Cascardo +** Copyright (C) 2009 Thadeu Lima de Souza Cascardo +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +** +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "log.h" + +#include "hcconn.h" +#include "hcconn_ssl.h" +#include "tcp_connect.h" + +#include "usermap.h" + +#define CONFFILE SYSCONFDIR "/rnetproxy.conf" + +struct rnet_address +{ + char *server; + char *port; + int ssl; + char *priority; +}; + +static HCConn * +server_conn_new (char *server, char *port, int ssl) +{ + int fd; + HCConn *conn; + HCConn *ssl_conn; + int r; + fd = hc_tcp_connect (server, port); + if (fd < 0) + { + g_warning ("Could not connect to server at %s:%s.", server, port); + return NULL; + } + conn = hc_conn_new (NULL, NULL); + r = hc_conn_set_driver_channel (conn, fd); + if (r != 0) + { + hc_conn_close (conn); + close (fd); + return NULL; + } + if (!ssl) + return conn; + ssl_conn = hc_conn_new (NULL, NULL); + r = hc_conn_set_driver_ssl_client (ssl_conn, conn); + if (r != 0) + { + hc_conn_close (ssl_conn); + hc_conn_close (conn); + return NULL; + } + return ssl_conn; +} + +static HCConn * +client_conn_new (int fd, struct rnet_address *address) +{ + HCConn *conn; + HCConn *ssl_conn; + HCConn *rnet_conn; + int r; + conn = hc_conn_new (NULL, NULL); + r = hc_conn_set_driver_channel (conn, fd); + if (r != 0) + { + hc_conn_close (conn); + close (fd); + return NULL; + } + + ssl_conn = hc_conn_new (NULL, NULL); + hc_conn_set_driver_ssl_server (ssl_conn, conn); + if (address && address->priority) + hc_conn_ssl_server_set_priority (ssl_conn, address->priority); + + if (r != 0) + { + hc_conn_close (ssl_conn); + hc_conn_close (conn); + return NULL; + } + rnet_conn = hc_conn_new (NULL, NULL); + r = hc_conn_set_driver_rnet (rnet_conn, ssl_conn); + if (r != 0) + { + hc_conn_close (rnet_conn); + hc_conn_close (ssl_conn); + return NULL; + } + return rnet_conn; +} + +static void +push_other (HCConn *conn, HCEvent event, gpointer data) +{ + char buffer[4096]; + int r; + switch (event) + { + case HC_EVENT_READ: + while ((r = hc_conn_read (conn, buffer, sizeof (buffer))) > 0) + hc_conn_write (data, buffer, r); + break; + case HC_EVENT_CLOSE: + hc_conn_close (conn); + hc_conn_close (data); + break; + } +} + +static void +ssl_connected (HCConn *client_conn, HCEvent event, gpointer data) +{ + struct rnet_address *address = data; + HCConn *server_conn; + if (event != HC_EVENT_CONNECT) + { + g_debug ("Did not get connect event when trying to handshake:" + " got %d", event); + hc_conn_close (client_conn); + return; + } + server_conn = server_conn_new (address->server, address->port, + address->ssl); + if (server_conn == NULL) + { + g_debug ("Failure to create connection to server."); + hc_conn_close (client_conn); + return; + } + hc_conn_set_callback (client_conn, push_other, server_conn); + hc_conn_set_callback (server_conn, push_other, client_conn); +} + +static void +new_client (int fd, struct sockaddr *addr, socklen_t saddr, gpointer data) +{ + HCConn *client_conn; + struct rnet_address *address = data; + if (fd < 0) + { + g_critical ("Server has received an error event."); + return; + } + + /* FIXME: Should be independent of address type. */ + g_message ("Received connection from %s.", + inet_ntoa (((struct sockaddr_in *) addr)->sin_addr)); + + client_conn = client_conn_new (fd, address); + if (client_conn == NULL) + { + return; + } + + hc_conn_set_callback (client_conn, ssl_connected, address); + +} + +static gchar *configfile; +static gboolean foreground; + +static GOptionEntry opt_entries[] = + { + { "config-file", 'c', 0, G_OPTION_ARG_FILENAME, &configfile, + "Configuration file location", "file" }, + { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, + "Run in foreground", 0 }, + { NULL } + }; + +int main (int argc, char **argv) +{ + + GOptionContext *opt_ctx; + GKeyFile *keyfile; + GError *error; + int server_fd; + gchar *conf_address; + gchar *port; + gchar *server_address; + gchar *server_port; + int server_ssl; + gchar *server_priority; + gchar *certfile; + gchar *ssl_keyfile; + gchar *policy; + struct rnet_address rnet_address; + + signal (SIGPIPE, SIG_IGN); + + gnutls_global_init (); + + configfile = CONFFILE; + opt_ctx = g_option_context_new (""); + g_option_context_add_main_entries (opt_ctx, opt_entries, NULL); + + error = NULL; + if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) + { + g_critical ("Could not parse command line options: %s.", + error->message); + g_error_free (error); + exit (1); + } + g_option_context_free (opt_ctx); + + keyfile = g_key_file_new (); + + error = NULL; + if (g_key_file_load_from_file (keyfile, configfile, + G_KEY_FILE_NONE, &error) == FALSE) + { + g_critical ("Could not load configuration file %s: %s.", + configfile, error->message); + g_error_free (error); + exit (1); + } + + error = NULL; + certfile = g_key_file_get_string (keyfile, "global", "certfile", + &error); + if (certfile == NULL && error != NULL) + { + g_critical ("No certification file specified: %s.", + error->message); + g_error_free (error); + exit (1); + } + error = NULL; + ssl_keyfile = g_key_file_get_string (keyfile, "global", "keyfile", + &error); + if (ssl_keyfile == NULL && error != NULL) + { + ssl_keyfile = g_strdup (certfile); + g_error_free (error); + } + + + error = NULL; + conf_address = g_key_file_get_string (keyfile, "global", "address", + &error); + if (conf_address == NULL && error != NULL) + { + conf_address = g_strdup ("0.0.0.0"); + g_error_free (error); + } + error = NULL; + port = g_key_file_get_string (keyfile, "global", "port", &error); + if (port == NULL && error != NULL) + { + port = g_strdup ("110"); + g_error_free (error); + } + error = NULL; + server_address = g_key_file_get_string (keyfile, "global", "server", + &error); + if (server_address == NULL && error != NULL) + { + server_address = g_strdup ("127.0.0.1"); + g_error_free (error); + } + error = NULL; + server_port = g_key_file_get_string (keyfile, "global", "server_port", + &error); + if (server_port == NULL && error != NULL) + { + server_port = g_strdup ("995"); + g_error_free (error); + } + error = NULL; + server_ssl = g_key_file_get_boolean (keyfile, "global", "server_ssl", + &error); + if (server_ssl == 0 && error != NULL) + { + server_ssl = 0; + g_error_free (error); + } + error = NULL; + server_priority = g_key_file_get_string (keyfile, "global", "priority", + &error); + if (server_priority == NULL && error != NULL) + { + server_priority = g_strdup ("NORMAL"); + g_error_free (error); + } + + error = NULL; + policy = g_key_file_get_string (keyfile, "global", "policy", + &error); + if (policy == NULL && error != NULL) + { + policy = g_strdup ("deny"); + g_error_free (error); + } + + if (!strcmp (policy, "allow")) + ACCESS_DEFAULT = ACCESS_ALLOW; + g_free (policy); + + + rnet_address.server = server_address; + rnet_address.port = server_port; + rnet_address.ssl = server_ssl; + rnet_address.priority = server_priority; + + server_fd = hc_tcp_server (port); + if (server_fd < 0) + { + g_critical ("Could not create server."); + exit (1); + } + hc_server_add_watch (server_fd, new_client, &rnet_address); + + rnet_log_init (); + + g_message ("Listening at %s:%s.", conf_address, port); + if (ACCESS_DEFAULT == ACCESS_ALLOW) + g_message ("Authorizing users by default."); + + if (!foreground) + daemon (0, 0); + + g_free (conf_address); + g_free (port); + + hc_conn_ssl_server_init_credentials (certfile, ssl_keyfile); + + g_free (certfile); + g_free (ssl_keyfile); + + g_main_loop_run (g_main_loop_new (g_main_context_default (), TRUE)); + + gnutls_global_deinit (); + + g_free (server_address); + g_free (server_port); + + return 0; + +} diff --git a/rnetproxy.conf b/rnetproxy.conf new file mode 100644 index 0000000..97788e2 --- /dev/null +++ b/rnetproxy.conf @@ -0,0 +1,10 @@ +[global] + +address = 0.0.0.0 +port = 3456 +server = 161.148.185.140 +server_port = 3456 +server_ssl = 1 +certfile = cert.pem +keyfile = key.pem +priority = NORMAL diff --git a/rnetproxy.init b/rnetproxy.init new file mode 100644 index 0000000..4851151 --- /dev/null +++ b/rnetproxy.init @@ -0,0 +1,34 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: rnetproxy +# Required-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 1 +# Short-Description: Receitanet Proxy +### END INIT INFO + +RNETPROXY_BIN=/usr/sbin/rnetproxy + +if [ -f /etc/init.d/functions ] +then + . /etc/init.d/functions +fi + +case $1 in + start) + daemon $RNETPROXY_BIN + ;; + stop) + killproc $RNETPROXY_BIN + ;; + restart) + $0 stop + $0 start + ;; + *) + echo Not implemented. Use one of start, stop or restart. + exit 1 + ;; +esac + diff --git a/rnetproxy.spec b/rnetproxy.spec new file mode 100644 index 0000000..2cddfff --- /dev/null +++ b/rnetproxy.spec @@ -0,0 +1,53 @@ +Name: rnetproxy +Version: 0.1 +Release: 1 +License: GPL +Group: System Environment/Daemons +Summary: Receitanet Proxy +Vendor: Minas Livre +URL: http://minaslivre.org/ +Source: rnetproxy-%{version}.tar.gz +BuildRequires: glib2-devel gnutls-devel +Buildroot: %{_tmppath}/%{name}-%{version}-root +%description +Receitanet Proxy with SSL support. + +%define _sysconfdir /etc +%prep +%setup -q + +%build +%configure +make + +%install +rm -rf %{buildroot} +%makeinstall +install -D -m 755 rnetproxy.init %{buildroot}/etc/init.d/rnetproxy + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root) +%{_bindir}/rnetproxy +%config /etc/rnetproxy.conf +/etc/init.d/rnetproxy +%dir /etc/pki/rnetproxy/ + +%post +chkconfig --add rnetproxy + +%preun +if [ "$1" == 0 ]; then + /sbin/service rnetproxy stop > /dev/null 2>&1 +fi + +%postun +if [ "$1" -ge 1 ]; then + /sbin/service rnetproxy condrestart > /dev/null 2>&1 +fi + +%changelog +* Tue Jul 07 2009 Thadeu Lima de Souza Cascardo +- Added remove and upgrade scripts diff --git a/tcp_connect.c b/tcp_connect.c index 99e12d4..1ec710f 100644 --- a/tcp_connect.c +++ b/tcp_connect.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Thadeu Lima de Souza Cascardo + * Copyright (C) 2008-2009 Thadeu Lima de Souza Cascardo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tcp_connect.h b/tcp_connect.h index 249d654..90e0831 100644 --- a/tcp_connect.h +++ b/tcp_connect.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Thadeu Lima de Souza Cascardo + * Copyright (C) 2008 Thadeu Lima de Souza Cascardo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tcp_server.c b/tcp_server.c index 1bd3933..a51df9f 100644 --- a/tcp_server.c +++ b/tcp_server.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2008 Thadeu Lima de Souza Cascardo - * Copyright (C) 2009 Thadeu Lima de Souza Cascardo + * Copyright (C) 2008 Thadeu Lima de Souza Cascardo + * Copyright (C) 2009 Thadeu Lima de Souza Cascardo * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/usermap.c b/usermap.c deleted file mode 100644 index 9b8cb62..0000000 --- a/usermap.c +++ /dev/null @@ -1,56 +0,0 @@ -/* -** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -*/ - -#include -#include -#include "usermap.h" - -int ACCESS_DEFAULT = ACCESS_DENY; - -int -usermap_perm (char *user) -{ - GDBM_FILE allow_db = NULL; - GDBM_FILE deny_db = NULL; - int allow = 0; - int deny = 0; - datum key; - key.dptr = user; - key.dsize = strlen (user); - allow_db = gdbm_open ("/var/lib/popproxy/allow.db", - 0, GDBM_READER, 0, NULL); - deny_db = gdbm_open ("/var/lib/popproxy/deny.db", - 0, GDBM_READER, 0, NULL); - if (allow_db) - { - allow = gdbm_exists (allow_db, key); - gdbm_close (allow_db); - } - if (deny_db) - { - deny = gdbm_exists (deny_db, key); - gdbm_close (deny_db); - } - if (deny) - return ACCESS_DENY; - if (allow) - return ACCESS_ALLOW; - return ACCESS_DEFAULT; -} diff --git a/usermap.h b/usermap.h deleted file mode 100644 index 363a778..0000000 --- a/usermap.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -** Copyright (C) 2006 Thadeu Lima de Souza Cascardo -** Copyright (C) 2009 Thadeu Lima de Souza Cascardo -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -** -*/ - -#ifndef POPPROXY_USERMAP_H -#define POPPROXY_USERMAP_H - -enum -{ - ACCESS_ALLOW, - ACCESS_DENY -}; - -int usermap_perm (char *); - -extern int ACCESS_DEFAULT; - -#endif