示例#1
0
        public XdrStream(Stream innerStream, Charset charset, bool compression, bool ownsStream)
            : base()
        {
            _innerStream = innerStream;
            _charset     = charset;
            _compression = compression;
            _ownsStream  = ownsStream;

            _position     = 0;
            _outputBuffer = new List <byte>(PreferredBufferSize);
            _inputBuffer  = new ReadBuffer(PreferredBufferSize);
            if (_compression)
            {
                _deflate           = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Compress);
                _inflate           = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Decompress);
                _compressionBuffer = new byte[1024 * 1024];
            }

            ResetOperation();
        }
示例#2
0
        public XdrStream(Stream innerStream, Charset charset, bool compression, bool ownsStream)
            : base()
        {
            _innerStream = innerStream;
            _charset     = charset;
            _compression = compression;
            _ownsStream  = ownsStream;

            _position     = 0;
            _outputBuffer = new List <byte>(PreferredBufferSize);
            _inputBuffer  = new Queue <byte>(PreferredBufferSize);
            _readBuffer   = new byte[PreferredBufferSize];
            _smallBuffer  = new byte[8];
            if (_compression)
            {
                _deflate           = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Compress);
                _inflate           = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Decompress);
                _compressionBuffer = new byte[CompressionBufferSize];
            }

            _ioFailed = false;
            ResetOperation();
        }
示例#3
0
 public void StartCompression()
 {
     _compressionBuffer = new byte[PreferredBufferSize];
     _compressor        = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Compress);
     _decompressor      = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Decompress);
 }
示例#4
0
 public void StartCompression(Ionic.Zlib.ZlibCodec compressor, Ionic.Zlib.ZlibCodec decompressor)
 {
     _compressionBuffer = new byte[CompressionBufferSize];
     _compressor        = compressor;
     _decompressor      = decompressor;
 }
示例#5
0
        public void Identify(string database)
        {
            try
            {
                Xdr.Write(IscCodes.op_connect);
                Xdr.Write(IscCodes.op_attach);
                Xdr.Write(IscCodes.CONNECT_VERSION3);
                Xdr.Write(IscCodes.GenericAchitectureClient);

                Xdr.Write(database);

                var protocols = ProtocolsSupported.Get(_compression);
                Xdr.Write(protocols.Count());

#warning These out params are ugly, refactor
                var userIdentificationData = UserIdentificationData(out var srp, out var sspi);
                using (sspi)
                {
                    Xdr.WriteBuffer(userIdentificationData);

                    var priority = 0;
                    foreach (var protocol in protocols)
                    {
                        Xdr.Write(protocol.Version);
                        Xdr.Write(IscCodes.GenericAchitectureClient);
                        Xdr.Write(protocol.MinPType);
                        Xdr.Write(protocol.MaxPType);
                        Xdr.Write(priority);

                        priority++;
                    }

                    Xdr.Flush();

                    var operation = Xdr.ReadOperation();
                    if (operation == IscCodes.op_accept || operation == IscCodes.op_cond_accept || operation == IscCodes.op_accept_data)
                    {
                        var wireCryptInitialized = false;

                        ProtocolVersion      = Xdr.ReadInt32();
                        ProtocolArchitecture = Xdr.ReadInt32();
                        ProtocolMinimunType  = Xdr.ReadInt32();

                        if (ProtocolVersion < 0)
                        {
                            ProtocolVersion = (ushort)(ProtocolVersion & IscCodes.FB_PROTOCOL_MASK) | IscCodes.FB_PROTOCOL_FLAG;
                        }

                        if (_compression && !((ProtocolMinimunType & IscCodes.pflag_compress) != 0))
                        {
                            _compression = false;
                        }

                        if (operation == IscCodes.op_cond_accept || operation == IscCodes.op_accept_data)
                        {
                            var serverData       = Xdr.ReadBuffer();
                            var acceptPluginName = Xdr.ReadString();
                            var isAuthenticated  = Xdr.ReadBoolean();
                            var serverKeys       = Xdr.ReadBuffer();
                            if (!isAuthenticated)
                            {
                                switch (acceptPluginName)
                                {
                                case SrpClient.PluginName:
                                    AuthData = Encoding.ASCII.GetBytes(srp.ClientProof(NormalizeLogin(_userID), Password, serverData).ToHexString());
                                    break;

                                case SspiHelper.PluginName:
                                    AuthData = sspi.GetClientSecurity(serverData);
                                    break;

                                default:
                                    throw new ArgumentOutOfRangeException(nameof(acceptPluginName), $"{nameof(acceptPluginName)}={acceptPluginName}");
                                }
                            }

                            if (_compression)
                            {
                                var compressor   = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Compress);
                                var decompressor = new Ionic.Zlib.ZlibCodec(Ionic.Zlib.CompressionMode.Decompress);
                                // after reading before writing
                                _firebirdNetworkStream.StartCompression(compressor, decompressor);
                            }

                            if (operation == IscCodes.op_cond_accept)
                            {
                                Xdr.Write(IscCodes.op_cont_auth);
                                Xdr.WriteBuffer(AuthData);
                                Xdr.Write(acceptPluginName);                                 // like CNCT_plugin_name
                                Xdr.Write(acceptPluginName);                                 // like CNCT_plugin_list
                                Xdr.WriteBuffer(serverKeys);
                                Xdr.Flush();
                                var response = (GenericResponse)ProcessOperation(Xdr.ReadOperation(), Xdr);
                                serverKeys      = response.Data;
                                isAuthenticated = true;

                                if (_wireCrypt != WireCryptOption.Disabled)
                                {
                                    Xdr.Write(IscCodes.op_crypt);
                                    Xdr.Write(FirebirdNetworkStream.EncryptionName);
                                    Xdr.Write(SrpClient.SessionKeyName);
                                    Xdr.Flush();

                                    var encryptor = CreateCipher(srp.SessionKey);
                                    var decryptor = CreateCipher(srp.SessionKey);
                                    // after writing before reading
                                    _firebirdNetworkStream.StartEncryption(encryptor, decryptor);

                                    ProcessOperation(Xdr.ReadOperation(), Xdr);

                                    wireCryptInitialized = true;
                                }
                            }
                        }

                        // fbclient does not care about wirecrypt in older protocols either
                        if (ProtocolVersion == IscCodes.PROTOCOL_VERSION13 && _wireCrypt == WireCryptOption.Required && !wireCryptInitialized)
                        {
                            throw IscException.ForErrorCode(IscCodes.isc_wirecrypt_incompatible);
                        }
                    }
                    else if (operation == IscCodes.op_response)
                    {
                        var response = (GenericResponse)ProcessOperation(operation, Xdr);
                        throw response.Exception;
                    }
                    else
                    {
                        try
                        {
                            Disconnect();
                        }
                        catch
                        { }
                        finally
                        {
                            throw IscException.ForErrorCode(IscCodes.isc_connect_reject);
                        }
                    }
                }
            }
            catch (IOException ex)
            {
                throw IscException.ForErrorCode(IscCodes.isc_network_error, ex);
            }
        }