]> PatchyGit - patchyircd.git/commitdiff
add basic account system
authorEgor <egor@patchysicp.xyz>
Wed, 11 May 2022 20:14:55 +0000 (23:14 +0300)
committerEgor <egor@patchysicp.xyz>
Wed, 11 May 2022 20:14:55 +0000 (23:14 +0300)
.gitignore
irc.c
ircfmt.c
ircfmt.h
passwd.c
passwd.h

index d6975e7..12e498f 100644 (file)
@@ -7,3 +7,5 @@ init.txt
 chanlog.txt
 cert.pem
 key.pem
+users.txt
+newusers.txt
diff --git a/irc.c b/irc.c
index 78bcaff..c400507 100644 (file)
--- a/irc.c
+++ b/irc.c
@@ -238,6 +238,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                client->username = malloc(strlen(args[0])+2);
                if (!client->username)
                        abort();
+               client->umode &= ~UMODE_REGISTERED;
                client->username[0] = '~';
                strcpy(client->username + 1, args[0]);
                // set realname
@@ -250,6 +251,23 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        abort();
                // Send welcome
                newUser(client);
+       } else if(strcmp(command, "PASS") == 0) {
+               if (is_registered(client))
+                       return err_alreadyregistered(client), sendbuf(client), 0;
+               if (client->umode & UMODE_REGISTERED)
+                       return 0; // FIXME: error message
+               if (argc < 1)
+                       return err_needmoreparams(client, command), sendbuf(client), 0;
+               if (!(client->umode & UMODE_SECURE)) {
+                       memset(args[0], 0, strlen(args[0]));
+                       return err_passwdmismatch(client), sendbuf(client), 0;
+               }
+               if (client->pass_reg) {
+                       memset(client->pass_reg, 0, strlen(client->pass_reg));
+                       free(client->pass_reg);
+               }
+               client->pass_reg = mystrdup(args[0]);
+               if (!client->pass_reg) abort();
        } else if(strcmp(command, "OPER") == 0) {
                if (!is_registered(client))
                        return err_notregistered(client), sendbuf(client), 0;
@@ -258,9 +276,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                stringlower(args[0]);
                int res = password_check(args[0], args[1], "ops.txt");
                memset(args[1], 0, strlen(args[1]));
-               if (res == -1) {
-                       copy_strf(&databuf, ":%s 464 %s :Password incorrect\r\n", hostname, client->nick);
-                       sendbuf(client);
+               if (!(client->umode & UMODE_SECURE) || res == -1) {
+                       err_passwdmismatch(client), sendbuf(client);
                } else {
                        client->umode |= UMODE_OPER;
                        copy_strf(&databuf, ":%s 381 %s :You are now an IRC operator\r\n", hostname, client->nick);
@@ -268,6 +285,24 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        copy_strf(&databuf, ":%s MODE %s +o\r\n", hostname, client->nick);
                        sendbuf(client);
                }
+       } else if(strcmp(command, "NEWACC") == 0) {
+               if (!is_registered(client))
+                       return err_notregistered(client), sendbuf(client), 0;
+               if (argc < 2)
+                       return err_needmoreparams(client, command), sendbuf(client), 0;
+               stringlower(args[0]);
+               const char *hash = password_hash(args[1]);
+               if (!hash)
+                       return 0; // TODO: error message
+               memset(args[1], 0, strlen(args[1]));
+               FILE *f = fopen("newusers.txt", "ab");
+               if (!f)
+                       return 0; // TODO: error message
+               fprintf(f, "%s:%s\n", args[0], hash);
+               fclose(f);
+               msg_notice_server(hostname, client->nick,
+                               "Your information has been recorded. Contact IRCops for assistance with registration.");
+               sendbuf(client);
        } else if(strcmp(command, "JEDGAR") == 0) {
                if (!is_registered(client))
                        return err_notregistered(client), sendbuf(client), 0;
@@ -905,6 +940,18 @@ unknown:
 void newUser(struct client_data *client) {
        if (client->regstate == REG_CAPLS || !client->nick_reg || !client->username)
                return;
+       if (client->username[0] == '~' && client->pass_reg) {
+               int res = password_check(client->username + 1, client->pass_reg, "users.txt");
+               memset(client->pass_reg, 0, strlen(client->pass_reg));
+               free(client->pass_reg);
+               client->pass_reg = NULL;
+               if (res == -1) {
+                       return err_passwdmismatch(client), sendbuf(client);
+               } else {
+                       client->umode |= UMODE_REGISTERED;
+                       memmove(client->username, client->username+1, strlen(client->username));
+               }
+       }
        setNick(client, client->nick_reg);
        free(client->nick_reg);
        client->nick_reg = NULL;
index 509aa98..3b7e76b 100644 (file)
--- a/ircfmt.c
+++ b/ircfmt.c
@@ -74,6 +74,11 @@ void msg_notice(struct client_data *src, const char *dst, const char *msg)
        copy_strf(&databuf, ":%s!%s@%s NOTICE %s :%s\r\n",
                        src->nick, src->username, src->hostname, dst, msg);
 }
+void msg_notice_server(const char *src, const char *dst, const char *msg)
+{
+       copy_strf(&databuf, ":%s NOTICE %s :%s\r\n",
+                       src, dst, msg);
+}
 #if 0
 void msg_kill(struct client_data *src, struct client_data *dst, const char *reason)
 {
@@ -374,11 +379,11 @@ void err_alreadyregistered(struct client_data *client) // 462
 {
        copy_strf(&databuf, ":%s 462 %s :You may not reregister\r\n", hostname, client->nick ? client->nick : "*");
 }
-#if 0
 void err_passwdmismatch(struct client_data *client) // 464
 {
        copy_strf(&databuf, ":%s 464 %s :Password incorrect\r\n", hostname, client->nick ? client->nick : "*");
 }
+#if 0
 void err_yourebannedcreep(struct client_data *client) // 465
 {
        copy_strf(&databuf, ":%s 465 %s :You are banned from this server.\r\n", hostname, client->nick ? client->nick : "*");
index 10de3df..9ea934f 100644 (file)
--- a/ircfmt.h
+++ b/ircfmt.h
@@ -13,6 +13,7 @@ void msg_invite(struct client_data *src, struct client_data *dst, struct channel
 void msg_kick(struct client_data *src, struct client_data *who, struct channel *chan, const char *reason);
 void msg_privmsg(struct client_data *src, const char *dst, const char *msg);
 void msg_notice(struct client_data *src, const char *dst, const char *msg);
+void msg_notice_server(const char *src, const char *dst, const char *msg);
 void msg_kill(struct client_data *src, struct client_data *dst, const char *reason);
 void msg_wallops(struct client_data *src, const char *msg);
 void rpl_welcome(struct client_data *client); // 001
index 26e4b19..e0d1c62 100644 (file)
--- a/passwd.c
+++ b/passwd.c
@@ -1,4 +1,9 @@
 #ifdef _WIN32
+const char *password_hash(const char *pw)
+{
+       (void)pw;
+       return 0;
+}
 int password_set(const char *key, const char *pw, const char *fn, const char *tmpfn)
 {
        (void)key;
@@ -19,26 +24,30 @@ int password_check(const char *key, const char *pw, const char *fn)
 #include <string.h>
 #include <unistd.h>
 #include <crypt.h>
+const char *password_hash(const char *pw)
+{
+       char salt[20];
+       char ubytes[16];
+       if (getentropy(ubytes, 16) == -1)
+               return NULL;
+       salt[0] = '$';
+       salt[1] = '6';
+       salt[2] = '$';
+       for (int i = 0; i < 16; i++)
+               salt[3+i] =
+                       "./0123456789ABCDEFGHIJKLMNOPQRST"
+                       "UVWXYZabcdefghijklmnopqrstuvwxyz"[ubytes[i]&63];
+       salt[19] = '\0';
+       const char *hash = crypt(pw, salt);
+       if (!hash || *hash == '*')
+               return NULL;
+       return hash;
+}
 int password_set(const char *key, const char *pw, const char *fn, const char *tmpfn)
 {
-       const char *hash;
-       {
-               char salt[20];
-               char ubytes[16];
-               if (getentropy(ubytes, 16) == -1)
-                       return -1;
-               salt[0] = '$';
-               salt[1] = '6';
-               salt[2] = '$';
-               for (int i = 0; i < 16; i++)
-                       salt[3+i] =
-                               "./0123456789ABCDEFGHIJKLMNOPQRST"
-                               "UVWXYZabcdefghijklmnopqrstuvwxyz"[ubytes[i]&63];
-               salt[19] = '\0';
-               hash = crypt(pw, salt);
-               if (!hash || *hash == '*')
-                       return -1;
-       }
+       const char *hash = password_hash(pw);
+       if (!hash)
+               return -1;
 
        FILE *fi = fopen(fn, "rb");
        if (!fi)
index 564de7f..d33f5aa 100644 (file)
--- a/passwd.h
+++ b/passwd.h
@@ -1,5 +1,6 @@
 #ifndef PASSWD_H_
 #define PASSWD_H_
+const char *password_hash(const char *pw);
 int password_set(const char *key, const char *pw, const char *fn, const char *tmpfn);
 int password_check(const char *key, const char *pw, const char *fn);
 #endif