Ejemplo n.º 1
0
        public InheritedEntityAvro DeserializeAvro(byte[] bytes)
        {
            using (var ms = new MemoryStream(bytes))
            {
                var dec = new BinaryDecoder(ms);
                var reader = new SpecificDefaultReader(InheritedEntityAvro._SCHEMA, InheritedEntityAvro._SCHEMA);
                var regenAvroMsg = new InheritedEntityAvro();
                reader.Read(regenAvroMsg, dec);

                return regenAvroMsg;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads the schema information from a XML document.
        /// </summary>
        public void LoadFromBinary(ISystemContext context, Stream istrm, bool updateTables)
        {
            ServiceMessageContext messageContext = new ServiceMessageContext();

            messageContext.NamespaceUris = context.NamespaceUris;
            messageContext.ServerUris    = context.ServerUris;
            messageContext.Factory       = context.EncodeableFactory;

            using (BinaryDecoder decoder = new BinaryDecoder(istrm, messageContext))
            {
                // check if a namespace table was provided.
                NamespaceTable namespaceUris = new NamespaceTable();

                if (!decoder.LoadStringTable(namespaceUris))
                {
                    namespaceUris = null;
                }

                // update namespace table.
                if (updateTables)
                {
                    if (namespaceUris != null && context.NamespaceUris != null)
                    {
                        for (int ii = 0; ii < namespaceUris.Count; ii++)
                        {
                            context.NamespaceUris.GetIndexOrAppend(namespaceUris.GetString((uint)ii));
                        }
                    }
                }

                // check if a server uri table was provided.
                StringTable serverUris = new StringTable();

                if (namespaceUris != null && namespaceUris.Count > 1)
                {
                    serverUris.Append(namespaceUris.GetString(1));
                }

                if (!decoder.LoadStringTable(serverUris))
                {
                    serverUris = null;
                }

                // update server table.
                if (updateTables)
                {
                    if (serverUris != null && context.ServerUris != null)
                    {
                        for (int ii = 0; ii < serverUris.Count; ii++)
                        {
                            context.ServerUris.GetIndexOrAppend(serverUris.GetString((uint)ii));
                        }
                    }
                }

                // setup the mappings to use during decoding.
                decoder.SetMappingTables(namespaceUris, serverUris);

                int count = decoder.ReadInt32(null);

                for (int ii = 0; ii < count; ii++)
                {
                    NodeState state = NodeState.LoadNode(context, decoder);
                    this.Add(state);
                }
            }
        }
        protected void ReadAsymmetricMessageHeader(
            BinaryDecoder decoder,
            X509Certificate2 receiverCertificate,
            out uint secureChannelId,
            out X509Certificate2 senderCertificate,
            out string securityPolicyUri)
        {
            senderCertificate = null;

            uint messageType = decoder.ReadUInt32(null);
            uint messageSize = decoder.ReadUInt32(null);

            // decode security header.
            byte[] certificateData = null;
            byte[] thumbprintData  = null;

            try
            {
                secureChannelId   = decoder.ReadUInt32(null);
                securityPolicyUri = decoder.ReadString(null, TcpMessageLimits.MaxSecurityPolicyUriSize);
                certificateData   = decoder.ReadByteString(null, TcpMessageLimits.MaxCertificateSize);
                thumbprintData    = decoder.ReadByteString(null, TcpMessageLimits.CertificateThumbprintSize);
            }
            catch (Exception e)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadSecurityChecksFailed,
                          e,
                          "The asymmetric security header could not be parsed.");
            }

            // verify sender certificate.
            if (certificateData != null && certificateData.Length > 0)
            {
                senderCertificate = CertificateFactory.Create(certificateData, true);

                try
                {
                    string thumbprint = senderCertificate.Thumbprint;

                    if (thumbprint == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Invalid certificate thumbprint.");
                    }
                }
                catch (Exception e)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, e, "The sender's certificate could not be parsed.");
                }
            }
            else
            {
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The sender's certificate was not specified.");
                }
            }

            // verify receiver thumbprint.
            if (thumbprintData != null && thumbprintData.Length > 0)
            {
                if (receiverCertificate.Thumbprint.ToUpperInvariant() != GetThumbprintString(thumbprintData))
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint is not valid.");
                }
            }
            else
            {
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint was not specified.");
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Processes a request message.
        /// </summary>
        private bool ProcessRequestMessage(uint messageType, ArraySegment <byte> messageChunk)
        {
            // validate the channel state.
            if (State != TcpChannelState.Open)
            {
                ForceChannelFault(StatusCodes.BadTcpMessageTypeInvalid, "Client sent an unexpected request message.");
                return(false);
            }

            // validate security on the message.
            TcpChannelToken token          = null;
            uint            requestId      = 0;
            uint            sequenceNumber = 0;

            ArraySegment <byte> messageBody;

            try
            {
                messageBody = ReadSymmetricMessage(messageChunk, true, out token, out requestId, out sequenceNumber);

                // check for replay attacks.
                if (!VerifySequenceNumber(sequenceNumber, "ProcessRequestMessage"))
                {
                    throw new ServiceResultException(StatusCodes.BadSequenceNumberInvalid);
                }

                if (token == CurrentToken && PreviousToken != null && !PreviousToken.Expired)
                {
                    Utils.Trace("Server Revoked Token. ChannelId={1}, TokenId={0}", PreviousToken.TokenId, PreviousToken.ChannelId, DateTime.UtcNow);
                    PreviousToken.Lifetime = 0;
                }
            }
            catch (Exception e)
            {
                Utils.Trace("Could not verify security on incoming request.");
                ForceChannelFault(e, StatusCodes.BadSecurityChecksFailed, "Could not verify security on incoming request.");
                return(false);
            }

            BufferCollection chunksToProcess = null;

            try
            {
                // check for an abort.
                if (TcpMessageType.IsAbort(messageType))
                {
                    Utils.Trace("Request was aborted.");
                    chunksToProcess = GetSavedChunks(requestId, messageBody);
                    return(true);
                }

                // check if it is necessary to wait for more chunks.
                if (!TcpMessageType.IsFinal(messageType))
                {
                    SaveIntermediateChunk(requestId, messageBody);
                    return(true);
                }

                Utils.Trace("Channel {0}: ProcessRequestMessage {1}", ChannelId, requestId);

                // get the chunks to process.
                chunksToProcess = GetSavedChunks(requestId, messageBody);

                // decode the request.
                IServiceRequest request = BinaryDecoder.DecodeMessage(new ArraySegmentStream(chunksToProcess), null, Quotas.MessageContext) as IServiceRequest;

                if (request == null)
                {
                    SendServiceFault(token, requestId, ServiceResult.Create(StatusCodes.BadStructureMissing, "Could not parse request body."));
                    return(true);
                }

                // ensure that only discovery requests come through unsecured.
                if (DiscoveryOnly)
                {
                    if (!(request is GetEndpointsRequest || request is FindServersRequest))
                    {
                        SendServiceFault(token, requestId, ServiceResult.Create(StatusCodes.BadSecurityPolicyRejected, "Channel can only be used for discovery."));
                        return(true);
                    }
                }

                // hand the request to the server.
                if (m_RequestReceived != null)
                {
                    m_RequestReceived(this, requestId, request);
                }

                return(true);
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error processing request.");
                SendServiceFault(token, requestId, ServiceResult.Create(e, StatusCodes.BadTcpInternalError, "Unexpected error processing request."));
                return(false);
            }
            finally
            {
                if (chunksToProcess != null)
                {
                    chunksToProcess.Release(BufferManager, "ProcessRequestMessage");
                }
            }
        }
Ejemplo n.º 5
0
 public Response(Requestor requestor, RpcRequest request, BinaryDecoder input)
 {
     this.requestor = requestor;
     this.request   = request;
     this.input     = input;
 }
Ejemplo n.º 6
0
        protected ArraySegment<byte> ReadSymmetricMessage(
            ArraySegment<byte>  buffer,
            bool                isRequest,
            out TcpChannelToken token,
            out uint            requestId,
            out uint            sequenceNumber)
        {            
            BinaryDecoder decoder = new BinaryDecoder(buffer.Array, buffer.Offset, buffer.Count, Quotas.MessageContext);
                      
            uint messageType = decoder.ReadUInt32(null);
            uint messageSize = decoder.ReadUInt32(null);
            uint channelId   = decoder.ReadUInt32(null);
            uint tokenId     = decoder.ReadUInt32(null);

            // ensure the channel is valid.
            if (channelId != ChannelId)
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadTcpSecureChannelUnknown,
                    "SecureChannelId is not known. ChanneId={0}, CurrentChannelId={1}", 
                    channelId,
                    ChannelId);
            }

            // check for a message secured with the new token.
            if (RenewedToken != null && RenewedToken.TokenId == tokenId)
            {
                ActivateToken(RenewedToken);
            }

            // check if activation of the new token should be forced.
            if (RenewedToken != null && CurrentToken.ActivationRequired)
            {
                ActivateToken(RenewedToken);

                Utils.Trace("Token #{0} activated forced.", CurrentToken.TokenId);
            }

            // check for valid token.
            TcpChannelToken currentToken = CurrentToken;

            if (currentToken == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecureChannelClosed);
            }

            // find the token.
            if (currentToken.TokenId != tokenId && PreviousToken != null && PreviousToken.TokenId != tokenId)
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadTcpSecureChannelUnknown,
                    "TokenId is not known. ChanneId={0}, TokenId={1}, CurrentTokenId={2}, PreviousTokenId={3}", 
                    channelId, 
                    tokenId,
                    currentToken.TokenId,
                    (PreviousToken != null)?(int)PreviousToken.TokenId:-1);
            }

            token = currentToken;

            // check for a message secured with the token before it expired.
            if (PreviousToken != null && PreviousToken.TokenId == tokenId)
            {
                token = PreviousToken;
            }
            
            // check if token has expired.
            if (token.Expired)
            {
                throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Token #{0} has expired. CreatedAt = {1:HH:mm:ss.fff} . Lifetime = {2}", token.TokenId, token.CreatedAt, token.Lifetime);
            }

            int headerSize = decoder.Position;

            if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
            {
                // decrypt the message.
                Decrypt(token, new ArraySegment<byte>(buffer.Array, buffer.Offset + headerSize, buffer.Count - headerSize), isRequest);
            }
      
            if (SecurityMode != MessageSecurityMode.None)
            {
                // extract signature.
                byte[] signature = new byte[SymmetricSignatureSize];

                for (int ii = 0; ii < SymmetricSignatureSize; ii++)
                {
                    signature[ii] = buffer.Array[buffer.Offset+buffer.Count-SymmetricSignatureSize+ii];
                }
                
                // verify the signature.                                    
                if (!Verify(token, signature, new ArraySegment<byte>(buffer.Array, buffer.Offset, buffer.Count - SymmetricSignatureSize), isRequest))
                {
                    Utils.Trace("Could not verify signature on message.");
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the signature on the message.");
                }
             }
            
            int paddingCount = 0;
      
            if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
            {
                // verify padding.
                int paddingStart = buffer.Offset + buffer.Count - SymmetricSignatureSize - 1;
                paddingCount = buffer.Array[paddingStart];

                for (int ii = paddingStart - paddingCount; ii < paddingStart; ii++)
                {
                    if (buffer.Array[ii] != paddingCount)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the padding in the message.");
                    }
                }

                // add byte for size.
                paddingCount++;
            }

            // extract request id and sequence number.
            sequenceNumber = decoder.ReadUInt32(null);
            requestId = decoder.ReadUInt32(null);

            // return an the data contained in the message.
            int startOfBody = buffer.Offset + TcpMessageLimits.SymmetricHeaderSize + TcpMessageLimits.SequenceHeaderSize;
            int sizeOfBody  = buffer.Count - TcpMessageLimits.SymmetricHeaderSize - TcpMessageLimits.SequenceHeaderSize - paddingCount - SymmetricSignatureSize;

            return new ArraySegment<byte>(buffer.Array, startOfBody, sizeOfBody);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Processes an Error message received over the socket.
        /// </summary>
        protected bool ProcessErrorMessage(uint messageType, ArraySegment<byte> messageChunk)
        {
            // Utils.Trace("Channel {0}: ProcessErrorMessage()", ChannelId);

            // read request buffer sizes.            
            MemoryStream istrm = new MemoryStream(messageChunk.Array, messageChunk.Offset, messageChunk.Count, false);
            BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);

            istrm.Seek(TcpMessageLimits.MessageTypeAndSize, SeekOrigin.Current);

            try
            {                
                ServiceResult error = ReadErrorMessageBody(decoder);
                
                // check if a handshake is in progress
                if (m_handshakeOperation != null)
                {
                    m_handshakeOperation.Fault(error);
                    return false;
                }

                // handle the fatal error.
                ForceReconnect(error);
                return false;
            }
            finally
            {
                decoder.Close();
            }
        }        
        /// <summary>
        /// Processes an OpenSecureChannel request message.
        /// </summary>
        protected ArraySegment<byte> ReadAsymmetricMessage(
            ArraySegment<byte>   buffer,
            X509Certificate2     receiverCertificate,
            out uint             channelId,
            out X509Certificate2 senderCertificate,
            out uint             requestId,
            out uint             sequenceNumber)
        {            
            BinaryDecoder decoder = new BinaryDecoder(buffer.Array, buffer.Offset, buffer.Count, Quotas.MessageContext);
            
            string securityPolicyUri = null;

            //X509Certificate2Collection senderCertificateChain;
            // parse the security header.
            ReadAsymmetricMessageHeader(
                decoder,
                receiverCertificate,
                out channelId,
                out senderCertificate,
                out securityPolicyUri);

            /*senderCertificate = null;
            if (senderCertificateChain != null && senderCertificateChain.Count > 0)
            {
                senderCertificate = senderCertificateChain[0];
            }*/

            // validate the sender certificate.
            if (senderCertificate != null && Quotas.CertificateValidator != null && securityPolicyUri != SecurityPolicies.None)
            {
                //(Quotas.CertificateValidator as Opc.Ua.CertificateValidator.WcfValidatorWrapper).Validate(senderCertificateChain);
                Quotas.CertificateValidator.Validate(senderCertificate);
            }
                 
            // check if this is the first open secure channel request.
            if (!m_uninitialized)
            {
                if (securityPolicyUri != m_securityPolicyUri)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "Cannot change the security policy after creating the channnel.");
                }
            }
            else
            {
                // find a matching endpoint description.
                if (m_endpoints != null)
                {
                    foreach (EndpointDescription endpoint in m_endpoints)
                    {       
                        // There may be multiple endpoints with the same securityPolicyUri.
                        // Just choose the first one that matches. This choice will be re-examined
                        // When the OpenSecureChannel request body is processed.
                        if (endpoint.SecurityPolicyUri == securityPolicyUri || (securityPolicyUri == SecurityPolicies.None && endpoint.SecurityMode == MessageSecurityMode.None))
                        {
                            m_securityMode      = endpoint.SecurityMode;
                            m_securityPolicyUri = securityPolicyUri;
                            m_discoveryOnly     = false;
                            m_uninitialized     = false;
                            m_selectedEndpoint  = endpoint;
                            
                            // recalculate the key sizes.
                            CalculateSymmetricKeySizes();
                            break;
                        }
                    }
                }
                
                // allow a discovery only channel with no security if policy not suppported
                if (m_uninitialized)
                {
                    if (securityPolicyUri != SecurityPolicies.None)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "The security policy is not supported.");
                    }

                    m_securityMode      = MessageSecurityMode.None;
                    m_securityPolicyUri = SecurityPolicies.None;
                    m_discoveryOnly     = true;
                    m_uninitialized     = false;      
                    m_selectedEndpoint  = null;
                }
            }

            int headerSize = decoder.Position;

            // decrypt the body.
            ArraySegment<byte> plainText = Decrypt(
                new ArraySegment<byte>(buffer.Array, buffer.Offset + headerSize, buffer.Count - headerSize),
                new ArraySegment<byte>(buffer.Array, buffer.Offset, headerSize),
                receiverCertificate);
            
            // extract signature.
            int signatureSize = GetAsymmetricSignatureSize(senderCertificate);

            byte[] signature = new byte[signatureSize];

            for (int ii = 0; ii < signatureSize; ii++)
            {
                signature[ii] = plainText.Array[plainText.Offset+plainText.Count-signatureSize+ii];
            }
            
            // verify the signature.
            ArraySegment<byte> dataToVerify = new ArraySegment<byte>(plainText.Array, plainText.Offset, plainText.Count-signatureSize);
                                    
            if (!Verify(dataToVerify, signature, senderCertificate))
            {                
                Utils.Trace("Could not verify signature on message.");
                throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the signature on the message.");
            }

            // verify padding.
            int paddingCount = 0;

            if (SecurityMode != MessageSecurityMode.None)
            {
                int paddingEnd = -1;
                if (receiverCertificate.PublicKey.Key.KeySize > TcpMessageLimits.KeySizeExtraPadding)
                {
                    paddingEnd = plainText.Offset + plainText.Count - signatureSize - 1;
                    paddingCount = plainText.Array[paddingEnd - 1] + plainText.Array[paddingEnd] * 256;

                    //parse until paddingStart-1; the last one is actually the extrapaddingsize
                    for (int ii = paddingEnd - paddingCount; ii < paddingEnd; ii++)
                    {
                        if (plainText.Array[ii] != plainText.Array[paddingEnd - 1])
                        {
                            throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the padding in the message.");
                        }
                    }
                }
                else
                {
                    paddingEnd = plainText.Offset + plainText.Count - signatureSize - 1;
                    paddingCount = plainText.Array[paddingEnd];

                    for (int ii = paddingEnd - paddingCount; ii < paddingEnd; ii++)
                    {
                        if (plainText.Array[ii] != plainText.Array[paddingEnd])
                        {
                            throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the padding in the message.");
                        }
                    }
                }

                paddingCount++;
            }

            // decode message.
            decoder = new BinaryDecoder(
                plainText.Array, 
                plainText.Offset + headerSize, 
                plainText.Count - headerSize, 
                Quotas.MessageContext);
            
            sequenceNumber = decoder.ReadUInt32(null);
            requestId = decoder.ReadUInt32(null);

            headerSize += decoder.Position;
            decoder.Close();

            // Utils.Trace("Security Policy: {0}", SecurityPolicyUri);
            // Utils.Trace("Sender Certificate: {0}", (senderCertificate != null)?senderCertificate.Subject:"(none)");

            // return the body.
            return new ArraySegment<byte>(
                plainText.Array, 
                plainText.Offset + headerSize, 
                plainText.Count - headerSize - signatureSize - paddingCount);
        }
        private async Task<IServiceResponse> ReceiveResponseAsync(CancellationToken token = default(CancellationToken))
        {
            await this.receivingSemaphore.WaitAsync(token).ConfigureAwait(false);
            try
            {
                token.ThrowIfCancellationRequested();
                this.ThrowIfClosedOrNotOpening();
                uint sequenceNumber;
                uint requestId;
                int paddingHeaderSize;
                int plainHeaderSize;
                int bodySize;
                int paddingSize;

                var bodyStream = SerializableBytes.CreateWritableStream();
                var bodyDecoder = new BinaryDecoder(bodyStream, this);
                try
                {
                    // read chunks
                    int chunkCount = 0;
                    bool isFinal = false;
                    do
                    {
                        chunkCount++;
                        if (this.LocalMaxChunkCount > 0 && chunkCount > this.LocalMaxChunkCount)
                        {
                            throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                        }

                        var count = await this.ReceiveAsync(this.receiveBuffer, 0, (int)this.LocalReceiveBufferSize, token).ConfigureAwait(false);
                        if (count == 0)
                        {
                            return null;
                        }

                        var stream = new MemoryStream(this.receiveBuffer, 0, count, true, true);
                        var decoder = new BinaryDecoder(stream, this);
                        try
                        {
                            uint channelId;
                            uint messageType = decoder.ReadUInt32(null);
                            int messageLength = (int)decoder.ReadUInt32(null);
                            Debug.Assert(count == messageLength, "Bytes received not equal to encoded Message length");
                            switch (messageType)
                            {
                                case UaTcpMessageTypes.MSGF:
                                case UaTcpMessageTypes.MSGC:
                                    // header
                                    channelId = decoder.ReadUInt32(null);
                                    if (channelId != this.ChannelId)
                                    {
                                        throw new ServiceResultException(StatusCodes.BadTcpSecureChannelUnknown);
                                    }

                                    // symmetric security header
                                    var tokenId = decoder.ReadUInt32(null);

                                    // detect new token
                                    if (tokenId != this.currentServerTokenId)
                                    {
                                        this.currentServerTokenId = tokenId;

                                        // update with new keys
                                        if (this.symIsSigned)
                                        {
                                            this.symVerifier.Key = this.serverSigningKey;
                                            if (this.symIsEncrypted)
                                            {
                                                this.currentServerEncryptingKey = this.serverEncryptingKey;
                                                this.currentServerInitializationVector = this.serverInitializationVector;
                                                this.symDecryptor = this.symEncryptionAlgorithm.CreateDecryptor(this.currentServerEncryptingKey, this.currentServerInitializationVector);
                                            }
                                        }
                                    }

                                    plainHeaderSize = decoder.Position;

                                    // decrypt
                                    if (this.symIsEncrypted)
                                    {
                                        using (var symDecryptor = this.symEncryptionAlgorithm.CreateDecryptor(this.currentServerEncryptingKey, this.currentServerInitializationVector))
                                        {
                                            int inputCount = messageLength - plainHeaderSize;
                                            Debug.Assert(inputCount % symDecryptor.InputBlockSize == 0, "Input data is not an even number of encryption blocks.");
                                            symDecryptor.TransformBlock(this.receiveBuffer, plainHeaderSize, inputCount, this.receiveBuffer, plainHeaderSize);
                                            symDecryptor.TransformFinalBlock(this.receiveBuffer, messageLength, 0);
                                        }
                                    }

                                    // verify
                                    if (this.symIsSigned)
                                    {
                                        var datalen = messageLength - this.symSignatureSize;
                                        byte[] signature = this.symVerifier.ComputeHash(this.receiveBuffer, 0, datalen);
                                        if (!signature.SequenceEqual(this.receiveBuffer.AsArraySegment(datalen, this.symSignatureSize)))
                                        {
                                            throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed);
                                        }
                                    }

                                    // read sequence header
                                    sequenceNumber = decoder.ReadUInt32(null);
                                    requestId = decoder.ReadUInt32(null);

                                    // body
                                    if (this.symIsEncrypted)
                                    {
                                        if (this.symEncryptionBlockSize > 256)
                                        {
                                            paddingHeaderSize = 2;
                                            paddingSize = BitConverter.ToInt16(this.receiveBuffer, messageLength - this.symSignatureSize - paddingHeaderSize);
                                        }
                                        else
                                        {
                                            paddingHeaderSize = 1;
                                            paddingSize = this.receiveBuffer[messageLength - this.symSignatureSize - paddingHeaderSize];
                                        }

                                        bodySize = messageLength - plainHeaderSize - SequenceHeaderSize - paddingSize - paddingHeaderSize - this.symSignatureSize;
                                    }
                                    else
                                    {
                                        bodySize = messageLength - plainHeaderSize - SequenceHeaderSize - this.symSignatureSize;
                                    }

                                    bodyStream.Write(this.receiveBuffer, plainHeaderSize + SequenceHeaderSize, bodySize);
                                    isFinal = messageType == UaTcpMessageTypes.MSGF;
                                    break;

                                case UaTcpMessageTypes.OPNF:
                                case UaTcpMessageTypes.OPNC:
                                    // header
                                    channelId = decoder.ReadUInt32(null);

                                    // asymmetric header
                                    var securityPolicyUri = decoder.ReadString(null);
                                    var serverCertificateByteString = decoder.ReadByteString(null);
                                    var clientThumbprint = decoder.ReadByteString(null);
                                    plainHeaderSize = decoder.Position;

                                    // decrypt
                                    if (this.asymIsEncrypted)
                                    {
                                        byte[] cipherTextBlock = new byte[this.asymLocalCipherTextBlockSize];
                                        int jj = plainHeaderSize;
                                        for (int ii = plainHeaderSize; ii < messageLength; ii += this.asymLocalCipherTextBlockSize)
                                        {
                                            Buffer.BlockCopy(this.receiveBuffer, ii, cipherTextBlock, 0, this.asymLocalCipherTextBlockSize);

                                            // decrypt with local private key.
                                            byte[] plainTextBlock = this.LocalPrivateKey.Decrypt(cipherTextBlock, this.asymEncryptionPadding);
                                            Debug.Assert(plainTextBlock.Length == this.asymLocalPlainTextBlockSize, "Decrypted block length was not as expected.");
                                            Buffer.BlockCopy(plainTextBlock, 0, this.receiveBuffer, jj, this.asymLocalPlainTextBlockSize);
                                            jj += this.asymLocalPlainTextBlockSize;
                                        }

                                        messageLength = jj;
                                        decoder.Position = plainHeaderSize;
                                    }

                                    // verify
                                    if (this.asymIsSigned)
                                    {
                                        // verify with remote public key.
                                        var datalen = messageLength - this.asymRemoteSignatureSize;
                                        if (!this.RemotePublicKey.VerifyData(this.receiveBuffer, 0, datalen, this.receiveBuffer.AsArraySegment(datalen, this.asymRemoteSignatureSize).ToArray(), this.asymSignatureHashAlgorithmName, RSASignaturePadding.Pkcs1))
                                        {
                                            throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed);
                                        }
                                    }

                                    // sequence header
                                    sequenceNumber = decoder.ReadUInt32(null);
                                    requestId = decoder.ReadUInt32(null);

                                    // body
                                    if (this.asymIsEncrypted)
                                    {
                                        if (this.asymLocalCipherTextBlockSize > 256)
                                        {
                                            paddingHeaderSize = 2;
                                            paddingSize = BitConverter.ToInt16(this.receiveBuffer, messageLength - this.asymRemoteSignatureSize - paddingHeaderSize);
                                        }
                                        else
                                        {
                                            paddingHeaderSize = 1;
                                            paddingSize = this.receiveBuffer[messageLength - this.asymRemoteSignatureSize - paddingHeaderSize];
                                        }

                                        bodySize = messageLength - plainHeaderSize - SequenceHeaderSize - paddingSize - paddingHeaderSize - this.asymRemoteSignatureSize;
                                    }
                                    else
                                    {
                                        bodySize = messageLength - plainHeaderSize - SequenceHeaderSize - this.asymRemoteSignatureSize;
                                    }

                                    bodyStream.Write(this.receiveBuffer, plainHeaderSize + SequenceHeaderSize, bodySize);
                                    isFinal = messageType == UaTcpMessageTypes.OPNF;
                                    break;

                                case UaTcpMessageTypes.ERRF:
                                case UaTcpMessageTypes.MSGA:
                                case UaTcpMessageTypes.OPNA:
                                case UaTcpMessageTypes.CLOA:
                                    var code = (StatusCode)decoder.ReadUInt32(null);
                                    var message = decoder.ReadString(null);
                                    throw new ServiceResultException(code, message);

                                default:
                                    throw new ServiceResultException(StatusCodes.BadUnknownResponse);
                            }

                            if (this.LocalMaxMessageSize > 0 && bodyStream.Position > this.LocalMaxMessageSize)
                            {
                                throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                            }
                        }
                        finally
                        {
                            decoder.Dispose();
                        }
                    }
                    while (!isFinal);
                    bodyStream.Seek(0L, SeekOrigin.Begin);
                    var nodeId = bodyDecoder.ReadNodeId(null);
                    IServiceResponse response;

                    // fast path
                    if (nodeId == PublishResponseNodeId)
                    {
                        response = new PublishResponse();
                    }
                    else if (nodeId == ReadResponseNodeId)
                    {
                        response = new ReadResponse();
                    }
                    else
                    {
                        // find node in dictionary
                        Type type2;
                        if (!BinaryEncodingIdToTypeDictionary.TryGetValue(NodeId.ToExpandedNodeId(nodeId, this.NamespaceUris), out type2))
                        {
                            throw new ServiceResultException(StatusCodes.BadEncodingError, "NodeId not registered in dictionary.");
                        }

                        // create response
                        response = (IServiceResponse)Activator.CreateInstance(type2);
                    }

                    // set properties from message stream
                    response.Decode(bodyDecoder);
                    return response;
                }
                finally
                {
                    bodyDecoder.Dispose();
                }
            }
            finally
            {
                this.receivingSemaphore.Release();
            }
        }
Ejemplo n.º 10
0
 public IGenericRecord Read(Stream inputStream)
 {
     try
     {
         var decoder    = new BinaryDecoder(inputStream);
         var avroRecord = _reader.Read(default, decoder);
Ejemplo n.º 11
0
        public static int AvroDecodeInt(BinaryReader stream)
        {
            BinaryDecoder _e = new BinaryDecoder(stream.BaseStream);

            return(_e.ReadInt());
        }
Ejemplo n.º 12
0
 public bool Decode(BinaryDecoder decoder)
 {
     if (!BinaryCodec.Decode(decoder, out _id))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _name))
     {
         return(false);
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _tileMaterial = (E_TileMaterial)enumValue;
     }
     if (!BinaryCodec.Decode(decoder, out _isMove))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _groupname))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _randomCount))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _isAutoTile))
     {
         return(false);
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _autoTileType = (E_AutoTile)enumValue;
     }
     if (!BinaryCodec.Decode(decoder, out _subPath))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _spritePack))
     {
         return(false);
     }
     {
         ushort _size = 0;
         if (!BinaryCodec.Decode(decoder, out _size))
         {
             return(false);
         }
         sprites.Capacity = _size;
         for (int i = 0; i < _size; ++i)
         {
             string item = null;
             if (!BinaryCodec.Decode(decoder, out item))
             {
                 return(false);
             }
             sprites.Add(item);
         }
     }
     return(true);
 }
Ejemplo n.º 13
0
 public bool Decode(BinaryDecoder decoder)
 {
     if (!BinaryCodec.Decode(decoder, out _id))
     {
         return(false);
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _tileMapType = (E_TileMap)enumValue;
     }
     if (!BinaryCodec.Decode(decoder, out _name))
     {
         return(false);
     }
     if (!BinaryCodec.DecodeUnicodeString(decoder, out _displayName))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _sizeX))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _sizeY))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _isFog))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _groupname))
     {
         return(false);
     }
     {
         ushort _size = 0;
         if (!BinaryCodec.Decode(decoder, out _size))
         {
             return(false);
         }
         bgTileSets.Capacity = _size;
         for (int i = 0; i < _size; ++i)
         {
             string item = null;
             if (!BinaryCodec.Decode(decoder, out item))
             {
                 return(false);
             }
             bgTileSets.Add(item);
         }
     }
     {
         ushort _size = 0;
         if (!BinaryCodec.Decode(decoder, out _size))
         {
             return(false);
         }
         objectTileSets.Capacity = _size;
         for (int i = 0; i < _size; ++i)
         {
             string item = null;
             if (!BinaryCodec.Decode(decoder, out item))
             {
                 return(false);
             }
             objectTileSets.Add(item);
         }
     }
     return(true);
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Decode a scalar type
        /// </summary>
        /// <param name="binaryDecoder"></param>
        /// <param name="builtInType"></param>
        /// <returns>The decoded object</returns>
        private object DecodeRawScalar(BinaryDecoder binaryDecoder, byte builtInType)
        {
            switch ((BuiltInType)builtInType)
            {
            case BuiltInType.Boolean:
                return(binaryDecoder.ReadBoolean(null));

            case BuiltInType.SByte:
                return(binaryDecoder.ReadSByte(null));

            case BuiltInType.Byte:
                return(binaryDecoder.ReadByte(null));

            case BuiltInType.Int16:
                return(binaryDecoder.ReadInt16(null));

            case BuiltInType.UInt16:
                return(binaryDecoder.ReadUInt16(null));

            case BuiltInType.Int32:
                return(binaryDecoder.ReadInt32(null));

            case BuiltInType.UInt32:
                return(binaryDecoder.ReadUInt32(null));

            case BuiltInType.Int64:
                return(binaryDecoder.ReadInt64(null));

            case BuiltInType.UInt64:
                return(binaryDecoder.ReadUInt64(null));

            case BuiltInType.Float:
                return(binaryDecoder.ReadFloat(null));

            case BuiltInType.Double:
                return(binaryDecoder.ReadDouble(null));

            case BuiltInType.String:
                return(binaryDecoder.ReadString(null));

            case BuiltInType.DateTime:
                return(binaryDecoder.ReadDateTime(null));

            case BuiltInType.Guid:
                return(binaryDecoder.ReadGuid(null));

            case BuiltInType.ByteString:
                return(binaryDecoder.ReadByteString(null));

            case BuiltInType.XmlElement:
                return(binaryDecoder.ReadXmlElement(null));

            case BuiltInType.NodeId:
                return(binaryDecoder.ReadNodeId(null));

            case BuiltInType.ExpandedNodeId:
                return(binaryDecoder.ReadExpandedNodeId(null));

            case BuiltInType.StatusCode:
                return(binaryDecoder.ReadStatusCode(null));

            case BuiltInType.QualifiedName:
                return(binaryDecoder.ReadQualifiedName(null));

            case BuiltInType.LocalizedText:
                return(binaryDecoder.ReadLocalizedText(null));

            case BuiltInType.DataValue:
                return(binaryDecoder.ReadDataValue(null));

            case BuiltInType.Enumeration:
                return(binaryDecoder.ReadInt32(null));

            case BuiltInType.Variant:
                return(binaryDecoder.ReadVariant(null));

            case BuiltInType.ExtensionObject:
                return(binaryDecoder.ReadExtensionObject(null));

            default:
                return(null);
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Handles requests arriving from a channel.
        /// </summary>
        public async Task SendAsync(HttpContext context)
        {
            string            message = string.Empty;
            CancellationToken ct      = context.RequestAborted;

            try
            {
                if (m_callback == null)
                {
                    await WriteResponseAsync(context.Response, message, HttpStatusCode.NotImplemented).ConfigureAwait(false);

                    return;
                }

                if (context.Request.ContentType != kApplicationContentType)
                {
                    message = "HTTPSLISTENER - Unsupported content type.";
                    await WriteResponseAsync(context.Response, message, HttpStatusCode.BadRequest).ConfigureAwait(false);

                    return;
                }

                int    length = (int)context.Request.ContentLength;
                byte[] buffer = await ReadBodyAsync(context.Request).ConfigureAwait(false);

                if (buffer.Length != length)
                {
                    message = "HTTPSLISTENER - Invalid buffer.";
                    await WriteResponseAsync(context.Response, message, HttpStatusCode.BadRequest).ConfigureAwait(false);

                    return;
                }

                IServiceRequest input = (IServiceRequest)BinaryDecoder.DecodeMessage(buffer, null, m_quotas.MessageContext);

                // extract the JWT token from the HTTP headers.
                if (input.RequestHeader == null)
                {
                    input.RequestHeader = new RequestHeader();
                }

                if (NodeId.IsNull(input.RequestHeader.AuthenticationToken) &&
                    input.TypeId != DataTypeIds.CreateSessionRequest)
                {
                    if (context.Request.Headers.ContainsKey(kAuthorizationKey))
                    {
                        foreach (string value in context.Request.Headers[kAuthorizationKey])
                        {
                            if (value.StartsWith(kBearerKey, StringComparison.OrdinalIgnoreCase))
                            {
                                // note: use NodeId(string, uint) to avoid the NodeId.Parse call.
                                input.RequestHeader.AuthenticationToken = new NodeId(value.Substring(kBearerKey.Length + 1).Trim(), 0);
                            }
                        }
                    }
                }

                if (!context.Request.Headers.TryGetValue(Profiles.HttpsSecurityPolicyHeader, out var header))
                {
                    header = SecurityPolicies.None;
                }

                EndpointDescription endpoint = null;
                foreach (var ep in m_descriptions)
                {
                    if (ep.EndpointUrl.StartsWith(Utils.UriSchemeHttps, StringComparison.Ordinal))
                    {
                        if (!string.IsNullOrEmpty(header))
                        {
                            if (!string.Equals(ep.SecurityPolicyUri, header, StringComparison.Ordinal))
                            {
                                continue;
                            }
                        }

                        endpoint = ep;
                        break;
                    }
                }

                if (endpoint == null &&
                    input.TypeId != DataTypeIds.GetEndpointsRequest &&
                    input.TypeId != DataTypeIds.FindServersRequest)
                {
                    message = "Connection refused, invalid security policy.";
                    Utils.LogError(message);
                    await WriteResponseAsync(context.Response, message, HttpStatusCode.Unauthorized).ConfigureAwait(false);

                    return;
                }

                // note: do not use Task.Factory.FromAsync here
                var result = m_callback.BeginProcessRequest(
                    m_listenerId,
                    endpoint,
                    input as IServiceRequest,
                    null,
                    null);

                IServiceResponse output = m_callback.EndProcessRequest(result);

                byte[] response = BinaryEncoder.EncodeMessage(output, m_quotas.MessageContext);
                context.Response.ContentLength = response.Length;
                context.Response.ContentType   = context.Request.ContentType;
                context.Response.StatusCode    = (int)HttpStatusCode.OK;
#if NETSTANDARD2_1 || NET5_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER
                await context.Response.Body.WriteAsync(response.AsMemory(0, response.Length), ct).ConfigureAwait(false);
#else
                await context.Response.Body.WriteAsync(response, 0, response.Length, ct).ConfigureAwait(false);
#endif
                return;
            }
            catch (Exception e)
            {
                message = "HTTPSLISTENER - Unexpected error processing request.";
                Utils.LogError(e, message);
            }

            await WriteResponseAsync(context.Response, message, HttpStatusCode.InternalServerError).ConfigureAwait(false);
        }
Ejemplo n.º 16
0
        private bool ProcessHelloMessage(ArraySegment <byte> messageChunk)
        {
            // validate the channel state.
            if (State != TcpChannelState.Connecting)
            {
                ForceChannelFault(StatusCodes.BadTcpMessageTypeInvalid, "Client sent an unexpected Hello message.");
                return(false);
            }

            try
            {
                MemoryStream  istrm   = new MemoryStream(messageChunk.Array, messageChunk.Offset, messageChunk.Count, false);
                BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);
                istrm.Seek(TcpMessageLimits.MessageTypeAndSize, SeekOrigin.Current);

                // read requested buffer sizes.
                uint protocolVersion   = decoder.ReadUInt32(null);
                uint receiveBufferSize = decoder.ReadUInt32(null);
                uint sendBufferSize    = decoder.ReadUInt32(null);
                uint maxMessageSize    = decoder.ReadUInt32(null);
                uint maxChunkCount     = decoder.ReadUInt32(null);

                // read the endpoint url.
                int length = decoder.ReadInt32(null);

                if (length > 0)
                {
                    if (length > TcpMessageLimits.MaxEndpointUrlLength)
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return(false);
                    }

                    byte[] endpointUrl = new byte[length];

                    for (int ii = 0; ii < endpointUrl.Length; ii++)
                    {
                        endpointUrl[ii] = decoder.ReadByte(null);
                    }

                    if (!SetEndpointUrl(new UTF8Encoding().GetString(endpointUrl, 0, endpointUrl.Length)))
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return(false);
                    }
                }

                decoder.Close();

                // update receive buffer size.
                if (receiveBufferSize < ReceiveBufferSize)
                {
                    ReceiveBufferSize = (int)receiveBufferSize;
                }

                if (ReceiveBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    ReceiveBufferSize = TcpMessageLimits.MinBufferSize;
                }

                // update send buffer size.
                if (sendBufferSize < SendBufferSize)
                {
                    SendBufferSize = (int)sendBufferSize;
                }

                if (SendBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    SendBufferSize = TcpMessageLimits.MinBufferSize;
                }

                // update the max message size.
                if (maxMessageSize > 0 && maxMessageSize < MaxResponseMessageSize)
                {
                    MaxResponseMessageSize = (int)maxMessageSize;
                }

                if (MaxResponseMessageSize < SendBufferSize)
                {
                    MaxResponseMessageSize = SendBufferSize;
                }

                // update the max chunk count.
                if (maxChunkCount > 0 && maxChunkCount < MaxResponseChunkCount)
                {
                    MaxResponseChunkCount = (int)maxChunkCount;
                }

                // send acknowledge.
                byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "ProcessHelloMessage");

                try
                {
                    MemoryStream  ostrm   = new MemoryStream(buffer, 0, SendBufferSize);
                    BinaryEncoder encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);

                    encoder.WriteUInt32(null, TcpMessageType.Acknowledge);
                    encoder.WriteUInt32(null, 0);
                    encoder.WriteUInt32(null, 0); // ProtocolVersion
                    encoder.WriteUInt32(null, (uint)ReceiveBufferSize);
                    encoder.WriteUInt32(null, (uint)SendBufferSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestMessageSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestChunkCount);

                    int size = encoder.Close();
                    UpdateMessageSize(buffer, 0, size);

                    // now ready for the open or bind request.
                    State = TcpChannelState.Opening;

                    BeginWriteMessage(new ArraySegment <byte>(buffer, 0, size), null);
                    buffer = null;
                }
                finally
                {
                    if (buffer != null)
                    {
                        BufferManager.ReturnBuffer(buffer, "ProcessHelloMessage");
                    }
                }
            }
            catch (Exception e)
            {
                ForceChannelFault(e, StatusCodes.BadTcpInternalError, "Unexpected error while processing a Hello message.");
            }

            return(false);
        }
Ejemplo n.º 17
0
        public static void TestSpecific(string str, object[] result)
        {
            Protocol protocol = Protocol.Parse(str);
            var codegen = new CodeGen();
            codegen.AddProtocol(protocol);
            var compileUnit = codegen.GenerateCode();

            // add a constructor to the main class using the passed assignment statements
            CodeTypeDeclaration ctd = compileUnit.Namespaces[0].Types[(int)result[0]];
            CodeConstructor constructor = new CodeConstructor();
            constructor.Attributes = MemberAttributes.Public;
            CodeSnippetExpression snippet = new CodeSnippetExpression((string)result[2]);
            constructor.Statements.Add(snippet);
            ctd.Members.Add(constructor);

            // compile
            var comparam = new CompilerParameters(new string[] { "mscorlib.dll" });
            comparam.ReferencedAssemblies.Add("System.dll");
            comparam.ReferencedAssemblies.Add("System.Core.dll");
            comparam.ReferencedAssemblies.Add(Type.GetType("Mono.Runtime") != null ? "Mono.CSharp.dll" : "Microsoft.CSharp.dll");
            comparam.ReferencedAssemblies.Add("Avro.dll");
            comparam.GenerateInMemory = true;
            var ccp = new Microsoft.CSharp.CSharpCodeProvider();
            var units = new CodeCompileUnit[] { compileUnit };
            var compres = ccp.CompileAssemblyFromDom(comparam, units);
            if (compres == null || compres.Errors.Count > 0)
            {
                for (int i = 0; i < compres.Errors.Count; i++)
                    Console.WriteLine(compres.Errors[i]);
            }
            if (null != compres)
                Assert.IsTrue(compres.Errors.Count == 0);

            // create record
            ISpecificRecord rec = compres.CompiledAssembly.CreateInstance((string)result[1]) as ISpecificRecord;
            Assert.IsFalse(rec == null);

            // serialize
            var stream = new MemoryStream();
            var binEncoder = new BinaryEncoder(stream);
            var writer = new SpecificDefaultWriter(rec.Schema);
            writer.Write(rec.Schema, rec, binEncoder);

            // deserialize
            stream.Position = 0;
            var decoder = new BinaryDecoder(stream);
            var reader = new SpecificDefaultReader(rec.Schema, rec.Schema);
            var rec2 = (ISpecificRecord)reader.Read(null, rec.Schema, rec.Schema, decoder);
            Assert.IsFalse(rec2 == null);
        }
Ejemplo n.º 18
0
        public static void TestSpecific(string str, object[] result)
        {
            Protocol protocol = Protocol.Parse(str);
            var codegen = new CodeGen();
            codegen.AddProtocol(protocol);
            var compileUnit = codegen.GenerateCode();

            // add a constructor to the main class using the passed assignment statements
            CodeTypeDeclaration ctd = compileUnit.Namespaces[0].Types[(int)result[0]];
            CodeConstructor constructor = new CodeConstructor();
            constructor.Attributes = MemberAttributes.Public;
            CodeSnippetExpression snippet = new CodeSnippetExpression((string)result[2]);
            constructor.Statements.Add(snippet);
            ctd.Members.Add(constructor);

            // add a function to the main class to populate the data
            // This has been moved from constructor, as it was causing some tests to pass that shouldn't when referencing a blank object on READ.

            CodeMemberMethod method = new CodeMemberMethod();
            method.Attributes = MemberAttributes.Public;
            method.Name = "Populate";
            CodeSnippetExpression snippet2 = new CodeSnippetExpression((string)result[3]);
            method.Statements.Add(snippet2);
            ctd.Members.Add(method);

            // compile
            var comparam = new CompilerParameters(new string[] { "mscorlib.dll" });
            comparam.ReferencedAssemblies.Add("System.dll");
            comparam.ReferencedAssemblies.Add("Avro.dll");
            comparam.GenerateInMemory = true;
            var ccp = new Microsoft.CSharp.CSharpCodeProvider();
            var units = new CodeCompileUnit[] { compileUnit };
            var compres = ccp.CompileAssemblyFromDom(comparam, units);
            if (compres == null || compres.Errors.Count > 0)
            {
                for (int i = 0; i < compres.Errors.Count; i++)
                    Console.WriteLine(compres.Errors[i]);
            }
            if (null != compres)
                Assert.IsTrue(compres.Errors.Count == 0);

            // create record
            ISpecificRecord rec = compres.CompiledAssembly.CreateInstance((string)result[1]) as ISpecificRecord;

            // Call populate to put some data in it.
            Type recType = rec.GetType(); ;
            MethodInfo methodInfo = recType.GetMethod("Populate");
            methodInfo.Invoke(rec, null);

            var x1 = compres.CompiledAssembly.FullName;

            Assert.IsFalse(rec == null);

            // serialize
            var stream = new MemoryStream();
            var binEncoder = new BinaryEncoder(stream);
            var writer = new SpecificDefaultWriter(rec.Schema);
            writer.Write(rec.Schema, rec, binEncoder);

            // deserialize
            stream.Position = 0;
            var decoder = new BinaryDecoder(stream);
            var reader = new SpecificDefaultReader(rec.Schema, rec.Schema);
            var rec2 = (ISpecificRecord)reader.Read(null, rec.Schema, rec.Schema, decoder);
            Assert.IsFalse(rec2 == null);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Handles requests arriving from a channel.
        /// </summary>
        public async void SendAsync(HttpContext context)
        {
            IAsyncResult result = null;

            try
            {
                if (m_callback == null)
                {
                    context.Response.ContentLength = 0;
                    context.Response.ContentType   = "text/plain";
                    context.Response.StatusCode    = (int)HttpStatusCode.NotImplemented;
                    await context.Response.WriteAsync(string.Empty);

                    return;
                }

                byte[] buffer = new byte[(int)context.Request.ContentLength];
                lock (m_lock)
                {
                    Task <int> task = context.Request.Body.ReadAsync(buffer, 0, (int)context.Request.ContentLength);
                    task.Wait();
                }

                IServiceRequest input = (IServiceRequest)BinaryDecoder.DecodeMessage(buffer, null, m_quotas.MessageContext);

                // extract the JWT token from the HTTP headers.
                if (input.RequestHeader == null)
                {
                    input.RequestHeader = new RequestHeader();
                }

                if (NodeId.IsNull(input.RequestHeader.AuthenticationToken) && input.TypeId != DataTypeIds.CreateSessionRequest)
                {
                    if (context.Request.Headers.Keys.Contains("Authorization"))
                    {
                        foreach (string value in context.Request.Headers["Authorization"])
                        {
                            if (value.StartsWith("Bearer"))
                            {
                                input.RequestHeader.AuthenticationToken = new NodeId(value.Substring("Bearer ".Length).Trim());
                            }
                        }
                    }
                }

                EndpointDescription endpoint = null;

                foreach (var ep in m_descriptions)
                {
                    if (ep.EndpointUrl.StartsWith(Utils.UriSchemeHttps))
                    {
                        endpoint = ep;
                        break;
                    }
                }

                result = m_callback.BeginProcessRequest(
                    m_listenerId,
                    endpoint,
                    input as IServiceRequest,
                    null,
                    null);

                IServiceResponse output = m_callback.EndProcessRequest(result);

                byte[] response = BinaryEncoder.EncodeMessage(output, m_quotas.MessageContext);
                context.Response.ContentLength = response.Length;
                context.Response.ContentType   = context.Request.ContentType;
                context.Response.StatusCode    = (int)HttpStatusCode.OK;
                await context.Response.Body.WriteAsync(response, 0, response.Length);
            }
            catch (Exception e)
            {
                Utils.Trace(e, "HTTPSLISTENER - Unexpected error processing request.");
                context.Response.ContentLength = e.Message.Length;
                context.Response.ContentType   = "text/plain";
                context.Response.StatusCode    = (int)HttpStatusCode.InternalServerError;
                await context.Response.WriteAsync(e.Message);
            }
        }
Ejemplo n.º 20
0
        private bool ProcessAcknowledgeMessage(ArraySegment<byte> messageChunk)
        {            
            // Utils.Trace("Channel {0}: ProcessAcknowledgeMessage()", ChannelId);

            // check state.
            if (State != TcpChannelState.Connecting)
            {
                ForceReconnect(ServiceResult.Create(StatusCodes.BadTcpMessageTypeInvalid, "Server sent an unexpected acknowledge message."));
                return false;
            }
         
            // check if operation was abandoned.
            if (m_handshakeOperation == null)
            {
                return false;
            }

            // read buffer sizes.
            MemoryStream istrm = new MemoryStream(messageChunk.Array,  messageChunk.Offset, messageChunk.Count);
            BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);

            istrm.Seek(TcpMessageLimits.MessageTypeAndSize, SeekOrigin.Current);

            try
            {
                uint protocolVersion = decoder.ReadUInt32(null);
                SendBufferSize       = (int)decoder.ReadUInt32(null);
                ReceiveBufferSize    = (int)decoder.ReadUInt32(null);
                int maxMessageSize   = (int)decoder.ReadUInt32(null);
                int maxChunkCount    = (int)decoder.ReadUInt32(null);

                // update the max message size.
                if (maxMessageSize > 0 && maxMessageSize < MaxRequestMessageSize)
                {
                    MaxRequestMessageSize = (int)maxMessageSize;
                }
                
                if (MaxRequestMessageSize < SendBufferSize)
                {
                    MaxRequestMessageSize = SendBufferSize;
                }

                // update the max chunk count.
                if (maxChunkCount > 0 && maxChunkCount < MaxRequestChunkCount)
                {
                    MaxRequestChunkCount = (int)maxChunkCount;
                }
            }
            finally
            {
                decoder.Close();
            }

            // valdiate buffer sizes.
            if (ReceiveBufferSize < TcpMessageLimits.MinBufferSize)
            {
                m_handshakeOperation.Fault(StatusCodes.BadTcpNotEnoughResources, "Server receive buffer size is too small ({0} bytes).", ReceiveBufferSize);                
                return false;
            }

            if (SendBufferSize < TcpMessageLimits.MinBufferSize)
            {
                m_handshakeOperation.Fault(StatusCodes.BadTcpNotEnoughResources, "Server send buffer size is too small ({0} bytes).", SendBufferSize);
                return false;
            }
            
            // ready to open the channel.
            State = TcpChannelState.Opening;
            
            try
            {
                // check if reconnecting after a socket failure.
                if (CurrentToken != null)
                {
                    SendOpenSecureChannelRequest(true);
                    return false;
                }
                    
                // open a new connection.
                SendOpenSecureChannelRequest(false);    
            }
            catch (Exception e)
            {
                m_handshakeOperation.Fault(e, StatusCodes.BadTcpInternalError, "Could not send an Open Secure Channel request.");
            }

            return false;
        }
        protected void Decode(byte[] data)
        {
            var receivedTime = DateTime.UtcNow;

            using (var inputStream = new MemoryStream(data))
            {
                // create avro binary decoder to read from memory stream
                var decoder = new BinaryDecoder(inputStream);

                var           record = Activator.CreateInstance <MessageHeader>();
                var           reader = new SpecificReader <MessageHeader>(new EtpSpecificReader(record.Schema, record.Schema));
                MessageHeader header = reader.Read(record, decoder);


                // string message = Encoding.UTF8.GetString(inputStream.ToArray());

                if (header.Protocol == 0 && header.MessageType == 2)
                {
                    lock (m_ConnectionLock)
                    {
                        m_HasConnected = true;
                    }
                    var recordSession = Activator.CreateInstance <OpenSession>();
                    var readerSession = new SpecificReader <OpenSession>(new EtpSpecificReader(recordSession.Schema, recordSession.Schema));
                    readerSession.Read(recordSession, decoder);
                    string message  = ToString(recordSession);
                    var    timediff = receivedTime - m_Time;
                    Message?.Invoke(message, timediff.TotalMilliseconds, TraceLevel.Info);
                }
                else if (header.Protocol == 3 && header.MessageType == 2)
                {
                    var responce   = Activator.CreateInstance <GetResourcesResponse>();
                    var bodyreader = new SpecificReader <GetResourcesResponse>(new EtpSpecificReader(responce.Schema, responce.Schema));
                    GetResourcesResponse bodyheader = bodyreader.Read(responce, decoder);

                    RequestInformation parent;
                    lock (m_RequestInformation)
                    {
                        parent = m_RequestInformation[header.CorrelationId];
                    }

                    var    timediff = receivedTime - parent.RequestTime;
                    string message  = ToString(responce);
                    Message?.Invoke(message, timediff.TotalMilliseconds, TraceLevel.Info);

                    if (parent.ChannelItem == null)
                    {
                        ChannelItem channelItem = new ChannelItem()
                        {
                            Name           = responce.Resource.Name,
                            Uid            = responce.Resource.Uuid,
                            Eml            = responce.Resource.Uri,
                            Level          = 0,
                            ChildrensCount = responce.Resource.HasChildren
                        };

                        ChannelItemsReceived?.Invoke(channelItem);
                    }
                    else
                    {
                        ChannelItem channelItem = new ChannelItem()
                        {
                            Name           = responce.Resource.Name,
                            Uid            = responce.Resource.Uuid,
                            Eml            = responce.Resource.Uri,
                            Level          = parent.ChannelItem.Level + 1,
                            ChildrensCount = responce.Resource.HasChildren
                        };
                        ChannelChildrensReceived?.Invoke(channelItem, parent.ChannelItem);
                    }
                }
                else if (header.Protocol == 1 && header.MessageType == 2)
                {
                    var timediff = receivedTime - m_Time;

                    string message        = "Channels received: [";
                    var    recordMetadata = Activator.CreateInstance <ChannelMetadata>();
                    var    readerMetadata = new SpecificReader <ChannelMetadata>(new EtpSpecificReader(recordMetadata.Schema, recordMetadata.Schema));
                    readerMetadata.Read(recordMetadata, decoder);


                    ChannelMetadata metadata = new ChannelMetadata();
                    metadata.Channels = new List <ChannelMetadataRecord>();
                    lock (m_ChannelStreamingInfo)
                    {
                        foreach (var channel in recordMetadata.Channels)
                        {
                            if (m_LogCurveEml.Contains(channel.ChannelUri, StringComparer.InvariantCultureIgnoreCase))
                            {
                                metadata.Channels.Add(channel);
                                ChannelStreamingInfo channelStreamingInfo = new ChannelStreamingInfo()
                                {
                                    ChannelId  = channel.ChannelId,
                                    StartIndex = new StreamingStartIndex()
                                    {
                                        Item = null
                                    },
                                    ReceiveChangeNotification = true
                                };

                                m_ChannelStreamingInfo.Add(channelStreamingInfo);
                                message = message + $"\n{channel.ChannelId} {channel.ChannelName}";

                                ChannelMetaDataVM channelMetaData_VM = ETPMapper.Instance().Map <ChannelMetaDataVM>(channel);
                                string            json = JsonConvert.SerializeObject(channelMetaData_VM, Formatting.Indented);
                                Message?.Invoke(json, timediff.TotalMilliseconds, TraceLevel.Info);
                            }
                        }

                        ChannelInfoReceived?.Invoke(metadata);
                    }

                    message = message + "\n]";
                    Message?.Invoke(message, timediff.TotalMilliseconds, TraceLevel.Info);

                    HasDescribing = false;
                }
                else if (header.Protocol == 1 && header.MessageType == 3)
                {
                    var recordData = Activator.CreateInstance <ChannelData>();
                    var readerdata = new SpecificReader <ChannelData>(new EtpSpecificReader(recordData.Schema, recordData.Schema));
                    readerdata.Read(recordData, decoder);

                    ChannelDataReceived?.Invoke(recordData.Data);
                }
                else if (header.MessageType == 1000)
                {
                    var timediff   = receivedTime - m_Time;
                    var bodyrecord = Activator.CreateInstance <ProtocolException>();
                    var bodyreader = new SpecificReader <ProtocolException>(new EtpSpecificReader(bodyrecord.Schema, bodyrecord.Schema));
                    ProtocolException bodyheader = bodyreader.Read(bodyrecord, decoder);
                    string            message    = $"Error Received ({bodyrecord.ErrorCode}): {bodyrecord.ErrorMessage}";

                    Message?.Invoke(message, timediff.TotalMilliseconds, TraceLevel.Error);
                    HasDescribing = false;
                }
                else
                {
                    HasDescribing = false;
                }
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Converts a local value to a remote value.
        /// </summary>
        /// <param name="srcValue">The local value.</param>
        /// <param name="srcType">The data type of the local value.</param>
        /// <param name="dstType">The data type of the remote value.</param>
        /// <returns>The remote value.</returns>
        private object ConvertLocalToRemote(object srcValue, BuiltInType srcType, BuiltInType dstType)
        {
            // must determine the type from the source if the containing array is a variant.
            if (srcType == BuiltInType.Variant)
            {
                TypeInfo typeInfo = TypeInfo.Construct(srcValue);
                srcType = typeInfo.BuiltInType;
            }

            // no conversion by default.
            object dstValue = srcValue;

            // apply different conversions depending on the data type.
            switch (dstType)
            {
                case BuiltInType.Guid:
                {
                    dstValue = new Uuid((string)srcValue);
                    break;
                }

                case BuiltInType.XmlElement:
                {
                    XmlDocument document = new XmlDocument();
                    document.InnerXml = (string)srcValue;
                    dstValue = document.DocumentElement;
                    break;
                }

                case BuiltInType.NodeId:
                {
                    dstValue = GetRemoteNodeId((string)srcValue);
                    break;
                }

                case BuiltInType.ExpandedNodeId:
                {
                    ExpandedNodeId nodeId = ExpandedNodeId.Parse((string)srcValue);
                    dstValue = GetRemoteExpandedNodeId(nodeId);
                    break;
                }

                case BuiltInType.QualifiedName:
                {
                    dstValue = GetRemoteBrowseName((string)srcValue);
                    break;
                }

                case BuiltInType.LocalizedText:
                {
                    dstValue = new LocalizedText((string)srcValue);
                    break;
                }

                case BuiltInType.StatusCode:
                {
                    dstValue = new StatusCode((uint)srcValue);
                    break;
                }

                case BuiltInType.ExtensionObject:
                {
                    BinaryDecoder decoder = new BinaryDecoder((byte[])srcValue, m_localMessageContext);
                    dstValue = decoder.ReadExtensionObject(null);
                    decoder.Close();
                    break;
                }

                default:
                {
                    if (dstType != srcType && dstType != BuiltInType.Variant && dstType != BuiltInType.Null)
                    {
                        throw ComUtils.CreateComException(ResultIds.E_BADTYPE);
                    }

                    break;
                }
            }

            // all done.
            return dstValue;
        }
Ejemplo n.º 23
0
 protected abstract bool ReadData(BinaryDecoder decoder);
        protected ArraySegment <byte> ReadSymmetricMessage(
            ArraySegment <byte> buffer,
            bool isRequest,
            out TcpChannelToken token,
            out uint requestId,
            out uint sequenceNumber)
        {
            BinaryDecoder decoder = new BinaryDecoder(buffer.Array, buffer.Offset, buffer.Count, Quotas.MessageContext);

            uint messageType = decoder.ReadUInt32(null);
            uint messageSize = decoder.ReadUInt32(null);
            uint channelId   = decoder.ReadUInt32(null);
            uint tokenId     = decoder.ReadUInt32(null);

            // ensure the channel is valid.
            if (channelId != ChannelId)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadTcpSecureChannelUnknown,
                          "SecureChannelId is not known. ChanneId={0}, CurrentChannelId={1}",
                          channelId,
                          ChannelId);
            }

            // check for valid token.
            TcpChannelToken currentToken = CurrentToken;

            if (currentToken == null)
            {
                throw new ServiceResultException(StatusCodes.BadSecureChannelClosed);
            }

            // find the token.
            if (currentToken.TokenId != tokenId && PreviousToken != null && PreviousToken.TokenId != tokenId)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadTcpSecureChannelUnknown,
                          "TokenId is not known. ChanneId={0}, TokenId={1}, CurrentTokenId={2}, PreviousTokenId={3}",
                          channelId,
                          tokenId,
                          currentToken.TokenId,
                          (PreviousToken != null)?(int)PreviousToken.TokenId:-1);
            }

            token = currentToken;

            // check for a message secured with the token before it expired.
            if (PreviousToken != null && PreviousToken.TokenId == tokenId)
            {
                token = PreviousToken;
            }

            // check if token has expired.
            if (token.Expired)
            {
                throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Token #{0} has expired. Lifetime={1:HH:mm:ss.fff}", token.TokenId, token.CreatedAt);
            }

            int headerSize = decoder.Position;

            if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
            {
                // decrypt the message.
                Decrypt(token, new ArraySegment <byte>(buffer.Array, buffer.Offset + headerSize, buffer.Count - headerSize), isRequest);
            }

            if (SecurityMode != MessageSecurityMode.None)
            {
                // extract signature.
                byte[] signature = new byte[SymmetricSignatureSize];

                for (int ii = 0; ii < SymmetricSignatureSize; ii++)
                {
                    signature[ii] = buffer.Array[buffer.Offset + buffer.Count - SymmetricSignatureSize + ii];
                }

                // verify the signature.
                if (!Verify(token, signature, new ArraySegment <byte>(buffer.Array, buffer.Offset, buffer.Count - SymmetricSignatureSize), isRequest))
                {
                    Utils.Trace("Could not verify signature on message.");
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the signature on the message.");
                }
            }

            int paddingCount = 0;

            if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
            {
                // verify padding.
                int paddingStart = buffer.Offset + buffer.Count - SymmetricSignatureSize - 1;
                paddingCount = buffer.Array[paddingStart];

                for (int ii = paddingStart - paddingCount; ii < paddingStart; ii++)
                {
                    if (buffer.Array[ii] != paddingCount)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the padding in the message.");
                    }
                }

                // add byte for size.
                paddingCount++;
            }

            // extract request id and sequence number.
            sequenceNumber = decoder.ReadUInt32(null);
            requestId      = decoder.ReadUInt32(null);

            // return an the data contained in the message.
            int startOfBody = buffer.Offset + TcpMessageLimits.SymmetricHeaderSize + TcpMessageLimits.SequenceHeaderSize;
            int sizeOfBody  = buffer.Count - TcpMessageLimits.SymmetricHeaderSize - TcpMessageLimits.SequenceHeaderSize - paddingCount - SymmetricSignatureSize;

            return(new ArraySegment <byte>(buffer.Array, startOfBody, sizeOfBody));
        }
Ejemplo n.º 25
0
        /// <summary cref="IClientMessageInspector.AfterReceiveReply" />
        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            // check for fault.
            if (reply.IsFault)
            {
                return;
            }

            // parse request parameters.
            object[] parameters = correlationState as object[];

            if (parameters == null || parameters.Length != 3)
            {
                throw new InvalidOperationException("Cannot decode request because the IClientMessageInspector not configured properly.");
            }

            // extract request parameters.
            MessageVersion  messageVersion = parameters[0] as MessageVersion;
            string          action         = parameters[1] as string;
            IServiceMessage request        = parameters[2] as IServiceMessage;

            object encodeable = null;

            if (!reply.Properties.TryGetValue(MessageProperties.UnencodedBody, out encodeable))
            {
                // extract binary encoded response from body.
                XmlDictionaryReader reader = reply.GetReaderAtBodyContents();
                reader.MoveToStartElement("InvokeServiceResponse", Namespaces.OpcUaXsd);
                byte[] response = reader.ReadElementContentAsBase64();

                // decode body.
                try
                {
                    encodeable = BinaryDecoder.DecodeMessage(response, null, m_messageContext);
                }
                catch (Exception e)
                {
                    ServiceResult error = ServiceResult.Create(
                        e,
                        StatusCodes.BadDecodingError,
                        "Could not decoding incoming response message.");

                    ServiceFault fault = new ServiceFault();

                    fault.ResponseHeader.RequestHandle = request.GetRequest().RequestHeader.RequestHandle;
                    fault.ResponseHeader.Timestamp     = DateTime.UtcNow;
                    fault.ResponseHeader.ServiceResult = error.Code;

                    StringTable stringTable = new StringTable();

                    fault.ResponseHeader.ServiceDiagnostics = new DiagnosticInfo(
                        error,
                        DiagnosticsMasks.NoInnerStatus,
                        true,
                        stringTable);

                    fault.ResponseHeader.StringTable = stringTable.ToArray();

                    encodeable = fault;
                }
            }

            object unencodedBody = request.CreateResponse((IServiceResponse)encodeable);

            // create the unencoded reply message.
            Message unencodedReply = Message.CreateMessage(
                messageVersion,
                action + "Response",
                unencodedBody);

            unencodedReply.Headers.MessageId = reply.Headers.MessageId;
            unencodedReply.Headers.RelatesTo = reply.Headers.RelatesTo;

            unencodedReply.Properties.Add(MessageProperties.UnencodedBody, unencodedBody);

            // replace the incoming message.
            reply = unencodedReply;
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Processes an CloseSecureChannel request message.
        /// </summary>
        private bool ProcessCloseSecureChannelRequest(uint messageType, ArraySegment <byte> messageChunk)
        {
            // validate security on the message.
            TcpChannelToken token          = null;
            uint            requestId      = 0;
            uint            sequenceNumber = 0;

            ArraySegment <byte> messageBody;

            try
            {
                messageBody = ReadSymmetricMessage(messageChunk, true, out token, out requestId, out sequenceNumber);

                // check for replay attacks.
                if (!VerifySequenceNumber(sequenceNumber, "ProcessCloseSecureChannelRequest"))
                {
                    throw new ServiceResultException(StatusCodes.BadSequenceNumberInvalid);
                }
            }
            catch (Exception e)
            {
                throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, e, "Could not verify security on CloseSecureChannel request.");
            }

            BufferCollection chunksToProcess = null;

            try
            {
                // check if it is necessary to wait for more chunks.
                if (!TcpMessageType.IsFinal(messageType))
                {
                    SaveIntermediateChunk(requestId, messageBody);
                    return(false);
                }

                // get the chunks to process.
                chunksToProcess = GetSavedChunks(requestId, messageBody);

                CloseSecureChannelRequest request = BinaryDecoder.DecodeMessage(
                    new ArraySegmentStream(chunksToProcess),
                    typeof(CloseSecureChannelRequest),
                    Quotas.MessageContext) as CloseSecureChannelRequest;

                if (request == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadStructureMissing, "Could not parse CloseSecureChannel request body.");
                }

                // send the response.
                // SendCloseSecureChannelResponse(requestId, token, request);
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error processing OpenSecureChannel request.");
            }
            finally
            {
                if (chunksToProcess != null)
                {
                    chunksToProcess.Release(BufferManager, "ProcessCloseSecureChannelRequest");
                }

                Utils.Trace(
                    "TCPSERVERCHANNEL ProcessCloseSecureChannelRequest Socket={0:X8}, ChannelId={1}, TokenId={2}",
                    (Socket != null)?Socket.Handle:0,
                    (CurrentToken != null)?CurrentToken.ChannelId:0,
                    (CurrentToken != null)?CurrentToken.TokenId:0);

                // close the channel.
                ChannelClosed();
            }

            return(true);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Reads the trust list.
        /// </summary>
        public TrustListDataType ReadTrustList(NodeId trustListId)
        {
            if (!IsConnected)
            {
                Connect();
            }

            var outputArguments = Session.Call(
                trustListId,
                Opc.Ua.MethodIds.FileType_Open,
                (byte)OpenFileMode.Read);

            uint         fileHandle = (uint)outputArguments[0];
            MemoryStream ostrm      = new MemoryStream();

            try
            {
                while (true)
                {
                    int length = 4096;

                    outputArguments = Session.Call(
                        trustListId,
                        Opc.Ua.MethodIds.FileType_Read,
                        fileHandle,
                        length);

                    byte[] bytes = (byte[])outputArguments[0];
                    ostrm.Write(bytes, 0, bytes.Length);

                    if (length != bytes.Length)
                    {
                        break;
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (IsConnected)
                {
                    Session.Call(
                        trustListId,
                        Opc.Ua.MethodIds.FileType_Close,
                        fileHandle);
                }
            }

            ostrm.Position = 0;

            BinaryDecoder     decoder   = new BinaryDecoder(ostrm, Session.MessageContext);
            TrustListDataType trustList = new TrustListDataType();

            trustList.Decode(decoder);
            decoder.Close();
            ostrm.Close();

            return(trustList);
        }
        /// <summary>
        /// Processes an OpenSecureChannel request message.
        /// </summary>
        protected ArraySegment <byte> ReadAsymmetricMessage(
            ArraySegment <byte> buffer,
            X509Certificate2 receiverCertificate,
            out uint channelId,
            out X509Certificate2 senderCertificate,
            out uint requestId,
            out uint sequenceNumber)
        {
            BinaryDecoder decoder = new BinaryDecoder(buffer.Array, buffer.Offset, buffer.Count, Quotas.MessageContext);

            string securityPolicyUri = null;

            // parse the security header.
            ReadAsymmetricMessageHeader(
                decoder,
                receiverCertificate,
                out channelId,
                out senderCertificate,
                out securityPolicyUri);

            // validate the sender certificate.
            if (senderCertificate != null && Quotas.CertificateValidator != null && securityPolicyUri != SecurityPolicies.None)
            {
                Quotas.CertificateValidator.Validate(senderCertificate);
            }

            // check if this is the first open secure channel request.
            if (!m_uninitialized)
            {
                if (securityPolicyUri != m_securityPolicyUri)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "Cannot change the security policy after creating the channnel.");
                }
            }
            else
            {
                // find a matching endpoint description.
                if (m_endpoints != null)
                {
                    foreach (EndpointDescription endpoint in m_endpoints)
                    {
                        // There may be multiple endpoints with the same securityPolicyUri.
                        // Just choose the first one that matches. This choice will be re-examined
                        // When the OpenSecureChannel request body is processed.
                        if (endpoint.SecurityPolicyUri == securityPolicyUri || (securityPolicyUri == SecurityPolicies.None && endpoint.SecurityMode == MessageSecurityMode.None))
                        {
                            m_securityMode      = endpoint.SecurityMode;
                            m_securityPolicyUri = securityPolicyUri;
                            m_discoveryOnly     = false;
                            m_uninitialized     = false;
                            m_selectedEndpoint  = endpoint;

                            // recalculate the key sizes.
                            CalculateSymmetricKeySizes();
                            break;
                        }
                    }
                }

                // allow a discovery only channel with no security if policy not suppported
                if (m_uninitialized)
                {
                    if (securityPolicyUri != SecurityPolicies.None)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "The security policy is not supported.");
                    }

                    m_securityMode      = MessageSecurityMode.None;
                    m_securityPolicyUri = SecurityPolicies.None;
                    m_discoveryOnly     = true;
                    m_uninitialized     = false;
                    m_selectedEndpoint  = null;
                }
            }

            int headerSize = decoder.Position;

            // decrypt the body.
            ArraySegment <byte> plainText = Decrypt(
                new ArraySegment <byte>(buffer.Array, buffer.Offset + headerSize, buffer.Count - headerSize),
                new ArraySegment <byte>(buffer.Array, buffer.Offset, headerSize),
                receiverCertificate);

            // extract signature.
            int signatureSize = GetAsymmetricSignatureSize(senderCertificate);

            byte[] signature = new byte[signatureSize];

            for (int ii = 0; ii < signatureSize; ii++)
            {
                signature[ii] = plainText.Array[plainText.Offset + plainText.Count - signatureSize + ii];
            }

            // verify the signature.
            ArraySegment <byte> dataToVerify = new ArraySegment <byte>(plainText.Array, plainText.Offset, plainText.Count - signatureSize);

            if (!Verify(dataToVerify, signature, senderCertificate))
            {
                Utils.Trace("Could not verify signature on message.");
                throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the signature on the message.");
            }

            // verify padding.
            int paddingCount = 0;

            if (SecurityMode != MessageSecurityMode.None)
            {
                int paddingEnd = -1;
                if (receiverCertificate.GetRSAPublicKey().KeySize > TcpMessageLimits.KeySizeExtraPadding)
                {
                    paddingEnd   = plainText.Offset + plainText.Count - signatureSize - 1;
                    paddingCount = plainText.Array[paddingEnd - 1] + plainText.Array[paddingEnd] * 256;

                    //parse until paddingStart-1; the last one is actually the extrapaddingsize
                    for (int ii = paddingEnd - paddingCount; ii < paddingEnd; ii++)
                    {
                        if (plainText.Array[ii] != plainText.Array[paddingEnd - 1])
                        {
                            throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the padding in the message.");
                        }
                    }
                }
                else
                {
                    paddingEnd   = plainText.Offset + plainText.Count - signatureSize - 1;
                    paddingCount = plainText.Array[paddingEnd];

                    for (int ii = paddingEnd - paddingCount; ii < paddingEnd; ii++)
                    {
                        if (plainText.Array[ii] != plainText.Array[paddingEnd])
                        {
                            throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the padding in the message.");
                        }
                    }
                }

                paddingCount++;
            }

            // decode message.
            decoder = new BinaryDecoder(
                plainText.Array,
                plainText.Offset + headerSize,
                plainText.Count - headerSize,
                Quotas.MessageContext);

            sequenceNumber = decoder.ReadUInt32(null);
            requestId      = decoder.ReadUInt32(null);

            headerSize += decoder.Position;
            decoder.Close();

            Utils.Trace("Security Policy: {0}", SecurityPolicyUri);
            Utils.Trace("Sender Certificate: {0}", (senderCertificate != null)?senderCertificate.Subject:"(none)");

            // return the body.
            return(new ArraySegment <byte>(
                       plainText.Array,
                       plainText.Offset + headerSize,
                       plainText.Count - headerSize - signatureSize - paddingCount));
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Converts a local value to a remote value.
        /// </summary>
        /// <param name="srcValue">The local value.</param>
        /// <param name="srcType">The data type of the local value.</param>
        /// <param name="dstType">The data type of the remote value.</param>
        /// <returns>The remote value.</returns>
        private object ConvertLocalToRemote(object srcValue, BuiltInType srcType, BuiltInType dstType)
        {
            // must determine the type from the source if the containing array is a variant.
            if (srcType == BuiltInType.Variant)
            {
                TypeInfo typeInfo = TypeInfo.Construct(srcValue);
                srcType = typeInfo.BuiltInType;
            }

            // no conversion by default.
            object dstValue = srcValue;

            // apply different conversions depending on the data type.
            switch (dstType)
            {
            case BuiltInType.Guid:
            {
                dstValue = new Uuid((string)srcValue);
                break;
            }

            case BuiltInType.XmlElement:
            {
                XmlDocument document = new XmlDocument();
                document.InnerXml = (string)srcValue;
                dstValue          = document.DocumentElement;
                break;
            }

            case BuiltInType.NodeId:
            {
                dstValue = GetRemoteNodeId((string)srcValue);
                break;
            }

            case BuiltInType.ExpandedNodeId:
            {
                ExpandedNodeId nodeId = ExpandedNodeId.Parse((string)srcValue);
                dstValue = GetRemoteExpandedNodeId(nodeId);
                break;
            }

            case BuiltInType.QualifiedName:
            {
                dstValue = GetRemoteBrowseName((string)srcValue);
                break;
            }

            case BuiltInType.LocalizedText:
            {
                dstValue = new LocalizedText((string)srcValue);
                break;
            }

            case BuiltInType.StatusCode:
            {
                dstValue = new StatusCode((uint)srcValue);
                break;
            }

            case BuiltInType.ExtensionObject:
            {
                BinaryDecoder decoder = new BinaryDecoder((byte[])srcValue, m_localMessageContext);
                dstValue = decoder.ReadExtensionObject(null);
                decoder.Close();
                break;
            }

            default:
            {
                if (dstType != srcType && dstType != BuiltInType.Variant && dstType != BuiltInType.Null)
                {
                    throw ComUtils.CreateComException(ResultIds.E_BADTYPE);
                }

                break;
            }
            }

            // all done.
            return(dstValue);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Handles requests arriving from a channel.
        /// </summary>
        public async Task SendAsync(HttpContext context)
        {
            IAsyncResult result = null;

            try
            {
                if (m_callback == null)
                {
                    context.Response.ContentLength = 0;
                    context.Response.ContentType   = "text/plain";
                    context.Response.StatusCode    = (int)HttpStatusCode.NotImplemented;
                    await context.Response.WriteAsync(string.Empty);

                    return;
                }

                if (context.Request.ContentType != "application/octet-stream")
                {
                    context.Response.ContentLength = 0;
                    context.Response.ContentType   = "text/plain";
                    context.Response.StatusCode    = (int)HttpStatusCode.BadRequest;
                    await context.Response.WriteAsync("HTTPSLISTENER - Unsupported content type.");

                    return;
                }

                int    length = (int)context.Request.ContentLength;
                byte[] buffer = await ReadBodyAsync(context.Request);

                if (buffer.Length != length)
                {
                    context.Response.ContentLength = 0;
                    context.Response.ContentType   = "text/plain";
                    context.Response.StatusCode    = (int)HttpStatusCode.BadRequest;
                    await context.Response.WriteAsync("HTTPSLISTENER - Couldn't decode buffer.");

                    return;
                }

                IServiceRequest input = (IServiceRequest)BinaryDecoder.DecodeMessage(buffer, null, m_quotas.MessageContext);

                // extract the JWT token from the HTTP headers.
                if (input.RequestHeader == null)
                {
                    input.RequestHeader = new RequestHeader();
                }

                if (NodeId.IsNull(input.RequestHeader.AuthenticationToken) && input.TypeId != DataTypeIds.CreateSessionRequest)
                {
                    if (context.Request.Headers.Keys.Contains("Authorization"))
                    {
                        foreach (string value in context.Request.Headers["Authorization"])
                        {
                            if (value.StartsWith("Bearer"))
                            {
                                input.RequestHeader.AuthenticationToken = new NodeId(value.Substring("Bearer ".Length).Trim());
                            }
                        }
                    }
                }

                EndpointDescription endpoint = null;

                foreach (var ep in m_descriptions)
                {
                    if (ep.EndpointUrl.StartsWith(Utils.UriSchemeHttps))
                    {
                        endpoint = ep;
                        break;
                    }
                }

                IPAddress remoteIP   = (context.Connection == null ? null : context.Connection.RemoteIpAddress);
                int       remotePort = (context.Connection == null ? 0 : context.Connection.RemotePort);

                result = m_callback.BeginProcessRequest(
                    m_listenerId,
                    endpoint,
                    input as IServiceRequest,
                    null,
                    null,
                    remoteIP,      // HONEYPOT - pass the remote IP address as an additional parameter.
                    remotePort);   // HONEYPOT - pass the remote port as an additional parameter.

                IServiceResponse output = m_callback.EndProcessRequest(result);

                byte[] response = BinaryEncoder.EncodeMessage(output, m_quotas.MessageContext);
                context.Response.ContentLength = response.Length;
                context.Response.ContentType   = context.Request.ContentType;
                context.Response.StatusCode    = (int)HttpStatusCode.OK;
                await context.Response.Body.WriteAsync(response, 0, response.Length);
            }
            catch (Exception e)
            {
                Utils.Trace(e, "HTTPSLISTENER - Unexpected error processing request.");
                context.Response.ContentLength = e.Message.Length;
                context.Response.ContentType   = "text/plain";
                context.Response.StatusCode    = (int)HttpStatusCode.InternalServerError;
                await context.Response.WriteAsync(e.Message);
            }
        }
Ejemplo n.º 31
0
        public static async Task Run(
            [EventHubTrigger("table-update", Connection = "eventHubConnection")] EventData[] events,
            [CosmosDB(
                 databaseName: "Temenos",
                 collectionName: "Events",
                 ConnectionStringSetting = "CosmosDBConnection")]
            IAsyncCollector <JObject> eventsOut,
            ILogger log)
        {
            log.LogInformation($"ProcessAvroEvent triggered with {events.Count()} events");

            var exceptions = new List <Exception>();

            foreach (EventData eventData in events)
            {
                try
                {
                    // convert messageBody of this event to a stream
                    MemoryStream stream = new MemoryStream(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);

                    // skip the first 2 bytes
                    stream.Position = 3;

                    // decode the stream and get the schema number
                    BinaryDecoder decoder      = new BinaryDecoder(stream);
                    var           magicCode    = (decoder.ReadBoolean() == false);
                    var           schemaNumber = decoder.ReadLong();

                    // get the appropriate schema
                    Schema schema = null;
                    switch (schemaNumber)
                    {
                    case 23:
                        schema = Schema.Parse(File.ReadAllText(@"SerializationID-46-CUSTOMER.avsc"));
                        break;

                    case -21:
                        schema = Schema.Parse(File.ReadAllText(@"SerializationID-41-DE_ADDRESS.avsc"));
                        break;

                    default:
                        throw new Exception("Unknown schema nuumber: " + schemaNumber);
                    }

                    // read the avro message using the identified schema
                    var           reader = new DefaultReader(schema, schema);
                    GenericRecord record = reader.Read(null, schema, schema, decoder) as GenericRecord;

                    // convert to JSON and return
                    JObject outputData = ConvertToJson(record);
                    eventsOut.AddAsync(outputData).Wait();

                    // Replace these two lines with your processing logic.
                    await Task.Yield();
                }
                catch (Exception e)
                {
                    // We need to keep processing the rest of the batch - capture this exception and continue.
                    // TODO: consider capturing details of the message that failed processing so it can be processed again later.
                    exceptions.Add(e);
                }
            }

            // Once processing of the batch is complete, if any messages in the batch failed processing throw an exception so that there is a record of the failure.

            if (exceptions.Count > 1)
            {
                throw new AggregateException(exceptions);
            }

            if (exceptions.Count == 1)
            {
                throw exceptions.Single();
            }
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Handles requests arriving from a channel.
        /// </summary>
        private IAsyncResult BeginProcessRequest(Stream istrm, string action, string securityPolicyUri,
                                                 object callbackData)
        {
            IAsyncResult result = null;

            try {
                if (m_callback != null)
                {
                    string contentType = WebOperationContext.Current.IncomingRequest.ContentType;
                    Uri    uri         = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri;

                    string scheme = uri.Scheme + ":";

                    EndpointDescription endpoint = null;

                    for (int ii = 0; ii < m_descriptions.Count; ii++)
                    {
                        if (m_descriptions[ii].EndpointUrl.StartsWith(scheme))
                        {
                            if (endpoint == null)
                            {
                                endpoint = m_descriptions[ii];
                            }

                            if (m_descriptions[ii].SecurityPolicyUri == securityPolicyUri)
                            {
                                endpoint = m_descriptions[ii];
                                break;
                            }
                        }
                    }

                    IEncodeable request = null;

                    if (String.IsNullOrEmpty(action))
                    {
                        request = BinaryDecoder.DecodeMessage(istrm, null, this.m_quotas.MessageContext);
                    }
                    else
                    {
                        string requestType = "Opc.Ua." + action + "Request";

                        request = HttpsTransportChannel.ReadSoapMessage(
                            istrm,
                            action + "Request",
                            Type.GetType(requestType),
                            this.m_quotas.MessageContext);
                    }

                    result = m_callback.BeginProcessRequest(
                        m_listenerId,
                        endpoint,
                        request as IServiceRequest,
                        null,
                        callbackData);
                }
            } catch (Exception e) {
                Utils.Trace(e, "HTTPSLISTENER - Unexpected error processing request.");
            }

            return(result);
        }
Ejemplo n.º 33
0
        // Just a simple unit test, non-exhaustive! Encodes/Decodes 100 1's and 100 0's.
        private static void UnitTest()
        {
            System.IO.MemoryStream output = new System.IO.MemoryStream();

            BinaryCoder   coder         = new BinaryCoder((Stream)output);
            BinShiftModel adaptiveModel = new BinShiftModel();

            adaptiveModel.Inertia = 1;

            // NB: Skipping try/catch here!
            for (int i = 0; i < 100; ++i)
            {
                adaptiveModel.Encode(coder, 1);
            }
            for (int i = 0; i < 100; ++i)
            {
                adaptiveModel.Encode(coder, 0);
            }
            coder.Flush();


            output.Seek(0, SeekOrigin.Begin);

            BinaryDecoder decoder             = new BinaryDecoder(output);
            BinShiftModel adaptiveDecodeModel = new BinShiftModel();

            adaptiveDecodeModel.Inertia = 1;

            bool works = true;

            //for (int j = 0; j < 10; ++j)
            //{
            for (int i = 0; i < 100; ++i)
            {
                int val = adaptiveDecodeModel.Decode(decoder);
                if (val != 1)
                {
                    Console.WriteLine("Decomp (1) error at " + i);
                    works = false;
                }
            }
            for (int i = 0; i < 100; ++i)
            {
                int val = adaptiveDecodeModel.Decode(decoder);
                if (val != 0)
                {
                    Console.WriteLine("Decomp (0) error at " + i);
                    works = false;
                }
            }
            //}

            if (!works)
            {
                Console.WriteLine("Compression test had an error");
            }
            else
            {
                Console.WriteLine("Compression test worked");
            }


            coder.Flush();
            //  Console.WriteLine("Size of compressed data = " + output.Length);
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Processes an OpenSecureChannel request message.
        /// </summary>
        private bool ProcessOpenSecureChannelRequest(uint messageType, ArraySegment <byte> messageChunk)
        {
            // validate the channel state.
            if (State != TcpChannelState.Opening && State != TcpChannelState.Open)
            {
                ForceChannelFault(StatusCodes.BadTcpMessageTypeInvalid, "Client sent an unexpected OpenSecureChannel message.");
                return(false);
            }

            // parse the security header.
            uint             channelId         = 0;
            X509Certificate2 clientCertificate = null;
            uint             requestId         = 0;
            uint             sequenceNumber    = 0;

            ArraySegment <byte> messageBody;

            try
            {
                messageBody = ReadAsymmetricMessage(
                    messageChunk,
                    ServerCertificate,
                    out channelId,
                    out clientCertificate,
                    out requestId,
                    out sequenceNumber);

                // check for replay attacks.
                if (!VerifySequenceNumber(sequenceNumber, "ProcessOpenSecureChannelRequest"))
                {
                    throw new ServiceResultException(StatusCodes.BadSequenceNumberInvalid);
                }
            }
            catch (Exception e)
            {
                ServiceResultException innerException = e.InnerException as ServiceResultException;

                // If the certificate structre, signature and trust list checks pass, we return the other specific validation errors instead of BadSecurityChecksFailed
                if (innerException != null)
                {
                    if (innerException.StatusCode == StatusCodes.BadCertificateUntrusted ||
                        innerException.StatusCode == StatusCodes.BadCertificateChainIncomplete ||
                        innerException.StatusCode == StatusCodes.BadCertificateRevoked ||
                        innerException.StatusCode == StatusCodes.BadCertificateInvalid ||
                        (innerException.InnerResult != null && innerException.InnerResult.StatusCode == StatusCodes.BadCertificateUntrusted))
                    {
                        ForceChannelFault(StatusCodes.BadSecurityChecksFailed, e.Message);
                        return(false);
                    }
                    else if (innerException.StatusCode == StatusCodes.BadCertificateTimeInvalid ||
                             innerException.StatusCode == StatusCodes.BadCertificateIssuerTimeInvalid ||
                             innerException.StatusCode == StatusCodes.BadCertificateHostNameInvalid ||
                             innerException.StatusCode == StatusCodes.BadCertificateUriInvalid ||
                             innerException.StatusCode == StatusCodes.BadCertificateUseNotAllowed ||
                             innerException.StatusCode == StatusCodes.BadCertificateIssuerUseNotAllowed ||
                             innerException.StatusCode == StatusCodes.BadCertificateRevocationUnknown ||
                             innerException.StatusCode == StatusCodes.BadCertificateIssuerRevocationUnknown ||
                             innerException.StatusCode == StatusCodes.BadCertificateIssuerRevoked)
                    {
                        ForceChannelFault(innerException, innerException.StatusCode, e.Message);
                        return(false);
                    }
                }

                ForceChannelFault(e, StatusCodes.BadSecurityChecksFailed, "Could not verify security on OpenSecureChannel request.");
                return(false);
            }

            BufferCollection chunksToProcess = null;

            try
            {
                bool firstCall = ClientCertificate == null;

                // must ensure the same certificate was used.
                if (ClientCertificate != null)
                {
                    CompareCertificates(ClientCertificate, clientCertificate, false);
                }
                else
                {
                    ClientCertificate = clientCertificate;
                }

                // check if it is necessary to wait for more chunks.
                if (!TcpMessageType.IsFinal(messageType))
                {
                    SaveIntermediateChunk(requestId, messageBody);
                    return(false);
                }

                // create a new token.
                ChannelToken token = CreateToken();

                token.TokenId     = GetNewTokenId();
                token.ServerNonce = CreateNonce();

                // get the chunks to process.
                chunksToProcess = GetSavedChunks(requestId, messageBody);

                OpenSecureChannelRequest request = (OpenSecureChannelRequest)BinaryDecoder.DecodeMessage(
                    new ArraySegmentStream(chunksToProcess),
                    typeof(OpenSecureChannelRequest),
                    Quotas.MessageContext);

                if (request == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadStructureMissing, "Could not parse OpenSecureChannel request body.");
                }

                // check the security mode.
                if (request.SecurityMode != SecurityMode)
                {
                    ReviseSecurityMode(firstCall, request.SecurityMode);
                }

                // check the client nonce.
                token.ClientNonce = request.ClientNonce;

                if (!ValidateNonce(token.ClientNonce))
                {
                    throw ServiceResultException.Create(StatusCodes.BadNonceInvalid, "Client nonce is not the correct length or not random enough.");
                }

                // choose the lifetime.
                int lifetime = (int)request.RequestedLifetime;

                if (lifetime < TcpMessageLimits.MinSecurityTokenLifeTime)
                {
                    lifetime = TcpMessageLimits.MinSecurityTokenLifeTime;
                }

                if (lifetime > 0 && lifetime < token.Lifetime)
                {
                    token.Lifetime = lifetime;
                }

                // check the request type.
                SecurityTokenRequestType requestType = request.RequestType;

                if (requestType == SecurityTokenRequestType.Issue && State != TcpChannelState.Opening)
                {
                    throw ServiceResultException.Create(StatusCodes.BadRequestTypeInvalid, "Cannot request a new token for an open channel.");
                }

                if (requestType == SecurityTokenRequestType.Renew && State != TcpChannelState.Open)
                {
                    // may be reconnecting to a dropped channel.
                    if (State == TcpChannelState.Opening)
                    {
                        // tell the listener to find the channel that can process the request.
                        Listener.ReconnectToExistingChannel(
                            Socket,
                            requestId,
                            sequenceNumber,
                            channelId,
                            ClientCertificate,
                            token,
                            request);

                        Utils.Trace(
                            "{0} ReconnectToExistingChannel Socket={0:X8}, ChannelId={1}, TokenId={2}",
                            ChannelName,
                            (Socket != null) ? Socket.Handle : 0,
                            (CurrentToken != null) ? CurrentToken.ChannelId : 0,
                            (CurrentToken != null) ? CurrentToken.TokenId : 0);

                        // close the channel.
                        ChannelClosed();

                        // nothing more to do.
                        return(false);
                    }

                    throw ServiceResultException.Create(StatusCodes.BadRequestTypeInvalid, "Cannot request to renew a token for a channel that has not been opened.");
                }

                // check the channel id.
                if (requestType == SecurityTokenRequestType.Renew && channelId != ChannelId)
                {
                    throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Do not recognize the secure channel id provided.");
                }

                // log security information.
                if (requestType == SecurityTokenRequestType.Issue)
                {
                    Opc.Ua.Security.Audit.SecureChannelCreated(
                        m_ImplementationString,
                        Listener.EndpointUrl.ToString(),
                        Utils.Format("{0}", ChannelId),
                        EndpointDescription,
                        ClientCertificate,
                        ServerCertificate,
                        BinaryEncodingSupport.Required);
                }
                else
                {
                    Opc.Ua.Security.Audit.SecureChannelRenewed(
                        m_ImplementationString,
                        Utils.Format("{0}", ChannelId));
                }

                if (requestType == SecurityTokenRequestType.Renew)
                {
                    SetRenewedToken(token);
                }
                else
                {
                    ActivateToken(token);
                }

                State = TcpChannelState.Open;

                // send the response.
                SendOpenSecureChannelResponse(requestId, token, request);

                // notify reverse
                CompleteReverseHello(null);

                // notify any monitors.
                NotifyMonitors(ServiceResult.Good, false);

                return(false);
            }
            catch (Exception e)
            {
                SendServiceFault(requestId, ServiceResult.Create(e, StatusCodes.BadTcpInternalError, "Unexpected error processing OpenSecureChannel request."));
                CompleteReverseHello(e);
                return(false);
            }
            finally
            {
                if (chunksToProcess != null)
                {
                    chunksToProcess.Release(BufferManager, "ProcessOpenSecureChannelRequest");
                }
            }
        }
Ejemplo n.º 35
0
        static void SimpleExample()
        {
            // let's construct some data consisting of runs of 0's and 1's.
            byte[] simpleSampleData =
            {
                0x00,
                0x00,
                0x00,
                0x0f,

                0xff,
                0xf0,
                0x00,
                0x1f,

                0xff,
                0xff,
                0xff,
                0xff,

                0xf1,
                0xe0,
                0x0c,
                0xf0
            };


            // Naiive adaptive example
            {
                System.IO.MemoryStream output        = new System.IO.MemoryStream();
                BinaryCoder            coder         = new BinaryCoder((Stream)output);
                BinShiftModel          adaptiveModel = new BinShiftModel();

                // the lower the number, the faster it adapts
                adaptiveModel.Inertia = 1;

                foreach (byte b in simpleSampleData)
                {
                    for (int bitpos = 7; bitpos >= 0; --bitpos)
                    {
                        int bit = (int)(b >> bitpos) & 1;
                        // NB: Skipping try/catch here!
                        adaptiveModel.Encode(coder, bit);
                    }
                }
                coder.Flush();

                Console.WriteLine("Adaptive Output size is " + output.Length);
            }

            // Context-switching example
            {
                // encode
                System.IO.MemoryStream output2 = new System.IO.MemoryStream();
                BinaryCoder            coder2  = new BinaryCoder((Stream)output2);
                SimpleStaticModel      model0  = new SimpleStaticModel();
                SimpleStaticModel      model1  = new SimpleStaticModel();

                model0.SetProb(10f / 128f);
                model1.SetProb(1f - (10f / 128f));

                bool use0Context = true; // 0 bits come first, use the correct model!

                foreach (byte b in simpleSampleData)
                {
                    for (int bitpos = 7; bitpos >= 0; --bitpos)
                    {
                        int bit = (int)(b >> bitpos) & 1;

                        // encode using the correct context
                        // NB: Skipping try/catch here!
                        if (use0Context)
                        {
                            model0.Encode(coder2, bit);
                        }
                        else
                        {
                            model1.Encode(coder2, bit);
                        }

                        // switch context AFTER the bit state changes
                        use0Context = (bit == 0 ? true : false);
                    }
                }
                coder2.Flush();

                Console.WriteLine("Ideal static model with context switch size is " + output2.Length);

                // The decoder looks much like the encoder. Notice how the context switch occurs only
                // after a symbol is decoded, exactly as the encoder does it.

                output2.Seek(0, SeekOrigin.Begin);


                // decode
                BinaryDecoder     decoder2        = new BinaryDecoder((Stream)output2);
                SimpleStaticModel staticModel0dec = new SimpleStaticModel();
                SimpleStaticModel staticModel1dec = new SimpleStaticModel();

                staticModel0dec.SetProb(10f / 128f);
                staticModel1dec.SetProb(1f - (10f / 128f));

                bool use0ContextDec = true; // 0 bits come first, use the correct model!
                foreach (byte b in simpleSampleData)
                {
                    for (int bitpos = 7; bitpos >= 0; --bitpos)
                    {
                        int bit = (int)(b >> bitpos) & 1;

                        int decBit;

                        // decode using the correct context!
                        // NB: Skipping try/catch here!
                        if (use0ContextDec)
                        {
                            decBit = staticModel0dec.Decode(decoder2);
                        }
                        else
                        {
                            decBit = staticModel1dec.Decode(decoder2);
                        }

                        // the decoded bit should match the source bit for the decoder to have worked
                        if (decBit != bit)
                        {
                            Console.WriteLine("Error, static example 1 did not decode properly!");
                        }

                        // switch context when the bit state changes
                        use0ContextDec = (decBit == 0 ? true : false);
                    }
                }
            }
        }
        protected void ReadAsymmetricMessageHeader(
            BinaryDecoder        decoder,
            X509Certificate2     receiverCertificate,
            out uint             secureChannelId,            
            out X509Certificate2 senderCertificate,
            out string           securityPolicyUri)
        {        
            senderCertificate = null;

            uint messageType = decoder.ReadUInt32(null);
            uint messageSize = decoder.ReadUInt32(null);

            // decode security header.
            byte[] certificateData = null;
            byte[] thumbprintData = null;

            try
            {
                secureChannelId = decoder.ReadUInt32(null);
                securityPolicyUri = decoder.ReadString(null, TcpMessageLimits.MaxSecurityPolicyUriSize);
                certificateData = decoder.ReadByteString(null, TcpMessageLimits.MaxCertificateSize);
                thumbprintData = decoder.ReadByteString(null, TcpMessageLimits.CertificateThumbprintSize);
            }
            catch (Exception e)
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadSecurityChecksFailed, 
                    e,
                    "The asymmetric security header could not be parsed.");
            }
            
            // verify sender certificate.
            if (certificateData != null && certificateData.Length > 0)
            {
                senderCertificate = CertificateFactory.Create(certificateData, true);

                try
                {
                    string thumbprint = senderCertificate.Thumbprint;

                    if (thumbprint == null)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "Invalid certificate thumbprint.");
                    }
                }
                catch (Exception e)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, e, "The sender's certificate could not be parsed.");
                }
            }
            else
            {
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The sender's certificate was not specified.");
                }
            }

            // verify receiver thumbprint.
            if (thumbprintData != null && thumbprintData.Length > 0)
            {
                if (receiverCertificate.Thumbprint.ToUpperInvariant() != GetThumbprintString(thumbprintData))
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint is not valid.");
                }
            }
            else
            {
                if (securityPolicyUri != SecurityPolicies.None)
                {
                    throw ServiceResultException.Create(StatusCodes.BadCertificateInvalid, "The receiver's certificate thumbprint was not specified.");
                }
            }
        }
Ejemplo n.º 37
0
            /// <summary>
            /// Called whenever socket operation completes
            /// </summary>
            /// <param name="index"></param>
            /// <param name="arg"></param>
            /// <param name="ok"></param>
            /// <param name="timeout"></param>
            /// <returns>true if completed, false to be called again</returns>
            public bool CompleteAsync(int index, SocketAsyncEventArgs arg,
                                      out bool ok, out int timeout)
            {
                ok      = false;
                timeout = _timeout;
                if (arg.SocketError != SocketError.Success)
                {
                    _logger.Debug("Probe {index} : {remoteEp} found no opc server. {error}",
                                  index, _socket?.RemoteEndPoint, arg.SocketError);
                    _state = State.BeginProbe;
                    return(true);
                }
                while (true)
                {
                    switch (_state)
                    {
                    case State.BeginProbe:
                        if (arg.ConnectSocket == null)
                        {
                            _logger.Error("Probe {index} : Called without connected socket!",
                                          index);
                            return(true);
                        }
                        _socket = arg.ConnectSocket;
                        var ep = _socket.RemoteEndPoint.TryResolve();
                        using (var ostrm = new MemoryStream(_buffer, 0, _buffer.Length))
                            using (var encoder = new BinaryEncoder(ostrm,
                                                                   ServiceMessageContext.GlobalContext)) {
                                encoder.WriteUInt32(null, TcpMessageType.Hello);
                                encoder.WriteUInt32(null, 0);
                                encoder.WriteUInt32(null, 0); // ProtocolVersion
                                encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize);
                                encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize);
                                encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize);
                                encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize);
                                encoder.WriteByteString(null, Encoding.UTF8.GetBytes("opc.tcp://" + ep));
                                _size = encoder.Close();
                            }
                        _buffer[4] = (byte)(_size & 0x000000FF);
                        _buffer[5] = (byte)((_size & 0x0000FF00) >> 8);
                        _buffer[6] = (byte)((_size & 0x00FF0000) >> 16);
                        _buffer[7] = (byte)((_size & 0xFF000000) >> 24);
                        arg.SetBuffer(_buffer, 0, _size);
                        _len = 0;
                        _logger.Debug("Probe {index} : {ep} ({remoteEp})...", index, "opc.tcp://" + ep,
                                      _socket.RemoteEndPoint);
                        _state = State.SendHello;
                        if (!_socket.SendAsync(arg))
                        {
                            break;
                        }
                        return(false);

                    case State.SendHello:
                        _len += arg.Count;
                        if (_len >= _size)
                        {
                            _len   = 0;
                            _size  = TcpMessageLimits.MessageTypeAndSize;
                            _state = State.ReceiveSize;
                            arg.SetBuffer(0, _size);
                            // Start read size
                            if (!_socket.ReceiveAsync(arg))
                            {
                                break;
                            }
                            return(false);
                        }
                        // Continue to send reset
                        arg.SetBuffer(_len, _size - _len);
                        if (!_socket.SendAsync(arg))
                        {
                            break;
                        }
                        return(false);

                    case State.ReceiveSize:
                        _len += arg.Count;
                        if (_len >= _size)
                        {
                            var type = BitConverter.ToUInt32(_buffer, 0);
                            if (type != TcpMessageType.Acknowledge)
                            {
                                if (TcpMessageType.IsValid(type))
                                {
                                    _logger.Debug("Probe {index} : {remoteEp} " +
                                                  "returned message type {type} != Ack.",
                                                  index, _socket.RemoteEndPoint, type);
                                }
                                else
                                {
                                    _logger.Verbose("Probe {index} : {remoteEp} " +
                                                    "returned invalid message type {type}.",
                                                    index, _socket.RemoteEndPoint, type);
                                }
                                _state = State.BeginProbe;
                                return(true);
                            }
                            _size = (int)BitConverter.ToUInt32(_buffer, 4);
                            if (_size > _buffer.Length)
                            {
                                _logger.Debug("Probe {index} : {remoteEp} " +
                                              "returned invalid message length {size}.",
                                              index, _socket.RemoteEndPoint, _size);
                                _state = State.BeginProbe;
                                return(true);
                            }
                            _len = 0;
                            // Start receive message
                            _state = State.ReceiveAck;
                        }
                        // Continue to read rest of type and size
                        arg.SetBuffer(_len, _size - _len);
                        if (!_socket.ReceiveAsync(arg))
                        {
                            break;
                        }
                        return(false);

                    case State.ReceiveAck:
                        _len += arg.Count;
                        if (_len >= _size)
                        {
                            _state = State.BeginProbe;
                            // Validate message
                            using (var istrm = new MemoryStream(_buffer, 0, _size))
                                using (var decoder = new BinaryDecoder(istrm,
                                                                       ServiceMessageContext.GlobalContext)) {
                                    var protocolVersion   = decoder.ReadUInt32(null);
                                    var sendBufferSize    = (int)decoder.ReadUInt32(null);
                                    var receiveBufferSize = (int)decoder.ReadUInt32(null);
                                    var maxMessageSize    = (int)decoder.ReadUInt32(null);
                                    var maxChunkCount     = (int)decoder.ReadUInt32(null);

                                    _logger.Information("Probe {index} : found OPC UA " +
                                                        "server at {remoteEp} (protocol:{protocolVersion}) ...",
                                                        index, _socket.RemoteEndPoint, protocolVersion);

                                    if (sendBufferSize < TcpMessageLimits.MinBufferSize ||
                                        receiveBufferSize < TcpMessageLimits.MinBufferSize)
                                    {
                                        _logger.Warning("Probe {index} : Bad size value read " +
                                                        "{sendBufferSize} or {receiveBufferSize} from opc " +
                                                        "server at {_socket.RemoteEndPoint}.", index,
                                                        sendBufferSize, receiveBufferSize, _socket.RemoteEndPoint);
                                    }
                                }
                            ok = true;
                            return(true);
                        }
                        // Continue to read rest
                        arg.SetBuffer(_len, _size - _len);
                        if (!_socket.ReceiveAsync(arg))
                        {
                            break;
                        }
                        return(false);

                    default:
                        throw new SystemException("Bad state");
                    }
                }
            }
Ejemplo n.º 38
0
        public void TestEnumResolution()
        {
            Schema writerSchema = Schema.Parse("{\"type\":\"record\",\"name\":\"EnumRecord\",\"namespace\":\"Avro.Test\"," +
                                        "\"fields\":[{\"name\":\"enumType\",\"type\": { \"type\": \"enum\", \"name\": \"EnumType\", \"symbols\": [\"FIRST\", \"SECOND\"]} }]}");

            Schema readerSchema = Schema.Parse("{\"type\":\"record\",\"name\":\"EnumRecord\",\"namespace\":\"Avro.Test\"," +
                                        "\"fields\":[{\"name\":\"enumType\",\"type\": { \"type\": \"enum\", \"name\": \"EnumType\", \"symbols\": [\"THIRD\", \"FIRST\", \"SECOND\"]} }]}");

            EnumRecord testRecord = new EnumRecord();
            testRecord.enumType = EnumType.SECOND;

            // serialize
            var stream = new MemoryStream();
            var binEncoder = new BinaryEncoder(stream);
            var writer = new SpecificWriter<EnumRecord>(writerSchema);
            writer.Write(testRecord, binEncoder);

            // deserialize
            stream.Position = 0;
            var decoder = new BinaryDecoder(stream);
            var reader = new SpecificReader<EnumRecord>(writerSchema, readerSchema);
            var rec2 = reader.Read(null, decoder);
            Assert.AreEqual( EnumType.SECOND, rec2.enumType );
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Reads the trust list.
        /// </summary>
        public TrustListDataType ReadTrustList(TrustListMasks masks = TrustListMasks.All)
        {
            if (!IsConnected)
            {
                Connect();
            }

            IUserIdentity oldUser = ElevatePermissions();

            try
            {
                var outputArguments = m_session.Call(
                    ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris),
                    ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_OpenWithMasks, m_session.NamespaceUris),
                    (uint)masks);

                uint         fileHandle = (uint)outputArguments[0];
                MemoryStream ostrm      = new MemoryStream();

                try
                {
                    while (true)
                    {
                        int length = 256;

                        outputArguments = m_session.Call(
                            ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris),
                            ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Read, m_session.NamespaceUris),
                            fileHandle,
                            length);

                        byte[] bytes = (byte[])outputArguments[0];
                        ostrm.Write(bytes, 0, bytes.Length);

                        if (length != bytes.Length)
                        {
                            break;
                        }
                    }

                    m_session.Call(
                        ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris),
                        ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Close, m_session.NamespaceUris),
                        fileHandle);
                }
                catch (Exception)
                {
                    if (IsConnected)
                    {
                        m_session.Call(
                            ExpandedNodeId.ToNodeId(Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList, m_session.NamespaceUris),
                            ExpandedNodeId.ToNodeId(Opc.Ua.MethodIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup_TrustList_Close, m_session.NamespaceUris),
                            fileHandle);
                    }

                    throw;
                }

                ostrm.Position = 0;

                BinaryDecoder     decoder   = new BinaryDecoder(ostrm, m_session.MessageContext);
                TrustListDataType trustList = new TrustListDataType();
                trustList.Decode(decoder);
                decoder.Close();
                ostrm.Close();

                return(trustList);
            }
            finally
            {
                RevertPermissions(oldUser);
            }
        }
Ejemplo n.º 40
0
        /// <summary>
        /// Processes a response message.
        /// </summary>
        private bool ProcessResponseMessage(uint messageType, ArraySegment<byte> messageChunk)
        {
            // Utils.Trace("Channel {0}: ProcessResponseMessage()", ChannelId);

            // validate security on the message.
            TcpChannelToken token = null;
            uint requestId = 0;
            uint sequenceNumber = 0;
                
            ArraySegment<byte> messageBody;

            try
            {
                messageBody = ReadSymmetricMessage(messageChunk, false, out token, out requestId, out sequenceNumber);
            }
            catch (Exception e)
            {
                ForceReconnect(ServiceResult.Create(e, StatusCodes.BadSecurityChecksFailed, "Could not verify security on response."));
                return false;
            }
            
            // check if operation is still available.
            WriteOperation operation = null;

            if (!m_requests.TryGetValue(requestId, out operation))
            {
                return false;
            }

            BufferCollection chunksToProcess = null;
            
            // check for replay attacks.
            if (!VerifySequenceNumber(sequenceNumber, "ProcessResponseMessage"))
            {
                throw new ServiceResultException(StatusCodes.BadSequenceNumberInvalid);
            }

            try
            {
                // check for an abort.
                if (TcpMessageType.IsAbort(messageType))
                {
                    // get the chunks to process.
                    chunksToProcess = GetSavedChunks(requestId, messageBody);

                    // decoder reason.
                    MemoryStream istrm = new MemoryStream(messageBody.Array, messageBody.Offset, messageBody.Count, false);
                    BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);
                    ServiceResult error = ReadErrorMessageBody(decoder);
                    decoder.Close();

                    // report a fault.
                    operation.Fault(true, error);
                    return true;
                }                

                // check if it is necessary to wait for more chunks.
                if (!TcpMessageType.IsFinal(messageType))
                {
                    SaveIntermediateChunk(requestId, messageBody);
                    return true;
                }
                
                // get the chunks to process.
                chunksToProcess = GetSavedChunks(requestId, messageBody);

                // get response.
                operation.MessageBody = ParseResponse(chunksToProcess);
                
                if (operation.MessageBody == null)
                {
                    operation.Fault(true, StatusCodes.BadStructureMissing, "Could not parse response body.");
                    return true;
                }
                    
                // is complete.
                operation.Complete(true, 0);
                return true;
            }
            catch (Exception e)
            {
                operation.Fault(true, e, StatusCodes.BadUnknownResponse, "Unexpected error processing response.");
                return true;
            }
            finally
            {
                if (chunksToProcess != null)
                {
                    chunksToProcess.Release(BufferManager, "ProcessResponseMessage");
                }
            }
        }
Ejemplo n.º 41
0
 public bool Decode(BinaryDecoder decoder)
 {
     if (!BinaryCodec.Decode(decoder, out _itemID))
     {
         return(false);
     }
     if (!BinaryCodec.DecodeUnicodeString(decoder, out _itemName))
     {
         return(false);
     }
     if (!BinaryCodec.DecodeUnicodeString(decoder, out _itemDesc))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _iconName))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _price))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _option))
     {
         return(false);
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _itemType = (E_ItemType)enumValue;
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _itemKindType = (E_ItemKindType)enumValue;
     }
     if (!BinaryCodec.Decode(decoder, out _isConsume))
     {
         return(false);
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _scopeType = (E_ScopeType)enumValue;
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _occasionType = (E_OccasionType)enumValue;
     }
     return(true);
 }
Ejemplo n.º 42
0
        /// <summary>
        /// Parses the response return from the server.
        /// </summary>
        private IServiceResponse ParseResponse(BufferCollection chunksToProcess)
        {
            BinaryDecoder decoder = new BinaryDecoder(new ArraySegmentStream(chunksToProcess), Quotas.MessageContext);

            try
            {       
                IServiceResponse response = BinaryDecoder.DecodeMessage(new ArraySegmentStream(chunksToProcess), null, Quotas.MessageContext) as IServiceResponse;

                if (response == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadStructureMissing, "Could not parse response body.");
                }

                return response;
            }
            finally
            {
                decoder.Close();
            }
        }
Ejemplo n.º 43
0
 public bool Decode(BinaryDecoder decoder)
 {
     if (!BinaryCodec.Decode(decoder, out _itemID))
     {
         return(false);
     }
     if (!BinaryCodec.DecodeUnicodeString(decoder, out _itemName))
     {
         return(false);
     }
     if (!BinaryCodec.DecodeUnicodeString(decoder, out _itemDesc))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _iconName))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _price))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _option))
     {
         return(false);
     }
     {
         int enumValue = 0;
         if (!BinaryCodec.Decode(decoder, out enumValue))
         {
             return(false);
         }
         _armorType = (E_ArmorType)enumValue;
     }
     if (!BinaryCodec.Decode(decoder, out _health))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _energy))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _healthRecover))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _energyRecover))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _physicalArmor))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _elementalArmor))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _physicalAvoid))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _elementalAvoid))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _physicalResistance))
     {
         return(false);
     }
     if (!BinaryCodec.Decode(decoder, out _elementalResistance))
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 44
0
        private bool ProcessHelloMessage(uint messageType, ArraySegment<byte> messageChunk)
        {
            // validate the channel state.            
            if (State != TcpChannelState.Connecting)
            {
                ForceChannelFault(StatusCodes.BadTcpMessageTypeInvalid, "Client sent an unexpected Hello message.");
                return false;
            }
         
            try
            {
                MemoryStream istrm = new MemoryStream(messageChunk.Array, messageChunk.Offset, messageChunk.Count, false);
                BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);
                istrm.Seek(TcpMessageLimits.MessageTypeAndSize, SeekOrigin.Current);

                // read requested buffer sizes.
                uint protocolVersion = decoder.ReadUInt32(null);  
                uint receiveBufferSize = decoder.ReadUInt32(null); 
                uint sendBufferSize = decoder.ReadUInt32(null); 
                uint maxMessageSize = decoder.ReadUInt32(null); 
                uint maxChunkCount = decoder.ReadUInt32(null); 
                
                // read the endpoint url.
                int length = decoder.ReadInt32(null);

                if (length > 0)
                {
                    if (length > TcpMessageLimits.MaxEndpointUrlLength)
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return false;
                    }

                    byte[] endpointUrl = new byte[length];

                    for (int ii = 0; ii < endpointUrl.Length; ii++)
                    {
                        endpointUrl[ii] = decoder.ReadByte(null);
                    }

                    if (!SetEndpointUrl(new UTF8Encoding().GetString(endpointUrl)))
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return false;
                    }
                }
                
                decoder.Close();

                // update receive buffer size.
                if (receiveBufferSize < ReceiveBufferSize)
                {
                    ReceiveBufferSize = (int)receiveBufferSize;
                }

                if (ReceiveBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    ReceiveBufferSize = TcpMessageLimits.MinBufferSize;
                }
                
                // update send buffer size.
                if (sendBufferSize < SendBufferSize)
                {
                    SendBufferSize = (int)sendBufferSize;
                }

                if (SendBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    SendBufferSize = TcpMessageLimits.MinBufferSize;
                }            
                
                // update the max message size.
                if (maxMessageSize > 0 && maxMessageSize < MaxResponseMessageSize)
                {
                    MaxResponseMessageSize = (int)maxMessageSize;
                }
                
                if (MaxResponseMessageSize < SendBufferSize)
                {
                    MaxResponseMessageSize = SendBufferSize;
                }

                // update the max chunk count.
                if (maxChunkCount > 0 && maxChunkCount < MaxResponseChunkCount)
                {
                    MaxResponseChunkCount = (int)maxChunkCount;
                }
                
                // send acknowledge.
                byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "ProcessHelloMessage");
                
                try
                {
                    MemoryStream ostrm = new MemoryStream(buffer, 0, SendBufferSize);
                    BinaryEncoder encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);
                    
                    encoder.WriteUInt32(null, TcpMessageType.Acknowledge);
                    encoder.WriteUInt32(null, 0);
                    encoder.WriteUInt32(null, 0); // ProtocolVersion
                    encoder.WriteUInt32(null, (uint)ReceiveBufferSize);
                    encoder.WriteUInt32(null, (uint)SendBufferSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestMessageSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestChunkCount);
                    
                    int size = encoder.Close();
                    UpdateMessageSize(buffer, 0, size);
                                                
                    // now ready for the open or bind request.
                    State = TcpChannelState.Opening;

                    BeginWriteMessage(new ArraySegment<byte>(buffer, 0, size), Int32.MaxValue, null);
                    buffer = null;
                }
                finally
                {
                    if (buffer != null)
                    {
                        BufferManager.ReturnBuffer(buffer, "ProcessHelloMessage");
                    }
                }
            }
            catch (Exception e)
            {
                ForceChannelFault(e, StatusCodes.BadTcpInternalError, "Unexpected error while processing a Hello message.");
            }

            return false;
        }
        protected override async Task OnOpenAsync(CancellationToken token)
        {
            token.ThrowIfCancellationRequested();
            this.sendBuffer = new byte[MinBufferSize];
            this.receiveBuffer = new byte[MinBufferSize];

            this.tcpClient = new System.Net.Sockets.TcpClient { NoDelay = true };
            var uri = new UriBuilder(this.RemoteEndpoint.EndpointUrl);
            await this.tcpClient.ConnectAsync(uri.Host, uri.Port).ConfigureAwait(false);
            this.instream = this.outstream = this.tcpClient.GetStream();

            // send 'hello'.
            int count;
            var encoder = new BinaryEncoder(new MemoryStream(this.sendBuffer, 0, MinBufferSize, true, false));
            try
            {
                encoder.WriteUInt32(null, UaTcpMessageTypes.HELF);
                encoder.WriteUInt32(null, 0u);
                encoder.WriteUInt32(null, ProtocolVersion);
                encoder.WriteUInt32(null, this.LocalReceiveBufferSize);
                encoder.WriteUInt32(null, this.LocalSendBufferSize);
                encoder.WriteUInt32(null, this.LocalMaxMessageSize);
                encoder.WriteUInt32(null, this.LocalMaxChunkCount);
                encoder.WriteString(null, uri.ToString());
                count = encoder.Position;
                encoder.Position = 4;
                encoder.WriteUInt32(null, (uint)count);
                encoder.Position = count;

                await this.SendAsync(this.sendBuffer, 0, count, token).ConfigureAwait(false);
            }
            finally
            {
                encoder.Dispose();
            }

            // receive response
            count = await this.ReceiveAsync(this.receiveBuffer, 0, MinBufferSize, token).ConfigureAwait(false);
            if (count == 0)
            {
                throw new ObjectDisposedException("socket");
            }

            // decode 'ack' or 'err'.
            var decoder = new BinaryDecoder(new MemoryStream(this.receiveBuffer, 0, count, false, false));
            try
            {
                var type = decoder.ReadUInt32(null);
                var len = decoder.ReadUInt32(null);
                if (type == UaTcpMessageTypes.ACKF)
                {
                    var remoteProtocolVersion = decoder.ReadUInt32(null);
                    if (remoteProtocolVersion < ProtocolVersion)
                    {
                        throw new ServiceResultException(StatusCodes.BadProtocolVersionUnsupported);
                    }

                    this.RemoteSendBufferSize = decoder.ReadUInt32(null);
                    this.RemoteReceiveBufferSize = decoder.ReadUInt32(null);
                    this.RemoteMaxMessageSize = decoder.ReadUInt32(null);
                    this.RemoteMaxChunkCount = decoder.ReadUInt32(null);
                    return;
                }
                else if (type == UaTcpMessageTypes.ERRF)
                {
                    var statusCode = decoder.ReadUInt32(null);
                    var message = decoder.ReadString(null);
                    throw new ServiceResultException(statusCode, message);
                }

                throw new InvalidOperationException("UaTcpTransportChannel.OnOpenAsync received unexpected message type.");
            }
            finally
            {
                decoder.Dispose();
            }
        }