From 72cee2b26449468734de68c797d0cc6945f176f9 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Tue, 22 Oct 2019 22:49:05 -0400 Subject: Implement serverLogin --- bounce.c | 10 ++++++++ bounce.h | 5 ++++ listen.c | 3 --- server.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/bounce.c b/bounce.c index b3d8b33..43d3ef8 100644 --- a/bounce.c +++ b/bounce.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -91,6 +92,15 @@ int main(int argc, char *argv[]) { int bind[BindCap]; size_t bindLen = listenBind(bind, BindCap, localHost, localPort); + int server = serverConnect(host, port); + serverLogin(pass, auth, nick, user, real); + + // TODO: Wait for successful login before listening. + for (size_t i = 0; i < bindLen; ++i) { + int error = listen(bind[i], 1); + if (error) err(EX_IOERR, "listen"); + } + // Wishing for struct-of-arrays... struct pollfd fds[BindCap]; for (size_t i = 0; i < bindLen; ++i) { diff --git a/bounce.h b/bounce.h index e731ac0..999180f 100644 --- a/bounce.h +++ b/bounce.h @@ -30,3 +30,8 @@ size_t listenBind(int fds[], size_t cap, const char *host, const char *port); int listenAccept(struct tls **client, int fd); int serverConnect(const char *host, const char *port); +void serverLogin( + const char *pass, const char *auth, + const char *nick, const char *user, const char *real +); +void serverSend(const char *ptr, size_t len); diff --git a/listen.c b/listen.c index d758b9d..1179a8b 100644 --- a/listen.c +++ b/listen.c @@ -69,9 +69,6 @@ size_t listenBind(int fds[], size_t cap, const char *host, const char *port) { continue; } - error = listen(fds[len], 1); - if (error) err(EX_IOERR, "listen"); - len++; } freeaddrinfo(head); diff --git a/server.c b/server.c index b86d769..4c22287 100644 --- a/server.c +++ b/server.c @@ -17,7 +17,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -25,6 +28,8 @@ #include "bounce.h" +typedef unsigned char byte; + static struct tls *client; int serverConnect(const char *host, const char *port) { @@ -69,3 +74,77 @@ int serverConnect(const char *host, const char *port) { return sock; } + +void serverSend(const char *ptr, size_t len) { + while (len) { + ssize_t ret = tls_write(client, ptr, len); + if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) continue; + if (ret < 0) errx(EX_IOERR, "tls_write: %s", tls_error(client)); + ptr += ret; + len -= ret; + } +} + +static void format(const char *format, ...) { + char *buf; + va_list ap; + va_start(ap, format); + int len = vasprintf(&buf, format, ap); + va_end(ap); + if (!buf) err(EX_OSERR, "vasprintf"); + serverSend(format, len); + free(buf); +} + +static const char Base64[64] = { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" +}; + +static char *base64(const byte *src, size_t len) { + char *dst = malloc(1 + (len + 2) / 3 * 4); + if (!dst) err(EX_OSERR, "malloc"); + + size_t i = 0; + while (len > 2) { + dst[i++] = Base64[0x3F & (src[0] >> 2)]; + dst[i++] = Base64[0x3F & (src[0] << 4 | src[1] >> 4)]; + dst[i++] = Base64[0x3F & (src[1] << 2 | src[2] >> 6)]; + dst[i++] = Base64[0x3F & src[2]]; + src += 3; + len -= 3; + } + + if (len) { + dst[i++] = Base64[0x3F & (src[0] >> 2)]; + if (len > 1) { + dst[i++] = Base64[0x3F & (src[0] << 4 | src[1] >> 4)]; + dst[i++] = Base64[0x3F & (src[1] << 2)]; + } else { + dst[i++] = Base64[0x3F & (src[0] << 4)]; + dst[i++] = '='; + } + dst[i++] = '='; + } + + dst[i] = '\0'; + return dst; +} + +static char *authBase64; + +void serverLogin( + const char *pass, const char *auth, + const char *nick, const char *user, const char *real +) { + if (pass) format("PASS :%s\r\n", pass); + if (auth) { + byte plain[1 + strlen(auth)]; + plain[0] = 0; + for (size_t i = 0; auth[i]; ++i) { + plain[1 + i] = (auth[i] == ':' ? 0 : auth[i]); + } + authBase64 = base64(plain, sizeof(plain)); + format("CAP REQ :sasl\r\n"); + } + format("NICK %s\r\nUSER %s 0 * :%s\r\n", nick, user, real); +} -- cgit 1.4.1