X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcutil.c;h=a3746f92ff8bf9f745c731cc17f99bfae5bdfb97;hb=c257b555225193e54d85daf541d29578b3c93882;hp=1ede14fc8c81e7f623250b50013dd6a3813c2fdf;hpb=99b7ff2e35905ef361dcfab4800e4a99355d3e24;p=silc.git diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index 1ede14fc..a3746f92 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2002 Pekka Riikonen + Copyright (C) 1997 - 2005 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 @@ -156,7 +156,7 @@ bool silc_parse_userfqdn(const char *string, char **left, char **right) } } else { if (left) - *left = strdup(string); + *left = silc_memdup(string, strlen(string)); } return TRUE; @@ -467,6 +467,25 @@ SilcUInt32 silc_hash_string(void *key, void *user_context) return h; } +/* Hash UTF-8 string */ + +SilcUInt32 silc_hash_utf8_string(void *key, void *user_context) +{ + unsigned char *s = (unsigned char *)key; + SilcUInt32 h = 0, g; + + while (*s != '\0') { + h = (h << 4) + *s; + if ((g = h & 0xf0000000)) { + h = h ^ (g >> 24); + h = h ^ g; + } + s++; + } + + return h; +} + /* Basic hash function to hash integers. May be used with the SilcHashTable. */ SilcUInt32 silc_hash_uint(void *key, void *user_context) @@ -478,14 +497,14 @@ SilcUInt32 silc_hash_uint(void *key, void *user_context) SilcUInt32 silc_hash_ptr(void *key, void *user_context) { - return (SilcUInt32)key; + return SILC_PTR_TO_32(key); } /* Hash a ID. The `user_context' is the ID type. */ SilcUInt32 silc_hash_id(void *key, void *user_context) { - SilcIdType id_type = (SilcIdType)(SilcUInt32)user_context; + SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context); SilcUInt32 h = 0; int i; @@ -553,7 +572,7 @@ SilcUInt32 silc_hash_client_id_hash(void *key, void *user_context) SilcUInt32 silc_hash_data(void *key, void *user_context) { - SilcUInt32 len = (SilcUInt32)user_context, h = 0; + SilcUInt32 len = SILC_PTR_TO_32(user_context), h = 0; unsigned char *data = (unsigned char *)key; int i; @@ -569,9 +588,9 @@ SilcUInt32 silc_hash_data(void *key, void *user_context) SilcUInt32 silc_hash_public_key(void *key, void *user_context) { SilcPublicKey pk = (SilcPublicKey)key; - return (pk->len + silc_hash_string(pk->name, NULL) + - silc_hash_string(pk->identifier, NULL) + - silc_hash_data(pk->pk, (void *)pk->pk_len)); + return (pk->len + (silc_hash_string(pk->name, NULL) ^ + silc_hash_string(pk->identifier, NULL) ^ + silc_hash_data(pk->pk, SILC_32_TO_PTR(pk->pk_len)))); } /* Compares two strings. It may be used as SilcHashTable comparison @@ -588,7 +607,7 @@ bool silc_hash_string_compare(void *key1, void *key2, void *user_context) bool silc_hash_id_compare(void *key1, void *key2, void *user_context) { - SilcIdType id_type = (SilcIdType)(SilcUInt32)user_context; + SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context); return (id_type == SILC_ID_CLIENT ? SILC_ID_COMPARE_HASH((SilcClientID *)key1, (SilcClientID *)key2) : SILC_ID_COMPARE_TYPE(key1, key2, id_type)); @@ -605,10 +624,21 @@ bool silc_hash_client_id_compare(void *key1, void *key2, void *user_context) bool silc_hash_data_compare(void *key1, void *key2, void *user_context) { - SilcUInt32 len = (SilcUInt32)user_context; + SilcUInt32 len = SILC_PTR_TO_32(user_context); return !memcmp(key1, key2, len); } +/* Compares UTF-8 string. */ + +bool silc_hash_utf8_compare(void *key1, void *key2, void *user_context) +{ + int l1 = strlen((char *)key1); + int l2 = strlen((char *)key2); + if (l1 > l2) + l2 = l1; + return !memcmp(key1, key2, l2); +} + /* Compares two SILC Public keys. It may be used as SilcHashTable comparison function. */ @@ -652,20 +682,33 @@ char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac) if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) strncat(string, "f", 1); + if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) + strncat(string, "C", 1); + if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) strncat(string, "m", 1); if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) strncat(string, "M", 1); + if (mode & SILC_CHANNEL_MODE_CIPHER) + strncat(string, "c", 1); + + if (mode & SILC_CHANNEL_MODE_HMAC) + strncat(string, "h", 1); + if (mode & SILC_CHANNEL_MODE_CIPHER) { - if (strlen(cipher) + strlen(string) < sizeof(string)) + if (strlen(cipher) + strlen(string) + 1< sizeof(string)) { + strncat(string, " ", 1); strncat(string, cipher, strlen(cipher)); + } } if (mode & SILC_CHANNEL_MODE_HMAC) { - if (strlen(hmac) + strlen(string) < sizeof(string)) + if (strlen(hmac) + strlen(string) + 1< sizeof(string)) { + strncat(string, " ", 1); strncat(string, hmac, strlen(hmac)); + } } /* Rest of mode is ignored */ @@ -1031,6 +1074,10 @@ static const SilcStatusMessage silc_status_messages[] = { { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" }, { STAT(BAD_VERSION), "Bad version" }, { STAT(TIMEDOUT), "Service timed out" }, + { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" }, + { STAT(OPERATION_ALLOWED), "Operation is not allowed" }, + { STAT(BAD_SERVER), "Bad server name" }, + { STAT(BAD_USERNAME), "Bad user name" }, { 0, NULL } }; @@ -1143,7 +1190,7 @@ const char *silc_get_command_name(unsigned char command) /* Return TRUE if `smaller' is smaller than `bigger'. */ -bool silc_compare_timeval(struct timeval *smaller, +bool silc_compare_timeval(struct timeval *smaller, struct timeval *bigger) { if ((smaller->tv_sec < bigger->tv_sec) ||