X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcutil.c;h=c3af592539a49d72b430f572c80cea7b40e4b307;hp=c61e70ce4836026c38789cdefc2250c1f192ee53;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hpb=2dc218143c7859f7529396dc121ae08e2fd78da0 diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index c61e70ce..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,157 +24,6 @@ #include "silcincludes.h" -/* Opens a file indicated by the filename `filename' with flags indicated - by the `flags'. */ - -int silc_file_open(const char *filename, int flags) -{ - int fd; - - fd = open(filename, flags, 0600); - - return fd; -} - -/* Reads data from file descriptor `fd' to `buf'. */ - -int silc_file_read(int fd, unsigned char *buf, uint32 buf_len) -{ - return read(fd, (void *)buf, buf_len); -} - -/* Writes `buffer' of length of `len' to file descriptor `fd. */ - -int silc_file_write(int fd, const char *buffer, uint32 len) -{ - return write(fd, (const void *)buffer, len); -} - -/* Closes file descriptor */ - -int silc_file_close(int fd) -{ - return close(fd); -} - -/* Writes a buffer to the file. */ - -int silc_file_writefile(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_writefile_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; -} - -/* 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_readfile(const char *filename, uint32 *return_len) -{ - int fd; - char *buffer; - int filelen; - - fd = silc_file_open(filename, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) - return NULL; - 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; -} - -/* Returns files size. Returns 0 on error. */ - -uint64 silc_file_size(const char *filename) -{ - int ret; - struct stat stats; - -#ifndef SILC_WIN32 - ret = lstat(filename, &stats); -#else - ret = stat(filename, &stats); -#endif - if (ret < 0) - return 0; - - return (uint64)stats.st_size; -} - /* 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. */ @@ -264,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; @@ -312,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); @@ -341,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]; @@ -412,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, "@"); @@ -444,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; @@ -529,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]; @@ -539,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)); } @@ -560,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)); } @@ -582,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)); } @@ -611,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; @@ -680,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); @@ -699,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 @@ -772,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; @@ -798,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)); @@ -815,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]; @@ -867,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]; @@ -887,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]; @@ -904,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); +}