X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcutil.c;h=c3af592539a49d72b430f572c80cea7b40e4b307;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=d571b8a62a4dd328b3a1b901a8ac00f59f8e2934;hpb=017dec75a98209fbef49eb496c2269b0c49e736d;p=silc.git diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index d571b8a6..c3af5925 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -1,16 +1,15 @@ /* - silcutil.c + silcutil.c - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 1997 - 2000 Pekka Riikonen + Copyright (C) 1997 - 2002 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -25,104 +24,6 @@ #include "silcincludes.h" -/* Reads a file to a buffer. The allocated buffer is returned. Length of - the file read is returned to the return_len argument. */ - -char *silc_file_read(const char *filename, uint32 *return_len) -{ - int fd; - char *buffer; - int filelen; - - fd = open(filename, O_RDONLY); - if (fd < 0) { - SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); - return NULL; - } - - filelen = lseek(fd, (off_t)0L, SEEK_END); - if (filelen < 0) { - close(fd); - return NULL; - } - if (lseek(fd, (off_t)0L, SEEK_SET) < 0) { - close(fd); - return NULL; - } - - if (filelen < 0) { - SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); - close(fd); - return NULL; - } - - buffer = silc_calloc(filelen + 1, sizeof(char)); - - if ((read(fd, buffer, filelen)) == -1) { - memset(buffer, 0, sizeof(buffer)); - close(fd); - SILC_LOG_ERROR(("Cannot read from file %s: %s", filename, - strerror(errno))); - return NULL; - } - - close(fd); - buffer[filelen] = EOF; - - if (return_len) - *return_len = filelen; - - return buffer; -} - -/* Writes a buffer to the file. */ - -int silc_file_write(const char *filename, const char *buffer, uint32 len) -{ - int fd; - - if ((fd = creat(filename, 0644)) == -1) { - SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename, - strerror(errno))); - return -1; - } - - if ((write(fd, buffer, len)) == -1) { - SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno))); - close(fd); - return -1; - } - - close(fd); - - return 0; -} - -/* Writes a buffer to the file. If the file is created specific mode is - set to the file. */ - -int silc_file_write_mode(const char *filename, const char *buffer, - uint32 len, int mode) -{ - int fd; - - if ((fd = creat(filename, mode)) == -1) { - SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename, - strerror(errno))); - return -1; - } - - if ((write(fd, buffer, len)) == -1) { - SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno))); - close(fd); - return -1; - } - - close(fd); - - return 0; -} - /* Gets line from a buffer. Stops reading when a newline or EOF occurs. This doesn't remove the newline sign from the destination buffer. The argument begin is returned and should be passed again for the function. */ @@ -211,10 +112,10 @@ static unsigned char pem_enc[64] = data string. Note: This is originally public domain code and is still PD. */ -char *silc_encode_pem(unsigned char *data, uint32 len) +char *silc_encode_pem(unsigned char *data, SilcUInt32 len) { int i, j; - uint32 bits, c, char_count; + SilcUInt32 bits, c, char_count; char *pem; char_count = 0; @@ -259,10 +160,10 @@ char *silc_encode_pem(unsigned char *data, uint32 len) /* Same as above but puts newline ('\n') every 72 characters. */ -char *silc_encode_pem_file(unsigned char *data, uint32 data_len) +char *silc_encode_pem_file(unsigned char *data, SilcUInt32 data_len) { int i, j; - uint32 len, cols; + SilcUInt32 len, cols; char *pem, *pem2; pem = silc_encode_pem(data, data_len); @@ -288,11 +189,11 @@ char *silc_encode_pem_file(unsigned char *data, uint32 data_len) /* Decodes PEM into data. Returns the decoded data. Note: This is originally public domain code and is still PD. */ -unsigned char *silc_decode_pem(unsigned char *pem, uint32 pem_len, - uint32 *ret_len) +unsigned char *silc_decode_pem(unsigned char *pem, SilcUInt32 pem_len, + SilcUInt32 *ret_len) { int i, j; - uint32 len, c, char_count, bits; + SilcUInt32 len, c, char_count, bits; unsigned char *data; static char ialpha[256], decoder[256]; @@ -359,11 +260,17 @@ unsigned char *silc_decode_pem(unsigned char *pem, uint32 pem_len, bool silc_parse_userfqdn(const char *string, char **left, char **right) { - uint32 tlen; + SilcUInt32 tlen; if (!string) return FALSE; + if (string[0] == '@') { + if (left) + *left = strdup(string); + return TRUE; + } + if (strchr(string, '@')) { tlen = strcspn(string, "@"); @@ -391,10 +298,10 @@ bool silc_parse_userfqdn(const char *string, char **left, char **right) void silc_parse_command_line(unsigned char *buffer, unsigned char ***parsed, - uint32 **parsed_lens, - uint32 **parsed_types, - uint32 *parsed_num, - uint32 max_args) + SilcUInt32 **parsed_lens, + SilcUInt32 **parsed_types, + SilcUInt32 *parsed_num, + SilcUInt32 max_args) { int i, len = 0; int argc = 0; @@ -476,7 +383,7 @@ char *silc_format(char *fmt, ...) static char rid[256]; -char *silc_id_render(void *id, uint16 type) +char *silc_id_render(void *id, SilcUInt16 type) { char tmp[100]; unsigned char tmps[2]; @@ -486,12 +393,16 @@ char *silc_id_render(void *id, uint16 type) case SILC_ID_SERVER: { SilcServerID *server_id = (SilcServerID *)id; - struct in_addr ipv4; - if (server_id->ip.data_len > 4) { - +#ifdef HAVE_IPV6 + struct in6_addr ipv6; + memmove(&ipv6, server_id->ip.data, sizeof(ipv6)); + if (!inet_ntop(AF_INET6, &ipv6, tmp, sizeof(tmp))) + strcat(rid, tmp); +#endif } else { - SILC_GET32_MSB(ipv4.s_addr, server_id->ip.data); + struct in_addr ipv4; + memmove(&ipv4.s_addr, server_id->ip.data, 4); strcat(rid, inet_ntoa(ipv4)); } @@ -507,12 +418,16 @@ char *silc_id_render(void *id, uint16 type) case SILC_ID_CLIENT: { SilcClientID *client_id = (SilcClientID *)id; - struct in_addr ipv4; - if (client_id->ip.data_len > 4) { - +#ifdef HAVE_IPV6 + struct in6_addr ipv6; + memmove(&ipv6, client_id->ip.data, sizeof(ipv6)); + if (!inet_ntop(AF_INET6, &ipv6, tmp, sizeof(tmp))) + strcat(rid, tmp); +#endif } else { - SILC_GET32_MSB(ipv4.s_addr, client_id->ip.data); + struct in_addr ipv4; + memmove(&ipv4.s_addr, client_id->ip.data, 4); strcat(rid, inet_ntoa(ipv4)); } @@ -529,12 +444,16 @@ char *silc_id_render(void *id, uint16 type) case SILC_ID_CHANNEL: { SilcChannelID *channel_id = (SilcChannelID *)id; - struct in_addr ipv4; - if (channel_id->ip.data_len > 4) { - +#ifdef HAVE_IPV6 + struct in6_addr ipv6; + memmove(&ipv6, channel_id->ip.data, sizeof(ipv6)); + if (!inet_ntop(AF_INET6, &ipv6, tmp, sizeof(tmp))) + strcat(rid, tmp); +#endif } else { - SILC_GET32_MSB(ipv4.s_addr, channel_id->ip.data); + struct in_addr ipv4; + memmove(&ipv4.s_addr, channel_id->ip.data, 4); strcat(rid, inet_ntoa(ipv4)); } @@ -558,13 +477,16 @@ char *silc_id_render(void *id, uint16 type) int silc_string_compare(char *string1, char *string2) { int i; - int slen1 = strlen(string1); - int slen2 = strlen(string2); + int slen1; + int slen2; char *tmpstr1, *tmpstr2; if (!string1 || !string2) return FALSE; + slen1 = strlen(string1); + slen2 = strlen(string2); + /* See if they are same already */ if (!strncmp(string1, string2, strlen(string2))) return TRUE; @@ -627,10 +549,10 @@ int silc_string_compare(char *string1, char *string2) this is used usually with nicknames, channel and server names to provide case insensitive keys. */ -uint32 silc_hash_string(void *key, void *user_context) +SilcUInt32 silc_hash_string(void *key, void *user_context) { char *s = (char *)key; - uint32 h = 0, g; + SilcUInt32 h = 0, g; while (*s != '\0') { h = (h << 4) + tolower(*s); @@ -646,31 +568,31 @@ uint32 silc_hash_string(void *key, void *user_context) /* Basic hash function to hash integers. May be used with the SilcHashTable. */ -uint32 silc_hash_uint(void *key, void *user_context) +SilcUInt32 silc_hash_uint(void *key, void *user_context) { - return *(uint32 *)key; + return *(SilcUInt32 *)key; } /* Basic hash funtion to hash pointers. May be used with the SilcHashTable. */ -uint32 silc_hash_ptr(void *key, void *user_context) +SilcUInt32 silc_hash_ptr(void *key, void *user_context) { - return (uint32)key; + return (SilcUInt32)key; } /* Hash a ID. The `user_context' is the ID type. */ -uint32 silc_hash_id(void *key, void *user_context) +SilcUInt32 silc_hash_id(void *key, void *user_context) { - SilcIdType id_type = (SilcIdType)(uint32)user_context; - uint32 h = 0; + SilcIdType id_type = (SilcIdType)(SilcUInt32)user_context; + SilcUInt32 h = 0; int i; switch (id_type) { case SILC_ID_CLIENT: { SilcClientID *id = (SilcClientID *)key; - uint32 g; + SilcUInt32 g; /* The client ID is hashed by hashing the hash of the ID (which is a truncated MD5 hash of the nickname) so that we @@ -719,9 +641,9 @@ uint32 silc_hash_id(void *key, void *user_context) /* Hash binary data. The `user_context' is the data length. */ -uint32 silc_hash_data(void *key, void *user_context) +SilcUInt32 silc_hash_data(void *key, void *user_context) { - uint32 len = (uint32)user_context, h = 0; + SilcUInt32 len = (SilcUInt32)user_context, h = 0; unsigned char *data = (unsigned char *)key; int i; @@ -745,7 +667,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)(uint32)user_context; + SilcIdType id_type = (SilcIdType)(SilcUInt32)user_context; return (id_type == SILC_ID_CLIENT ? SILC_ID_COMPARE_HASH((SilcClientID *)key1, (SilcClientID *)key2) : SILC_ID_COMPARE_TYPE(key1, key2, id_type)); @@ -762,13 +684,13 @@ 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) { - uint32 len = (uint32)user_context; + SilcUInt32 len = (SilcUInt32)user_context; return !memcmp(key1, key2, len); } /* Parses mode mask and returns the mode as string. */ -char *silc_client_chmode(uint32 mode, const char *cipher, const char *hmac) +char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac) { char string[100]; @@ -814,7 +736,7 @@ char *silc_client_chmode(uint32 mode, const char *cipher, const char *hmac) /* Parses channel user mode mask and returns te mode as string */ -char *silc_client_chumode(uint32 mode) +char *silc_client_chumode(SilcUInt32 mode) { char string[4]; @@ -834,7 +756,7 @@ char *silc_client_chumode(uint32 mode) /* Parses channel user mode and returns it as special mode character. */ -char *silc_client_chumode_char(uint32 mode) +char *silc_client_chumode_char(SilcUInt32 mode) { char string[4]; @@ -851,3 +773,31 @@ char *silc_client_chumode_char(uint32 mode) return strdup(string); } + +/* Creates fingerprint from data, usually used with SHA1 digests */ + +char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len) +{ + char fingerprint[64], *cp; + int i; + + memset(fingerprint, 0, sizeof(fingerprint)); + cp = fingerprint; + for (i = 0; i < data_len; i++) { + snprintf(cp, sizeof(fingerprint), "%02X", data[i]); + cp += 2; + + if ((i + 1) % 2 == 0) + snprintf(cp++, sizeof(fingerprint), " "); + + if ((i + 1) % 10 == 0) + snprintf(cp++, sizeof(fingerprint), " "); + } + i--; + if ((i + 1) % 2 == 0) + cp[-2] = 0; + if ((i + 1) % 10 == 0) + cp[-1] = 0; + + return strdup(fingerprint); +}