X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcargument.c;h=eac8bdf60e72d5dfef128924ba389df5fbee842f;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=18446fbe2f9242ca559051b619bddcf5441f64fa;hpb=27126950b0669ffcecd5ecd12b1a813705587d1d;p=silc.git diff --git a/lib/silccore/silcargument.c b/lib/silccore/silcargument.c index 18446fbe..eac8bdf6 100644 --- a/lib/silccore/silcargument.c +++ b/lib/silccore/silcargument.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2006 Pekka Riikonen + Copyright (C) 2001 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,11 +22,7 @@ #include "silc.h" #include "silcargument.h" -/****************************************************************************** - - Argument Payload - -******************************************************************************/ +/*************************** Argument Payload *******************************/ struct SilcArgumentPayloadStruct { SilcUInt32 argc; @@ -71,8 +67,10 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, SILC_STR_UI_SHORT(&p_len), SILC_STR_UI_CHAR(&arg_type), SILC_STR_END); - if (ret == -1 || p_len > silc_buffer_len(&buffer) - 3) + if (ret == -1 || p_len > silc_buffer_len(&buffer) - 3) { + SILC_LOG_DEBUG(("Malformed argument payload")); goto err; + } newp->argv_lens[i] = p_len; newp->argv_types[i] = arg_type; @@ -83,8 +81,10 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, SILC_STR_UI_XNSTRING_ALLOC(&newp->argv[i], p_len), SILC_STR_END); - if (ret == -1) + if (ret == -1) { + SILC_LOG_DEBUG(("Malformed argument payload")); goto err; + } silc_buffer_pull(&buffer, p_len); pull_len += 3 + p_len; @@ -300,29 +300,22 @@ unsigned char *silc_argument_get_arg_type(SilcArgumentPayload payload, /* Return argument already decoded */ -SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, - SilcUInt32 type, - SilcArgumentDecodeType dec_type, - void *ret_arg, - void **ret_arg_alloc) +static SilcBool silc_argument_decode(unsigned char *data, + SilcUInt32 data_len, + SilcArgumentDecodeType dec_type, + void *ret_arg, + void **ret_arg_alloc) { - unsigned char *tmp; - SilcUInt32 tmp_len; - - tmp = silc_argument_get_arg_type(payload, type, &tmp_len); - if (!tmp) - return FALSE; - switch (dec_type) { case SILC_ARGUMENT_ID: if (ret_arg) - if (!silc_id_payload_parse_id(tmp, tmp_len, (SilcID *)ret_arg)) + if (!silc_id_payload_parse_id(data, data_len, (SilcID *)ret_arg)) return FALSE; if (ret_arg_alloc) { SilcID id; - if (!silc_id_payload_parse_id(tmp, tmp_len, &id)) + if (!silc_id_payload_parse_id(data, data_len, &id)) return FALSE; *ret_arg_alloc = silc_memdup(&id, sizeof(id)); } @@ -335,7 +328,7 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, if (!ret_arg_alloc) return FALSE; - if (!silc_public_key_payload_decode(tmp, tmp_len, &public_key)) + if (!silc_public_key_payload_decode(data, data_len, &public_key)) return FALSE; *ret_arg_alloc = public_key; @@ -346,37 +339,37 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, if (!ret_arg_alloc) return FALSE; - *ret_arg_alloc = silc_attribute_payload_parse(tmp, tmp_len); + *ret_arg_alloc = silc_attribute_payload_parse(data, data_len); break; case SILC_ARGUMENT_UINT32: - if (tmp_len != 4) + if (data_len != 4) return FALSE; if (ret_arg) { SilcUInt32 *i = ret_arg; - SILC_GET32_MSB(*i, tmp); + SILC_GET32_MSB(*i, data); } if (ret_arg_alloc) { SilcUInt32 i; - SILC_GET32_MSB(i, tmp); + SILC_GET32_MSB(i, data); *ret_arg_alloc = silc_memdup(&i, sizeof(i)); } break; case SILC_ARGUMENT_BOOL: - if (tmp_len != 1) + if (data_len != sizeof(SilcBool)) return FALSE; if (ret_arg) { SilcBool *b = ret_arg; - *b = (tmp[0] == 0x01 ? TRUE : FALSE); + *b = (data[0] == 0x01 ? TRUE : FALSE); } if (ret_arg_alloc) { SilcBool b; - b = (tmp[0] == 0x01 ? TRUE : FALSE); + b = (data[0] == 0x01 ? TRUE : FALSE); *ret_arg_alloc = silc_memdup(&b, sizeof(b)); } break; @@ -387,3 +380,122 @@ SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, return TRUE; } + +/* Return argument already decoded */ + +SilcBool silc_argument_get_decoded(SilcArgumentPayload payload, + SilcUInt32 type, + SilcArgumentDecodeType dec_type, + void *ret_arg, + void **ret_arg_alloc) +{ + unsigned char *tmp; + SilcUInt32 tmp_len; + + tmp = silc_argument_get_arg_type(payload, type, &tmp_len); + if (!tmp) + return FALSE; + + return silc_argument_decode(tmp, tmp_len, dec_type, ret_arg, ret_arg_alloc); +} + +/************************* Argument List Payload ****************************/ + +/* Parses argument payload list */ + +SilcArgumentPayload +silc_argument_list_parse(const unsigned char *payload, + SilcUInt32 payload_len) +{ + SilcArgumentPayload arg; + SilcUInt16 argc; + + if (payload_len < 5) + return NULL; + + SILC_GET16_MSB(argc, payload); + + arg = silc_argument_payload_parse(payload + 2, payload_len - 2, argc); + + return arg; +} + +/* Parses argument payload list of specific argument types */ + +SilcDList +silc_argument_list_parse_decoded(const unsigned char *payload, + SilcUInt32 payload_len, + SilcArgumentDecodeType dec_type) +{ + SilcArgumentPayload arg; + SilcArgumentDecodedList dec; + unsigned char *data; + SilcUInt32 data_len, type; + SilcDList list; + + arg = silc_argument_list_parse(payload, payload_len); + if (!arg) + return NULL; + + list = silc_dlist_init(); + if (!list) { + silc_argument_payload_free(arg); + return NULL; + } + + data = silc_argument_get_first_arg(arg, &type, &data_len); + while (data) { + dec = silc_calloc(1, sizeof(*dec)); + if (!dec) + continue; + dec->arg_type = type; + if (silc_argument_decode(data, data_len, dec_type, NULL, &dec->argument)) + silc_dlist_add(list, dec); + else + silc_free(dec); + data = silc_argument_get_next_arg(arg, &type, &data_len); + } + + silc_argument_payload_free(arg); + + silc_dlist_start(list); + + return list; +} + +/* Free decoded argument payload list */ + +void silc_argument_list_free(SilcDList list, SilcArgumentDecodeType dec_type) +{ + SilcArgumentDecodedList dec; + + if (!list) + return; + + silc_dlist_start(list); + while ((dec = silc_dlist_get(list))) { + switch (dec_type) { + + case SILC_ARGUMENT_ID: + case SILC_ARGUMENT_UINT32: + case SILC_ARGUMENT_BOOL: + silc_free(dec->argument); + break; + + case SILC_ARGUMENT_PUBLIC_KEY: + silc_pkcs_public_key_free(dec->argument); + break; + + case SILC_ARGUMENT_ATTRIBUTES: + silc_attribute_payload_free(dec->argument); + break; + + default: + break; + } + + silc_free(dec); + } + + silc_dlist_uninit(list); +}