]> PatchyGit - patchyircd.git/commitdiff
add WEBIRC support
authorEgor <egor@patchysicp.xyz>
Fri, 28 Jun 2024 17:46:30 +0000 (20:46 +0300)
committerEgor <egor@patchysicp.xyz>
Fri, 28 Jun 2024 17:46:30 +0000 (20:46 +0300)
data/.gitignore
src/admin.c
src/common.h
src/irc.c
src/main.c
src/net.c

index fc5f977..d00c475 100644 (file)
@@ -10,3 +10,4 @@ motd.txt
 certfp.txt
 nicks.txt
 irccloud.txt
+webirc.txt
index 2e54325..ab8ef63 100644 (file)
@@ -146,6 +146,7 @@ static int client_index(lua_State *L)
        /* saslbuf */
        /* saslbufLen */
        /* saslusername */
+       /* webircpeername */
        /* buf/bufLen/wbuf/wbufLen */
        integer_getter(cl, umode);
        integer_getter(cl, regstate);
@@ -166,6 +167,7 @@ static int client_index(lua_State *L)
        integer_getter(cl, poll_reg);
        /* saslexternal */
        /* passwait */
+       /* webircwait */
        return 0;
 }
 static int channel_index(lua_State *L)
index 5dcdad6..7e94d07 100644 (file)
@@ -51,6 +51,7 @@ struct client_data {
        char   *saslbuf;
        size_t saslbufLen;
        char   *saslusername;
+       char   *webircpeername;
        char   buf[2048];
        size_t bufLen;
        char   wbuf[8192];
@@ -74,6 +75,7 @@ struct client_data {
        unsigned poll_reg :2;
        unsigned saslexternal :1;
        unsigned passwait :1;
+       unsigned webircwait :2;
 };
 struct channel {
        char *key;
index e21ebc4..2de69fb 100644 (file)
--- a/src/irc.c
+++ b/src/irc.c
@@ -182,6 +182,23 @@ int parsePacket(struct client_data *client) {
        fprintf(stderr, "\n");
        return processPacket(client, source, command, argc, args);
 }
+static void cont_webirc(struct client_data *client, int res) {
+       if (!(client->umode & UMODE_SECURE) || res != 0) {
+               free(client->webircpeername);
+               client->webircpeername = 0;
+               err_passwdmismatch(client), sendbuf(client);
+       } else {
+               free(client->peername);
+               client->peername = client->webircpeername;
+               client->webircpeername = 0;
+               if (client->webircwait == 2) {
+                       // NOTE: this relies on the job system being FIFO
+                       client->umode &= ~UMODE_SECURE;
+               }
+               client->webircwait = 0;
+               newUser(client);
+       }
+}
 static void cont_oper(struct client_data *client, int res) {
        if (!(client->umode & UMODE_SECURE) || res != 0) {
                err_passwdmismatch(client), sendbuf(client);
@@ -469,6 +486,20 @@ saslcleanup:
                client->pass_reg = mystrdup(args[0]);
                memset(args[0], 0, strlen(args[0]));
                if (!client->pass_reg) abort();
+       } else if(strcmp(command, "WEBIRC") == 0) {
+               if (is_registered(client))
+                       return err_alreadyregistered(client), sendbuf(client), 0;
+               if (argc < 4)
+                       return err_needmoreparams(client, command), sendbuf(client), 0;
+               if (!client->webircwait) {
+                       client->webircpeername = mystrdup(args[3]);
+                       if (argc > 4 && (!strncmp(args[4], "secure", 6) || strstr(args[4], " secure")))
+                               client->webircwait = 1;
+                       else
+                               client->webircwait = 2;
+                       job_password_check(client, args[1], args[0], getdatafile("webirc.txt"), cont_webirc);
+                       memset(args[0], 0, strlen(args[0]));
+               }
        } else if(strcmp(command, "OPER") == 0) {
                if (!is_registered(client))
                        return err_notregistered(client), sendbuf(client), 0;
@@ -1165,7 +1196,7 @@ unknown:
 }
 
 void newUser(struct client_data *client) {
-       if (client->regstate == REG_CAPLS || !client->nick_reg || !client->username || client->passwait)
+       if (client->regstate == REG_CAPLS || !client->nick_reg || !client->username || client->passwait || client->webircwait)
                return;
        if (client->saslbuf || client->saslusername) {
                copy_strf(&databuf, ":%s 906 * :SASL auhtentication aborted\r\n", hostname), sendbuf(client);
index 05548c1..02e6828 100644 (file)
@@ -151,6 +151,7 @@ void accept_from_sock(struct listener *listener)
                net_nonblock(newSocket);
 
                int is_onion = 0;
+               int is_webirc = 0;
                {
                        struct sockaddr_storage sockname;
                        socklen_t socknamelen = sizeof(sockname);
@@ -163,6 +164,9 @@ void accept_from_sock(struct listener *listener)
                                // onion if connecting to 127.0.0.2
                                if (ntohl(ia->s_addr) == 0x7F000002)
                                        is_onion = 1;
+                               // webirc if connecting to 127.0.0.3
+                               if (ntohl(ia->s_addr) == 0x7F000003)
+                                       is_webirc = 1;
                        }
                }
 
@@ -211,7 +215,7 @@ void accept_from_sock(struct listener *listener)
                        cl->umode |= UMODE_SECURE;
                extern const char *hostname;
                if (is_local) {
-                       cl->hostname = mystrdup(is_onion ? "onion" : "localhost");
+                       cl->hostname = mystrdup(is_webirc ? "webirc" : is_onion ? "onion" : "localhost");
                        cl->umode |= UMODE_SECURE;
                } else {
                        cl->hostname = mystrdup(hostname);
index 1e6f2ac..ddd9b00 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -142,6 +142,7 @@ void killConnectionPart2(struct client_data *cl)
                memset(cl->saslbuf, 0, 1024);
        free(cl->saslbuf);
        free(cl->saslusername);
+       free(cl->webircpeername);
        free(cl);
 }