No release numbers
------------------
+ - Mon Aug 28 03:11:15 GMT 2000
+ - Adds lots of comments
+ - Add AIM_CLASS_ALLUSERS constant for setgrouppermmask()
+ - Add warnings support (jbm)
+
- Mon Aug 21 22:00:18 UTC 2000
- Implement SNAC login MD5 (thanks to Sonuvbob for that one)
- Clear out all that old login cruft. Much cleaner now.
if (aim_gettlv(innerlist, 0x0004, 1))
;
+ /*
+ * Type 0x0002: Unknown
+ */
+ if (aim_gettlv(innerlist, 0x0002, 1)) {
+ struct aim_tlv_t *tmptlv;
+ unsigned short classperms = 0;
+
+ tmptlv = aim_gettlv(innerlist, 0x0002, 1);
+ classperms = aimutil_get16(tmptlv->value);
+
+ printf("faim: class permissions %x\n", classperms);
+ }
+
/*
* Type 0x00c9: Unknown
*/
;
/*
- * Type 0x00d0: Unknown
+ * Type 0x00d0: Mandatory Channels?
*/
if (aim_gettlv(innerlist, 0x00d0, 1))
;
;
/*
- * Type 0x00d2: Unknown
+ * Type 0x00d2: Maximum Occupancy?
*/
if (aim_gettlv(innerlist, 0x00d2, 1))
;
exchanges[curexchange-1].name = NULL;
/*
- * Type 0x00d5: Unknown
+ * Type 0x00d5: Creation Permissions
+ *
+ * 0 Creation not allowed
+ * 1 Room creation allowed
+ * 2 Exchange creation allowed
+ *
*/
- if (aim_gettlv(innerlist, 0x00d5, 1))
- ;
+ if (aim_gettlv(innerlist, 0x00d5, 1)) {
+ struct aim_tlv_t *tmptlv;
+ unsigned char createperms = 0;
+
+ tmptlv = aim_gettlv(innerlist, 0x00d5, 1);
+ createperms = aimutil_get8(tmptlv->value);
+
+ printf("faim: creation permissions %x\n", createperms);
+ }
/*
* Type 0x00d6: Character Set (First Time)
rxcallback_t userfunc;
keylen = aimutil_get16(command->data+10);
- key = malloc(keylen+1);
+ if (!(key = malloc(keylen+1)))
+ return ret;
memcpy(key, command->data+12, keylen);
key[keylen] = '\0';
/*
* aim_bos_setgroupperm(mask)
*
- * Set group permisson mask. Normally 0x1f.
+ * Set group permisson mask. Normally 0x1f (all classes).
+ *
+ * The group permission mask allows you to keep users of a certain
+ * class or classes from talking to you. The mask should be
+ * a bitwise OR of all the user classes you want to see you.
*
*/
u_long aim_bos_setgroupperm(struct aim_session_t *sess,
}
/*
- * send_login_phase3(int socket)
- *
* Request Rate Information.
*
- * TODO: Move to aim_conn.
- * TODO: Move to SNAC interface.
*/
u_long aim_bos_reqrate(struct aim_session_t *sess,
struct aim_conn_t *conn)
}
/*
- * send_login_phase3b(int socket)
- *
* Rate Information Response Acknowledge.
*
*/
* Sets privacy flags. Normally 0x03.
*
* Bit 1: Allows other AIM users to see how long you've been idle.
- *
+ * Bit 2: Allows other AIM users to see how long you've been a member.
*
*/
u_long aim_bos_setprivacyflags(struct aim_session_t *sess,
* aim_bos_nop()
*
* No-op. WinAIM sends these every 4min or so to keep
- * the connection alive. With the recent changes
- * in the OSCAR servers, it looks like we must do the
- * same or be disconnected with a mysterious 'you logged
- * on from another client' message.
+ * the connection alive. Its not real necessary.
*
*/
u_long aim_bos_nop(struct aim_session_t *sess,
return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
}
+/*
+ * aim_send_warning(struct aim_session_t *sess,
+ * struct aim_conn_t *conn, char *destsn, int anon)
+ * send a warning to destsn.
+ * anon is anonymous or not;
+ * AIM_WARN_ANON anonymous
+ *
+ * returns -1 on error (couldn't alloc packet), next snacid on success.
+ *
+ */
+int aim_send_warning(struct aim_session_t *sess, struct aim_conn_t *conn, char *destsn, int anon)
+{
+ struct command_tx_struct *newpacket;
+ int curbyte;
+
+ if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, strlen(destsn)+13)))
+ return -1;
+
+ newpacket->lock = 1;
+
+ curbyte = 0;
+ curbyte += aim_putsnac(newpacket->data+curbyte,
+ 0x0004, 0x0008, 0x0000, sess->snac_nextid);
+
+ curbyte += aimutil_put16(newpacket->data+curbyte, (anon & AIM_WARN_ANON)?1:0);
+
+ curbyte += aimutil_put8(newpacket->data+curbyte, strlen(destsn));
+
+ curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn));
+
+ newpacket->commandlen = curbyte;
+ newpacket->lock = 0;
+
+ aim_tx_enqueue(sess, newpacket);
+
+ return (sess->snac_nextid++);
+}
+
+
+
/*
* aim_debugconn_sendconnect()
*
case 0x000f:
workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000f, workingPtr);
break;
+ case 0x0010:
+ workingPtr->handled = aim_parse_evilnotify_middle(sess, workingPtr);
+ break;
case 0x0013:
workingPtr->handled = aim_parsemotd_middle(sess, workingPtr);
break;
return ret;
}
+int aim_parse_evilnotify_middle(struct aim_session_t *sess, struct command_rx_struct *command)
+{
+ rxcallback_t userfunc = NULL;
+ int ret = 1, pos;
+ char *sn = NULL;
+
+ if(command->commandlen < 12) /* a warning level dec sends this */
+ return 1;
+
+ if ((pos = aimutil_get8(command->data+ 12)) > MAXSNLEN)
+ return 1;
+
+ if(!(sn = (char *)calloc(1, pos+1)))
+ return 1;
+
+ memcpy(sn, command->data+13, pos);
+
+ if ((userfunc = aim_callhandler(command->conn, 0x0001, 0x0010)))
+ ret = userfunc(sess, command, sn);
+
+ return ret;
+}
+
int aim_parsemotd_middle(struct aim_session_t *sess,
struct command_rx_struct *command, ...)
{
u_short id;
/*
- * Dunno.
+ * Code.
+ *
+ * Valid values:
+ * 1 Mandatory upgrade
+ * 2 Advisory upgrade
+ * 3 System bulletin
+ * 4 Nothing's wrong ("top o the world" -- normal)
+ *
*/
id = aimutil_get16(command->data+10);
cur->tlv->length = length;
cur->tlv->value = (u_char *)malloc(length*sizeof(u_char));
memcpy(cur->tlv->value, buf+pos, length);
-
+
cur->next = list;
list = cur;
}
* for WinAIM clients (up through the latest (4.0.1957)) to
* send any more than 1kb. Amaze all your windows friends
* with utterly oversized instant messages!
+ *
+ * XXX: the real limit is the total SNAC size at 8192. Fix this.
*
*/
#define MAXMSGLEN 7987
u_short capabilities;
};
-#define AIM_CLASS_TRIAL 0x0001
-#define AIM_CLASS_UNKNOWN2 0x0002
+#define AIM_CLASS_TRIAL 0x0001 /* "damned transients" */
+#define AIM_CLASS_ADMINISTRATOR 0x0002
#define AIM_CLASS_AOL 0x0004
-#define AIM_CLASS_UNKNOWN4 0x0008
+#define AIM_CLASS_OSCAR_PAY 0x0008
#define AIM_CLASS_FREE 0x0010
#define AIM_CLASS_AWAY 0x0020
#define AIM_CLASS_UNKNOWN40 0x0040
#define AIM_CLASS_UNKNOWN80 0x0080
+#define AIM_CLASS_ALLUSERS 0x001f
+
/*
* TLV handling
*/
#define AIM_VISIBILITYCHANGE_DENYADD 0x07
#define AIM_VISIBILITYCHANGE_DENYREMOVE 0x08
+#define AIM_PRIVFLAGS_ALLOWIDLE 0x01
+#define AIM_PRIVFLAGS_ALLOWMEMBERSINCE 0x02
+
+#define AIM_WARN_ANON 0x01
+
+int aim_send_warning(struct aim_session_t *sess, struct aim_conn_t *conn, char *destsn, int anon);
u_long aim_bos_nop(struct aim_session_t *, struct aim_conn_t *);
u_long aim_bos_setidle(struct aim_session_t *, struct aim_conn_t *, u_long);
u_long aim_bos_changevisibility(struct aim_session_t *, struct aim_conn_t *, int, char *);
int aim_parse_generalerrs(struct aim_session_t *, struct command_rx_struct *command, ...);
int aim_parsemotd_middle(struct aim_session_t *sess, struct command_rx_struct *command, ...);
int aim_parse_ratechange_middle(struct aim_session_t *sess, struct command_rx_struct *command);
+int aim_parse_evilnotify_middle(struct aim_session_t *sess, struct command_rx_struct *command);
int aim_parse_msgack_middle(struct aim_session_t *sess, struct command_rx_struct *command);
/* aim_im.c */
int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...);
int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
+int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...);
int faimtest_reportinterval(struct aim_session_t *sess, struct command_rx_struct *command, ...)
{
aim_bos_reqrate(sess, command->conn); /* request rate info */
aim_bos_ackrateresp(sess, command->conn); /* ack rate info response -- can we say timing? */
- aim_bos_setprivacyflags(sess, command->conn, 0x00000003);
+ aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE|AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
#if 0
aim_bos_reqpersonalinfo(sess, command->conn);
aim_bos_reqicbmparaminfo(sess, command->conn);
#endif
- /* set group permissions */
- aim_bos_setgroupperm(sess, command->conn, 0x1f);
+ /* set group permissions -- all user classes */
+ aim_bos_setgroupperm(sess, command->conn, AIM_CLASS_ALLUSERS);
fprintf(stderr, "faimtest: done with BOS ServerReady\n");
break;
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, faimtest_parse_misses, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, faimtest_parse_misses, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, faimtest_parse_ratechange, 0);
+ aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, faimtest_parse_evilnotify, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, faimtest_parse_misses, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, faimtest_parse_userinfo, 0);
aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, faimtest_parse_msgack, 0);
if (userinfo->class & 0x0001)
printf("TRIAL ");
if (userinfo->class & 0x0002)
- printf("UNKNOWN_BIT2 ");
+ printf("ADMINISTRATOR ");
if (userinfo->class & 0x0004)
printf("AOL ");
if (userinfo->class & 0x0008)
- printf("UNKNOWN_BIT4 ");
+ printf("OSCAR_PAY ");
if (userinfo->class & 0x0010)
printf("FREE ");
if (userinfo->class & 0x0040)
} else if (strstr(tmpstr, "goodday")) {
printf("faimtest: icbm: sending response\n");
aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
+ } else if (strstr(tmpstr, "warnme")) {
+ printf("faimtest: icbm: sending non-anon warning\n");
+ aim_send_warning(sess, command->conn, userinfo->sn, 0);
+ } else if (strstr(tmpstr, "anonwarn")) {
+ printf("faimtest: icbm: sending anon warning\n");
+ aim_send_warning(sess, command->conn, userinfo->sn, AIM_WARN_ANON);
} else if (!strncmp(tmpstr, "open chatnav", 12)) {
aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
//aim_chat_join(sess, command->conn, "thishereisaname2_chat85");
printf("\n%s is now online (class: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
userinfo->sn, userinfo->class,
(userinfo->class&AIM_CLASS_TRIAL)?" TRIAL":"",
- (userinfo->class&AIM_CLASS_UNKNOWN2)?" UNKNOWN2":"",
+ (userinfo->class&AIM_CLASS_ADMINISTRATOR)?" ADMINISTRATOR":"",
(userinfo->class&AIM_CLASS_AOL)?" AOL":"",
- (userinfo->class&AIM_CLASS_UNKNOWN4)?" UNKNOWN4":"",
+ (userinfo->class&AIM_CLASS_OSCAR_PAY)?" OSCAR_PAY":"",
(userinfo->class&AIM_CLASS_FREE)?" FREE":"",
(userinfo->class&AIM_CLASS_AWAY)?" AWAY":"",
(userinfo->class&AIM_CLASS_UNKNOWN40)?" UNKNOWN40":"",
msg = va_arg(ap, char *);
va_end(ap);
- printf("faimtest: motd: %s\n", msg);
+ printf("faimtest: motd: %s (%d)\n", msg, id);
return 1;
}
return (1);
};
+
+int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...)
+{
+ va_list ap;
+ char *sn;
+
+ va_start(ap, command);
+ sn = va_arg(ap, char *);
+ va_end(ap);
+
+ printf("faimtest: warning from: %s\n", sn);
+
+ free(sn);
+
+ return 1;
+};