aboutsummaryrefslogtreecommitdiffstats
path: root/irc_commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'irc_commands.c')
-rw-r--r--irc_commands.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/irc_commands.c b/irc_commands.c
index dd5bdf38..19855075 100644
--- a/irc_commands.c
+++ b/irc_commands.c
@@ -25,6 +25,7 @@
#define BITLBEE_CORE
#include "bitlbee.h"
+#include "canohost.h"
#include "help.h"
#include "ipc.h"
#include "base64.h"
@@ -58,6 +59,48 @@ static void irc_cmd_pass(irc_t *irc, char **cmd)
}
}
+/* http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
+
+ This isn't actually IRC, it's used by for example stunnel4 to indicate
+ the origin of the secured counterpart of the connection. It'll go wrong
+ with arguments starting with : like for example "::1" but I guess I'm
+ okay with that. */
+static void irc_cmd_proxy(irc_t *irc, char **cmd)
+{
+ struct addrinfo hints, *ai;
+ struct sockaddr_storage sock;
+ socklen_t socklen = sizeof(sock);
+
+ if (getpeername(irc->fd, (struct sockaddr*) &sock, &socklen) != 0) {
+ return;
+ }
+
+ ipv64_normalise_mapped(&sock, &socklen);
+
+ /* Only accept PROXY "command" on localhost sockets. */
+ if (!((sock.ss_family == AF_INET &&
+ ntohl(((struct sockaddr_in*)&sock)->sin_addr.s_addr) == INADDR_LOOPBACK) ||
+ (sock.ss_family == AF_INET6 &&
+ IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6*)&sock)->sin6_addr)))) {
+ return;
+ }
+
+ /* And only once. Do this with a pretty dumb regex-match for
+ now, maybe better to use some sort of flag.. */
+ if (!g_regex_match_simple("^(ip6-)?localhost(.(localdomain.?)?)?$", irc->user->host, 0, 0)) {
+ return;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(cmd[2], NULL, &hints, &ai) != 0) {
+ return;
+ }
+
+ irc_set_hosts(irc, ai->ai_addr, ai->ai_addrlen);
+ freeaddrinfo(ai);
+}
+
static gboolean irc_sasl_plain_parse(char *input, char **user, char **pass)
{
int i, part, len;
@@ -807,6 +850,7 @@ static void irc_cmd_rehash(irc_t *irc, char **cmd)
static const command_t irc_commands[] = {
{ "cap", 1, irc_cmd_cap, 0 },
{ "pass", 1, irc_cmd_pass, 0 },
+ { "proxy", 5, irc_cmd_proxy, IRC_CMD_PRE_LOGIN },
{ "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN },
{ "nick", 1, irc_cmd_nick, 0 },
{ "quit", 0, irc_cmd_quit, 0 },