Octstr *wsp_cap_pack_list(List *caps_list) { Octstr *result; Capability *cap; long i, len; result = octstr_create(""); len = gwlist_len(caps_list); for (i = 0; i < len; i++) { long datalen; cap = gwlist_get(caps_list, i); datalen = 0; if (cap->data) datalen = octstr_len(cap->data); if (datalen == 0 && cap->accept) continue; if (cap->name) { if (octstr_get_char(cap->name, 0) >= 0x80 || octstr_search_char(cap->name, 0, 0) >= 0) { error(0, "WSP: Bad capability."); wsp_cap_dump(cap); continue; } /* Add length */ octstr_append_uintvar(result, octstr_len(cap->name) + 1 + datalen); /* Add identifier */ octstr_append(result, cap->name); octstr_append_char(result, 0); } else { if (cap->id >= 0x80 || cap->id < 0) { error(0, "WSP: Bad capability."); wsp_cap_dump(cap); continue; } /* Add length */ octstr_append_uintvar(result, 1 + datalen); /* Add identifier */ octstr_append_char(result, 0x80 | cap->id); } /* Add payload, if any */ if (cap->data) { octstr_append(result, cap->data); } } return result; }
void wsp_cap_dump_list(List *caps_list) { long i; if (caps_list == NULL) { debug("wsp", 0, "NULL capability list"); return; } debug("wsp", 0, "Dumping capability list at %p, length %ld", caps_list, gwlist_len(caps_list)); for (i = 0; i < gwlist_len(caps_list); i++) { wsp_cap_dump(gwlist_get(caps_list, i)); } debug("wsp", 0, "End of capability list dump"); }
static void sanitize_capabilities(List *caps, WSPMachine *m) { long i; Capability *cap; unsigned long ui; for (i = 0; i < gwlist_len(caps); i++) { cap = gwlist_get(caps, i); /* We only know numbered capabilities. Let the application * layer negotiate whatever it wants for unknown ones. */ if (cap->name != NULL) continue; switch (cap->id) { case WSP_CAPS_CLIENT_SDU_SIZE: /* Check if it's a valid uintvar. The value is the * max SDU size we will send, and there's no * internal limit to that, so accept any value. */ if (cap->data != NULL && octstr_extract_uintvar(cap->data, &ui, 0) < 0) goto bad_cap; else m->client_SDU_size = ui; break; case WSP_CAPS_SERVER_SDU_SIZE: /* Check if it's a valid uintvar */ if (cap->data != NULL && (octstr_extract_uintvar(cap->data, &ui, 0) < 0)) goto bad_cap; /* XXX Our MRU is not quite unlimited, since we * use signed longs in the library functions -- * should we make sure we limit the reply value * to LONG_MAX? (That's already a 2GB packet) */ break; case WSP_CAPS_PROTOCOL_OPTIONS: /* Currently we don't support any Push, nor * session resume, nor acknowledgement headers, * so make sure those bits are not set. */ if (cap->data != NULL && octstr_len(cap->data) > 0 && (octstr_get_char(cap->data, 0) & 0xf0) != 0) { warning(0, "WSP: Application layer tried to " "negotiate protocol options."); octstr_set_bits(cap->data, 0, 4, 0); } break; case WSP_CAPS_EXTENDED_METHODS: /* XXX Check format here */ break; case WSP_CAPS_HEADER_CODE_PAGES: /* We don't support any yet, so don't let this * be negotiated. */ if (cap->data) goto bad_cap; break; } continue; bad_cap: error(0, "WSP: Found illegal value in capabilities reply."); wsp_cap_dump(cap); gwlist_delete(caps, i, 1); i--; wsp_cap_destroy(cap); continue; } }