Beispiel #1
0
        private static void ForwardData(object args)
        {
            StreamsPair pair   = args as StreamsPair;
            HeyLogger   logger = pair.Logger;

            byte[] buffer = new byte[1024 * 1024];

            try
            {
                while (pair.StreamA.CanRead)
                {
                    int bytesRead = pair.StreamA.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                    {
                        logger.WriteLine(String.Format("No more bytes to read from {0}.", pair.Label));
                        break;
                    }

                    pair.StreamB.Write(buffer, 0, bytesRead);
                    logger.WriteLine(String.Format("{0} bytes from {1}.", bytesRead, pair.Label));
                }
            }
            catch (IOException ex)
            {
                WriteLine(ConsoleColor.Red, pair.Label);
                logger.WriteLine(ex.ToString());
            }

            // TODO: Check this is right.
            // Tell the other side connections is being shutdown.
            pair.StreamB.Close();
        }
Beispiel #2
0
        private static void DoHttp(HeyLogger logger, Stream sslStream, Socket clientSocket)
        {
            HeyHttpServerThread connection = new HeyHttpServerThread(
                logger,
                clientSocket,
                null);

            connection.Accept(sslStream);
        }
        private void IsAuthorizationValid(string path, string authorizationHeader, bool isValid)
        {
            HeyLogger      logger  = new HeyLogger();
            HeyHttpRequest request = new HeyHttpRequest(logger);

            request.ParsePath(path);
            request.Authorization = authorizationHeader;

            Assert.AreEqual(isValid, HeyHttpAuthentication.IsAuthorizationValid(request));
        }
        public void AddAuthenticateHeaderIfNeeded_Basic_NoAuthorization()
        {
            HeyLogger       logger   = new HeyLogger();
            HeyHttpRequest  request  = new HeyHttpRequest(logger);
            HeyHttpResponse response = new HeyHttpResponse(logger);

            request.ParsePath("/?basic=1");

            HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response);

            Assert.AreEqual("401 Unauthorized", response.Status);
            Assert.IsTrue(response.Headers.Contains("WWW-Authenticate: Basic realm=\"Secure Area\""));
        }
Beispiel #5
0
        private static void Reply407AndClose(HeyLogger logger, NetworkStream clientStream)
        {
            HeyHttpResponse response = new HeyHttpResponse(logger);

            response.Version = "HTTP/1.0";
            response.Status  = "407 Proxy Authentication Required";
            response.Headers.Add("Proxy-agent: Netscape-Proxy/1.1");
            response.Headers.Add("Proxy-Authenticate: Basic realm=\"WallyWorld\"");
            response.Headers.Add("Content-Length: 0");
            response.Headers.Add("Connection: close");
            response.CopyHeadersTo(clientStream);
            clientStream.Close();
        }
        public void AddAuthenticateHeaderIfNeeded_Basic_InvalidAuthorization()
        {
            HeyLogger       logger   = new HeyLogger();
            HeyHttpRequest  request  = new HeyHttpRequest(logger);
            HeyHttpResponse response = new HeyHttpResponse(logger);

            request.ParsePath("/?basic=1&user=foo&password=bar");
            request.Authorization = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==";

            HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response);

            Assert.AreEqual("401 Unauthorized", response.Status);
            Assert.IsTrue(response.Headers.Contains("WWW-Authenticate: Basic realm=\"Secure Area\""));
        }
        public void AddAuthenticateHeaderIfNeeded_Basic_ValidAuthorization()
        {
            HeyLogger       logger   = new HeyLogger();
            HeyHttpRequest  request  = new HeyHttpRequest(logger);
            HeyHttpResponse response = new HeyHttpResponse(logger);

            request.ParsePath("/?basic=1&user=foo&password=bar");
            request.Authorization = "Basic Zm9vOmJhcg==";

            HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response);

            Assert.IsTrue(String.IsNullOrEmpty(response.Status));
            Assert.AreEqual(0, response.Headers.Count);
        }
Beispiel #8
0
        public static void Start(HeyWebSocketServerSettings settings)
        {
            HeyWebSocketServer.OnMessage += (sender, data) =>
            {
                Console.WriteLine(data.Length);

                //// Send a ping.
                //WebSocketServerPro.Ping();

                //WebSocketServerPro.Send(new String('x', 0x10000));

                // Non-fragmented message.
                HeyWebSocketServer.Send(FinType.Set, OpcodeType.Text, "Hey!");

                // Send fragmented message.
                HeyWebSocketServer.Send(FinType.Clear, OpcodeType.Text, "Go");
                Thread.Sleep(1000);
                HeyWebSocketServer.Send(FinType.Set, OpcodeType.Continuation, "Hawks!");
            };

            TcpListener tcpListener = new TcpListener(IPAddress.IPv6Any, settings.Port);

            tcpListener.Start();
            Console.WriteLine("Listening on port {0} ...", settings.Port);

            while (true)
            {
                try
                {
                    using (TcpClient tcpClient = tcpListener.AcceptTcpClient())
                    {
                        Console.WriteLine("Connected: {0}", tcpClient.Client.RemoteEndPoint);
                        Console.WriteLine();

                        using (networkStream = tcpClient.GetStream())
                        {
                            logger = new HeyLogger();
                            AcceptCore();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.WriteLine();
                Console.WriteLine("Disconnected.");
            }
        }
Beispiel #9
0
        public HeyHttpRequest(HeyLogger logger)
        {
            this.logger = logger;

            // Use the default port, unless any header specifies a different one.
            Port = 80;

            // Invariant culture is a fake culture based on English, great to write out, for example,
            // stuff into config files so it can be read an written regardless of the culture the user
            // has defined.
            headers = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            // Initialize with an empty NameValueCollection, so we never have to check if QueryString is null.
            ParseQueryString("");
        }
Beispiel #10
0
        private static void ProcessDigestAuthorization(HeyHttpRequest request, HeyLogger logger)
        {
            string headerValue = request.Authorization.Substring("Digest ".Length);

            string[] pairs = headerValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string pair in pairs)
            {
                string[] keyAndValue = pair.Split(new char[] { '=' }, 2);
                if (keyAndValue.Length == 2)
                {
                    string key   = keyAndValue[0].Trim();
                    string value = keyAndValue[1].Trim('"');

                    logger.WriteHeadersLine(
                        String.Format("{0}: {1}", key, value));
                }
            }

            logger.WriteHeadersLine("\r\n");

            // TODO: If the password is not the expected one, clear Authorization header,
            // so a 401 Unauthorized response is sent.
        }
Beispiel #11
0
 public HeyHttpResponse(HeyLogger logger)
 {
     this.logger = logger;
     Headers     = new List <string>();
     Version     = "HTTP/1.1";
 }
Beispiel #12
0
 public static void Accept(HeyLogger logger, Stream stream)
 {
     HeyWebSocketServer.logger        = logger;
     HeyWebSocketServer.networkStream = stream;
     AcceptCore();
 }
Beispiel #13
0
        private static void OnAccept(IAsyncResult asyncResult)
        {
            HeyLogger logger         = new HeyLogger();
            Socket    socketListener = asyncResult.AsyncState as Socket;
            SslStream sslStream      = null;
            string    clientName     = null;

            try
            {
                using (Socket clientSocket = socketListener.EndAccept(asyncResult))
                {
                    socketListener.BeginAccept(OnAccept, socketListener);

                    clientName = clientSocket.RemoteEndPoint.ToString();
                    logger.WriteTransportLine(String.Format("Client connected from {0}\r\n", clientName));

                    NetworkStream networkStream = new NetworkStream(clientSocket);

                    // Plain connection before upgrading to SSL?
                    //message = ReadMessage(networkStream);
                    //Console.WriteLine(message);

                    RemoteCertificateValidationCallback callback = null;
                    if (settings.ClientCertificateRequired)
                    {
                        callback = new RemoteCertificateValidationCallback(ValidateClientCertificate);
                    }

                    sslStream = new SslStream(
                        networkStream,
                        false,
                        callback,
                        null);

                    sslStream.AuthenticateAsServer(
                        serverCertificate,
                        settings.ClientCertificateRequired,
                        SslProtocols.Default,
                        false);

                    switch (settings.Protocol)
                    {
                    case ApplicationLayerProtocol.Http:
                        DoHttp(logger, sslStream, clientSocket);
                        break;

                    case ApplicationLayerProtocol.Ws:
                        DoWs(logger, sslStream, clientSocket);
                        break;

                    default:
                        DoUndefined(sslStream);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.WriteErrorLine(ex.Message);
            }
            finally
            {
                logger.WriteTransportLine(String.Format("Disconnected from {0}\r\n", clientName));

                if (sslStream != null)
                {
                    SslClientCertificateInfo.Remove(sslStream.GetHashCode());
                }
            }
        }
Beispiel #14
0
 private static void DoWs(HeyLogger logger, Stream sslStream, Socket clientSocket)
 {
     HeyWebSocketServer.Accept(logger, sslStream);
 }
Beispiel #15
0
        private static void OnAccept(IAsyncResult asyncResult)
        {
            HeyLogger logger         = new HeyLogger();
            Socket    socketListener = asyncResult.AsyncState as Socket;
            Socket    client         = socketListener.EndAccept(asyncResult);

            socketListener.BeginAccept(OnAccept, asyncResult.AsyncState);

            try
            {
                HeyHttpRequest request = new HeyHttpRequest(logger);

                // Client got connected.
                logger.WriteLine(String.Format("Connected: {0}", client.RemoteEndPoint));

                // Read HTTP headers.
                NetworkStream clientStream = new NetworkStream(client);
                MemoryStream  tempStream   = new MemoryStream();
                request.ReadHeaders(clientStream, tempStream);

                // Authentication.
                if (settings.AuthenticationRequired && !IsAuthenticated(request))
                {
                    Reply407AndClose(logger, clientStream);
                    return;
                }

                // Find server host name.
                logger.WriteLine(String.Format("Trying to connect to {0}", request.Host));

                // Get IP address for the given server hostname.
                IPHostEntry hostEntry = Dns.GetHostEntry(request.Host);
                if (hostEntry.AddressList.Length == 0)
                {
                    throw new Exception("Unknow server hostname.");
                }
                IPAddress address = hostEntry.AddressList[0];

                // Connect to server.
                Socket server = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                server.Connect(new IPEndPoint(address, request.Port));

                logger.WriteLine(String.Format("Connected to {0}", request.Host));

                // Send cached data to server.
                NetworkStream serverStream = new NetworkStream(server);

                // When using the CONNECT method, proxy must send a HTTP response to client.
                // See "Tunneling TCP based protocols through Web proxy servers" internet-draft.
                if (request.Method == "CONNECT")
                {
                    HeyHttpResponse response = new HeyHttpResponse(logger);
                    response.Status = "200 Connection established";
                    response.Headers.Add("Proxy-agent: Happy-Sockets-Proxy/1.0");
                    response.CopyHeadersTo(clientStream);
                }
                else
                {
                    // Only forward headers when it is not a CONNECT request.
                    tempStream.Seek(0, SeekOrigin.Begin);
                    tempStream.CopyTo(serverStream);
                }

                // Forward data.
                ParameterizedThreadStart serverToClientStart = new ParameterizedThreadStart(ForwardData);
                Thread serverToClientThread = new Thread(serverToClientStart);
                serverToClientThread.Start(
                    new StreamsPair
                {
                    StreamA = serverStream,
                    StreamB = clientStream,
                    Label   = "server to client",
                    Logger  = logger
                });

                ParameterizedThreadStart clientToServerStart = new ParameterizedThreadStart(ForwardData);
                Thread clientToServerThread = new Thread(clientToServerStart);
                clientToServerThread.Start(
                    new StreamsPair
                {
                    StreamA = clientStream,
                    StreamB = serverStream,
                    Label   = "client to server",
                    Logger  = logger
                });

                //serverToClientThread.Join();
                //clientToServerThread.Join();

                // TODO: make sure streams do not go out of scope.
                // TODO: wait until threads end and ensure connections are close.
            }
            catch (SocketException ex)
            {
                WriteLine(ConsoleColor.Red, ex.Message);
                logger.WriteLine(ex.ToString());

                // We couldn't connect to the  server, terminate connection with the client.
                client.Close();
            }
            catch (IOException ex)
            {
                WriteLine(ConsoleColor.Red, ex.Message);
                logger.WriteLine(ex.ToString());

                // The client closed the connection, terminate the connection with the server.
                client.Close();
            }
            catch (Exception ex)
            {
                WriteLine(ConsoleColor.Red, ex.Message);
                logger.WriteLine(ex.ToString());
            }
        }
Beispiel #16
0
 public HeyHttpServerThread(HeyLogger logger, Socket tcpClient, RemoveConnectionDelegate removeConnection)
 {
     this.clientSocket     = tcpClient;
     this.removeConnection = removeConnection;
     this.logger           = logger;
 }