1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
| using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Net;
namespace CrossPolicyServer
{
// Encapsulate and manage state for a single connection from a client
class PolicyConnection
{
private Socket mConnection;
// buffer to receive the request from the client
private byte[] mBuffer;
private int mReceived;
// the policy to return to the client
private byte[] mPolicy;
// the request that we're expecting from the client
private static string policyRequestString = "<policy-file-request/>";
public PolicyConnection(Socket client, byte[] policy)
{
mConnection = client;
mPolicy = policy;
mBuffer = new byte[policyRequestString.Length];
mReceived = 0;
try
{
// receive the request from the client
mConnection.BeginReceive(mBuffer, 0, policyRequestString.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
}
catch (SocketException)
{
mConnection.Close();
}
}
// Called when we receive data from the client
private void OnReceive(IAsyncResult res)
{
try
{
mReceived += mConnection.EndReceive(res);
// if we haven't gotten enough for a full request yet, receive again
if (mReceived < policyRequestString.Length)
{
mConnection.BeginReceive(mBuffer, mReceived, policyRequestString.Length - mReceived, SocketFlags.None, new AsyncCallback(OnReceive), null);
return;
}
// make sure the request is valid
string request = System.Text.Encoding.UTF8.GetString(mBuffer, 0, mReceived);
if (StringComparer.InvariantCultureIgnoreCase.Compare(request, policyRequestString) != 0)
{
mConnection.Close();
return;
}
// send the policy
mConnection.BeginSend(mPolicy, 0, mPolicy.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
}
catch (SocketException)
{
mConnection.Close();
}
}
// called after sending the policy to the client; close the connection.
public void OnSend(IAsyncResult res)
{
try
{
mConnection.EndSend(res);
}
finally
{
mConnection.Close();
}
}
}
// Listens for connections on port 943 and dispatches requests to a PolicyConnection
class PolicyServer
{
private Socket mListener;
private byte[] mPolicy;
// pass in the path of an XML file containing the socket policy
public PolicyServer(string policyFile)
{
// Load the policy file
FileStream policyStream = new FileStream(policyFile, FileMode.Open);
mPolicy = new byte[policyStream.Length];
policyStream.Read(mPolicy, 0, mPolicy.Length);
policyStream.Close();
// Create the Listening Socket
mListener = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
// Put the socket into dual mode to allow a single socket
// to accept both IPv4 and IPv6 connections
// Otherwise, server needs to listen on two sockets,
// one for IPv4 and one for IPv6
// NOTE: dual-mode sockets are supported on Vista and later
mListener.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0);
mListener.Bind(new IPEndPoint(IPAddress.IPv6Any, 943));
mListener.Listen(10);
mListener.BeginAccept(new AsyncCallback(OnConnection), null);
}
// Called when we receive a connection from a client
public void OnConnection(IAsyncResult res)
{
Socket client = null;
try
{
client = mListener.EndAccept(res);
}
catch (SocketException)
{
return;
}
// handle this policy request with a PolicyConnection
PolicyConnection pc = new PolicyConnection(client, mPolicy);
// look for more connections
mListener.BeginAccept(new AsyncCallback(OnConnection), null);
}
public void Close()
{
mListener.Close();
}
}
public class Program
{
static void Main(string[] args)
{
PolicyServer ps = new PolicyServer("clientaccesspolicy.xml");
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
}
} |
Partager