struct command_tx_struct *newpacket;
- if (!(newpacket = aim_tx_new(0x0001, conn, 4)))
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0001, conn, 4)))
return -1;
newpacket->lock = 1;
struct command_tx_struct *newpacket;
- if (!(newpacket = aim_tx_new(0x0002, conn, 10+2+2+strlen(sn))))
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+2+2+strlen(sn))))
return -1;
newpacket->lock = 1;
{
u_char *password_encoded = NULL; /* to store encoded password */
int curbyte=0;
-
+ int icqmode = 0;
+
struct command_tx_struct *newpacket;
if (!clientinfo || !sn || !password)
return -1;
- if (!(newpacket = aim_tx_new(0x0002, conn, 1152)))
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152)))
return -1;
+ /*
+ * For ICQ logins, the client version must be at
+ * least as high as ICQ2000a.
+ */
+ if ((sn[0] >= '0') && (sn[0] <= '9')) {
+ icqmode = 1; /* needs a different password encoding */
+ if (clientinfo && (clientinfo->major < 4)) {
+ printf("faim: icq: version must be at least 4.30.3141 for ICQ OSCAR login\n");
+ }
+ if (strlen(password) > 8) {
+ printf("faim: icq: password too long (8 char max)\n");
+ }
+ }
+
#ifdef SNACLOGIN
newpacket->commandlen = 10;
newpacket->commandlen += 2 + 2 + strlen(sn);
curbyte+= aim_puttlv_16(newpacket->data+curbyte, 0x0009, 0x0015);
#else
- newpacket->commandlen = 4 + 4+strlen(sn) + 4+strlen(password) + 6;
-
- if (clientinfo) {
- if (strlen(clientinfo->clientstring))
- newpacket->commandlen += 4+strlen(clientinfo->clientstring);
- newpacket->commandlen += 6+6+6+6;
- if (strlen(clientinfo->country))
- newpacket->commandlen += 4+strlen(clientinfo->country);
- if (strlen(clientinfo->lang))
- newpacket->commandlen += 4+strlen(clientinfo->lang);
- }
- newpacket->commandlen += 6;
-
newpacket->lock = 1;
- newpacket->type = 0x01;
+ newpacket->hdr.oscar.type = 0x01;
+ /*
+ * These four bytes are actually the FLAP version information.
+ * They're sent here for convenience. I suppose they could
+ * be seperated out into a seperate FLAP, but this is where
+ * everyone else sends them.
+ */
curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000);
curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
- curbyte += aimutil_put16(newpacket->data+curbyte, strlen(sn));
- curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn));
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002);
- curbyte += aimutil_put16(newpacket->data+curbyte, strlen(password));
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x0001, strlen(sn), sn);
+
password_encoded = (char *) malloc(strlen(password));
aim_encode_password(password, password_encoded);
- curbyte += aimutil_putstr(newpacket->data+curbyte, password_encoded, strlen(password));
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x0002, strlen(password), password_encoded);
free(password_encoded);
- curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0016, 0x0004);
-
- if (clientinfo) {
- if (strlen(clientinfo->clientstring)) {
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003);
- curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->clientstring));
- curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->clientstring, strlen(clientinfo->clientstring));
- }
- curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0017, clientinfo->major /*0x0001*/);
- curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0018, clientinfo->minor /*0x0001*/);
- curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0019, 0x0000);
- curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x001a, clientinfo->build /*0x0013*/);
- if (strlen(clientinfo->country)) {
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x000e);
- curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->country));
- curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->country, strlen(clientinfo->country));
- }
- if (strlen(clientinfo->lang)) {
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f);
- curbyte += aimutil_put16(newpacket->data+curbyte, strlen(clientinfo->lang));
- curbyte += aimutil_putstr(newpacket->data+curbyte, clientinfo->lang, strlen(clientinfo->lang));
- }
- }
+ /* XXX is clientstring required by oscar? */
+ if (strlen(clientinfo->clientstring))
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x0003, strlen(clientinfo->clientstring), clientinfo->clientstring);
+
+ curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0016, clientinfo->major2);
+ curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0017, clientinfo->major);
+ curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0018, clientinfo->minor);
+ curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0019, clientinfo->minor2);
+ curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x001a, clientinfo->build);
+
+ curbyte += aim_puttlv_32(newpacket->data+curbyte, 0x0014, clientinfo->unknown);
- curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0009, 0x0015);
+ if (strlen(clientinfo->country))
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x000e, strlen(clientinfo->country), clientinfo->country);
+ else
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x000e, 2, "us");
+
+ if (strlen(clientinfo->lang))
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x000f, strlen(clientinfo->lang), clientinfo->lang);
+ else
+ curbyte += aim_puttlv_str(newpacket->data+curbyte, 0x000f, 2, "en");
+
+ newpacket->commandlen = curbyte;
#endif
newpacket->lock = 0;
int aim_encode_password(const char *password, u_char *encoded)
{
u_char encoding_table[] = {
+#if 0 /* old v1 table */
0xf3, 0xb3, 0x6c, 0x99,
0x95, 0x3f, 0xac, 0xb6,
0xc5, 0xfa, 0x6b, 0x63,
0x69, 0x6c, 0xc3, 0x9f
+#else /* v2.1 table, also works for ICQ */
+ 0xf3, 0x26, 0x81, 0xc4,
+ 0x39, 0x86, 0xdb, 0x92,
+ 0x71, 0xa3, 0xb9, 0xe6,
+ 0x53, 0x7a, 0x95, 0x7c
+#endif
};
int i;
* Check for an error code. If so, we should also
* have an error url.
*/
- if (aim_gettlv(tlvlist, 0x0008, 1))
- {
- struct aim_tlv_t *errtlv;
- errtlv = aim_gettlv(tlvlist, 0x0008, 1);
- sess->logininfo.errorcode = aimutil_get16(errtlv->value);
- sess->logininfo.errorurl = aim_gettlv_str(tlvlist, 0x0004, 1);
- }
+ if (aim_gettlv(tlvlist, 0x0008, 1)) {
+ struct aim_tlv_t *errtlv;
+ errtlv = aim_gettlv(tlvlist, 0x0008, 1);
+ sess->logininfo.errorcode = aimutil_get16(errtlv->value);
+ sess->logininfo.errorurl = aim_gettlv_str(tlvlist, 0x0004, 1);
+ }
/*
* If we have both an IP number (0x0005) and a cookie (0x0006),
* then the login was successful.
*/
- else if (aim_gettlv(tlvlist, 0x0005, 1) && aim_gettlv(tlvlist, 0x0006, 1))
- {
- struct aim_tlv_t *tmptlv;
-
- /*
- * IP address of BOS server.
- */
- sess->logininfo.BOSIP = aim_gettlv_str(tlvlist, 0x0005, 1);
-
- /*
- * Authorization Cookie
- */
- tmptlv = aim_gettlv(tlvlist, 0x0006, 1);
- memcpy(sess->logininfo.cookie, tmptlv->value, AIM_COOKIELEN);
-
- /*
- * The email address attached to this account
- */
+ else if (aim_gettlv(tlvlist, 0x0005, 1) && aim_gettlv(tlvlist, 0x0006, 1)
+ /*aim_gettlv(tlvlist, 0x0006, 1)->length*/) {
+ struct aim_tlv_t *tmptlv;
+
+ /*
+ * IP address of BOS server.
+ */
+ sess->logininfo.BOSIP = aim_gettlv_str(tlvlist, 0x0005, 1);
+
+ /*
+ * Authorization Cookie
+ */
+ tmptlv = aim_gettlv(tlvlist, 0x0006, 1);
+ memcpy(sess->logininfo.cookie, tmptlv->value, AIM_COOKIELEN);
+
+ /*
+ * The email address attached to this account
+ * Not available for ICQ logins.
+ */
+ if (aim_gettlv(tlvlist, 0x0011, 1))
sess->logininfo.email = aim_gettlv_str(tlvlist, 0x0011, 1);
-
- /*
- * The registration status. (Not real sure what it means.)
- */
- tmptlv = aim_gettlv(tlvlist, 0x0013, 1);
+
+ /*
+ * The registration status. (Not real sure what it means.)
+ * Not available for ICQ logins.
+ */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0013, 1)))
sess->logininfo.regstatus = aimutil_get16(tmptlv->value);
- }
+ }
#ifdef SNACLOGIN
userfunc = aim_callhandler(command->conn, 0x0017, 0x0003);
struct command_tx_struct *tx;
struct aim_tlvlist_t *tlvlist = NULL;
- if (!(tx = aim_tx_new(0x0001 /*right??*/, conn, 1152)))
+ if (!(tx = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0004, conn, 1152)))
return -1;
tx->lock = 1;
struct command_tx_struct *tx;
int i = 0;
- if (!(tx = aim_tx_new(0x0002, conn, 10+0x20)))
+ if (!(tx = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+0x22)))
return -1;
tx->lock = 1;
- i += aimutil_put16(tx->data+i, 0x0001);
- i += aimutil_put16(tx->data+i, 0x0003);
- i += aimutil_put16(tx->data+i, 0x0000);
- i += aimutil_put16(tx->data+i, 0x0000);
- i += aimutil_put16(tx->data+i, 0x0000);
+ i += aim_putsnac(tx->data, 0x0001, 0x0003, 0x0000, sess->snac_nextid++);
i += aimutil_put16(tx->data+i, 0x0001);
i += aimutil_put16(tx->data+i, 0x0002);
i += aimutil_put16(tx->data+i, 0x000a);
i += aimutil_put16(tx->data+i, 0x000b);
i += aimutil_put16(tx->data+i, 0x000c);
+ i += aimutil_put16(tx->data+i, 0x0013);
+ i += aimutil_put16(tx->data+i, 0x0015);
+ tx->commandlen = i;
tx->lock = 0;
-
return aim_tx_enqueue(sess, tx);
}
struct aim_tlvlist_t *tlvlist = NULL;
int i = 0;
- if (!(tx = aim_tx_new(0x0002, conn, 1152)))
+ if (!(tx = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152)))
return -1;
tx->lock = 1;
- i += aimutil_put16(tx->data+i, 0x0001);
- i += aimutil_put16(tx->data+i, 0x0005);
- i += aimutil_put16(tx->data+i, 0x0000);
- i += aimutil_put16(tx->data+i, 0x0000);
- i += aimutil_put16(tx->data+i, 0x0000);
+ i += aim_putsnac(tx->data+i, 0x0001, 0x0005, 0x0000, 0x00000000);
aim_addtlvtochain16(&tlvlist, 0x000d, servid);
aim_addtlvtochain_str(&tlvlist, 0x0005, ip, strlen(ip));