Dispose() protected method

protected Dispose ( bool disposing ) : void
disposing bool
return void
        //This is called when requests are routed through router to this endpoint
        //For ssl requests
        private static void HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient)
        {
            Stream clientStream = tcpClient.GetStream();
            CustomBinaryReader clientStreamReader = null;
            StreamWriter clientStreamWriter = null;
            X509Certificate2 certificate = null;

            if (endPoint.EnableSsl)
            {
                var sslStream = new SslStream(clientStream, true);
                //if(endPoint.UseServerNameIndication)
                //{
                //   //implement in future once SNI supported by SSL stream
                //    certificate = CertManager.CreateCertificate(endPoint.GenericCertificateName);
                //}
                //else
                certificate = CertManager.CreateCertificate(endPoint.GenericCertificateName);

                try
                {
                    //Successfully managed to authenticate the client using the fake certificate
                    sslStream.AuthenticateAsServer(certificate, false,
                       SslProtocols.Tls, false);

                    clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
                    clientStreamWriter = new StreamWriter(sslStream);
                    //HTTPS server created - we can now decrypt the client's traffic

                }
                catch (Exception)
                {
                    if (sslStream != null)
                        sslStream.Dispose();

                    Dispose(tcpClient, sslStream, clientStreamReader, clientStreamWriter, null);
                    return;
                }
                clientStream = sslStream;
            }
            else
            {
                clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII);
            }

            var httpCmd = clientStreamReader.ReadLine();

            //Now create the request
            HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
                true);
        }
Example #2
0
        /// <summary>
        /// Begin the secure negotiation and server authentication.
        /// </summary>
        /// <exception cref="System.Exception"></exception>
        /// <exception cref="System.Security.Authentication.AuthenticationException"></exception>
        public virtual void BeginSslNegotiation()
        {
            if (!_isSslAuthenticated && _useSslConnection && _networkStream == null)
            {
                // Block the socket for now.
                _socket.Blocking = true;

                // Initialy assign the network stream
                _networkStream = new NetworkStream(_socket);
            }

            try
            {
                // If not authenticated.
                if (!_isSslAuthenticated)
                {
                    // If ssl certificate has not been assigned.
                    if (_x509Certificate == null)
                    {
                        throw new Exception("Please add an SSL certificate for secure connections.");
                    }

                    // Get the current ssl stream
                    // from the socket.
                    _sslStream = new SslStream(_networkStream);

                    // Load the certificate into the
                    // secure stream used for secure communication.
                    _sslStream.AuthenticateAsServer(_x509Certificate, false, _sslProtocols, false);

                    // Get the state of the authentication.
                    if (_sslStream.IsAuthenticated && _sslStream.IsEncrypted)
                    {
                        _isSslAuthenticated = true;
                    }
                    else
                    {
                        _isSslAuthenticated = false;
                    }
                }
            }
            catch (System.Security.Authentication.AuthenticationException)
            {
                if (_sslStream != null)
                {
                    _sslStream.Dispose();
                }

                throw;
            }
        }
 public async Task<Stream> ConnectAsync(string host, int port, X509Certificate clientCert, CancellationToken cancel)
 {
     Stream lowerStream = null;
     SslStream sslStream = null;
     X509CertificateCollection certCollection = null;;
     if (clientCert != null)
     {
         certCollection = new X509CertificateCollection(new[] { clientCert });
     }
     try
     {
         lowerStream = await _connectionResolver.ConnectAsync(host, port, cancel);
         sslStream = new SslStream(lowerStream);
         await sslStream.AuthenticateAsClientAsync(host, certCollection, _protocols, checkCertificateRevocation: true);
         return sslStream;
     }
     catch (Exception)
     {
         if (sslStream != null)
         {
             sslStream.Dispose();
         }
         if (lowerStream != null)
         {
             lowerStream.Dispose();
         }
         throw;
     }
 }
        private static TcpConnection CreateClient(string Hostname, int port, bool IsSecure)
        {
            var client = new TcpClient(Hostname, port);
            var stream = (Stream)client.GetStream();

            if (IsSecure)
            {
                var sslStream = (SslStream)null;
                try
                {
                    sslStream = new SslStream(stream);
                    sslStream.AuthenticateAsClient(Hostname);
                    stream = (Stream)sslStream;
                }
                catch
                {
                    if (sslStream != null)
                        sslStream.Dispose();
                    throw;
                }
            }

            return new TcpConnection()
            {
                HostName = Hostname,
                port = port,
                IsSecure = IsSecure,
                TcpClient = client,
                ServerStreamReader = new CustomBinaryReader(stream, Encoding.ASCII),
                Stream = stream
            };
        }
 private bool TryConnectSsl(Stream stream, out SslStream ssl)
 {
     ssl = new SslStream(stream, false, UserCertificateValidationCallback, UserCertificateSelectionCallback, EncryptionPolicy.RequireEncryption);
     try
     {
         ssl.AuthenticateAsClient("Local", null, SslProtocols.Tls12, false);
     }
     catch (Exception ex)
     {
         Log.Publish(MessageLevel.Info, "Authentication Failed", null, null, ex);
         ssl.Dispose();
         ssl = null;
         return false;
     }
     return true;
 }
Example #6
0
		/// <summary>
		/// Establish a connection to the specified SMTP or SMTP/S server using the provided socket.
		/// </summary>
		/// <remarks>
		/// <para>Establishes a connection to the specified SMTP or SMTP/S server.</para>
		/// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the
		/// <paramref name="options"/> parameter is used to determine the default port to
		/// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/>
		/// is <c>465</c>. All other values will use a default port of <c>25</c>.</para>
		/// <para>If the <paramref name="options"/> has a value of
		/// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used
		/// to determine the default security options. If the <paramref name="port"/> has a value
		/// of <c>465</c>, then the default options used will be
		/// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use
		/// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para>
		/// <para>Once a connection is established, properties such as
		/// <see cref="AuthenticationMechanisms"/> and <see cref="Capabilities"/> will be
		/// populated.</para>
		/// <note type="note">The connection established by any of the
		/// <a href="Overload_MailKit_Net_Smtp_SmtpClient_Connect.htm">Connect</a>
		/// methods may be re-used if an application wishes to send multiple messages
		/// to the same SMTP server. Since connecting and authenticating can be expensive
		/// operations, re-using a connection can significantly improve performance when
		/// sending a large number of messages to the same SMTP server over a short
		/// period of time./</note>
		/// </remarks>
		/// <param name="socket">The socket to use for the connection.</param>
		/// <param name="host">The host name to connect to.</param>
		/// <param name="port">The port to connect to. If the specified port is <c>0</c>, then the default port will be used.</param>
		/// <param name="options">The secure socket options to when connecting.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="socket"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="host"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="socket"/> is not connected.</para>
		/// <para>-or-</para>
		/// The <paramref name="host"/> is a zero-length string.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="SmtpClient"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="SmtpClient"/> is already connected.
		/// </exception>
		/// <exception cref="System.NotSupportedException">
		/// <paramref name="options"/> was set to
		/// <see cref="MailKit.Security.SecureSocketOptions.StartTls"/>
		/// and the SMTP server does not support the STARTTLS extension.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="SmtpCommandException">
		/// An SMTP command failed.
		/// </exception>
		/// <exception cref="SmtpProtocolException">
		/// An SMTP protocol error occurred.
		/// </exception>
		public void Connect (Socket socket, string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken))
		{
			if (socket == null)
				throw new ArgumentNullException (nameof (socket));

			if (!socket.Connected)
				throw new ArgumentException ("The socket is not connected.", nameof (socket));

			if (host == null)
				throw new ArgumentNullException (nameof (host));

			if (host.Length == 0)
				throw new ArgumentException ("The host name cannot be empty.", nameof (host));

			if (port < 0 || port > 65535)
				throw new ArgumentOutOfRangeException (nameof (port));

			CheckDisposed ();

			if (IsConnected)
				throw new InvalidOperationException ("The SmtpClient is already connected.");

			capabilities = SmtpCapabilities.None;
			AuthenticationMechanisms.Clear ();
			MaxSize = 0;

			SmtpResponse response;
			Stream stream;
			bool starttls;
			Uri uri;

			ComputeDefaultValues (host, ref port, ref options, out uri, out starttls);

			this.host = host;

			if (options == SecureSocketOptions.SslOnConnect) {
				var ssl = new SslStream (new NetworkStream (socket, true), false, ValidateRemoteCertificate);

				try {
#if COREFX
					ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
					ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
				} catch {
					ssl.Dispose ();
					throw;
				}

				secure = true;
				stream = ssl;
			} else {
				stream = new NetworkStream (socket, true);
				secure = false;
			}

			if (stream.CanTimeout) {
				stream.WriteTimeout = timeout;
				stream.ReadTimeout = timeout;
			}

			ProtocolLogger.LogConnect (uri);

			Stream = new SmtpStream (stream, socket, ProtocolLogger);

			try {
				// read the greeting
				response = Stream.ReadResponse (cancellationToken);

				if (response.StatusCode != SmtpStatusCode.ServiceReady)
					throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);

				// Send EHLO and get a list of supported extensions
				Ehlo (cancellationToken);

				if (options == SecureSocketOptions.StartTls && (capabilities & SmtpCapabilities.StartTLS) == 0)
					throw new NotSupportedException ("The SMTP server does not support the STARTTLS extension.");

				if (starttls && (capabilities & SmtpCapabilities.StartTLS) != 0) {
					response = SendCommand ("STARTTLS", cancellationToken);
					if (response.StatusCode != SmtpStatusCode.ServiceReady)
						throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);

					var tls = new SslStream (stream, false, ValidateRemoteCertificate);
#if COREFX
					tls.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
					tls.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
					Stream.Stream = tls;

					secure = true;

					// Send EHLO again and get the new list of supported extensions
					Ehlo (cancellationToken);
				}

				connected = true;
			} catch {
				Stream.Dispose ();
				secure = false;
				Stream = null;
				throw;
			}

			OnConnected ();
		}
Example #7
0
        private void PopBeforeSmtp(MailParameters mailParams)
        {
            Stream stream = null;

            System.Net.Sockets.TcpClient popclient = null;
            try
            {
                string rstr;
                popclient = new System.Net.Sockets.TcpClient();

                // POPサーバーに接続
                popclient.Connect(mailParams.PopServer, mailParams.PopPort);
                logs.AppendLine("POP: Connected.");

                X509CertificateCollection clientCertificateCollection = new X509CertificateCollection();
                if (mailParams.IsClientCertValidate)
                {
                    var clientCertificate = Cert.GetCert(mailParams.ClientCertSerialNo);
                    clientCertificateCollection.Add(clientCertificate);
                }

                // サーバーとデータの送受信を行うストリームを取得する
                // 通信開始(SSL有り)
                switch (mailParams.PopSecureMode)
                {
                case SecureMode.SSL2:                   // SSL2で運用しているサーバは存在しないはずだが、一応対応しておく
                    stream = new System.Net.Security.SslStream(popclient.GetStream(), false, ServerCertificateValidation);
                    ((System.Net.Security.SslStream)stream).AuthenticateAsClient(mailParams.SmtpServer, clientCertificateCollection, SslProtocols.Ssl2, false);
                    logs.AppendLine("POP: socket is over SSL2.");
                    break;

                case SecureMode.SSL3:                   // SSL3で運用しているサーバはあるかもしれない
                    stream = new System.Net.Security.SslStream(popclient.GetStream(), false, ServerCertificateValidation);
                    ((System.Net.Security.SslStream)stream).AuthenticateAsClient(mailParams.SmtpServer, clientCertificateCollection, SslProtocols.Ssl3, false);
                    logs.AppendLine("POP: socket is over SSL3.");
                    break;

                case SecureMode.TLS:                    // TLSは現状では主流
                case SecureMode.STARTTLS:
                    stream = new System.Net.Security.SslStream(popclient.GetStream(), false, ServerCertificateValidation);
                    ((System.Net.Security.SslStream)stream).AuthenticateAsClient(mailParams.SmtpServer, clientCertificateCollection, SslProtocols.Tls, false);

                    logs.AppendLine("POP: socket is over TLS.");
                    break;

                case SecureMode.None:
                    stream = popclient.GetStream();
                    logs.AppendLine("POP: socket unsecure.");
                    break;
                }
                stream.ReadTimeout  = 5000;
                stream.WriteTimeout = 500;

                //サーバーからのはじめのメッセージを受信

                // POPサーバー接続時のレスポンス受信
                string connectstr = PopWriteAndRead(stream, "");
                if (connectstr.StartsWith("+OK") != true)
                {
                    throw new PopException("POPサーバー接続エラー");
                }

                switch (mailParams.PopAuth)
                {
                case PopAuthMethod.Standard:
                    // ユーザIDの送信
                    rstr = PopWriteAndRead(stream, "USER " + mailParams.PopUserId + "\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("ユーザIDエラー");
                    }

                    // パスワードの送信
                    rstr = PopWriteAndRead(stream, "PASS " + mailParams.PopPasswd + "\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("パスワードエラー");
                    }
                    break;

                case PopAuthMethod.APOP:
                    // APOP用のタイムスタンプ文字列を取得しておく
                    var timestamp = GetAPopTimeStamp(connectstr);
                    if (string.IsNullOrWhiteSpace(timestamp))
                    {
                        throw new PopException("APOP未対応");
                    }
                    Byte[] byt = System.Text.Encoding.ASCII.GetBytes(string.Format("<{0}>{1}", mailParams.PopUserId, mailParams.PopPasswd));
                    System.Security.Cryptography.MD5CryptoServiceProvider md5 =
                        new System.Security.Cryptography.MD5CryptoServiceProvider();
                    Byte[] res = md5.ComputeHash(byt);
                    string aps = BitConverter.ToString(res).Replace("-", "").ToLower();
                    rstr = PopWriteAndRead(stream, "APOP " + mailParams.PopUserId + " " + aps + "\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("ユーザIDまたはパスワードエラー");
                    }
                    break;

                case PopAuthMethod.NTLM:
                    // ユーザIDの送信
                    rstr = PopWriteAndRead(stream, "USER " + mailParams.PopUserId + "\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("ユーザIDエラー");
                    }

                    // パスワードの送信
                    rstr = PopWriteAndRead(stream, "PASS " + mailParams.PopPasswd + "\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("パスワードエラー");
                    }
                    break;

                case PopAuthMethod.CramMd5:
                    rstr = PopWriteAndRead(stream, "AUTH CRAM-MD5\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("CRAM-MD5未対応");
                    }

                    rstr = PopWriteAndRead(stream, CreateCramMd5ResponseString(rstr.Substring(4), mailParams.PopUserId, mailParams.PopPasswd) + "\r\n");
                    if (rstr.StartsWith("+OK") != true)
                    {
                        throw new PopException("認証エラー");
                    }
                    break;
                }

                // ステータスの送信
                rstr = PopWriteAndRead(stream, "STAT" + "\r\n");
                if (rstr.StartsWith("+OK") != true)
                {
                    throw new PopException("STATエラー");
                }

                // 終了の送信
                rstr = PopWriteAndRead(stream, "QUIT" + "\r\n");
                // 戻り値は無視
            }
            catch (PopException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw new PopException("内部例外発生", ex);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                }
                if (popclient != null)
                {
                    popclient.Close();
                }
            }
        }
        public bool Connect(int maxTryCount = 5)
        {
            TcpClient newTcpClient = null;
            SslStream newSslStream = null;
            int tryCount = 0;
            bool loggedIn = false;

            while (tryCount < maxTryCount && !loggedIn)
            {
                ++tryCount;
                bool retrying = tryCount > 1 ? true : false;

                if (retrying)
                {
                    Debug.WriteLine("ImapClient.Connect(): Trying to connect to " + Account.ImapServerName + ":" + Account.ImapPortNumber + "..." + tryCount);
                    if (newTcpClient != null)
                    {
                        newTcpClient.Close();
                    }
                    if (newSslStream != null)
                    {
                        newSslStream.Dispose();
                    }
                    Thread.Sleep(1000);
                }

                bool connected = false;
                try
                {
                    newTcpClient = new TcpClient();
                    var result = newTcpClient.BeginConnect(Account.ImapServerName, Account.ImapPortNumber, null, null);
                    var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5));
                    if (success && newTcpClient.Connected)
                    {
                        connected = true;
                        if (retrying)
                        {
                            Debug.WriteLine("ImapClient.Connect(): Connection succeeded.");
                        }
                    }
                    newTcpClient.EndConnect(result);
                }
                catch (Exception e)
                {
                    Error = e.Message;
                    Debug.WriteLine("ImapClient.Connect(): Exception occured while trying to connect to " + Account.ImapServerName + ":" + Account.ImapPortNumber + ".\n" + Error);
                    newTcpClient.Close();
                    return false;
                }

                if (!connected)
                {
                    if (tryCount < maxTryCount)
                    {
                        // Retry connecting.
                        continue;
                    }
                    else
                    {
                        Error = "Unable to connect to " + Account.ImapServerName + ":" + Account.ImapPortNumber;
                        Debug.WriteLine("ImapClient.Connect(): " + Error);
                        newTcpClient.Close();
                        return false;
                    }
                }

                // Now we're connected through TCP. Try to authenticate through SSL.
                try
                {
                    newSslStream = new SslStream(newTcpClient.GetStream(), false);
                    newSslStream.AuthenticateAsClient(Account.ImapServerName);
                }
                catch (Exception e)
                {
                    Error = e.Message;
                    Debug.WriteLine("ImapClient.Connect(): Exception occured while creating SSL stream to " + Account.ImapServerName + ":" + Account.ImapPortNumber + ".\n" + Error);
                    newTcpClient.Close();
                    return false;
                }

                // Now we're on SSL. Try to log in.
                if (retrying)
                {
                    Debug.WriteLine("ImapClient.Connect(): Logging in to " + Account.ImapServerName + "(" + Account.AccountName + ").");
                }

                newSslStream.ReadTimeout = 5000;  // For synchronous read calls.
                if (TryLogin(newSslStream))
                {
                    loggedIn = true;
                    if (retrying)
                    {
                        Debug.WriteLine("ImapClient.Connect(): Login succeeded.");
                    }
                }
            }

            if (!loggedIn)
            {
                // Reached max retry count. Clean up and return.
                Error = "Could not log in to " + Account.ImapServerName + "(" + Account.AccountName + "). Check credentials.";
                Debug.WriteLine("ImapClient.Connect(): " + Error);
                newTcpClient.Close();
                newSslStream.Dispose();
                return false;
            }

            this.tcpClient = newTcpClient;
            this.sslStream = newSslStream;
            return true;
        }
Example #9
0
        public string DonwloadTimeSheetMail()
        {
            string sUserid, sPassword;

            GetMailUseridAndPassword(out sUserid, out sPassword);

            string sTempDir = GetTempDir();
            string sPrefix  = GetTempFileNamePrefix();
            string sLpath   = sTempDir + "\\" + sPrefix + "maillog.txt";
//			if (File.Exists(sLpath)) File.Delete(sLpath);
            string sDpath = sTempDir + "\\" + sPrefix + "mailtext.txt";
//			if (File.Exists(sDpath)) File.Delete(sDpath);
            string sEpath = sTempDir + "\\" + sPrefix + "timesheet";
            string sRes;

            StreamWriter strmlgw = new System.IO.StreamWriter(System.IO.File.Create(sLpath));
            TcpClient    tcpclnt = new System.Net.Sockets.TcpClient("imap.gmail.com", 993);
            SslStream    sslstrm = new System.Net.Security.SslStream(tcpclnt.GetStream());

            // There should be no gap between the imap command and the \r\n
            // sslstrm.read() -- while sslstrm.readbyte!= eof does not work
            // because there is no eof from server and  cannot check for \r\n
            // because in case of larger response from server ex:read email
            // message. There are lot of lines so \r\n appears at the end of
            // each line sslstrm.timeout sets the underlying tcp connections
            // timeout if the read or writetime out exceeds then the undelying
            // connectionis closed.

            strmlgw.WriteLine("### START ====================================", sslstrm);
            sslstrm.AuthenticateAsClient("imap.gmail.com");
            strmlgw.WriteLine("# Send blank =================================", sslstrm);
            SendImapCommand("", sslstrm);
            sRes = ReceiveImapRespons(sslstrm);
            strmlgw.Write(sRes);

            strmlgw.WriteLine("# Send 'LOGIN' ===============================", sslstrm);
            SendImapCommand("$ LOGIN " + sUserid + " " + sPassword + "  \r\n", sslstrm);
            sRes = ReceiveImapRespons(sslstrm);
            strmlgw.Write(sRes);

            strmlgw.WriteLine("# Send 'SELECT INBOX' ========================", sslstrm);
            SendImapCommand("$ SELECT INBOX\r\n", sslstrm);
            sRes = ReceiveImapRespons(sslstrm);
            strmlgw.Write(sRes);

//			strmlgw.WriteLine("# Send 'TATUS INBOX (MESSAGES)' ==============", sslstrm);
//			SendImapCommand("$ STATUS INBOX (MESSAGES)\r\n", sslstrm);
//			sRes = ReceiveImapRespons(sslstrm);
//			strmlgw.Write(sRes);
//			int number = 1;
//			strmlgw.WriteLine("# Send 'FETCH " + number.ToString() + " BODYSTRUCTURE' =======", sslstrm);
//			SendImapCommand("$ FETCH " + number + " bodystructure\r\n", sslstrm);
//			sRes = ReceiveImapRespons(sslstrm);
//			strmlgw.Write(sRes);
//			strmlgw.WriteLine("# Send 'FETCH " + number.ToString() + " BODY[HEADER]' ========", sslstrm);
//			SendImapCommand("$ FETCH " + number + " body[header]\r\n", sslstrm);
//			sRes = ReceiveImapRespons(sslstrm);
//			strmlgw.Write(sRes);

            strmlgw.WriteLine("# Send 'FETCH 1 body[text]' ==================", sslstrm);
            SendImapCommand("$ FETCH 1 body[text]\r\n", sslstrm);
            ReceiveMailBody(sDpath, tcpclnt, sslstrm);

            string sTempTimeSheetPath = ExtractAttachedFile(sDpath, sEpath);

            strmlgw.WriteLine("# Send 'LOGOUT' ==============================", sslstrm);
            SendImapCommand("$ LOGOUT\r\n", sslstrm);
            sRes = ReceiveImapRespons(sslstrm);
            strmlgw.Write(sRes);
            strmlgw.WriteLine("### END ======================================", sslstrm);

            strmlgw.Close(); strmlgw.Dispose();
            sslstrm.Close(); sslstrm.Dispose();
            tcpclnt.Close();

            File.Delete(sLpath);
            File.Delete(sDpath);

            return(sTempTimeSheetPath);
        }
Example #10
0
        private static void HandleClient(TcpClient client)
        {
            Stream clientStream = client.GetStream();
            CustomBinaryReader clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII);
            StreamWriter clientStreamWriter = new StreamWriter(clientStream);

            string tunnelHostName = null;

            int tunnelPort = 0;

            try
            {

                string securehost = null;

                List<string> requestLines = new List<string>();
                string tmpLine;
                while (!String.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine()))
                {
                    requestLines.Add(tmpLine);
                }

                //read the first line HTTP command
                String httpCmd = requestLines.Count > 0 ? requestLines[0] : null;
                if (String.IsNullOrEmpty(httpCmd))
                {
                    throw new EndOfStreamException();
                }
                //break up the line into three components (method, remote URL & Http Version)
                String[] splitBuffer = httpCmd.Split(spaceSplit, 3);

                String method = splitBuffer[0];
                String remoteUri = splitBuffer[1];
                Version version;
                string RequestVersion;
                if (splitBuffer[2] == "HTTP/1.1")
                {
                    version = new Version(1, 1);
                    RequestVersion = "HTTP/1.1";
                }
                else
                {
                    version = new Version(1, 0);
                    RequestVersion = "HTTP/1.0";
                }

                //Client wants to create a secure tcp tunnel (its a HTTPS request)
                if (splitBuffer[0].ToUpper() == "CONNECT")
                {
                    //Browser wants to create a secure tunnel
                    //instead = we are going to perform a man in the middle "attack"
                    //the user's browser should warn them of the certification errors,
                    //to avoid that we need to install our root certficate in users machine as Certificate Authority.

                    remoteUri = "https://" + splitBuffer[1];
                    tunnelHostName = splitBuffer[1].Split(':')[0];

                    int.TryParse(splitBuffer[1].Split(':')[1], out tunnelPort);

                    if (tunnelPort == 0) tunnelPort = 443;

                    requestLines.Clear();

                    clientStreamWriter.WriteLine(RequestVersion + " 200 Connection established");
                    clientStreamWriter.WriteLine(String.Format("Timestamp: {0}", DateTime.Now.ToString()));
                    clientStreamWriter.WriteLine(String.Format("connection:close"));
                    clientStreamWriter.WriteLine();
                    clientStreamWriter.Flush();

                    //If port is not 443 its not a HTTP request, so just relay
                    if (tunnelPort != 443)
                    {
                        TcpHelper.SendRaw(tunnelHostName, tunnelPort, clientStreamReader.BaseStream);

                        if (clientStreamReader != null)
                            clientStreamReader.Dispose();

                        if (clientStreamWriter != null)
                            clientStreamWriter.Dispose();

                        if (clientStream != null)
                            clientStream.Dispose();

                        if (client != null)
                            client.Close();

                        return;
                    }

                    //Create the fake certificate signed using our fake certificate authority
                    Monitor.Enter(certificateAccessLock);
                    var certificate = ProxyServer.CertManager.CreateCertificate(tunnelHostName);
                    Monitor.Exit(certificateAccessLock);

                    SslStream sslStream = null;
                    //Pinned certificate clients cannot be proxied
                    //Example dropbox.com uses certificate pinning
                    //So just relay the request after identifying it by first failure
                    if (!pinnedCertificateClients.Contains(tunnelHostName))
                    {

                        try
                        {
                            sslStream = new SslStream(clientStream, true);
                            //Successfully managed to authenticate the client using the fake certificate
                            sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, false);

                            clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
                            clientStreamWriter = new StreamWriter(sslStream);
                            //HTTPS server created - we can now decrypt the client's traffic
                            clientStream = sslStream;
                        }

                        catch
                        {
                            //if authentication failed it could be because client uses pinned certificates
                            //So add the hostname to this list so that next time we can relay without touching it (tunnel the request)
                            if (pinnedCertificateClients.Contains(tunnelHostName) == false)
                            {
                                pinnedCertificateClients.Add(tunnelHostName);
                            }

                            if (sslStream != null)
                                sslStream.Dispose();

                            throw;
                        }

                    }
                    else
                    {
                        //Hostname was a previously failed request due to certificate pinning, just relay (tunnel the request)
                        TcpHelper.SendRaw(tunnelHostName, tunnelPort, clientStreamReader.BaseStream);

                        if (clientStreamReader != null)
                            clientStreamReader.Dispose();

                        if (clientStreamWriter != null)
                            clientStreamWriter.Dispose();

                        if (clientStream != null)
                            clientStream.Dispose();

                        if (client != null)
                            client.Close();

                        return;
                    }

                    while (!String.IsNullOrEmpty(tmpLine = clientStreamReader.ReadLine()))
                    {
                        requestLines.Add(tmpLine);
                    }

                    //read the new http command.
                    httpCmd = requestLines.Count > 0 ? requestLines[0] : null;
                    if (String.IsNullOrEmpty(httpCmd))
                    {
                        throw new EndOfStreamException();
                    }

                    securehost = remoteUri;
                }

                //Now create the request
                Task.Factory.StartNew(() => HandleHttpSessionRequest(client, httpCmd, clientStream, tunnelHostName, requestLines, clientStreamReader, clientStreamWriter, securehost));

            }
            catch
            {
                if (clientStreamReader != null)
                    clientStreamReader.Dispose();

                if (clientStreamWriter != null)
                    clientStreamWriter.Dispose();

                if (clientStream != null)
                    clientStream.Dispose();

                if (client != null)
                    client.Close();
            }
        }
Example #11
0
        public static void SendRaw(Stream clientStream, string httpCmd, List<HttpHeader> requestHeaders, string hostName,
            int tunnelPort, bool isHttps)
        {
            StringBuilder sb = null;
            if (httpCmd != null || requestHeaders != null)
            {
                sb = new StringBuilder();
                if (httpCmd != null)
                {
                    sb.Append(httpCmd);
                    sb.Append(Environment.NewLine);
                }
                if (requestHeaders != null)
                    foreach (var header in requestHeaders.Select(t => t.ToString()))
                    {
                        sb.Append(header);
                        sb.Append(Environment.NewLine);
                    }
                sb.Append(Environment.NewLine);
            }


            TcpClient tunnelClient = null;
            Stream tunnelStream = null;

            try
            {
                tunnelClient = new TcpClient(hostName, tunnelPort);
                tunnelStream = tunnelClient.GetStream();

                if (isHttps)
                {
                    SslStream sslStream = null;
                    try
                    {
                        sslStream = new SslStream(tunnelStream);
                        sslStream.AuthenticateAsClient(hostName);
                        tunnelStream = sslStream;
                    }
                    catch
                    {
                        if (sslStream != null)
                            sslStream.Dispose();

                        throw;
                    }
                }


                var sendRelay = Task.Factory.StartNew(() =>
                {
                    if (sb != null)
                        clientStream.CopyToAsync(sb.ToString(), tunnelStream, BUFFER_SIZE);
                    else
                        clientStream.CopyToAsync(tunnelStream, BUFFER_SIZE);
                });

                var receiveRelay = Task.Factory.StartNew(() => tunnelStream.CopyToAsync(clientStream, BUFFER_SIZE));

                Task.WaitAll(sendRelay, receiveRelay);
            }
            catch
            {
                if (tunnelStream != null)
                {
                    tunnelStream.Close();
                    tunnelStream.Dispose();
                }

                if (tunnelClient != null)
                    tunnelClient.Close();

                throw;
            }
        }
        private static bool TryConnect(out TcpClient tcpClient, out SslStream stream, string ip, int port)
        {
            tcpClient = null;
            stream = null;

            var client = new TcpClient();
            try
            {
                var result = client.BeginConnect(ip, port, null, null);
                var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(3));
                if (!success)
                    return false;

                client.EndConnect(result);
            }
            catch (Exception)
            {
                return false;
            }

            var sslStream = new SslStream(client.GetStream(), false, UserCertificateValidationCallback);

            try
            {
                var serverName = Environment.MachineName;
                sslStream.AuthenticateAsClient(serverName);
            }
            catch (AuthenticationException)
            {
                sslStream.Dispose();
                client.Close();
                return false;
            }

            tcpClient = client;
            stream = sslStream;
            return true;
        }
Example #13
0
        /// <summary>
        /// Sets up a connection to APNS and initializes the thread for sending notifications
        /// </summary>
        void _Connect()
        {
            var configuration = ApnsServiceConfiguration.GetConfiguration ();
            _certificate = new X509Certificate2 (File.ReadAllBytes (configuration.Certificate), configuration.Password,
                X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            try {
                if (!_connection.IsNullOrDefault ())
                    _connection.Close ();

            #if DEBUG
                NSLogger.Log (NSLogLevel.Info, "Connecting to APNS...");
            #endif
                _connection = new TcpClient (apnsHostName, 2195);

                if (!_sslStream.IsNullOrDefault ())
                    _sslStream.Close ();

                _sslStream = new SslStream (_connection.GetStream (), false,
                        new RemoteCertificateValidationCallback ((sender, cert, chain, sslPolicyErrors) => { return true; }),
                        new LocalCertificateSelectionCallback ((sender, targetHost, localCerts, remoteCert, acceptableIssuers) => {
                            return _certificate;
                        }));

                var certificates = new X509CertificateCollection { _certificate };
                _sslStream.AuthenticateAsClient (apnsHostName, certificates, SslProtocols.Ssl3, false);

                if (!_sslStream.IsMutuallyAuthenticated)
                    throw new ApplicationException ("SSL Stream Failed to Authenticate", null);

                if (!_sslStream.CanWrite)
                    throw new ApplicationException ("SSL Stream is not Writable", null);

            #if DEBUG
                NSLogger.Log (NSLogLevel.Info, "Connected!");
            #endif

            } catch (Exception) {
                if (_connection.Connected) {
                    _connection.Close ();
                }

                if (!_sslStream.IsNullOrDefault ()) {
                    _sslStream.Close ();
                    _sslStream.Dispose ();
                }
                throw;
            }
        }
Example #14
0
        public void Run(ApplePushChannelSettings settings, CancellationToken cancelToken)
        {
            var encoding = Encoding.ASCII;

            var certificate = settings.Certificate;

            var certificates = new X509CertificateCollection();
            certificates.Add(certificate);

            var client = new TcpClient(settings.FeedbackHost, settings.FeedbackPort);

            var stream = new SslStream(client.GetStream(), true,
                (sender, cert, chain, sslErrs) => { return true; },
                (sender, targetHost, localCerts, remoteCert, acceptableIssuers) => { return certificate; });

            stream.AuthenticateAsClient(settings.FeedbackHost, certificates, System.Security.Authentication.SslProtocols.Ssl3, false);

            //Set up
            byte[] buffer = new byte[38];
            int recd = 0;
            DateTime minTimestamp = DateTime.Now.AddYears(-1);

            //Get the first feedback
            recd = stream.Read(buffer, 0, buffer.Length);

            //Continue while we have results and are not disposing
            while (recd > 0 && !cancelToken.IsCancellationRequested)
            {
                try
                {

                    //Get our seconds since 1970 ?
                    byte[] bSeconds = new byte[4];
                    byte[] bDeviceToken = new byte[32];

                    Array.Copy(buffer, 0, bSeconds, 0, 4);

                    //Check endianness
                    if (BitConverter.IsLittleEndian)
                        Array.Reverse(bSeconds);

                    int tSeconds = BitConverter.ToInt32(bSeconds, 0);

                    //Add seconds since 1970 to that date, in UTC
                    var timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(tSeconds);

                    //flag to allow feedback times in UTC or local, but default is local
                    if (!settings.FeedbackTimeIsUTC)
                        timestamp = timestamp.ToLocalTime();

                    //Now copy out the device token
                    Array.Copy(buffer, 6, bDeviceToken, 0, 32);

                    var deviceToken = BitConverter.ToString(bDeviceToken).Replace("-", "").ToLower().Trim();

                    //Make sure we have a good feedback tuple
                    if (deviceToken.Length == 64
                        && timestamp > minTimestamp)
                    {
                        //Raise event
                        RaiseFeedbackReceived(deviceToken, timestamp);
                    }

                }
                catch { }

                //Clear our array to reuse it
                Array.Clear(buffer, 0, buffer.Length);

                //Read the next feedback
                recd = stream.Read(buffer, 0, buffer.Length);
            }

            try
            {
                stream.Close ();
                stream.Dispose();
            }
            catch { }

            try
            {
                client.Client.Shutdown (SocketShutdown.Both);
                client.Client.Dispose ();
            }
            catch { }

            try { client.Close (); } catch { }
        }
Example #15
0
		/// <summary>
		/// Establish a connection to the specified IMAP or IMAP/S server using the provided socket.
		/// </summary>
		/// <remarks>
		/// <para>Establishes a connection to the specified IMAP or IMAP/S server using
		/// the provided socket.</para>
		/// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the
		/// <paramref name="options"/> parameter is used to determine the default port to
		/// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/>
		/// is <c>993</c>. All other values will use a default port of <c>143</c>.</para>
		/// <para>If the <paramref name="options"/> has a value of
		/// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used
		/// to determine the default security options. If the <paramref name="port"/> has a value
		/// of <c>993</c>, then the default options used will be
		/// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use
		/// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para>
		/// <para>Once a connection is established, properties such as
		/// <see cref="AuthenticationMechanisms"/> and <see cref="Capabilities"/> will be
		/// populated.</para>
		/// </remarks>
		/// <param name="socket">The socket to use for the connection.</param>
		/// <param name="host">The host name to connect to.</param>
		/// <param name="port">The port to connect to. If the specified port is <c>0</c>, then the default port will be used.</param>
		/// <param name="options">The secure socket options to when connecting.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="socket"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="host"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <para><paramref name="socket"/> is not connected.</para>
		/// <para>-or-</para>
		/// The <paramref name="host"/> is a zero-length string.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="ImapClient"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="ImapClient"/> is already connected.
		/// </exception>
		/// <exception cref="System.NotSupportedException">
		/// <paramref name="options"/> was set to
		/// <see cref="MailKit.Security.SecureSocketOptions.StartTls"/>
		/// and the IMAP server does not support the STARTTLS extension.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ImapProtocolException">
		/// An IMAP protocol error occurred.
		/// </exception>
		public void Connect (Socket socket, string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken))
		{
			if (socket == null)
				throw new ArgumentNullException (nameof (socket));

			if (!socket.Connected)
				throw new ArgumentException ("The socket is not connected.", nameof (socket));

			if (host == null)
				throw new ArgumentNullException (nameof (host));

			if (host.Length == 0)
				throw new ArgumentException ("The host name cannot be empty.", nameof (host));

			if (port < 0 || port > 65535)
				throw new ArgumentOutOfRangeException (nameof (port));

			CheckDisposed ();

			if (IsConnected)
				throw new InvalidOperationException ("The ImapClient is already connected.");
			
			Stream stream;
			bool starttls;
			Uri uri;

			ComputeDefaultValues (host, ref port, ref options, out uri, out starttls);

			engine.Uri = uri;

			if (options == SecureSocketOptions.SslOnConnect) {
				var ssl = new SslStream (new NetworkStream (socket, true), false, ValidateRemoteCertificate);

				try {
#if COREFX
					ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
					ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
				} catch {
					ssl.Dispose ();
					throw;
				}

				secure = true;
				stream = ssl;
			} else {
				stream = new NetworkStream (socket, true);
				secure = false;
			}

			if (stream.CanTimeout) {
				stream.WriteTimeout = timeout;
				stream.ReadTimeout = timeout;
			}

			ProtocolLogger.LogConnect (uri);

			engine.Connect (new ImapStream (stream, socket, ProtocolLogger), cancellationToken);

			try {
				// Only query the CAPABILITIES if the greeting didn't include them.
				if (engine.CapabilitiesVersion == 0)
					engine.QueryCapabilities (cancellationToken);
				
				if (options == SecureSocketOptions.StartTls && (engine.Capabilities & ImapCapabilities.StartTLS) == 0)
					throw new NotSupportedException ("The IMAP server does not support the STARTTLS extension.");
				
				if (starttls && (engine.Capabilities & ImapCapabilities.StartTLS) != 0) {
					var ic = engine.QueueCommand (cancellationToken, null, "STARTTLS\r\n");

					engine.Wait (ic);

					ProcessResponseCodes (ic);

					if (ic.Response == ImapCommandResponse.Ok) {
						var tls = new SslStream (stream, false, ValidateRemoteCertificate);
#if COREFX
						tls.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
						tls.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
						engine.Stream.Stream = tls;

						secure = true;

						// Query the CAPABILITIES again if the server did not include an
						// untagged CAPABILITIES response to the STARTTLS command.
						if (engine.CapabilitiesVersion == 1)
							engine.QueryCapabilities (cancellationToken);
					} else if (options == SecureSocketOptions.StartTls) {
						throw ImapCommandException.Create ("STARTTLS", ic);
					}
				}
			} catch {
				engine.Disconnect ();
				secure = false;
				throw;
			}

			engine.Disconnected += OnEngineDisconnected;
			OnConnected ();
		}
Example #16
0
		/// <summary>
		/// Establish a connection to the specified IMAP server.
		/// </summary>
		/// <remarks>
		/// <para>Establishes a connection to the specified IMAP or IMAP/S server.</para>
		/// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the
		/// <paramref name="options"/> parameter is used to determine the default port to
		/// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/>
		/// is <c>993</c>. All other values will use a default port of <c>143</c>.</para>
		/// <para>If the <paramref name="options"/> has a value of
		/// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used
		/// to determine the default security options. If the <paramref name="port"/> has a value
		/// of <c>993</c>, then the default options used will be
		/// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use
		/// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para>
		/// <para>Once a connection is established, properties such as
		/// <see cref="AuthenticationMechanisms"/> and <see cref="Capabilities"/> will be
		/// populated.</para>
		/// </remarks>
		/// <example>
		/// <code language="c#" source="Examples\ImapExamples.cs" region="DownloadMessages"/>
		/// </example>
		/// <param name="host">The host name to connect to.</param>
		/// <param name="port">The port to connect to. If the specified port is <c>0</c>, then the default port will be used.</param>
		/// <param name="options">The secure socket options to when connecting.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="host"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// The <paramref name="host"/> is a zero-length string.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="ImapClient"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="ImapClient"/> is already connected.
		/// </exception>
		/// <exception cref="System.NotSupportedException">
		/// <paramref name="options"/> was set to
		/// <see cref="MailKit.Security.SecureSocketOptions.StartTls"/>
		/// and the IMAP server does not support the STARTTLS extension.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <exception cref="System.Net.Sockets.SocketException">
		/// A socket error occurred trying to connect to the remote host.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ImapProtocolException">
		/// An IMAP protocol error occurred.
		/// </exception>
		public override void Connect (string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken))
		{
			if (host == null)
				throw new ArgumentNullException (nameof (host));

			if (host.Length == 0)
				throw new ArgumentException ("The host name cannot be empty.", nameof (host));

			if (port < 0 || port > 65535)
				throw new ArgumentOutOfRangeException (nameof (port));

			CheckDisposed ();

			if (IsConnected)
				throw new InvalidOperationException ("The ImapClient is already connected.");

			Stream stream;
			bool starttls;
			Uri uri;

			ComputeDefaultValues (host, ref port, ref options, out uri, out starttls);

#if !NETFX_CORE
#if COREFX
			var ipAddresses = Dns.GetHostAddressesAsync (uri.DnsSafeHost).GetAwaiter ().GetResult ();
#else
			var ipAddresses = Dns.GetHostAddresses (uri.DnsSafeHost);
#endif
			Socket socket = null;

			for (int i = 0; i < ipAddresses.Length; i++) {
				socket = new Socket (ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp) {
					ReceiveTimeout = timeout,
					SendTimeout = timeout
				};

				try {
					cancellationToken.ThrowIfCancellationRequested ();

					if (LocalEndPoint != null)
						socket.Bind (LocalEndPoint);

					socket.Connect (ipAddresses[i], port);
					break;
				} catch (OperationCanceledException) {
					socket.Dispose ();
					throw;
				} catch {
					socket.Dispose ();

					if (i + 1 == ipAddresses.Length)
						throw;
				}
			}

			if (socket == null)
				throw new IOException (string.Format ("Failed to resolve host: {0}", host));
			
			engine.Uri = uri;

			if (options == SecureSocketOptions.SslOnConnect) {
				var ssl = new SslStream (new NetworkStream (socket, true), false, ValidateRemoteCertificate);

				try {
#if COREFX
					ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
					ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
				} catch {
					ssl.Dispose ();
					throw;
				}

				secure = true;
				stream = ssl;
			} else {
				stream = new NetworkStream (socket, true);
				secure = false;
			}
#else
			var protection = options == SecureSocketOptions.SslOnConnect ? SocketProtectionLevel.Tls12 : SocketProtectionLevel.PlainSocket;
			socket = new StreamSocket ();

			try {
				cancellationToken.ThrowIfCancellationRequested ();
				socket.ConnectAsync (new HostName (host), port.ToString (), protection)
					.AsTask (cancellationToken)
					.GetAwaiter ()
					.GetResult ();
			} catch {
				socket.Dispose ();
				socket = null;
				throw;
			}

			stream = new DuplexStream (socket.InputStream.AsStreamForRead (0), socket.OutputStream.AsStreamForWrite (0));
			secure = options == SecureSocketOptions.SslOnConnect;
			engine.Uri = uri;
#endif

			if (stream.CanTimeout) {
				stream.WriteTimeout = timeout;
				stream.ReadTimeout = timeout;
			}

			ProtocolLogger.LogConnect (uri);

			engine.Connect (new ImapStream (stream, socket, ProtocolLogger), cancellationToken);

			try {
				// Only query the CAPABILITIES if the greeting didn't include them.
				if (engine.CapabilitiesVersion == 0)
					engine.QueryCapabilities (cancellationToken);
				
				if (options == SecureSocketOptions.StartTls && (engine.Capabilities & ImapCapabilities.StartTLS) == 0)
					throw new NotSupportedException ("The IMAP server does not support the STARTTLS extension.");
				
				if (starttls && (engine.Capabilities & ImapCapabilities.StartTLS) != 0) {
					var ic = engine.QueueCommand (cancellationToken, null, "STARTTLS\r\n");

					engine.Wait (ic);

					ProcessResponseCodes (ic);

					if (ic.Response == ImapCommandResponse.Ok) {
#if !NETFX_CORE
						var tls = new SslStream (stream, false, ValidateRemoteCertificate);
#if COREFX
						tls.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
						tls.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
						engine.Stream.Stream = tls;
#else
						socket.UpgradeToSslAsync (SocketProtectionLevel.Tls12, new HostName (host))
							.AsTask (cancellationToken)
							.GetAwaiter ()
							.GetResult ();
#endif

						secure = true;

						// Query the CAPABILITIES again if the server did not include an
						// untagged CAPABILITIES response to the STARTTLS command.
						if (engine.CapabilitiesVersion == 1)
							engine.QueryCapabilities (cancellationToken);
					} else if (options == SecureSocketOptions.StartTls) {
						throw ImapCommandException.Create ("STARTTLS", ic);
					}
				}
			} catch {
				engine.Disconnect ();
				secure = false;
				throw;
			}

			engine.Disconnected += OnEngineDisconnected;
			OnConnected ();
		}
Example #17
0
		public void Run(ApplePushChannelSettings settings, CancellationToken cancelToken)
		{
			var encoding = Encoding.ASCII;

			var certificate = settings.Certificate;

			var certificates = new X509CertificateCollection();
			certificates.Add(certificate);


			var client = new TcpClient(settings.FeedbackHost, settings.FeedbackPort);

			var stream = new SslStream(client.GetStream(), true,
				(sender, cert, chain, sslErrs) => { return true; },
				(sender, targetHost, localCerts, remoteCert, acceptableIssuers) => { return certificate; });

			stream.AuthenticateAsClient(settings.FeedbackHost, certificates, System.Security.Authentication.SslProtocols.Tls, false);


			//Set up
			byte[] buffer = new byte[1482];
			int bufferIndex = 0;
			int bufferLevel = 0;
			int completePacketSize = 4 + 2 + 32;
			int recd = 0;
			DateTime minTimestamp = DateTime.Now.AddYears(-1);

			//Get the first feedback
			recd = stream.Read(buffer, 0, buffer.Length);

			//Continue while we have results and are not disposing
			while (recd > 0 && !cancelToken.IsCancellationRequested)
			{
				//Update how much data is in the buffer, and reset the position to the beginning
				bufferLevel += recd;
				bufferIndex = 0;

				try
				{
					//Process each complete notification "packet" available in the buffer
					while (bufferLevel - bufferIndex >= completePacketSize)
					{
						//Get our seconds since 1970 ?
						byte[] bSeconds = new byte[4];
						byte[] bDeviceToken = new byte[32];

						Array.Copy(buffer, bufferIndex, bSeconds, 0, 4);

						//Check endianness
						if (BitConverter.IsLittleEndian)
							Array.Reverse(bSeconds);

						int tSeconds = BitConverter.ToInt32(bSeconds, 0);

						//Add seconds since 1970 to that date, in UTC
						var timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(tSeconds);

						//flag to allow feedback times in UTC or local, but default is local
						if (!settings.FeedbackTimeIsUTC)
							timestamp = timestamp.ToLocalTime();

						//Now copy out the device token
						Array.Copy(buffer, bufferIndex + 6, bDeviceToken, 0, 32);

						var deviceToken = BitConverter.ToString(bDeviceToken).Replace("-", "").ToLower().Trim();

						//Make sure we have a good feedback tuple
						if (deviceToken.Length == 64
							&& timestamp > minTimestamp)
						{
							//Raise event
							try
							{
								RaiseFeedbackReceived(deviceToken, timestamp);
							}
							catch { }
						}

						//Keep track of where we are in the received data buffer
						bufferIndex += completePacketSize;
					}
				}
				catch { }

				//Figure out how much data we have left over in the buffer still
				bufferLevel -= bufferIndex;

				//Copy any leftover data in the buffer to the start of the buffer
				if (bufferLevel > 0)
					Array.Copy(buffer, bufferIndex, buffer, 0, bufferLevel);

				//Read the next feedback
				recd = stream.Read(buffer, bufferLevel, buffer.Length - bufferLevel);
			}

			try
			{
				stream.Close ();
				stream.Dispose();
			}
			catch { }

			try 
			{
				client.Client.Shutdown (SocketShutdown.Both);
				client.Client.Dispose ();
			}
			catch { }

			try { client.Close (); } catch { }

		}
Example #18
0
        public static async Task<EpoxyNetworkStream> MakeServerStreamAsync(
            Socket socket,
            EpoxyServerTlsConfig tlsConfig,
            Logger logger)
        {
            Stream serverStream;
            var networkStream = new NetworkStream(socket, ownsSocket: false);

            if (tlsConfig == null)
            {
                serverStream = networkStream;
            }
            else
            {
                const bool leaveInnerStreamOpen = false;

                var sslStream = new SslStream(
                    networkStream,
                    leaveInnerStreamOpen,
                    MakeServerCertificateValidationCallback(tlsConfig, logger));

                await sslStream.AuthenticateAsServerAsync(
                    tlsConfig.Certificate,
                    tlsConfig.ClientCertificateRequired,
                    enabledSslProtocols: AllowedTlsProtocols,
                    checkCertificateRevocation: tlsConfig.CheckCertificateRevocation);

                if (tlsConfig.ClientCertificateRequired && !sslStream.IsMutuallyAuthenticated)
                {
                    sslStream.Dispose();
                    throw new AuthenticationException("Mutual authentication was required, but it could not be performed.");
                }

                logger.Site().Debug(
                    "Authenticated connection from {0}. Mutually authenticated?: {1}",
                    socket.RemoteEndPoint,
                    sslStream.IsMutuallyAuthenticated);

                serverStream = sslStream;
            }

            return new EpoxyNetworkStream(socket, serverStream, logger);
        }
Example #19
0
		/// <summary>
		/// Establishes a connection to the specified SMTP or SMTP/S server.
		/// </summary>
		/// <remarks>
		/// <para>Establishes a connection to the specified SMTP or SMTP/S server.</para>
		/// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the
		/// <paramref name="options"/> parameter is used to determine the default port to
		/// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/>
		/// is <c>465</c>. All other values will use a default port of <c>25</c>.</para>
		/// <para>If the <paramref name="options"/> has a value of
		/// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used
		/// to determine the default security options. If the <paramref name="port"/> has a value
		/// of <c>465</c>, then the default options used will be
		/// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use
		/// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para>
		/// <para>Once a connection is established, properties such as
		/// <see cref="AuthenticationMechanisms"/> and <see cref="Capabilities"/> will be
		/// populated.</para>
		/// <note type="note">The connection established by any of the
		/// <a href="Overload_MailKit_Net_Smtp_SmtpClient_Connect.htm">Connect</a>
		/// methods may be re-used if an application wishes to send multiple messages
		/// to the same SMTP server. Since connecting and authenticating can be expensive
		/// operations, re-using a connection can significantly improve performance when
		/// sending a large number of messages to the same SMTP server over a short
		/// period of time.</note>
		/// </remarks>
		/// <example>
		/// <code language="c#" source="Examples\SmtpExamples.cs" region="SendMessage"/>
		/// </example>
		/// <param name="host">The host name to connect to.</param>
		/// <param name="port">The port to connect to. If the specified port is <c>0</c>, then the default port will be used.</param>
		/// <param name="options">The secure socket options to when connecting.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="host"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// The <paramref name="host"/> is a zero-length string.
		/// </exception>
		/// <exception cref="System.ObjectDisposedException">
		/// The <see cref="SmtpClient"/> has been disposed.
		/// </exception>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="SmtpClient"/> is already connected.
		/// </exception>
		/// <exception cref="System.NotSupportedException">
		/// <paramref name="options"/> was set to
		/// <see cref="MailKit.Security.SecureSocketOptions.StartTls"/>
		/// and the SMTP server does not support the STARTTLS extension.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled.
		/// </exception>
		/// <exception cref="System.Net.Sockets.SocketException">
		/// A socket error occurred trying to connect to the remote host.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="SmtpCommandException">
		/// An SMTP command failed.
		/// </exception>
		/// <exception cref="SmtpProtocolException">
		/// An SMTP protocol error occurred.
		/// </exception>
		public override void Connect (string host, int port = 0, SecureSocketOptions options = SecureSocketOptions.Auto, CancellationToken cancellationToken = default (CancellationToken))
		{
			if (host == null)
				throw new ArgumentNullException (nameof (host));

			if (host.Length == 0)
				throw new ArgumentException ("The host name cannot be empty.", nameof (host));

			if (port < 0 || port > 65535)
				throw new ArgumentOutOfRangeException (nameof (port));
			
			CheckDisposed ();

			if (IsConnected)
				throw new InvalidOperationException ("The SmtpClient is already connected.");

			capabilities = SmtpCapabilities.None;
			AuthenticationMechanisms.Clear ();
			MaxSize = 0;

			SmtpResponse response;
			Stream stream;
			bool starttls;
			Uri uri;

			ComputeDefaultValues (host, ref port, ref options, out uri, out starttls);

#if !NETFX_CORE
#if COREFX
			var ipAddresses = Dns.GetHostAddressesAsync (uri.DnsSafeHost).GetAwaiter ().GetResult ();
#else
			var ipAddresses = Dns.GetHostAddresses (uri.DnsSafeHost);
#endif
			Socket socket = null;

			for (int i = 0; i < ipAddresses.Length; i++) {
				socket = new Socket (ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp) {
					ReceiveTimeout = timeout,
					SendTimeout = timeout
				};

				try {
					cancellationToken.ThrowIfCancellationRequested ();

					if (LocalEndPoint != null)
						socket.Bind (LocalEndPoint);

					socket.Connect (ipAddresses[i], port);
					break;
				} catch (OperationCanceledException) {
					socket.Dispose ();
					socket = null;
					throw;
				} catch {
					socket.Dispose ();
					socket = null;

					if (i + 1 == ipAddresses.Length)
						throw;
				}
			}

			if (socket == null)
				throw new IOException (string.Format ("Failed to resolve host: {0}", host));

			this.host = host;

			if (options == SecureSocketOptions.SslOnConnect) {
				var ssl = new SslStream (new NetworkStream (socket, true), false, ValidateRemoteCertificate);

				try {
#if COREFX
					ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
					ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
				} catch {
					ssl.Dispose ();
					throw;
				}

				secure = true;
				stream = ssl;
			} else {
				stream = new NetworkStream (socket, true);
				secure = false;
			}
#else
			var protection = options == SecureSocketOptions.SslOnConnect ? SocketProtectionLevel.Tls12 : SocketProtectionLevel.PlainSocket;
			var socket = new StreamSocket ();

			try {
				cancellationToken.ThrowIfCancellationRequested ();
				socket.ConnectAsync (new HostName (host), port.ToString (), protection)
					.AsTask (cancellationToken)
					.GetAwaiter ()
					.GetResult ();
			} catch {
				socket.Dispose ();
				throw;
			}

			stream = new DuplexStream (socket.InputStream.AsStreamForRead (0), socket.OutputStream.AsStreamForWrite (0));
			secure = options == SecureSocketOptions.SslOnConnect;
			this.host = host;
#endif

			if (stream.CanTimeout) {
				stream.WriteTimeout = timeout;
				stream.ReadTimeout = timeout;
			}

			ProtocolLogger.LogConnect (uri);

			Stream = new SmtpStream (stream, socket, ProtocolLogger);

			try {
				// read the greeting
				response = Stream.ReadResponse (cancellationToken);

				if (response.StatusCode != SmtpStatusCode.ServiceReady)
					throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);

				// Send EHLO and get a list of supported extensions
				Ehlo (cancellationToken);

				if (options == SecureSocketOptions.StartTls && (capabilities & SmtpCapabilities.StartTLS) == 0)
					throw new NotSupportedException ("The SMTP server does not support the STARTTLS extension.");

				if (starttls && (capabilities & SmtpCapabilities.StartTLS) != 0) {
					response = SendCommand ("STARTTLS", cancellationToken);
					if (response.StatusCode != SmtpStatusCode.ServiceReady)
						throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);

#if !NETFX_CORE
					var tls = new SslStream (stream, false, ValidateRemoteCertificate);
#if COREFX
					tls.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, true).GetAwaiter ().GetResult ();
#else
					tls.AuthenticateAsClient (host, ClientCertificates, SslProtocols, true);
#endif
					Stream.Stream = tls;
#else
					socket.UpgradeToSslAsync (SocketProtectionLevel.Tls12, new HostName (host))
						.AsTask (cancellationToken)
						.GetAwaiter ()
						.GetResult ();
#endif

					secure = true;

					// Send EHLO again and get the new list of supported extensions
					Ehlo (cancellationToken);
				}

				connected = true;
			} catch {
				Stream.Dispose ();
				secure = false;
				Stream = null;
				throw;
			}

			OnConnected ();
		}
 /// <summary>
 /// Accept callback method for SSL connection.
 /// </summary>
 /// <param name="ar">The socket server</param>
 private void AcceptSSLCallback(IAsyncResult ar)
 {
     AbstractSocketServer server = (AbstractSocketServer)ar.AsyncState;
     SslStream sslStream = null;
     try
     {
         // Get the socket that handles the client request.
         TcpClient sslTcpClient = server.sslListener.EndAcceptTcpClient(ar);
         Trace.WriteLine("Start incoming ssl connection ...");
         sslStream = new SslStream(sslTcpClient.GetStream(), false, new RemoteCertificateValidationCallback(server.OnVerifyClientCertificate));
         sslStream.AuthenticateAsServer(server.serverCertificate, true, SslProtocols.Ssl3, false);
         Socket handler = sslTcpClient.Client;
         handler.Blocking = true;
         AbstractTcpSocketClientHandler clientHandler = this.GetHandler(handler, sslStream);
         clientHandler.KeepAlive = this.KeepAlive;
         clientHandler.ReceiveMessageEvent += new ReceiveMessageDelegate(server.OnReceiveMessage);
         clientHandler.CloseConnectionEvent += new SocketConnectionDelegate(server.clientHandler_CloseConnectionEvent);
         server.OnConnection(clientHandler);
         server.clientList.AddClient(this.GetClientInfo(clientHandler));
         clientHandler.StartReceive();
         Trace.WriteLine("New connection completed");
     }
     catch (Exception ex)
     {
         Trace.WriteLine(string.Format("Failed to accept incoming connection. Exception", ex));
         try
         {
             if (sslStream != null)
             {
                 sslStream.Close();
                 sslStream.Dispose();
             }
         }
         catch (Exception ex2)
         {
             Trace.WriteLine(ex2);
         }
     }
     finally
     {
         // Signal the main thread to continue.
         server.listenerCompleteConnectionEvent.Set();
     }
 }
Example #21
0
        public static void SendRaw(string httpCmd, string secureHostName, List<string> requestLines, bool isHttps, Stream clientStream)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(httpCmd);
            sb.Append(Environment.NewLine);

            string hostname = secureHostName;
            for (int i = 1; i < requestLines.Count; i++)
            {
                var header = requestLines[i];

                if (secureHostName == null)
                {
                    String[] headerParsed = httpCmd.Split(colonSpaceSplit, 2, StringSplitOptions.None);
                    switch (headerParsed[0].ToLower())
                    {
                        case "host":
                            var hostdetail = headerParsed[1];
                            if (hostdetail.Contains(":"))
                                hostname = hostdetail.Split(':')[0].Trim();
                            else
                                hostname = hostdetail.Trim();
                            break;
                        default:
                            break;
                    }
                }
                sb.Append(header);
                sb.Append(Environment.NewLine);
            }
            sb.Append(Environment.NewLine);

            int tunnelPort = 80;
            if (isHttps)
            {

                tunnelPort = 443;

            }

            System.Net.Sockets.TcpClient tunnelClient = null;
            Stream tunnelStream = null;
            try
            {
                tunnelClient = new System.Net.Sockets.TcpClient(hostname, tunnelPort);
                tunnelStream = tunnelClient.GetStream() as Stream;

                if (isHttps)
                {
                    SslStream sslStream = null;
                    try
                    {
                        sslStream = new SslStream(tunnelStream);
                        sslStream.AuthenticateAsClient(hostname);
                        tunnelStream = sslStream;
                    }
                    catch
                    {
                        if (sslStream != null)
                            sslStream.Dispose();
                    }
                }

                var sendRelay = new Task(() => StreamHelper.CopyTo(sb.ToString(), clientStream, tunnelStream, BUFFER_SIZE));
                var receiveRelay = new Task(() => StreamHelper.CopyTo(tunnelStream, clientStream, BUFFER_SIZE));

                sendRelay.Start();
                receiveRelay.Start();

                Task.WaitAll(sendRelay, receiveRelay);
            }
            catch
            {
                if (tunnelStream != null)
                {
                    tunnelStream.Close();
                    tunnelStream.Dispose();
                }

                if (tunnelClient != null)
                    tunnelClient.Close();

                throw;
            }
        }
        private static void HandleClient(TcpClient client)
        {
            Stream clientStream = client.GetStream();
            var clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII);
            var clientStreamWriter = new StreamWriter(clientStream);

            Uri httpRemoteUri;
            try
            {
                //read the first line HTTP command

                var httpCmd = clientStreamReader.ReadLine();

                if (string.IsNullOrEmpty(httpCmd))
                {
                    Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
                    return;
                }

                //break up the line into three components (method, remote URL & Http Version)
                var httpCmdSplit = httpCmd.Split(SpaceSplit, 3);

                var httpVerb = httpCmdSplit[0];

                if (httpVerb.ToUpper() == "CONNECT")
                    httpRemoteUri = new Uri("http://" + httpCmdSplit[1]);
                else
                    httpRemoteUri = new Uri(httpCmdSplit[1]);

                var httpVersion = httpCmdSplit[2];

                var excluded = ExcludedHttpsHostNameRegex.Any(x => Regex.IsMatch(httpRemoteUri.Host, x));

                //Client wants to create a secure tcp tunnel (its a HTTPS request)
                if (httpVerb.ToUpper() == "CONNECT" && !excluded && httpRemoteUri.Port == 443)
                {
                    httpRemoteUri = new Uri("https://" + httpCmdSplit[1]);
                    clientStreamReader.ReadAllLines();

                    WriteConnectResponse(clientStreamWriter, httpVersion);

                    var certificate = CertManager.CreateCertificate(httpRemoteUri.Host);

                    SslStream sslStream = null;

                    try
                    {
                        sslStream = new SslStream(clientStream, true);
                        //Successfully managed to authenticate the client using the fake certificate
                        sslStream.AuthenticateAsServer(certificate, false,
                            SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, false);

                        clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII);
                        clientStreamWriter = new StreamWriter(sslStream);
                        //HTTPS server created - we can now decrypt the client's traffic
                        clientStream = sslStream;
                    }

                    catch
                    {
                        if (sslStream != null)
                            sslStream.Dispose();

                        Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
                        return;
                    }


                    httpCmd = clientStreamReader.ReadLine();

                }
                else if (httpVerb.ToUpper() == "CONNECT")
                {
                    clientStreamReader.ReadAllLines();
                    WriteConnectResponse(clientStreamWriter, httpVersion);
                    TcpHelper.SendRaw(clientStreamReader.BaseStream, null, null, httpRemoteUri.Host, httpRemoteUri.Port,
                        false);
                    Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
                    return;
                }

                //Now create the request
                HandleHttpSessionRequest(client, httpCmd, clientStream, clientStreamReader, clientStreamWriter,
                    httpRemoteUri.Scheme == Uri.UriSchemeHttps ? httpRemoteUri.OriginalString : null);
            }
            catch
            {
                Dispose(client, clientStream, clientStreamReader, clientStreamWriter, null);
            }
        }
Example #23
0
 // guarantees to close the socket on error
 public static void TlsConnect(Socket sock, string host, RemoteCertificateValidationCallback rcvc, Action<Exception,SslStream> cb)
 {
     SslStream ssl = null;
     try {
         ssl = new SslStream (new NetworkStream (sock, true), false, rcvc);
         ssl.BeginAuthenticateAsClient (host, (ar) => {
             try {
                 ssl.EndAuthenticateAsClient (ar);
             } catch (Exception ex) {
                 ssl.Dispose ();
                 sock.Dispose ();
                 cb (ex, null);
                 return;
             }
             cb (null, ssl);
         }, null);
     } catch (Exception ex) {
         if (ssl != null)
             ssl.Dispose ();
         sock.Dispose ();
         cb (ex, null);
     }
 }
Example #24
0
        private bool ConnectSync(string sHost, int nPort)
        {
            bool result = false;
            try
            {
                var imapServer = new TcpClient(sHost, nPort);
                _imapSslStream = new SslStream(imapServer.GetStream(), false, ValidateServerCertificate, null);

                try
                {
                    _imapSslStream.AuthenticateAsClient(sHost, null, SslProtocols.Default, false);
                }
                catch (AuthenticationException authEx)
                {
                    _logger.Warn(authEx, "Authentication failed");
                    _imapSslStream.Dispose();
                    imapServer.Close();
                    return false;
                }
                _imapSslStreamReader = new StreamReader(_imapSslStream);
                var text = _imapSslStreamReader.ReadLine();
                if (text != null && text.StartsWith("* OK"))
                {
                    result = Capability();
                }
            }
            catch (IOException ioEx)
            {
                _logger.Warn(ioEx, "Failed to connect");
            }
            return result;
        }
Example #25
0
        public MFTestResults RunClient()
        {
             MFTestResults testResult = MFTestResults .Pass;
            try
            {
                if (ipAddress == null)
                    Console.WriteLine("IpAddress must be initialized before calling RunClient()");
                else
                    serverEp = new IPEndPoint(ipAddress, port);

                IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress localAddr = null;
                foreach (IPAddress addr in hostEntry.AddressList)
                {
                    if (addr.AddressFamily == AddressFamily.InterNetwork)
                    {
                        localAddr = addr;
                    }
                }

                IPEndPoint localEnpoint = new IPEndPoint(localAddr, port);

                Console.WriteLine("Connect to IPAddress: " + serverEp.Address.ToString() + " Port Number: " + serverEp.Port.ToString());

                // Create a TCP/IP client socket.
                bool connected = false;
                int retries = 0;
                while (!connected)
                {
                    try
                    {

                        clientSocket = new TcpClient(localEnpoint);
                        clientSocket.Connect(serverEp);
                        connected = true;
                    }
                    catch { }

                    Thread.Sleep(1000);
                    retries++;
                    if (retries > 20)
                    {
                        Console.WriteLine("Tried to connect 20 times without success.  Failing test.");
                        return MFTestResults.Fail;
                    }
                }

                // Create an SSL stream that will close the client's stream.
                sslClient = new SslStream(clientSocket.GetStream());

                Console.WriteLine("Calling AuthenticateAsClient()");
                // The server name must match the name on the server certificate.
                sslClient.AuthenticateAsClient(targetHost, certificateCollection, sslProtocols, false);

                // Send hello message to the server. 
                byte[] message = Encoding.UTF8.GetBytes(messageSent);
                sslClient.Write(message, 0, message.Length);
                Console.WriteLine("Sent:     " + messageSent);

                // Read message from the server.
                messageReceived = ReadMessage(sslClient);
                Console.WriteLine("Received: " + messageReceived);

                if (messageSent != messageReceived)
                    testResult = MFTestResults.Fail;

            }
            catch (SocketException e)
            {
                if (!expectedException)
                    testResult = MFTestResults.Fail;
                Console.WriteLine("ErrorCode: " + e.ErrorCode);
                Console.WriteLine("An exception occurred: " + e.Message);
            }
            catch (Exception e)
            {
                if (!expectedException)
                    testResult = MFTestResults.Fail;
                Console.WriteLine("An exception occurred: " + e.Message);
            }
            finally
            {
                if (sslClient != null)
                {
                    Thread.Sleep(50);
                    sslClient.Dispose();
                    sslClient = null;
                }
                if (clientSocket != null)
                {
                    clientSocket.Close();
                    clientSocket = null;
                }
            }
            return testResult;
        }
Example #26
0
        public MFTestResults RunServer()
        {
            MFTestResults testResult = MFTestResults.Fail;
            SslStream sslStream = null;

            try
            {
                sslServer = new TcpListener(ipAddress, port);

                // Start listening for client requests.
                sslServer.Start();

                // Buffer for reading data
                Byte[] bytes = new Byte[2048];
                String data = null;

                // Start Listening for a connection.
                Console.Write("Waiting for a connection... ");

                // Perform a blocking call to accept requests.
                // You could also user server.AcceptSocket() here.
                TcpClient client = sslServer.AcceptTcpClient();
                Console.WriteLine("Connected!");

                data = null;

                // Get a stream object for reading and writing
                sslStream = new SslStream(client.GetStream());

                sslStream.AuthenticateAsServer(certificate, clientCertificateRequired, enabledSslProtocols, false);

                TestUtilities.PrintSslStreamProperties(sslStream);

                int i = 0;
                // Loop to receive all the data sent by the client.
                while ((i = sslStream.Read(bytes, 0, bytes.Length)) != 0)
                {
                    // Translate data bytes to a string.
                    // The encoding used is application specific.
                    data = System.Text.Encoding.UTF8.GetString(bytes, 0, i);
                    Console.WriteLine("Received: {0}", data);

                    byte[] msg = System.Text.Encoding.UTF8.GetBytes(data);

                    // Send back a response.
                    sslStream.Write(msg, 0, msg.Length);
                    Console.WriteLine("Sent:     {0}", data);
                }
                testResult = MFTestResults.Pass;
            }
            catch (SocketException e)
            {
                if (expectedException)
                    testResult = MFTestResults.Pass;

                Console.WriteLine("SocketException in StartServer(): " + e.ToString());
                Console.WriteLine("ErrorCode: " + e.ErrorCode.ToString());
            }
            catch (Exception e)
            {
                if (expectedException)
                    testResult = MFTestResults.Pass;

                Console.WriteLine("Exception in StartServer(): " + e.ToString());
            }
            finally
            {
                if (sslStream != null)
                {
                    sslStream.Dispose();
                    sslStream = null;
                }
                if (sslServer != null)
                {
                    sslServer.Stop();
                    sslServer = null;
                }
            }

            return testResult;
        }
        public void Check ()
        {
            var encoding = Encoding.ASCII;

            var certificate = Configuration.Certificate;

            var certificates = new X509CertificateCollection();
            certificates.Add(certificate);

            var client = new TcpClient (Configuration.FeedbackHost, Configuration.FeedbackPort);

            var stream = new SslStream (client.GetStream(), true,
                (sender, cert, chain, sslErrs) => { return true; },
                (sender, targetHost, localCerts, remoteCert, acceptableIssuers) => { return certificate; });

            stream.AuthenticateAsClient(Configuration.FeedbackHost, certificates, System.Security.Authentication.SslProtocols.Tls, false);


            //Set up
            byte[] buffer = new byte[4096];
            int recd = 0;
            var data = new List<byte> ();

            //Get the first feedback
            recd = stream.Read(buffer, 0, buffer.Length);

            //Continue while we have results and are not disposing
            while (recd > 0)
            {
                // Add the received data to a list buffer to work with (easier to manipulate)
                for (int i = 0; i < recd; i++)
                    data.Add (buffer [i]);
                
                //Process each complete notification "packet" available in the buffer
                while (data.Count >= (4 + 2 + 32)) // Minimum size for a valid packet
                {
                    var secondsBuffer = data.GetRange (0, 4).ToArray ();
                    var tokenLengthBuffer = data.GetRange (4, 2).ToArray ();

                    // Get our seconds since epoch
                    // Check endianness and reverse if needed
                    if (BitConverter.IsLittleEndian)
                        Array.Reverse (secondsBuffer);
                    var seconds = BitConverter.ToInt32 (secondsBuffer, 0);

                    //Add seconds since 1970 to that date, in UTC
                    var timestamp = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds (seconds);

                    //flag to allow feedback times in UTC or local, but default is local
                    if (!Configuration.FeedbackTimeIsUTC)
                        timestamp = timestamp.ToLocalTime();


                    if (BitConverter.IsLittleEndian)
                        Array.Reverse (tokenLengthBuffer);
                    var tokenLength = BitConverter.ToInt16 (tokenLengthBuffer, 0);

                    if (data.Count >= 4 + 2 + tokenLength) {

                        var tokenBuffer = data.GetRange (6, tokenLength).ToArray ();
                        // Strings shouldn't care about endian-ness... this shouldn't be reversed
                        //if (BitConverter.IsLittleEndian)
                        //    Array.Reverse (tokenBuffer);
                        var token = BitConverter.ToString (tokenBuffer).Replace ("-", "").ToLower ().Trim ();

                        // Remove what we parsed from the buffer
                        data.RemoveRange (0, 4 + 2 + tokenLength);

                        // Raise the event to the consumer
                        var evt = FeedbackReceived;
                        if (evt != null)
                            evt (token, timestamp);
                    } else {
                        continue;
                    }

                }

                //Read the next feedback
                recd = stream.Read (buffer, 0, buffer.Length);
            }

            try
            {
                stream.Close ();
                stream.Dispose();
            }
            catch { }

            try 
            {
                client.Client.Shutdown (SocketShutdown.Both);
                client.Client.Dispose ();
            }
            catch { }

            try { client.Close (); } catch { }

        }