public static void Main() { using (Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { // Addressing IPAddress ipAddress = IPAddress.Parse(dottedServerIPAddress); IPEndPoint serverEndPoint = new IPEndPoint(ipAddress, port); // Connecting Debug.Print("Connecting to server " + serverEndPoint + "."); clientSocket.Connect(serverEndPoint); Debug.Print("Connected to server."); using (SslStream sslStream = new SslStream(clientSocket)) { X509Certificate rootCA = new X509Certificate(Resources.GetBytes(Resources.BinaryResources.MyRootCA)); X509Certificate clientCert = new X509Certificate(Resources.GetBytes(Resources.BinaryResources.MyRootCA)); sslStream.AuthenticateAsClient("MyServerName", // Hostname needs to match CN of server cert clientCert, // Authenticate client new X509Certificate[] { rootCA }, // CA certs for verification SslVerification.CertificateRequired, // Verify server SslProtocols.Default // Protocols that may be required ); // Sending byte[] messageBytes = Encoding.UTF8.GetBytes("Hello World!"); sslStream.Write(messageBytes, 0, messageBytes.Length); } }// the socket will be closed here }
public static void Main() { using (Socket listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { listeningSocket.Bind(new IPEndPoint(IPAddress.Any, port)); Debug.Print("Listening for a client..."); listeningSocket.Listen(1); using (Socket communicationSocket = listeningSocket.Accept()) { Debug.Print("Connected to client."); using (SslStream sslStream = new SslStream(communicationSocket)) { X509Certificate serverCert = new X509Certificate(Resources.GetBytes(Resources.BinaryResources.MyServer)); X509Certificate rootCA = new X509Certificate(Resources.GetBytes(Resources.BinaryResources.MyRootCA)); sslStream.AuthenticateAsServer(serverCert, // To authenticate the server new X509Certificate[] { rootCA }, // CA certificates SslVerification.CertificateRequired, // Verify client SslProtocols.Default // Protocols that may be used ); //wait infinitely to get a response sslStream.ReadTimeout = -1; byte[] inBuffer = new byte[1000]; int count = sslStream.Read(inBuffer, 0, inBuffer.Length); string message = new string(Encoding.UTF8.GetChars(inBuffer)); Debug.Print("Received '" + message + "'."); } } } }
public void RunClient() { // Create a TCP/IP client socket. clientSocket = new Socket(AddressFamily.InterNetwork, clientSocketType, clientProtocolType); clientSocket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); while (true) { try { // Connect to the server clientSocket.Connect(serverEp); break; } catch (SocketException) { // Server down, try again Thread.Sleep(1000); } } Log.Comment("Client connected."); // Create an SSL stream that will close the client's stream. sslClient = new SslStream(clientSocket); // The server name must match the name on the server certificate. sslClient.AuthenticateAsClient(targetHost, cert, ca, verify, sslProtocols); // Send hello message to the server. Log.Comment("Sending message to Server: " + messageSent); byte[] message = Encoding.UTF8.GetBytes(messageSent); sslClient.Write(message, 0, message.Length); Log.Comment("do we need to flush? after a write?"); sslClient.Flush(); // Read message from the server. messageReceived = ReadMessage(sslClient); Log.Comment("Server says:" + messageReceived); // Do not close the clientSslStream. That is handled by the test case. }
/// <summary> /// Waits for new connections from the client. /// </summary> /// <remarks>On new connections, this method enques the new input /// network stream and sets an event that a new connection is available. /// </remarks> private void AcceptThreadFunc() { Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; // If there was no exception up to this point, means we succeded to start listening. m_ServiceRunning = true; int retry = 0; // The Start function is waiting on this event. We set it to indicate that // thread that waits for connections is already started. m_RequestArrived.Set(); // The value of m_serviceStarted normally is changed from other thread by calling Stop. while (m_ServiceRunning) { Socket clientSock; // Need to create NetworkStream or SSL stream depending on protocol used. NetworkStream netStream = null; try { // It is important that multithread access to m_listener.Accept(); is not locked. // If it was locked - then Close or Stop would be blocked potnetially for ever while waiting for connection. // This is a blocking call waiting for connection. clientSock = m_listener.Accept(); retry = 0; try { // set NoDelay to increase HTTP(s) response times clientSock.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } catch { } } catch (SocketException) { if (retry > 5) { // If request to stop listener flag is set or locking call is interupted return // On exception we stop the service and record the exception. if (m_ServiceRunning && !m_Closed) { Stop(); } // Set event to unblock thread waiting for accept. m_RequestArrived.Set(); break; } retry++; continue; } catch { // If request to stop listener flag is set or locking call is interupted return // On exception we stop the service and record the exception. if (m_ServiceRunning && !m_Closed) { Stop(); } // Set event to unblock thread waiting for accept. m_RequestArrived.Set(); break; } try { if (!m_IsHttpsConnection) { // This is case of normal HTTP. Create network stream. netStream = new NetworkStream(clientSock, true); } else { // This is the case of https. // Once connection estiblished need to create secure stream and authenticate server. netStream = new SslStream(clientSock); SslProtocols[] sslProtocols = new SslProtocols[] { SslProtocols.Default }; // Throws exception if fails. ((SslStream)netStream).AuthenticateAsServer(m_httpsCert, SslVerification.NoVerification, sslProtocols); netStream.ReadTimeout = 10000; } } catch(SocketException) { if (netStream != null) { netStream.Dispose(); } else { clientSock.Close(); } m_RequestArrived.Set(); // try again continue; } // Add this connected stream to the list. lock (m_InputStreamsQueue) { m_InputStreamsQueue.Enqueue(new OutputNetworkStreamWrapper(clientSock, netStream)); } // Set event that client stream or exception is added to the queue. m_RequestArrived.Set(); } }
public MFTestResults RunServer() { MFTestResults testResult = MFTestResults.Fail; SslStream sslStream = null; try { IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); sslServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //sslServer.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false); sslServer.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new byte[] { 0, 0, 0, 0 }); sslServer.Bind(localEndPoint); sslServer.Listen(1); // Buffer for reading data Byte[] bytes = new Byte[2048]; String data = ""; // Start Listening for a connection. Log.Comment("Waiting for a connection... on IPAddress: " + localEndPoint.Address.ToString() + " Port: " +localEndPoint.Port.ToString()); // Perform a blocking call to accept requests. // block in listening mode until the desktop app connects. Then we know we can continue. Socket client = sslServer.Accept(); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new byte[] { 0, 0, 0, 0 }); //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 30000); //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 30000); Log.Comment("Connected!"); // Get a stream object for reading and writing sslStream = new SslStream(client); sslStream.AuthenticateAsServer(certificate, ca, clientCertificateRequired, enabledSslProtocols); int i = -1; do { // Loop to receive all the data sent by the client. i = sslStream.Read(bytes, 0, bytes.Length); // Translate data bytes to a string. // The encoding used is application specific. string newStr = new string(System.Text.Encoding.UTF8.GetChars(bytes), 0, i); Log.Comment("Received: " + newStr); data += newStr; if (data.IndexOf(SslClient.TERMINATOR) != -1) break; } while (i != 0); // Send back a response. sslStream.Write(bytes, 0, i); Log.Comment("Sent: " + data); Thread.Sleep(200); testResult = MFTestResults.Pass; } catch (SocketException e) { if (expectedException) testResult = MFTestResults.Pass; Log.Comment("SocketException in StartServer(): " + e.ToString()); Log.Comment("ErrorCode: " + e.ErrorCode.ToString()); } catch (Exception e) { if (expectedException) testResult = MFTestResults.Pass; Log.Comment("Exception in StartServer(): " + e.ToString()); } finally { if (sslServer != null) { sslServer.Close(); } if (sslStream != null) { sslStream.Dispose(); } } return testResult; }
/// <summary> /// Processes client socket requests. Sends the message received back to the client. /// </summary> internal void ProcessClient() { // Application blocks while waiting for an incoming connection. while (true) { try { Debug.Print("Waiting for a client to connect..."); Socket clientSocket = serverSocket.Accept(); Debug.Print("Socket Connected"); // A client has connected. Create the // SslStream using the client's network stream. sslServer = new SslStream(clientSocket); // Authenticate the server but don't require the client to authenticate. sslServer.AuthenticateAsServer(cert, ca, verify, sslProtocols); //Display the properties and settings for the authenticated stream. //DisplaySecurityLevel(sslStream); //DisplaySecurityServices(sslStream); //DisplayCertificateInformation(sslStream); //DisplayStreamProperties(sslStream); // Read a message from the client. Debug.Print("Waiting for client message..."); messageReceived = ReadMessage(sslServer); Debug.Print("Received: " + messageReceived); // Write a message to the client. Debug.Print("Resending message back to client..."); sslServer.Write(Encoding.UTF8.GetBytes(messageReceived), 0, messageReceived.Length); // Do not close the SslStream here. that is to be handled by the test case. } catch (Exception ex) { Debug.Print("Unhandled exception " + ex.Message); } if (runOnce) return; } }
/// <summary> /// Read the messages sent over the socket. /// </summary> internal string ReadMessage(SslStream sslStream) { // Read the message sent by the client. // The client signals the end of the message using the // "<EOF>" marker. byte[] buffer = new byte[2048]; String messageData = ""; int bytesRead = -1; do { // Read the client's test message. bytesRead = sslStream.Read(buffer, 0, buffer.Length); messageData += new String(Encoding.UTF8.GetChars(buffer)); // Check for <EOF> or an empty message. if (messageData.IndexOf(TERMINATOR) != -1) { break; } } while (bytesRead > 0); return messageData; }
public bool RunServer() { //MFTestResults testResult = MFTestResults.Fail; bool result = false; SslStream sslStream = null; Socket client = null; try { if (sslServer == null) { IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); sslServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sslServer.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false); sslServer.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new byte[] { 0, 0, 0, 0 }); sslServer.Bind(localEndPoint); sslServer.Listen(1); } // Buffer for reading data Byte[] bytes = new Byte[2048]; String data = ""; // Start Listening for a connection. //Log.Comment("Waiting for a connection... on IPAddress: " + localEndPoint.Address.ToString() + " Port: " +localEndPoint.Port.ToString()); // Perform a blocking call to accept requests. // block in listening mode until the desktop app connects. Then we know we can continue. client = sslServer.Accept(); //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new byte[] { 0, 0, 0, 0 }); //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000); //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 5000); //Log.Comment("Connected!"); // Get a stream object for reading and writing sslStream = new SslStream(client); //SK call of SSL_ServerInit in CLR-Code sslStream.AuthenticateAsServer(certificate, ca, clientCertificateRequired, enabledSslProtocols); sslStream.ReadTimeout = 5000; sslStream.WriteTimeout = 5000; int i = -1; do { // Loop to receive all the data sent by the client. try { i = sslStream.Read(bytes, 0, bytes.Length); } catch (Exception) { //throw; } // Translate data bytes to a string. // The encoding used is application specific. string newStr = new string(System.Text.Encoding.UTF8.GetChars(bytes), 0, i); //Log.Comment("Received: " + newStr); data += newStr; if (data.IndexOf(SslClient.TERMINATOR) != -1) break; } while (i != 0); // Send back a response. //sslStream.Write(bytes, 0, i); // Return a static HTML document to the client. String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<html><head><title>.NET Micro Framework Web Server</title></head>" + "<body>"; sslStream.Write(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetBytes(s).Length); for(int j = 0; j < 1000; j++) { s = "<p><bold><a href=\"http://www.microsoft.com/netmf/\">Learn more about the .NET Micro Framework by clicking here</a></bold></p>"; sslStream.Write(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetBytes(s).Length); } s = "</body></html>"; sslStream.Write(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetBytes(s).Length); //Log.Comment("Sent: " + data); Thread.Sleep(200); result = true; } catch (SocketException e) { if (expectedException) result = true; //Log.Comment("SocketException in StartServer(): " + e.ToString()); //Log.Comment("ErrorCode: " + e.ErrorCode.ToString()); } catch (Exception e) { if (expectedException) result = true; //Log.Comment("Exception in StartServer(): " + e.ToString()); } finally { if (sslStream != null) { sslStream.Close(); sslStream.Dispose(); //sslStream.Flush(); } if (sslServer != null) { // sslServer.Close(); } } return result; }
public SecureStream(string host, Socket socket, X509Certificate ca, SslProtocols encryption) { _socket = socket; _sslStream = new SslStream(socket); _sslStream.AuthenticateAsClient(host, null, new[] { ca }, SslVerification.CertificateRequired, encryption); }
/// <summary> /// Returns network stream connected to server. It could be a proxy or a /// real server Uri. /// </summary> /// <param name="proxyServer">Uri that describes the proxy server.</param> /// <param name="targetServer">Uri that describes the target (real) server.</param> /// <returns>Nerwork stream connected to server.</returns> private InputNetworkStreamWrapper EstablishConnection(Uri proxyServer, Uri targetServer) { InputNetworkStreamWrapper retStream = null; // Create a socket and set reuse true. // But before creating new socket we look in the list of existing sockets. If socket for this host already // exist - use it. No need to create new socket. string remoteServer = targetServer.Host + ":" + targetServer.Port; lock (m_ConnectedStreams) { ArrayList removeStreamList = new ArrayList(); for (int i = 0; i < m_ConnectedStreams.Count; i++) { InputNetworkStreamWrapper inputStream = (InputNetworkStreamWrapper)m_ConnectedStreams[i]; if (inputStream.m_rmAddrAndPort == remoteServer && !inputStream.m_InUse) { // Re-use the connected socket. // But first we need to know that socket is not closed. try { // If socket is closed ( from this or other side ) the call throws exception. if (inputStream.m_Socket.Poll(1, SelectMode.SelectWrite)) { // No exception, good we can condtinue and re-use connected stream. // Control flow returning here means persistent connection actually works. inputStream.m_InUse = true; inputStream.m_lastUsed = DateTime.Now; retStream = inputStream; break; } else { removeStreamList.Add(inputStream); } } catch (Exception) { removeStreamList.Add(inputStream); } } } for (int i = 0; i < removeStreamList.Count; i++) { InputNetworkStreamWrapper removeStream = (InputNetworkStreamWrapper)removeStreamList[i]; // Means socket was closed. Remove it from the list. m_ConnectedStreams.Remove(removeStream); removeStream.Dispose(); } } if (retStream == null) { // Existing connection did not worked. Need to establish new one. IPAddress address = null; UriHostNameType hostNameType = proxyServer.HostNameType; if (hostNameType == UriHostNameType.IPv4) { address = IPAddress.Parse(proxyServer.Host); } else if (hostNameType == UriHostNameType.Dns) { IPHostEntry hostEntry = null; try { hostEntry = Dns.GetHostEntry(proxyServer.Host); } catch(SocketException se) { throw new WebException("host not available", se, WebExceptionStatus.ConnectFailure, null); } int addressListSize = hostEntry.AddressList.Length; for (int i = 0; i < addressListSize; i++) { if ((address = hostEntry.AddressList[i]) != null) { break; } } if (address == null) { throw new WebException("Unable to resolve Dns entry to valid IPv4 Address", WebExceptionStatus.NameResolutionFailure); } } else { throw new WebException("Only IPv4 or Dns host names allowed."); } // If socket was not found in waiting connections, then we create new one. Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); // Connect to remote endpoint try { IPEndPoint remoteEP = new IPEndPoint(address, proxyServer.Port); socket.Connect((EndPoint)remoteEP); } catch (SocketException e) { throw new WebException("connection failed", e, WebExceptionStatus.ConnectFailure, null); } bool isHttps = m_originalUrl.Scheme == "https"; // We have connected socket. Create request stream retStream = new InputNetworkStreamWrapper(new NetworkStream(socket), socket, !isHttps, proxyServer.Host + ":" + proxyServer.Port); // For https proxy works differenly from http. if (isHttps) { // If proxy is set, then for https we need to send "CONNECT" command to proxy. // Once this command is send, the socket from proxy works as if it is the socket to the destination server. if (proxyServer != targetServer) { String request = "CONNECT " + remoteServer + " HTTP/" + ProtocolVersion + "\r\n\r\n"; Byte[] bytesToSend = Encoding.UTF8.GetBytes(request); retStream.Write(bytesToSend, 0, bytesToSend.Length); // Now proxy should respond with the connected status. If it is successul, then we are good to go. CoreResponseData respData = ParseHTTPResponse(retStream, m_keepAlive); if (respData.m_statusCode != (int)HttpStatusCode.OK) { throw new WebException("Proxy returned " + respData.m_statusCode, WebExceptionStatus.ConnectFailure); } } // Once connection estiblished need to create secure stream and authenticate server. SslStream sslStream = new SslStream(retStream.m_Socket); // Throws exception is fails. sslStream.AuthenticateAsClient(m_originalUrl.Host, null, m_caCerts, m_caCerts != null ? SslVerification.CertificateRequired : SslVerification.NoVerification, SslProtocols.Default); // Changes the stream to SSL stream. retStream.m_Stream = sslStream; // Changes the address. Originally socket was connected to proxy, now as if it connected to m_originalUrl.Host on m_originalUrl.Port retStream.m_rmAddrAndPort = m_originalUrl.Host + ":" + m_originalUrl.Port; } lock (m_ConnectedStreams) { m_ConnectedStreams.Add(retStream); // if the current stream list is empty then start the timer that drops unused connections. if (m_ConnectedStreams.Count == 1) { m_DropOldConnectionsTimer.Change(HttpListener.DefaultKeepAliveMilliseconds, System.Threading.Timeout.Infinite); } } } return retStream; }
public MFTestResults RunClient() { MFTestResults testResult = MFTestResults .Pass; try { if (ipAddress == null) Debug.Print("IpAddress must be initialized before calling RunClient()"); else serverEp = new IPEndPoint(ipAddress, port); // Create a TCP/IP client socket. clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); clientSocket.Connect(serverEp); // Create an SSL stream that will close the client's stream. sslClient = new SslStream(clientSocket); Log.Comment("Calling AuthenticateAsClient()"); // The server name must match the name on the server certificate. sslClient.AuthenticateAsClient(targetHost, cert, ca, verify, sslProtocols); // Send hello message to the server. byte[] message = Encoding.UTF8.GetBytes(messageSent); sslClient.Write(message, 0, message.Length); Log.Comment("Sent: " + messageSent); // Read message from the server. messageReceived = ReadMessage(sslClient); Log.Comment("Received: " + messageReceived); if (messageSent != messageReceived) testResult = MFTestResults.Fail; } catch (SocketException e) { if (!expectedException) testResult = MFTestResults.Fail; Log.Comment("ErrorCode: " + e.ErrorCode); Log.Comment("An exception occurred: " + e.Message); } catch (Exception e) { if (!expectedException) testResult = MFTestResults.Fail; Log.Comment("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; }
public string ReadMessage(SslStream sslStream) { // Read the message sent by the server. // The end of the message is signaled using the // "<EOF>" marker. byte[] buffer = new byte[2048]; String messageData = ""; int bytesRead = 0; do { if (sslStream.DataAvailable) { int len = (int)sslStream.Length; if (len > buffer.Length) { len = buffer.Length; } bytesRead += sslStream.Read(buffer, 0, len); // Convert the bytes to a string messageData += new String(Encoding.UTF8.GetChars(buffer)); // Check for EOF. int index = messageData.IndexOf("<EOF>"); if (index != -1) { messageData = messageData.Substring(0, index + 5); break; } } Thread.Sleep(200); } while (sslStream.CanRead); return messageData.ToString(); }
public string ReadMessage(SslStream sslStream) { // Read the message sent by the server. // The end of the message is signaled using the // "<EOF>" marker. byte[] buffer = new byte[2048]; String messageData = ""; int bytes = -1; do { bytes = sslStream.Read(buffer, 0, buffer.Length); // Convert the bytes to a string messageData += new String(Encoding.UTF8.GetChars(buffer)); // Check for EOF. if (messageData.ToString().IndexOf(TERMINATOR) != -1) { break; } } while (bytes > 0); return messageData.ToString(); }
static NetworkStream Connect(string host, int port, bool useSsl) { var ipHostEntry = Dns.GetHostEntry(host); Socket socket = null; SocketException exception = null; foreach (var ipAddress in ipHostEntry.AddressList) { if (ipAddress == null) continue; socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { socket.Connect(new IPEndPoint(ipAddress, port)); exception = null; break; } catch (SocketException socketException) { exception = socketException; socket = null; } } if (exception != null) { throw exception; } NetworkStream stream; if (useSsl) { SslStream sslStream = new SslStream(socket); sslStream.AuthenticateAsClient(host, null, SslVerification.VerifyPeer, SslProtocols.Default); stream = sslStream; } else { stream = new NetworkStream(socket, true); } return stream; }