Implemented the server form. Client <-> Server interaction actually works.
Fixed a few bugs in the CustomServer - wasn't configuring the listen socket correctly, doing read/write operations from the wrong socket, etc. Reworked how the CustomConnection class handles serialization. Added Disconnected events to the sample's CustomConnection and CustomServer classes so the forms could reset state.
This commit is contained in:
1
TestClient/Form1.Designer.cs
generated
1
TestClient/Form1.Designer.cs
generated
@@ -75,6 +75,7 @@
|
||||
this.serverTextBox.Name = "serverTextBox";
|
||||
this.serverTextBox.Size = new System.Drawing.Size(137, 20);
|
||||
this.serverTextBox.TabIndex = 2;
|
||||
this.serverTextBox.Text = "localhost";
|
||||
//
|
||||
// portNumeric
|
||||
//
|
||||
|
||||
@@ -40,14 +40,13 @@ namespace TestClient
|
||||
InitializeComponent();
|
||||
|
||||
this.connectButton.Click += connectButton_Click;
|
||||
|
||||
this.disconnectButton.Click += disconnectButton_Click;
|
||||
|
||||
|
||||
this.encryptButton.Click += encryptButton_Click;
|
||||
|
||||
this.signButton.Click += signButton_Click;
|
||||
|
||||
this.FormClosing += Form1_FormClosing;
|
||||
|
||||
// --- SSPI ---
|
||||
this.cred = new ClientCredential( SecurityPackage.Negotiate );
|
||||
|
||||
@@ -64,6 +63,7 @@ namespace TestClient
|
||||
|
||||
this.connection = new CustomConnection();
|
||||
this.connection.Received += connection_Received;
|
||||
this.connection.Disconnected += connection_Disconnected;
|
||||
|
||||
// --- UI Fillout ---
|
||||
this.usernameTextbox.Text = this.cred.Name;
|
||||
@@ -71,6 +71,11 @@ namespace TestClient
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void Form1_FormClosing( object sender, FormClosingEventArgs e )
|
||||
{
|
||||
this.connection.Stop();
|
||||
}
|
||||
|
||||
private void connectButton_Click( object sender, EventArgs e )
|
||||
{
|
||||
if( string.IsNullOrWhiteSpace( this.serverTextBox.Text ) )
|
||||
@@ -82,6 +87,8 @@ namespace TestClient
|
||||
try
|
||||
{
|
||||
this.connection.StartClient( this.serverTextBox.Text, (int)this.portNumeric.Value );
|
||||
this.initializing = true;
|
||||
DoInit();
|
||||
}
|
||||
catch( SocketException socketExcept )
|
||||
{
|
||||
@@ -101,7 +108,6 @@ namespace TestClient
|
||||
}
|
||||
}
|
||||
|
||||
this.initializing = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +180,18 @@ namespace TestClient
|
||||
} );
|
||||
}
|
||||
|
||||
private void connection_Disconnected()
|
||||
{
|
||||
this.connected = false;
|
||||
this.initializing = false;
|
||||
this.lastServerToken = null;
|
||||
|
||||
this.Invoke( (Action)delegate()
|
||||
{
|
||||
UpdateButtons();
|
||||
});
|
||||
}
|
||||
|
||||
private void DoInit()
|
||||
{
|
||||
SecurityStatus status;
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace TestProtocol
|
||||
|
||||
public event ReceivedAction Received;
|
||||
|
||||
public event Action Disconnected;
|
||||
|
||||
public void StartClient( string server, int port )
|
||||
{
|
||||
if( this.running )
|
||||
@@ -49,7 +51,7 @@ namespace TestProtocol
|
||||
{
|
||||
if( this.running == false )
|
||||
{
|
||||
throw new InvalidOperationException( "Already stopped" );
|
||||
return;
|
||||
}
|
||||
|
||||
this.socket.Close();
|
||||
@@ -64,13 +66,19 @@ namespace TestProtocol
|
||||
}
|
||||
|
||||
byte[] outBuffer = new byte[ message.Data.Length + 8 ];
|
||||
int position = 0;
|
||||
|
||||
ByteWriter.WriteInt32_BE( (int)message.Operation, outBuffer, 0 );
|
||||
ByteWriter.WriteInt32_BE( message.Data.Length, outBuffer, 4 );
|
||||
ByteWriter.WriteInt32_BE( (int)message.Operation, outBuffer, position );
|
||||
position += 4;
|
||||
|
||||
Array.Copy( message.Data, 0, outBuffer, 8, message.Data.Length );
|
||||
ByteWriter.WriteInt32_BE( message.Data.Length, outBuffer, position );
|
||||
position += 4;
|
||||
|
||||
Array.Copy( message.Data, 0, outBuffer, position, message.Data.Length );
|
||||
|
||||
this.socket.Send( outBuffer, 0, outBuffer.Length, SocketFlags.None );
|
||||
|
||||
Console.Out.WriteLine( "Client: Sent " + message.Operation );
|
||||
}
|
||||
|
||||
private void ReceiveThreadEntry()
|
||||
@@ -82,7 +90,20 @@ namespace TestProtocol
|
||||
catch( Exception e )
|
||||
{
|
||||
MessageBox.Show( "The SspiConnection receive thread crashed:\r\n\r\n" + e.ToString() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.running = false;
|
||||
|
||||
try
|
||||
{
|
||||
if( this.Disconnected != null )
|
||||
{
|
||||
this.Disconnected();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +154,7 @@ namespace TestProtocol
|
||||
}
|
||||
}
|
||||
|
||||
Console.Out.WriteLine( "Client: Received " + operation );
|
||||
|
||||
if( this.Received != null )
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace TestProtocol
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -35,6 +36,8 @@ namespace TestProtocol
|
||||
|
||||
public event ReceivedAction Received;
|
||||
|
||||
public event Action Disconnected;
|
||||
|
||||
public void StartServer( int port )
|
||||
{
|
||||
if( this.running )
|
||||
@@ -43,6 +46,8 @@ namespace TestProtocol
|
||||
}
|
||||
|
||||
this.serverSocket = new Socket( SocketType.Stream, ProtocolType.Tcp );
|
||||
this.serverSocket.Bind( new IPEndPoint( IPAddress.Any, port ) );
|
||||
this.serverSocket.Listen( 1 );
|
||||
|
||||
this.running = true;
|
||||
|
||||
@@ -55,7 +60,7 @@ namespace TestProtocol
|
||||
{
|
||||
if( this.running == false )
|
||||
{
|
||||
throw new InvalidOperationException( "Already stopped" );
|
||||
return;
|
||||
}
|
||||
|
||||
this.serverSocket.Close();
|
||||
@@ -82,7 +87,9 @@ namespace TestProtocol
|
||||
|
||||
Array.Copy( message.Data, 0, outBuffer, 8, message.Data.Length );
|
||||
|
||||
this.serverSocket.Send( outBuffer, 0, outBuffer.Length, SocketFlags.None );
|
||||
this.readSocket.Send( outBuffer, 0, outBuffer.Length, SocketFlags.None );
|
||||
|
||||
Console.Out.WriteLine( "Server: Sent " + message.Operation );
|
||||
}
|
||||
|
||||
private void ReceiveThreadEntry()
|
||||
@@ -112,13 +119,25 @@ namespace TestProtocol
|
||||
}
|
||||
|
||||
ReadLoop();
|
||||
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
MessageBox.Show( "The SspiConnection receive thread crashed:\r\n\r\n" + e.ToString() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.running = false;
|
||||
|
||||
try
|
||||
{
|
||||
if( this.Disconnected != null )
|
||||
{
|
||||
this.Disconnected();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +157,7 @@ namespace TestProtocol
|
||||
|
||||
|
||||
// Read the operation.
|
||||
this.serverSocket.Receive( readBuffer, 4, SocketFlags.None );
|
||||
this.readSocket.Receive( readBuffer, 4, SocketFlags.None );
|
||||
|
||||
// Check if we popped out of a receive call after we were shut down.
|
||||
if( this.running == false ) { break; }
|
||||
@@ -146,11 +165,11 @@ namespace TestProtocol
|
||||
operation = (ProtocolOp)ByteWriter.ReadInt32_BE( readBuffer, 0 );
|
||||
|
||||
// Read the length
|
||||
this.serverSocket.Receive( readBuffer, 4, SocketFlags.None );
|
||||
this.readSocket.Receive( readBuffer, 4, SocketFlags.None );
|
||||
length = ByteWriter.ReadInt32_BE( readBuffer, 0 );
|
||||
|
||||
// Read the data
|
||||
this.serverSocket.Receive( readBuffer, length, SocketFlags.None );
|
||||
this.readSocket.Receive( readBuffer, length, SocketFlags.None );
|
||||
|
||||
}
|
||||
catch( SocketException e )
|
||||
@@ -169,6 +188,7 @@ namespace TestProtocol
|
||||
}
|
||||
}
|
||||
|
||||
Console.Out.WriteLine( "Server: Received " + operation );
|
||||
|
||||
if( this.Received != null )
|
||||
{
|
||||
@@ -180,7 +200,7 @@ namespace TestProtocol
|
||||
{
|
||||
this.Received( message );
|
||||
}
|
||||
catch( Exception e )
|
||||
catch( Exception )
|
||||
{ }
|
||||
}
|
||||
|
||||
|
||||
218
TestServer/Form1.Designer.cs
generated
218
TestServer/Form1.Designer.cs
generated
@@ -28,12 +28,226 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.portNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.startButton = new System.Windows.Forms.Button();
|
||||
this.stopButton = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.usernameTextbox = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.sendTextbox = new System.Windows.Forms.TextBox();
|
||||
this.receivedTextbox = new System.Windows.Forms.TextBox();
|
||||
this.encryptButton = new System.Windows.Forms.Button();
|
||||
this.signButton = new System.Windows.Forms.Button();
|
||||
((System.ComponentModel.ISupportInitialize)(this.portNumeric)).BeginInit();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 21);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(83, 13);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Port to listen on:";
|
||||
//
|
||||
// portNumeric
|
||||
//
|
||||
this.portNumeric.Location = new System.Drawing.Point(101, 19);
|
||||
this.portNumeric.Maximum = new decimal(new int[] {
|
||||
65536,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.portNumeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.portNumeric.Name = "portNumeric";
|
||||
this.portNumeric.Size = new System.Drawing.Size(69, 20);
|
||||
this.portNumeric.TabIndex = 1;
|
||||
this.portNumeric.Value = new decimal(new int[] {
|
||||
10000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// startButton
|
||||
//
|
||||
this.startButton.Location = new System.Drawing.Point(196, 16);
|
||||
this.startButton.Name = "startButton";
|
||||
this.startButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.startButton.TabIndex = 2;
|
||||
this.startButton.Text = "Start server";
|
||||
this.startButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// stopButton
|
||||
//
|
||||
this.stopButton.Location = new System.Drawing.Point(277, 16);
|
||||
this.stopButton.Name = "stopButton";
|
||||
this.stopButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.stopButton.TabIndex = 3;
|
||||
this.stopButton.Text = "Stop server";
|
||||
this.stopButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.groupBox1.Controls.Add(this.label2);
|
||||
this.groupBox1.Controls.Add(this.usernameTextbox);
|
||||
this.groupBox1.Location = new System.Drawing.Point(400, 12);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(313, 65);
|
||||
this.groupBox1.TabIndex = 4;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Server credentials";
|
||||
//
|
||||
// usernameTextbox
|
||||
//
|
||||
this.usernameTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.usernameTextbox.Location = new System.Drawing.Point(74, 20);
|
||||
this.usernameTextbox.Name = "usernameTextbox";
|
||||
this.usernameTextbox.ReadOnly = true;
|
||||
this.usernameTextbox.Size = new System.Drawing.Size(233, 20);
|
||||
this.usernameTextbox.TabIndex = 0;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(7, 23);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(61, 13);
|
||||
this.label2.TabIndex = 1;
|
||||
this.label2.Text = "User name:";
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.signButton);
|
||||
this.groupBox2.Controls.Add(this.encryptButton);
|
||||
this.groupBox2.Controls.Add(this.sendTextbox);
|
||||
this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.groupBox2.Location = new System.Drawing.Point(3, 3);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(344, 381);
|
||||
this.groupBox2.TabIndex = 5;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Send a message to the client";
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.receivedTextbox);
|
||||
this.groupBox3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.groupBox3.Location = new System.Drawing.Point(353, 3);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(345, 381);
|
||||
this.groupBox3.TabIndex = 6;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "Received messages from the client";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.groupBox2, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.groupBox3, 1, 0);
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 87);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 1;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(701, 387);
|
||||
this.tableLayoutPanel1.TabIndex = 7;
|
||||
//
|
||||
// sendTextbox
|
||||
//
|
||||
this.sendTextbox.Location = new System.Drawing.Point(6, 19);
|
||||
this.sendTextbox.Multiline = true;
|
||||
this.sendTextbox.Name = "sendTextbox";
|
||||
this.sendTextbox.Size = new System.Drawing.Size(331, 322);
|
||||
this.sendTextbox.TabIndex = 0;
|
||||
//
|
||||
// receivedTextbox
|
||||
//
|
||||
this.receivedTextbox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.receivedTextbox.Location = new System.Drawing.Point(3, 16);
|
||||
this.receivedTextbox.Multiline = true;
|
||||
this.receivedTextbox.Name = "receivedTextbox";
|
||||
this.receivedTextbox.Size = new System.Drawing.Size(339, 362);
|
||||
this.receivedTextbox.TabIndex = 0;
|
||||
//
|
||||
// encryptButton
|
||||
//
|
||||
this.encryptButton.Location = new System.Drawing.Point(33, 349);
|
||||
this.encryptButton.Name = "encryptButton";
|
||||
this.encryptButton.Size = new System.Drawing.Size(120, 23);
|
||||
this.encryptButton.TabIndex = 2;
|
||||
this.encryptButton.Text = "Encrypt and send";
|
||||
this.encryptButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// signButton
|
||||
//
|
||||
this.signButton.Location = new System.Drawing.Point(174, 349);
|
||||
this.signButton.Name = "signButton";
|
||||
this.signButton.Size = new System.Drawing.Size(117, 23);
|
||||
this.signButton.TabIndex = 3;
|
||||
this.signButton.Text = "Sign and send";
|
||||
this.signButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Text = "Form1";
|
||||
this.ClientSize = new System.Drawing.Size(725, 477);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.stopButton);
|
||||
this.Controls.Add(this.startButton);
|
||||
this.Controls.Add(this.portNumeric);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Name = "Form1";
|
||||
this.Text = "Server - SSPI Test";
|
||||
((System.ComponentModel.ISupportInitialize)(this.portNumeric)).EndInit();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox3.PerformLayout();
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.NumericUpDown portNumeric;
|
||||
private System.Windows.Forms.Button startButton;
|
||||
private System.Windows.Forms.Button stopButton;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox usernameTextbox;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.Button signButton;
|
||||
private System.Windows.Forms.Button encryptButton;
|
||||
private System.Windows.Forms.TextBox sendTextbox;
|
||||
private System.Windows.Forms.TextBox receivedTextbox;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,215 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using TestProtocol;
|
||||
|
||||
namespace TestServer
|
||||
{
|
||||
using NSspi;
|
||||
using NSspi.Contexts;
|
||||
using NSspi.Credentials;
|
||||
using Message = TestProtocol.Message;
|
||||
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
private ServerCredential serverCred;
|
||||
|
||||
private ServerContext serverContext;
|
||||
|
||||
private CustomServer server;
|
||||
|
||||
private bool running;
|
||||
|
||||
private bool initializing;
|
||||
|
||||
private bool connected;
|
||||
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.serverCred = new ServerCredential( SecurityPackage.Negotiate );
|
||||
|
||||
this.serverContext = new ServerContext(
|
||||
serverCred,
|
||||
ContextAttrib.AcceptIntegrity |
|
||||
ContextAttrib.ReplayDetect |
|
||||
ContextAttrib.SequenceDetect |
|
||||
ContextAttrib.MutualAuth |
|
||||
ContextAttrib.Delegate |
|
||||
ContextAttrib.Confidentiality
|
||||
);
|
||||
|
||||
this.server = new CustomServer();
|
||||
this.server.Received += server_Received;
|
||||
this.server.Disconnected += server_Disconnected;
|
||||
|
||||
this.FormClosing += Form1_FormClosing;
|
||||
|
||||
this.startButton.Click += startButton_Click;
|
||||
this.stopButton.Click += stopButton_Click;
|
||||
|
||||
this.encryptButton.Click += encryptButton_Click;
|
||||
this.signButton.Click += signButton_Click;
|
||||
|
||||
this.running = false;
|
||||
this.initializing = false;
|
||||
this.connected = false;
|
||||
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void Form1_FormClosing( object sender, FormClosingEventArgs e )
|
||||
{
|
||||
this.server.Stop();
|
||||
}
|
||||
|
||||
private void startButton_Click( object sender, EventArgs e )
|
||||
{
|
||||
this.server.StartServer( (int)this.portNumeric.Value );
|
||||
|
||||
this.running = true;
|
||||
this.initializing = true;
|
||||
this.connected = false;
|
||||
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void stopButton_Click( object sender, EventArgs e )
|
||||
{
|
||||
this.server.Stop();
|
||||
|
||||
this.running = false;
|
||||
this.initializing = false;
|
||||
this.connected = false;
|
||||
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private void encryptButton_Click( object sender, EventArgs e )
|
||||
{
|
||||
Message message;
|
||||
|
||||
byte[] plainText = Encoding.UTF8.GetBytes( this.sendTextbox.Text );
|
||||
byte[] cipherText = this.serverContext.Encrypt( plainText );
|
||||
|
||||
message = new Message( ProtocolOp.EncryptedMessage, cipherText );
|
||||
|
||||
this.server.Send( message );
|
||||
}
|
||||
|
||||
private void signButton_Click( object sender, EventArgs e )
|
||||
{
|
||||
// Not implemented.
|
||||
}
|
||||
|
||||
private void UpdateButtons()
|
||||
{
|
||||
this.startButton.Enabled = this.running == false;
|
||||
this.stopButton.Enabled = this.running;
|
||||
|
||||
this.encryptButton.Enabled = this.connected;
|
||||
this.signButton.Enabled = this.connected;
|
||||
}
|
||||
|
||||
|
||||
private void server_Received( Message message )
|
||||
{
|
||||
if( message.Operation == ProtocolOp.ClientToken )
|
||||
{
|
||||
HandleInit( message );
|
||||
}
|
||||
else if( message.Operation == ProtocolOp.EncryptedMessage )
|
||||
{
|
||||
HandleEncrypted( message );
|
||||
}
|
||||
else if( message.Operation == ProtocolOp.SignedMessage )
|
||||
{
|
||||
HandleSigned( message );
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleUnknown( message );
|
||||
}
|
||||
}
|
||||
|
||||
private void server_Disconnected()
|
||||
{
|
||||
this.running = false;
|
||||
this.initializing = false;
|
||||
this.connected = false;
|
||||
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
|
||||
private void HandleInit( Message message )
|
||||
{
|
||||
byte[] nextToken;
|
||||
SecurityStatus status;
|
||||
|
||||
if( initializing )
|
||||
{
|
||||
status = this.serverContext.AcceptToken( message.Data, out nextToken );
|
||||
|
||||
if( status == SecurityStatus.OK || status == SecurityStatus.ContinueNeeded )
|
||||
{
|
||||
if( nextToken != null )
|
||||
{
|
||||
this.server.Send( new Message( ProtocolOp.ServerToken, nextToken ) );
|
||||
}
|
||||
|
||||
if( status == SecurityStatus.OK )
|
||||
{
|
||||
this.initializing = false;
|
||||
this.connected = true;
|
||||
|
||||
this.Invoke( (Action)delegate() { UpdateButtons(); } );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Invoke( (Action)delegate()
|
||||
{
|
||||
MessageBox.Show( "Failed to accept token from client. Sspi error code: " + status );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleEncrypted( Message message )
|
||||
{
|
||||
this.Invoke( (Action)delegate()
|
||||
{
|
||||
byte[] plainText = this.serverContext.Decrypt( message.Data );
|
||||
string text = Encoding.UTF8.GetString( plainText );
|
||||
|
||||
this.receivedTextbox.Text += "Received encrypted message from client:\r\n" + text + "\r\n";
|
||||
} );
|
||||
}
|
||||
|
||||
private void HandleSigned( Message message )
|
||||
{
|
||||
// Not implemented yet.
|
||||
/*
|
||||
this.Invoke( (Action)delegate()
|
||||
{
|
||||
byte[] plainText = this.serverContext.Decrypt( message.Data );
|
||||
string text = Encoding.UTF8.GetString( plainText );
|
||||
|
||||
this.receivedTextbox.Text += "Received encrypted message from client:\r\n" + text + "\r\n";
|
||||
} );
|
||||
*/
|
||||
}
|
||||
|
||||
private void HandleUnknown( Message message )
|
||||
{
|
||||
this.Invoke( (Action)delegate()
|
||||
{
|
||||
MessageBox.Show( "Received unexpected message from server. Message type: " + message.Operation );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
120
TestServer/Form1.resx
Normal file
120
TestServer/Form1.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -52,6 +52,9 @@
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
@@ -74,6 +77,16 @@
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NSspi.csproj">
|
||||
<Project>{4b4cd933-bf62-4f92-b8fa-6771758c5197}</Project>
|
||||
<Name>NSspi</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\TestProtocol\TestProtocol.csproj">
|
||||
<Project>{9bfd94e1-d9fb-44d7-a6e7-8bac2620e535}</Project>
|
||||
<Name>TestProtocol</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
Reference in New Issue
Block a user