public byte[] GetBytes(byte[] data, int offset, int count, bool isFinalData) { _basicHeader = new BasicHeaderSegment(); _basicHeader.Immediate = true; _basicHeader.OpCode = OpCode.LoginRequest; _basicHeader.FinalPdu = isFinalData; _basicHeader.TotalAhsLength = 0; _basicHeader.DataSegmentLength = count; _basicHeader.InitiatorTaskTag = _connection.Session.CurrentTaskTag; _transit = isFinalData; _continue = !isFinalData; _currentStage = _connection.CurrentLoginStage; if (_transit) { _nextStage = _connection.NextLoginStage; } _connectionId = _connection.Id; _commandSequenceNumber = _connection.Session.CommandSequenceNumber; _expectedStatusSequenceNumber = _connection.ExpectedStatusSequenceNumber; byte[] buffer = new byte[Utilities.RoundUp(48 + count, 4)]; _basicHeader.WriteTo(buffer, 0); buffer[1] = PackState(); buffer[2] = 0; // Max Version buffer[3] = 0; // Min Version Utilities.WriteBytesBigEndian(_connection.Session.InitiatorSessionId, buffer, 8); Utilities.WriteBytesBigEndian(IsidQualifier, buffer, 12); Utilities.WriteBytesBigEndian(_connection.Session.TargetSessionId, buffer, 14); Utilities.WriteBytesBigEndian(_connectionId, buffer, 20); Utilities.WriteBytesBigEndian(_commandSequenceNumber, buffer, 24); Utilities.WriteBytesBigEndian(_expectedStatusSequenceNumber, buffer, 28); Array.Copy(data, offset, buffer, 48, count); return buffer; }
private void UnpackState(byte value) { Transit = (value & 0x80) != 0; Continue = (value & 0x40) != 0; CurrentStage = (LoginStages)((value >> 2) & 0x3); NextStage = (LoginStages)(value & 0x3); }
public byte[] GetBytes(byte[] data, int offset, int count, bool isFinalData) { _basicHeader = new BasicHeaderSegment(); _basicHeader.Immediate = true; _basicHeader.OpCode = OpCode.LoginRequest; _basicHeader.FinalPdu = isFinalData; _basicHeader.TotalAhsLength = 0; _basicHeader.DataSegmentLength = count; _basicHeader.InitiatorTaskTag = _connection.Session.CurrentTaskTag; _transit = isFinalData; _continue = !isFinalData; _currentStage = _connection.CurrentLoginStage; if (_transit) { _nextStage = _connection.NextLoginStage; } _connectionId = _connection.Id; _commandSequenceNumber = _connection.Session.CommandSequenceNumber; _expectedStatusSequenceNumber = _connection.ExpectedStatusSequenceNumber; byte[] buffer = new byte[Utilities.RoundUp(48 + count, 4)]; _basicHeader.WriteTo(buffer, 0); buffer[1] = PackState(); buffer[2] = 0; // Max Version buffer[3] = 0; // Min Version Utilities.WriteBytesBigEndian(_connection.Session.InitiatorSessionId, buffer, 8); Utilities.WriteBytesBigEndian(IsidQualifier, buffer, 12); Utilities.WriteBytesBigEndian(_connection.Session.TargetSessionId, buffer, 14); Utilities.WriteBytesBigEndian(_connectionId, buffer, 20); Utilities.WriteBytesBigEndian(_commandSequenceNumber, buffer, 24); Utilities.WriteBytesBigEndian(_expectedStatusSequenceNumber, buffer, 28); Array.Copy(data, offset, buffer, 48, count); return(buffer); }
private void NegotiateFeatures() { // // Send the request... // TextBuffer parameters = new TextBuffer(); GetParametersToNegotiate(parameters, KeyUsagePhase.OperationalNegotiation, _session.SessionType); _session.GetParametersToNegotiate(parameters, KeyUsagePhase.OperationalNegotiation); byte[] paramBuffer = new byte[parameters.Size]; parameters.WriteTo(paramBuffer, 0); LoginRequest req = new LoginRequest(this); byte[] packet = req.GetBytes(paramBuffer, 0, paramBuffer.Length, true); _stream.Write(packet, 0, packet.Length); _stream.Flush(); // // Read the response... // TextBuffer settings = new TextBuffer(); ProtocolDataUnit pdu = ReadPdu(); LoginResponse resp = ParseResponse <LoginResponse>(pdu); if (resp.StatusCode != LoginStatusCode.Success) { throw new LoginException("iSCSI Target indicated login failure: " + resp.StatusCode); } if (resp.Continue) { MemoryStream ms = new MemoryStream(); ms.Write(resp.TextData, 0, resp.TextData.Length); while (resp.Continue) { pdu = ReadPdu(); resp = ParseResponse <LoginResponse>(pdu); ms.Write(resp.TextData, 0, resp.TextData.Length); } settings.ReadFrom(ms.GetBuffer(), 0, (int)ms.Length); } else if (resp.TextData != null) { settings.ReadFrom(resp.TextData, 0, resp.TextData.Length); } parameters = new TextBuffer(); ConsumeParameters(settings, parameters); while (!resp.Transit || parameters.Count != 0) { paramBuffer = new byte[parameters.Size]; parameters.WriteTo(paramBuffer, 0); req = new LoginRequest(this); packet = req.GetBytes(paramBuffer, 0, paramBuffer.Length, true); _stream.Write(packet, 0, packet.Length); _stream.Flush(); // // Read the response... // settings = new TextBuffer(); pdu = ReadPdu(); resp = ParseResponse <LoginResponse>(pdu); if (resp.StatusCode != LoginStatusCode.Success) { throw new LoginException("iSCSI Target indicated login failure: " + resp.StatusCode); } parameters = new TextBuffer(); if (resp.TextData != null) { if (resp.Continue) { MemoryStream ms = new MemoryStream(); ms.Write(resp.TextData, 0, resp.TextData.Length); while (resp.Continue) { pdu = ReadPdu(); resp = ParseResponse <LoginResponse>(pdu); ms.Write(resp.TextData, 0, resp.TextData.Length); } settings.ReadFrom(ms.GetBuffer(), 0, (int)ms.Length); } else { settings.ReadFrom(resp.TextData, 0, resp.TextData.Length); } ConsumeParameters(settings, parameters); } } if (resp.NextStage != NextLoginStage) { throw new LoginException("iSCSI Target wants to transition to a different login stage: " + resp.NextStage + " (expected: " + NextLoginStage + ")"); } _loginStage = resp.NextStage; }
private void NegotiateSecurity() { _loginStage = LoginStages.SecurityNegotiation; // // Establish the contents of the request // TextBuffer parameters = new TextBuffer(); GetParametersToNegotiate(parameters, KeyUsagePhase.SecurityNegotiation, _session.SessionType); _session.GetParametersToNegotiate(parameters, KeyUsagePhase.SecurityNegotiation); string authParam = _authenticators[0].Identifier; for (int i = 1; i < _authenticators.Length; ++i) { authParam += "," + _authenticators[i].Identifier; } parameters.Add(AuthMethodParameter, authParam); // // Send the request... // byte[] paramBuffer = new byte[parameters.Size]; parameters.WriteTo(paramBuffer, 0); LoginRequest req = new LoginRequest(this); byte[] packet = req.GetBytes(paramBuffer, 0, paramBuffer.Length, true); _stream.Write(packet, 0, packet.Length); _stream.Flush(); // // Read the response... // TextBuffer settings = new TextBuffer(); ProtocolDataUnit pdu = ReadPdu(); LoginResponse resp = ParseResponse <LoginResponse>(pdu); if (resp.StatusCode != LoginStatusCode.Success) { throw new LoginException("iSCSI Target indicated login failure: " + resp.StatusCode); } if (resp.Continue) { MemoryStream ms = new MemoryStream(); ms.Write(resp.TextData, 0, resp.TextData.Length); while (resp.Continue) { pdu = ReadPdu(); resp = ParseResponse <LoginResponse>(pdu); ms.Write(resp.TextData, 0, resp.TextData.Length); } settings.ReadFrom(ms.GetBuffer(), 0, (int)ms.Length); } else if (resp.TextData != null) { settings.ReadFrom(resp.TextData, 0, resp.TextData.Length); } Authenticator authenticator = null; for (int i = 0; i < _authenticators.Length; ++i) { if (settings[AuthMethodParameter] == _authenticators[i].Identifier) { authenticator = _authenticators[i]; break; } } settings.Remove(AuthMethodParameter); settings.Remove("TargetPortalGroupTag"); if (authenticator == null) { throw new LoginException("iSCSI Target specified an unsupported authentication method: " + settings[AuthMethodParameter]); } parameters = new TextBuffer(); ConsumeParameters(settings, parameters); while (!resp.Transit) { // // Send the request... // parameters = new TextBuffer(); authenticator.GetParameters(parameters); paramBuffer = new byte[parameters.Size]; parameters.WriteTo(paramBuffer, 0); req = new LoginRequest(this); packet = req.GetBytes(paramBuffer, 0, paramBuffer.Length, true); _stream.Write(packet, 0, packet.Length); _stream.Flush(); // // Read the response... // settings = new TextBuffer(); pdu = ReadPdu(); resp = ParseResponse <LoginResponse>(pdu); if (resp.StatusCode != LoginStatusCode.Success) { throw new LoginException("iSCSI Target indicated login failure: " + resp.StatusCode); } if (resp.TextData != null && resp.TextData.Length != 0) { if (resp.Continue) { MemoryStream ms = new MemoryStream(); ms.Write(resp.TextData, 0, resp.TextData.Length); while (resp.Continue) { pdu = ReadPdu(); resp = ParseResponse <LoginResponse>(pdu); ms.Write(resp.TextData, 0, resp.TextData.Length); } settings.ReadFrom(ms.GetBuffer(), 0, (int)ms.Length); } else { settings.ReadFrom(resp.TextData, 0, resp.TextData.Length); } authenticator.SetParameters(settings); } } if (resp.NextStage != NextLoginStage) { throw new LoginException("iSCSI Target wants to transition to a different login stage: " + resp.NextStage + " (expected: " + NextLoginStage + ")"); } _loginStage = resp.NextStage; }