From 0e2be2725c40e5687a034a075a5dbe65c46d45a9 Mon Sep 17 00:00:00 2001 From: mid Date: Sun, 19 Mar 2000 00:07:32 +0000 Subject: [PATCH] - Fixed a robustness problem in aim_handleredirect_middle() - Added TLV chain creation routines (yes, aimd is progressing) --- CHANGES | 4 ++ aim_rxhandlers.c | 31 ++++++++++-- aim_tlv.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++ faim/aim.h | 5 +- 4 files changed, 158 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index d3ff26d..3bf1aeb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ No release numbers ------------------ + - Sun Mar 12 00:07:40 UTC 2000 + - Fixed a robustness problem in aim_handleredirect_middle() + - Added TLV chain creation routines (yes, aimd is progressing) + - Mon Jan 3 04:07:55 UTC 2000 - Fixed bug in aim_snac.c - Fixed condition where commands read from connections that have diff --git a/aim_rxhandlers.c b/aim_rxhandlers.c index 0331433..0022a4e 100644 --- a/aim_rxhandlers.c +++ b/aim_rxhandlers.c @@ -630,14 +630,33 @@ int aim_handleredirect_middle(struct aim_session_t *sess, struct aim_tlvlist_t *tlvlist; int ret = 1; - tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10); + if (!(tlvlist = aim_readtlvchain(command->data+10, command->commandlen-10))) + { + printf("libfaim: major bug: unable to read tlvchain from redirect\n"); + return ret; + } - tmptlv = aim_gettlv(tlvlist, 0x000d, 1); + if (!(tmptlv = aim_gettlv(tlvlist, 0x000d, 1))) + { + printf("libfaim: major bug: no service ID in tlvchain from redirect\n"); + aim_freetlvchain(&tlvlist); + return ret; + } serviceid = aimutil_get16(tmptlv->value); - ip = aim_gettlv_str(tlvlist, 0x0005, 1); + if (!(ip = aim_gettlv_str(tlvlist, 0x0005, 1))) + { + printf("libfaim: major bug: no IP in tlvchain from redirect (service 0x%02x)\n", serviceid); + aim_freetlvchain(&tlvlist); + return ret; + } - tmptlv = aim_gettlv(tlvlist, 0x0006, 1); + if (!(tmptlv = aim_gettlv(tlvlist, 0x0006, 1))) + { + printf("libfaim: major bug: no cookie in tlvchain from redirect (service 0x%02x)\n", serviceid); + aim_freetlvchain(&tlvlist); + return ret; + } memcpy(cookie, tmptlv->value, AIM_COOKIELEN); if (serviceid == AIM_CONN_TYPE_CHAT) @@ -658,6 +677,10 @@ int aim_handleredirect_middle(struct aim_session_t *sess, if (userfunc) ret = userfunc(sess, command, serviceid, ip, cookie); } + + /* + * XXX: Is there a leak here? Where does IP get freed? + */ aim_freetlvchain(&tlvlist); return ret; diff --git a/aim_tlv.c b/aim_tlv.c index d03f2f9..06f1f7a 100644 --- a/aim_tlv.c +++ b/aim_tlv.c @@ -67,6 +67,129 @@ void aim_freetlvchain(struct aim_tlvlist_t **list) return; } +int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str) +{ + struct aim_tlvlist_t *new; + struct aim_tlvlist_t *cur; + + if (!list) + return 0; + + new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(new, 0x00, sizeof(struct aim_tlvlist_t)); + + new->tlv = aim_createtlv(); + new->tlv->type = type; + new->tlv->length = strlen(str); + new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); + memcpy(new->tlv->value, str, new->tlv->length); + + new->next = NULL; + + if (*list == NULL) { + *list = new; + } else if ((*list)->next == NULL) { + (*list)->next = new; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = new; + } + return new->tlv->length; +} + +int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val) +{ + struct aim_tlvlist_t *new; + struct aim_tlvlist_t *cur; + + if (!list) + return 0; + + new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(new, 0x00, sizeof(struct aim_tlvlist_t)); + + new->tlv = aim_createtlv(); + new->tlv->type = type; + new->tlv->length = 2; + new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); + aimutil_put16(new->tlv->value, val); + + new->next = NULL; + + if (*list == NULL) { + *list = new; + } else if ((*list)->next == NULL) { + (*list)->next = new; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = new; + } + return 2; +} + +int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val) +{ + struct aim_tlvlist_t *new; + struct aim_tlvlist_t *cur; + + if (!list) + return 0; + + new = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(new, 0x00, sizeof(struct aim_tlvlist_t)); + + new->tlv = aim_createtlv(); + new->tlv->type = type; + new->tlv->length = 4; + new->tlv->value = (u_char *)malloc(new->tlv->length*sizeof(u_char)); + aimutil_put32(new->tlv->value, val); + + new->next = NULL; + + if (*list == NULL) { + *list = new; + } else if ((*list)->next == NULL) { + (*list)->next = new; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = new; + } + return 4; +} + +int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list) +{ + int goodbuflen = 0; + int i = 0; + struct aim_tlvlist_t *cur; + + if (!list || !buf || !buflen) + return 0; + + /* do an initial run to test total length */ + for (cur = *list; cur; cur = cur->next) { + goodbuflen += 2 + 2; /* type + len */ + goodbuflen += cur->tlv->length; + } + + if (goodbuflen > buflen) + return 0; /* not enough buffer */ + + /* do the real write-out */ + for (cur = *list; cur; cur = cur->next) { + i += aimutil_put16(buf+i, cur->tlv->type); + i += aimutil_put16(buf+i, cur->tlv->length); + memcpy(buf+i, cur->tlv->value, cur->tlv->length); + i += cur->tlv->length; + } + + return i; +} + + /* * Grab the Nth TLV of type type in the TLV list list. */ diff --git a/faim/aim.h b/faim/aim.h index 8b52f85..bf813bc 100644 --- a/faim/aim.h +++ b/faim/aim.h @@ -245,7 +245,10 @@ int aim_freetlv(struct aim_tlv_t **oldtlv); int aim_puttlv_16(u_char *, u_short, u_short); int aim_puttlv_32(u_char *, u_short, u_long); int aim_puttlv_str(u_char *buf, u_short t, u_short l, u_char *v); - +int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list); +int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val); +int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val); +int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str); /* * Get command from connections / Dispatch commands -- 2.45.1