Пример #1
0
static int is_default_cap(Capability *cap) {
	unsigned long ui;

	/* All unknown values are empty by default */
	if (cap->name != NULL || cap->id < 0 || cap->id >= WSP_NUM_CAPS)
		return cap->data == NULL || octstr_len(cap->data) == 0;

	switch (cap->id) {
	case WSP_CAPS_CLIENT_SDU_SIZE:
	case WSP_CAPS_SERVER_SDU_SIZE:
		return (cap->data != NULL &&
		    octstr_extract_uintvar(cap->data, &ui, 0) >= 0 &&
		    ui == 1400);
	case WSP_CAPS_PROTOCOL_OPTIONS:
		return cap->data != NULL && octstr_get_char(cap->data, 0) == 0;
	case WSP_CAPS_METHOD_MOR:
	case WSP_CAPS_PUSH_MOR:
		return cap->data != NULL && octstr_get_char(cap->data, 0) == 1;
	case WSP_CAPS_EXTENDED_METHODS:
	case WSP_CAPS_HEADER_CODE_PAGES:
	case WSP_CAPS_ALIASES:
		return cap->data == NULL || octstr_len(cap->data) == 0;
	default:
		return 0;
	}
}
Пример #2
0
int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu) {
	Octstr *data;
	int found;

	found = wsp_cap_get_data(caps_list, WSP_CAPS_SERVER_SDU_SIZE,
					NULL, &data);
	if (found > 0 && octstr_extract_uintvar(data, sdu, 0) < 0)
		return -1;

	return found;
}
Пример #3
0
List *wsp_cap_unpack_list(Octstr *caps) {
	List *caps_list;
	long pos, capslen;

	caps_list = gwlist_create();
	if (caps == NULL)
		return caps_list;

	capslen = octstr_len(caps);
	pos = 0;
	while (pos < capslen) {
		unsigned long length;
		int id;
		Octstr *name;
		Octstr *data;

		pos = octstr_extract_uintvar(caps, &length, pos);
		if (pos < 0 || length == 0)
			goto error;

		id = octstr_get_char(caps, pos);
		if (id >= 0x80) {
			id &= 0x7f; /* It's encoded as a short-integer */
			name = NULL;
			data = octstr_copy(caps, pos + 1, length - 1);
		} else {
			long nullpos;
			id = -1;  /* It's encoded as token-text */
			nullpos = octstr_search_char(caps, 0, pos);
			if (nullpos < 0)
                            goto error;
                        /* check length
                         * FIXME: If it's not allowed that data is empty then change check
                         *        to <= .
                         */
                        if (length < (nullpos + 1 - pos))
                            goto error;
			name = octstr_copy(caps, pos, nullpos - pos);
			data = octstr_copy(caps, nullpos + 1,
				length - (nullpos + 1 - pos));
		}
		gwlist_append(caps_list, wsp_cap_create(id, name, data));
		pos += length;
	}

	return caps_list;

error:
	warning(0, "WSP: Error unpacking capabilities");
	return caps_list;
}
Пример #4
0
unsigned long parse_get_uintvar(ParseContext *context)
{
    long pos;
    unsigned long value;

    gw_assert(context != NULL);

    pos = octstr_extract_uintvar(context->data, &value, context->pos);
    if (pos < 0 || pos > context->limit) {
        context->error = 1;
        return 0;
    }

    context->pos = pos;
    return value;
}
Пример #5
0
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;
	}
}