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
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;
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);
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;
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;
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)
{
{
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 : "*");
#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;
#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)