diff options
Diffstat (limited to 'src/irc')
-rw-r--r-- | src/irc/irc-display.c | 3 | ||||
-rw-r--r-- | src/irc/irc-server.c | 73 | ||||
-rw-r--r-- | src/irc/irc.h | 7 |
3 files changed, 71 insertions, 12 deletions
diff --git a/src/irc/irc-display.c b/src/irc/irc-display.c index 1fd1e045c..ab7276d45 100644 --- a/src/irc/irc-display.c +++ b/src/irc/irc-display.c @@ -176,6 +176,9 @@ irc_display_server (t_irc_server *server) " server_port . . . . . . .: %d\n", server->port); gui_printf_color (NULL, COLOR_WIN_CHAT, + " server_ssl . . . . . . . .: %s\n", + (server->ssl) ? _("yes") : _("no")); + gui_printf_color (NULL, COLOR_WIN_CHAT, " server_password . . . . .: %s\n", (server->password && server->password[0]) ? _("(hidden)") : ""); diff --git a/src/irc/irc-server.c b/src/irc/irc-server.c index e1cbf5453..3497a724c 100644 --- a/src/irc/irc-server.c +++ b/src/irc/irc-server.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* irc-server.c: (dis)connection and communication with irc server */ +/* irc-server.c: connection and communication with IRC server */ #ifdef HAVE_CONFIG_H @@ -38,6 +38,7 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> +#include <gnutls/gnutls.h> #include "../common/weechat.h" #include "irc.h" @@ -67,6 +68,7 @@ server_init (t_irc_server *server) server->command_line = 0; server->address = NULL; server->port = -1; + server->ssl = 0; server->password = NULL; server->nick1 = NULL; server->nick2 = NULL; @@ -317,7 +319,7 @@ server_free_all () t_irc_server * server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_delay, - int command_line, char *address, int port, char *password, + int command_line, char *address, int port, int ssl, char *password, char *nick1, char *nick2, char *nick3, char *username, char *realname, char *command, int command_delay, char *autojoin, int autorejoin, char *notify_levels) @@ -347,6 +349,7 @@ server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_de new_server->command_line = command_line; new_server->address = strdup (address); new_server->port = port; + new_server->ssl = ssl; new_server->password = (password) ? strdup (password) : strdup (""); new_server->nick1 = (nick1) ? strdup (nick1) : strdup ("weechat_user"); new_server->nick2 = (nick2) ? strdup (nick2) : strdup ("weechat2"); @@ -371,7 +374,7 @@ server_new (char *name, int autoconnect, int autoreconnect, int autoreconnect_de } /* - * server_send: send data to irc server + * server_send: send data to IRC server */ int @@ -380,11 +383,14 @@ server_send (t_irc_server *server, char *buffer, int size_buf) if (!server) return -1; - return send (server->sock, buffer, size_buf, 0); + if (server->ssl) + return gnutls_record_send (server->gnutls_sess, buffer, size_buf); + else + return send (server->sock, buffer, size_buf, 0); } /* - * server_sendf: send formatted data to irc server + * server_sendf: send formatted data to IRC server */ void @@ -651,7 +657,14 @@ server_recv (t_irc_server *server) static char buffer[4096 + 2]; int num_read; - num_read = recv (server->sock, buffer, sizeof (buffer) - 2, 0); + if (!server) + return; + + if (server->ssl) + num_read = gnutls_record_recv (server->gnutls_sess, buffer, sizeof (buffer) - 2); + else + num_read = recv (server->sock, buffer, sizeof (buffer) - 2, 0); + if (num_read > 0) { buffer[num_read] = '\0'; @@ -708,8 +721,12 @@ server_close_connection (t_irc_server *server) /* close network socket */ if (server->sock != -1) { + if (server->ssl) + gnutls_bye (server->gnutls_sess, GNUTLS_SHUT_RDWR); close (server->sock); server->sock = -1; + if (server->ssl) + gnutls_deinit (server->gnutls_sess); } /* free any pending message */ @@ -758,6 +775,22 @@ server_child_read (t_irc_server *server) { /* connection OK */ case '0': + /* enable SSL if asked */ + if (server->ssl) + { + gnutls_transport_set_ptr (server->gnutls_sess, (gnutls_transport_ptr) server->sock); + if (gnutls_handshake (server->gnutls_sess) < 0) + { + irc_display_prefix (server->buffer, PREFIX_ERROR); + gui_printf (server->buffer, + _("%s gnutls handshake failed\n"), + WEECHAT_ERROR); + server_close_connection (server); + server_reconnect_schedule (server); + return; + } + } + /* kill child and login to server */ server_kill_child (server); irc_login (server); break; @@ -845,17 +878,37 @@ server_connect (t_irc_server *server) { int child_pipe[2], set; pid_t pid; + const int proto_prio[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; + const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; irc_display_prefix (server->buffer, PREFIX_INFO); gui_printf (server->buffer, - _("%s: connecting to %s:%d...\n"), - PACKAGE_NAME, server->address, server->port); - wee_log_printf (_("Connecting to server %s:%d...\n"), - server->address, server->port); + _("%s: connecting to %s:%d%s...\n"), + PACKAGE_NAME, server->address, server->port, + (server->ssl) ? "(ssl)" : ""); + wee_log_printf (_("Connecting to server %s:%d%s...\n"), + server->address, server->port, + (server->ssl) ? "(ssl)" : ""); /* close any opened connection and kill child process if running */ server_close_connection (server); + /* init SSL if asked */ + if (server->ssl) + { + if (gnutls_init (&server->gnutls_sess, GNUTLS_CLIENT) != 0) + { + irc_display_prefix (server->buffer, PREFIX_ERROR); + gui_printf (server->buffer, + _("%s gnutls init error\n"), WEECHAT_ERROR); + return 0; + } + gnutls_set_default_priority (server->gnutls_sess); + gnutls_protocol_set_priority (server->gnutls_sess, proto_prio); + gnutls_kx_set_priority (server->gnutls_sess, kx_prio); + gnutls_credentials_set (server->gnutls_sess, GNUTLS_CRD_ANON, &gnutls_anoncred); + } + /* create pipe for child process */ if (pipe (child_pipe) < 0) { diff --git a/src/irc/irc.h b/src/irc/irc.h index e397937d0..f0a920f5f 100644 --- a/src/irc/irc.h +++ b/src/irc/irc.h @@ -24,6 +24,7 @@ #include <time.h> #include <sys/time.h> #include <sys/types.h> +#include <gnutls/gnutls.h> #include "../gui/gui.h" /* prefixes for chat window */ @@ -137,6 +138,7 @@ struct t_irc_server int command_line; /* server was given on command line */ char *address; /* address of server (IP or name) */ int port; /* port for server (6667 by default) */ + int ssl; /* SSL protocol */ char *password; /* password for server */ char *nick1; /* first nickname for the server */ char *nick2; /* alternate nickname */ @@ -154,6 +156,7 @@ struct t_irc_server int child_read; /* to read into child pipe */ int child_write; /* to write into child pipe */ int sock; /* socket for server */ + gnutls_session gnutls_sess; /* gnutls session (only if SSL is used) */ int is_connected; /* 1 if WeeChat is connected to server */ char *unterminated_message; /* beginning of a message in input buf */ char *nick; /* current nickname */ @@ -249,9 +252,9 @@ extern t_irc_server *server_alloc (); extern void server_destroy (t_irc_server *); extern void server_free (t_irc_server *); extern void server_free_all (); -extern t_irc_server *server_new (char *, int, int, int, int, char *, int, char *, +extern t_irc_server *server_new (char *, int, int, int, int, char *, int, int, char *, char *, char *, char *, char *, char *, - int, char *, int, char *); + char *, int, char *, int, char *); extern int server_send (t_irc_server *, char *, int); extern void server_sendf (t_irc_server *, char *, ...); extern void server_recv (t_irc_server *); |