Mercurial > pidgin.yaz
comparison libfaim/aim_login.c @ 331:f3c8d79688db
[gaim-migrate @ 341]
GAIM DOES ICQ!!!! CATCHING UP TO EVERYBUDDY! :)
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Sat, 03 Jun 2000 07:25:42 +0000 |
parents | 0f14e6d8a51b |
children | ad08e67ec874 |
comparison
equal
deleted
inserted
replaced
330:02da800b7805 | 331:f3c8d79688db |
---|---|
78 struct aim_conn_t *conn, | 78 struct aim_conn_t *conn, |
79 char *sn, char *password, struct client_info_s *clientinfo) | 79 char *sn, char *password, struct client_info_s *clientinfo) |
80 { | 80 { |
81 u_char *password_encoded = NULL; /* to store encoded password */ | 81 u_char *password_encoded = NULL; /* to store encoded password */ |
82 int curbyte=0; | 82 int curbyte=0; |
83 | 83 int icqmode = 0; |
84 | |
84 struct command_tx_struct *newpacket; | 85 struct command_tx_struct *newpacket; |
85 | 86 |
86 if (!clientinfo || !sn || !password) | 87 if (!clientinfo || !sn || !password) |
87 return -1; | 88 return -1; |
88 | 89 |
89 if (!(newpacket = aim_tx_new(0x0002, conn, 1152))) | 90 if (!(newpacket = aim_tx_new(0x0002, conn, 1152))) |
90 return -1; | 91 return -1; |
92 | |
93 /* | |
94 * For ICQ logins, the client version must be at | |
95 * least as high as ICQ2000a. | |
96 */ | |
97 if ((sn[0] >= '0') && (sn[0] <= '9')) { | |
98 icqmode = 1; /* needs a different password encoding */ | |
99 if (clientinfo && (clientinfo->major < 4)) { | |
100 printf("faim: icq: version must be at least 4.30.3141 for ICQ OSCAR login\n"); | |
101 return -1; | |
102 } | |
103 if (strlen(password) > 8) { | |
104 printf("faim: icq: password too long (8 char max)\n"); | |
105 return -1; | |
106 } | |
107 } | |
91 | 108 |
92 #ifdef SNACLOGIN | 109 #ifdef SNACLOGIN |
93 newpacket->commandlen = 10; | 110 newpacket->commandlen = 10; |
94 newpacket->commandlen += 2 + 2 + strlen(sn); | 111 newpacket->commandlen += 2 + 2 + strlen(sn); |
95 newpacket->commandlen += 2 + 2 + strlen(password); | 112 newpacket->commandlen += 2 + 2 + strlen(password); |
116 curbyte+= aim_puttlv_str(newpacket->data+curbyte, 0x0001, 0x0002, clientinfo->lang); | 133 curbyte+= aim_puttlv_str(newpacket->data+curbyte, 0x0001, 0x0002, clientinfo->lang); |
117 curbyte+= aim_puttlv_32(newpacket->data+curbyte, 0x0014, 0x0000002a); | 134 curbyte+= aim_puttlv_32(newpacket->data+curbyte, 0x0014, 0x0000002a); |
118 curbyte+= aim_puttlv_16(newpacket->data+curbyte, 0x0009, 0x0015); | 135 curbyte+= aim_puttlv_16(newpacket->data+curbyte, 0x0009, 0x0015); |
119 #else | 136 #else |
120 | 137 |
121 newpacket->commandlen = 4 + 4+strlen(sn) + 4+strlen(password) + 6; | 138 newpacket->commandlen = 4 + 4 + strlen(sn) + 4+strlen(password) + 6; |
122 | 139 |
140 newpacket->commandlen += 8; /* tlv 0x0014 */ | |
141 | |
123 if (clientinfo) { | 142 if (clientinfo) { |
124 if (strlen(clientinfo->clientstring)) | 143 if (strlen(clientinfo->clientstring)) |
125 newpacket->commandlen += 4+strlen(clientinfo->clientstring); | 144 newpacket->commandlen += 4+strlen(clientinfo->clientstring); |
126 newpacket->commandlen += 6+6+6+6; | 145 newpacket->commandlen += 6+6+6+6; |
127 if (strlen(clientinfo->country)) | 146 if (strlen(clientinfo->country)) |
128 newpacket->commandlen += 4+strlen(clientinfo->country); | 147 newpacket->commandlen += 4+strlen(clientinfo->country); |
129 if (strlen(clientinfo->lang)) | 148 if (strlen(clientinfo->lang)) |
130 newpacket->commandlen += 4+strlen(clientinfo->lang); | 149 newpacket->commandlen += 4+strlen(clientinfo->lang); |
131 } | 150 } |
132 newpacket->commandlen += 6; | |
133 | 151 |
134 newpacket->lock = 1; | 152 newpacket->lock = 1; |
135 newpacket->type = 0x01; | 153 newpacket->type = 0x01; |
136 | 154 |
137 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); | 155 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); |
141 curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn)); | 159 curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn)); |
142 | 160 |
143 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); | 161 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); |
144 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(password)); | 162 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(password)); |
145 password_encoded = (char *) malloc(strlen(password)); | 163 password_encoded = (char *) malloc(strlen(password)); |
146 aim_encode_password(password, password_encoded); | 164 if (icqmode) |
165 aimicq_encode_password(password, password_encoded); | |
166 else | |
167 aim_encode_password(password, password_encoded); | |
147 curbyte += aimutil_putstr(newpacket->data+curbyte, password_encoded, strlen(password)); | 168 curbyte += aimutil_putstr(newpacket->data+curbyte, password_encoded, strlen(password)); |
148 free(password_encoded); | 169 free(password_encoded); |
149 | 170 |
150 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0016, 0x0004); | 171 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0016, 0x010a /*0x0004*/); |
151 | 172 |
152 if (clientinfo) { | 173 if (strlen(clientinfo->clientstring)) { |
153 if (strlen(clientinfo->clientstring)) { | 174 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); |
154 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); | 175 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->clientstring)); |
155 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->clientstring)); | 176 curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->clientstring, strlen(clientinfo->clientstring)); |
156 curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->clientstring, strlen(clientinfo->clientstring)); | 177 } |
157 } | 178 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0017, clientinfo->major /*0x0001*/); |
158 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0017, clientinfo->major /*0x0001*/); | 179 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0018, clientinfo->minor /*0x0001*/); |
159 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0018, clientinfo->minor /*0x0001*/); | 180 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0019, 0x0001); |
160 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0019, 0x0000); | 181 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x001a, clientinfo->build /*0x0013*/); |
161 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x001a, clientinfo->build /*0x0013*/); | 182 |
162 if (strlen(clientinfo->country)) { | 183 curbyte += aim_puttlv_32(newpacket->data+curbyte, 0x0014, 0x00000055); |
163 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000e); | 184 |
164 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->country)); | 185 if (strlen(clientinfo->country)) { |
165 curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->country, strlen(clientinfo->country)); | 186 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000e); |
166 } | 187 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->country)); |
167 if (strlen(clientinfo->lang)) { | 188 curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->country, strlen(clientinfo->country)); |
168 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f); | 189 } |
169 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->lang)); | 190 if (strlen(clientinfo->lang)) { |
170 curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->lang, strlen(clientinfo->lang)); | 191 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f); |
171 } | 192 curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->lang)); |
172 } | 193 curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->lang, strlen(clientinfo->lang)); |
173 | 194 } |
174 curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0009, 0x0015); | 195 |
175 #endif | 196 #endif |
176 | 197 |
177 newpacket->lock = 0; | 198 newpacket->lock = 0; |
178 return aim_tx_enqueue(sess, newpacket); | 199 return aim_tx_enqueue(sess, newpacket); |
179 } | 200 } |
203 0x69, 0x6c, 0xc3, 0x9f | 224 0x69, 0x6c, 0xc3, 0x9f |
204 }; | 225 }; |
205 | 226 |
206 int i; | 227 int i; |
207 | 228 |
229 for (i = 0; i < strlen(password); i++) | |
230 encoded[i] = (password[i] ^ encoding_table[i]); | |
231 | |
232 return 0; | |
233 } | |
234 | |
235 /* | |
236 * They changed the hash slightly for ICQ. | |
237 * This new hash may work for AIM too (though | |
238 * the max password length for ICQ is only | |
239 * eight characters, where its 16 with AIM). | |
240 * | |
241 */ | |
242 int aimicq_encode_password(const char *password, u_char *encoded) | |
243 { | |
244 u_char encoding_table[] = { | |
245 0xf3, 0x26, 0x81, 0xc4, | |
246 0x39, 0x86, 0xdb, 0x92 | |
247 }; | |
248 | |
249 int i; | |
250 | |
251 if (strlen(password) > 8) | |
252 return -1; | |
253 | |
208 for (i = 0; i < strlen(password); i++) | 254 for (i = 0; i < strlen(password); i++) |
209 encoded[i] = (password[i] ^ encoding_table[i]); | 255 encoded[i] = (password[i] ^ encoding_table[i]); |
210 | 256 |
211 return 0; | 257 return 0; |
212 } | 258 } |
248 | 294 |
249 /* | 295 /* |
250 * Check for an error code. If so, we should also | 296 * Check for an error code. If so, we should also |
251 * have an error url. | 297 * have an error url. |
252 */ | 298 */ |
253 if (aim_gettlv(tlvlist, 0x0008, 1)) | 299 if (aim_gettlv(tlvlist, 0x0008, 1)) { |
254 { | 300 struct aim_tlv_t *errtlv; |
255 struct aim_tlv_t *errtlv; | 301 errtlv = aim_gettlv(tlvlist, 0x0008, 1); |
256 errtlv = aim_gettlv(tlvlist, 0x0008, 1); | 302 sess->logininfo.errorcode = aimutil_get16(errtlv->value); |
257 sess->logininfo.errorcode = aimutil_get16(errtlv->value); | 303 sess->logininfo.errorurl = aim_gettlv_str(tlvlist, 0x0004, 1); |
258 sess->logininfo.errorurl = aim_gettlv_str(tlvlist, 0x0004, 1); | 304 } |
259 } | |
260 /* | 305 /* |
261 * If we have both an IP number (0x0005) and a cookie (0x0006), | 306 * If we have both an IP number (0x0005) and a cookie (0x0006), |
262 * then the login was successful. | 307 * then the login was successful. |
263 */ | 308 */ |
264 else if (aim_gettlv(tlvlist, 0x0005, 1) && aim_gettlv(tlvlist, 0x0006, 1)) | 309 else if (aim_gettlv(tlvlist, 0x0005, 1) && aim_gettlv(tlvlist, 0x0006, 1)) { |
265 { | 310 struct aim_tlv_t *tmptlv; |
266 struct aim_tlv_t *tmptlv; | 311 |
267 | 312 /* |
268 /* | 313 * IP address of BOS server. |
269 * IP address of BOS server. | 314 */ |
270 */ | 315 sess->logininfo.BOSIP = aim_gettlv_str(tlvlist, 0x0005, 1); |
271 sess->logininfo.BOSIP = aim_gettlv_str(tlvlist, 0x0005, 1); | 316 |
272 | 317 /* |
273 /* | 318 * Authorization Cookie |
274 * Authorization Cookie | 319 */ |
275 */ | 320 tmptlv = aim_gettlv(tlvlist, 0x0006, 1); |
276 tmptlv = aim_gettlv(tlvlist, 0x0006, 1); | 321 memcpy(sess->logininfo.cookie, tmptlv->value, AIM_COOKIELEN); |
277 memcpy(sess->logininfo.cookie, tmptlv->value, AIM_COOKIELEN); | 322 |
278 | 323 /* |
279 /* | 324 * The email address attached to this account |
280 * The email address attached to this account | 325 * Not available for ICQ logins. |
281 */ | 326 */ |
327 if (aim_gettlv(tlvlist, 0x0011, 1)) | |
282 sess->logininfo.email = aim_gettlv_str(tlvlist, 0x0011, 1); | 328 sess->logininfo.email = aim_gettlv_str(tlvlist, 0x0011, 1); |
283 | 329 |
284 /* | 330 /* |
285 * The registration status. (Not real sure what it means.) | 331 * The registration status. (Not real sure what it means.) |
286 */ | 332 * Not available for ICQ logins. |
287 tmptlv = aim_gettlv(tlvlist, 0x0013, 1); | 333 */ |
334 if ((tmptlv = aim_gettlv(tlvlist, 0x0013, 1))) | |
288 sess->logininfo.regstatus = aimutil_get16(tmptlv->value); | 335 sess->logininfo.regstatus = aimutil_get16(tmptlv->value); |
289 | 336 |
290 } | 337 } |
291 | 338 |
292 #ifdef SNACLOGIN | 339 #ifdef SNACLOGIN |
293 userfunc = aim_callhandler(command->conn, 0x0017, 0x0003); | 340 userfunc = aim_callhandler(command->conn, 0x0017, 0x0003); |
294 #else | 341 #else |
295 userfunc = aim_callhandler(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS); | 342 userfunc = aim_callhandler(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS); |