📄 iscsi-auth.c
字号:
/* * 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.c,v 1.9 2005/01/11 04:28:08 mikenc Exp $ * * This file contains the user level wrappers around iscsi authentication code. */#include <stdint.h>#include "iscsi-auth.h"#include "iscsi-auth-client.h"#include "iscsi-protocol.h"#include "iscsi-session.h"enum auth_dbg_statusacl_chap_compute_rsp(struct iscsi_acl *client, int rmt_auth, unsigned int id, unsigned char *challenge_data, unsigned int challenge_length, unsigned char *response_data){ unsigned char id_data[1]; struct MD5Context context; unsigned char out_data[AUTH_STR_MAX_LEN]; unsigned int out_length = AUTH_STR_MAX_LEN; if (!client->passwd_present) return AUTH_DBG_STATUS_LOCAL_PASSWD_NOT_SET; auth_md5_init(&context); /* id byte */ id_data[0] = id; auth_md5_update(&context, id_data, 1); /* decrypt password */ if (acl_data(out_data, &out_length, client->passwd_data, client->passwd_length)) return AUTH_DBG_STATUS_PASSWD_DECRYPT_FAILED; if (!rmt_auth && !client->ip_sec && out_length < 12) return AUTH_DBG_STATUS_PASSWD_TOO_SHORT_WITH_NO_IPSEC; /* shared secret */ auth_md5_update(&context, out_data, out_length); /* clear decrypted password */ memset(out_data, 0, AUTH_STR_MAX_LEN); /* challenge value */ auth_md5_update(&context, challenge_data, challenge_length); auth_md5_final(response_data, &context); return AUTH_DBG_STATUS_NOT_SET; /* no error */}/* * Authenticate a target's CHAP response. */intacl_chap_auth_request(struct iscsi_acl *client, char *username, unsigned int id, unsigned char *challenge_data, unsigned int challenge_length, unsigned char *response_data, unsigned int rsp_length){ struct iscsi_session *session = client->session_handle; struct MD5Context context; unsigned char verify_data[16]; /* the expected credentials are in the session */ if (session->username_in == NULL) { logmsg(AS_ERROR, "failing authentication, no incoming username" " configured to authenticate target %s\n", session->target_name); return AUTH_STATUS_FAIL; } if (strcmp(username, session->username_in) != 0) { logmsg(AS_ERROR, "failing authentication, received incorrect" "username from target %s\n", session->target_name); return AUTH_STATUS_FAIL; } if ((session->password_length_in < 1) || (session->password_in == NULL) || (session->password_in[0] == '\0')) { logmsg(AS_ERROR, "failing authentication, no incoming password " "configured to authenticate target %s\n", session->target_name); return AUTH_STATUS_FAIL; } /* challenge length is I->T, and shouldn't need to be checked */ if (rsp_length != sizeof(verify_data)) { logmsg(AS_ERROR, "failing authentication, received incorrect" " CHAP response length %u from target %s\n", rsp_length, session->target_name); return AUTH_STATUS_FAIL; } auth_md5_init(&context); /* id byte */ verify_data[0] = id; auth_md5_update(&context, verify_data, 1); /* shared secret */ auth_md5_update(&context, (unsigned char *)session->password_in, session->password_length_in); /* challenge value */ auth_md5_update(&context, (unsigned char *)challenge_data, challenge_length); auth_md5_final(verify_data, &context); if (memcmp(response_data, verify_data, sizeof(verify_data)) == 0) { debugmsg(1, "initiator authenticated target %s\n", session->target_name); return AUTH_STATUS_PASS; } logmsg(AS_ERROR,"failing authentication, received incorrect CHAP" "response from target %s\n", session->target_name); return AUTH_STATUS_FAIL;}voidauth_md5_init(struct MD5Context *context){ MD5Init(context);}voidauth_md5_update(struct MD5Context *context, unsigned char *data, unsigned int length){ MD5Update(context, data, length);}voidauth_md5_final(unsigned char *hash, struct MD5Context *context){ MD5Final(hash, context);}voidget_random_bytes(unsigned char *data, unsigned int length){ long r; unsigned n; while (length > 0) { r = rand(); r = r ^ (r >> 8); r = r ^ (r >> 4); n = r & 0x7; r = rand(); r = r ^ (r >> 8); r = r ^ (r >> 5); n = (n << 3) | (r & 0x7); r = rand(); r = r ^ (r >> 8); r = r ^ (r >> 5); n = (n << 2) | (r & 0x3); *data++ = n; length--; }}/** * strlcpy - Copy a %NUL terminated string into a sized buffer * @dest: Where to copy the string to * @src: Where to copy the string from * @size: size of destination buffer * * Compatible with *BSD: the result is always a valid * NUL-terminated string that fits in the buffer (unless, * of course, the buffer size is zero). It does not pad * out the result like strncpy() does. **/size_t strlcpy(char *dest, const char *src, size_t size){ size_t ret = strlen(src); if (size) { size_t len = (ret >= size) ? size-1 : ret; memcpy(dest, src, len); dest[len] = '\0'; } return ret;}/** * strlcat - Append a length-limited, %NUL-terminated string to another * @dest: The string to be appended to * @src: The string to append to it * @count: The size of the destination buffer. **/size_t strlcat(char *dest, const char *src, size_t count){ size_t dsize = strlen(dest); size_t len = strlen(src); size_t res = dsize + len; /* This would be a bug */ if (dsize >= count) { dest[count - 1] = 0; return count; } dest += dsize; count -= dsize; if (len >= count) len = count-1; memcpy(dest, src, len); dest[len] = 0; return res;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -