- Timestamp:
- Jul 16, 2010, 7:43:41 PM (15 years ago)
- Branches:
- master, release-1.10, release-1.7, release-1.8, release-1.9
- Children:
- c5873be
- Parents:
- 8ab1f28
- git-author:
- Geoffrey Thomas <geofft@mit.edu> (05/29/10 18:39:22)
- git-committer:
- Nelson Elhage <nelhage@mit.edu> (07/16/10 19:43:41)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
aim.c
r5e5f08f r0552482 7 7 8 8 struct owlfaim_priv { 9 char *aimbinarypath;10 9 char *screenname; 11 10 char *password; … … 65 64 /* static int reportinterval(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs); */ 66 65 static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...); 67 static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname);68 static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...);69 66 /* static void printuserflags(fu16_t flags); */ 70 67 static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...); … … 635 632 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0); 636 633 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO, faimtest_locrights, 0); 637 aim_conn_addhandler(sess, bosconn, 0x0001, 0x001f, faimtest_memrequest, 0);638 634 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, faimtest_parse_oncoming, 0); 639 635 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, faimtest_parse_offgoing, 0); … … 951 947 952 948 /* 953 * This is a little more complicated than it looks. The module954 * name (proto, boscore, etc) may or may not be given. If it is955 * not given, then use aim.exe. If it is given, put ".ocm" on the956 * end of it.957 *958 * Now, if the offset or length requested would cause a read past959 * the end of the file, then the request is considered invalid. Invalid960 * requests are processed specially. The value hashed is the961 * the request, put into little-endian (eight bytes: offset followed962 * by length).963 *964 * Additionally, if the request is valid, the length is mod 4096. It is965 * important that the length is checked for validity first before doing966 * the mod.967 *968 * Note to Bosco's Brigade: if you'd like to break this, put the969 * module name on an invalid request.970 *971 */972 static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname)973 {974 struct owlfaim_priv *priv = sess->aux_data;975 FILE *f;976 static const char defaultmod[] = "aim.exe";977 char *filename = NULL;978 struct stat st;979 unsigned char *buf;980 int invalid = 0;981 982 if (!bufret || !buflenret)983 return -1;984 985 if (modname) {986 filename = owl_sprintf("%s/%s.ocm", priv->aimbinarypath, modname);987 } else {988 filename = owl_sprintf("%s/%s", priv->aimbinarypath, defaultmod);989 }990 991 if (stat(filename, &st) == -1) {992 if (!modname) {993 /* perror("memrequest: stat"); */994 owl_free(filename);995 return -1;996 }997 invalid = 1;998 }999 1000 if (!invalid) {1001 if ((offset > st.st_size) || (len > st.st_size))1002 invalid = 1;1003 else if ((st.st_size - offset) < len)1004 len = st.st_size - offset;1005 else if ((st.st_size - len) < len)1006 len = st.st_size - len;1007 }1008 1009 if (!invalid && len) {1010 len %= 4096;1011 }1012 1013 if (invalid) {1014 int i;1015 1016 owl_free(filename); /* not needed */1017 owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);1018 i = 8;1019 if (modname) {1020 i+=strlen(modname);1021 }1022 1023 if (!(buf = owl_malloc(i))) {1024 return -1;1025 }1026 1027 i=0;1028 1029 if (modname) {1030 memcpy(buf, modname, strlen(modname));1031 i+=strlen(modname);1032 }1033 1034 /* Damn endianness. This must be little (LSB first) endian. */1035 buf[i++] = offset & 0xff;1036 buf[i++] = (offset >> 8) & 0xff;1037 buf[i++] = (offset >> 16) & 0xff;1038 buf[i++] = (offset >> 24) & 0xff;1039 buf[i++] = len & 0xff;1040 buf[i++] = (len >> 8) & 0xff;1041 buf[i++] = (len >> 16) & 0xff;1042 buf[i++] = (len >> 24) & 0xff;1043 1044 *bufret = buf;1045 *buflenret = i;1046 } else {1047 if (!(buf = owl_malloc(len))) {1048 owl_free(filename);1049 return -1;1050 }1051 /* printf("memrequest: loading %ld bytes from 0x%08lx in \"%s\"...\n", len, offset, filename); */1052 if (!(f = fopen(filename, "r"))) {1053 /* perror("memrequest: fopen"); */1054 owl_free(filename);1055 owl_free(buf);1056 return -1;1057 }1058 1059 owl_free(filename);1060 1061 if (fseek(f, offset, SEEK_SET) == -1) {1062 /* perror("memrequest: fseek"); */1063 fclose(f);1064 owl_free(buf);1065 return -1;1066 }1067 1068 if (fread(buf, len, 1, f) != 1) {1069 /* perror("memrequest: fread"); */1070 fclose(f);1071 owl_free(buf);1072 return -1;1073 }1074 1075 fclose(f);1076 *bufret = buf;1077 *buflenret = len;1078 }1079 return 0; /* success! */1080 }1081 1082 /*1083 * This will get an offset and a length. The client should read this1084 * data out of whatever AIM.EXE binary the user has provided (hopefully1085 * it matches the client information thats sent at login) and pass a1086 * buffer back to libfaim so it can hash the data and send it to AOL for1087 * inspection by the client police.1088 */1089 static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...)1090 {1091 struct owlfaim_priv *priv = sess->aux_data;1092 va_list ap;1093 fu32_t offset, len;1094 const char *modname;1095 unsigned char *buf;1096 int buflen;1097 1098 va_start(ap, fr);1099 offset = va_arg(ap, fu32_t);1100 len = va_arg(ap, fu32_t);1101 modname = va_arg(ap, const char *);1102 va_end(ap);1103 1104 if (priv->aimbinarypath && (getaimdata(sess, &buf, &buflen, offset, len, modname) == 0)) {1105 aim_sendmemblock(sess, fr->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);1106 owl_free(buf);1107 } else {1108 owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);1109 aim_sendmemblock(sess, fr->conn, offset, len, NULL, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);1110 }1111 return 1;1112 }1113 1114 /*1115 949 static void printuserflags(fu16_t flags) 1116 950 {
Note: See TracChangeset
for help on using the changeset viewer.