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

📄 iscsi-login.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * iSCSI login library * 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: iscsi-login.c,v 1.19 2002/10/08 20:32:33 smferris Exp $ * */#include "iscsi-platform.h"#include "iscsi-protocol.h"#include "iscsi-io.h"#include "iscsi-login.h"struct IscsiHdr *iscsi_align_pdu(iscsi_session_t *session, unsigned char *buffer, int buffersize){    struct IscsiHdr *header;    unsigned long addr = (unsigned long)buffer;    /* find a buffer location guaranteed to be reasonably aligned for the header */    addr += (addr % sizeof(*header));    header = (struct IscsiHdr *)addr;    return header;}/* caller is assumed to be well-behaved and passing NUL terminated strings */int iscsi_add_text(iscsi_session_t *session, struct IscsiHdr *pdu, char *data, int max_data_length, char *param, char *value){    int param_len = strlen(param);    int value_len = strlen(value);    int length = param_len + 1 + value_len + 1; /* param, separator, value, and trailing NUL */    int pdu_length = ntoh24(pdu->dlength);    char *text = data;    char *end = data + max_data_length;    char *pdu_text;        /* find the end of the current text */    text += pdu_length;    pdu_text = text;    pdu_length += length;    if (text + length >= end) {        logmsg(AS_NOTICE, "failed to add login text '%s=%s'\n", param, value);        return 0;    }    /* param */    iscsi_strncpy(text, param, param_len);    text += param_len;    /* separator */    *text++ = ISCSI_TEXT_SEPARATOR;    /* value */    strncpy(text, value, value_len);    text += value_len;        /* NUL */    *text++ = '\0';    /* update the length in the PDU header */    hton24(pdu->dlength, pdu_length);    return 1;}int iscsi_find_key_value(char *param, char *pdu, char *pdu_end, char **value_start, char **value_end){    char *str = param;    char *text = pdu;    char *value = NULL;    if (value_start)        *value_start = NULL;    if (value_end)        *value_end = NULL;            /* make sure they contain the same bytes */    while (*str) {        if (text >= pdu_end)             return 0;        if (*text == '\0')            return 0;        if (*str != *text)            return 0;        str++;        text++;    }        if ((text >= pdu_end) || (*text == '\0') || (*text != ISCSI_TEXT_SEPARATOR)) {        return 0;    }    /* find the value */    value = text + 1;    /* find the end of the value */    while ((text < pdu_end) && (*text))        text++;    if (value_start)        *value_start = value;    if (value_end)        *value_end = text;    return 1;}/* we never authenticate the target, so we don't need an AuthClient callback that does anything. * It would only be needed if we were authenticating the target, which we currently never do. */static void null_callback(void *user_handle, void *message_handle, int auth_status){}/* this assumes the text data is always NUL terminated.  The caller can always arrange for that * by using a slightly larger buffer than the max PDU size, and then appending a NUL to the PDU. */int iscsi_process_login_response(iscsi_session_t *session, struct IscsiLoginRspHdr *login_rsp_pdu, char *data, int max_data_length){    int tbit = login_rsp_pdu->tbit;    char *text = data;    char *end;    end = text + ntoh24(login_rsp_pdu->dlength) + 1;     if (end >= (data + max_data_length)) {        logmsg(AS_ERROR, "process_login_response - buffer too small to guarantee NUL termination\n");        return 0;    }    /* guarantee a trailing NUL */    *end = '\0';    /* if the response status was success, sanity check the response */    if (login_rsp_pdu->status_class == STATUS_CLASS_SUCCESS) {        /* check the active version */        if (login_rsp_pdu->active_version != ISCSI_DRAFT16_VERSION) {            logmsg(AS_ERROR, "received incompatible active iSCSI version 0x%02x during login, expected version 0x%02x\n",                   login_rsp_pdu->active_version, ISCSI_DRAFT16_VERSION);            return 0;        }        /* make sure the current phase matches */        if (login_rsp_pdu->curr != session->current_phase) {            logmsg(AS_ERROR, "current phase mismatch, session %d, response %d\n",                    session->current_phase, login_rsp_pdu->curr);            return 0;        }        /* make sure that we're actually advancing if the T-bit is set */        if (login_rsp_pdu->tbit && (login_rsp_pdu->next <= session->current_phase)) {            logmsg(AS_ERROR, "current phase %d, target wants to go to phase %d, but we want to go to phase %d\n",                   session->current_phase, login_rsp_pdu->next, session->next_phase);            return 0;        }    }    if (session->current_phase == ISCSI_SECURITY_NEGOTIATION_PHASE) {        if (iscsiAuthClientRecvBegin(session->auth_client) != iscsiAuthStatusNoError) {            logmsg(AS_ERROR, "authClientRecvBegin failed\n");            return 0;        }                if (iscsiAuthClientRecvTransitBit(session->auth_client, tbit) != iscsiAuthStatusNoError) {            logmsg(AS_ERROR, "authClientRecvTransitBit failed\n");            return 0;        }    }    /* scan the text data */ more_text:    while (text && (text < end)) {        char *value = NULL;        char *value_end = NULL;        /* skip any NULs separating each text key=value pair */        while ((text < end) && (*text == '\0'))            text++;        if (text >= end)            break;        /* handle keys appropriate for each phase */        switch (session->current_phase) {            case ISCSI_SECURITY_NEGOTIATION_PHASE: {                /* a few keys are possible in Security phase which the                 * auth code doesn't care about, but which we might                 * want to see, or at least not choke on.                 */                if (iscsi_find_key_value("TargetAlias", text, end, &value, &value_end)) {                    size_t size = sizeof(session->TargetAlias);                    if ((value_end - value) < size)                        size = value_end - value;                    memcpy(session->TargetAlias, value, size);                    session->TargetAlias[sizeof(session->TargetAlias)-1] = '\0';                    text = value_end;                }                else if (iscsi_find_key_value("TargetAddress", text, end, &value, &value_end)) {                    /* if possible, change the session's ip_address and port to the new TargetAddress */                    if (session->update_address && session->update_address(session, value)) {                        text = value_end;                    }                    else {                        logmsg(AS_ERROR, "session %p can't handle redirection to %s\n", session, value);                        return 0;                    }                }                else if (iscsi_find_key_value("TargetPortalGroupTag", text, end, &value, &value_end)) {                    /* We should have already obtained this via discovery.                      * We've already picked an isid, so the most we can do is confirm we reached                     * the portal group we were expecting to.                     */                    int tag = iscsi_strtoul(value, NULL, 0);                    if (session->portal_group_tag >= 0) {                        if (tag != session->portal_group_tag) {                            logmsg(AS_ERROR, "session %p portal group tag mismatch, expected %u, actual %u\n",                                   session, session->portal_group_tag, tag);                            return 0;                        }                    }                    else {                        /* we now know the tag */                        session->portal_group_tag = tag;                    }                    text = value_end;                }                 else {                    /* any key we don't recognize either goes to the auth code, or we choke on it */                    int keytype = iscsiAuthKeyTypeNone;                                        while (iscsiAuthClientGetNextKeyType(&keytype) == iscsiAuthStatusNoError) {                        char *key = (char *)iscsiAuthClientGetKeyName(keytype);                                                if (key && iscsi_find_key_value(key, text, end, &value, &value_end)) {                            if (iscsiAuthClientRecvKeyValue(session->auth_client, keytype, value) != iscsiAuthStatusNoError) {                                logmsg(AS_ERROR, "authentication failed to process %s\n", text);                                return 0;                            }                            text = value_end;                            goto more_text;                        }                    }                    logmsg(AS_ERROR, "security phase failed to recognize text %s\n", text);                    return 0;                }                break;            }            case ISCSI_OP_PARMS_NEGOTIATION_PHASE: {                /* FIXME: they're making base64 an encoding option for                 * all numbers in draft13, since some security                 * protocols use large numbers, and it was somehow                 * considered "simpler" to let them be used for any                 * number anywhere.                 */                if (iscsi_find_key_value("TargetAlias", text, end, &value, &value_end)) {                    size_t size = sizeof(session->TargetAlias);                    if ((value_end - value) < size)                        size = value_end - value;                    memcpy(session->TargetAlias, value, size);                    session->TargetAlias[sizeof(session->TargetAlias)-1] = '\0';                    text = value_end;                }                else if (iscsi_find_key_value("TargetAddress", text, end, &value, &value_end)) {                    if (session->update_address && session->update_address(session, value)) {                        text = value_end;                    }                    else {                        logmsg(AS_ERROR, "session %p can't handle redirection to %s\n", session, value);

⌨️ 快捷键说明

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