Fix for pull request #85

This commit is contained in:
sta 2014-10-30 19:09:12 +09:00
parent 956f16a162
commit 912b1f0d62
11 changed files with 419 additions and 263 deletions

View File

@ -36,6 +36,13 @@
*/ */
#endregion #endregion
#region Contributors
/*
* Contributors:
* - Liryna <liryna.stark@gmail.com>
*/
#endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
@ -554,10 +561,11 @@ namespace WebSocketSharp
this TcpClient tcpClient, this TcpClient tcpClient,
string protocol, string protocol,
bool secure, bool secure,
ServerSslAuthConfiguration certificateConfig, ServerSslAuthConfiguration sslConfiguration,
Logger logger) Logger logger)
{ {
return new TcpListenerWebSocketContext (tcpClient, protocol, secure, certificateConfig, logger); return new TcpListenerWebSocketContext (
tcpClient, protocol, secure, sslConfiguration, logger);
} }
internal static byte[] InternalToByteArray (this ushort value, ByteOrder order) internal static byte[] InternalToByteArray (this ushort value, ByteOrder order)

View File

@ -5,6 +5,7 @@
* The MIT License * The MIT License
* *
* Copyright (c) 2014 liryna * Copyright (c) 2014 liryna
* Copyright (c) 2014 sta.blockhead
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -29,7 +30,7 @@
#region Authors #region Authors
/* /*
* Authors: * Authors:
* - Liryna liryna.stark@gmail.com * - Liryna <liryna.stark@gmail.com>
*/ */
#endregion #endregion
@ -44,57 +45,94 @@ namespace WebSocketSharp.Net
/// </summary> /// </summary>
public class ClientSslAuthConfiguration public class ClientSslAuthConfiguration
{ {
/// <summary> #region Public Constructors
/// Gets or sets the certificate configuration used to authenticate the clients on the secure connection.
/// </summary>
/// <value>
/// A <see cref="X509CertificateCollection"/> that represents the certificate collection used to authenticate
/// the clients.
/// </value>
public X509CertificateCollection clientCertificates { get; set; }
/// <summary> /// <summary>
/// Gets or sets the Ssl protocols type enabled. /// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with
/// the specified <paramref name="clientCertificates"/>.
/// </summary> /// </summary>
/// <value> /// <param name="clientCertificates">
/// The <see cref="SslProtocols"/> value that represents the protocol used for authentication. /// A <see cref="X509CertificateCollection"/> that contains client certificates.
/// </value> /// </param>
public SslProtocols EnabledSslProtocols { get; set; } public ClientSslAuthConfiguration (X509CertificateCollection clientCertificates)
: this (clientCertificates, SslProtocols.Default, false)
{
}
/// <summary> /// <summary>
/// Gets or sets the verification of certificate revocation option. /// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with
/// the specified <paramref name="clientCertificates"/> and
/// <paramref name="enabledSslProtocols"/>.
/// </summary>
/// <param name="clientCertificates">
/// A <see cref="X509CertificateCollection"/> that contains client certificates.
/// </param>
/// <param name="enabledSslProtocols">
/// The <see cref="SslProtocols"/> enum value that represents the protocols used for
/// authentication.
/// </param>
public ClientSslAuthConfiguration (
X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols)
: this (clientCertificates, enabledSslProtocols, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class with
/// the specified <paramref name="clientCertificates"/>, <paramref name="enabledSslProtocols"/>,
/// and <paramref name="checkCertificateRevocation"/>.
/// </summary>
/// <param name="clientCertificates">
/// A <see cref="X509CertificateCollection"/> that contains client certificates.
/// </param>
/// <param name="enabledSslProtocols">
/// The <see cref="SslProtocols"/> enum value that represents the protocols used for
/// authentication.
/// </param>
/// <param name="checkCertificateRevocation">
/// <c>true</c> if the certificate revocation list is checked during authentication;
/// otherwise, <c>false</c>.
/// </param>
public ClientSslAuthConfiguration (
X509CertificateCollection clientCertificates,
SslProtocols enabledSslProtocols,
bool checkCertificateRevocation)
{
ClientCertificates = clientCertificates;
EnabledSslProtocols = enabledSslProtocols;
CheckCertificateRevocation = checkCertificateRevocation;
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether the certificate revocation list is checked
/// during authentication.
/// </summary> /// </summary>
/// <value> /// <value>
/// A Boolean value that specifies whether the certificate revocation list is checked during authentication. /// <c>true</c> if the certificate revocation list is checked; otherwise, <c>false</c>.
/// </value> /// </value>
public bool CheckCertificateRevocation { get; set; } public bool CheckCertificateRevocation { get; set; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class. /// Gets or sets the collection that contains client certificates.
/// </summary> /// </summary>
public ClientSslAuthConfiguration(X509CertificateCollection clientCertificates) /// <value>
: this(clientCertificates, SslProtocols.Default, false) /// A <see cref="X509CertificateCollection"/> that contains client certificates.
{ /// </value>
} public X509CertificateCollection ClientCertificates { get; set; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class. /// Gets or sets the SSL protocols used for authentication.
/// </summary> /// </summary>
public ClientSslAuthConfiguration(X509CertificateCollection clientCertificates, /// <value>
SslProtocols enabledSslProtocols) /// The <see cref="SslProtocols"/> enum value that represents the protocols used for
: this(clientCertificates, enabledSslProtocols, false) /// authentication.
{ /// </value>
} public SslProtocols EnabledSslProtocols { get; set; }
/// <summary> #endregion
/// Initializes a new instance of the <see cref="ClientSslAuthConfiguration"/> class.
/// </summary>
public ClientSslAuthConfiguration(X509CertificateCollection clientCertificates,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
this.clientCertificates = clientCertificates;
this.EnabledSslProtocols = enabledSslProtocols;
this.CheckCertificateRevocation = checkCertificateRevocation;
}
} }
} }

View File

@ -37,6 +37,13 @@
*/ */
#endregion #endregion
#region Contributors
/*
* Contributors:
* - Liryna <liryna.stark@gmail.com>
*/
#endregion
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -54,12 +61,12 @@ namespace WebSocketSharp.Net
#region Private Fields #region Private Fields
private List<HttpListenerPrefix> _all; // host == '+' private List<HttpListenerPrefix> _all; // host == '+'
private ServerSslAuthConfiguration _sslAuthenticationConfig;
private static readonly string _defaultCertFolderPath; private static readonly string _defaultCertFolderPath;
private IPEndPoint _endpoint; private IPEndPoint _endpoint;
private Dictionary<HttpListenerPrefix, HttpListener> _prefixes; private Dictionary<HttpListenerPrefix, HttpListener> _prefixes;
private bool _secure; private bool _secure;
private Socket _socket; private Socket _socket;
private ServerSslAuthConfiguration _sslConfig;
private List<HttpListenerPrefix> _unhandled; // host == '*' private List<HttpListenerPrefix> _unhandled; // host == '*'
private Dictionary<HttpConnection, HttpConnection> _unregistered; private Dictionary<HttpConnection, HttpConnection> _unregistered;
private object _unregisteredSync; private object _unregisteredSync;
@ -83,14 +90,17 @@ namespace WebSocketSharp.Net
int port, int port,
bool secure, bool secure,
string certificateFolderPath, string certificateFolderPath,
ServerSslAuthConfiguration defaultCertificate, ServerSslAuthConfiguration sslConfiguration,
bool reuseAddress) bool reuseAddress)
{ {
if (secure) { if (secure) {
_secure = secure; var cert = getCertificate (port, certificateFolderPath, sslConfiguration.ServerCertificate);
_sslAuthenticationConfig = getCertificate(port, certificateFolderPath, defaultCertificate); if (cert == null)
if (_sslAuthenticationConfig == null)
throw new ArgumentException ("No server certificate could be found."); throw new ArgumentException ("No server certificate could be found.");
_secure = secure;
_sslConfig = sslConfiguration;
_sslConfig.ServerCertificate = cert;
} }
_prefixes = new Dictionary<HttpListenerPrefix, HttpListener> (); _prefixes = new Dictionary<HttpListenerPrefix, HttpListener> ();
@ -116,19 +126,18 @@ namespace WebSocketSharp.Net
#region Public Properties #region Public Properties
public ServerSslAuthConfiguration CertificateConfig
{
get {
return _sslAuthenticationConfig;
}
}
public bool IsSecure { public bool IsSecure {
get { get {
return _secure; return _secure;
} }
} }
public ServerSslAuthConfiguration SslConfiguration {
get {
return _sslConfig;
}
}
#endregion #endregion
#region Private Methods #region Private Methods
@ -174,8 +183,8 @@ namespace WebSocketSharp.Net
return rsa; return rsa;
} }
private static ServerSslAuthConfiguration getCertificate( private static X509Certificate2 getCertificate (
int port, string certificateFolderPath, ServerSslAuthConfiguration defaultCertificate) int port, string certificateFolderPath, X509Certificate2 defaultCertificate)
{ {
if (certificateFolderPath == null || certificateFolderPath.Length == 0) if (certificateFolderPath == null || certificateFolderPath.Length == 0)
certificateFolderPath = _defaultCertFolderPath; certificateFolderPath = _defaultCertFolderPath;
@ -187,7 +196,7 @@ namespace WebSocketSharp.Net
var cert = new X509Certificate2 (cer); var cert = new X509Certificate2 (cer);
cert.PrivateKey = createRSAFromFile (key); cert.PrivateKey = createRSAFromFile (key);
return new ServerSslAuthConfiguration(cert); return cert;
} }
} }
catch { catch {

View File

@ -37,6 +37,13 @@
*/ */
#endregion #endregion
#region Contributors
/*
* Contributors:
* - Liryna <liryna.stark@gmail.com>
*/
#endregion
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -107,7 +114,7 @@ namespace WebSocketSharp.Net
port, port,
secure, secure,
httpListener.CertificateFolderPath, httpListener.CertificateFolderPath,
httpListener.DefaultSslAuthenticationConfig, httpListener.DefaultSslConfiguration,
httpListener.ReuseAddress); httpListener.ReuseAddress);
eps[port] = epl; eps[port] = epl;

View File

@ -37,6 +37,13 @@
*/ */
#endregion #endregion
#region Contributors
/*
* Contributors:
* - Liryna <liryna.stark@gmail.com>
*/
#endregion
using System; using System;
using System.IO; using System.IO;
using System.Net; using System.Net;
@ -87,10 +94,13 @@ namespace WebSocketSharp.Net
var netStream = new NetworkStream (socket, false); var netStream = new NetworkStream (socket, false);
if (_secure) { if (_secure) {
var sslStream = new SslStream (netStream, false); var sslStream = new SslStream (netStream, false);
var certificateConfig = listener.CertificateConfig; var sslConfig = listener.SslConfiguration;
sslStream.AuthenticateAsServer(certificateConfig.ServerCertificate, sslStream.AuthenticateAsServer (
certificateConfig.ClientCertificateRequired, certificateConfig.EnabledSslProtocols, sslConfig.ServerCertificate,
certificateConfig.CheckCertificateRevocation); sslConfig.ClientCertificateRequired,
sslConfig.EnabledSslProtocols,
sslConfig.CheckCertificateRevocation);
_stream = sslStream; _stream = sslStream;
} }
else { else {

View File

@ -37,6 +37,13 @@
*/ */
#endregion #endregion
#region Contributors
/*
* Contributors:
* - Liryna <liryna.stark@gmail.com>
*/
#endregion
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -64,7 +71,7 @@ namespace WebSocketSharp.Net
private Dictionary<HttpListenerContext, HttpListenerContext> _ctxRegistry; private Dictionary<HttpListenerContext, HttpListenerContext> _ctxRegistry;
private object _ctxRegistrySync; private object _ctxRegistrySync;
private Func<IIdentity, NetworkCredential> _credFinder; private Func<IIdentity, NetworkCredential> _credFinder;
private ServerSslAuthConfiguration _defaultSslAuthenticationConfig; private ServerSslAuthConfiguration _defaultSslConfig;
private bool _disposed; private bool _disposed;
private bool _ignoreWriteExceptions; private bool _ignoreWriteExceptions;
private bool _listening; private bool _listening;
@ -213,27 +220,25 @@ namespace WebSocketSharp.Net
} }
/// <summary> /// <summary>
/// Gets or sets the default Ssl configuration used to authenticate the server on the secure /// Gets or sets the default SSL configuration used to authenticate the server and
/// connection. /// optionally the client on the secure connection.
/// </summary> /// </summary>
/// <value> /// <value>
/// A <see cref="ServerSslAuthConfiguration"/> used to authenticate the server if the certificate /// A <see cref="ServerSslAuthConfiguration"/> that represents the SSL configuration used to
/// files aren't found in the <see cref="CertificateFolderPath"/>. The default value is /// authenticate the server optionally the client. The default value is <see langword="null"/>.
/// <see langword="null"/>.
/// </value> /// </value>
/// <exception cref="ObjectDisposedException"> /// <exception cref="ObjectDisposedException">
/// This listener has been closed. /// This listener has been closed.
/// </exception> /// </exception>
public ServerSslAuthConfiguration DefaultSslAuthenticationConfig public ServerSslAuthConfiguration DefaultSslConfiguration {
{
get { get {
CheckDisposed (); CheckDisposed ();
return _defaultSslAuthenticationConfig; return _defaultSslConfig;
} }
set { set {
CheckDisposed (); CheckDisposed ();
_defaultSslAuthenticationConfig = value; _defaultSslConfig = value;
} }
} }

View File

@ -5,6 +5,7 @@
* The MIT License * The MIT License
* *
* Copyright (c) 2014 liryna * Copyright (c) 2014 liryna
* Copyright (c) 2014 sta.blockhead
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -29,7 +30,7 @@
#region Authors #region Authors
/* /*
* Authors: * Authors:
* - Liryna liryna.stark@gmail.com * - Liryna <liryna.stark@gmail.com>
*/ */
#endregion #endregion
@ -44,6 +45,130 @@ namespace WebSocketSharp.Net
/// </summary> /// </summary>
public class ServerSslAuthConfiguration public class ServerSslAuthConfiguration
{ {
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class with
/// the specified <paramref name="serverCertificate"/>.
/// </summary>
/// <param name="serverCertificate">
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
/// the server.
/// </param>
public ServerSslAuthConfiguration (X509Certificate2 serverCertificate)
: this (serverCertificate, false, SslProtocols.Default, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class with
/// the specified <paramref name="serverCertificate"/> and
/// <paramref name="clientCertificateRequired"/>.
/// </summary>
/// <param name="serverCertificate">
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
/// the server.
/// </param>
/// <param name="clientCertificateRequired">
/// <c>true</c> if the client must supply a certificate for authentication;
/// otherwise, <c>false</c>.
/// </param>
public ServerSslAuthConfiguration (
X509Certificate2 serverCertificate, bool clientCertificateRequired)
: this (serverCertificate, clientCertificateRequired, SslProtocols.Default, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class with
/// the specified <paramref name="serverCertificate"/>,
/// <paramref name="clientCertificateRequired"/>, and <paramref name="enabledSslProtocols"/>.
/// </summary>
/// <param name="serverCertificate">
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
/// the server.
/// </param>
/// <param name="clientCertificateRequired">
/// <c>true</c> if the client must supply a certificate for authentication;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="enabledSslProtocols">
/// The <see cref="SslProtocols"/> enum value that represents the protocols used for
/// authentication.
/// </param>
public ServerSslAuthConfiguration (
X509Certificate2 serverCertificate,
bool clientCertificateRequired,
SslProtocols enabledSslProtocols)
: this (serverCertificate, clientCertificateRequired, enabledSslProtocols, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class with
/// the specified <paramref name="serverCertificate"/>,
/// <paramref name="clientCertificateRequired"/>, <paramref name="enabledSslProtocols"/>,
/// and <paramref name="checkCertificateRevocation"/>.
/// </summary>
/// <param name="serverCertificate">
/// A <see cref="X509Certificate2"/> that represents the certificate used to authenticate
/// the server.
/// </param>
/// <param name="clientCertificateRequired">
/// <c>true</c> if the client must supply a certificate for authentication;
/// otherwise, <c>false</c>.
/// </param>
/// <param name="enabledSslProtocols">
/// The <see cref="SslProtocols"/> enum value that represents the protocols used for
/// authentication.
/// </param>
/// <param name="checkCertificateRevocation">
/// <c>true</c> if the certificate revocation list is checked during authentication;
/// otherwise, <c>false</c>.
/// </param>
public ServerSslAuthConfiguration (
X509Certificate2 serverCertificate,
bool clientCertificateRequired,
SslProtocols enabledSslProtocols,
bool checkCertificateRevocation)
{
ServerCertificate = serverCertificate;
ClientCertificateRequired = clientCertificateRequired;
EnabledSslProtocols = enabledSslProtocols;
CheckCertificateRevocation = checkCertificateRevocation;
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether the certificate revocation list is checked
/// during authentication.
/// </summary>
/// <value>
/// <c>true</c> if the certificate revocation list is checked; otherwise, <c>false</c>.
/// </value>
public bool CheckCertificateRevocation { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the client must supply a certificate for
/// authentication.
/// </summary>
/// <value>
/// <c>true</c> if the client must supply a certificate; otherwise, <c>false</c>.
/// </value>
public bool ClientCertificateRequired { get; set; }
/// <summary>
/// Gets or sets the SSL protocols used for authentication.
/// </summary>
/// <value>
/// The <see cref="SslProtocols"/> enum value that represents the protocols used for
/// authentication.
/// </value>
public SslProtocols EnabledSslProtocols { get; set; }
/// <summary> /// <summary>
/// Gets or sets the certificate used to authenticate the server on the secure connection. /// Gets or sets the certificate used to authenticate the server on the secure connection.
/// </summary> /// </summary>
@ -53,65 +178,6 @@ namespace WebSocketSharp.Net
/// </value> /// </value>
public X509Certificate2 ServerCertificate { get; set; } public X509Certificate2 ServerCertificate { get; set; }
/// <summary> #endregion
/// Gets or sets the client certificate request option.
/// </summary>
/// <value>
/// A Boolean value that specifies whether the client must supply a certificate for authentication.
/// </value>
public bool ClientCertificateRequired { get; set; }
/// <summary>
/// Gets or sets the Ssl protocols type enabled.
/// </summary>
/// <value>
/// The <see cref="SslProtocols"/> value that represents the protocol used for authentication.
/// </value>
public SslProtocols EnabledSslProtocols { get; set; }
/// <summary>
/// Gets or sets the verification of certificate revocation option.
/// </summary>
/// <value>
/// A Boolean value that specifies whether the certificate revocation list is checked during authentication.
/// </value>
public bool CheckCertificateRevocation { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class.
/// </summary>
public ServerSslAuthConfiguration(X509Certificate2 serverCertificate)
: this(serverCertificate, false, SslProtocols.Default, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class.
/// </summary>
public ServerSslAuthConfiguration(X509Certificate2 serverCertificate, bool clientCertificateRequired)
: this(serverCertificate, clientCertificateRequired, SslProtocols.Default, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class.
/// </summary>
public ServerSslAuthConfiguration(X509Certificate2 serverCertificate, bool clientCertificateRequired,
SslProtocols enabledSslProtocols)
: this(serverCertificate, clientCertificateRequired, enabledSslProtocols, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ServerSslAuthConfiguration"/> class.
/// </summary>
public ServerSslAuthConfiguration(X509Certificate2 serverCertificate, bool clientCertificateRequired,
SslProtocols enabledSslProtocols, bool checkCertificateRevocation)
{
this.ServerCertificate = serverCertificate;
this.ClientCertificateRequired = clientCertificateRequired;
this.EnabledSslProtocols = enabledSslProtocols;
this.CheckCertificateRevocation = checkCertificateRevocation;
}
} }
} }

View File

@ -26,6 +26,13 @@
*/ */
#endregion #endregion
#region Contributors
/*
* Contributors:
* - Liryna <liryna.stark@gmail.com>
*/
#endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
@ -61,7 +68,11 @@ namespace WebSocketSharp.Net.WebSockets
#region Internal Constructors #region Internal Constructors
internal TcpListenerWebSocketContext ( internal TcpListenerWebSocketContext (
TcpClient tcpClient, string protocol, bool secure, ServerSslAuthConfiguration certificateConfig, Logger logger) TcpClient tcpClient,
string protocol,
bool secure,
ServerSslAuthConfiguration sslConfiguration,
Logger logger)
{ {
_tcpClient = tcpClient; _tcpClient = tcpClient;
_secure = secure; _secure = secure;
@ -69,9 +80,12 @@ namespace WebSocketSharp.Net.WebSockets
var netStream = tcpClient.GetStream (); var netStream = tcpClient.GetStream ();
if (secure) { if (secure) {
var sslStream = new SslStream (netStream, false); var sslStream = new SslStream (netStream, false);
sslStream.AuthenticateAsServer(certificateConfig.ServerCertificate, sslStream.AuthenticateAsServer (
certificateConfig.ClientCertificateRequired, certificateConfig.EnabledSslProtocols, sslConfiguration.ServerCertificate,
certificateConfig.CheckCertificateRevocation); sslConfiguration.ClientCertificateRequired,
sslConfiguration.EnabledSslProtocols,
sslConfiguration.CheckCertificateRevocation);
_stream = sslStream; _stream = sslStream;
} }
else { else {

View File

@ -32,6 +32,7 @@
/* /*
* Contributors: * Contributors:
* - Juan Manuel Lallana <juan.manuel.lallana@gmail.com> * - Juan Manuel Lallana <juan.manuel.lallana@gmail.com>
* - Liryna <liryna.stark@gmail.com>
*/ */
#endregion #endregion
@ -180,33 +181,6 @@ namespace WebSocketSharp.Server
} }
} }
/// <summary>
/// Gets or sets the Ssl configuration used to authenticate the server on the secure connection.
/// </summary>
/// <value>
/// A <see cref="ServerSslAuthConfiguration"/> that represents the Ssl configuration used to authenticate
/// the server.
/// </value>
public ServerSslAuthConfiguration CertificateConfig
{
get {
return _listener.DefaultSslAuthenticationConfig;
}
set {
var msg = _state.CheckIfStartable ();
if (msg != null) {
_logger.Error (msg);
return;
}
if (EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath))
_logger.Warn ("The server certificate associated with the port number already exists.");
_listener.DefaultSslAuthenticationConfig = value;
}
}
/// <summary> /// <summary>
/// Gets a value indicating whether the server has started. /// Gets a value indicating whether the server has started.
/// </summary> /// </summary>
@ -360,6 +334,33 @@ namespace WebSocketSharp.Server
} }
} }
/// <summary>
/// Gets or sets the SSL configuration used to authenticate the server and optionally the client
/// on the secure connection.
/// </summary>
/// <value>
/// A <see cref="ServerSslAuthConfiguration"/> that represents the SSL configuration used to
/// authenticate the server and optionally the client.
/// </value>
public ServerSslAuthConfiguration SslConfiguration {
get {
return _listener.DefaultSslConfiguration;
}
set {
var msg = _state.CheckIfStartable ();
if (msg != null) {
_logger.Error (msg);
return;
}
if (EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath))
_logger.Warn ("The server certificate associated with the port number already exists.");
_listener.DefaultSslConfiguration = value;
}
}
/// <summary> /// <summary>
/// Gets or sets the delegate called to find the credentials for an identity used to /// Gets or sets the delegate called to find the credentials for an identity used to
/// authenticate a client. /// authenticate a client.
@ -509,7 +510,8 @@ namespace WebSocketSharp.Server
{ {
return _secure && return _secure &&
!EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath) && !EndPointListener.CertificateExists (_port, _listener.CertificateFolderPath) &&
_listener.DefaultSslAuthenticationConfig == null (_listener.DefaultSslConfiguration == null ||
_listener.DefaultSslConfiguration.ServerCertificate == null)
? "The secure connection requires a server certificate." ? "The secure connection requires a server certificate."
: null; : null;
} }

View File

@ -33,6 +33,7 @@
* Contributors: * Contributors:
* - Juan Manuel Lallana <juan.manuel.lallana@gmail.com> * - Juan Manuel Lallana <juan.manuel.lallana@gmail.com>
* - Jonas Hovgaard <j@jhovgaard.dk> * - Jonas Hovgaard <j@jhovgaard.dk>
* - Liryna <liryna.stark@gmail.com>
*/ */
#endregion #endregion
@ -60,7 +61,6 @@ namespace WebSocketSharp.Server
private System.Net.IPAddress _address; private System.Net.IPAddress _address;
private AuthenticationSchemes _authSchemes; private AuthenticationSchemes _authSchemes;
private ServerSslAuthConfiguration _certificateConfig;
private Func<IIdentity, NetworkCredential> _credentialsFinder; private Func<IIdentity, NetworkCredential> _credentialsFinder;
private TcpListener _listener; private TcpListener _listener;
private Logger _logger; private Logger _logger;
@ -70,6 +70,7 @@ namespace WebSocketSharp.Server
private bool _reuseAddress; private bool _reuseAddress;
private bool _secure; private bool _secure;
private WebSocketServiceManager _services; private WebSocketServiceManager _services;
private ServerSslAuthConfiguration _sslConfig;
private volatile ServerState _state; private volatile ServerState _state;
private object _sync; private object _sync;
private Uri _uri; private Uri _uri;
@ -311,30 +312,6 @@ namespace WebSocketSharp.Server
} }
} }
/// <summary>
/// Gets or sets the certificate configuration used to authenticate the server on the secure connection.
/// </summary>
/// <value>
/// A <see cref="ServerSslAuthConfiguration"/> that represents the certificate configuration used to authenticate
/// the server.
/// </value>
public ServerSslAuthConfiguration SslAuthenticationConfig
{
get {
return _certificateConfig;
}
set {
var msg = _state.CheckIfStartable ();
if (msg != null) {
_logger.Error (msg);
return;
}
_certificateConfig = value;
}
}
/// <summary> /// <summary>
/// Gets a value indicating whether the server has started. /// Gets a value indicating whether the server has started.
/// </summary> /// </summary>
@ -463,6 +440,30 @@ namespace WebSocketSharp.Server
} }
} }
/// <summary>
/// Gets or sets the SSL configuration used to authenticate the server and optionally the client
/// on the secure connection.
/// </summary>
/// <value>
/// A <see cref="ServerSslAuthConfiguration"/> that represents the SSL configuration used to
/// authenticate the server and optionally the client.
/// </value>
public ServerSslAuthConfiguration SslConfiguration {
get {
return _sslConfig;
}
set {
var msg = _state.CheckIfStartable ();
if (msg != null) {
_logger.Error (msg);
return;
}
_sslConfig = value;
}
}
/// <summary> /// <summary>
/// Gets or sets the delegate called to find the credentials for an identity used to /// Gets or sets the delegate called to find the credentials for an identity used to
/// authenticate a client. /// authenticate a client.
@ -588,8 +589,7 @@ namespace WebSocketSharp.Server
private string checkIfCertificateExists () private string checkIfCertificateExists ()
{ {
return _secure && (_certificateConfig == null return _secure && (_sslConfig == null || _sslConfig.ServerCertificate == null)
|| _certificateConfig != null && _certificateConfig.ServerCertificate == null)
? "The secure connection requires a server certificate." ? "The secure connection requires a server certificate."
: null; : null;
} }
@ -640,7 +640,7 @@ namespace WebSocketSharp.Server
ThreadPool.QueueUserWorkItem ( ThreadPool.QueueUserWorkItem (
state => { state => {
try { try {
var ctx = cl.GetWebSocketContext (null, _secure, _certificateConfig, _logger); var ctx = cl.GetWebSocketContext (null, _secure, _sslConfig, _logger);
if (_authSchemes != AuthenticationSchemes.Anonymous && if (_authSchemes != AuthenticationSchemes.Anonymous &&
!authenticateRequest (_authSchemes, ctx)) !authenticateRequest (_authSchemes, ctx))
return; return;

View File

@ -37,6 +37,7 @@
* Contributors: * Contributors:
* - Frank Razenberg <frank@zzattack.org> * - Frank Razenberg <frank@zzattack.org>
* - David Wood <dpwood@gmail.com> * - David Wood <dpwood@gmail.com>
* - Liryna <liryna.stark@gmail.com>
*/ */
#endregion #endregion
@ -71,8 +72,6 @@ namespace WebSocketSharp
private string _base64Key; private string _base64Key;
private LocalCertificateSelectionCallback private LocalCertificateSelectionCallback
_certSelectionCallback; _certSelectionCallback;
private ClientSslAuthConfiguration
_certificateConfig;
private RemoteCertificateValidationCallback private RemoteCertificateValidationCallback
_certValidationCallback; _certValidationCallback;
private bool _client; private bool _client;
@ -102,6 +101,8 @@ namespace WebSocketSharp
private volatile WebSocketState _readyState; private volatile WebSocketState _readyState;
private AutoResetEvent _receivePong; private AutoResetEvent _receivePong;
private bool _secure; private bool _secure;
private ClientSslAuthConfiguration
_sslConfig;
private Stream _stream; private Stream _stream;
private TcpClient _tcpClient; private TcpClient _tcpClient;
private Uri _uri; private Uri _uri;
@ -463,40 +464,6 @@ namespace WebSocketSharp
} }
} }
/// <summary>
/// Gets or sets the certificate configuration used to authenticate the client on the secure connection.
/// </summary>
/// <value>
/// A <see cref="ClientSslAuthConfiguration"/> that represents the certificate configuration used to authenticate
/// the client.
/// </value>
public ClientSslAuthConfiguration SslAuthenticationConfig
{
get
{
return _certificateConfig;
}
set
{
lock (_forConn)
{
var msg = checkIfAvailable(false, false);
if (msg != null)
{
_logger.Error(msg);
error(
"An error has occurred in setting the server certificate configuration.",
null);
return;
}
_certificateConfig = value;
}
}
}
/// <summary> /// <summary>
/// Gets or sets the callback used to validate the certificate supplied by the server. /// Gets or sets the callback used to validate the certificate supplied by the server.
/// </summary> /// </summary>
@ -530,6 +497,34 @@ namespace WebSocketSharp
} }
} }
/// <summary>
/// Gets or sets the SSL configuration used to authenticate the server and optionally the client
/// on the secure connection.
/// </summary>
/// <value>
/// A <see cref="ClientSslAuthConfiguration"/> that represents the SSL configuration used to
/// authenticate the server and optionally the client.
/// </value>
public ClientSslAuthConfiguration SslConfiguration {
get {
return _sslConfig;
}
set {
lock (_forConn) {
var msg = checkIfAvailable (false, false);
if (msg != null) {
_logger.Error (msg);
error ("An error has occurred in setting the ssl configuration.", null);
return;
}
_sslConfig = value;
}
}
}
/// <summary> /// <summary>
/// Gets the WebSocket URL to connect. /// Gets the WebSocket URL to connect.
/// </summary> /// </summary>
@ -1379,13 +1374,15 @@ namespace WebSocketSharp
((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => ((sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) =>
null)); null));
if (_certificateConfig == null) if (_sslConfig == null)
sslStream.AuthenticateAsClient(_uri.DnsSafeHost); sslStream.AuthenticateAsClient (_uri.DnsSafeHost);
else else
{ sslStream.AuthenticateAsClient (
sslStream.AuthenticateAsClient(_uri.DnsSafeHost, _certificateConfig.clientCertificates, _uri.DnsSafeHost,
_certificateConfig.EnabledSslProtocols, _certificateConfig.CheckCertificateRevocation); _sslConfig.ClientCertificates,
} _sslConfig.EnabledSslProtocols,
_sslConfig.CheckCertificateRevocation);
_stream = sslStream; _stream = sslStream;
} }
} }