From: Egor Date: Wed, 11 May 2022 20:14:55 +0000 (+0300) Subject: add basic account system X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=3e7d28e2b6d46804f6e684296b01aae5ae882b2f;p=patchyircd.git add basic account system --- diff --git a/.gitignore b/.gitignore index d6975e7..12e498f 100644 --- a/.gitignore +++ b/.gitignore @@ -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 --- 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; diff --git a/ircfmt.c b/ircfmt.c index 509aa98..3b7e76b 100644 --- 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 : "*"); diff --git a/ircfmt.h b/ircfmt.h index 10de3df..9ea934f 100644 --- 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 diff --git a/passwd.c b/passwd.c index 26e4b19..e0d1c62 100644 --- 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 #include #include +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) diff --git a/passwd.h b/passwd.h index 564de7f..d33f5aa 100644 --- 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