コード例 #1
0
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if(m_IsDisposed){
                    return;
                }
                m_IsDisposed = true;

                m_pOwner       = null;
                m_pBuffer      = null;
                m_pException   = null;
                this.Completed = null;
            }
コード例 #2
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="stream">Source stream.</param>
        /// <param name="access">Specifies stream access mode.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
        public QuotedPrintableStream(SmartStream stream,FileAccess access)
        {
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            m_pStream    = stream;
            m_AccessMode = access;

            m_pDecodedBuffer = new byte[32000];
            m_pEncodedBuffer = new byte[78];
        }
コード例 #3
0
        /// <summary>
        /// Cleans up any resources being used.
        /// </summary>
        public override void Dispose()
        {
            if(m_IsDisposed){
                return;
            }
            if(!m_IsTerminated){
                try{
                    Disconnect();
                }
                catch{
                    // Skip disconnect errors.
                }
            }
            m_IsDisposed = true;

            // We must call disposed event before we release events.
            try{
                OnDisposed();
            }
            catch{
                // We never should get exception here, user should handle it, just skip it.
            }

            m_pLocalEP = null;
            m_pRemoteEP = null;
            m_pCertificate = null;
            if(m_pTcpStream != null){
                m_pTcpStream.Dispose();
            }
            m_pTcpStream = null;
            m_pTags = null;

            // Release events.
            this.IdleTimeout = null;
            this.Disonnected  = null;
            this.Disposed    = null;
        }
コード例 #4
0
            /// <summary>
            /// Starts period-terminated data reading.
            /// </summary>
            /// <param name="stream">Owner SmartStream.</param>
            /// <returns>Returns true if read line completed synchronously, false if asynchronous operation pending.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
            internal bool Start(SmartStream stream)
            {
                if(stream == null){
                    throw new ArgumentNullException("stream");
                }

                m_pOwner = stream;

                // Clear old data, if any.
                m_IsCompleted = false;
                m_BytesStored = 0;
                m_LinesStored = 0;
                m_pException  = null;

                m_IsCompletedSync = DoRead();
   
                return m_IsCompletedSync;
            }
コード例 #5
0
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if(m_IsDisposed){
                    return;
                }
                m_IsDisposed = true;

                m_pOwner       = null;
                m_pStream      = null;
                m_pReadLineOP.Dispose();
                m_pReadLineOP  = null;
                m_pException   = null;
                this.Completed = null;
            }
コード例 #6
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="owner">Owner stream.</param>
            /// <param name="buffer">Buffer where to store data.</param>
            /// <param name="offset">The location in <b>buffer</b> to begin storing the data.</param>
            /// <param name="maxSize">Maximum number of bytes to read.</param>
            /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param>
            /// <param name="asyncState">User-defined object that qualifies or contains information about an asynchronous operation.</param>
            public ReadAsyncOperation(SmartStream owner,byte[] buffer,int offset,int maxSize,AsyncCallback callback,object asyncState)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }
                if(buffer == null){
                    throw new ArgumentNullException("buffer");
                }
                if(offset < 0){
                    throw new ArgumentOutOfRangeException("offset","Argument 'offset' value must be >= 0.");
                }
                if(offset > buffer.Length){
                    throw new ArgumentOutOfRangeException("offset","Argument 'offset' value must be < buffer.Length.");
                }
                if(maxSize < 0){
                    throw new ArgumentOutOfRangeException("maxSize","Argument 'maxSize' value must be >= 0.");
                }
                if(offset + maxSize > buffer.Length){
                    throw new ArgumentOutOfRangeException("maxSize","Argument 'maxSize' is bigger than than argument 'buffer' can store.");
                }

                m_pOwner             = owner;
                m_pBuffer            = buffer;
                m_OffsetInBuffer     = offset;
                m_MaxSize            = maxSize;
                m_pAsyncCallback     = callback;
                m_pAsyncState        = asyncState;

                m_pAsyncWaitHandle = new AutoResetEvent(false);

                DoRead();
            }
コード例 #7
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="owner">Owner stream.</param>
            /// <param name="storeStream">Stream where to store readed data.</param>
            /// <param name="count">Number of bytes to read from source stream.</param>
            /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param>
            /// <param name="asyncState">User-defined object that qualifies or contains information about an asynchronous operation.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> or <b>storeStream</b> is null reference.</exception>
            /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
            public ReadToStreamAsyncOperation(SmartStream owner,Stream storeStream,long count,AsyncCallback callback,object asyncState)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }
                if(storeStream == null){
                    throw new ArgumentNullException("storeStream");
                }
                if(count < 0){
                    throw new ArgumentException("Argument 'count' must be >= 0.");
                }

                m_pOwner             = owner;
                m_pStoreStream       = storeStream;
                m_Count              = count;
                m_pAsyncCallback     = callback;
                m_pAsyncState        = asyncState;

                m_pAsyncWaitHandle = new AutoResetEvent(false);

                if(m_Count == 0){
                    Completed();                    
                }
                else{
                    DoDataReading();
                }
            }
コード例 #8
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="owner">Owner stream.</param>
            /// <param name="terminator">Data terminator.</param>
            /// <param name="storeStream">Stream where to store readed header.</param>
            /// <param name="maxCount">Maximum number of bytes to read. Value 0 means not limited.</param>
            /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param>
            /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param>
            /// <param name="asyncState">User-defined object that qualifies or contains information about an asynchronous operation.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>,<b>terminator</b> or <b>storeStream</b> is null reference.</exception>
            public ReadToTerminatorAsyncOperation(SmartStream owner,string terminator,Stream storeStream,long maxCount,SizeExceededAction exceededAction,AsyncCallback callback,object asyncState)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }
                if(terminator == null){
                    throw new ArgumentNullException("terminator");
                }
                if(storeStream == null){
                    throw new ArgumentNullException("storeStream");
                }
                if(maxCount < 0){
                    throw new ArgumentException("Argument 'maxCount' must be >= 0.");
                }

                m_pOwner             = owner;
                m_Terminator         = terminator;
                m_pTerminatorBytes   = Encoding.ASCII.GetBytes(terminator);
                m_pStoreStream       = storeStream;
                m_MaxCount           = maxCount;
                m_SizeExceededAction = exceededAction;
                m_pAsyncCallback     = callback;
                m_pAsyncState        = asyncState;

                m_pAsyncWaitHandle = new AutoResetEvent(false);

                m_pLineBuffer = new byte[32000];

                // Start reading data.
                #pragma warning disable
                m_pOwner.BeginReadLine(m_pLineBuffer,0,m_pLineBuffer.Length - 2,m_SizeExceededAction,new AsyncCallback(this.ReadLine_Completed),null);
                #pragma warning restore
            }
コード例 #9
0
        /// <summary>
        /// Disconnects connection.
        /// </summary>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="InvalidOperationException">Is raised when TCP client is not connected.</exception>
        public override void Disconnect()
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException("TCP_Client");
            }
            if(!m_IsConnected){
                throw new InvalidOperationException("TCP client is not connected.");
            }
            m_IsConnected = false;

            m_pLocalEP = null;
            m_pRemoteEP = null;
            m_pTcpStream.Dispose();
            m_IsSecure = false;
            m_pTcpStream = null;

            LogAddText("Disconnected.");
        }
コード例 #10
0
            /// <summary>
            /// Starts reading line.
            /// </summary>
            /// <param name="async">If true then this method can complete asynchronously. If false, this method completed always syncronously.</param>
            /// <param name="stream">Owner SmartStream.</param>
            /// <returns>Returns true if read line completed synchronously, false if asynchronous operation pending.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
            internal bool Start(bool async,SmartStream stream)
            {   
                if(stream == null){
                    throw new ArgumentNullException("stream");
                }

                m_pOwner = stream;

                // Clear old data, if any.
                m_IsCompleted   = false;
                m_BytesInBuffer = 0;
                m_LastByte      = -1;
                m_pException    = null;
   
                m_IsCompletedSync = DoLineReading(async);

                return m_IsCompletedSync;
            }
コード例 #11
0
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if(m_State == AsyncOP_State.Disposed){
                    return;
                }
                SetState(AsyncOP_State.Disposed);
                
                m_pException  = null;
                m_pStream     = null;
                m_pOwner      = null;
                m_pReadLineOP = null;

                this.CompletedAsync = null;
            }
コード例 #12
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="stream">Source stream. Reading starts from stream current location.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
            public WritePeriodTerminatedAsyncOP(Stream stream)
            {
                if(stream == null){
                    throw new ArgumentNullException("stream");
                }

                m_pStream = new SmartStream(stream,false);
            }
コード例 #13
0
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner SmartStream.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(SmartStream owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }
                
                m_pOwner = owner;

                SetState(AsyncOP_State.Active);
                
                BeginReadData();

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }
コード例 #14
0
        /// <summary>
        /// Initializes session. This method is called from TCP_Server when new session created.
        /// </summary>
        /// <param name="server">Owner TCP server.</param>
        /// <param name="socket">Connected socket.</param>
        /// <param name="hostName">Local host name.</param>
        /// <param name="ssl">Specifies if session should switch to SSL.</param>
        /// <param name="certificate">SSL certificate.</param>
        internal void Init(object server,Socket socket,string hostName,bool ssl,X509Certificate certificate)
        {   
            // NOTE: We may not raise any event here !
            
            m_pServer       = server;
            m_LocalHostName = hostName;
            m_ID            = Guid.NewGuid().ToString();
            m_ConnectTime   = DateTime.Now;
            m_pLocalEP      = (IPEndPoint)socket.LocalEndPoint;
            m_pRemoteEP     = (IPEndPoint)socket.RemoteEndPoint;            
            m_pCertificate  = certificate;

            socket.ReceiveBufferSize = 32000;
            socket.SendBufferSize = 32000;

            if(ssl){
                m_pTcpStream = new SmartStream(new NetworkStream(socket,true),true);
                SwitchToSecure();
            }
            else{
                m_pTcpStream = new SmartStream(new NetworkStream(socket,true),true);
            }
        }
コード例 #15
0
        /// <summary>
        /// Switches session to secure connection.
        /// </summary>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="InvalidOperationException">Is raised when connection is already secure or when SSL certificate is not specified.</exception>
        public void SwitchToSecure()
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException("TCP_ServerSession");
            }
            if(m_IsSecure){
                throw new InvalidOperationException("Session is already SSL/TLS.");
            }
            if(m_pCertificate == null){
                throw new InvalidOperationException("There is no certificate specified.");
            }

            // FIX ME: if ssl switching fails, it closes source stream or otherwise if ssl successful, source stream leaks.

            SslStream sslStream = new SslStream(m_pTcpStream.SourceStream);
            sslStream.AuthenticateAsServer(m_pCertificate);

            // Close old stream, but leave source stream open.
            m_pTcpStream.IsOwner = false;
            m_pTcpStream.Dispose();

            m_IsSecure   = true;
            m_pTcpStream = new SmartStream(sslStream,true);
        }
コード例 #16
0
        /// <summary>
        /// Switches session to secure connection.
        /// </summary>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="InvalidOperationException">Is raised when TCP client is not connected or is already secure.</exception>
        protected void SwitchToSecure()
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException("TCP_Client");
            }
            if(!m_IsConnected){
                throw new InvalidOperationException("TCP client is not connected.");
            }
            if(m_IsSecure){
                throw new InvalidOperationException("TCP client is already secure.");
            }

            LogAddText("Switching to SSL.");

            // FIX ME: if ssl switching fails, it closes source stream or otherwise if ssl successful, source stream leaks.

            SslStream sslStream = new SslStream(m_pTcpStream.SourceStream,true,this.RemoteCertificateValidationCallback);
            sslStream.AuthenticateAsClient("dummy");

            // Close old stream, but leave source stream open.
            m_pTcpStream.IsOwner = false;
            m_pTcpStream.Dispose();

            m_IsSecure = true;
            m_pTcpStream = new SmartStream(sslStream,true);
        }
コード例 #17
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="owner">Owner stream.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            public BufferReadAsyncOP(SmartStream owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner = owner;
            }
コード例 #18
0
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner SmartStream.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(SmartStream owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner = owner;

                SetState(AsyncOP_State.Active);

                try{
                    // Read line.
                    m_pReadLineOP = new ReadLineAsyncOP(new byte[32000],SizeExceededAction.ThrowException);
                    m_pReadLineOP.Completed += delegate(object s,EventArgs<ReadLineAsyncOP> e){
                        ReadLineCompleted(m_pReadLineOP);
                    };
                    if(m_pStream.ReadLine(m_pReadLineOP,true)){
                        ReadLineCompleted(m_pReadLineOP);
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    SetState(AsyncOP_State.Completed);
                    m_pReadLineOP.Dispose();
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }
コード例 #19
0
        /// <summary>
        /// Reads header from source <b>stream</b> and writes it to stream.
        /// </summary>
        /// <param name="stream">Stream from where to read header.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null.</exception>
        public void WriteHeader(Stream stream)
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            SmartStream reader = new SmartStream(stream,false);
            reader.ReadHeader(this,0,SizeExceededAction.ThrowException);
        }
コード例 #20
0
        /// <summary>
        /// Completes command reading operation.
        /// </summary>
        /// <param name="op">Operation.</param>
        /// <returns>Returns true if server should start reading next command.</returns>
        private bool ProcessCmd(SmartStream.ReadLineAsyncOP op)
        {
            bool readNextCommand = true;
                        
            try{
                // We are already disposed.
                if(this.IsDisposed){
                    return false;
                }
                // Check errors.
                if(op.Error != null){
                    OnError(op.Error);
                }
                // Remote host shut-down(Socket.ShutDown) socket.
                if(op.BytesInBuffer == 0){
                    LogAddText("The remote host '" + this.RemoteEndPoint.ToString() + "' shut down socket.");
                    Dispose();
                
                    return false;
                }
                                
                string[] cmd_args = Encoding.UTF8.GetString(op.Buffer,0,op.LineBytesInBuffer).Split(new char[]{' '},2);
                string   cmd      = cmd_args[0].ToUpperInvariant();
                string   args     = cmd_args.Length == 2 ? cmd_args[1] : "";

                // Log.
                if(this.Server.Logger != null){
                    // Hide password from log.
                    if(cmd == "PASS"){
                        this.Server.Logger.AddRead(this.ID,this.AuthenticatedUserIdentity,op.BytesInBuffer,"PASS <***REMOVED***>",this.LocalEndPoint,this.RemoteEndPoint);
                    }
                    else{
                        this.Server.Logger.AddRead(this.ID,this.AuthenticatedUserIdentity,op.BytesInBuffer,op.LineUtf8,this.LocalEndPoint,this.RemoteEndPoint);
                    }
                }

                if(cmd == "STLS"){
                    STLS(args);
                }
                else if(cmd == "USER"){
                    USER(args);
                }
                else if(cmd == "PASS"){
                    PASS(args);
                }
                else if(cmd == "PASS"){
                    PASS(args);
                }
                else if(cmd == "AUTH"){
                    AUTH(args);
                }
                else if(cmd == "STAT"){
                    STAT(args);
                }
                else if(cmd == "LIST"){
                    LIST(args);
                }
                else if(cmd == "UIDL"){
                    UIDL(args);
                }
                else if(cmd == "TOP"){
                    TOP(args);
                }
                else if(cmd == "RETR"){
                    RETR(args);
                }
                else if(cmd == "DELE"){
                    DELE(args);
                }
                else if(cmd == "NOOP"){
                    NOOP(args);
                }
                else if(cmd == "RSET"){
                    RSET(args);
                }
                else if(cmd == "DELE"){
                    DELE(args);
                }
                else if(cmd == "CAPA"){
                    CAPA(args);
                }
                else if(cmd == "QUIT"){
                    QUIT(args);
                }
                else{
                     m_BadCommands++;

                     // Maximum allowed bad commands exceeded.
                     if(this.Server.MaxBadCommands != 0 && m_BadCommands > this.Server.MaxBadCommands){
                         WriteLine("-ERR Too many bad commands, closing transmission channel.");
                         Disconnect();
                         return false;
                     }
                            
                     WriteLine("-ERR Error: command '" + cmd + "' not recognized.");
                 }
             }
             catch(Exception x){
                 OnError(x);
             }

             return readNextCommand;
        }