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

📄 iscsi-auth-client.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * iSCSI driver for Linux * Copyright (C) 2001 Cisco Systems, Inc. * maintained by linux-iscsi-devel@lists.sourceforge.net * * 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: iscsi-auth-client.c,v 1.14 2005/01/19 22:53:50 mikenc Exp $ * * This file implements the iSCSI CHAP authentication method based on * RFC 3720.  The code in this file is meant to be common for both kernel and * user level and makes use of only limited  library  functions, presently only * string.h. Routines specific to kernel, user level are implemented in * seperate files under the appropriate directories. * This code in this files assumes a single thread of execution * for each iscsi_acl structure, and does no locking. */#include "iscsi-auth-client.h"#include "iscsi-session.h"#include "iscsi-protocol.h"#include "iscsi-sfnet.h"static const char acl_hexstring[] = "0123456789abcdefABCDEF";static const char acl_base64_string[] =    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static const char acl_authmethod_set_chap_alg_list[] = "CHAP";static const char acl_reject_option_name[] = "Reject";static const char acl_none_option_name[] = "None";static intacl_text_to_number(const char *text, unsigned long *num){	char *end;	unsigned long number = *num;	if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X'))		number = simple_strtoul(text + 2, &end, 16);	else		number = simple_strtoul(text, &end, 10);	if (*text != '\0' && *end == '\0') {		*num = number;		return 0;	/* No error */	} else		return 1;	/* Error */}static intacl_chk_string(const char *s, unsigned int max_len, unsigned int *out_len){	unsigned int len;	if (!s)		return 1;	for (len = 0; len < max_len; len++)		if (*s++ == '\0') {			if (out_len)				*out_len = len;			return 0;		}	return 1;}static intacl_str_index(const char *s, int c){	char *str = strchr(s, c);		if (str)		return (str - s);	else 		return -1;}static intacl_chk_auth_mthd_optn(int val){	if (val == AUTH_OPTION_NONE || val == AUTH_METHOD_CHAP)		return 0;	return 1;}static const char *acl_authmethod_optn_to_text(int value){	const char *s;	switch (value) {	case AUTH_OPTION_REJECT:		s = acl_reject_option_name;		break;	case AUTH_OPTION_NONE:		s = acl_none_option_name;		break;	case AUTH_METHOD_CHAP:		s = acl_authmethod_set_chap_alg_list;		break;	default:		s = 0;	}	return s;}static intacl_chk_chap_alg_optn(int chap_algorithm){	if (chap_algorithm == AUTH_OPTION_NONE ||	    chap_algorithm == AUTH_CHAP_ALG_MD5)		return 0;	return 1;}static intacl_data_to_text(unsigned char *data, unsigned int data_length, char *text,		 unsigned int text_length){	unsigned long n;	if (!text || text_length == 0)		return 1;	if (!data || data_length == 0) {		*text = '\0';		return 1;	}	if (text_length < 3) {		*text = '\0';		return 1;	}	*text++ = '0';	*text++ = 'x';	text_length -= 2;	while (data_length > 0) {		if (text_length < 3) {			*text = '\0';			return 1;		}		n = *data++;		data_length--;		*text++ = acl_hexstring[(n >> 4) & 0xf];		*text++ = acl_hexstring[n & 0xf];		text_length -= 2;	}	*text = '\0';	return 0;}static intacl_hex_to_data(const char *text, unsigned int text_length, unsigned char *data,		unsigned int *data_lenp){	int i;	unsigned int n1;	unsigned int n2;	unsigned int data_length = *data_lenp;	if ((text_length % 2) == 1) {		i = acl_str_index(acl_hexstring, *text++);		if (i < 0)			return 1;	/* error, bad character */		if (i > 15)			i -= 6;		n2 = i;		if (data_length < 1)			return 1;	/* error, too much data */		*data++ = n2;		data_length--;	}	while (*text != '\0') {		i = acl_str_index(acl_hexstring, *text++);		if (i < 0)			return 1;	/* error, bad character */		if (i > 15)			i -= 6;		n1 = i;		if (*text == '\0')			return 1;	/* error, odd string length */		i = acl_str_index(acl_hexstring, *text++);		if (i < 0)			return 1;	/* error, bad character */		if (i > 15)			i -= 6;		n2 = i;		if (data_length < 1)			return 1;	/* error, too much data */		*data++ = (n1 << 4) | n2;		data_length--;	}	if (data_length >= *data_lenp)		return 1;	/* error, no data */	*data_lenp = *data_lenp - data_length;	return 0;		/* no error */}static intacl_base64_to_data(const char *text, unsigned char *data,		   unsigned int *data_lenp){	int i;	unsigned int n;	unsigned int count;	unsigned int data_length = *data_lenp;	n = 0;	count = 0;	while (*text != '\0' && *text != '=') {		i = acl_str_index(acl_base64_string, *text++);		if (i < 0)			return 1;	/* error, bad character */		n = (n << 6 | (unsigned int)i);		count++;		if (count >= 4) {			if (data_length < 3)				return 1;	/* error, too much data */			*data++ = n >> 16;			*data++ = n >> 8;			*data++ = n;			data_length -= 3;			n = 0;			count = 0;		}	}	while (*text != '\0')		if (*text++ != '=')			return 1;	/* error, bad pad */	if (count == 0) {		/* do nothing */	} else if (count == 2) {		if (data_length < 1)			return 1;	/* error, too much data */		n = n >> 4;		*data++ = n;		data_length--;	} else if (count == 3) {		if (data_length < 2)			return 1;	/* error, too much data */		n = n >> 2;		*data++ = n >> 8;		*data++ = n;		data_length -= 2;	} else		return 1;	/* bad encoding */	if (data_length >= *data_lenp)		return 1;	/* error, no data */	*data_lenp = *data_lenp - data_length;	return 0;		/* no error */}static intacl_text_to_data(const char *text, unsigned char *data,		 unsigned int *data_length){	int status;	unsigned int text_length;	status = acl_chk_string(text, 2 + 2 * AUTH_LARGE_BINARY_MAX_LEN + 1,				&text_length);	if (status)		return status;	if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X')) {		/* skip prefix */		text += 2;		text_length -= 2;		status = acl_hex_to_data(text, text_length, data, data_length);	} else if (text[0] == '0' && (text[1] == 'b' || text[1] == 'B')) {		/* skip prefix */		text += 2;		text_length -= 2;		status = acl_base64_to_data(text, data, data_length);	} else		status = 1;	/* prefix not recognized. */	return status;}static voidacl_init_key_blk(struct auth_key_block *key_blk){	char *str_block = key_blk->str_block;	memset(key_blk, 0, sizeof(*key_blk));	key_blk->str_block = str_block;}static voidacl_set_key_value(struct auth_key_block *key_blk, int key_type,		  const char *key_val){	unsigned int length;	char *string;	if (key_blk->key[key_type].value_set) {		key_blk->dup_set = 1;		return;	}	key_blk->key[key_type].value_set = 1;	if (!key_val)		return;	if (acl_chk_string(key_val, AUTH_STR_MAX_LEN, &length)) {		key_blk->str_too_long = 1;		return;	}	length += 1;	if ((key_blk->blk_length + length) > AUTH_STR_BLOCK_MAX_LEN) {		key_blk->too_much_data = 1;		return;	}	string = &key_blk->str_block[key_blk->blk_length];	if (strlcpy(string, key_val, length) >= length) {		key_blk->too_much_data = 1;		return;	}	key_blk->blk_length += length;	key_blk->key[key_type].string = string;	key_blk->key[key_type].present = 1;}static const char *acl_get_key_val(struct auth_key_block *key_blk, int key_type){	key_blk->key[key_type].processed = 1;	if (!key_blk->key[key_type].present)		return 0;	return key_blk->key[key_type].string;}static voidacl_chk_key(struct iscsi_acl *client, int key_type, int *negotiated_option,	    unsigned int option_count, int *option_list,	    const char *(*value_to_text) (int)){	const char *key_val;	int length;	unsigned int i;	key_val = acl_get_key_val(&client->recv_key_block, key_type);	if (!key_val) {		*negotiated_option = AUTH_OPTION_NOT_PRESENT;		return;	}	while (*key_val != '\0') {		length = 0;		while (*key_val != '\0' && *key_val != ',')			client->scratch_key_value[length++] = *key_val++;		if (*key_val == ',')			key_val++;		client->scratch_key_value[length++] = '\0';		for (i = 0; i < option_count; i++) {			const char *s = (*value_to_text)(option_list[i]);			if (!s)				continue;			if (strcmp(client->scratch_key_value, s) == 0) {				*negotiated_option = option_list[i];				return;			}		}	}	*negotiated_option = AUTH_OPTION_REJECT;}static voidacl_set_key(struct iscsi_acl *client, int key_type, unsigned int option_count,	    int *option_list, const char *(*value_to_text)(int)){	unsigned int i;	if (option_count == 0) {		/*		 * No valid options to send, but we always want to		 * send something.		 */		acl_set_key_value(&client->send_key_block, key_type,				  acl_none_option_name);		return;	}	if (option_count == 1 && option_list[0] == AUTH_OPTION_NOT_PRESENT) {		acl_set_key_value(&client->send_key_block, key_type, 0);		return;	}	for (i = 0; i < option_count; i++) {		const char *s = (*value_to_text)(option_list[i]);		if (!s)			continue;		if (i == 0)			strlcpy(client->scratch_key_value, s,				   AUTH_STR_MAX_LEN);		else {			strlcat(client->scratch_key_value, ",",				   AUTH_STR_MAX_LEN);			strlcat(client->scratch_key_value, s,			  	   AUTH_STR_MAX_LEN);		}

⌨️ 快捷键说明

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