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

📄 chap.c

📁 iscsi企业级target.很好用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * chap.c - support for (mutual) CHAP authentication. * (C) 2004 Xiranet Communications GmbH <arne.redlich@xiranet.com> * available under the terms of the GNU GPL v2.0 * * heavily based on code from iscsid.c: *   Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>, *   licensed under the terms of the GNU GPL v2.0, * * and code taken from UNH iSCSI software: *   Copyright (C) 2001-2003 InterOperability Lab (IOL) *   University of New Hampshire (UNH) *   Durham, NH 03824 *   licensed under the terms of the GNU GPL v2.0 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/sha.h>#include <openssl/md5.h>#include "iscsid.h"#define HEX_FORMAT    0x01#define BASE64_FORMAT 0x02#define CHAP_DIGEST_ALG_MD5   5#define CHAP_DIGEST_ALG_SHA1  7#define CHAP_MD5_DIGEST_LEN  16#define CHAP_SHA1_DIGEST_LEN 20#define CHAP_INITIATOR_ERROR -1#define CHAP_AUTH_ERROR      -2#define CHAP_TARGET_ERROR    -3#define CHAP_AUTH_STATE_START     AUTH_STATE_START#define CHAP_AUTH_STATE_CHALLENGE 1#define CHAP_AUTH_STATE_RESPONSE  2#define CHAP_INITIATOR_AUTH 0#define CHAP_TARGET_AUTH    1#define CHAP_CHALLENGE_MAX	50static inline int decode_hex_digit(char c){	switch (c) {	case '0' ... '9':		return c - '0';	case 'a' ... 'f':		return c - 'a' + 10;	case 'A' ... 'F':		return c - 'A' + 10;	}	return 0;}static void decode_hex_string(char *hex_string, u8 *intnum, int intlen){	char *ptr;	int j;	j = strlen(hex_string);	ptr = hex_string + j;	j = --intlen;	do {		intnum[j] = decode_hex_digit(*--ptr);		intnum[j] |= decode_hex_digit(*--ptr) << 4;		j--;	} while (ptr > hex_string);	while (j >= 0)		intnum[j--] = 0;}/* Base64 decoding, taken from UNH-iSCSI "Base64codeToNumber()" */static u8 decode_base64_digit(char base64){	switch (base64) {	case '=':		return 64;	case '/':		return 63;	case '+':		return 62;	default:		if ((base64 >= 'A') && (base64 <= 'Z'))			return base64 - 'A';		else if ((base64 >= 'a') && (base64 <= 'z'))			return 26 + (base64 - 'a');		else if ((base64 >= '0') && (base64 <= '9'))			return 52 + (base64 - '0');		else			return -1;	}}/* Base64 decoding, taken from UNH-iSCSI "Base64StringToInteger()" */static void decode_base64_string(char *string, u8 *intnum, int int_len){	int len;	int count;	int intptr;	u8 num[4];	int octets;	if ((string == NULL) || (intnum == NULL))		return;	len = strlen(string);	if (len == 0)		return;	if ((len % 4) != 0)		return;	count = 0;	intptr = 0;	while (count < len - 4) {		num[0] = decode_base64_digit(string[count]);		num[1] = decode_base64_digit(string[count + 1]);		num[2] = decode_base64_digit(string[count + 2]);		num[3] = decode_base64_digit(string[count + 3]);		if ((num[0] == 65) || (num[1] == 65) || (num[2] == 65) || (num[3] == 65))			return;		count += 4;		octets =		    (num[0] << 18) | (num[1] << 12) | (num[2] << 6) | num[3];		intnum[intptr] = (octets & 0xFF0000) >> 16;		intnum[intptr + 1] = (octets & 0x00FF00) >> 8;		intnum[intptr + 2] = octets & 0x0000FF;		intptr += 3;	}	num[0] = decode_base64_digit(string[count]);	num[1] = decode_base64_digit(string[count + 1]);	num[2] = decode_base64_digit(string[count + 2]);	num[3] = decode_base64_digit(string[count + 3]);	if ((num[0] == 64) || (num[1] == 64))		return;	if (num[2] == 64) {		if (num[3] != 64)			return;		intnum[intptr] = (num[0] << 2) | (num[1] >> 4);	} else if (num[3] == 64) {		intnum[intptr] = (num[0] << 2) | (num[1] >> 4);		intnum[intptr + 1] = (num[1] << 4) | (num[2] >> 2);	} else {		octets =		    (num[0] << 18) | (num[1] << 12) | (num[2] << 6) | num[3];		intnum[intptr] = (octets & 0xFF0000) >> 16;		intnum[intptr + 1] = (octets & 0x00FF00) >> 8;		intnum[intptr + 2] = octets & 0x0000FF;	}}static inline void encode_hex_string(u8 *intnum, long length, char *string){	int i;	char *strptr;	strptr = string;	for (i = 0; i < length; i++, strptr += 2)			sprintf(strptr, "%.2hhx", intnum[i]);}/* Base64 encoding, taken from UNH iSCSI "IntegerToBase64String()" */static void encode_base64_string(u8 *intnum, long length, char *string){	int count, octets, strptr, delta;	static const char base64code[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G',					   'H', 'I', 'J', 'K', 'L', 'M', 'N',					   'O', 'P', 'Q', 'R', 'S', 'T', 'U',					   'V', 'W', 'X', 'Y', 'Z', 'a', 'b',					   'c', 'd', 'e', 'f', 'g', 'h', 'i',					   'j', 'k', 'l', 'm', 'n', 'o', 'p',					   'q', 'r', 's', 't', 'u', 'v', 'w',					   'x', 'y', 'z', '0', '1', '2', '3',					   '4', '5', '6', '7', '8', '9', '+',					   '/', '=' };	if ((!intnum) || (!string) || (!length))		return;	count = 0;	octets = 0;	strptr = 0;	while ((delta = (length - count)) > 2) {		octets = (intnum[count] << 16) | (intnum[count + 1] << 8) | intnum[count + 2];		string[strptr] = base64code[(octets & 0xfc0000) >> 18];		string[strptr + 1] = base64code[(octets & 0x03f000) >> 12];		string[strptr + 2] = base64code[(octets & 0x000fc0) >> 6];		string[strptr + 3] = base64code[octets & 0x00003f];		count += 3;		strptr += 4;	}	if (delta == 1) {		string[strptr] = base64code[(intnum[count] & 0xfc) >> 2];		string[strptr + 1] = base64code[(intnum[count] & 0x03) << 4];		string[strptr + 2] = base64code[64];		string[strptr + 3] = base64code[64];		strptr += 4;	} else if (delta == 2) {		string[strptr] = base64code[(intnum[count] & 0xfc) >> 2];		string[strptr + 1] = base64code[((intnum[count] & 0x03) << 4) | ((intnum[count + 1] & 0xf0) >> 4)];		string[strptr + 2] = base64code[(intnum[count + 1] & 0x0f) << 2];		string[strptr + 3] = base64code[64];		strptr += 4;	}	string[strptr] = '\0';}static inline int chap_check_encoding_format(char *encoded){	int encoding_fmt;	if (!encoded)		return -1;	if ((strlen(encoded) < 3) || (encoded[0] != '0'))		return -1;	if (encoded[1] == 'x' || encoded[1] == 'X')		encoding_fmt = HEX_FORMAT;	else if (encoded[1] == 'b' || encoded[1] == 'B')		encoding_fmt = BASE64_FORMAT;	else		return -1;	return encoding_fmt;}static int chap_alloc_decode_buffer(char *encoded, u8 **decode_buf, int encoding_fmt){	int i;	int decode_len = 0;	i = strlen(encoded);	i -= 2;	if (encoding_fmt == HEX_FORMAT)		decode_len = (i - 1) / 2 + 1;	else if (encoding_fmt == BASE64_FORMAT) {		if (i % 4)			return CHAP_INITIATOR_ERROR;		decode_len =  i / 4 * 3;		if (encoded[i + 1] == '=')			decode_len--;		if (encoded[i] == '=')			decode_len--;	}	if (!decode_len)		return CHAP_INITIATOR_ERROR;	*decode_buf = malloc(decode_len);	if (!*decode_buf)		return CHAP_TARGET_ERROR;	return decode_len;}static int chap_decode_string(char *encoded, u8 *decode_buf, int buf_len, int encoding_fmt){	if (encoding_fmt == HEX_FORMAT) {		if ((strlen(encoded) - 2) > (2 * buf_len)) {			log_error("%s(%d) BUG? "				  " buf[%d] !sufficient to decode string[%d]",				  __FUNCTION__, __LINE__, buf_len, (int) strlen(encoded));			return CHAP_TARGET_ERROR;		}		decode_hex_string(encoded + 2, decode_buf, buf_len);	} else if (encoding_fmt == BASE64_FORMAT) {		if ((strlen(encoded) - 2) > ((buf_len - 1) / 3 + 1) * 4) {			log_error("%s(%d) BUG? "				  " buf[%d] !sufficient to decode string[%d]",				  __FUNCTION__, __LINE__, buf_len, (int) strlen(encoded));			return CHAP_TARGET_ERROR;		}		decode_base64_string(encoded + 2, decode_buf, buf_len);	} else		return CHAP_INITIATOR_ERROR;	return 0;}static inline void chap_encode_string(u8 *intnum, int buf_len, char *encode_buf, int encoding_fmt){	encode_buf[0] = '0';	if (encoding_fmt == HEX_FORMAT) {		encode_buf[1] = 'x';		encode_hex_string(intnum, buf_len, encode_buf + 2);	} else if (encoding_fmt == BASE64_FORMAT) {		encode_buf[1] = 'b';		encode_base64_string(intnum, buf_len, encode_buf + 2);	}}static inline void chap_calc_digest_md5(char chap_id, char *secret, int secret_len, u8 *challenge, int challenge_len, u8 *digest){	MD5_CTX ctx;	MD5_Init(&ctx);	MD5_Update(&ctx, &chap_id, 1);	MD5_Update(&ctx, secret, secret_len);	MD5_Update(&ctx, challenge, challenge_len);	MD5_Final(digest, &ctx);}static inline void chap_calc_digest_sha1(char chap_id, char *secret, int secret_len, u8 *challenge, int challenge_len, u8 *digest){	SHA_CTX ctx;

⌨️ 快捷键说明

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