예제 #1
0
        public bool Connect(IPAddress serverAddress, SMBTransportType transport, bool forceExtendedSecurity, string serverName = null)
        {
            m_transport = transport;
            if (!m_isConnected)
            {
                m_forceExtendedSecurity = forceExtendedSecurity;
                int port;
                port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;

                if (!ConnectSocket(serverAddress, port))
                {
                    return(false);
                }

                if (transport == SMBTransportType.NetBiosOverTCP)
                {
                    SessionRequestPacket sessionRequest = new SessionRequestPacket();
                    sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName(serverName ?? "*SMBSERVER", NetBiosSuffix.FileServiceService);
                    sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                    TrySendPacket(m_clientSocket, sessionRequest);

                    SessionPacket sessionResponsePacket = WaitForSessionResponsePacket();
                    if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                    {
                        m_clientSocket.Disconnect(false);
                        if (!ConnectSocket(serverAddress, port))
                        {
                            return(false);
                        }

                        NameServiceClient nameServiceClient = new NameServiceClient(serverAddress);
                        serverName = nameServiceClient.GetServerName();
                        if (serverName == null)
                        {
                            return(false);
                        }

                        sessionRequest.CalledName = serverName;
                        TrySendPacket(m_clientSocket, sessionRequest);

                        sessionResponsePacket = WaitForSessionResponsePacket();
                        if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                        {
                            return(false);
                        }
                    }
                }

                bool supportsDialect = NegotiateDialect(m_forceExtendedSecurity);
                if (!supportsDialect)
                {
                    m_clientSocket.Close();
                }
                else
                {
                    m_isConnected = true;
                }
            }
            return(m_isConnected);
        }
예제 #2
0
        private bool NegotiateNTLanManagerDialect()
        {
            if (m_transport == SMBTransportType.NetBiosOverTCP)
            {
                SessionRequestPacket sessionRequest = new SessionRequestPacket();
                sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);;
                sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                TrySendPacket(m_clientSocket, sessionRequest);
            }
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);
            TrySendMessage(m_clientSocket, request);
            SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE);

            if (reply == null)
            {
                return(false);
            }

            if (reply.Commands[0] is NegotiateResponse)
            {
                NegotiateResponse response = (NegotiateResponse)reply.Commands[0];
                return(true);
            }
            else if (reply.Commands[0] is NegotiateResponseExtended)
            {
                NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0];
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        private bool NegotiateDialect(bool forceExtendedSecurity)
        {
            if (m_transport == SMBTransportType.NetBiosOverTCP)
            {
                SessionRequestPacket sessionRequest = new SessionRequestPacket();
                sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);;
                sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                TrySendPacket(m_clientSocket, sessionRequest);
            }
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);

            TrySendMessage(request);
            SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE);

            if (reply == null)
            {
                return(false);
            }

            if (reply.Commands[0] is NegotiateResponse && !forceExtendedSecurity)
            {
                NegotiateResponse response = (NegotiateResponse)reply.Commands[0];
                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_serverChallenge      = response.Challenge;
                return(ntSMB && rpc && ntStatusCode);
            }
            else if (reply.Commands[0] is NegotiateResponseExtended)
            {
                NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0];
                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_securityBlob         = response.SecurityBlob;
                return(ntSMB && rpc && ntStatusCode);
            }
            else
            {
                return(false);
            }
        }
예제 #4
0
        public void Test2()
        {
            byte[] buffer = { 0x20, 0x46, 0x47, 0x45, 0x4e, 0x44, 0x4a, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x41, 0x41, 0x00 };
            int    offset = 0;
            string name   = NetBiosUtils.DecodeName(buffer, ref offset);

            byte[] encodedName = NetBiosUtils.EncodeName(name, string.Empty);
            Assert.True(ByteUtils.AreByteArraysEqual(buffer, encodedName));
        }
예제 #5
0
        public static void Test2()
        {
            byte[] buffer = new byte[] { 0x20, 0x46, 0x47, 0x45, 0x4e, 0x44, 0x4a, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x41, 0x41, 0x00 };
            int    offset = 0;
            string name   = NetBiosUtils.DecodeName(buffer, ref offset);

            byte[] encodedName = NetBiosUtils.EncodeName(name, String.Empty);
            bool   success     = ByteUtils.AreByteArraysEqual(buffer, encodedName);
        }
예제 #6
0
        public string?GetServerName()
        {
            NodeStatusRequest request = new NodeStatusRequest
            {
                Header   = { QDCount = 1 },
                Question =
                {
                    Name = "*".PadRight(16, '\0')
                }
            };
            NodeStatusResponse response = SendNodeStatusRequest(request);

            return((from entry in response.Names let suffix = NetBiosUtils.GetSuffixFromMSNetBiosName(entry.Key) where suffix == NetBiosSuffix.FileServiceService select entry.Key).FirstOrDefault());
        }
예제 #7
0
        public string GetServerName()
        {
            NodeStatusRequest request = new NodeStatusRequest();

            request.Header.QDCount = 1;
            request.Question.Name  = "*".PadRight(16, '\0');
            NodeStatusResponse response = SendNodeStatusRequest(request);

            foreach (KeyValuePair <string, NameFlags> entry in response.Names)
            {
                NetBiosSuffix suffix = NetBiosUtils.GetSuffixFromMSNetBiosName(entry.Key);
                if (suffix == NetBiosSuffix.FileServiceService)
                {
                    return(entry.Key);
                }
            }

            return(null);
        }
예제 #8
0
        private void ReceiveCallback(IAsyncResult result)
        {
            if (!m_listening)
            {
                return;
            }

            IPEndPoint remoteEP = null;

            byte[] buffer;
            try
            {
                buffer = m_client.EndReceive(result, ref remoteEP);
            }
            catch (ObjectDisposedException)
            {
                return;
            }
            catch (SocketException)
            {
                return;
            }

            // Process buffer
            if (buffer.Length > NameServicePacketHeader.Length)
            {
                NameServicePacketHeader header = new NameServicePacketHeader(buffer, 0);
                if (header.OpCode == NameServiceOperation.QueryRequest)
                {
                    NameQueryRequest request = null;
                    try
                    {
                        request = new NameQueryRequest(buffer, 0);
                    }
                    catch
                    {
                    }
                    if (request != null)
                    {
                        if (request.Question.Type == NameRecordType.NB)
                        {
                            string        name   = NetBiosUtils.GetNameFromMSNetBiosName(request.Question.Name);
                            NetBiosSuffix suffix = (NetBiosSuffix)request.Question.Name[15];

                            bool nameMatch = String.Equals(name, Environment.MachineName, StringComparison.OrdinalIgnoreCase);

                            if (nameMatch && ((suffix == NetBiosSuffix.WorkstationService) || (suffix == NetBiosSuffix.FileServiceService)))
                            {
                                PositiveNameQueryResponse response = new PositiveNameQueryResponse();
                                response.Header.TransactionID = request.Header.TransactionID;
                                response.Resource.Name        = request.Question.Name;
                                NameFlags nameFlags = new NameFlags();
                                response.Addresses.Add(m_serverAddress.GetAddressBytes(), nameFlags);
                                byte[] responseBytes = response.GetBytes();
                                m_client.Send(responseBytes, responseBytes.Length, remoteEP);
                            }
                        }
                        else // NBStat
                        {
                            NodeStatusResponse response = new NodeStatusResponse();
                            response.Header.TransactionID = request.Header.TransactionID;
                            response.Resource.Name        = request.Question.Name;
                            NameFlags nameFlags  = new NameFlags();
                            string    name1      = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                            string    name2      = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.FileServiceService);
                            NameFlags nameFlags3 = new NameFlags();
                            nameFlags3.WorkGroup = true;
                            string name3 = NetBiosUtils.GetMSNetBiosName(WorkgroupName, NetBiosSuffix.WorkstationService);
                            response.Names.Add(name1, nameFlags);
                            response.Names.Add(name2, nameFlags);
                            response.Names.Add(name3, nameFlags3);
                            byte[] responseBytes = response.GetBytes();
                            try
                            {
                                m_client.Send(responseBytes, responseBytes.Length, remoteEP);
                            }
                            catch (ObjectDisposedException)
                            {
                            }
                        }
                    }
                }
            }

            try
            {
                m_client.BeginReceive(ReceiveCallback, null);
            }
            catch (ObjectDisposedException)
            {
            }
            catch (SocketException)
            {
            }
        }
예제 #9
0
        public bool Connect(IPAddress serverAddress, SMBTransportType transport)
        {
            // Sometimes underline socket is disconnected, but m_isConnected flag is still true.
            // This cause the caller try to reuse the client and fail on all calls.
            if (m_clientSocket != null && !m_clientSocket.Connected)
            {
                // Since reconnect doesn't work for now, return false directly make response faster
                return(false);
            }

            m_transport = transport;
            if (!m_isConnected)
            {
                int port;
                if (transport == SMBTransportType.NetBiosOverTCP)
                {
                    port = NetBiosOverTCPPort;
                }
                else
                {
                    port = DirectTCPPort;
                }

                if (!ConnectSocket(serverAddress, port))
                {
                    return(false);
                }

                if (transport == SMBTransportType.NetBiosOverTCP)
                {
                    SessionRequestPacket sessionRequest = new SessionRequestPacket();
                    sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);
                    sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                    TrySendPacket(m_clientSocket, sessionRequest);

                    SessionPacket sessionResponsePacket = WaitForSessionResponsePacket();
                    if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                    {
                        m_clientSocket.Disconnect(false);
                        if (!ConnectSocket(serverAddress, port))
                        {
                            return(false);
                        }

                        NameServiceClient nameServiceClient = new NameServiceClient(serverAddress);
                        string            serverName        = nameServiceClient.GetServerName();
                        if (serverName == null)
                        {
                            return(false);
                        }

                        sessionRequest.CalledName = serverName;
                        TrySendPacket(m_clientSocket, sessionRequest);

                        sessionResponsePacket = WaitForSessionResponsePacket();
                        if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                        {
                            return(false);
                        }
                    }
                }

                bool supportsDialect = NegotiateDialect();
                if (!supportsDialect)
                {
                    m_clientSocket.Close();
                }
                else
                {
                    m_isConnected = true;
                }
            }
            return(m_isConnected);
        }
예제 #10
0
        private bool Connect(IPAddress serverAddress, SMBTransportType transport, bool forceExtendedSecurity)
        {
            m_transport = transport;
            if (IsConnected)
            {
                return(true);
            }

            m_forceExtendedSecurity = forceExtendedSecurity;
            int port = transport == SMBTransportType.NetBiosOverTcp ? NetBiosOverTCPPort : DirectTCPPort;

            ConnectSocket(serverAddress, port);

            if (transport == SMBTransportType.NetBiosOverTcp)
            {
                SessionRequestPacket sessionRequest = new SessionRequestPacket
                {
                    CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService),
                    CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService)
                };
                SendPacket(m_clientSocket !, sessionRequest);

                SessionPacket?sessionResponsePacket = WaitForSessionResponsePacket();
                if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                {
                    m_clientSocket?.Shutdown(SocketShutdown.Both);
                    m_clientSocket?.Dispose();
                    m_clientSocket = null;

                    ConnectSocket(serverAddress, port);

                    NameServiceClient nameServiceClient = new NameServiceClient(serverAddress);
                    string?           serverName        = nameServiceClient.GetServerName();
                    if (serverName == null)
                    {
                        return(false);
                    }

                    sessionRequest.CalledName = serverName;
                    SendPacket(m_clientSocket, sessionRequest);

                    sessionResponsePacket = WaitForSessionResponsePacket();
                    if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                    {
                        return(false);
                    }
                }
            }

            bool supportsDialect = NegotiateDialect(m_forceExtendedSecurity);

            if (!supportsDialect)
            {
                m_clientSocket?.Shutdown(SocketShutdown.Both);
                m_clientSocket?.Dispose();
                m_clientSocket = null;
            }
            else
            {
                m_isConnected = true;
            }
            return(m_isConnected);
        }
예제 #11
0
        public async Task <bool> ConnectAsync(IPAddress serverAddress, SMBTransportType transport, CancellationToken cancellationToken)
        {
            m_transport = transport;
            if (!m_isConnected)
            {
                int port;
                if (transport == SMBTransportType.NetBiosOverTCP)
                {
                    port = NetBiosOverTCPPort;
                }
                else
                {
                    port = DirectTCPPort;
                }

                if (!ConnectSocket(serverAddress, port))
                {
                    return(false);
                }

                if (transport == SMBTransportType.NetBiosOverTCP)
                {
                    SessionRequestPacket sessionRequest = new SessionRequestPacket();
                    sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);
                    sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                    await TrySendPacketAsync(m_clientSocket, sessionRequest, cancellationToken);

                    SessionPacket sessionResponsePacket = WaitForSessionResponsePacket();
                    if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                    {
                        m_clientSocket.Disconnect(false);
                        if (!ConnectSocket(serverAddress, port))
                        {
                            return(false);
                        }

                        NameServiceClient nameServiceClient = new NameServiceClient(serverAddress);
                        string            serverName        = nameServiceClient.GetServerName();
                        if (serverName == null)
                        {
                            return(false);
                        }

                        sessionRequest.CalledName = serverName;
                        await TrySendPacketAsync(m_clientSocket, sessionRequest, cancellationToken);

                        sessionResponsePacket = WaitForSessionResponsePacket();
                        if (!(sessionResponsePacket is PositiveSessionResponsePacket))
                        {
                            return(false);
                        }
                    }
                }

                bool supportsDialect = await NegotiateDialectAsync(cancellationToken);

                if (!supportsDialect)
                {
                    m_clientSocket.Close();
                }
                else
                {
                    m_isConnected = true;
                }
            }
            return(m_isConnected);
        }