Changeset 58b63de6
- Timestamp:
- 2015-10-08T08:34:18Z (9 years ago)
- Branches:
- master
- Children:
- c788e15
- Parents:
- 2f73692
- git-author:
- dequis <dx@…> (11-09-15 22:07:10)
- git-committer:
- dequis <dx@…> (08-10-15 08:34:18)
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
irc.h
r2f73692 r58b63de6 50 50 Currently just blocks irc_vawrite(). */ 51 51 USTATUS_CAP_PENDING = 16, 52 USTATUS_SASL_PLAIN_PENDING = 32, 52 53 53 54 /* Not really status stuff, but other kinds of flags: For slightly … … 67 68 68 69 typedef enum { 70 CAP_SASL = (1 << 0), 69 71 CAP_MULTI_PREFIX = (1 << 1), 70 72 } irc_cap_flag_t; -
irc_cap.c
r2f73692 r58b63de6 38 38 39 39 static const cap_info_t supported_caps[] = { 40 {"sasl", CAP_SASL}, 40 41 {"multi-prefix", CAP_MULTI_PREFIX}, 41 42 {NULL}, … … 170 171 } else if (g_strcasecmp(cmd[1], "END") == 0) { 171 172 irc->status &= ~USTATUS_CAP_PENDING; 173 174 if (irc->status & USTATUS_SASL_PLAIN_PENDING) { 175 irc_send_num(irc, 906, ":SASL authentication aborted"); 176 irc->status &= ~USTATUS_SASL_PLAIN_PENDING; 177 } 178 172 179 irc_check_login(irc); 173 180 -
irc_commands.c
r2f73692 r58b63de6 28 28 #include "help.h" 29 29 #include "ipc.h" 30 #include "base64.h" 30 31 31 32 static void irc_cmd_pass(irc_t *irc, char **cmd) … … 55 56 irc_setpass(irc, cmd[1]); 56 57 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[2]; 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) || strcmp(parts[0], parts[1]) != 0) { 83 g_free(decoded); 84 return FALSE; 85 } else { 86 *user = g_strdup(parts[0]); 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 numerics 98 * 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 case 139 * 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; 57 172 } 58 173 } … … 83 198 irc->status &= ~USTATUS_IDENTIFIED; 84 199 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 85 206 irc_rootmsg(irc, "Changing nicks resets your identify status. " 86 207 "Re-identify or register a new account if you want " … … 722 843 { "restart", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 723 844 { "kill", 2, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 845 { "authenticate", 1, irc_cmd_authenticate, 0 }, 724 846 { NULL } 725 847 }; -
root_commands.c
r2f73692 r58b63de6 163 163 irc_umode_set(irc, "+R", 1); 164 164 165 if (irc->caps & CAP_SASL) { 166 irc_user_t *iu = irc->user; 167 irc_send_num(irc, 900, "%s!%s@%s %s :You are now logged in as %s", 168 iu->nick, iu->user, iu->host, iu->nick, iu->nick); 169 } 170 165 171 bitlbee_whatsnew(irc); 166 172 … … 238 244 irc->status |= USTATUS_IDENTIFIED; 239 245 irc_umode_set(irc, "+R", 1); 246 247 if (irc->caps & CAP_SASL) { 248 irc_user_t *iu = irc->user; 249 irc_send_num(irc, 900, "%s!%s@%s %s :You are now logged in as %s", 250 iu->nick, iu->user, iu->host, iu->nick, iu->nick); 251 } 240 252 241 253 /* Set this var now, or anyone who logs in to his/her
Note: See TracChangeset
for help on using the changeset viewer.