No release numbers
------------------
+ - Sun Feb 11 01:07:36 UTC 2001
+ - Make secondary connections to the authorizer work again
+ - Make aim_auth_changepasswd() work again.
+ - Add aim_auth_setversions(), aim_auth_getinfo(), aim_auth_setemail(),
+ aim_auth_reqconfirm()
+ - Add middle handlers for responses to all of above.
+ - Add examples of above to faimtest (start with 'reqauth')
+
- Fri Feb 9 22:31:22 UTC 2001
- Add aim_tx_setenqueue().
faim_export unsigned long aim_auth_clientready(struct aim_session_t *sess,
struct aim_conn_t *conn)
{
+ struct aim_tool_version tools[] = {
+ {0x0001, 0x0003, AIM_TOOL_NEWWIN, 0x0361},
+ {0x0007, 0x0001, AIM_TOOL_NEWWIN, 0x0361},
+ };
+ int i,j;
struct command_tx_struct *newpacket;
- int curbyte = 0;
+ int toolcount = sizeof(tools)/sizeof(struct aim_tool_version);
- if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 26)))
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152)))
return -1;
newpacket->lock = 1;
- curbyte += aim_putsnac(newpacket->data+curbyte, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0013);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0007);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001);
+ i = aim_putsnac(newpacket->data, 0x0001, 0x0002, 0x0000, sess->snac_nextid);
+ aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0);
- aim_tx_enqueue(sess, newpacket);
+ for (j = 0; j < toolcount; j++) {
+ i += aimutil_put16(newpacket->data+i, tools[j].group);
+ i += aimutil_put16(newpacket->data+i, tools[j].version);
+ i += aimutil_put16(newpacket->data+i, tools[j].tool);
+ i += aimutil_put16(newpacket->data+i, tools[j].toolversion);
+ }
- aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, NULL, 0);
+ newpacket->commandlen = i;
+ newpacket->lock = 0;
+
+ aim_tx_enqueue(sess, newpacket);
return sess->snac_nextid;
}
newpacket->lock = 1;
i = aim_putsnac(newpacket->data, 0x0007, 0x0004, 0x0000, sess->snac_nextid);
+ aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
- /* current password TLV t(0002) */
- i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(current), current);
+ /* new password TLV t(0002) */
+ i += aim_puttlv_str(newpacket->data+i, 0x0002, strlen(new), new);
- /* new password TLV t(0012) */
- i += aim_puttlv_str(newpacket->data+i, 0x0012, strlen(new), new);
+ /* current password TLV t(0012) */
+ i += aim_puttlv_str(newpacket->data+i, 0x0012, strlen(current), current);
aim_tx_enqueue(sess, newpacket);
- aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, NULL, 0);
+ return sess->snac_nextid;
+}
+
+faim_export unsigned long aim_auth_setversions(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
+{
+ struct command_tx_struct *newpacket;
+ int i;
+
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + (4*2))))
+ return -1;
+
+ newpacket->lock = 1;
+
+ i = aim_putsnac(newpacket->data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
+ aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0);
+
+ i += aimutil_put16(newpacket->data+i, 0x0001);
+ i += aimutil_put16(newpacket->data+i, 0x0003);
+
+ i += aimutil_put16(newpacket->data+i, 0x0007);
+ i += aimutil_put16(newpacket->data+i, 0x0001);
+
+ newpacket->commandlen = i;
+ newpacket->lock = 0;
+ aim_tx_enqueue(sess, newpacket);
+
+ return sess->snac_nextid;
+}
+
+/*
+ * Request account confirmation.
+ *
+ * This will cause an email to be sent to the address associated with
+ * the account. By following the instructions in the mail, you can
+ * get the TRIAL flag removed from your account.
+ *
+ */
+faim_export unsigned long aim_auth_reqconfirm(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
+{
+ return aim_genericreq_n(sess, conn, 0x0007, 0x0006);
+}
+
+/*
+ * Request a bit of account info.
+ *
+ * The only known valid tag is 0x0011 (email address).
+ *
+ */
+faim_export unsigned long aim_auth_getinfo(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ unsigned short info)
+{
+ struct command_tx_struct *newpacket;
+ int i;
+
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10 + 4)))
+ return -1;
+
+ newpacket->lock = 1;
+
+ i = aim_putsnac(newpacket->data, 0x0007, 0x0002, 0x0000, sess->snac_nextid);
+ aim_cachesnac(sess, 0x0002, 0x0002, 0x0000, NULL, 0);
+
+ i += aimutil_put16(newpacket->data+i, info);
+ i += aimutil_put16(newpacket->data+i, 0x0000);
+
+ newpacket->commandlen = i;
+ newpacket->lock = 0;
+ aim_tx_enqueue(sess, newpacket);
+
+ return sess->snac_nextid;
+}
+
+faim_export unsigned long aim_auth_setemail(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ char *newemail)
+{
+ struct command_tx_struct *newpacket;
+ int i;
+
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+2+2+strlen(newemail))))
+ return -1;
+
+ newpacket->lock = 1;
+
+ i = aim_putsnac(newpacket->data, 0x0007, 0x0004, 0x0000, sess->snac_nextid);
+ aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
+
+ i += aim_puttlv_str(newpacket->data+i, 0x0011, strlen(newemail), newemail);
+
+ aim_tx_enqueue(sess, newpacket);
return sess->snac_nextid;
}
faim_export unsigned long aim_bos_clientready(struct aim_session_t *sess,
struct aim_conn_t *conn)
{
-#define AIM_TOOL_JAVA 0x0001
-#define AIM_TOOL_MAC 0x0002
-#define AIM_TOOL_WIN16 0x0003
-#define AIM_TOOL_WIN32 0x0004
-#define AIM_TOOL_MAC68K 0x0005
-#define AIM_TOOL_MACPPC 0x0006
- struct aim_tool_version {
- unsigned short group;
- unsigned short version;
- unsigned short tool;
- unsigned short toolversion;
- } tools[] = {
+ struct aim_tool_version tools[] = {
{0x0001, 0x0003, AIM_TOOL_WIN32, 0x0686},
{0x0002, 0x0001, AIM_TOOL_WIN32, 0x0001},
{0x0003, 0x0001, AIM_TOOL_WIN32, 0x0001},
else
workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr);
break;
+
case 0x0001:
if (subtype == 0x0003)
workingPtr->handled = aim_parse_hostonline(sess, workingPtr);
+ else if (subtype == 0x0007)
+ workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr);
+ else if (subtype == 0x0018)
+ workingPtr->handled = aim_parse_hostversions(sess, workingPtr);
else
- workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr);
+ workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0xffff, workingPtr);
break;
+
case 0x0007:
- if (subtype == 0x0005)
- workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY, workingPtr);
+ if (subtype == 0x0003)
+ workingPtr->handled = aim_parse_infochange(sess, workingPtr);
+ else if (subtype == 0x0005)
+ workingPtr->handled = aim_parse_infochange(sess, workingPtr);
+ else if (subtype == 0x0007)
+ workingPtr->handled = aim_parse_accountconfirm(sess, workingPtr);
break;
+
case AIM_CB_FAM_SPECIAL:
if (subtype == AIM_CB_SPECIAL_DEBUGCONN_CONNECT) {
workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr);
} else
workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0017, 0xffff, workingPtr);
break;
+
default:
break;
}
} /* switch(family) */
break;
} /* AIM_CONN_TYPE_BOS */
+ case AIM_CONN_TYPE_ADS: {
+ unsigned short family;
+ unsigned short subtype;
+
+ family = aimutil_get16(workingPtr->data);
+ subtype= aimutil_get16(workingPtr->data+2);
+
+ if ((family == 0x0000) && (subtype == 0x00001)) {
+ workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, workingPtr);
+ } else if ((family == 0x0001) && (subtype == 0x0003)) {
+ workingPtr->handled = aim_parse_hostonline(sess, workingPtr);
+ } else {
+ workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr);
+ }
+ break;
+ }
case AIM_CONN_TYPE_CHATNAV: {
u_short family;
u_short subtype;
return ret;
}
+faim_internal int aim_parse_accountconfirm(struct aim_session_t *sess,
+ struct command_rx_struct *command)
+{
+ rxcallback_t userfunc = NULL;
+ int ret = 1;
+ int status = -1;
+
+ status = aimutil_get16(command->data+10);
+
+ if ((userfunc = aim_callhandler(command->conn, 0x0007, 0x0007)))
+ ret = userfunc(sess, command, status);
+
+ return ret;
+}
+
+faim_internal int aim_parse_infochange(struct aim_session_t *sess,
+ struct command_rx_struct *command)
+{
+ unsigned short subtype; /* called for both reply and change-reply */
+ int i;
+
+ subtype = aimutil_get16(command->data+2);
+
+ /*
+ * struct {
+ * unsigned short perms;
+ * unsigned short tlvcount;
+ * aim_tlv_t tlvs[tlvcount];
+ * } admin_info[n];
+ */
+ for (i = 10; i < command->commandlen; ) {
+ int perms, tlvcount;
+
+ perms = aimutil_get16(command->data+i);
+ i += 2;
+
+ tlvcount = aimutil_get16(command->data+i);
+ i += 2;
+
+ while (tlvcount) {
+ rxcallback_t userfunc;
+ struct aim_tlv_t *tlv;
+ int str = 0;
+
+ if ((aimutil_get16(command->data+i) == 0x0011) ||
+ (aimutil_get16(command->data+i) == 0x0004))
+ str = 1;
+
+ if (str)
+ tlv = aim_grabtlvstr(command->data+i);
+ else
+ tlv = aim_grabtlv(command->data+i);
+
+ /* XXX fix so its only called once for the entire packet */
+ if ((userfunc = aim_callhandler(command->conn, 0x0007, subtype)))
+ userfunc(sess, command, perms, tlv->type, tlv->length, tlv->value, str);
+
+ if (tlv)
+ i += 2+2+tlv->length;
+
+ if (tlv && tlv->value)
+ free(tlv->value);
+ if (tlv)
+ free(tlv);
+
+ tlvcount--;
+ }
+ }
+
+ return 1;
+}
+
faim_internal int aim_parse_hostversions(struct aim_session_t *sess,
struct command_rx_struct *command, ...)
{
faim_internal int aim_tx_printqueue(struct aim_session_t *);
faim_internal int aim_parse_hostonline(struct aim_session_t *sess, struct command_rx_struct *command, ...);
faim_internal int aim_parse_hostversions(struct aim_session_t *sess, struct command_rx_struct *command, ...);
+faim_internal int aim_parse_accountconfirm(struct aim_session_t *sess, struct command_rx_struct *command);
+faim_internal int aim_parse_infochange(struct aim_session_t *sess, struct command_rx_struct *command);
#endif /* FAIM_INTERNAL */
#define AIM_TX_QUEUED 0 /* default */
faim_export unsigned long aim_bos_reqicbmparaminfo(struct aim_session_t *, struct aim_conn_t *);
faim_export unsigned long aim_addicbmparam(struct aim_session_t *sess,struct aim_conn_t *conn);
faim_export unsigned long aim_setversions(struct aim_session_t *sess, struct aim_conn_t *conn);
+faim_export unsigned long aim_auth_setversions(struct aim_session_t *sess, struct aim_conn_t *conn);
+faim_export unsigned long aim_auth_reqconfirm(struct aim_session_t *sess, struct aim_conn_t *conn);
+faim_export unsigned long aim_auth_getinfo(struct aim_session_t *sess, struct aim_conn_t *conn, unsigned short info);
+faim_export unsigned long aim_auth_setemail(struct aim_session_t *sess, struct aim_conn_t *conn, char *newemail);
faim_export unsigned long aim_setdirectoryinfo(struct aim_session_t *sess, struct aim_conn_t *conn, char *first, char *middle, char *last, char *maiden, char *nickname, char *street, char *city, char *state, char *zip, int country, unsigned short privacy);
faim_export unsigned long aim_setuserinterests(struct aim_session_t *sess, struct aim_conn_t *conn, char *interest1, char *interest2, char *interest3, char *interest4, char *interest5, unsigned short privacy);
faim_export unsigned long aim_icq_setstatus(struct aim_session_t *sess, struct aim_conn_t *conn, unsigned long status);
faim_internal int aim_parse_unknown(struct aim_session_t *, struct command_rx_struct *, ...);
faim_internal int aim_parse_generalerrs(struct aim_session_t *, struct command_rx_struct *command, ...);
faim_internal int aim_parsemotd_middle(struct aim_session_t *sess, struct command_rx_struct *command, ...);
+
+/* these are used by aim_*_clientready */
+#define AIM_TOOL_JAVA 0x0001
+#define AIM_TOOL_MAC 0x0002
+#define AIM_TOOL_WIN16 0x0003
+#define AIM_TOOL_WIN32 0x0004
+#define AIM_TOOL_MAC68K 0x0005
+#define AIM_TOOL_MACPPC 0x0006
+#define AIM_TOOL_NEWWIN 0x0010
+struct aim_tool_version {
+ unsigned short group;
+ unsigned short version;
+ unsigned short tool;
+ unsigned short toolversion;
+};
+
#endif /* FAIM_INTERNAL */
#define AIM_RATE_CODE_CHANGE 0x0001
int faimtest_parse_incoming_im(struct aim_session_t *, struct command_rx_struct *command, ...);
int faimtest_parse_userinfo(struct aim_session_t *, struct command_rx_struct *command, ...);
int faimtest_handleredirect(struct aim_session_t *, struct command_rx_struct *command, ...);
-int faimtest_authsvrready(struct aim_session_t *, struct command_rx_struct *command, ...);
-int faimtest_pwdchngdone(struct aim_session_t *, struct command_rx_struct *command, ...);
+int faimtest_infochange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
int faimtest_serverready(struct aim_session_t *, struct command_rx_struct *command, ...);
int faimtest_hostversions(struct aim_session_t *sess, struct command_rx_struct *command, ...);
int faimtest_parse_misses(struct aim_session_t *, struct command_rx_struct *command, ...);
break;
}
+ case AIM_CONN_TYPE_AUTH:
+ aim_bos_ackrateresp(sess, command->conn);
+ aim_auth_clientready(sess, command->conn);
+ dprintf("faimtest: connected to authorization/admin service\n");
+ break;
default:
dvprintf("faimtest: got rate response for unhandled connection type %04x\n", command->conn->type);
return 1;
}
+int faimtest_accountconfirm(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ int status;
+ va_list ap;
+
+ va_start(ap, command);
+ status = va_arg(ap, int); /* status code of confirmation request */
+ va_end(ap);
+
+ dvprintf("account confirmation returned status 0x%04x (%s)\n", status, (status==0x0000)?"email sent":"unknown");
+
+ return 1;
+}
+
int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
{
int famcount, i;
dinlineprintf("\n");
switch (command->conn->type) {
+ case AIM_CONN_TYPE_AUTH:
+ aim_auth_setversions(sess, command->conn);
+ aim_bos_reqrate(sess, command->conn); /* request rate info */
+
+ dprintf("faimtest: done with auth ServerReady\n");
+ break;
+
case AIM_CONN_TYPE_BOS:
aim_setversions(sess, command->conn);
break;
default:
- dprintf("faimtest: unknown connection type on Server Ready\n");
+ dvprintf("faimtest: unknown connection type on Host Online (0x%04x)\n", command->conn->type);
}
return 1;
switch(serviceid)
{
+ case 0x0005: /* Adverts */
+ {
+ struct aim_conn_t *tstconn;
+
+ tstconn = aim_newconn(sess, AIM_CONN_TYPE_ADS, ip);
+ if ((tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
+ dprintf("faimtest: unable to reconnect with authorizer\n");
+ } else {
+ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
+ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
+ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, 0x0018, faimtest_hostversions, 0);
+ aim_auth_sendcookie(sess, tstconn, cookie);
+ dprintf("sent cookie to adverts host\n");
+ }
+
+ }
+ break;
case 0x0007: /* Authorizer */
{
struct aim_conn_t *tstconn;
} else {
aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
+ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, 0x0018, faimtest_hostversions, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, faimtest_accountconfirm, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, faimtest_infochange, 0);
+ aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, faimtest_infochange, 0);
/* Send the cookie to the Auth */
aim_auth_sendcookie(sess, tstconn, cookie);
+ dprintf("sent cookie to authorizer host\n");
}
}
aim_usersearch_address(sess, command->conn, tmpstr+7);
} else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
aim_send_im(sess, command->conn, ohcaptainmycaptain, 0, "sendmsg 7900");
+ } else if (!strncmp(tmpstr, "reqauth", 7)) {
+ aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_AUTH);
+ } else if (!strncmp(tmpstr, "reqconfirm", 10)) {
+ aim_auth_reqconfirm(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH));
+ } else if (!strncmp(tmpstr, "reqemail", 8)) {
+ aim_auth_getinfo(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), 0x0011);
+ } else if (!strncmp(tmpstr, "changepass", 8)) {
+ aim_auth_changepasswd(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWPASSWORD", "OLDPASSWORD");
+ } else if (!strncmp(tmpstr, "setemail", 8)) {
+ aim_auth_setemail(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWEMAILADDRESS");
} else if (!strncmp(tmpstr, "sendmsg", 7)) {
int i;
i = atoi(tmpstr+8);
return 1;
}
-int faimtest_authsvrready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+int faimtest_infochange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
{
- dvprintf("faimtest_authsvrready: called (contype: %d)\n", command->conn->type);
- sleep(10);
- /* should just be able to tell it we're ready too... */
- aim_auth_clientready(sess, command->conn);
+ unsigned short change = 0;
+ int perms, type, length, str;
+ char *val;
+ va_list ap;
-#if 0
- /*
- * This is where you'd really begin changing your password.
- * However, this callback may get called for reasons other
- * than you wanting to change your password. You should
- * probably check that before actually doing it.
- */
- aim_auth_changepasswd(sess, command->conn, "PWD1", "PWD2");
-#endif
+ va_start(ap, command);
+ perms = va_arg(ap, int);
+ type = va_arg(ap, int);
+ length = va_arg(ap, int);
+ val = va_arg(ap, char *);
+ str = va_arg(ap, int);
+ va_end(ap);
- return 1;
-}
+ if (aimutil_get16(command->data+2) == 0x0005)
+ change = 1;
+
+ dvprintf("info%s: perms = %d, type = %x, length = %d, val = %s\n", change?" change":"", perms, type, length, str?val:"(not string)");
-int faimtest_pwdchngdone(struct aim_session_t *sess, struct command_rx_struct *command, ...)
-{
- dprintf("PASSWORD CHANGE SUCCESSFUL!!!\n");
return 1;
}