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

📄 iscsiauthclient.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * iSCSI connection daemon * Copyright (C) 2001 Cisco Systems, Inc. * maintained by linux-iscsi@cisco.com * * 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. * * 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. * * See the file COPYING included with this distribution for more details. * * $Id: iscsiAuthClient.c,v 1.11 2002/09/23 17:46:00 smferris Exp $ *//* * This file implements the iSCSI CHAP authentication method based on * draft-ietf-ips-iscsi-15.txt.  The code in this file is meant * to be platform independent, and makes use of only limited library * functions, presently only string.h.  Platform dependent routines are * defined in iscsiAuthClient.h, but implemented in another file. * * This code in this files assumes a single thread of execution * for each IscsiAuthClient structure, and does no locking. */#include "iscsiAuthClient.h"#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endifstruct iscsiAuthClientKeyInfo_t {	const char *name;};typedef struct iscsiAuthClientKeyInfo_t IscsiAuthClientKeyInfo;IscsiAuthClientGlobalStats iscsiAuthClientGlobalStats;static IscsiAuthClientKeyInfo	iscsiAuthClientKeyInfo[iscsiAuthKeyTypeMaxCount] = {	{"AuthMethod"},	{"CHAP_A"},	{"CHAP_I"},	{"CHAP_C"},	{"CHAP_R"},	{"CHAP_N"}};static const char iscsiAuthClientHexString[] = "0123456789abcdefABCDEF";static const char iscsiAuthClientBase64String[] =	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static const char iscsiAuthClientAuthMethodChapOptionName[] = "CHAP";static intiscsiAuthClientCheckString(const char *s, unsigned int *pLength){	unsigned int length;	if (!s) {		return TRUE;	}	for (length = 0; length < iscsiAuthStringMaxLength; length++) {		if (*s++ == '\0') {			if (pLength) *pLength = length;			return FALSE;		}	}	return TRUE;}static intiscsiAuthClientCheckNodeType(int nodeType){	if (nodeType == iscsiAuthNodeTypeInitiator ||		nodeType == iscsiAuthNodeTypeTarget) {		return FALSE;	}	return TRUE;}static intiscsiAuthClientCheckVersion(int value){	if (value == iscsiAuthVersionDraft8 ||		value == iscsiAuthVersionRfc) {		return FALSE;	}	return TRUE;}static intiscsiAuthClientCheckNegRole(int value){	if (value == iscsiAuthNegRoleOriginator ||		value == iscsiAuthNegRoleResponder) {		return FALSE;	}	return TRUE;}static intiscsiAuthClientCheckAuthMethodOption(int value){	if (value == iscsiAuthOptionNone ||		value == iscsiAuthMethodChap) {		return FALSE;	}	return TRUE;}static const char *iscsiAuthClientAuthMethodOptionToText(IscsiAuthClient *client, int value){	const char *s;	switch (value) {	case iscsiAuthOptionReject:		s = client->rejectOptionName;		break;	case iscsiAuthOptionNone:		s = client->noneOptionName;		break;	case iscsiAuthMethodChap:		s = iscsiAuthClientAuthMethodChapOptionName;		break;	default:		s = NULL;	}	return s;}static intiscsiAuthClientCheckChapAlgorithmOption(int chapAlgorithm){	if (chapAlgorithm == iscsiAuthOptionNone ||		chapAlgorithm == iscsiAuthChapAlgorithmMd5) {		return FALSE;	}	return TRUE;}static voidiscsiAuthClientDataToHex(unsigned char *data, unsigned int length, char *text){	*text++ = '0';	*text++ = 'x';	while (length > 0) {		*text++ = iscsiAuthClientHexString[(*data >> 4) & 0xf];		*text++ = iscsiAuthClientHexString[*data & 0xf];		data++;		length--;	}	*text++ = '\0';}static voidiscsiAuthClientDataToBase64(	unsigned char *data, unsigned int length, char *text){	unsigned long n;	*text++ = '0';	*text++ = 'b';	while (length > 3) {		n = *data++;		n = (n << 8) | *data++;		n = (n << 8) | *data++;		*text++ = iscsiAuthClientBase64String[(n >> 18) & 0x3f];		*text++ = iscsiAuthClientBase64String[(n >> 12) & 0x3f];		*text++ = iscsiAuthClientBase64String[(n >> 6) & 0x3f];		*text++ = iscsiAuthClientBase64String[n & 0x3f];		length -= 3;	}	if (length == 1) {		n = *data++;		n = n << 4;		*text++ = iscsiAuthClientBase64String[(n >> 6) & 0x3f];		*text++ = iscsiAuthClientBase64String[n & 0x3f];		*text++ = '=';		*text++ = '=';	} else if (length == 2) {		n = *data++;		n = (n << 8) | *data++;		n = n << 2;		*text++ = iscsiAuthClientBase64String[(n >> 12) & 0x3f];		*text++ = iscsiAuthClientBase64String[(n >> 6) & 0x3f];		*text++ = iscsiAuthClientBase64String[n & 0x3f];		*text++ = '=';	}	*text++ = '\0';}static voidiscsiAuthClientDataToText(	int base64, unsigned char *data, unsigned int length, char *text){	if (base64) {		iscsiAuthClientDataToBase64(data, length, text);	} else {		iscsiAuthClientDataToHex(data, length, text);	}}static intiscsiAuthClientHexToData(	const char *text, unsigned char *data, unsigned int *dataLength){	char *p;	unsigned int n1;	unsigned int n2;	unsigned int length = 0;	n1 = strlen(text);	if (n1 == 0) return 1; /* error, no data */	if (((n1 + 1) / 2) > *dataLength) {		return 1; /* error, length too long */	}	if ((n1 % 2) == 1) {		p = strchr(iscsiAuthClientHexString, *text++);		if (!p) return 1; /* error, bad character */		n2 = p - iscsiAuthClientHexString;		if (n2 > 15) n2 -= 6;		*data++ = n2;		length++;	}	while (*text != '\0') {		p = strchr(iscsiAuthClientHexString, *text++);		if (!p) return 1; /* error, bad character */		n1 = p - iscsiAuthClientHexString;		if (n1 > 15) n1 -= 6;		if (*text == '\0') return 1; /* error, odd string length */		p = strchr(iscsiAuthClientHexString, *text++);		if (!p) return 1; /* error, bad character */		n2 = p - iscsiAuthClientHexString;		if (n2 > 15) n2 -= 6;		*data++ = (n1 << 4) | n2;		length++;	}	*dataLength = length;	return 0; /* no error */}static intiscsiAuthClientBase64ToData(	const char *text, unsigned char *data, unsigned int *dataLength){	char *p;	unsigned int n1;	unsigned int length = 0;	unsigned int n;	int count;	p = strchr(text, '=');	while (p && *p != '\0') {		if (*p != '=') return 1; /* bad pad character */		*p++ = '\0'; /* delete pad character */	}	n1 = strlen(text);	if (n1 == 0) return 1; /* error, no data */	if (((n1 * 3) / 4) > *dataLength) {		return 1; /* error, length too long */	}	n = 0;	count = 0;	while (*text != '\0') {		p = strchr(iscsiAuthClientBase64String, *text++);		if (!p) return 1; /* error, bad character */		n1 = p - iscsiAuthClientBase64String;		n = (n << 6 | n1);		count++;		if (count >= 4) {			*data++ = n >> 16;			*data++ = n >> 8;			*data++ = n;			length += 3;			n = 0;			count = 0;		}	}	if (count == 0) {		/* do nothing */	} else if (count == 2) {		n = n >> 4;		*data++ = n;		length += 1;	} else if (count == 3) {		n = n >> 2;		*data++ = n >> 8;		*data++ = n;		length += 2;	} else {		return 1; /* bad encoding */	}	*dataLength = length;	return 0; /* no error */}static intiscsiAuthClientTextToData(	const char *text, unsigned char *data, unsigned int *dataLength){	int status;	if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X')) {		/* skip prefix */		text += 2;		status = iscsiAuthClientHexToData(text, data, dataLength);	} else if (text[0] == '0' && (text[1] == 'b' || text[1] == 'B')) {		/* skip prefix */		text += 2;		status = iscsiAuthClientBase64ToData(text, data, dataLength);	} else {		status = 1; /* prefix not recognized. */	}	return status;}static IscsiAuthDebugStatusiscsiAuthClientChapComputeResponse(	IscsiAuthClient *client,	unsigned char *passwordData, unsigned int passwordLength,	unsigned int id,	unsigned char *challengeData, unsigned int challengeLength,	unsigned char *responseData){	unsigned char idData[1];	IscsiAuthMd5Context context;	unsigned char *outData = client->scratchKeyValue;	unsigned int outLength = sizeof(client->scratchKeyValue);	if (!client->passwordPresent) {		return iscsiAuthDebugStatusLocalPasswordNotSet;	}	iscsiAuthMd5Init(&context);	/* id byte */	idData[0] = id;	iscsiAuthMd5Update(&context, idData, 1);	/* decrypt password */	if (iscsiAuthClientData(		outData, &outLength, passwordData, passwordLength)) {		return iscsiAuthDebugStatusPasswordDecryptFailed;	}	if (!client->ipSec && outLength < 12) {		return iscsiAuthDebugStatusPasswordTooShortWithNoIpSec;	}	/* shared secret */	iscsiAuthMd5Update(&context, outData, outLength);	/* clear decrypted password */	memset(outData, 0, sizeof(outData));	/* challenge value */	iscsiAuthMd5Update(&context, challengeData, challengeLength);	iscsiAuthMd5Final(responseData, &context);	return iscsiAuthDebugStatusNotSet; /* no error */}static voidiscsiAuthClientInitKeyBlock(IscsiAuthClientKeyBlock *keyBlock){	memset(keyBlock, 0, sizeof(*keyBlock));}static voidiscsiAuthClientSetKeyValue(	IscsiAuthClientKeyBlock *keyBlock, int keyType, const char *keyValue){	unsigned int length;	if (keyBlock->key[keyType].valueSet) {		keyBlock->duplicateSet = TRUE;		return;	}	keyBlock->key[keyType].valueSet = TRUE;	if (!keyValue) {		return;	}	if (iscsiAuthClientCheckString(keyValue, &length)) {		keyBlock->stringTooLong = TRUE;		return;	}	if ((keyBlock->blockLength + length + 1) > iscsiAuthStringBlockMaxLength) {		keyBlock->tooMuchData = TRUE;		return;	}	keyBlock->key[keyType].value = &keyBlock->block[keyBlock->blockLength];	keyBlock->blockLength += (length + 1);	strcpy(keyBlock->key[keyType].value, keyValue);	keyBlock->key[keyType].present = TRUE;}static const char *iscsiAuthClientGetKeyValue(	IscsiAuthClientKeyBlock *keyBlock, int keyType){	keyBlock->key[keyType].processed = TRUE;	if (!keyBlock->key[keyType].present) {		return NULL;	}	return keyBlock->key[keyType].value;}static voidiscsiAuthClientCheckKey(	IscsiAuthClient *client,	int keyType,	int *negotiatedOption,	unsigned int optionCount,	int *optionList,	const char *(*valueToText)(IscsiAuthClient *, int)){	const char *keyValue;	int length;	unsigned int i;	keyValue = iscsiAuthClientGetKeyValue(&client->recvKeyBlock, keyType);	if (!keyValue) {		*negotiatedOption = iscsiAuthOptionNotPresent;		return;	}	while (*keyValue != '\0') {		length = 0;		while (*keyValue != '\0' && *keyValue != ',') {			client->scratchKeyValue[length++] = *keyValue++;		}		if (*keyValue == ',') keyValue++;		client->scratchKeyValue[length++] = '\0';		for (i = 0; i < optionCount; i++) {			const char *s = (*valueToText)(client, optionList[i]);			if (!s) continue;			if (strcmp(client->scratchKeyValue, s) == 0) {				*negotiatedOption = optionList[i];				return;			}		}	}	*negotiatedOption = iscsiAuthOptionReject;}static voidiscsiAuthClientSetKey(	IscsiAuthClient *client,	int keyType,	unsigned int optionCount,	int *optionList,	const char *(*valueToText)(IscsiAuthClient *, int)){	unsigned int i;	if (optionCount == 0) {		/*		 * No valid options to send, but we always want to		 * send something.		 */		iscsiAuthClientSetKeyValue(			&client->sendKeyBlock, keyType, client->noneOptionName);		return;	}	if (optionCount == 1 && optionList[0] == iscsiAuthOptionNotPresent) {		iscsiAuthClientSetKeyValue(&client->sendKeyBlock, keyType, NULL);		return;	}	for (i = 0; i < optionCount; i++) {		const char *s = (*valueToText)(client, optionList[i]);		if (!s) continue;		if (i == 0) {			strcpy(client->scratchKeyValue, s);		} else {			strcat(client->scratchKeyValue, ",");			strcat(client->scratchKeyValue, s);		}	}	iscsiAuthClientSetKeyValue(		&client->sendKeyBlock, keyType, client->scratchKeyValue);}static voidiscsiAuthClientCheckAuthMethodKey(IscsiAuthClient *client){	iscsiAuthClientCheckKey(		client,		iscsiAuthKeyTypeAuthMethod,		&client->negotiatedAuthMethod,		client->authMethodValidCount,		client->authMethodValidList,		iscsiAuthClientAuthMethodOptionToText);}static voidiscsiAuthClientSetAuthMethodKey(	IscsiAuthClient *client,	unsigned int authMethodCount,	int *authMethodList){	iscsiAuthClientSetKey(		client,		iscsiAuthKeyTypeAuthMethod,		authMethodCount,		authMethodList,		iscsiAuthClientAuthMethodOptionToText);}static voidiscsiAuthClientCheckChapAlgorithmKey(IscsiAuthClient *client){	const char *keyValue;	int length;	unsigned long number;	unsigned int i;	keyValue = iscsiAuthClientGetKeyValue(		&client->recvKeyBlock, iscsiAuthKeyTypeChapAlgorithm);	if (!keyValue) {		client->negotiatedChapAlgorithm = iscsiAuthOptionNotPresent;		return;	}	while (*keyValue != '\0') {

⌨️ 快捷键说明

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