Ejemplo n.º 1
0
        /// <summary>
        /// update the connection isSigningActive, combination of the client's MessageSigningPolicy and the 
        /// connection's ServerSigningState. 
        /// </summary>
        /// <param name = "connection">the target connection to update </param>
        /// <returns>the combination result </returns>
        internal void UpdateSigningActive(SmbClientConnection connection)
        {
            if (connection == null)
            {
                return;
            }

            switch (smbClient.Capability.ClientSignState)
            {
                case SignState.REQUIRED:
                    MergeClientRequiredState(connection);
                    break;
                case SignState.ENABLED:
                    MergeClientEnableState(connection);
                    break;
                case SignState.DISABLED_UNLESS_REQUIRED:
                    MergeClientDisalbedUnlessRequiredState(connection);
                    break;
                case SignState.DISABLED:
                    MergeClientDisabledState(connection);
                    break;

                default:
                    break;
            }
        }
 /// <summary>
 /// Deep copy constructor. if need to copy the connection instance, you must call the Clone method. its sub
 /// class inherit from this, and need to provide more features.
 /// </summary>
 /// <param name="session">the session to get the opentable</param>
 /// <param name="treeconnect">the treeconnect to copy from</param>
 protected SmbClientTreeConnect(SmbClientSession session, SmbClientTreeConnect treeconnect)
     : base(treeconnect)
 {
     this.session = session;
     this.maximalShareAccessRights      = treeconnect.maximalShareAccessRights;
     this.guestMaximalShareAccessRights = treeconnect.guestMaximalShareAccessRights;
     this.connection = treeconnect.connection;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// get the session in current connection
        /// </summary>
        /// <param name="sessionUid">the id of session</param>
        /// <returns>the session object</returns>
        public SmbClientSession GetSession(ushort sessionUid)
        {
            SmbClientConnection connection = Connection;

            if (connection == null)
            {
                return null;
            }

            return new SmbClientSession(GetSession(connection.ConnectionId, sessionUid));
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Deep copy constructor. if need to copy the connection instance, you must call the Clone method. its sub
 /// class inherit from this, and need to provide more features.
 /// </summary>
 protected SmbClientConnection(SmbClientConnection connection)
     : base(connection)
 {
     lock (connection)
     {
         this.GssApi = connection.GssApi;
         if (connection.SecurityBlob != null)
         {
             this.SecurityBlob = new byte[connection.SecurityBlob.Length];
             Array.Copy(connection.SecurityBlob, this.SecurityBlob, connection.SecurityBlob.Length);
         }
     }
 }
 /// <summary>
 /// Deep copy constructor. if need to copy the connection instance, you must call the Clone method. its sub 
 /// class inherit from this, and need to provide more features. 
 /// </summary>
 protected SmbClientConnection(SmbClientConnection connection)
     : base(connection)
 {
     lock (connection)
     {
         this.GssApi = connection.GssApi;
         if (connection.SecurityBlob != null)
         {
             this.SecurityBlob = new byte[connection.SecurityBlob.Length];
             Array.Copy(connection.SecurityBlob, this.SecurityBlob, connection.SecurityBlob.Length);
         }
     }
 }
Ejemplo n.º 6
0
 /// <summary>
 /// merge the server sign state when client is disabled-unless-required. 
 /// </summary>
 /// <param name = "connection">the target connection to update </param>
 private void MergeClientDisalbedUnlessRequiredState(SmbClientConnection connection)
 {
     switch (connection.ServerSigningState)
     {
         case SignState.REQUIRED:
             connection.IsSigningActive = true;
             break;
         case SignState.ENABLED:
         case SignState.DISABLED_UNLESS_REQUIRED:
         case SignState.DISABLED:
             connection.IsSigningActive = false;
             break;
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// merge the server sign state when client is enable. 
        /// </summary>
        /// <param name = "connection">the target connection to update </param>
        private void MergeClientEnableState(SmbClientConnection connection)
        {
            switch (connection.ServerSigningState)
            {
                case SignState.REQUIRED:
                case SignState.ENABLED:
                    connection.IsSigningActive = true;
                    break;
                case SignState.DISABLED_UNLESS_REQUIRED:
                case SignState.DISABLED:
                    connection.IsSigningActive = false;
                    break;

                default:
                    break;
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// get the file in current connection
        /// </summary>
        /// <param name="fid">the id of file</param>
        /// <returns>the file object</returns>
        public SmbClientOpen GetOpenFile(ushort fid)
        {
            SmbClientConnection connection = Connection;

            if (connection == null)
            {
                return null;
            }

            ReadOnlyCollection<CifsClientPerOpenFile> files = GetOpenFiles(connection.ConnectionId);
            foreach (CifsClientPerOpenFile file in files)
            {
                if (file.FileHandle == fid)
                {
                    return new SmbClientOpen(file);
                }
            }

            return null;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// get the treeconnect in current connection
        /// </summary>
        /// <param name="tid">the id of treeconnect</param>
        /// <returns>the treeconnect object</returns>
        public SmbClientTreeConnect GetTreeConnect(ushort tid)
        {
            SmbClientConnection connection = Connection;

            if (connection == null)
            {
                return null;
            }

            ReadOnlyCollection<CifsClientPerTreeConnect> treeconnects = GetTreeConnects(connection.ConnectionId);
            foreach (CifsClientPerTreeConnect treeconnect in treeconnects)
            {
                if (treeconnect.TreeId == tid)
                {
                    return new SmbClientTreeConnect(GetSession((ushort)treeconnect.SessionId), treeconnect);
                }
            }

            return null;
        }
Ejemplo n.º 10
0
        private bool SmbUpdateContextWithResponsePacket(SmbClientConnection connection, SmbPacket response)
        {
            if (response == null)
            {
                return false;
            }

            int connectionId = connection.ConnectionId;

            SmbHeader smbHeader = response.SmbHeader;

            // only process the response packet.
            if (response.PacketType != SmbPacketType.BatchedResponse
                && response.PacketType != SmbPacketType.SingleResponse)
            {
                return false;
            }

            // packet status
            SmbStatus packetStatus = (SmbStatus)smbHeader.Status;

            // filter error packet
            if (packetStatus != SmbStatus.STATUS_SUCCESS &&
                    packetStatus != SmbStatus.STATUS_MORE_PROCESSING_REQUIRED &&
                    packetStatus != SmbStatus.STATUS_BUFFER_OVERFLOW)
            {
                return false;
            }

            // process each special command
            switch (smbHeader.Command)
            {
                #region Negotiate Response

                case SmbCommand.SMB_COM_NEGOTIATE:

                    // implicit ntlm, decode using cifs sdk.
                    if (!smbClient.Capability.IsSupportsExtendedSecurity)
                    {
                        return false;
                    }

                    // down cast to negotiate response packet.
                    SmbNegotiateResponsePacket negotiate = response as SmbNegotiateResponsePacket;

                    // set negotiate flag
                    connection.NegotiateSent = true;

                    #region update security mode

                    SecurityModes securityModes = negotiate.SmbParameters.SecurityMode;

                    if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED
                        == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED))
                    {
                        connection.ServerSigningState = SignState.ENABLED;
                    }
                    else if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
                        == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED))
                    {
                        connection.ServerSigningState = SignState.REQUIRED;
                    }
                    else
                    {
                        connection.ServerSigningState = SignState.DISABLED;
                    }

                    if (SecurityModes.NEGOTIATE_USER_SECURITY
                        == (securityModes & SecurityModes.NEGOTIATE_USER_SECURITY))
                    {
                        connection.UsesSharePasswords = false;
                    }
                    else
                    {
                        connection.UsesSharePasswords = true;
                    }

                    if (SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS
                        == (securityModes & SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS))
                    {
                        connection.IsClientEncryptPasswords = true;
                    }
                    else
                    {
                        connection.IsClientEncryptPasswords = false;
                    }

                    // update IsSignActive using the combination of the client's 
                    // MessageSigningPolicy and the connection's ServerSigningState
                    smbClient.Context.UpdateSigningActive(connection);

                    #endregion

                    #region update server capabilities

                    connection.ServerCapabilities = (Capabilities)negotiate.SmbParameters.Capabilities;

                    if (Capabilities.CAP_INFOLEVEL_PASSTHRU
                        == (connection.ServerCapabilities & Capabilities.CAP_INFOLEVEL_PASSTHRU))
                    {
                        smbClient.Capability.IsUsePassThrough = true;
                    }

                    #endregion

                    #region update maxbuffersize

                    connection.MaxBufferSize = negotiate.SmbParameters.MaxBufferSize;

                    #endregion

                    this.AddOrUpdateConnection(connection);

                    break;

                #endregion

                #region Session Setup Response

                case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:

                    // implicit ntlm, decode using cifs sdk.
                    if (!smbClient.Capability.IsSupportsExtendedSecurity)
                    {
                        return false;
                    }

                    // the session to operation on.
                    SmbClientSession session = null;

                    // down-case the packet
                    SmbSessionSetupAndxResponsePacket packet = response as SmbSessionSetupAndxResponsePacket;

                    // if session exists, use it.
                    if (this.GetSession(connectionId, smbHeader.Uid) != null)
                    {
                        session = new SmbClientSession(this.GetSession(connectionId, smbHeader.Uid));
                    }
                    else
                    {
                        session = new SmbClientSession();
                    }

                    // if success, update context and session key.
                    if (packetStatus == SmbStatus.STATUS_SUCCESS)
                    {
                        // if spng, the SessionKey is null and the SecurityBlob from server contains data
                        // in this situation, need to initialize the SecurityBlob of server to generate the SessionKey
                        if (connection.GssApi.SessionKey == null
                            && packet.SecurityBlob != null && packet.SecurityBlob.Length > 0)
                        {
                            connection.GssApi.Initialize(packet.SecurityBlob);
                        }

                        // get session key and store in the context
                        session.SessionKey = connection.GssApi.SessionKey;

                        // reset the gss api of connection
                        connection.GssApi = null;

                        // reset the securityblob when success
                        packet.SecurityBlob = null;
                    }

                    // update the security blob from server
                    connection.SecurityBlob = packet.SecurityBlob;
                    this.AddOrUpdateConnection(connection);

                    // update session
                    session.SessionUid = smbHeader.Uid;
                    session.ConnectionId = connectionId;

                    this.AddOrUpdateSession(session);

                    break;

                #endregion

                default:
                    return false;
            }

            return true;
        }
        /// <summary>
        /// to set up Netbios session with server, and add the connection into context.
        /// </summary>
        /// <param name="server">the server NetBios Name.</param>
        /// <param name="client">the local NetBios Name.</param>
        /// <param name="bufferSize">the size of buffer used for receiving data.</param>
        /// <param name="maxSessions">the max sessions supported by the transport.</param>
        /// <param name="maxNames">
        /// the max Netbios names used to initialize the NCB. It is only used in NetBios transport.
        /// </param>
        /// <returns>the Identity of the connection. if connected, is the session number 
        /// of the Netbios session; otherwise -1.</returns>
        /// <exception cref="System.ArgumentNullException">the server and client must not be null.</exception>
        public virtual void Connect(string server, string client, int bufferSize, int maxSessions, int maxNames)
        {
            if (server == null)
            {
                throw new ArgumentNullException("server");
            }

            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            NetbiosTransportConfig transportConfig = new NetbiosTransportConfig();
            transportConfig.Type = StackTransportType.Netbios;
            transportConfig.Role = Role.Client;
            transportConfig.BufferSize = bufferSize;
            transportConfig.MaxSessions = maxSessions;
            transportConfig.MaxNames = maxNames;
            transportConfig.RemoteNetbiosName = server;
            transportConfig.LocalNetbiosName = client + new Random().Next();

            this.transport = new TransportStack(transportConfig, new SmbClientDecodePacket(this).DecodePacket);

            int connectionId = (int)this.transport.Connect();
            this.ConnectionId = connectionId;

            SmbClientConnection connection = new SmbClientConnection();
            connection.ConnectionId = connectionId;
            connection.ConnectionState = StackTransportState.ConnectionEstablished;
            connection.ServerNetbiosName = server;
            connection.ClientNetbiosName = client;
            this.Context.AddOrUpdateConnection(connection);

            // set the transport type
            this.capability.TransportType = TransportType.NetBIOS;
        }
        private bool SmbUpdateContextWithResponsePacket(SmbClientConnection connection, SmbPacket response)
        {
            if (response == null)
            {
                return false;
            }

            int connectionId = connection.ConnectionId;

            SmbHeader smbHeader = response.SmbHeader;

            // only process the response packet.
            if (response.PacketType != SmbPacketType.BatchedResponse
                && response.PacketType != SmbPacketType.SingleResponse)
            {
                return false;
            }

            // packet status
            SmbStatus packetStatus = (SmbStatus)smbHeader.Status;

            // filter error packet
            if (packetStatus != SmbStatus.STATUS_SUCCESS &&
                    packetStatus != SmbStatus.STATUS_MORE_PROCESSING_REQUIRED &&
                    packetStatus != SmbStatus.STATUS_BUFFER_OVERFLOW)
            {
                return false;
            }

            // process each special command
            switch (smbHeader.Command)
            {
                #region Negotiate Response

                case SmbCommand.SMB_COM_NEGOTIATE:

                    // implicit ntlm, decode using cifs sdk.
                    if (!smbClient.Capability.IsSupportsExtendedSecurity)
                    {
                        return false;
                    }

                    // down cast to negotiate response packet.
                    SmbNegotiateResponsePacket negotiate = response as SmbNegotiateResponsePacket;

                    // set negotiate flag
                    connection.NegotiateSent = true;

                    #region update security mode

                    SecurityModes securityModes = negotiate.SmbParameters.SecurityMode;

                    if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED
                        == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_ENABLED))
                    {
                        connection.ServerSigningState = SignState.ENABLED;
                    }
                    else if (SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED
                        == (securityModes & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED))
                    {
                        connection.ServerSigningState = SignState.REQUIRED;
                    }
                    else
                    {
                        connection.ServerSigningState = SignState.DISABLED;
                    }

                    if (SecurityModes.NEGOTIATE_USER_SECURITY
                        == (securityModes & SecurityModes.NEGOTIATE_USER_SECURITY))
                    {
                        connection.UsesSharePasswords = false;
                    }
                    else
                    {
                        connection.UsesSharePasswords = true;
                    }

                    if (SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS
                        == (securityModes & SecurityModes.NEGOTIATE_ENCRYPT_PASSWORDS))
                    {
                        connection.IsClientEncryptPasswords = true;
                    }
                    else
                    {
                        connection.IsClientEncryptPasswords = false;
                    }

                    // update IsSignActive using the combination of the client's
                    // MessageSigningPolicy and the connection's ServerSigningState
                    smbClient.Context.UpdateSigningActive(connection);

                    #endregion

                    #region update server capabilities

                    connection.ServerCapabilities = (Capabilities)negotiate.SmbParameters.Capabilities;

                    if (Capabilities.CAP_INFOLEVEL_PASSTHRU
                        == (connection.ServerCapabilities & Capabilities.CAP_INFOLEVEL_PASSTHRU))
                    {
                        smbClient.Capability.IsUsePathThrough = true;
                    }

                    #endregion

                    #region update maxbuffersize

                    connection.MaxBufferSize = negotiate.SmbParameters.MaxBufferSize;

                    #endregion

                    this.AddOrUpdateConnection(connection);

                    break;

                #endregion

                #region Session Setup Response

                case SmbCommand.SMB_COM_SESSION_SETUP_ANDX:

                    // implicit ntlm, decode using cifs sdk.
                    if (!smbClient.Capability.IsSupportsExtendedSecurity)
                    {
                        return false;
                    }

                    // the session to operation on.
                    SmbClientSession session = null;

                    // down-case the packet
                    SmbSessionSetupAndxResponsePacket packet = response as SmbSessionSetupAndxResponsePacket;

                    // if session exists, use it.
                    if (this.GetSession(connectionId, smbHeader.Uid) != null)
                    {
                        session = new SmbClientSession(this.GetSession(connectionId, smbHeader.Uid));
                    }
                    else
                    {
                        session = new SmbClientSession();
                    }

                    // if success, update context and session key.
                    if (packetStatus == SmbStatus.STATUS_SUCCESS)
                    {
                        // if spng, the SessionKey is null and the SecurityBlob from server contains data
                        // in this situation, need to initialize the SecurityBlob of server to generate the SessionKey
                        if (connection.GssApi.SessionKey == null
                            && packet.SecurityBlob != null && packet.SecurityBlob.Length > 0)
                        {
                            connection.GssApi.Initialize(packet.SecurityBlob);
                        }

                        // get session key and store in the context
                        session.SessionKey = connection.GssApi.SessionKey;

                        // reset the gss api of connection
                        connection.GssApi = null;

                        // reset the securityblob when success
                        packet.SecurityBlob = null;
                    }

                    // update the security blob from server
                    connection.SecurityBlob = packet.SecurityBlob;
                    this.AddOrUpdateConnection(connection);

                    // update session
                    session.SessionUid = smbHeader.Uid;
                    session.ConnectionId = connectionId;

                    this.AddOrUpdateSession(session);

                    break;

                #endregion

                default:
                    return false;
            }

            return true;
        }
 /// <summary>
 /// merge the server sign state when client is required. 
 /// </summary>
 /// <param name = "connection">the target connection to update </param>
 private void MergeClientRequiredState(SmbClientConnection connection)
 {
     switch (connection.ServerSigningState)
     {
         case SignState.REQUIRED:
         case SignState.ENABLED:
         case SignState.DISABLED_UNLESS_REQUIRED:
             connection.IsSigningActive = true;
             break;
         case SignState.DISABLED:
             break;
         default:
             break;
     }
 }
        /// <summary>
        /// update the connection isSigningActive, combination of the client's MessageSigningPolicy and the 
        /// connection's ServerSigningState. 
        /// </summary>
        /// <param name = "connection">the target connection to update </param>
        /// <returns>the combination result </returns>
        internal void UpdateSigningActive(SmbClientConnection connection)
        {
            if (connection == null)
            {
                return;
            }

            switch (smbClient.Capability.ClientSignState)
            {
                case SignState.REQUIRED:
                    MergeClientRequiredState(connection);
                    break;
                case SignState.ENABLED:
                    MergeClientEnableState(connection);
                    break;
                case SignState.DISABLED_UNLESS_REQUIRED:
                    MergeClientDisalbedUnlessRequiredState(connection);
                    break;
                case SignState.DISABLED:
                    MergeClientDisabledState(connection);
                    break;

                default:
                    break;
            }
        }
 /// <summary>
 /// Deep copy constructor. if need to copy the connection instance, you must call the Clone method. its sub 
 /// class inherit from this, and need to provide more features. 
 /// </summary>
 protected SmbClientSession(SmbClientSession session)
     : base(session)
 {
     this.connection = session.connection;
     this.sessionKeyState = session.sessionKeyState;
 }
 /// <summary>
 /// Deep copy constructor. if need to copy the connection instance, you must call the Clone method. its sub 
 /// class inherit from this, and need to provide more features. 
 /// </summary>
 /// <param name="session">the session to get the opentable</param>
 /// <param name="treeconnect">the treeconnect to copy from</param>
 protected SmbClientTreeConnect(SmbClientSession session, SmbClientTreeConnect treeconnect)
     : base(treeconnect)
 {
     this.session = session;
     this.maximalShareAccessRights = treeconnect.maximalShareAccessRights;
     this.guestMaximalShareAccessRights = treeconnect.guestMaximalShareAccessRights;
     this.connection = treeconnect.connection;
 }
        /// <summary>
        /// to set up the tcp connection, and add the connection into context. Exception will  be thrown if failed to 
        /// set up connection with server. 
        /// </summary>
        /// <param name = "serverName">the server name or server ip address to connect to </param>
        /// <param name = "serverPort">the port of server to connect to </param>
        /// <param name = "ipVersion">the ipversion to connect to server </param>
        /// <param name = "bufferSize">the buffer size of transport </param>
        /// <exception cref="InvalidOperationException">
        /// Failed to get the IP address of SMB server in SmbClient().
        /// </exception>
        public virtual void Connect(string serverName, int serverPort, IpVersion ipVersion, int bufferSize)
        {
            // initialize the config for transport
            SocketTransportConfig config = new SocketTransportConfig();

            config.Role = Role.Client;
            config.Type = StackTransportType.Tcp;
            config.BufferSize = bufferSize;

            // init remote address of config
            #region Lookup the ip address from server name.

            IPHostEntry ipHostEntry = Dns.GetHostEntry(serverName);
            if (ipHostEntry != null)
            {
                foreach (IPAddress address in ipHostEntry.AddressList)
                {
                    if (ipVersion != IpVersion.Ipv4 && address.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        config.LocalIpAddress = IPAddress.IPv6Any;
                        config.RemoteIpAddress = address;
                        break;
                    }
                    else if (ipVersion != IpVersion.Ipv6 && address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        config.LocalIpAddress = IPAddress.Any;
                        config.RemoteIpAddress = address;
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            if (config.RemoteIpAddress == null)
            {
                throw new InvalidOperationException("Failed to get the IP address of SMB server in SmbClient().");
            }

            #endregion

            // init remote port
            config.RemoteIpPort = serverPort;

            // init local address of config
            config.LocalIpAddress = IPAddress.Any;
            config.LocalIpPort = 0;

            // init transport
            this.transport = new TransportStack(config, new SmbClientDecodePacket(this).DecodePacket);

            // connect to server.
            object endPointIdentity = this.transport.Connect();

            // initialize the connection
            SmbClientConnection connection = new SmbClientConnection();

            connection.ConnectionId = this.Context.GetConnectionID(endPointIdentity as IPEndPoint);
            connection.ConnectionState = StackTransportState.ConnectionEstablished;
            connection.MaxBufferSize = (uint)bufferSize;

            // update the context
            this.cifsClient.Context.AddOrUpdateConnection(connection);

            // update the connection id, to identity the connection instance.
            this.ConnectionId = connection.ConnectionId;

            // set the transport type
            this.capability.TransportType = TransportType.TCP;
        }
 /// <summary>
 /// Deep copy constructor. if need to copy the connection instance, you must call the Clone method. its sub
 /// class inherit from this, and need to provide more features.
 /// </summary>
 protected SmbClientSession(SmbClientSession session)
     : base(session)
 {
     this.connection      = session.connection;
     this.sessionKeyState = session.sessionKeyState;
 }