Example #1
0
        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;
        }
Example #2
0
 private void UnpackState(byte value)
 {
     Transit = (value & 0x80) != 0;
     Continue = (value & 0x40) != 0;
     CurrentStage = (LoginStages)((value >> 2) & 0x3);
     NextStage = (LoginStages)(value & 0x3);
 }
Example #3
0
 private void UnpackState(byte value)
 {
     Transit      = (value & 0x80) != 0;
     Continue     = (value & 0x40) != 0;
     CurrentStage = (LoginStages)((value >> 2) & 0x3);
     NextStage    = (LoginStages)(value & 0x3);
 }
Example #4
0
        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);
        }
Example #5
0
        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;
        }
Example #6
0
        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;
        }