📄 chap.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 + -