Beispiel #1
0
        private byte[] UserIdentificationData(out SrpClient srp, out SspiHelper sspi)
        {
            srp  = null;
            sspi = null;

            using (var result = new MemoryStream())
            {
                var userString = Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER") ?? string.Empty;
                var user       = Encoding.UTF8.GetBytes(userString);
                result.WriteByte(IscCodes.CNCT_user);
                result.WriteByte((byte)user.Length);
                result.Write(user, 0, user.Length);

                var host = Encoding.UTF8.GetBytes(Dns.GetHostName());
                result.WriteByte(IscCodes.CNCT_host);
                result.WriteByte((byte)host.Length);
                result.Write(host, 0, host.Length);

                result.WriteByte(IscCodes.CNCT_user_verification);
                result.WriteByte(0);

                if (!string.IsNullOrEmpty(_userID))
                {
                    srp = new SrpClient();

                    var login = Encoding.UTF8.GetBytes(_userID);
                    result.WriteByte(IscCodes.CNCT_login);
                    result.WriteByte((byte)login.Length);
                    result.Write(login, 0, login.Length);

                    var pluginName = Encoding.ASCII.GetBytes(SrpClient.PluginName);
                    result.WriteByte(IscCodes.CNCT_plugin_name);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);
                    result.WriteByte(IscCodes.CNCT_plugin_list);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);

                    var specificData = Encoding.ASCII.GetBytes(srp.PublicKeyHex);
                    WriteMultiPartHelper(result, IscCodes.CNCT_specific_data, specificData);

                    result.WriteByte(IscCodes.CNCT_client_crypt);
                    result.WriteByte(4);
                    result.Write(TypeEncoder.EncodeInt32(WireCryptOptionValue(_wireCrypt)), 0, 4);
                }
                else
                {
                    sspi = new SspiHelper();

                    var pluginName = Encoding.ASCII.GetBytes(SspiHelper.PluginName);
                    result.WriteByte(IscCodes.CNCT_plugin_name);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);
                    result.WriteByte(IscCodes.CNCT_plugin_list);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);

                    var specificData = sspi.InitializeClientSecurity();
                    WriteMultiPartHelper(result, IscCodes.CNCT_specific_data, specificData);

                    result.WriteByte(IscCodes.CNCT_client_crypt);
                    result.WriteByte(4);
                    result.Write(TypeEncoder.EncodeInt32(IscCodes.WIRE_CRYPT_DISABLED), 0, 4);
                }

                return(result.ToArray());
            }
        }
        public void Identify(string database)
        {
            using (var xdrStream = CreateXdrStream(false))
            {
                try
                {
                    xdrStream.Write(IscCodes.op_connect);
                    xdrStream.Write(IscCodes.op_attach);
                    xdrStream.Write(IscCodes.CONNECT_VERSION3);
                    xdrStream.Write(IscCodes.GenericAchitectureClient);

                    xdrStream.Write(database);

                    var protocols = ProtocolsSupported.Get(_compression);
                    xdrStream.Write(protocols.Count());
                    xdrStream.WriteBuffer(UserIdentificationData());

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

                        priority++;
                    }

                    xdrStream.Flush();

                    var operation = xdrStream.ReadOperation();
                    if (operation == IscCodes.op_accept || operation == IscCodes.op_cond_accept || operation == IscCodes.op_accept_data)
                    {
                        _protocolVersion      = xdrStream.ReadInt32();
                        _protocolArchitecture = xdrStream.ReadInt32();
                        _protocolMinimunType  = xdrStream.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 data             = xdrStream.ReadBuffer();
                            var acceptPluginName = xdrStream.ReadString();
                            var isAuthenticated  = xdrStream.ReadBoolean();
                            var keys             = xdrStream.ReadString();
                            if (!isAuthenticated)
                            {
                                switch (acceptPluginName)
                                {
                                case SrpClient.PluginName:
                                    _authData = Encoding.ASCII.GetBytes(_srp.ClientProof(_userID, _password, data).ToHexString());
                                    break;

                                case SspiHelper.PluginName:
                                    _authData = _sspi.GetClientSecurity(data);
                                    break;

                                default:
                                    throw new ArgumentOutOfRangeException();
                                }
                            }
                        }
                    }
                    else if (operation == IscCodes.op_response)
                    {
                        var response = (GenericResponse)ProcessOperation(operation, xdrStream);
                        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);
                }
                finally
                {
                    // UserIdentificationData might allocate these
                    _srp = null;
                    _sspi?.Dispose();
                    _sspi = null;
                }
            }
        }
        private byte[] UserIdentificationData()
        {
            using (var result = new MemoryStream())
            {
                if (!string.IsNullOrEmpty(_userID))
                {
                    _srp = new SrpClient();

                    var login = Encoding.UTF8.GetBytes(_userID);
                    result.WriteByte(IscCodes.CNCT_login);
                    result.WriteByte((byte)login.Length);
                    result.Write(login, 0, login.Length);

                    var pluginName = Encoding.ASCII.GetBytes(SrpClient.PluginName);
                    result.WriteByte(IscCodes.CNCT_plugin_name);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);
                    result.WriteByte(IscCodes.CNCT_plugin_list);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);

                    var specificData = Encoding.ASCII.GetBytes(_srp.PublicKeyHex);
                    WriteMultiPartHelper(result, IscCodes.CNCT_specific_data, specificData);
                }
                else
                {
                    _sspi = new SspiHelper();

                    var pluginName = Encoding.ASCII.GetBytes(SspiHelper.PluginName);
                    result.WriteByte(IscCodes.CNCT_plugin_name);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);
                    result.WriteByte(IscCodes.CNCT_plugin_list);
                    result.WriteByte((byte)pluginName.Length);
                    result.Write(pluginName, 0, pluginName.Length);

                    var specificData = _sspi.InitializeClientSecurity();
                    WriteMultiPartHelper(result, IscCodes.CNCT_specific_data, specificData);
                }

                var userString = Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER") ?? string.Empty;
                var user       = Encoding.UTF8.GetBytes(userString);
                result.WriteByte(IscCodes.CNCT_user);
                result.WriteByte((byte)user.Length);
                result.Write(user, 0, user.Length);

                var host = Encoding.UTF8.GetBytes(Dns.GetHostName());
                result.WriteByte(IscCodes.CNCT_host);
                result.WriteByte((byte)host.Length);
                result.Write(host, 0, host.Length);

                result.WriteByte(IscCodes.CNCT_client_crypt);
                result.WriteByte(4);
                result.Write(new byte[] { 0, 0, 0, 0 }, 0, 4);

                result.WriteByte(IscCodes.CNCT_user_verification);
                result.WriteByte(0);

                return(result.ToArray());
            }
        }