Пример #1
0
        private void ConsumeParameters(TextBuffer inParameters, TextBuffer outParameters)
        {
            PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (var propInfo in properties)
            {
                ProtocolKeyAttribute attr = (ProtocolKeyAttribute)Attribute.GetCustomAttribute(propInfo, typeof(ProtocolKeyAttribute));
                if (attr != null && (attr.Sender & KeySender.Target) != 0)
                {
                    if (inParameters[attr.Name] != null)
                    {
                        object value = ProtocolKeyAttribute.GetValueAsObject(inParameters[attr.Name], propInfo.PropertyType);

                        propInfo.GetSetMethod(true).Invoke(this, new object[] { value });
                        inParameters.Remove(attr.Name);

                        if (attr.Type == KeyType.Negotiated && !_negotiatedParameters.ContainsKey(attr.Name))
                        {
                            value = propInfo.GetGetMethod(true).Invoke(this, null);
                            outParameters.Add(attr.Name, ProtocolKeyAttribute.GetValueAsString(value, propInfo.PropertyType));
                            _negotiatedParameters.Add(attr.Name, string.Empty);
                        }
                    }
                }
            }

            _session.ConsumeParameters(inParameters, outParameters);

            foreach (var param in inParameters.Lines)
            {
                outParameters.Add(param.Key, "NotUnderstood");
            }
        }
Пример #2
0
        public override bool GetParameters(TextBuffer textBuffer)
        {
            switch (_state)
            {
            case State.SendAlgorithm:
                textBuffer.Add("CHAP_A", "5");
                _state = State.ReceiveChallenge;
                return(false);

            case State.SendResponse:
                textBuffer.Add("CHAP_N", _name);
                textBuffer.Add("CHAP_R", CalcResponse());
                _state = State.Finished;
                return(true);

            default:
                throw new InvalidOperationException("Unknown authentication state: " + _state);
            }
        }
Пример #3
0
        private void GetParametersToNegotiate(TextBuffer parameters, KeyUsagePhase phase, SessionType sessionType)
        {
            PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (var propInfo in properties)
            {
                ProtocolKeyAttribute attr = (ProtocolKeyAttribute)Attribute.GetCustomAttribute(propInfo, typeof(ProtocolKeyAttribute));
                if (attr != null)
                {
                    object value = propInfo.GetGetMethod(true).Invoke(this, null);

                    if (attr.ShouldTransmit(value, propInfo.PropertyType, phase, sessionType == SessionType.Discovery))
                    {
                        parameters.Add(attr.Name, ProtocolKeyAttribute.GetValueAsString(value, propInfo.PropertyType));
                        _negotiatedParameters.Add(attr.Name, string.Empty);
                    }
                }
            }
        }
Пример #4
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;
        }
Пример #5
0
        public TargetInfo[] EnumerateTargets()
        {
            TextBuffer parameters = new TextBuffer();

            parameters.Add(SendTargetsParameter, "All");

            byte[] paramBuffer = new byte[parameters.Size];
            parameters.WriteTo(paramBuffer, 0);

            TextRequest req = new TextRequest(this);

            byte[] packet = req.GetBytes(0, paramBuffer, 0, paramBuffer.Length, true);

            _stream.Write(packet, 0, packet.Length);
            _stream.Flush();

            ProtocolDataUnit pdu  = ReadPdu();
            TextResponse     resp = ParseResponse <TextResponse>(pdu);

            TextBuffer buffer = new TextBuffer();

            if (resp.TextData != null)
            {
                buffer.ReadFrom(resp.TextData, 0, resp.TextData.Length);
            }

            List <TargetInfo> targets = new List <TargetInfo>();

            string currentTarget = null;
            List <TargetAddress> currentAddresses = null;

            foreach (var line in buffer.Lines)
            {
                if (currentTarget == null)
                {
                    if (line.Key != TargetNameParameter)
                    {
                        throw new InvalidProtocolException("Unexpected response parameter " + line.Key + " expected " + TargetNameParameter);
                    }

                    currentTarget    = line.Value;
                    currentAddresses = new List <TargetAddress>();
                }
                else if (line.Key == TargetNameParameter)
                {
                    targets.Add(new TargetInfo(currentTarget, currentAddresses.ToArray()));
                    currentTarget = line.Value;
                    currentAddresses.Clear();
                }
                else if (line.Key == TargetAddressParameter)
                {
                    currentAddresses.Add(TargetAddress.Parse(line.Value));
                }
            }

            if (currentTarget != null)
            {
                targets.Add(new TargetInfo(currentTarget, currentAddresses.ToArray()));
            }

            return(targets.ToArray());
        }