mirror of
https://github.com/irssi/irssi.git
synced 2026-08-18 16:12:30 +02:00
use starttls
This commit is contained in:
parent
9b02424f30
commit
51508ff1d3
13 changed files with 324 additions and 116 deletions
|
|
@ -20,10 +20,11 @@
|
|||
|
||||
#include "module.h"
|
||||
|
||||
#include <irssi/src/core/net-sendbuffer.h>
|
||||
#include <irssi/src/core/signals.h>
|
||||
#include <irssi/src/core/rawlog.h>
|
||||
#include <irssi/src/core/misc.h>
|
||||
#include <irssi/src/core/net-sendbuffer.h>
|
||||
#include <irssi/src/core/network.h>
|
||||
#include <irssi/src/core/rawlog.h>
|
||||
#include <irssi/src/core/signals.h>
|
||||
|
||||
#include <irssi/src/core/channels.h>
|
||||
#include <irssi/src/core/queries.h>
|
||||
|
|
@ -207,17 +208,17 @@ static char **split_message(SERVER_REC *server, const char *target,
|
|||
strlen(target));
|
||||
}
|
||||
|
||||
static void server_init(IRC_SERVER_REC *server)
|
||||
static void server_init_2(IRC_SERVER_REC *server);
|
||||
static void server_init_1(IRC_SERVER_REC *server)
|
||||
{
|
||||
IRC_SERVER_CONNECT_REC *conn;
|
||||
char *address, *ptr, *username, *cmd;
|
||||
char *cmd;
|
||||
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
conn = server->connrec;
|
||||
|
||||
if (conn->proxy != NULL && conn->proxy_password != NULL &&
|
||||
*conn->proxy_password != '\0') {
|
||||
if (conn->proxy != NULL && conn->proxy_password != NULL && *conn->proxy_password != '\0') {
|
||||
cmd = g_strdup_printf("PASS %s", conn->proxy_password);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
|
|
@ -243,45 +244,8 @@ static void server_init(IRC_SERVER_REC *server)
|
|||
irc_cap_toggle(server, CAP_ACCOUNT_NOTIFY, TRUE);
|
||||
irc_cap_toggle(server, CAP_SELF_MESSAGE, TRUE);
|
||||
irc_cap_toggle(server, CAP_SERVER_TIME, TRUE);
|
||||
|
||||
irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION);
|
||||
|
||||
if (conn->password != NULL && *conn->password != '\0') {
|
||||
/* send password */
|
||||
cmd = g_strdup_printf("PASS %s", conn->password);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
}
|
||||
|
||||
/* send nick */
|
||||
cmd = g_strdup_printf("NICK %s", conn->nick);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
|
||||
/* send user/realname */
|
||||
address = server->connrec->address;
|
||||
ptr = strrchr(address, ':');
|
||||
if (ptr != NULL) {
|
||||
/* IPv6 address .. doesn't work here, use the string after
|
||||
the last : char */
|
||||
address = ptr+1;
|
||||
if (*address == '\0')
|
||||
address = "x";
|
||||
}
|
||||
|
||||
username = g_strdup(conn->username);
|
||||
ptr = strchr(username, ' ');
|
||||
if (ptr != NULL) *ptr = '\0';
|
||||
|
||||
cmd = g_strdup_printf("USER %s %s %s :%s", username, username, address, conn->realname);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
g_free(username);
|
||||
|
||||
if (conn->proxy != NULL && conn->proxy_string_after != NULL) {
|
||||
cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
if (!conn->use_tls && (conn->starttls || !conn->no_starttls)) {
|
||||
irc_cap_toggle(server, CAP_STARTTLS, TRUE);
|
||||
}
|
||||
|
||||
server->isupport = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal);
|
||||
|
|
@ -296,6 +260,163 @@ static void server_init(IRC_SERVER_REC *server)
|
|||
/* this will reset to 1 sec after we get the 001 event */
|
||||
server->wait_cmd = g_get_real_time();
|
||||
server->wait_cmd += 120 * G_USEC_PER_SEC;
|
||||
|
||||
irc_send_cmd_now(server, "CAP LS " CAP_LS_VERSION);
|
||||
/* to detect non-CAP servers, send this bogus join */
|
||||
irc_send_cmd_now(server, "JOIN ");
|
||||
if (conn->starttls)
|
||||
irc_server_send_starttls(server);
|
||||
}
|
||||
|
||||
static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (server->starttls_tag) {
|
||||
g_source_remove(server->starttls_tag);
|
||||
server->starttls_tag = 0;
|
||||
}
|
||||
|
||||
error = irssi_ssl_handshake(handle);
|
||||
if (error == -1) {
|
||||
server->connection_lost = TRUE;
|
||||
server_disconnect((SERVER_REC *) server);
|
||||
return;
|
||||
}
|
||||
if (error & 1) { /* wait */
|
||||
server->starttls_tag =
|
||||
i_input_add(handle, error == 1 ? I_INPUT_READ : I_INPUT_WRITE,
|
||||
(GInputFunction) init_ssl_loop, server);
|
||||
return;
|
||||
}
|
||||
/* continue */
|
||||
rawlog_redirect(server->rawlog, "Now talking encrypted");
|
||||
signal_emit("server connection switched", 1, server);
|
||||
if (!server->cap_supported) {
|
||||
server_init_2(server);
|
||||
} else {
|
||||
signal_emit("server cap continue", 1, server);
|
||||
}
|
||||
|
||||
server->connrec->starttls = 1;
|
||||
if (settings_get_bool("starttls_sts")) {
|
||||
IRC_SERVER_SETUP_REC *ssetup = IRC_SERVER_SETUP(server_setup_find(
|
||||
server->connrec->address, server->connrec->port, server->connrec->chatnet));
|
||||
if (ssetup != NULL) {
|
||||
ssetup->starttls = 1;
|
||||
server_setup_add((SERVER_SETUP_REC *) ssetup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <irssi/src/core/line-split.h>
|
||||
void irc_server_send_starttls(IRC_SERVER_REC *server)
|
||||
{
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
g_warning("Now attempting STARTTLS");
|
||||
irc_send_cmd_now(server, "STARTTLS");
|
||||
}
|
||||
|
||||
static void event_starttls(IRC_SERVER_REC *server, const char *data)
|
||||
{
|
||||
GIOChannel *ssl_handle;
|
||||
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
if (!IS_IRC_SERVER(server))
|
||||
return;
|
||||
|
||||
if (server->handle->readbuffer != NULL &&
|
||||
!line_split_is_empty(server->handle->readbuffer)) {
|
||||
char *str;
|
||||
line_split("", -1, &str, &server->handle->readbuffer);
|
||||
}
|
||||
ssl_handle = net_start_ssl((SERVER_REC *) server);
|
||||
if (ssl_handle != NULL) {
|
||||
g_source_remove(server->readtag);
|
||||
server->readtag = -1;
|
||||
server->handle->handle = ssl_handle;
|
||||
init_ssl_loop(server, server->handle->handle);
|
||||
} else {
|
||||
g_warning("net_start_ssl failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void event_registerfirst(IRC_SERVER_REC *server, const char *data)
|
||||
{
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
if (!IS_IRC_SERVER(server))
|
||||
return;
|
||||
|
||||
if (server->connected)
|
||||
return;
|
||||
|
||||
if (!server->cap_supported && !server->connrec->starttls)
|
||||
server_init_2(server);
|
||||
}
|
||||
|
||||
static void event_capend(IRC_SERVER_REC *server)
|
||||
{
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
if (!IS_IRC_SERVER(server))
|
||||
return;
|
||||
|
||||
if (server->connected)
|
||||
return;
|
||||
|
||||
server_init_2(server);
|
||||
}
|
||||
|
||||
static void server_init_2(IRC_SERVER_REC *server)
|
||||
{
|
||||
IRC_SERVER_CONNECT_REC *conn;
|
||||
char *address, *ptr, *username, *cmd;
|
||||
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
conn = server->connrec;
|
||||
|
||||
if (conn->password != NULL && *conn->password != '\0') {
|
||||
/* send password */
|
||||
cmd = g_strdup_printf("PASS %s", conn->password);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
}
|
||||
|
||||
/* send nick */
|
||||
cmd = g_strdup_printf("NICK %s", conn->nick);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
|
||||
/* send user/realname */
|
||||
address = server->connrec->address;
|
||||
ptr = strrchr(address, ':');
|
||||
if (ptr != NULL) {
|
||||
/* IPv6 address .. doesn't work here, use the string after
|
||||
the last : char */
|
||||
address = ptr + 1;
|
||||
if (*address == '\0')
|
||||
address = "x";
|
||||
}
|
||||
|
||||
username = g_strdup(conn->username);
|
||||
ptr = strchr(username, ' ');
|
||||
if (ptr != NULL)
|
||||
*ptr = '\0';
|
||||
|
||||
cmd = g_strdup_printf("USER %s %s %s :%s", username, username, address, conn->realname);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
g_free(username);
|
||||
|
||||
if (conn->proxy != NULL && conn->proxy_string_after != NULL) {
|
||||
cmd = g_strdup_printf(conn->proxy_string_after, conn->address, conn->port);
|
||||
irc_send_cmd_now(server, cmd);
|
||||
g_free(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
SERVER_REC *irc_server_init_connect(SERVER_CONNECT_REC *conn)
|
||||
|
|
@ -420,7 +541,7 @@ static void sig_connected(IRC_SERVER_REC *server)
|
|||
server->splits = g_hash_table_new((GHashFunc) i_istr_hash, (GCompareFunc) i_istr_equal);
|
||||
|
||||
if (!server->session_reconnect)
|
||||
server_init(server);
|
||||
server_init_1(server);
|
||||
}
|
||||
|
||||
static void isupport_destroy_hash(void *key, void *value)
|
||||
|
|
@ -429,6 +550,17 @@ static void isupport_destroy_hash(void *key, void *value)
|
|||
g_free(value);
|
||||
}
|
||||
|
||||
static void sig_disconnected(IRC_SERVER_REC *server)
|
||||
{
|
||||
if (!IS_IRC_SERVER(server))
|
||||
return;
|
||||
|
||||
if (server->starttls_tag) {
|
||||
g_source_remove(server->starttls_tag);
|
||||
server->starttls_tag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_destroyed(IRC_SERVER_REC *server)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
|
@ -1048,6 +1180,7 @@ void irc_server_init_isupport(IRC_SERVER_REC *server)
|
|||
|
||||
void irc_servers_init(void)
|
||||
{
|
||||
settings_add_bool("servers", "starttls_sts", TRUE);
|
||||
settings_add_choice("servers", "rejoin_channels_on_reconnect", 1, "off;on;auto");
|
||||
settings_add_str("misc", "usermode", DEFAULT_USER_MODE);
|
||||
settings_add_str("misc", "split_line_start", "");
|
||||
|
|
@ -1059,9 +1192,13 @@ void irc_servers_init(void)
|
|||
cmd_tag = -1;
|
||||
|
||||
signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
|
||||
signal_add_first("server disconnected", (SIGNAL_FUNC) sig_disconnected);
|
||||
signal_add_last("server destroyed", (SIGNAL_FUNC) sig_destroyed);
|
||||
signal_add_last("server quit", (SIGNAL_FUNC) sig_server_quit);
|
||||
signal_add("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline);
|
||||
signal_add("event 670", (SIGNAL_FUNC) event_starttls);
|
||||
signal_add("event 451", (SIGNAL_FUNC) event_registerfirst);
|
||||
signal_add("server cap end", (SIGNAL_FUNC) event_capend);
|
||||
signal_add("event 001", (SIGNAL_FUNC) event_connected);
|
||||
signal_add("event 004", (SIGNAL_FUNC) event_server_info);
|
||||
signal_add("event 005", (SIGNAL_FUNC) event_isupport);
|
||||
|
|
@ -1087,9 +1224,13 @@ void irc_servers_deinit(void)
|
|||
g_source_remove(cmd_tag);
|
||||
|
||||
signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
|
||||
signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
|
||||
signal_remove("server destroyed", (SIGNAL_FUNC) sig_destroyed);
|
||||
signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit);
|
||||
signal_remove("server cap ack " CAP_MAXLINE, (SIGNAL_FUNC) cap_maxline);
|
||||
signal_remove("event 670", (SIGNAL_FUNC) event_starttls);
|
||||
signal_remove("event 451", (SIGNAL_FUNC) event_registerfirst);
|
||||
signal_remove("server cap end", (SIGNAL_FUNC) event_capend);
|
||||
signal_remove("event 001", (SIGNAL_FUNC) event_connected);
|
||||
signal_remove("event 004", (SIGNAL_FUNC) event_server_info);
|
||||
signal_remove("event 005", (SIGNAL_FUNC) event_isupport);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue