示例#1
0
        public byte[] SerializeAvro(InheritedEntityAvro thisObj)
        {
            using (var ms = new MemoryStream())
            {
                var enc = new BinaryEncoder(ms);
                var writer = new SpecificDefaultWriter(InheritedEntityAvro._SCHEMA); // Schema comes from pre-compiled, code-gen phase
                writer.Write(thisObj, enc);

                return ms.ToArray();
            }
        }
示例#2
0
        public void testEnumMismatch()
        {
            Schema actual = Schema.Parse
              ("{\"type\":\"enum\",\"name\":\"E\",\"symbols\":[\"X\",\"Y\"]}");
            Schema expected = Schema.Parse
              ("{\"type\":\"enum\",\"name\":\"E\",\"symbols\":[\"Y\",\"Z\"]}");
            MemoryStream iostr = new MemoryStream();
            DatumWriter writer = new DatumWriter(actual);
            BinaryEncoder encoder = new BinaryEncoder(iostr);
            writer.write("Y", encoder);
            writer.write("X", encoder);
            byte[] data = iostr.ToArray();
            throw new NotImplementedException();

            //BinaryDecoder decoder = new BinaryDecoder(
            //Decoder decoder = BinaryDecoder.CreateBinaryDecoder(
            //    data, null);
            //DatumReader<String> input = new GenericDatumReader<String>(actual, expected);
            //Assert.AreEqual(input.Read(null, decoder), "Wrong value", "Y");
            //try
            //{
            //    input.Read(null, decoder);
            //    Assert.Fail("Should have thrown exception.");
            //}
            //catch (AvroTypeException e)
            //{
            //    // expected
            //}
        }
        /// <summary>
        /// Sends a OpenSecureChannel response.
        /// </summary>
        protected BufferCollection WriteAsymmetricMessage(
            uint               messageType,
            uint               requestId, 
            X509Certificate2   senderCertificate,
            X509Certificate2   receiverCertificate,
            ArraySegment<byte> messageBody)
        {                
            bool success = false;
            BufferCollection chunksToSend = new BufferCollection();

            byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "WriteAsymmetricMessage");

            try
            {
                int headerSize = GetAsymmetricHeaderSize(SecurityPolicyUri, senderCertificate);
                int signatureSize = GetAsymmetricSignatureSize(senderCertificate);
                                    
                BinaryEncoder encoder = new BinaryEncoder(buffer, 0, SendBufferSize, Quotas.MessageContext);

                WriteAsymmetricMessageHeader(
                    encoder,
                    messageType | TcpMessageType.Intermediate,
                    ChannelId,
                    SecurityPolicyUri,
                    senderCertificate,
                    receiverCertificate);
                
                // save the header.
                ArraySegment<byte> header = new ArraySegment<byte>(buffer, 0, headerSize);
                
                // calculate the space available.
                int plainTextBlockSize = GetPlainTextBlockSize(receiverCertificate);
                int cipherTextBlockSize = GetCipherTextBlockSize(receiverCertificate);
                int maxCipherTextSize = SendBufferSize - headerSize;
                int maxCipherBlocks = maxCipherTextSize/cipherTextBlockSize; 
                int maxPlainTextSize = maxCipherBlocks*plainTextBlockSize;
                int maxPayloadSize = maxPlainTextSize - signatureSize - 1 - TcpMessageLimits.SequenceHeaderSize;

                int bytesToWrite = messageBody.Count;
                int startOfBytes = messageBody.Offset;

                while (bytesToWrite > 0)
                {
                    encoder.WriteUInt32(null, GetNewSequenceNumber());
                    encoder.WriteUInt32(null, requestId);

                    int payloadSize = bytesToWrite;

                    if (payloadSize > maxPayloadSize)
                    {
                        payloadSize = maxPayloadSize;
                    }
                    else
                    {
                        UpdateMessageType(buffer, 0, messageType | TcpMessageType.Final);
                    }

                    // write the message body.
                    encoder.WriteRawBytes(messageBody.Array, messageBody.Offset+startOfBytes, payloadSize);

                    // calculate the amount of plain text to encrypt.
                    int plainTextSize = encoder.Position - headerSize + signatureSize;
                                    
                    // calculate the padding.
                    int padding = 0;         
           
                    if (SecurityMode != MessageSecurityMode.None)
                    {
                        if (receiverCertificate.PublicKey.Key.KeySize <= TcpMessageLimits.KeySizeExtraPadding)
                        {
                            // need to reserve one byte for the padding.
                            plainTextSize++;

                            if (plainTextSize % plainTextBlockSize != 0)
                            {
                                padding = plainTextBlockSize - (plainTextSize % plainTextBlockSize);
                            }

                            encoder.WriteByte(null, (byte)padding);
                            for (int ii = 0; ii < padding; ii++)
                            {
                                encoder.WriteByte(null, (byte)padding);
                            }
                        }
                        else
                        {
                            // need to reserve one byte for the padding.
                            plainTextSize++;
                            // need to reserve one byte for the extrapadding.
                            plainTextSize++;

                            if (plainTextSize % plainTextBlockSize != 0)
                            {
                                padding = plainTextBlockSize - (plainTextSize % plainTextBlockSize);
                            }

                            byte paddingSize = (byte)(padding & 0xff);
                            byte extraPaddingByte = (byte)((padding >> 8) & 0xff);

                            encoder.WriteByte(null, paddingSize);
                            for (int ii = 0; ii < padding; ii++)
                            {
                                encoder.WriteByte(null, (byte)paddingSize);
                            }
                            encoder.WriteByte(null, extraPaddingByte);
                        }

                        // update the plaintext size with the padding size.
                        plainTextSize += padding;
                    }
                      
                    // calculate the number of block to encrypt.
                    int encryptedBlocks = plainTextSize/plainTextBlockSize;

                    // calculate the size of the encrypted data.
                    int cipherTextSize = encryptedBlocks*cipherTextBlockSize;
                    
                    // put the message size after encryption into the header.
                    UpdateMessageSize(buffer, 0, cipherTextSize + headerSize);

                    // write the signature.
                    byte[] signature = Sign(new ArraySegment<byte>(buffer, 0, encoder.Position), senderCertificate);
                                   
                    if (signature != null)
                    {
                        encoder.WriteRawBytes(signature, 0, signature.Length);
                    }
                    
                    int messageSize = encoder.Close();

                    // encrypt the data.
                    ArraySegment<byte> encryptedBuffer = Encrypt(
                        new ArraySegment<byte>(buffer, headerSize, messageSize-headerSize), 
                        header, 
                        receiverCertificate);

                    // check for math errors due to code bugs.
                    if (encryptedBuffer.Count != cipherTextSize + headerSize)
                    {
                        throw new InvalidDataException("Actual message size is not the same as the predicted message size.");
                    }

                    // save chunk.
                    chunksToSend.Add(encryptedBuffer);

                    bytesToWrite -= payloadSize;
                    startOfBytes += payloadSize;

                    // reset the encoder to write the plaintext for the next chunk into the same buffer.
                    if (bytesToWrite > 0)
                    {
                        MemoryStream ostrm = new MemoryStream(buffer, 0, SendBufferSize);
                        ostrm.Seek(header.Count, SeekOrigin.Current);
                        encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);
                    }
                }

                // ensure the buffers don't get clean up on exit.
                success = true;
                return chunksToSend;
            }
            finally
            {
                BufferManager.ReturnBuffer(buffer, "WriteAsymmetricMessage");  

                if (!success)
                {
                    chunksToSend.Release(BufferManager, "WriteAsymmetricMessage");
                }
            }
        }
        /// <summary>
        /// Updates the base event.
        /// </summary>
        private void UpdateBaseEvent(BaseEventState instance, EventType eventType, ONEVENTSTRUCT e)
        {
            BinaryEncoder encoder = new BinaryEncoder(ServiceMessageContext.GlobalContext);

            encoder.WriteString(null, e.szSource);
            encoder.WriteString(null, e.szConditionName);
            encoder.WriteInt32(null, e.ftActiveTime.dwHighDateTime);
            encoder.WriteInt32(null, e.ftActiveTime.dwLowDateTime);
            encoder.WriteInt32(null, e.dwCookie);

            byte[] eventId = encoder.CloseAndReturnBuffer();
            NodeId eventTypeId = AeParsedNodeId.Construct(e.dwEventType, e.dwEventCategory, e.szConditionName, m_namespaceIndex);
            NodeId sourceNode = AeModelUtils.ConstructIdForSource(e.szSource, null, m_namespaceIndex);
            string sourceName = e.szSource;
            DateTime time = ComUtils.GetDateTime(e.ftTime);
            DateTime receiveTime = DateTime.UtcNow;
            LocalizedText message = e.szMessage;
            ushort severity = (ushort)e.dwSeverity;

            instance.TypeDefinitionId = eventTypeId;
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EventId, eventId, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.EventType, eventTypeId, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.SourceNode, sourceNode, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.SourceName, sourceName, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Time, time, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.ReceiveTime, receiveTime, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Message, message, false);
            instance.SetChildValue(m_defaultContext, Opc.Ua.BrowseNames.Severity, severity, false);
        }
示例#5
0
        public void FVEncryptMultiplyManyDecryptNET()
        {
            var parms = new EncryptionParameters(MemoryPoolHandle.AcquireNew());

            parms.SetDecompositionBitCount(4);
            parms.SetNoiseStandardDeviation(3.19);
            parms.SetNoiseMaxDeviation(35.06);

            var coeffModulus = new BigUInt(48);

            coeffModulus.Set("FFFFFFFFC001");
            parms.SetCoeffModulus(coeffModulus);

            var plainModulus = new BigUInt(7);

            plainModulus.Set(1 << 6);
            parms.SetPlainModulus(plainModulus);

            var polyModulus = new BigPoly(65, 1);

            polyModulus[0].Set(1);
            polyModulus[64].Set(1);
            parms.SetPolyModulus(polyModulus);

            parms.Validate();

            var keygen = new KeyGenerator(parms, MemoryPoolHandle.AcquireNew());

            keygen.Generate(1);

            var encoder = new BinaryEncoder(parms.PlainModulus, MemoryPoolHandle.AcquireNew());

            var encryptor = new Encryptor(parms, keygen.PublicKey, MemoryPoolHandle.AcquireNew());
            var evaluator = new Evaluator(parms, keygen.EvaluationKeys, MemoryPoolHandle.AcquireNew());
            var decryptor = new Decryptor(parms, keygen.SecretKey, MemoryPoolHandle.AcquireNew());

            var encrypted1 = encryptor.Encrypt(encoder.Encode(2));
            var encrypted2 = encryptor.Encrypt(encoder.Encode(-3));
            var encrypted3 = encryptor.Encrypt(encoder.Encode(4));
            var encrypteds = new List <BigPolyArray>()
            {
                encrypted1, encrypted2, encrypted3
            };
            var product = evaluator.MultiplyMany(encrypteds);

            Assert.AreEqual(-24, encoder.DecodeInt32(decryptor.Decrypt(product)));

            encrypted1 = encryptor.Encrypt(encoder.Encode(-9));
            encrypted2 = encryptor.Encrypt(encoder.Encode(-17));
            encrypteds = new List <BigPolyArray>()
            {
                encrypted1, encrypted2
            };
            product = evaluator.MultiplyMany(encrypteds);
            Assert.AreEqual(153, encoder.DecodeInt32(decryptor.Decrypt(product)));

            encrypted1 = encryptor.Encrypt(encoder.Encode(2));
            encrypted2 = encryptor.Encrypt(encoder.Encode(-31));
            encrypted3 = encryptor.Encrypt(encoder.Encode(7));
            encrypteds = new List <BigPolyArray>()
            {
                encrypted1, encrypted2, encrypted3
            };
            product = evaluator.MultiplyMany(encrypteds);
            Assert.AreEqual(-434, encoder.DecodeInt32(decryptor.Decrypt(product)));

            encrypted1 = encryptor.Encrypt(encoder.Encode(1));
            encrypted2 = encryptor.Encrypt(encoder.Encode(-1));
            encrypted3 = encryptor.Encrypt(encoder.Encode(1));
            var encrypted4 = encryptor.Encrypt(encoder.Encode(-1));

            encrypteds = new List <BigPolyArray>()
            {
                encrypted1, encrypted2, encrypted3, encrypted4
            };
            product = evaluator.MultiplyMany(encrypteds);
            Assert.AreEqual(1, encoder.DecodeInt32(decryptor.Decrypt(product)));

            encrypted1 = encryptor.Encrypt(encoder.Encode(98765));
            encrypted2 = encryptor.Encrypt(encoder.Encode(0));
            encrypted3 = encryptor.Encrypt(encoder.Encode(12345));
            encrypted4 = encryptor.Encrypt(encoder.Encode(34567));
            encrypteds = new List <BigPolyArray>()
            {
                encrypted1, encrypted2, encrypted3, encrypted4
            };
            product = evaluator.MultiplyMany(encrypteds);
            Assert.AreEqual(0, encoder.DecodeInt32(decryptor.Decrypt(product)));
        }
        /// <summary>
        /// Converts a remote value to a local value.
        /// </summary>
        /// <param name="srcValue">The remote value.</param>
        /// <param name="srcType">The data type of the remote value.</param>
        /// <param name="dstType">The data type of the local value.</param>
        /// <returns>The local value.</returns>
        private object ConvertRemoteToLocal(object srcValue, BuiltInType srcType, BuiltInType dstType)
        {
            // check for null.
            if (srcValue == null)
            {
                return null;
            }

            // 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;

                if (typeInfo.ValueRank != ValueRanks.Scalar)
                {
                    return TypeInfo.CastArray((Array)srcValue, srcType, BuiltInType.Null, ConvertRemoteToLocal);
                }
            }

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

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

                case BuiltInType.XmlElement:
                {
                    dstValue = ((XmlElement)srcValue).OuterXml;
                    break;
                }

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

                case BuiltInType.ExpandedNodeId:
                {
                    ExpandedNodeId nodeId = GetLocaleExpandedNodeId((ExpandedNodeId)srcValue);
                    dstValue = nodeId.ToString();
                    break;
                }

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

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

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

                case BuiltInType.ExtensionObject:
                {
                    BinaryEncoder encoder = new BinaryEncoder(m_localMessageContext);
                    encoder.WriteExtensionObject(null, (ExtensionObject)srcValue);
                    dstValue = encoder.CloseAndReturnBuffer();
                    break;
                }

                case BuiltInType.Variant:
                {
                    dstValue = ((Variant)srcValue).Value;
                    break;
                }

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

                    break;
                }
            }

            // all done.
            return dstValue;
        }
示例#7
0
        /// <summary>
        /// Converts an object into a value that can be marshalled to a VARIANT.
        /// </summary>
        /// <param name="source">The object to convert.</param>
        /// <param name="typeInfo">The type info.</param>
        /// <returns>The converted object.</returns>
        public static object GetVARIANT(object source, TypeInfo typeInfo)
		{
			// check for invalid args.
			if (source == null)
			{
				return null;
			}
            
            try
            {
                switch (typeInfo.BuiltInType)
                {
                    case BuiltInType.Boolean:
                    case BuiltInType.Byte:
                    case BuiltInType.Int16:
                    case BuiltInType.UInt16:
                    case BuiltInType.Int32:
                    case BuiltInType.UInt32:
                    case BuiltInType.Int64:
                    case BuiltInType.UInt64:
                    case BuiltInType.Float:
                    case BuiltInType.Double:
                    case BuiltInType.String:
                    case BuiltInType.DateTime:
                    {
                        return source;
                    }

                    case BuiltInType.ByteString:
                    {
                        if (typeInfo.ValueRank < 0)
                        {
                            return source;
                        }
                        
                        return VariantToObjectArray((Array)source);
                    }

                    case BuiltInType.Guid:
                    case BuiltInType.LocalizedText:
                    case BuiltInType.QualifiedName:
                    case BuiltInType.NodeId:
                    case BuiltInType.ExpandedNodeId:                  
                    case BuiltInType.XmlElement:  
                    {
                        return TypeInfo.Cast(source, typeInfo, BuiltInType.String);
                    }

                    case BuiltInType.StatusCode: 
                    {
                        return TypeInfo.Cast(source, typeInfo, BuiltInType.UInt32);
                    }
                       
                    case BuiltInType.Variant:
                    {
                        if (typeInfo.ValueRank < 0)
                        {
                            return GetVARIANT(((Variant)source).Value);
                        }

                        return VariantToObjectArray((Array)source);
                    }

                    case BuiltInType.ExtensionObject:
                    {
                        if (typeInfo.ValueRank < 0)
                        {
                            byte[] body = null;

                            ExtensionObject extension = (ExtensionObject)source;

                            switch (extension.Encoding)
                            {
                                case ExtensionObjectEncoding.Binary: 
                                {
                                    body = (byte[])extension.Body;
                                    break;
                                }

                                case ExtensionObjectEncoding.Xml: 
                                {
                                    body = new UTF8Encoding().GetBytes(((XmlElement)extension.Body).OuterXml);
                                    break;
                                }

                                case ExtensionObjectEncoding.EncodeableObject: 
                                {
                                    BinaryEncoder encoder = new BinaryEncoder(ServiceMessageContext.GlobalContext);
                                    encoder.WriteEncodeable(null, (IEncodeable)extension.Body, null);
                                    body = encoder.CloseAndReturnBuffer();
                                    break;
                                }
                            }

                            return body;
                        }

                        return VariantToObjectArray((Array)source);
                    }
                       
                    case BuiltInType.DataValue:
                    case BuiltInType.DiagnosticInfo:
                    {
                        return "(unsupported)";
                    }
                }
            }
            catch (Exception e)
            {
                return e.Message;
            }

			// no conversion required.
			return source;
		}
        /// <summary>
        /// Saves object in an binary stream.
        /// </summary>
        /// <param name="context">The context user.</param>
        /// <param name="encoder">The encoder to write to.</param>
        /// <param name="attributesToSave">The masks indicating what attributes to write.</param>
        public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave)
        {
            base.Save(context, encoder, attributesToSave);

            if ((attributesToSave & AttributesToSave.Value) != 0)
            {
                encoder.WriteVariant(null, WrappedValue);
            }

            if ((attributesToSave & AttributesToSave.DataType) != 0)
            {
                encoder.WriteNodeId(null, m_dataType);
            }

            if ((attributesToSave & AttributesToSave.ValueRank) != 0)
            {
                encoder.WriteInt32(null, m_valueRank);
            }

            if ((attributesToSave & AttributesToSave.ArrayDimensions) != 0)
            {
                encoder.WriteUInt32Array(null, m_arrayDimensions);
            }
        }
示例#9
0
 public bool Encode(BinaryEncoder encoder)
 {
     if (!BinaryCodec.Encode(encoder, _id))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _name))
     {
         return(false);
     }
     {
         int enumValue = (int)tileMaterial;
         if (!BinaryCodec.Encode(encoder, enumValue))
         {
             return(false);
         }
     }
     if (!BinaryCodec.Encode(encoder, _isMove))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _groupname))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _randomCount))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _isAutoTile))
     {
         return(false);
     }
     {
         int enumValue = (int)autoTileType;
         if (!BinaryCodec.Encode(encoder, enumValue))
         {
             return(false);
         }
     }
     if (!BinaryCodec.Encode(encoder, _subPath))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _spritePack))
     {
         return(false);
     }
     {
         ushort _size = (ushort)sprites.Count;
         if (!BinaryCodec.Encode(encoder, _size))
         {
             return(false);
         }
         for (int i = 0; i < sprites.Count; ++i)
         {
             string item = sprites[i];
             if (!BinaryCodec.Encode(encoder, item))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
示例#10
0
 public bool Encode(BinaryEncoder encoder)
 {
     if (!BinaryCodec.Encode(encoder, _id))
     {
         return(false);
     }
     {
         int enumValue = (int)tileMapType;
         if (!BinaryCodec.Encode(encoder, enumValue))
         {
             return(false);
         }
     }
     if (!BinaryCodec.Encode(encoder, _name))
     {
         return(false);
     }
     if (!BinaryCodec.EncodeUnicodeString(encoder, _displayName))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _sizeX))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _sizeY))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _isFog))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _groupname))
     {
         return(false);
     }
     {
         ushort _size = (ushort)bgTileSets.Count;
         if (!BinaryCodec.Encode(encoder, _size))
         {
             return(false);
         }
         for (int i = 0; i < bgTileSets.Count; ++i)
         {
             string item = bgTileSets[i];
             if (!BinaryCodec.Encode(encoder, item))
             {
                 return(false);
             }
         }
     }
     {
         ushort _size = (ushort)objectTileSets.Count;
         if (!BinaryCodec.Encode(encoder, _size))
         {
             return(false);
         }
         for (int i = 0; i < objectTileSets.Count; ++i)
         {
             string item = objectTileSets[i];
             if (!BinaryCodec.Encode(encoder, item))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
示例#11
0
        public void Run(TcpClient client)
        {
            try
            {
                logger.Log(this, String.Format("Godot has been activated. Client IP address is {0}",
                                               LUtils.GetIpAddress(client)));
                godotCounter.IncreaseRunning();

                stream = new SslStream(client.GetStream(), false, CertificateValidation);
                stream.AuthenticateAsServer(serverCert, true, SslProtocols.Tls12, false);

                logger.Log(this, "SSL authentication completed. Starting Handshake.");
                this.connectionInfo = Handshake.Run(stream, Log, config);


                bool running = true;
                while (running)
                {
                    ConnectionCommand command = BinaryEncoder.ReadCommand(stream);
                    switch (command)
                    {
                    case ConnectionCommand.TRUST_CONTACT:
                        Log("TRUST_CONTACT command received.");
                        TrustContact();
                        break;

                    case ConnectionCommand.UNTRUST_CONTACT:
                        Log("UNTRUST_CONTACT command received.");
                        UntrustContact();
                        break;

                    case ConnectionCommand.PULL:
#if (DEBUG)
                        Log("PULL command received.");
#endif
                        Push();
                        break;

                    case ConnectionCommand.PUSH:
#if (DEBUG)
                        Log("PUSH command received.");
#endif
                        Pull();
                        break;

                    case ConnectionCommand.SEARCH_CONTACT:
                        Log("SEARCH_CONTACT command received.");
                        SearchContact();
                        break;

                    case ConnectionCommand.END_CONNECTION:
                        Log("END_CONNECTION command received.");
                        running = false;
                        break;

                    default:
                        throw new Exception("Received unknown command.");
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Log(this, "Godot has crashed.");
                logger.LogException(this, ex);
            }
            finally
            {
                stream.Close();
                client.Close();
                godotCounter.IncreaseDestroyed();
                logger.Log(this, "Godot has died.");
            }
        }
示例#12
0
        private void Push()
        {
#if (DEBUG)
            Log("Pushing started.");
#endif
            ClientPullCapsula clientPullCapsula = TextEncoder.ReadJson <ClientPullCapsula>(stream);

            using (Context context = new Context(config))
            {
                ServerPullCapsula capsula = new ServerPullCapsula();

                List <byte[]> messagesBlobsToSend = new List <byte[]>();
                List <byte[]> aesBlobsToSend      = new List <byte[]>();

                var messagesIdsUploaded = context.ClientsMessagesDownloaded
                                          .Where(u => u.ClientsId == connectionInfo.ClientId)
                                          .Select(u => u.BlobMessagesId);

                List <PullMessage> pullMessages = new List <PullMessage>();
                foreach (var message in
                         from messages in context.BlobMessages
                         orderby messages.Priority descending, messages.Id ascending                 //Message order must be respected
                         where messages.RecepientId == connectionInfo.UserId                         //Messages of connected user
                         where !messagesIdsUploaded.Contains(messages.Id)                            //New messages

                         join keys in context.UsersKeys on messages.RecepientId equals keys.SenderId //Keys sended by connected user
                         where keys.Trusted == true                                                  //Only trusted
                         where messages.SenderId == keys.RecepientId                                 //Trusted information just only about sending user
                         select new { messages.SenderId, messages.Content, messages.Id }
                         )
                {
                    pullMessages.Add(new PullMessage()
                    {
                        PublicId = message.Id,
                        SenderId = message.SenderId
                    });
                    messagesBlobsToSend.Add(message.Content);
                    context.ClientsMessagesDownloaded.Add(new ClientsMessagesDownloaded()
                    {
                        BlobMessagesId = message.Id,
                        ClientsId      = connectionInfo.ClientId
                    });
                }
                capsula.Messages = pullMessages;
#if (DEBUG)
                Log($"{messagesBlobsToSend.Count} messageBlobs will be pushed.");
#endif
                capsula.AesKeysUserIds = new List <long>();
                foreach (var user in
                         from userKeys in context.UsersKeys
                         where userKeys.RecepientId == connectionInfo.UserId
                         where clientPullCapsula.AesKeysUserIds.Contains(userKeys.SenderId)
                         select new { userKeys.SenderId, userKeys.AesKey })
                {
                    capsula.AesKeysUserIds.Add(user.SenderId);
                    aesBlobsToSend.Add(user.AesKey);
                }
#if (DEBUG)
                Log($"{capsula.AesKeysUserIds.Count} AES keys will be pushed.");
                Log($"Sending PullCapsula.");
#endif
                TextEncoder.SendJson(stream, capsula);
#if (DEBUG)
                Log($"Sending AES keys.");
#endif
                foreach (byte[] data in aesBlobsToSend)
                {
                    BinaryEncoder.SendBytes(stream, data);
                }
#if (DEBUG)
                Log($"Sending Messages content.");
#endif
                foreach (byte[] data in messagesBlobsToSend)
                {
                    BinaryEncoder.SendBytes(stream, data);
                }
                stream.Flush();
                context.SaveChanges();
            }
#if (DEBUG)
            Log("Pushing completed.");
#endif
        }
示例#13
0
        private void Pull()
        {
#if (DEBUG)
            Log("Pulling started.");
            Log("Receiving PushCapsula.");
#endif

            PushCapsula  capsula  = TextEncoder.ReadJson <PushCapsula>(stream);
            PushResponse response = new PushResponse()
            {
                MessageIds = new List <long>()
            };

            using (Context context = new Context(config))
            {
#if (DEBUG)
                Log($"Receiving and saving {capsula.PushMessages.Count} blobs.");
#endif

                foreach (var pushMessage in capsula.PushMessages)
                {
                    BlobMessages blobMessage = new BlobMessages()
                    {
                        Content     = BinaryEncoder.ReceiveBytes(stream),
                        RecepientId = pushMessage.RecepientId,
                        SenderId    = connectionInfo.UserId,
                        Priority    = pushMessage.Priority
                    };
                    context.BlobMessages.Add(blobMessage);
                    context.SaveChanges();

                    if (pushMessage.RecepientId == connectionInfo.UserId)
                    {
                        response.MessageIds.Add(blobMessage.Id);
                        context.ClientsMessagesDownloaded.Add(new ClientsMessagesDownloaded()
                        {
                            BlobMessagesId = blobMessage.Id,
                            ClientsId      = connectionInfo.ClientId
                        });
                    }
                    context.SaveChanges();
                }
#if (DEBUG)
                Log($"Deleting {capsula.MessageToDeleteIds.Count} blobs.");
#endif
                foreach (var toDeleteId in capsula.MessageToDeleteIds)
                {
                    var toDelete = context.BlobMessages
                                   .Where(u => u.RecepientId == connectionInfo.UserId && u.Id == toDeleteId).SingleOrDefault();
                    if (toDelete != null)
                    {
                        context.BlobMessages.Remove(toDelete);
                    }
                }
                context.SaveChanges();
            }


#if (DEBUG)
            Log("Sending push response.");
#endif
            TextEncoder.SendJson(stream, response);
#if (DEBUG)
            Log("Pulling ended.");
#endif
        }
        /// <summary>
        /// Encodes field value as RawData
        /// </summary>
        /// <param name="binaryEncoder"></param>
        /// <param name="field"></param>
        private void EncodeFieldAsRawData(BinaryEncoder binaryEncoder, Field field)
        {
            try
            {
                // 01 RawData Field Encoding (TODO: StructuredValue)
                var variant = field.Value.WrappedValue;

                if (variant.TypeInfo == null || variant.TypeInfo.BuiltInType == BuiltInType.Null)
                {
                    return;
                }

                if (field.FieldMetaData.ValueRank == ValueRanks.Scalar)
                {
                    switch ((BuiltInType)field.FieldMetaData.BuiltInType)
                    {
                    case BuiltInType.Boolean:
                        binaryEncoder.WriteBoolean("Bool", Convert.ToBoolean(variant.Value));
                        break;

                    case BuiltInType.SByte:
                        binaryEncoder.WriteSByte("SByte", Convert.ToSByte(variant.Value));
                        break;

                    case BuiltInType.Byte:
                        binaryEncoder.WriteByte("Byte", Convert.ToByte(variant.Value));
                        break;

                    case BuiltInType.Int16:
                        binaryEncoder.WriteInt16("Int16", Convert.ToInt16(variant.Value));
                        break;

                    case BuiltInType.UInt16:
                        binaryEncoder.WriteUInt16("UInt16", Convert.ToUInt16(variant.Value));
                        break;

                    case BuiltInType.Int32:
                        binaryEncoder.WriteInt32("Int32", Convert.ToInt32(variant.Value));
                        break;

                    case BuiltInType.UInt32:
                        binaryEncoder.WriteUInt32("UInt32", Convert.ToUInt32(variant.Value));
                        break;

                    case BuiltInType.Int64:
                        binaryEncoder.WriteInt64("Int64", Convert.ToInt64(variant.Value));
                        break;

                    case BuiltInType.UInt64:
                        binaryEncoder.WriteUInt64("UInt64", Convert.ToUInt64(variant.Value));
                        break;

                    case BuiltInType.Float:
                        binaryEncoder.WriteFloat("Float", Convert.ToSingle(variant.Value));
                        break;

                    case BuiltInType.Double:
                        binaryEncoder.WriteDouble("Double", Convert.ToDouble(variant.Value));
                        break;

                    case BuiltInType.DateTime:
                        binaryEncoder.WriteDateTime("DateTime", Convert.ToDateTime(variant.Value));
                        break;

                    case BuiltInType.Guid:
                        binaryEncoder.WriteGuid("GUID", (Uuid)variant.Value);
                        break;

                    case BuiltInType.String:
                        binaryEncoder.WriteString("String", variant.Value as string);
                        break;

                    case BuiltInType.ByteString:
                        binaryEncoder.WriteByteString("ByteString", (byte[])variant.Value);
                        break;

                    case BuiltInType.QualifiedName:
                        binaryEncoder.WriteQualifiedName("QualifiedName", variant.Value as QualifiedName);
                        break;

                    case BuiltInType.LocalizedText:
                        binaryEncoder.WriteLocalizedText("LocalizedText", variant.Value as LocalizedText);
                        break;

                    case BuiltInType.NodeId:
                        binaryEncoder.WriteNodeId("NodeId", variant.Value as NodeId);
                        break;

                    case BuiltInType.ExpandedNodeId:
                        binaryEncoder.WriteExpandedNodeId("ExpandedNodeId", variant.Value as ExpandedNodeId);
                        break;

                    case BuiltInType.StatusCode:
                        binaryEncoder.WriteStatusCode("StatusCode", (StatusCode)variant.Value);
                        break;

                    case BuiltInType.XmlElement:
                        binaryEncoder.WriteXmlElement("XmlElement", variant.Value as XmlElement);
                        break;

                    case BuiltInType.Enumeration:
                        binaryEncoder.WriteInt32("Enumeration", Convert.ToInt32(variant.Value));
                        break;

                    case BuiltInType.ExtensionObject:
                        binaryEncoder.WriteExtensionObject("ExtensionObject", variant.Value as ExtensionObject);
                        break;
                    }
                }
                else
                {
                    switch ((BuiltInType)field.FieldMetaData.BuiltInType)
                    {
                    case BuiltInType.Boolean:
                        binaryEncoder.WriteBooleanArray("BooleanArray", (bool[])variant.Value);
                        break;

                    case BuiltInType.SByte:
                        binaryEncoder.WriteSByteArray("SByteArray", (sbyte[])variant.Value);
                        break;

                    case BuiltInType.Byte:
                        binaryEncoder.WriteByteArray("ByteArray", (byte[])variant.Value);
                        break;

                    case BuiltInType.Int16:
                        binaryEncoder.WriteInt16Array("ByteArray", (short[])variant.Value);
                        break;

                    case BuiltInType.UInt16:
                        binaryEncoder.WriteUInt16Array("UInt16Array", (ushort[])variant.Value);
                        break;

                    case BuiltInType.Int32:
                        binaryEncoder.WriteInt32Array("Int32Array", (int[])variant.Value);
                        break;

                    case BuiltInType.UInt32:
                        binaryEncoder.WriteUInt32Array("UInt32Array", (uint[])variant.Value);
                        break;

                    case BuiltInType.Int64:
                        binaryEncoder.WriteInt64Array("Int64Array", (long[])variant.Value);
                        break;

                    case BuiltInType.UInt64:
                        binaryEncoder.WriteUInt64Array("UInt64Array", (ulong[])variant.Value);
                        break;

                    case BuiltInType.Float:
                        binaryEncoder.WriteFloatArray("FloatArray", (float[])variant.Value);
                        break;

                    case BuiltInType.Double:
                        binaryEncoder.WriteDoubleArray("DoubleArray", (double[])variant.Value);
                        break;

                    case BuiltInType.DateTime:
                        binaryEncoder.WriteDateTimeArray("DateTimeArray", (DateTime[])variant.Value);
                        break;

                    case BuiltInType.Guid:
                        binaryEncoder.WriteGuidArray("GuidArray", (Uuid[])variant.Value);
                        break;

                    case BuiltInType.String:
                        binaryEncoder.WriteStringArray("StringArray", (string[])variant.Value);
                        break;

                    case BuiltInType.ByteString:
                        binaryEncoder.WriteByteStringArray("StringArray", (byte[][])variant.Value);
                        break;

                    case BuiltInType.QualifiedName:
                        binaryEncoder.WriteQualifiedNameArray("QualifiedNameArray", (QualifiedName[])variant.Value);
                        break;

                    case BuiltInType.LocalizedText:
                        binaryEncoder.WriteLocalizedTextArray("LocalizedTextArray", (LocalizedText[])variant.Value);
                        break;

                    case BuiltInType.NodeId:
                        binaryEncoder.WriteNodeIdArray("NodeIdArray", (NodeId[])variant.Value);
                        break;

                    case BuiltInType.ExpandedNodeId:
                        binaryEncoder.WriteExpandedNodeIdArray("ExpandedNodeIdArray", (ExpandedNodeId[])variant.Value);
                        break;

                    case BuiltInType.StatusCode:
                        binaryEncoder.WriteStatusCodeArray("StatusCodeArray", (StatusCode[])variant.Value);
                        break;

                    case BuiltInType.XmlElement:
                        binaryEncoder.WriteXmlElementArray("XmlElementArray", (System.Xml.XmlElement[])variant.Value);
                        break;

                    case BuiltInType.Variant:
                        binaryEncoder.WriteVariantArray("VariantArray", (Variant[])variant.Value);
                        break;

                    case BuiltInType.Enumeration:
                        //TODO make this work
                        //binaryEncoder.WriteInt32Array("EnumerationArray", Convert.ToInt32(variant.Value));
                        binaryEncoder.WriteVariantArray("EnumerationArray", (Variant[])variant.Value);
                        break;

                    case BuiltInType.ExtensionObject:
                        binaryEncoder.WriteExtensionObjectArray("ExtensionObjectArray", (ExtensionObject[])variant.Value);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.Trace("Error encoding field {0} - {1}", field.FieldMetaData.Name, ex);
            }
        }
示例#15
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);
        }
        /// <summary>
        /// Completes an asynchronous operation to send a request over the secure channel.
        /// </summary>
        public void OnGetRequestStreamComplete(IAsyncResult result)
        {
            AsyncResult result2 = result.AsyncState as AsyncResult;

            if (result2 == null)
            {
                return;
            }

            try
            {
                Stream ostrm = result2.WebRequest.EndGetRequestStream(result);

                MemoryStream mstrm = new MemoryStream();

                if (m_settings.Configuration.UseBinaryEncoding)
                {
                    BinaryEncoder encoder = new BinaryEncoder(mstrm, this.MessageContext);
                    encoder.EncodeMessage(result2.Request);
                }
                else
                {
                    WriteSoapMessage(
                        mstrm, 
                        result2.Request.GetType().Name,
                        result2.Request,
                        this.MessageContext);
                }

                int bytesToRead = (int)mstrm.Position;
                mstrm.Position = 0;

                int bytesRead = 0;
                int blockSize = 0;
                byte[] buffer = new byte[4096];

                do
                {
                    blockSize = mstrm.Read(buffer, 0, buffer.Length);
                    bytesRead += blockSize;

                    if (bytesRead > bytesToRead)
                    {
                        blockSize -= (bytesRead - bytesToRead);
                    }

                    ostrm.Write(buffer, 0, blockSize);
                }
                while (blockSize >= 0 && bytesRead < bytesToRead);

                ostrm.Close();

                result2.InnerResult = result2.WebRequest.BeginGetResponse(OnBeginGetResponseComplete, result2);
            }
            catch (Exception exception)
            {
                result2.Exception = exception;
                result2.OperationCompleted();
            }
        }
示例#17
0
        public static void AvroEncodeInt(BinaryWriter stream, int x)
        {
            BinaryEncoder _e = new BinaryEncoder(stream.BaseStream);

            _e.WriteInt(x);
        }
示例#18
0
        /// <summary>
        /// Secures the message using the security token.
        /// </summary>
        protected BufferCollection WriteSymmetricMessage(
            uint            messageType,
            uint            requestId, 
            TcpChannelToken token,
            object          messageBody,
            bool            isRequest,
            out bool        limitsExceeded)
        {   
            limitsExceeded = false;
            bool success = false;
            BufferCollection chunksToProcess = null;

            try
            {
                // calculate chunk sizes.
                int maxCipherTextSize = SendBufferSize - TcpMessageLimits.SymmetricHeaderSize;
                int maxCipherBlocks   = maxCipherTextSize/EncryptionBlockSize;
                int maxPlainTextSize  = maxCipherBlocks*EncryptionBlockSize;
                int maxPayloadSize    = maxPlainTextSize - SymmetricSignatureSize - 1 - TcpMessageLimits.SequenceHeaderSize;        
                int headerSize        = TcpMessageLimits.SymmetricHeaderSize + TcpMessageLimits.SequenceHeaderSize;

                // write the body to stream.
                ArraySegmentStream ostrm = new ArraySegmentStream(
                    BufferManager, 
                    SendBufferSize, 
                    headerSize,
                    maxPayloadSize);
                
                // check for encodeable body.
                IEncodeable encodeable = messageBody as IEncodeable;

                if (encodeable != null)
                {                    
                    // debug code used to verify that message aborts are handled correctly.
                    // int maxMessageSize = Quotas.MessageContext.MaxMessageSize;
                    // Quotas.MessageContext.MaxMessageSize = Int32.MaxValue;
                    
                    BinaryEncoder.EncodeMessage(encodeable, ostrm, Quotas.MessageContext);

                    // Quotas.MessageContext.MaxMessageSize = maxMessageSize;
                }

                // check for raw bytes.
                ArraySegment<byte>? rawBytes = messageBody as ArraySegment<byte>?;
                
                if (rawBytes != null)
                {
                    BinaryEncoder encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);
                    encoder.WriteRawBytes(rawBytes.Value.Array, rawBytes.Value.Offset, rawBytes.Value.Count);
                    encoder.Close();
                }

                chunksToProcess = ostrm.GetBuffers("WriteSymmetricMessage");   
             
                // ensure there is at least one chunk.
                if (chunksToProcess.Count == 0)
                {
                    byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "WriteSymmetricMessage");
                    chunksToProcess.Add(new ArraySegment<byte>(buffer, 0, 0));
                }

                BufferCollection chunksToSend = new BufferCollection(chunksToProcess.Capacity);

                int messageSize = 0;

                for (int ii = 0; ii < chunksToProcess.Count; ii++)
                {
                    ArraySegment<byte> chunkToProcess = chunksToProcess[ii];
                    
                    // nothing more to do if limits exceeded.
                    if (limitsExceeded)
                    {
                        BufferManager.ReturnBuffer(chunkToProcess.Array, "WriteSymmetricMessage");
                        continue;
                    }

                    MemoryStream strm = new MemoryStream(chunkToProcess.Array, 0, SendBufferSize);
                    BinaryEncoder encoder = new BinaryEncoder(strm, Quotas.MessageContext);
                    
                    // check if the message needs to be aborted.
                    if (MessageLimitsExceeded(isRequest, messageSize + chunkToProcess.Count - headerSize, ii+1))
                    {
                        encoder.WriteUInt32(null, messageType | TcpMessageType.Abort);
                        
                        // replace the body in the chunk with an error message.
                        BinaryEncoder errorEncoder = new BinaryEncoder(
                            chunkToProcess.Array, 
                            chunkToProcess.Offset, 
                            chunkToProcess.Count, 
                            Quotas.MessageContext);
                        
                        WriteErrorMessageBody(errorEncoder, (isRequest)?StatusCodes.BadRequestTooLarge:StatusCodes.BadResponseTooLarge);
                                        
                        int size = errorEncoder.Close();
                        chunkToProcess = new ArraySegment<byte>(chunkToProcess.Array, chunkToProcess.Offset, size);

                        limitsExceeded = true;
                    }

                    // check if the message is complete.
                    else if (ii == chunksToProcess.Count-1)
                    {
                        encoder.WriteUInt32(null, messageType | TcpMessageType.Final);
                    }

                    // more chunks to follow.
                    else
                    {
                        encoder.WriteUInt32(null, messageType | TcpMessageType.Intermediate);
                    }
                    
                    int count = 0;
                    
                    count += TcpMessageLimits.SequenceHeaderSize;
                    count += chunkToProcess.Count;
                    count += SymmetricSignatureSize;
                    
                    // calculate the padding.
                    int padding = 0;                    
                    
                    if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
                    {
                        // reserve one byte for the padding size.
                        count++;

                        if (count%EncryptionBlockSize != 0)
                        {
                            padding = EncryptionBlockSize - (count%EncryptionBlockSize);
                        }
                        
                        count += padding;
                    }

                    count += TcpMessageLimits.SymmetricHeaderSize;

                    encoder.WriteUInt32(null, (uint)count);
                    encoder.WriteUInt32(null, ChannelId);
                    encoder.WriteUInt32(null, token.TokenId);

                    uint sequenceNumber = GetNewSequenceNumber();
                    encoder.WriteUInt32(null, sequenceNumber);
                    
                    encoder.WriteUInt32(null, requestId);

                    // skip body.
                    strm.Seek(chunkToProcess.Count, SeekOrigin.Current);
                        
                    // update message size count.
                    messageSize += chunkToProcess.Count;

                    // write padding.
                    if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
                    {
                        for (int jj = 0; jj <= padding; jj++)
                        {
                            encoder.WriteByte(null, (byte)padding);
                        }
                    }

                    if (SecurityMode != MessageSecurityMode.None)
                    {
                        // calculate and write signature.
                        byte[] signature = Sign(token, new ArraySegment<byte>(chunkToProcess.Array, 0, encoder.Position), isRequest);

                        if (signature != null)
                        {
                            encoder.WriteRawBytes(signature, 0, signature.Length);
                        }
                    }
                    
                    if (SecurityMode == MessageSecurityMode.SignAndEncrypt)
                    {
                        // encrypt the data.
                        ArraySegment<byte> dataToEncrypt = new ArraySegment<byte>(chunkToProcess.Array, TcpMessageLimits.SymmetricHeaderSize, encoder.Position-TcpMessageLimits.SymmetricHeaderSize);
                        Encrypt(token, dataToEncrypt, isRequest);
                    }

                    // add the header into chunk.
                    chunksToSend.Add(new ArraySegment<byte>(chunkToProcess.Array, 0, encoder.Position));
                }
           
                // ensure the buffers don't get cleaned up on exit.
                success = true;
                return chunksToSend;
            }
            finally
            {
                if (!success)
                {
                    if (chunksToProcess != null)
                    {
                        chunksToProcess.Release(BufferManager, "WriteSymmetricMessage");
                    }
                }
            }
        }      
        private async Task SendOpenSecureChannelRequestAsync(OpenSecureChannelRequest request, CancellationToken token)
        {
            var bodyStream = SerializableBytes.CreateWritableStream();
            var bodyEncoder = new BinaryEncoder(bodyStream, this);
            try
            {
                bodyEncoder.WriteNodeId(null, OpenSecureChannelRequestNodeId);
                request.Encode(bodyEncoder);
                bodyStream.Position = 0;
                if (bodyStream.Length > this.RemoteMaxMessageSize)
                {
                    throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                }

                // write chunks
                int chunkCount = 0;
                int bodyCount = (int)(bodyStream.Length - bodyStream.Position);
                while (bodyCount > 0)
                {
                    chunkCount++;
                    if (this.RemoteMaxChunkCount > 0 && chunkCount > this.RemoteMaxChunkCount)
                    {
                        throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                    }

                    var stream = new MemoryStream(this.sendBuffer, 0, (int)this.RemoteReceiveBufferSize, true, true);
                    var encoder = new BinaryEncoder(stream, this);
                    try
                    {
                        // header
                        encoder.WriteUInt32(null, UaTcpMessageTypes.OPNF);
                        encoder.WriteUInt32(null, 0u);
                        encoder.WriteUInt32(null, this.ChannelId);

                        // asymmetric security header
                        encoder.WriteString(null, this.RemoteEndpoint.SecurityPolicyUri);
                        if (this.RemoteEndpoint.SecurityMode != MessageSecurityMode.None)
                        {
                            encoder.WriteByteString(null, this.localCertificateBlob);
                            encoder.WriteByteString(null, this.RemoteCertificate.GetCertHash());
                        }
                        else
                        {
                            encoder.WriteByteString(null, null);
                            encoder.WriteByteString(null, null);
                        }

                        int plainHeaderSize = encoder.Position;

                        // sequence header
                        encoder.WriteUInt32(null, this.GetNextSequenceNumber());
                        encoder.WriteUInt32(null, request.RequestHeader.RequestHandle);

                        // body
                        int paddingHeaderSize;
                        int maxBodySize;
                        int bodySize;
                        int paddingSize;
                        int chunkSize;
                        if (this.asymIsEncrypted)
                        {
                            paddingHeaderSize = this.asymRemoteCipherTextBlockSize > 256 ? 2 : 1;
                            maxBodySize = ((((int)this.RemoteReceiveBufferSize - plainHeaderSize - this.asymLocalSignatureSize - paddingHeaderSize) / this.asymRemoteCipherTextBlockSize) * this.asymRemotePlainTextBlockSize) - SequenceHeaderSize;
                            if (bodyCount < maxBodySize)
                            {
                                bodySize = bodyCount;
                                paddingSize = (this.asymRemotePlainTextBlockSize - ((SequenceHeaderSize + bodySize + paddingHeaderSize + this.asymLocalSignatureSize) % this.asymRemotePlainTextBlockSize)) % this.asymRemotePlainTextBlockSize;
                            }
                            else
                            {
                                bodySize = maxBodySize;
                                paddingSize = 0;
                            }

                            chunkSize = plainHeaderSize + (((SequenceHeaderSize + bodySize + paddingSize + paddingHeaderSize + this.asymLocalSignatureSize) / this.asymRemotePlainTextBlockSize) * this.asymRemoteCipherTextBlockSize);
                        }
                        else
                        {
                            paddingHeaderSize = 0;
                            paddingSize = 0;
                            maxBodySize = (int)this.RemoteReceiveBufferSize - plainHeaderSize - this.asymLocalSignatureSize - SequenceHeaderSize;
                            if (bodyCount < maxBodySize)
                            {
                                bodySize = bodyCount;
                            }
                            else
                            {
                                bodySize = maxBodySize;
                            }

                            chunkSize = plainHeaderSize + SequenceHeaderSize + bodySize + this.asymLocalSignatureSize;
                        }

                        bodyStream.Read(this.sendBuffer, encoder.Position, bodySize);
                        encoder.Position += bodySize;
                        bodyCount -= bodySize;

                        // padding
                        if (this.asymIsEncrypted)
                        {
                            byte paddingByte = (byte)(paddingSize & 0xFF);
                            encoder.WriteByte(null, paddingByte);
                            for (int i = 0; i < paddingSize; i++)
                            {
                                encoder.WriteByte(null, paddingByte);
                            }

                            if (paddingHeaderSize == 2)
                            {
                                byte extraPaddingByte = (byte)((paddingSize >> 8) & 0xFF);
                                encoder.WriteByte(null, extraPaddingByte);
                            }
                        }

                        // update message type and (encrypted) length
                        var position = encoder.Position;
                        encoder.Position = 3;
                        encoder.WriteByte(null, bodyCount > 0 ? (byte)'C' : (byte)'F');
                        encoder.WriteUInt32(null, (uint)chunkSize);
                        encoder.Position = position;

                        // sign
                        if (this.asymIsSigned)
                        {
                            // sign with local private key.
                            byte[] signature = this.LocalPrivateKey.SignData(this.sendBuffer, 0, position, this.asymSignatureHashAlgorithmName, RSASignaturePadding.Pkcs1);
                            Debug.Assert(signature.Length == this.asymLocalSignatureSize, nameof(this.asymLocalSignatureSize));
                            encoder.Write(signature, 0, this.asymLocalSignatureSize);
                        }

                        // encrypt
                        if (this.asymIsEncrypted)
                        {
                            position = encoder.Position;
                            Buffer.BlockCopy(this.sendBuffer, 0, this.encryptionBuffer, 0, plainHeaderSize);
                            byte[] plainText = new byte[this.asymRemotePlainTextBlockSize];
                            int jj = plainHeaderSize;
                            for (int ii = plainHeaderSize; ii < position; ii += this.asymRemotePlainTextBlockSize)
                            {
                                Buffer.BlockCopy(this.sendBuffer, ii, plainText, 0, this.asymRemotePlainTextBlockSize);

                                // encrypt with remote public key.
                                byte[] cipherText = this.RemotePublicKey.Encrypt(plainText, this.asymEncryptionPadding);
                                Debug.Assert(cipherText.Length == this.asymRemoteCipherTextBlockSize, nameof(this.asymRemoteCipherTextBlockSize));
                                Buffer.BlockCopy(cipherText, 0, this.encryptionBuffer, jj, this.asymRemoteCipherTextBlockSize);
                                jj += this.asymRemoteCipherTextBlockSize;
                            }

                            await this.SendAsync(this.encryptionBuffer, 0, jj, token).ConfigureAwait(false);
                            return;
                        }

                        // pass buffer to transport
                        await this.SendAsync(this.sendBuffer, 0, encoder.Position, token).ConfigureAwait(false);
                    }
                    finally
                    {
                        encoder.Dispose();
                    }
                }
            }
            finally
            {
                bodyEncoder.Dispose();
            }
        }
        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;
        }
        private async Task SendCloseSecureChannelRequestAsync(CloseSecureChannelRequest request, CancellationToken token)
        {
            var bodyStream = SerializableBytes.CreateWritableStream();
            var bodyEncoder = new BinaryEncoder(bodyStream, this);
            try
            {
                bodyEncoder.WriteNodeId(null, CloseSecureChannelRequestNodeId);
                request.Encode(bodyEncoder);
                bodyStream.Position = 0;
                if (bodyStream.Length > this.RemoteMaxMessageSize)
                {
                    throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                }

                // write chunks
                int chunkCount = 0;
                int bodyCount = (int)(bodyStream.Length - bodyStream.Position);
                while (bodyCount > 0)
                {
                    chunkCount++;
                    if (this.RemoteMaxChunkCount > 0 && chunkCount > this.RemoteMaxChunkCount)
                    {
                        throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded);
                    }

                    var stream = new MemoryStream(this.sendBuffer, 0, (int)this.RemoteReceiveBufferSize, true, true);
                    var encoder = new BinaryEncoder(stream, this);
                    try
                    {
                        // header
                        encoder.WriteUInt32(null, UaTcpMessageTypes.CLOF);
                        encoder.WriteUInt32(null, 0u);
                        encoder.WriteUInt32(null, this.ChannelId);

                        // symmetric security header
                        encoder.WriteUInt32(null, this.TokenId);

                        // detect new TokenId
                        if (this.TokenId != this.currentClientTokenId)
                        {
                            this.currentClientTokenId = this.TokenId;

                            // update signer and encrypter with new symmetric keys
                            if (this.symIsSigned)
                            {
                                this.symSigner.Key = this.clientSigningKey;
                                if (this.symIsEncrypted)
                                {
                                    this.currentClientEncryptingKey = this.clientEncryptingKey;
                                    this.currentClientInitializationVector = this.clientInitializationVector;
                                    this.symEncryptor = this.symEncryptionAlgorithm.CreateEncryptor(this.currentClientEncryptingKey, this.currentClientInitializationVector);
                                }
                            }
                        }

                        int plainHeaderSize = encoder.Position;

                        // sequence header
                        encoder.WriteUInt32(null, this.GetNextSequenceNumber());
                        encoder.WriteUInt32(null, request.RequestHeader.RequestHandle);

                        // body
                        int paddingHeaderSize;
                        int maxBodySize;
                        int bodySize;
                        int paddingSize;
                        int chunkSize;
                        if (this.symIsEncrypted)
                        {
                            paddingHeaderSize = this.symEncryptionBlockSize > 256 ? 2 : 1;
                            maxBodySize = ((((int)this.RemoteReceiveBufferSize - plainHeaderSize - this.symSignatureSize - paddingHeaderSize) / this.symEncryptionBlockSize) * this.symEncryptionBlockSize) - SequenceHeaderSize;
                            if (bodyCount < maxBodySize)
                            {
                                bodySize = bodyCount;
                                paddingSize = (this.symEncryptionBlockSize - ((SequenceHeaderSize + bodySize + paddingHeaderSize + this.symSignatureSize) % this.symEncryptionBlockSize)) % this.symEncryptionBlockSize;
                            }
                            else
                            {
                                bodySize = maxBodySize;
                                paddingSize = 0;
                            }

                            chunkSize = plainHeaderSize + (((SequenceHeaderSize + bodySize + paddingSize + paddingHeaderSize + this.symSignatureSize) / this.symEncryptionBlockSize) * this.symEncryptionBlockSize);
                        }
                        else
                        {
                            paddingHeaderSize = 0;
                            paddingSize = 0;
                            maxBodySize = (int)this.RemoteReceiveBufferSize - plainHeaderSize - this.symSignatureSize - SequenceHeaderSize;
                            if (bodyCount < maxBodySize)
                            {
                                bodySize = bodyCount;
                            }
                            else
                            {
                                bodySize = maxBodySize;
                            }

                            chunkSize = plainHeaderSize + SequenceHeaderSize + bodySize + this.symSignatureSize;
                        }

                        bodyStream.Read(this.sendBuffer, encoder.Position, bodySize);
                        encoder.Position += bodySize;
                        bodyCount -= bodySize;

                        // padding
                        if (this.symIsEncrypted)
                        {
                            var paddingByte = (byte)(paddingSize & 0xFF);
                            encoder.WriteByte(null, paddingByte);
                            for (int i = 0; i < paddingSize; i++)
                            {
                                encoder.WriteByte(null, paddingByte);
                            }

                            if (paddingHeaderSize == 2)
                            {
                                var extraPaddingByte = (byte)((paddingSize >> 8) & 0xFF);
                                encoder.WriteByte(null, extraPaddingByte);
                            }
                        }

                        // update message type and (encrypted) length
                        var position = encoder.Position;
                        encoder.Position = 3;
                        encoder.WriteByte(null, bodyCount > 0 ? (byte)'C' : (byte)'F');
                        encoder.WriteUInt32(null, (uint)chunkSize);
                        encoder.Position = position;

                        // signature
                        if (this.symIsSigned)
                        {
                            byte[] signature = this.symSigner.ComputeHash(this.sendBuffer, 0, position);
                            if (signature != null)
                            {
                                encoder.Write(signature, 0, signature.Length);
                            }
                        }

                        // encrypt
                        position = encoder.Position;
                        if (this.symIsEncrypted)
                        {
                            using (var symEncryptor = this.symEncryptionAlgorithm.CreateEncryptor(this.currentClientEncryptingKey, this.currentClientInitializationVector))
                            {
                                int inputCount = position - plainHeaderSize;
                                Debug.Assert(inputCount % symEncryptor.InputBlockSize == 0, "Input data is not an even number of encryption blocks.");
                                symEncryptor.TransformBlock(this.sendBuffer, plainHeaderSize, inputCount, this.sendBuffer, plainHeaderSize);
                                symEncryptor.TransformFinalBlock(this.sendBuffer, position, 0);
                            }
                        }

                        // pass buffer to transport
                        await this.SendAsync(this.sendBuffer, 0, position, token).ConfigureAwait(false);
                    }
                    finally
                    {
                        encoder.Dispose();
                    }
                }
            }
            finally
            {
                bodyEncoder.Dispose();
            }
        }
示例#22
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);
        }
示例#23
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);
        }
示例#24
0
 /// <summary>
 /// Encodes the object in binary
 /// </summary>
 public static byte[] EncodeBinary(IEncodeable encodeable, ServiceMessageContext context)
 {
     BinaryEncoder encoder = new BinaryEncoder(context);
     encoder.WriteEncodeable(null, encodeable, null);
     return encoder.CloseAndReturnBuffer();
 }
示例#25
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);
            }
        }
        /// <summary>
        /// Writes the asymmetric security header to the buffer.
        /// </summary>
        protected void WriteAsymmetricMessageHeader(
            BinaryEncoder      encoder,
            uint               messageType,
            uint               secureChannelId,
            string             securityPolicyUri,
            X509Certificate2   senderCertificate, 
            X509Certificate2   receiverCertificate)
        {
            int start = encoder.Position;

            encoder.WriteUInt32(null, messageType);
            encoder.WriteUInt32(null, 0);
            encoder.WriteUInt32(null, secureChannelId);
            encoder.WriteString(null, securityPolicyUri);

            if (SecurityMode != MessageSecurityMode.None)
            {
                encoder.WriteByteString(null, senderCertificate.RawData);
                encoder.WriteByteString(null, GetThumbprintBytes(receiverCertificate.Thumbprint));
            }
            else
            {
                encoder.WriteByteString(null, null);
                encoder.WriteByteString(null, null);
            }
            
            if (encoder.Position - start > SendBufferSize)
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadInternalError, 
                    "AsymmetricSecurityHeader is {0} bytes which is too large for the send buffer size of {1} bytes.",
                    encoder.Position - start,
                    SendBufferSize);
            }
        }
示例#27
0
        /// <summary>
        /// Saves object in an binary stream.
        /// </summary>
        /// <param name="context">The context user.</param>
        /// <param name="encoder">The encoder to write to.</param>
        /// <param name="attributesToSave">The masks indicating what attributes to write.</param>
        public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave)
        {
            base.Save(context, encoder, attributesToSave);

            if ((attributesToSave & AttributesToSave.SuperTypeId) != 0)
            {
                encoder.WriteNodeId(null, m_superTypeId);
            }

            if ((attributesToSave & AttributesToSave.IsAbstract) != 0)
            {
                encoder.WriteBoolean(null, m_isAbstract);
            }
        }
示例#28
0
        private Stream EndProcessRequest(IAsyncResult result)
        {
            MemoryStream ostrm = new MemoryStream();

            try
            {
                if (m_callback != null)
                {
                    IServiceResponse response = m_callback.EndProcessRequest(result);

                    string contentType = WebOperationContext.Current.IncomingRequest.ContentType;

                    if (contentType == "application/octet-stream")
                    {
                        BinaryEncoder encoder = new BinaryEncoder(ostrm, this.m_quotas.MessageContext);
                        encoder.EncodeMessage(response);
                    }
                    else
                    {
                        HttpsTransportChannel.WriteSoapMessage(
                            ostrm,
                            response.GetType().Name,
                            response,
                            this.m_quotas.MessageContext);
                    }

                    ostrm.Position = 0;
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "TCPLISTENER - Unexpected error sending result.");
            }

            return ostrm;
        }
        /// <summary>
        /// Converts a remote value to a local value.
        /// </summary>
        /// <param name="srcValue">The remote value.</param>
        /// <param name="srcType">The data type of the remote value.</param>
        /// <param name="dstType">The data type of the local value.</param>
        /// <returns>The local value.</returns>
        private object ConvertRemoteToLocal(object srcValue, BuiltInType srcType, BuiltInType dstType)
        {
            // check for null.
            if (srcValue == null)
            {
                return(null);
            }

            // 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;

                if (typeInfo.ValueRank != ValueRanks.Scalar)
                {
                    return(TypeInfo.CastArray((Array)srcValue, srcType, BuiltInType.Null, ConvertRemoteToLocal));
                }
            }

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

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

            case BuiltInType.XmlElement:
            {
                dstValue = ((XmlElement)srcValue).OuterXml;
                break;
            }

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

            case BuiltInType.ExpandedNodeId:
            {
                ExpandedNodeId nodeId = GetLocaleExpandedNodeId((ExpandedNodeId)srcValue);
                dstValue = nodeId.ToString();
                break;
            }

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

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

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

            case BuiltInType.ExtensionObject:
            {
                BinaryEncoder encoder = new BinaryEncoder(m_localMessageContext);
                encoder.WriteExtensionObject(null, (ExtensionObject)srcValue);
                dstValue = encoder.CloseAndReturnBuffer();
                break;
            }

            case BuiltInType.Variant:
            {
                dstValue = ((Variant)srcValue).Value;
                break;
            }

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

                break;
            }
            }

            // all done.
            return(dstValue);
        }
        /// <summary>
        /// Saves object in an binary stream.
        /// </summary>
        /// <param name="context">The context user.</param>
        /// <param name="encoder">The encoder to write to.</param>
        /// <param name="attributesToSave">The masks indicating what attributes to write.</param>
        public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave)
        {
            base.Save(context, encoder, attributesToSave);

            if ((attributesToSave & AttributesToSave.EventNotifier) != 0)
            {
                encoder.WriteByte(null, m_eventNotifier);
            }

            if ((attributesToSave & AttributesToSave.ContainsNoLoops) != 0)
            {
                encoder.WriteBoolean(null, m_containsNoLoops);
            }
        }
示例#31
0
        private ReadItem ResolveRecord(RecordSchema writerSchema, RecordSchema readerSchema)
        {
            var      schemaPair = new SchemaPair(writerSchema, readerSchema);
            ReadItem recordReader;

            if (_recordReaders.TryGetValue(schemaPair, out recordReader))
            {
                return(recordReader);
            }

            FieldReader[] fieldReaderArray = null;
            var           recordAccess     = GetRecordAccess(readerSchema);

            recordReader = (r, d) => ReadRecord(r, d, recordAccess, fieldReaderArray);
            _recordReaders.Add(schemaPair, recordReader);

            var readSteps = new List <FieldReader>();

            foreach (Field wf in writerSchema)
            {
                Field rf;
                if (readerSchema.TryGetFieldAlias(wf.Name, out rf))
                {
                    var readItem = ResolveReader(wf.Schema, rf.Schema);
                    if (IsReusable(rf.Schema.Tag))
                    {
                        readSteps.Add((rec, d) => recordAccess.AddField(rec, rf.Name, rf.Pos,
                                                                        readItem(recordAccess.GetField(rec, rf.Name, rf.Pos), d)));
                    }
                    else
                    {
                        readSteps.Add((rec, d) => recordAccess.AddField(rec, rf.Name, rf.Pos,
                                                                        readItem(null, d)));
                    }
                }
                else
                {
                    var skip = GetSkip(wf.Schema);
                    readSteps.Add((rec, d) => skip(d));
                }
            }

            // fill in defaults for any reader fields not in the writer schema
            foreach (Field rf in readerSchema)
            {
                if (writerSchema.Contains(rf.Name))
                {
                    continue;
                }

                var defaultStream  = new MemoryStream();
                var defaultEncoder = new BinaryEncoder(defaultStream);

                defaultStream.Position = 0; // reset for writing
                Resolver.EncodeDefaultValue(defaultEncoder, rf.Schema, rf.DefaultValue);
                defaultStream.Flush();
                var defaultBytes = defaultStream.ToArray();

                var readItem = ResolveReader(rf.Schema, rf.Schema);

                var rfInstance = rf;
                if (IsReusable(rf.Schema.Tag))
                {
                    readSteps.Add((rec, d) => recordAccess.AddField(rec, rfInstance.Name, rfInstance.Pos,
                                                                    readItem(recordAccess.GetField(rec, rfInstance.Name, rfInstance.Pos),
                                                                             new BinaryDecoder(new MemoryStream(defaultBytes)))));
                }
                else
                {
                    readSteps.Add((rec, d) => recordAccess.AddField(rec, rfInstance.Name, rfInstance.Pos,
                                                                    readItem(null, new BinaryDecoder(new MemoryStream(defaultBytes)))));
                }
            }

            fieldReaderArray = readSteps.ToArray();
            return(recordReader);
        }
示例#32
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 );
        }
示例#33
0
 public bool Encode(BinaryEncoder encoder)
 {
     if (!BinaryCodec.Encode(encoder, _itemID))
     {
         return(false);
     }
     if (!BinaryCodec.EncodeUnicodeString(encoder, _itemName))
     {
         return(false);
     }
     if (!BinaryCodec.EncodeUnicodeString(encoder, _itemDesc))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _iconName))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _price))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _option))
     {
         return(false);
     }
     {
         int enumValue = (int)armorType;
         if (!BinaryCodec.Encode(encoder, enumValue))
         {
             return(false);
         }
     }
     if (!BinaryCodec.Encode(encoder, _health))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _energy))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _healthRecover))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _energyRecover))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _physicalArmor))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _elementalArmor))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _physicalAvoid))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _elementalAvoid))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _physicalResistance))
     {
         return(false);
     }
     if (!BinaryCodec.Encode(encoder, _elementalResistance))
     {
         return(false);
     }
     return(true);
 }
        /// <summary>
        /// Saves object in an binary stream.
        /// </summary>
        /// <param name="context">The context user.</param>
        /// <param name="encoder">The encoder to write to.</param>
        /// <param name="attributesToSave">The masks indicating what attributes to write.</param>
        public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave)
        {
            base.Save(context, encoder, attributesToSave);

            if ((attributesToSave & AttributesToSave.InverseName) != 0)
            {
                encoder.WriteLocalizedText(null, m_inverseName);
            }

            if ((attributesToSave & AttributesToSave.Symmetric) != 0)
            {
                encoder.WriteBoolean(null, m_symmetric);
            }
        }
示例#35
0
        public void AssignFields()
        {
            BasicMessageFormatter formatter = new BasicMessageFormatter();
            Message message = new Message();

            // Add field Formatters.
            for (int i = 0; i < _fixedMessageFormatter.Length; i++)
            {
                if (_fixedMessageFormatter[i] != null)
                {
                    formatter.FieldFormatters.Add(_fixedMessageFormatter[i]);
                }
            }

            // Replace field formatter for field number 6, to perform
            // a complete AssignFields test.
            formatter.FieldFormatters.Add(new BinaryFieldFormatter(6,
                                                                   new FixedLengthManager(20), BinaryEncoder.GetInstance()));

            // Perform test for invalid parameters.
            try {
                formatter.AssignFields(null, null);
                Assert.Fail();
            } catch (ArgumentNullException e) {
                Assert.IsTrue(e.ParamName == "message");
            }

            try {
                formatter.AssignFields(message, null);
                Assert.Fail();
            } catch (ArgumentNullException e) {
                Assert.IsTrue(e.ParamName == "fieldsContainer");
            }

            // Perform a simple test.
            SimpleTransaction simpleTransaction = new SimpleTransaction();

            simpleTransaction.Terminal       = 106;
            simpleTransaction.CustomerName   = "John Doe";
            simpleTransaction.AdditionalData = "Some data";
            formatter.AssignFields(message, simpleTransaction);

            Assert.IsFalse(simpleTransaction.InvalidPropertyHasBeenTaken);
            Assert.IsFalse(message.Fields.Contains(1));
            Assert.IsFalse(message.Fields.Contains(2));
            Assert.IsTrue(message.Fields.Contains(5));
            Assert.IsTrue(simpleTransaction.Terminal.ToString().Equals(
                              message[5].ToString()));
            Assert.IsTrue(message.Fields.Contains(6));
            Assert.IsTrue(simpleTransaction.CustomerName.Equals(
                              message[6].ToString()));
            Assert.IsTrue(message.Fields.Contains(30));
            Assert.IsTrue(simpleTransaction.AdditionalData.Equals(
                              message[30].ToString()));
        }
示例#36
0
        /// <summary>
        /// Sends a Hello message.
        /// </summary>
        private void SendHelloMessage(WriteOperation operation)
        {            
            // Utils.Trace("Channel {0}: SendHelloMessage()", ChannelId);

            byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "SendHelloMessage");
            
            try
            {
                MemoryStream ostrm = new MemoryStream(buffer, 0, SendBufferSize);
                BinaryEncoder encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);
                
                encoder.WriteUInt32(null, TcpMessageType.Hello);
                encoder.WriteUInt32(null, 0);
                encoder.WriteUInt32(null, 0); // ProtocolVersion
                encoder.WriteUInt32(null, (uint)ReceiveBufferSize);
                encoder.WriteUInt32(null, (uint)SendBufferSize);
                encoder.WriteUInt32(null, (uint)MaxResponseMessageSize);
                encoder.WriteUInt32(null, (uint)MaxResponseChunkCount);
                            
                byte[] endpointUrl = new UTF8Encoding().GetBytes(m_url.ToString());

                if (endpointUrl.Length > TcpMessageLimits.MaxEndpointUrlLength)
                {
                    byte[] truncatedUrl = new byte[TcpMessageLimits.MaxEndpointUrlLength];
                    Array.Copy(endpointUrl, truncatedUrl, TcpMessageLimits.MaxEndpointUrlLength);
                    endpointUrl = truncatedUrl;
                }

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

                BeginWriteMessage(new ArraySegment<byte>(buffer, 0, size), Int32.MaxValue, operation);
                buffer = null;
            }
            finally
            {
                if (buffer != null)
                {
                    BufferManager.ReturnBuffer(buffer, "SendHelloMessage");
                }
            }
        }
示例#37
0
        public void RetrieveFields()
        {
            BasicMessageFormatter formatter = new BasicMessageFormatter();
            Message message = new Message();

            // Add field Formatters.
            for (int i = 0; i < _fixedMessageFormatter.Length; i++)
            {
                if (_fixedMessageFormatter[i] != null)
                {
                    formatter.FieldFormatters.Add(_fixedMessageFormatter[i]);
                }
            }

            // Replace field formatter for field number 6, to perform
            // a complete AssignFields test.
            formatter.FieldFormatters.Add(new BinaryFieldFormatter(6,
                                                                   new FixedLengthManager(20), BinaryEncoder.GetInstance()));

            // Perform test for invalid parameters.
            try {
                formatter.RetrieveFields(null, null);
                Assert.Fail();
            } catch (ArgumentNullException e) {
                Assert.IsTrue(e.ParamName == "message");
            }

            try {
                formatter.RetrieveFields(message, null);
                Assert.Fail();
            } catch (ArgumentNullException e) {
                Assert.IsTrue(e.ParamName == "fieldsContainer");
            }

            // Perform a simple test.
            message.Fields.Add(1, "01");
            message.Fields.Add(2, "02");
            message.Fields.Add(5, "1385");
            message.Fields.Add(6, "John Doe");
            message.Fields.Add(30, "Random data");
            SimpleTransaction simpleTransaction = new SimpleTransaction();

            formatter.RetrieveFields(message, simpleTransaction);

            Assert.IsFalse(simpleTransaction.InvalidPropertyHasBeenAssigned);
            Assert.IsNotNull(simpleTransaction.RetrieveBranch());
            Assert.IsTrue(simpleTransaction.RetrieveBranch().Equals("01"));
            Assert.IsTrue(simpleTransaction.Terminal == 1385);
            Assert.IsTrue(simpleTransaction.AdditionalData.Equals("Random data"));
        }
        /// <summary>
        /// Saves object in an binary stream.
        /// </summary>
        /// <param name="context">The context user.</param>
        /// <param name="encoder">The encoder to write to.</param>
        /// <param name="attributesToSave">The masks indicating what attributes to write.</param>
        public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave)
        {
            base.Save(context, encoder, attributesToSave);

            if ((attributesToSave & AttributesToSave.ReferenceTypeId) != 0)
            {
                encoder.WriteNodeId(null, m_referenceTypeId);
            }

            if ((attributesToSave & AttributesToSave.TypeDefinitionId) != 0)
            {
                encoder.WriteNodeId(null, m_typeDefinitionId);
            }

            if ((attributesToSave & AttributesToSave.ModellingRuleId) != 0)
            {
                encoder.WriteNodeId(null, m_modellingRuleId);
            }

            if ((attributesToSave & AttributesToSave.NumericId) != 0)
            {
                encoder.WriteUInt32(null, m_numericId);
            }
        }
        /// <summary>
        /// Perform DataSetMessageModel to batch NetworkMessageModel using binary encoding
        /// </summary>
        /// <param name="messages"></param>
        /// <param name="maxMessageSize"></param>
        /// <returns></returns>
        private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp(
            IEnumerable <DataSetMessageModel> messages, int maxMessageSize)
        {
            // by design all messages are generated in the same session context,
            // therefore it is safe to get the first message's context
            var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null)
                                  ?.ServiceMessageContext;
            var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Uadp, encodingContext);

            if (notifications.Count() == 0)
            {
                yield break;
            }
            var current     = notifications.GetEnumerator();
            var processing  = current.MoveNext();
            var messageSize = 4; // array length size
            var chunk       = new Collection <MonitoredItemMessage>();

            while (processing)
            {
                var notification     = current.Current;
                var messageCompleted = false;
                if (notification != null)
                {
                    var helperEncoder = new BinaryEncoder(encodingContext);
                    helperEncoder.WriteEncodeable(null, notification);
                    var notificationSize = helperEncoder.CloseAndReturnBuffer().Length;
                    if (notificationSize > maxMessageSize)
                    {
                        // Message too large, drop it.
                        NotificationsDroppedCount++;
                        _logger.Warning("Message too large, dropped {notificationsPerMessage} values");
                        processing = current.MoveNext();
                    }
                    else
                    {
                        messageCompleted = maxMessageSize < (messageSize + notificationSize);
                        if (!messageCompleted)
                        {
                            chunk.Add(notification);
                            NotificationsProcessedCount++;
                            processing   = current.MoveNext();
                            messageSize += notificationSize;
                        }
                    }
                }
                if (!processing || messageCompleted)
                {
                    var encoder = new BinaryEncoder(encodingContext);
                    encoder.WriteBoolean(null, true); // is Batch
                    encoder.WriteEncodeableArray(null, chunk);
                    var encoded = new NetworkMessageModel {
                        Body          = encoder.CloseAndReturnBuffer(),
                        Timestamp     = DateTime.UtcNow,
                        ContentType   = ContentMimeType.UaBinary,
                        MessageSchema = MessageSchemaTypes.MonitoredItemMessageBinary
                    };
                    AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) /
                                     (MessagesProcessedCount + 1);
                    AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount +
                                                  chunk.Count) / (MessagesProcessedCount + 1);
                    MessagesProcessedCount++;
                    chunk.Clear();
                    messageSize = 4;
                    yield return(encoded);
                }
            }
        }
        /// <summary>
        /// Sends an error message over the socket.
        /// </summary>
        protected void SendErrorMessage(ServiceResult error)
        {
            // Utils.Trace("Channel {0}: SendErrorMessage()", ChannelId);

            byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "SendErrorMessage");

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

                encoder.WriteUInt32(null, TcpMessageType.Error);
                encoder.WriteUInt32(null, 0);
                
                WriteErrorMessageBody(encoder, error);
                                
                int size = encoder.Close();
                UpdateMessageSize(buffer, 0, size);
                
                BeginWriteMessage(new ArraySegment<byte>(buffer, 0, size), Int32.MaxValue, null);
                buffer = null;
            }
            finally 
            {
                if (buffer != null)
                {
                    BufferManager.ReturnBuffer(buffer, "SendErrorMessage");
                }
            }
        }
示例#41
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);
            }
        }
示例#42
0
        /// <summary>
        /// Saves object in an binary stream.
        /// </summary>
        /// <param name="context">The context user.</param>
        /// <param name="encoder">The encoder to write to.</param>
        /// <param name="attributesToSave">The masks indicating what attributes to write.</param>
        public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave)
        {
            base.Save(context, encoder, attributesToSave);

            if ((attributesToSave & AttributesToSave.Executable) != 0)
            {
                encoder.WriteBoolean(null, m_executable);
            }

            if ((attributesToSave & AttributesToSave.UserExecutable) != 0)
            {
                encoder.WriteBoolean(null, m_userExecutable);
            }
        }
        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();
            }
        }