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);