Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Silverlight 4 RC – Socket Security Changes

Blogs

Mike Taulty's Blog

Elsewhere

Archives

I’ve been reading the SL4 RC docs and noticed that aspects of security have changed since the beta and since I made these screencasts on networking.

I think these are positive changes and, from what I’ve seen so far both TCP and UDP sockets drop their security limitations for an elevated application.

That is – a non-trusted application (whether in the browser or out of browser) has restrictions imposed on it;

  1. TCP sockets can only be opened to ports 4502 to 4534.
  2. TCP sockets can only be opened once a security policy allowing the opening has been downloaded via either;
    1. TCP over port 943 on the target server
    2. HTTP from port 80 on the target server ( this is new in the RC )
  3. UDP multicast sockets can only be opened to ports above 1024.
  4. UDP multicast groups can only be joined once a security policy allowing the joining has been downloaded via either;
    1. UDP unicast to port 9430 on the target server ( for a single source multicast group )
    2. UDP multicast to port 9430 on the multicast group ( for an any source multicast group )

and all those restrictions go away if you’re running trusted.

As a quick example – if I were to write a simple console application on the desktop such as this complete console application ( code hacked together in a few minutes );

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApplication4
{
  class Program
  {
    static void Main(string[] args)
    {
      TcpListener listener = new TcpListener(IPAddress.Any, 4502);       
      listener.Start();

      networkStream = new NetworkStream(listener.AcceptSocket());

      buffer = new byte[128];
      BeginRead();

      string input = string.Empty;

      while (true)
      {
        input = Console.ReadLine();

        if (input == "x")
        {
          break;
        }
        byte[] encoded = UnicodeEncoding.Unicode.GetBytes(input);
        networkStream.Write(encoded, 0, encoded.Length);
      }
      networkStream.Close();
      listener.Stop();
    }
    static void BeginRead()
    {
      networkStream.BeginRead(buffer, 0, buffer.Length, iar =>
        {
          int bytesRead = networkStream.EndRead(iar);

          Console.WriteLine("Received [{0}]",
            UnicodeEncoding.Unicode.GetString(buffer, 0, bytesRead));

          BeginRead();
        }, null);
    }
    static byte[] buffer;
    static NetworkStream networkStream;
  }
}

and then I hit that from a simple Silverlight UI defined by this XAML;

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition />
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock
                Text="Send" />
            <TextBox
                x:Name="txtSend"
                Grid.Row="1"                
                AcceptsReturn="True" />
            <Button
                Grid.Row="2"
                HorizontalAlignment="Right"
                Content="Send" 
                Click="OnSend"/>
        </Grid>
        <Grid
            Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <TextBlock
                Text="Received" />
            <TextBox
                x:Name="txtReceive"
                Grid.Row="1"
                IsReadOnly="True"/>
        </Grid>
    </Grid>
</UserControl>

with a little code behind it;

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace SilverlightApplication1
{
  public partial class MainPage : UserControl
  {
    public MainPage()
    {
      InitializeComponent();
      this.Loaded += OnLoaded;
    }
    void OnLoaded(object sender, RoutedEventArgs e)
    {
      buffer = new byte[128];

      Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
        ProtocolType.Tcp);

      SocketAsyncEventArgs args = new SocketAsyncEventArgs()
      {
        SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Http,
        RemoteEndPoint = new DnsEndPoint("localhost", 4502),
      };

      args.Completed += (s, eventArgs) =>
        {
          if (eventArgs.SocketError == SocketError.Success)
          {
            this.connectedSocket = socket;
            BeginRead();
          }
        };

      socket.ConnectAsync(args);
    }
    void BeginRead()
    {
      SocketAsyncEventArgs args = new SocketAsyncEventArgs();
      args.SetBuffer(this.buffer, 0, this.buffer.Length);

      args.Completed += (s, e) =>
        {
          if (e.BytesTransferred > 0)
          {
            string text = UnicodeEncoding.Unicode.GetString(
              this.buffer, 0, e.BytesTransferred);

            AddText(text);
          }
          BeginRead();
        };
      this.connectedSocket.ReceiveAsync(args);
    }
    void AddText(string text)
    {
      this.Dispatcher.BeginInvoke(() =>
        {
          this.txtReceive.Text += text;
        });
    }
    void OnSend(object sender, RoutedEventArgs e)
    {
      if (this.connectedSocket != null)
      {
        byte[] bytes = UnicodeEncoding.Unicode.GetBytes(
          this.txtSend.Text);

        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        args.SetBuffer(bytes, 0, bytes.Length);
        this.connectedSocket.SendAsync(args);
      }
    }
    byte[] buffer;
    Socket connectedSocket;
  }
}

then notice that line 25 above is using the SocketAsyncEventArgs member SocketClientAccessPolicyProtocol to specify that we want to use HTTP to grab the security policy rather than the usual TCP port 943 that Silverlight 3 always used.

Consequently, I can drop a clientaccesspolicy.xml file onto my main IIS server as below;

<?xml version="1.0" encoding ="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>
        <domain uri="http://localhost:10873/" />
      </allow-from>
      <grant-to>
        <socket-resource port="4502"
                         protocol="tcp" />
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

and then the socket connection is allowed because my Silverlight app is being hosted on localhost:10873.

If I take away the clientaccesspolicyfile.xml file then I can still make the application work by marking it as a trusted application and then installing it locally as trusted.

I’ll revisit this post with a UDP example.

Update 1 – I noticed that when using the new WCF TCP capabilities of Silverlight 4 it now seems to expect to make use of an HTTP Served Security Policy and not a TCP Served Security Policy. This is different to the beta but, frankly, I think that’s a smart choice as WCF TCP is new functionality and so anyone using it is likely to want the easier ( HTTP ) option and not the harder ( TCP ) option especially given that WCF is abstracting you from TCP in the first place.

Update 2 – As far as I know, UDP sockets remain using a security policy served over UDP ( either requested by unicast or by multicast depending on what kind of group you’re joining ) – this is as it was in the beta.

( of course, neither of these security policy things matters if you’re a trusted application )


Posted Sat, Mar 20 2010 5:52 PM by mtaulty
Filed under: ,

Comments

progg.ru wrote Silverlight 4 RC – изменения в безопасности сокетов
on Sat, Mar 20 2010 6:22 PM

Thank you for submitting this cool story - Trackback from progg.ru

Robert wrote re: Silverlight 4 RC – Socket Security Changes
on Sun, Mar 21 2010 1:59 AM

Great news! You don't happen to know if the policy security in SL4 now allow a WebReference to a WCF service to use different target endpoint addresses as opposed to SL3? As an example we're using SL3 to show some real time data served from WCF. To be able to receive data from multiple services for redundancy we had to create one WebReference for each service since SL3 does not allow one to just set a different EndpointAddress.

Peter Gfader wrote re: Silverlight 4 RC – Socket Security Changes
on Sun, Mar 21 2010 4:56 AM

Hi Mike

Thanks for that info!

Do you know how you can set the property

SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Http

when using a WCF generated proxy?

Code like in this example from Tomasz

tomasz.janczuk.org/.../pubsub-sample-with-wcf-nettcp-protocol.html

THANKS HEAPS!

Gui wrote re: Silverlight 4 RC – Socket Security Changes
on Mon, Mar 22 2010 4:11 AM

Can a port more firewall friendly be used in trusted? like 80 or 8080 , or the 4502 to 4534 restriction still apply?

ty

Microsoft Weblogs wrote Windows Client Developer Roundup for 3/22/2010
on Mon, Mar 22 2010 6:50 AM

This is Windows Client Developer roundup #17, the post-MIX10 edition. You can find my own MIX10 recap

Community Blogs wrote Windows Client Developer Roundup for 3/22/2010
on Mon, Mar 22 2010 6:51 AM

This is Windows Client Developer roundup #17, the post-MIX10 edition. You can find my own MIX10 recap

JC wrote re: Silverlight 4 RC – Socket Security Changes
on Mon, Mar 22 2010 9:12 AM

Hi Mike,

How does one go about marking an app as trusted?

Gui wrote re: Silverlight 4 RC – Socket Security Changes
on Mon, Mar 22 2010 2:53 PM

With a trusted application does the  4502 to 4534 port limitation disappear? and can we build a silverlight socket application? this would enable some p2p and also some interesting scenarios

mtaulty wrote re: Silverlight 4 RC – Socket Security Changes
on Tue, Mar 23 2010 10:23 AM

Gui - yes, AFAIK the restriction on ports 4502-4534 goes away for trusted applications but, no, Silverlight does not _listen_ on sockets and act as a server.

JC - in order to make an app trusted you go into its out of browser settings in Visual Studio and mark it as requiring elevation. The user then gets a warning dialog when they install it. There is also the notion of a verified trusted application which is one that has been signed.

Peter - As far as I know, for WCF using TCP the policy is _always_ download via HTTP rather than via TCP.

Robert - not sure on your comment. You should be able to use ClientBase<T> and spin that up with a particular binding and endpoint ( whether via configuration or just via code ) so I'm not sure why you couldn't "move" one proxy to point to another location _unless_ you are saying that cross-domain policy wouldn't let you in which case you should be able to use a client access policy file to remediate?

Mike

Anonymous wrote re: Silverlight 4 RC – Socket Security Changes
on Wed, Mar 24 2010 2:00 AM

Hi Mike

>>As far as I know, for WCF using TCP the policy is _always_ download via HTTP rather than via TCP.

You are right...

THanks!

Shawn Wildermuth wrote re: Silverlight 4 RC – Socket Security Changes
on Sat, Mar 27 2010 4:50 PM

>> and all those restrictions go away if you’re running trusted.

Don't you mean 'elevated'?

mtaulty wrote re: Silverlight 4 RC – Socket Security Changes
on Sun, Mar 28 2010 9:55 PM

Shawn - yeah, maybe :-)

"all those restrictions go away if you're running as a trusted application - i.e. with elevated permission".

How's that? ;-)

Mike.

PatM wrote re: Silverlight 4 RC – Socket Security Changes
on Tue, May 4 2010 12:01 PM

Is the source code for the screencasts available somewhere?

visit the next website page wrote visit the next website page
on Fri, Sep 19 2014 6:49 AM

Silverlight 4 RC – Socket Security Changes - Mike Taulty's Blog - Mike Taulty's Blog

family lawyer london wrote family lawyer london
on Thu, Oct 23 2014 2:20 PM

Silverlight 4 RC – Socket Security Changes - Mike Taulty's Blog - Mike Taulty's Blog