diff --git a/pkg/port/iscsit/conn.go b/pkg/port/iscsit/conn.go index f72d8e7..0b0c14a 100644 --- a/pkg/port/iscsit/conn.go +++ b/pkg/port/iscsit/conn.go @@ -159,10 +159,12 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error StartTime: conn.req.StartTime, StatSN: conn.req.ExpStatSN, TaskTag: conn.req.TaskTag, - ExpCmdSN: conn.session.ExpCmdSN, - MaxCmdSN: conn.session.ExpCmdSN + conn.session.MaxQueueCommand, ExpectedDataLen: conn.req.ExpectedDataLen, } + if conn.session != nil { + conn.resp.ExpCmdSN = conn.session.ExpCmdSN + conn.resp.MaxCmdSN = conn.session.ExpCmdSN + conn.session.MaxQueueCommand + } switch oc { case OpReady: conn.resp.OpCode = OpReady @@ -216,15 +218,17 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error conn.resp.NSG = conn.loginParam.tgtNSG conn.resp.ExpCmdSN = conn.req.CmdSN conn.resp.MaxCmdSN = conn.req.CmdSN - negoKeys, err := conn.processLoginData() - if err != nil { - return err + if conn.req.CSG != SecurityNegotiation { + negoKeys, err := conn.processLoginData() + if err != nil { + return err + } + if !conn.loginParam.keyDeclared { + negoKeys = loginKVDeclare(conn, negoKeys) + conn.loginParam.keyDeclared = true + } + conn.resp.RawData = util.MarshalKVText(negoKeys) } - if !conn.loginParam.keyDeclared { - negoKeys = loginKVDeclare(conn, negoKeys) - conn.loginParam.keyDeclared = true - } - conn.resp.RawData = util.MarshalKVText(negoKeys) conn.txTask = nil } diff --git a/pkg/port/iscsit/iscsid.go b/pkg/port/iscsit/iscsid.go index b8cbfd8..205d098 100644 --- a/pkg/port/iscsit/iscsid.go +++ b/pkg/port/iscsit/iscsid.go @@ -414,18 +414,19 @@ func (s *ISCSITargetDriver) iscsiExecLogin(conn *iscsiConnection) error { conn.maxSeqCount = conn.maxBurstLength / conn.maxRecvDataSegmentLength if conn.loginParam.iniCSG == SecurityNegotiation { - conn.state = CONN_STATE_EXIT - return fmt.Errorf("Doesn't support Auth") + if err := conn.processSecurityData(); err != nil { + return err + } + conn.state = CONN_STATE_LOGIN + return conn.buildRespPackage(OpLoginResp, nil) } - _, err := conn.processLoginData() - if err != nil { + if _, err := conn.processLoginData(); err != nil { return err } if !conn.loginParam.paramInit { - err = s.BindISCSISession(conn) - if err != nil { + if err := s.BindISCSISession(conn); err != nil { conn.state = CONN_STATE_EXIT return err } diff --git a/pkg/port/iscsit/login.go b/pkg/port/iscsit/login.go index 2a8d452..7451e5b 100644 --- a/pkg/port/iscsit/login.go +++ b/pkg/port/iscsit/login.go @@ -19,6 +19,7 @@ package iscsit import ( "bytes" "fmt" + "strings" "github.com/gostor/gotgt/pkg/util" ) @@ -62,14 +63,47 @@ func (s iSCSILoginStage) String() string { } func loginKVDeclare(conn *iscsiConnection, negoKV []util.KeyValue) []util.KeyValue { - negoKV = append(negoKV, util.KeyValue{"TargetPortalGroupTag", numberKeyInConv(uint(conn.loginParam.tpgt))}) negoKV = append(negoKV, util.KeyValue{"MaxRecvDataSegmentLength", numberKeyInConv(sessionKeys["MaxRecvDataSegmentLength"].def)}) return negoKV - } + +func stringsContains(s []string, p string) bool { + for _, q := range s { + if q == p { + return true + } + } + return false +} + +func (conn *iscsiConnection) processSecurityData() error { + securityKV := util.ParseKVText(conn.req.RawData) + + for key, val := range securityKV { + if key == "AuthMethod" { + // It can be a list. + vals := strings.Split(val, ",") + if !stringsContains(vals, "None") { + // TODO: respond with Reject message, rather + // than terminating TCP connection. + return fmt.Errorf("client requesting AuthMethod:%s, only support None", val) + } + conn.loginParam.tgtNSG = LoginOperationalNegotiation + conn.loginParam.tgtTrans = true + conn.loginParam.authMethod = AuthNone + } else if key == "TargetName" { + conn.loginParam.target = val + } else if key == "InitiatorName" { + conn.loginParam.initiator = val + } + } + + return nil +} + func (conn *iscsiConnection) processLoginData() ([]util.KeyValue, error) { var ( uintVal uint @@ -148,7 +182,7 @@ func (conn *iscsiConnection) processLoginData() ([]util.KeyValue, error) { conn.loginParam.tgtTrans = true } else { //Currently, we just reject these kind of cases - return negoKV, fmt.Errorf("reject CSG=%d,NSG=%d,trans=%t", + return negoKV, fmt.Errorf("reject CSG=%s,NSG=%s,trans=%t", conn.loginParam.iniCSG, conn.loginParam.iniNSG, conn.loginParam.iniTrans) } } else {