Changes in irc_commands.c [c4e61db:9076a1c]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
irc_commands.c
rc4e61db r9076a1c 28 28 #include "help.h" 29 29 #include "ipc.h" 30 #include "base64.h"31 30 32 31 static void irc_cmd_pass(irc_t *irc, char **cmd) … … 56 55 irc_setpass(irc, cmd[1]); 57 56 irc_check_login(irc); 58 }59 }60 61 static gboolean irc_sasl_plain_parse(char *input, char **user, char **pass)62 {63 int i, part, len;64 guint8 *decoded;65 char *parts[3];66 67 /* bitlbee's base64_decode wrapper adds an extra null terminator at the end */68 len = base64_decode(input, &decoded);69 70 /* this loop splits the decoded string into the parts array, like this:71 "username\0username\0password" -> {"username", "username", "password"} */72 73 for (i = 0, part = 0; i < len && part < 3; part++) {74 /* set each of parts[] to point to the beginning of a string */75 parts[part] = (char *) decoded + i;76 77 /* move the cursor forward to the next null terminator*/78 i += strlen(parts[part]) + 1;79 }80 81 /* sanity checks */82 if (part != 3 || i != (len + 1) || (parts[0][0] && strcmp(parts[0], parts[1]) != 0)) {83 g_free(decoded);84 return FALSE;85 } else {86 *user = g_strdup(parts[1]);87 *pass = g_strdup(parts[2]);88 g_free(decoded);89 return TRUE;90 }91 }92 93 static gboolean irc_sasl_check_pass(irc_t *irc, char *user, char *pass)94 {95 storage_status_t status;96 97 /* just check the password here to be able to reply with useful numerics98 * the actual identification will be handled later */99 status = storage_check_pass(user, pass);100 101 if (status == STORAGE_OK) {102 if (!irc->user->nick) {103 /* set the nick here so we have it for the following numeric */104 irc->user->nick = g_strdup(user);105 }106 irc_send_num(irc, 903, ":Password accepted");107 return TRUE;108 109 } else if (status == STORAGE_INVALID_PASSWORD) {110 irc_send_num(irc, 904, ":Incorrect password");111 } else if (status == STORAGE_NO_SUCH_USER) {112 irc_send_num(irc, 904, ":The nick is (probably) not registered");113 } else {114 irc_send_num(irc, 904, ":Unknown SASL authentication error");115 }116 117 return FALSE;118 }119 120 static void irc_cmd_authenticate(irc_t *irc, char **cmd)121 {122 /* require the CAP to be enabled, and don't allow authentication before server password */123 if (!(irc->caps & CAP_SASL) ||124 (global.conf->authmode == AUTHMODE_CLOSED && !(irc->status & USTATUS_AUTHORIZED))) {125 return;126 }127 128 if (irc->status & USTATUS_SASL_PLAIN_PENDING) {129 char *user, *pass;130 131 irc->status &= ~USTATUS_SASL_PLAIN_PENDING;132 133 if (!irc_sasl_plain_parse(cmd[1], &user, &pass)) {134 irc_send_num(irc, 904, ":SASL authentication failed");135 return;136 }137 138 /* let's not support the nick != user case139 * if NICK is received after SASL, it will just fail after registration */140 if (user && irc->user->nick && strcmp(user, irc->user->nick) != 0) {141 irc_send_num(irc, 902, ":Your SASL username does not match your nickname");142 143 } else if (irc_sasl_check_pass(irc, user, pass)) {144 /* and here we do the same thing as the PASS command*/145 if (irc->status & USTATUS_LOGGED_IN) {146 char *send_cmd[] = { "identify", pass, NULL };147 root_command(irc, send_cmd);148 } else {149 /* no check_login here - wait for CAP END */150 irc_setpass(irc, pass);151 }152 }153 154 g_free(user);155 g_free(pass);156 157 } else if (irc->status & USTATUS_IDENTIFIED) {158 irc_send_num(irc, 907, ":You have already authenticated");159 160 } else if (strcmp(cmd[1], "*") == 0) {161 irc_send_num(irc, 906, ":SASL authentication aborted");162 irc->status &= ~USTATUS_SASL_PLAIN_PENDING;163 164 } else if (g_strcasecmp(cmd[1], "PLAIN") == 0) {165 irc_write(irc, "AUTHENTICATE +");166 irc->status |= USTATUS_SASL_PLAIN_PENDING;167 168 } else {169 irc_send_num(irc, 908, "PLAIN :is the available SASL mechanism");170 irc_send_num(irc, 904, ":SASL authentication failed");171 irc->status &= ~USTATUS_SASL_PLAIN_PENDING;172 57 } 173 58 } … … 198 83 irc->status &= ~USTATUS_IDENTIFIED; 199 84 irc_umode_set(irc, "-R", 1); 200 201 if (irc->caps & CAP_SASL) {202 irc_send_num(irc, 901, "%s!%s@%s :You are now logged out",203 irc->user->nick, irc->user->user, irc->user->host);204 }205 206 85 irc_rootmsg(irc, "Changing nicks resets your identify status. " 207 86 "Re-identify or register a new account if you want " … … 287 166 showed an error message, or is doing some work 288 167 before the join should be confirmed. (In the 289 latter case, the calle rshould take care of that168 latter case, the callee should take care of that 290 169 confirmation.) TRUE means all's good, let the 291 170 user join the channel right away. */ … … 806 685 807 686 static const command_t irc_commands[] = { 808 { "cap", 1, irc_cmd_cap, 0 },809 687 { "pass", 1, irc_cmd_pass, 0 }, 810 688 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, … … 843 721 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 844 722 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 845 { "authenticate", 1, irc_cmd_authenticate, 0 },846 723 { NULL } 847 724 };
Note: See TracChangeset
for help on using the changeset viewer.