⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 MSyslog是一个允许在Linux下运行的网络系统日志程序
💻 C
字号:
/*	$CoreSDI: hash.c,v 1.43 2001/04/05 20:56:26 alejo Exp $	*/ /* * Copyright (c) 2001, Core SDI S.A., Argentina * All rights reserved *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither name of the Core SDI S.A. nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* * hash -- few things used by both peo output module and peochk  * * Author: Claudio Castiglia * */#include "config.h"#include <sys/types.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <stdio.h>#include <stdlib.h>#include <strings.h>   /* some OSs have strcasecmp here */#include <string.h>#include <unistd.h>#ifdef HAVE_MD5_H#include <md5.h>#else#include "md5.h"#endif#ifdef HAVE_RMD160_H#include <rmd160.h>#else#include "rmd160.h"#endif#ifdef HAVE_SHA1_H#include <sha1.h>#else#include "sha1.h"#endif#include "hash.h"#ifdef HAVE_SRANDOM	#define RANDOM_DEVICE	"/dev/srandom"#else	#define RANDOM_DEVICE	"/dev/random"#endifchar *default_keyfile = "/var/ssyslog/.var.log.messages.key";char *hmstr[] = { /* enum order */	"md5",	"rmd160",	"sha1"};typedef union {	MD5_CTX 	md5;	RMD160_CTX	rmd160;	SHA1_CTX	sha1;} HASH_CTX;/* * mac: *	method:		hash method to use (see enum, gethash(..) output) *	data1:		buffer 1 (commonly a key[i]) *	data1len:	data1 lenght *	data2:		buffer 2 (commonly a message) *	data2len:	data2 lenght *	dest:		destination buffer * *	Fills dest with a key and returns dest lenght *	dest should have enough space. *	On error returns -1 */intmac(int method, const unsigned char *data1, unsigned int data1len,    const unsigned char *data2, unsigned int data2len, unsigned char *dest){	HASH_CTX	 ctx;	int	 	 i, destlen, tmplen;	unsigned char	*tmp;	/* Calculate tmp buffer lenght */	tmplen = 0;	if (data1len && data2len) {		if (data1len > data2len) {			tmplen = data1len / data2len * data2len;			tmplen += (tmplen < data1len) ? data2len : 0;		} else if (data1len < data2len) {			tmplen = data2len / data1len * data1len;			tmplen += (tmplen < data2len) ? data1len : 0;		} else tmplen = data1len;	} else {		tmplen = (data1len) ? data1len : data2len;		if (!tmplen)			tmplen = 1; 	}		/* Allocate needed memory and clear tmp buffer */	if ( (tmp = (unsigned char *) calloc(1, tmplen)) == NULL)		return (-1);	/* tmp = data1 xor data2 */	if (data1len && data2len)		for (i = 0; i < tmplen; i++)			tmp[i] = data1[i % data1len] ^ data2[i % data2len];	else if (data1len)		memcpy(tmp, data1, tmplen);	else		memcpy(tmp, data2, tmplen);	/* dest = hash(tmp) */	switch(method) {	case MD5:		MD5Init(&ctx.md5);		MD5Update(&ctx.md5, tmp, tmplen);		MD5Final(dest, &ctx.md5);		destlen = 16;		break;	case RMD160:		RMD160Init(&ctx.rmd160);		RMD160Update(&ctx.rmd160, tmp, tmplen);		RMD160Final(dest, &ctx.rmd160);		destlen = 20;		break;	case SHA1:	default:		SHA1Init(&ctx.sha1);		SHA1Update(&ctx.sha1, tmp, tmplen);		SHA1Final(dest, &ctx.sha1);		destlen = 20;		break;	}			free(tmp);	return (destlen);}/* * mac2: *	data1:		buffer 1 (commonly key[i]) *	data1len:	data1 lenght *	data2:		buffer 2 (commonly message) *	data2len:	data2 lenght *	dest:		destination buffer (commonly key[i+1]) * *	Fills dest with a digest and returns dest lenght *	dest should have enough space. *	On error returns -1 */intmac2(const unsigned char *data1, int data1len, const unsigned char *data2,     int data2len, unsigned char *dest){	int destlen;	destlen = mac(SHA1, data1, data1len, data2, data2len, dest);	if (destlen != -1)		destlen = mac(RMD160, dest, destlen, data2, data2len, dest);	return (destlen);}/* * gethash: *	Converts method string to method number. *	The string should be one of those specified in hmstr declaration, *	otherwise -1 is returned. *	Case is ignored. */intgethash(const char *str){	int i;	for (i = 0; i < LAST_HASH; i++)		if (!strcasecmp(str, hmstr[i]))			return (i);	return (-1);}/* * strdot: * 	Receives something like this: /a/b/c/d/e *	and chages it to something like this: .a.b.c.d.e */char *strdot(char *s){	char *b;	if ( (b = s) != NULL)		while ( (b = strchr(b, '/')) != NULL)			*b = '.';	return (s);}/* * strallocat: *	Concatenates two strings and returns a pointer to the new string *	The new buffer should be freed using free(3) */char *strallocat(const char *s1, const char *s2){	char *dest;	int   size;	size = strlen(s1) + strlen(s2) + 1;	if ( (dest = (char *) calloc(1, size)) != NULL)		snprintf(dest, size, "%s%s", (s1 != NULL) ? s1 : "",		    (s2 != NULL) ? s2 : "");	return (dest);}/* * strmac */char *strmac(const char *s){	return (strallocat(s, ".mac"));}/* * strkey0 */char *strkey0(const char *s){	return (strallocat(s, "0"));}/* * strrealpath */char *strrealpath(const char *path){	char *resolved;	if ( (resolved = (char *) calloc(1, PATH_MAX)) != NULL)		return (realpath(path, resolved));	return (NULL);}/* * asc2bin: *	Translates an hex string to binary. *	Buffer lenght = string lenght / 2 *	(Ex.: 2 byte string "ab" is translated to byte 0xab) */#define ASC2BIN(x)	((x <= '9') ? x - '0' : x - 'a' + 10)unsigned char *asc2bin(unsigned char *dst, const unsigned char *src){	int   		 i;	int   		 j;	unsigned char	*tmp;	if (src == NULL || dst == NULL || (strlen((char *) src) & 1))		return (NULL);	if (dst == src) {		if ( (tmp = (unsigned char *) strdup((char *) src)) == NULL)			return (NULL);	} else		tmp = (unsigned char *) src;	for (j = i = 0; tmp[i] != '\0'; i += 2, j++)		dst[j] = (ASC2BIN(tmp[i]) << 4) | ASC2BIN(tmp[i + 1]);	if (dst == src)		free(tmp);	return (dst);}/* * bin2asc: *	Translates a binary buffer to string *	Based on XXXEnd function *	(2 byte buffer 0x3, 0x9a is translated to 4 byte string "039a") */char hex[] = { "0123456789abcdef" };unsigned char *bin2asc(unsigned char *dst, const unsigned char *src, int srclen){	int i;	if (dst == NULL || src == NULL)		return (NULL);    	for (i = 0; i < srclen; i++) {        	dst[i + i] = hex[src[i] >> 4];        	dst[i + i + 1] = hex[src[i] & 0x0f];    	}    	dst[i + i] = '\0';	return (dst);}/* * getrandom: *	Open RANDOM_DEVICE and reads len bytes random values. *	Returns 0 on success and -1 on error */intgetrandom(unsigned char *buffer, int bytes){	int fd;	if ( (fd = open(RANDOM_DEVICE, O_RDONLY, 0)) >= 0) {		if (read(fd, buffer, bytes) == bytes)			bytes = 0;		else			bytes = -1;		close(fd);		return (bytes);	}	return (-1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -