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

📄 chap.c

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 C
字号:
/*	chap/chap.c	vi: set autoindent tabstop=8 shiftwidth=4 :*//*	Copyright (C) 2001-2003 InterOperability Lab (IOL)	University of New Hampshier (UNH)	Durham, NH 03824	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, or (at your option)	any later version.	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	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,	USA.	The name of IOL and/or UNH may not be used to endorse or promote products	derived from this software without specific prior written permission.*/#include <linux/string.h>#include <linux/slab.h>#include <linux/stddef.h>#include "../../common/iscsi_common.h"#include "../../common/debug.h"#include "../../common/my_memory.h"#include "../hash/sha1.h"#include "../hash/md5.h"#include "chap.h"static int hash_algorithms[] = { MD5_ALGORITHM, SHA1_ALGORITHM };voidCHAP_PrintContext(struct CHAP_Context * context){	printk("**************************************************\n");	printk("the current chap context:\n");	// algorithm	printk("hash function :");	switch (context->hash_algorithm) {	case -1:		printk("not defined\n");		break;	case MD5_ALGORITHM:		printk("MD5\n");		break;	case SHA1_ALGORITHM:		printk("SHA1\n");		break;	default:		printk("unknown algorithm\n");		break;	}	// name	printk("name :");	if (context->name == NULL)		printk("not defined\n");	else		printk("%s\n", context->name);	// secret	printk("secret :");	if (context->secret == NULL)		printk("not defined\n");	else		printk("%s\n", context->secret);	printk("identifier :%d\n", context->identifier);	printk("challenge :");	PrintDataUnit(&context->challenge);	printk("response :");	PrintDataUnit(&context->response);}struct CHAP_Context *CHAP_InitializeContext(void){	struct CHAP_Context *context;	context =	    (struct CHAP_Context *) my_kmalloc(sizeof (struct CHAP_Context), 	    	"CHAP context");	if (context == NULL)		return NULL;	/* RDR start */	/* most fields set to 0 or NULL */	memset(context, 0, sizeof (struct CHAP_Context));	/* RDR end */	context->number_format = HEX_FORMAT;	context->hash_algorithm = -1;	return context;}struct CHAP_Context *CHAP_CloneContext(struct CHAP_Context * ctx){	struct CHAP_Context *new_ctx;	int length;	if ((new_ctx = CHAP_InitializeContext()) == NULL)		return NULL;	if (ctx == NULL)		return new_ctx;	new_ctx->number_format = ctx->number_format;	new_ctx->hash_algorithm = ctx->hash_algorithm;	if (ctx->name != NULL) {		length = strlen(ctx->name);		if ((new_ctx->name =		     (char *) my_kmalloc(length + 1, "ctx name")) != NULL) {			/* RDR start */			strcpy(new_ctx->name, ctx->name);			/* RDR end */		}	} else		new_ctx->name = NULL;	if (ctx->secret != NULL) {		length = strlen(ctx->secret);		if ((new_ctx->secret =		     (char *) my_kmalloc(length + 1, "ctx secret")) != NULL) {			/* RDR start */			strcpy(new_ctx->secret, ctx->secret);			/* RDR end */		}	} else		new_ctx->secret = NULL;	new_ctx->challenge.length = ctx->challenge.length;	return new_ctx;}intCHAP_FinalizeContext(struct CHAP_Context * context){	if (context != NULL) {		my_kfree((void **) &context->challenge.data, "challenge data");		my_kfree((void **) &context->response.data, "response data");		my_kfree((void **) &context->name, "name");		my_kfree((void **) &context->secret, "secret");		my_kfree((void **) &context, "CHAP context");	}	return 1;}intCHAP_SetNumberFormat(int format,struct CHAP_Context * context){	if (context == NULL)		return 0;	if ((format == HEX_FORMAT) || (format == BASE64_FORMAT)) {		context->number_format = format;		return 1;	} else		return 0;}intCHAP_SetChallengeLength(int clength,struct CHAP_Context * context){	if (context == NULL)		return 0;	if (clength > 0) {		context->challenge.length = clength;		return 1;	} else		return 0;}/*	Searches built-in "hash_algorithms[]" table to find "algorithm". *	If found, sets value in "hash_algorithm" field of  * 	"context" and returns 1. *	If not found, returns 0. */intCHAP_SetAlgorithm(int algorithm,struct CHAP_Context * context){	int i;	if (context == NULL)		return 0;	for (i = 0; i < NUMBER_OF_ALGORITHMS; i++) {		if (algorithm == hash_algorithms[i]) {			context->hash_algorithm = algorithm;			return 1;		}	}	return 0;}intCHAP_SetName(char *name,struct CHAP_Context * context){	int length;	if (context == NULL)		return 0;	if (name == NULL)		return 0;	my_kfree((void **) &context->name, "CHAP Set Name");	length = strlen(name);	context->name = (char *) my_kmalloc(length + 1, "CHAP Set Name");	if (context->name == NULL)		return 0;	strcpy(context->name, name);	return 1;}char *CHAP_GetName(struct CHAP_Context * context){	char *name;	int len;	if (context == NULL || context->name == NULL)		return NULL;	len = strlen(context->name);	if ((name = (char *) my_kmalloc(len + 1, "CHAP Get Name")) == NULL)		return NULL;	strcpy(name, context->name);	return name;}intCHAP_SetSecret(char *secret,struct CHAP_Context * context){	int length;	if (context == NULL)		return 0;	if (secret == NULL)		return 0;	my_kfree((void **) &context->secret, "CHAP Secret");	length = strlen(secret);	context->secret = (char *) my_kmalloc(length + 1, "CHAP Secret");	if (context->secret == NULL)		return 0;	strcpy(context->secret, secret);	return 1;}intCHAP_SetIdentifier(unsigned char identifier,struct CHAP_Context * context){	if (context == NULL)		return 0;	context->identifier = identifier;	return 1;}unsigned charCHAP_GetIdentifier(struct CHAP_Context * context){	if (context == NULL)		return 0;	RandomNumberGenerate(&context->identifier, 1);	return context->identifier;}char *CHAP_GetChallenge(struct CHAP_Context * context){	char *temp;	int length = 0;	if ((context == NULL) || (context->challenge.length == 0))		return NULL;	context->challenge.data = (char *)	    my_kmalloc(context->challenge.length, "CHAP challenge data");	if (context->challenge.data == NULL)		return NULL;	RandomNumberGenerate(context->challenge.data,			     context->challenge.length);	length =	    IntegerToStringLength(context->challenge.length,				  context->number_format);	temp = (char *) my_kmalloc(length, "CHAP Challenge");	if (temp == NULL)		return NULL;	IntegerToString(context->challenge.data,			context->challenge.length, temp,			context->number_format);	return temp;}/*	 * generates a hash response to "challenge" using "identifier" and the * secret in "context".  The result is stored in dynamically malloced * space, and is a printable string in either hex or base64, depending * on the format in the "context".  The algorithm used also is in the * "context".*/char *CHAP_GetResponse(unsigned char identifier,		 char *challenge,		 int max_challenge_length,struct CHAP_Context * context){	int length;	char *temp;	char *response_data;	int hashlen;	int secretlen;	if (context == NULL)		return NULL;	if (context->secret == NULL)		return NULL;	if (challenge == NULL)		return NULL;	TRACE(TRACE_DEBUG, "CHAP_GetResponse number format %s\n",	      context->number_format == BASE64_FORMAT ? "BASE64" :	      context->number_format == HEX_FORMAT ? "HEX" : "Unknown");	length = StringToIntegerLength(challenge);	if (length > max_challenge_length) {		TRACE_ERROR("CHAP_C binary length is %d, limit is %d\n", length,			    max_challenge_length);		return NULL;	}	secretlen = strlen(context->secret);	length += 1 + secretlen;	temp = (char *) my_kmalloc(length, "temp");	if (temp == NULL)		return NULL;	temp[0] = identifier;	memcpy(temp + 1, context->secret, secretlen);	StringToInteger(challenge, temp + 1 + secretlen);	if (context->hash_algorithm == MD5_ALGORITHM) {		hashlen = 16;		response_data = (char *) my_kmalloc(hashlen, "response data");		if (response_data == NULL) {			my_kfree((void **) &temp, "temp");			return NULL;		}		MD5_ProcessMessage(temp, 0, length * 8, response_data);	} else if (context->hash_algorithm == SHA1_ALGORITHM) {		hashlen = 20;		response_data = (char *) my_kmalloc(hashlen, "response data");		if (response_data == NULL) {			my_kfree((void **) &temp, "temp");			return NULL;		}		SHA1_ProcessMessage(temp, 0, length * 8, response_data);	} else {		my_kfree((void **) &temp, "temp");		return NULL;	}	my_kfree((void **) &temp, "temp");	length = IntegerToStringLength(hashlen, context->number_format);	temp = (char *) my_kmalloc(length, "CHAP Response");	if (temp != NULL) {		IntegerToString(response_data, hashlen, temp,				context->number_format);	}	my_kfree((void **) &response_data, "response data");	return temp;}/*	 * called to check a received "response" from a previous challenge in this * context". * Returns 1 if response is correct; else 0*/intCHAP_CheckResponse(char *response, int max_response_length,		  struct CHAP_Context * context){	/* RDR start */	int retval;	/* RDR end */	int length;	char *temp;	char *response_data;	int hashlen;	int secretlen;	/* RDR start **	   MD5_Context * md5ctx;	   SHA1_Context * sha1ctx;	   ** RDR end */	if (context == NULL)		return 0;	if (response == NULL)		return 0;	/*      check to be sure a challenge was previously generated */	if ((context->challenge.length == 0) ||	    (context->challenge.data == NULL) || (context->secret == NULL))		return 0;	secretlen = strlen(context->secret);	length = 1 + secretlen + context->challenge.length;	temp = (char *) my_kmalloc(length, "temp");	if (temp == NULL)		return 0;	temp[0] = context->identifier;	memcpy(temp + 1, context->secret, secretlen);	memcpy(temp + 1 + secretlen,	       context->challenge.data, context->challenge.length);	if (context->hash_algorithm == MD5_ALGORITHM) {		hashlen = 16;		response_data = (char *) my_kmalloc(hashlen, "response data");		if (response_data == NULL) {			my_kfree((void **) &temp, "temp");			return 0;		}		/* RDR start **		   md5ctx = MD5_InitializeContext();		   ** RDR end */		MD5_ProcessMessage(temp, 0, length * 8, response_data);	} else if (context->hash_algorithm == SHA1_ALGORITHM) {		hashlen = 20;		response_data = (char *) my_kmalloc(hashlen, "response data");		if (response_data == NULL) {			my_kfree((void **) &temp, "temp");			return 0;		}		/* RDR start **		   sha1ctx = SHA1_InitializeContext();		   ** RDR end */		SHA1_ProcessMessage(temp, 0, length * 8, response_data);	} else {		my_kfree((void **) &temp, "temp");		return 0;	}	my_kfree((void **) &temp, "temp");	length = StringToIntegerLength(response);	if (length > max_response_length) {		TRACE_ERROR("CHAP_R binary length is %d, limit is %d\n", length,			    max_response_length);		my_kfree((void **) &response_data, "response data");		return 0;	}	temp = (char *) my_kmalloc(length, "temp");	if (temp == NULL) {		my_kfree((void **) &response_data, "response data");		return 0;	}	StringToInteger(response, temp);	retval = IntegerCompare(response_data, hashlen, temp, length);	my_kfree((void **) &response_data, "response data");	my_kfree((void **) &temp, "temp");	return retval;}/*	* called to check a received "challenge" to see if it duplicates a previous* challenge in this "context".* Returns 1 if challenge is not a duplicate; else 0 on duplicate or error.*/intCHAP_CheckChallenge(char *challenge,struct CHAP_Context * context){	int retval;	int length;	char *temp;	if (context == NULL)		return 0;	if (challenge == NULL)		return 0;	/*      check to be sure a challenge was previously generated */	if ((context->challenge.length == 0) ||	    (context->challenge.data == NULL) || (context->secret == NULL))		return 0;	length = StringToIntegerLength(challenge);	temp = (char *) my_kmalloc(length, "temp");	if (temp == NULL) {		return 0;	}	StringToInteger(challenge, temp);	retval =	    !IntegerCompare(context->challenge.data, context->challenge.length,			    temp, length);	my_kfree((void **) &temp, "temp");	return retval;}/*	Searches "list" to find first algorithm number we support.	If found, return than number.	If not found, return -1.*/intCHAP_SelectAlgorithm(char *list){	int i, n;	char *comma, *ptr;	if (list == NULL)		return -1;	while (*list != '\0') {			/* find next comma-terminated item in remaining list */		comma = strchr(list, ',');		if (comma != NULL) {			/* replace ',' with nul to isolate item */			*comma++ = '\0';			}		/* convert the isolated item to a number */		n = simple_strtoul(list, &ptr, 0);		if (*ptr == '\0') {			/* this algorithm number has correct 			 * format, search table of			 * known hash algorithms 			 */			for (i = 0; i < NUMBER_OF_ALGORITHMS; i++) {				if (n == hash_algorithms[i]) {					/* found a matching algorithm 					 * number, accept it 					 */					return n;				}			}		}		/* if loop finishes, we do not support this algorithm number */		if (comma != NULL)			list = comma;		else			break;	}	/*      if loop ends, did not find any algorithms we like in list */	return -1;}/*	 * Builds list of available CHAP hash algorithms as a character string *starting at "list".  Returns strlen(final list).*/intCHAP_GetAlgorithmList(char *list){	int i;	char *base;	if ((base = list) == NULL)		return 0;	for (i = 0; i < NUMBER_OF_ALGORITHMS; i++) {		if (i != 0)			*list++ = ',';		list += sprintf(list, "%d", hash_algorithms[i]);	}	return list - base;}

⌨️ 快捷键说明

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