iscsit: support AuthMethod=None security negotiation

Signed-off-by: Chris Koch <chrisko@google.com>
This commit is contained in:
Chris Koch
2020-01-21 22:02:00 -08:00
parent 2f1d32710a
commit 6af024c2e3
3 changed files with 58 additions and 19 deletions

View File

@@ -159,10 +159,12 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error
StartTime: conn.req.StartTime, StartTime: conn.req.StartTime,
StatSN: conn.req.ExpStatSN, StatSN: conn.req.ExpStatSN,
TaskTag: conn.req.TaskTag, TaskTag: conn.req.TaskTag,
ExpCmdSN: conn.session.ExpCmdSN,
MaxCmdSN: conn.session.ExpCmdSN + conn.session.MaxQueueCommand,
ExpectedDataLen: conn.req.ExpectedDataLen, 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 { switch oc {
case OpReady: case OpReady:
conn.resp.OpCode = 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.NSG = conn.loginParam.tgtNSG
conn.resp.ExpCmdSN = conn.req.CmdSN conn.resp.ExpCmdSN = conn.req.CmdSN
conn.resp.MaxCmdSN = conn.req.CmdSN conn.resp.MaxCmdSN = conn.req.CmdSN
negoKeys, err := conn.processLoginData() if conn.req.CSG != SecurityNegotiation {
if err != nil { negoKeys, err := conn.processLoginData()
return err 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 conn.txTask = nil
} }

View File

@@ -414,18 +414,19 @@ func (s *ISCSITargetDriver) iscsiExecLogin(conn *iscsiConnection) error {
conn.maxSeqCount = conn.maxBurstLength / conn.maxRecvDataSegmentLength conn.maxSeqCount = conn.maxBurstLength / conn.maxRecvDataSegmentLength
if conn.loginParam.iniCSG == SecurityNegotiation { if conn.loginParam.iniCSG == SecurityNegotiation {
conn.state = CONN_STATE_EXIT if err := conn.processSecurityData(); err != nil {
return fmt.Errorf("Doesn't support Auth") return err
}
conn.state = CONN_STATE_LOGIN
return conn.buildRespPackage(OpLoginResp, nil)
} }
_, err := conn.processLoginData() if _, err := conn.processLoginData(); err != nil {
if err != nil {
return err return err
} }
if !conn.loginParam.paramInit { if !conn.loginParam.paramInit {
err = s.BindISCSISession(conn) if err := s.BindISCSISession(conn); err != nil {
if err != nil {
conn.state = CONN_STATE_EXIT conn.state = CONN_STATE_EXIT
return err return err
} }

View File

@@ -19,6 +19,7 @@ package iscsit
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"strings"
"github.com/gostor/gotgt/pkg/util" "github.com/gostor/gotgt/pkg/util"
) )
@@ -62,14 +63,47 @@ func (s iSCSILoginStage) String() string {
} }
func loginKVDeclare(conn *iscsiConnection, negoKV []util.KeyValue) []util.KeyValue { func loginKVDeclare(conn *iscsiConnection, negoKV []util.KeyValue) []util.KeyValue {
negoKV = append(negoKV, util.KeyValue{"TargetPortalGroupTag", negoKV = append(negoKV, util.KeyValue{"TargetPortalGroupTag",
numberKeyInConv(uint(conn.loginParam.tpgt))}) numberKeyInConv(uint(conn.loginParam.tpgt))})
negoKV = append(negoKV, util.KeyValue{"MaxRecvDataSegmentLength", negoKV = append(negoKV, util.KeyValue{"MaxRecvDataSegmentLength",
numberKeyInConv(sessionKeys["MaxRecvDataSegmentLength"].def)}) numberKeyInConv(sessionKeys["MaxRecvDataSegmentLength"].def)})
return negoKV 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) { func (conn *iscsiConnection) processLoginData() ([]util.KeyValue, error) {
var ( var (
uintVal uint uintVal uint
@@ -148,7 +182,7 @@ func (conn *iscsiConnection) processLoginData() ([]util.KeyValue, error) {
conn.loginParam.tgtTrans = true conn.loginParam.tgtTrans = true
} else { } else {
//Currently, we just reject these kind of cases //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) conn.loginParam.iniCSG, conn.loginParam.iniNSG, conn.loginParam.iniTrans)
} }
} else { } else {