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

📄 auth.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: auth.c,v 1.20 2001/08/03 22:34:09 jm Exp $ * Message Authentication Routines * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */#include <stdlib.h>#include <string.h>#include <assert.h>#include "md5_mac.h"#include "sha1.h"#include "debug.h"#include "util.h"#include "auth.h"#define DEBUG_FLAG 'U'/* #define AUTH_EXTRA_DEBUG *//* RFC 2002, sec. 3.5.1. * MAC protects UDP payload (reg. req or reg. reply), * all prior extension, and Type and Length of this auth. extension * * draft-ietf-mobileip-v2-00.txt adds SPI field of the extension to the * protected area and this is used as a default in our implementation. * There is an automatic fallback to use the RFC 2002 method to provide * compatibility with other implementations. * * Note: data pointer should be to the beginning of the registration * request or reply and auth pointer must be in the same message buffer * (i.e. just after the data to be protected) */#ifdef AUTH_EXTRA_DEBUGstatic void show_hex(unsigned char *data, int len){	int i;	for (i = 0; i < len; i++)		DEBUG(DEBUG_FLAG, "%02x", data[i]);}#endiftypedef void (*MACfunc)(unsigned char *key, unsigned int key_len,			unsigned char *data, unsigned int data_len,			unsigned char *mac);static MACfunc auth_get_mac_data(int alg, int *mac_len){	if (alg == AUTH_ALG_MD5 || alg == AUTH_ALG_MD5_RFC2002 ||	    alg == AUTH_ALG_MD5_PREFIX_SUFFIX) {		*mac_len = MD5_MAC_LEN;		return md5_mac;	} else if (alg == AUTH_ALG_HMAC_MD5) {		*mac_len = MD5_MAC_LEN;		return hmac_md5;	} else if (alg == AUTH_ALG_SHA1) {		*mac_len = SHA1_MAC_LEN;		return sha1_mac;	} else if (alg == AUTH_ALG_HMAC_SHA1) {		*mac_len = SHA1_MAC_LEN;		return hmac_sha1;	}	return NULL;}/* Add an authentication extension to a message and return the length of the * added authentication extension. * Parameter spi must be in network byte order. */int auth_add(int alg, unsigned char *key, unsigned int keylen,	     unsigned char *data, struct msg_auth *auth,	     __u8 auth_type, __u32 spi){	int len;	int mac_len;	MACfunc mac_func;	auth->type = auth_type;	auth->spi = spi;	mac_func = auth_get_mac_data(alg, &mac_len);	if (mac_func != NULL) {		auth->length = mac_len + SPI_LEN;		len = ((unsigned char *)auth) - data +			(alg == AUTH_ALG_MD5_RFC2002 ? 2 : 6);		mac_func(key, keylen, data, len, MSG_AUTH_DATA(auth));	} else {		DEBUG(DEBUG_FLAG, "auth_add: unknown algorithm %i\n", alg);		auth->length = SPI_LEN;		mac_len = 0;	}#ifdef AUTH_EXTRA_DEBUG	DEBUG(DEBUG_FLAG, "auth_add: len=%i, mac=", len);	show_hex(MSG_AUTH_DATA(auth), mac_len);	DEBUG(DEBUG_FLAG, "\n");#endif	return GET_AUTH_EXT_LEN(auth);}/* returns zero on failure and nonzero on successful authentication check */int auth_check(int alg, unsigned char *key, unsigned int keylen,	       unsigned char *data, struct msg_auth *auth){	int len, ret;	unsigned char *mac;	int mac_len;	MACfunc mac_func;	mac_func = auth_get_mac_data(alg, &mac_len);	if (mac_func == NULL) {		DEBUG(DEBUG_FLAG, "auth_check: unknown algorithm %i\n", alg);		return 0;	}	mac = (unsigned char *) malloc(mac_len);	if (mac == NULL) {		DEBUG(DEBUG_FLAG, "auth_check: malloc(%i) failed\n", mac_len);		return 0;	}	if (auth->length != mac_len + SPI_LEN) {		DEBUG(DEBUG_FLAG, "auth_check: len=%i != %i\n",		      auth->length, mac_len + SPI_LEN);		return 0;	}	len = ((unsigned char *)auth) - data +		(alg == AUTH_ALG_MD5_RFC2002 ? 2 : 6);	mac_func(key, keylen, data, len, mac);#ifdef AUTH_EXTRA_DEBUG	DEBUG(DEBUG_FLAG, "auth_check: len=%i, recvMAC=", len);	show_hex(MSG_AUTH_DATA(auth), mac_len);	DEBUG(DEBUG_FLAG, ", expMAC=");	show_hex(mac, mac_len);	DEBUG(DEBUG_FLAG, "\n");#endif	ret = memcmp(mac, MSG_AUTH_DATA(auth), mac_len) == 0;	free(mac);	return ret;}int auth_add_vendor(int alg, unsigned char *key, unsigned int keylen,		    unsigned char *data, struct vendor_msg_auth *auth,		    __u16 auth_type, __u32 spi){	int len;	int mac_len;	MACfunc mac_func;	auth->type = VENDOR_EXT_TYPE2;	auth->reserved = 0;	auth->vendor_id = htonl(VENDOR_ID_DYNAMICS);	auth->sub_type = htons(auth_type);	auth->spi = spi;	mac_func = auth_get_mac_data(alg, &mac_len);	if (mac_func != NULL) {		auth->length = mac_len + MIN_VENDOR_AUTH_LEN;		len = ((unsigned char *)auth) - data +			sizeof(struct vendor_msg_auth);		mac_func(key, keylen, data, len, MSG_VENDOR_AUTH_DATA(auth));	} else {		DEBUG(DEBUG_FLAG, "auth_add_vendor: unknown algorithm %i\n",		      alg);		auth->length = MIN_VENDOR_AUTH_LEN;		mac_len = 0;	}#ifdef AUTH_EXTRA_DEBUG	DEBUG(DEBUG_FLAG, "auth_add_vendor: len=%i, mac=", len);	show_hex(MSG_VENDOR_AUTH_DATA(auth), mac_len);	DEBUG(DEBUG_FLAG, "\n");#endif	return GET_VENDOR_AUTH_EXT_LEN(auth);}int auth_check_vendor(int alg, unsigned char *key, unsigned int keylen,		      unsigned char *data, struct vendor_msg_auth *auth){	int len, ret;	unsigned char *mac;	int mac_len;	MACfunc mac_func;	mac_func = auth_get_mac_data(alg, &mac_len);	if (mac_func == NULL) {		DEBUG(DEBUG_FLAG, "auth_check_vendor: unknown algorithm %i\n",		      alg);		return 0;	}	mac = (unsigned char *) malloc(mac_len);	if (mac == NULL) {		DEBUG(DEBUG_FLAG, "auth_check_vendor: malloc(%i) failed\n",		      mac_len);		return 0;	}	if (auth->length != mac_len + MIN_VENDOR_AUTH_LEN) {		DEBUG(DEBUG_FLAG, "auth_check_vendor: len=%i != %i\n",		      auth->length, mac_len + MIN_VENDOR_AUTH_LEN);		return 0;	}	len = ((unsigned char *)auth) - data +		sizeof(struct vendor_msg_auth);	mac_func(key, keylen, data, len, mac);#ifdef AUTH_EXTRA_DEBUG	DEBUG(DEBUG_FLAG, "auth_check_vendor: len=%i, recvMAC=", len);	show_hex(MSG_VENDOR_AUTH_DATA(auth), mac_len);	DEBUG(DEBUG_FLAG, ", expMAC=");	show_hex(mac, mac_len);	DEBUG(DEBUG_FLAG, "\n");#endif	ret = memcmp(mac, MSG_VENDOR_AUTH_DATA(auth), mac_len) == 0;	free(mac);	return ret;}/* Add a generalized authentication extension into the message and return the * length of the added authentication extension. * Parameter spi must be in network byte order. */int auth_add_gen(int alg, unsigned char *key, unsigned int keylen,		 unsigned char *data, unsigned char *challenge,		 int challenge_len, struct generalized_auth_ext *auth,		 __u8 auth_subtype, __u32 spi){	int len;	int mac_len;	MACfunc mac_func;	auth->type = GENERALIZED_AUTH_EXT;	auth->subtype = auth_subtype;	auth->spi = spi;	if (alg == AUTH_ALG_RADIUS) {		unsigned char tmp[MD5_MAC_LEN];		MD5_CTX context;		auth->length = htons(MD5_MAC_LEN + SPI_LEN);		MD5Init(&context);		len = ((unsigned char *) auth) - data + 8;		MD5Update(&context, data, len);		MD5Final(tmp, &context);		if (challenge_len > 0)			MD5Update(&context, challenge, 1);		MD5Update(&context, key, keylen);		MD5Update(&context, tmp, MD5_MAC_LEN);		if (challenge_len > 1)			MD5Update(&context, challenge + 1, challenge_len - 1);		MD5Final(MSG_GEN_AUTH_DATA(auth), &context);	} else {		mac_func = auth_get_mac_data(alg, &mac_len);		if (mac_func != NULL) {			auth->length = htons(mac_len + SPI_LEN);			len = ((unsigned char *) auth) - data + 8;			mac_func(key, keylen, data, len,				 MSG_GEN_AUTH_DATA(auth));		} else {			DEBUG(DEBUG_FLAG, "auth_add_gen: unknown algorithm %i"			      "\n", alg);			auth->length = htons(SPI_LEN);		}	}	return GET_GEN_AUTH_EXT_LEN(auth);}int auth_check_gen(int alg, unsigned char *key, unsigned int keylen,		   unsigned char *data, struct generalized_auth_ext *auth){	int len, ret;	unsigned char *mac;	int mac_len;	MACfunc mac_func;	/* FIX: add support for AUTH_ALG_RADIUS as a special case like with	 * auth_add_gen() above (?) */	mac_func = auth_get_mac_data(alg, &mac_len);	if (mac_func == NULL) {

⌨️ 快捷键说明

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