protected void OnConnectionAccepted(ForwardingConnection con)
 {
     if (ConnectionAccepted != null)
     {
         ConnectionAccepted(con);
     }
 }
Exemple #2
0
        private void con_ConnectionAborted(ConnectionData data, bool fromClient, Exception ex)
        {
            ForwardingConnection con = data.Connection;

            // This event can be raised multiple times (or the connection may already be closed),
            // therefore we need to to this check
            if (!data.IsAbortedOrClosed)
            {
                data.IsAbortedOrClosed = true;

                connectionCount--;
                RefreshConnectionCount();

                string reason = Environment.NewLine + GetExceptionText(ex);

                string logStr = "Connection aborted from " + (fromClient ? "client" : "server") + " \u2013 Data Offset: 0x" + data.DataCountLocal.ToString("X") + ". Reason: " + reason;
                AddLogEntry(logClient, con.ConId, logStr);
                logStr = "Connection aborted from " + (fromClient ? "client" : "server") + " \u2013 Data Offset: 0x" + data.DataCountRemote.ToString("X") + ". Reason: " + reason;
                AddLogEntry(logServer, con.ConId, logStr);

                if (logDataToFile)
                {
                    if (data.fileIncoming != null)
                    {
                        data.fileIncoming.Dispose();
                    }
                    if (data.fileOutgoing != null)
                    {
                        data.fileOutgoing.Dispose();
                    }
                }
            }
        }
Exemple #3
0
        private void con_DataReceivedRemote(ConnectionData data, byte[] buf, int offset, int count)
        {
            ForwardingConnection con = data.Connection;

            if (!data.IsAbortedOrClosed)
            {
                if (checkLogDataEvents.IsChecked.Value)
                {
                    AddLogEntry(logServer, con.ConId, "Data - Offset: 0x" + data.DataCountRemote.ToString("X") + ", Count: 0x" + count.ToString("X") + ".");
                }
                if (logDataContents && buf != null)
                {
                    AddDataLog(logServer, buf, offset, count);
                }

                data.DataCountRemote += count;

                currentDLCount += count;

                if (logDataToFile)
                {
                    data.fileOutgoing.Write(buf, offset, count);
                    data.fileOutgoing.Flush();
                }
            }
        }
Exemple #4
0
        private void con_DataForwardedRemote(ConnectionData data)
        {
            ForwardingConnection con = data.Connection;

            if (!data.IsAbortedOrClosed)
            {
                if (checkLogDataEvents.IsChecked.Value)
                {
                    AddLogEntry(logServer, con.ConId, "Data forwarding completed.");
                }
            }
        }
Exemple #5
0
        private void con_RemoteConnectionEstablished(ConnectionData data, bool usedIpv6, IPEndPoint remoteLocalEndpoint, IPEndPoint remoteRemoteEndpoint)
        {
            ForwardingConnection con = data.Connection;

            AddLogEntry(logServer, con.ConId, "Remote connection established using IPv" + (usedIpv6 ? "6" : "4") + " from local endpoint \""
                        + remoteLocalEndpoint.ToString() + "\" to remote endpoint \"" + remoteRemoteEndpoint.ToString() + "\"."
                        + (forwarder.RemoteSslHost != null ? "\r\nAuthenticating..." : ""));

            if (logDataToFile)
            {
                // Create new Filestream for outgoing connection.
                data.fileOutgoing = CreateDataLogFileStream(false, con.ConId);
            }
        }
Exemple #6
0
        private void con_LocalConnectionAuthenticated(ConnectionData data, System.Security.Authentication.SslProtocols protocol,
                                                      System.Security.Authentication.CipherAlgorithmType cipherAlgorithmType, int cipherAlgorithmStrength,
                                                      System.Security.Authentication.HashAlgorithmType hashAlgorithmType, int hashAlgorithmStrength,
                                                      System.Security.Authentication.ExchangeAlgorithmType exchangeAlgorithmType, int exchangeAlgorithmStrength)
        {
            ForwardingConnection con = data.Connection;

            AddLogEntry(logClient, con.ConId, "Local connection authenticated. Protocol: " + protocol.ToString() + ", Cipher: " + cipherAlgorithmType.ToString()
                        + " (" + cipherAlgorithmStrength + " Bit), "
                        + "Hash: " + hashAlgorithmType.ToString() + " (" + hashAlgorithmStrength + " Bit), Exchange: " + exchangeAlgorithmType
                        + " (" + exchangeAlgorithmStrength + " Bit)");

            AddLogEntry(logServer, con.ConId, "Connecting...");
        }
Exemple #7
0
        private void con_ConnectionClosedCompletely(ConnectionData data)
        {
            ForwardingConnection con = data.Connection;

            // Fully closed.

            // This event can be raised multiple times (or the connection may already be aborted by one thread),
            // therefore we need to to this check
            if (!data.IsAbortedOrClosed)
            {
                data.IsAbortedOrClosed = true;

                connectionCount--;
                RefreshConnectionCount();
            }
        }
Exemple #8
0
        private void con_RemoteConnectionClosed(ConnectionData data)
        {
            ForwardingConnection con = data.Connection;

            if (!data.IsAbortedOrClosed)
            {
                int count = data.CloseCount++;

                AddLogEntry(logServer, con.ConId, "Remote connection closed (" + (count + 1) + ") \u2013 Data Offset: 0x" + data.DataCountRemote.ToString("X") + ".");

                if (logDataToFile)
                {
                    data.fileOutgoing.Dispose();
                }
            }
        }
Exemple #9
0
        private void con_LocalConnectionClosed(ConnectionData data)
        {
            ForwardingConnection con = data.Connection;

            if (!data.IsAbortedOrClosed)
            {
                int count = data.CloseCount++;

                AddLogEntry(logClient, con.ConId, "Local connection closed (" + (count + 1) + ") \u2013 Data Offset: 0x" + data.DataCountLocal.ToString("X") + ".");

                if (logDataToFile)
                {
                    data.fileIncoming.Dispose();
                }
            }
        }
Exemple #10
0
        private void con_RemoteConnectionAuthenticated(ConnectionData data, System.Security.Authentication.SslProtocols protocol,
                                                       System.Security.Cryptography.X509Certificates.X509Certificate2 remoteCertificate,
                                                       System.Security.Authentication.CipherAlgorithmType cipherAlgorithmType, int cipherAlgorithmStrength,
                                                       System.Security.Authentication.HashAlgorithmType hashAlgorithmType, int hashAlgorithmStrength,
                                                       System.Security.Authentication.ExchangeAlgorithmType exchangeAlgorithmType, int exchangeAlgorithmStrength)
        {
            ForwardingConnection con = data.Connection;

            AddLogEntry(logServer, con.ConId, "Remote connection authenticated. Protocol: " + protocol.ToString() + ", Cipher: " + cipherAlgorithmType.ToString()
                        + " (" + cipherAlgorithmStrength + " Bit), "
                        + "Hash: " + hashAlgorithmType.ToString() + " (" + hashAlgorithmStrength + " Bit), Exchange: " + exchangeAlgorithmType
                        + " (" + exchangeAlgorithmStrength + " Bit)\r\n"
                        + "Certiticate Subject: " + remoteCertificate.Subject + "\r\n"
                        + "Certificate Issuer: " + remoteCertificate.Issuer + "\r\n"
                        + "Valid: Not before " + new DateTimeOffset(remoteCertificate.NotBefore).ToString()
                        + ", not after " + new DateTimeOffset(remoteCertificate.NotAfter).ToString() + "\r\n"
                        + "Fingerprint: " + remoteCertificate.Thumbprint);
        }
Exemple #11
0
        private void forwarder_ConnectionAccepted(ConnectionData data)
        {
            ForwardingConnection con = data.Connection;

            connectionCount++;
            RefreshConnectionCount();

            AddLogEntry(logClient, con.ConId, "Local connection established from remote endpoint \"" + con.LocalRemoteIPEndpoint.ToString()
                        + "\" to local endpoint \"" + con.LocalLocalIPEndpoint.ToString() + "\"."
                        + (forwarder.LocalSslCertificate != null ? "\r\nAuthenticating..." : ""));

            if (forwarder.LocalSslCertificate == null)
            {
                AddLogEntry(logServer, con.ConId, "Connecting...");
            }

            if (logDataToFile)
            {
                // Create new Filestream for incoming connection.
                data.fileIncoming = CreateDataLogFileStream(true, con.ConId);
            }
        }
        //internal void DeregisterConnection(ForwardingConnection con) {
        //    lock (connections) {
        //        connections.Remove(con.ConId);
        //    }
        //}

        public async Task RunAsync()
        {
            // Ensure that exceptions thrown by listener.Start() are thrown in this thread
            // TODO: make the number of backlog queue configurable
            listener.Start(1000);

            while (true)
            {
                // Wait for the concurrent connections semaphore.
                await concurrentConnectionsSemaphore.WaitAsync();

                TcpClient client;
                try {
                    client = await listener.AcceptTcpClientAsync();
                } catch (ObjectDisposedException ex) {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    // Listener has been stopped.
                    // Ignore
                    return;
                }

                BigInteger conId = nextConId++;
                Func <SemaphoreSlim, Task> waitForSendingDelegate   = sem => ConnectionWaitForSending(sem, true);
                Func <SemaphoreSlim, Task> waitForReceivingDelegate = sem => ConnectionWaitForSending(sem, false);


                IPAddress[] bindAndConnectAddresses = new IPAddress[2];
                if (RemoteHost == "[localhost-random]")
                {
                    for (int i = 0; i < bindAndConnectAddresses.Length; i++)
                    {
                        // Generate two random addresses in the range 127.0.0.1-127.255.255.254.
                        // Bind to one of these addresses as local endpoint and use the other one for the remote endpoint.
                        // This ensures that if a lot of connections are opened and closed in a very short time, that we do not
                        // get errors that an address+port has been used multiple times when opening new connections (as the TCP/IP standard
                        // defines that between consecutive connections using the same combination of a specific local endpoint (adr+port) and a specific remote endpoint (adr+port)
                        // some time must pass, to minimize data corruption).
                        // If we use random addresses in the above range we are minimizing the risk of using the same adr+port again in a short time interval.

                        byte[] adr;
                        adr    = new byte[4];
                        adr[0] = 127;

                        // TODO: Currently, for the last byte only numbers in the range 1-254 are generated although a address like
                        // 127.2.3.255 would be OK (but 127.255.255-255 wouldn't).
                        for (int x = 1; x < adr.Length; x++)
                        {
                            adr[x] = (byte)(localhostAddressRNG.Next(254 + (x != 3 ? 2 : 0)) + (x == 3 ? 1 : 0));
                        }

                        bindAndConnectAddresses[i] = new IPAddress(adr);
                    }
                }

                ForwardingConnection con = new ForwardingConnection(this, client, conId, bindAndConnectAddresses[0], bindAndConnectAddresses[1], waitForSendingDelegate, waitForReceivingDelegate, concurrentConnectionsSemaphore);

                //lock (connections) {
                //    connections.Add(con.ConId, con);
                //}

                OnConnectionAccepted(con);

                // TODO maybe save the Task somewhere.
                Task t = ExceptionUtils.WrapTaskForHandlingUnhandledExceptions(async() => await con.Run());
            }
        }