diff --git a/NSspi.sln b/NSspi.sln
index aeaff87..2b40dc2 100644
--- a/NSspi.sln
+++ b/NSspi.sln
@@ -3,6 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSspi", "NSspi.csproj", "{4B4CD933-BF62-4F92-B8FA-6771758C5197}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "TestClient\TestClient.csproj", "{E93FBF1A-5198-44D6-BDF0-880D17F2B81A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProtocol", "TestProtocol\TestProtocol.csproj", "{9BFD94E1-D9FB-44D7-A6E7-8BAC2620E535}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -13,6 +17,14 @@ Global
{4B4CD933-BF62-4F92-B8FA-6771758C5197}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B4CD933-BF62-4F92-B8FA-6771758C5197}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4B4CD933-BF62-4F92-B8FA-6771758C5197}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E93FBF1A-5198-44D6-BDF0-880D17F2B81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E93FBF1A-5198-44D6-BDF0-880D17F2B81A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E93FBF1A-5198-44D6-BDF0-880D17F2B81A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E93FBF1A-5198-44D6-BDF0-880D17F2B81A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9BFD94E1-D9FB-44D7-A6E7-8BAC2620E535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9BFD94E1-D9FB-44D7-A6E7-8BAC2620E535}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9BFD94E1-D9FB-44D7-A6E7-8BAC2620E535}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9BFD94E1-D9FB-44D7-A6E7-8BAC2620E535}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Program.cs b/Program.cs
index a966572..3226955 100644
--- a/Program.cs
+++ b/Program.cs
@@ -16,9 +16,7 @@ namespace NSspi
{
public static void Main( string[] args )
{
- SecPkgInfo pkgInfo = PackageSupport.GetPackageCapabilities( "Negotiate" );
-
- //CredTest();
+ CredTest();
}
private static void IdentTest()
diff --git a/TestClient/App.config b/TestClient/App.config
new file mode 100644
index 0000000..fad249e
--- /dev/null
+++ b/TestClient/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestClient/CustomConnection.cs b/TestClient/CustomConnection.cs
new file mode 100644
index 0000000..24968d4
--- /dev/null
+++ b/TestClient/CustomConnection.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using NSspi;
+
+namespace TestClient
+{
+ public class CustomConnection
+ {
+ private string server;
+ private int port;
+
+ private Thread receiveThread;
+
+ private Socket socket;
+
+ private bool running;
+
+ public CustomConnection( string server, int port )
+ {
+ this.running = false;
+ }
+
+ public delegate void ReceivedAction( Message message );
+
+ public event ReceivedAction Received;
+
+ public void StartClient()
+ {
+ if( this.running )
+ {
+ throw new InvalidOperationException("Already running");
+ }
+
+ this.socket = new Socket( SocketType.Stream, ProtocolType.Tcp );
+
+ this.socket.Connect( this.server, this.port );
+
+ this.running = true;
+
+ this.receiveThread = new Thread( ReceiveThreadEntry );
+ this.receiveThread.Name = "SSPI Client Receive Thread";
+ this.receiveThread.Start();
+ }
+
+ public void Stop()
+ {
+ if( this.running == false )
+ {
+ throw new InvalidOperationException( "Already stopped" );
+ }
+ }
+
+ public void Send( byte[] buffer, int start, int length )
+ {
+ if( this.running == false )
+ {
+ throw new InvalidOperationException( "Not connected" );
+ }
+
+ this.socket.Send( buffer, start, length, SocketFlags.None );
+ }
+
+ private void ReceiveThreadEntry()
+ {
+ try
+ {
+ ReadLoop();
+ }
+ catch( Exception e )
+ {
+ MessageBox.Show( "The SspiConnection receive thread crashed:\r\n\r\n" + e.ToString() );
+ this.running = false;
+ }
+ }
+
+ private void ReadLoop()
+ {
+ byte[] readBuffer = new byte[65536];
+
+ ProtocolOp operation;
+ int length;
+
+ while( this.running )
+ {
+ try
+ {
+ // |--4 bytes--|--4 bytes--|---N--|
+ // Every command is a TLV - | Operation | Length | Data |
+
+ // Read the operation.
+ this.socket.Receive( readBuffer, 4, SocketFlags.None );
+
+ operation = (ProtocolOp)ByteWriter.ReadInt32_BE( readBuffer, 0 );
+
+ // Read the length
+ this.socket.Receive( readBuffer, 4, SocketFlags.None );
+ length = ByteWriter.ReadInt32_BE( readBuffer, 0 );
+
+ // Read the data
+ this.socket.Receive( readBuffer, length, SocketFlags.None );
+
+ }
+ catch( SocketException e )
+ {
+ if( e.SocketErrorCode == SocketError.ConnectionAborted ||
+ e.SocketErrorCode == SocketError.Interrupted ||
+ e.SocketErrorCode == SocketError.OperationAborted ||
+ e.SocketErrorCode == SocketError.Shutdown )
+ {
+ // Shutting down.
+ break;
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ try
+ {
+ if( this.Received != null )
+ {
+ byte[] dataCopy = new byte[length];
+ Array.Copy( readBuffer, 0, dataCopy, 0, length );
+ Message message = new Message( operation, dataCopy );
+
+ this.Received( message );
+ }
+ }
+ catch( Exception e )
+ {
+
+ }
+ }
+ }
+ }
+}
diff --git a/TestClient/Form1.Designer.cs b/TestClient/Form1.Designer.cs
new file mode 100644
index 0000000..7b40a2c
--- /dev/null
+++ b/TestClient/Form1.Designer.cs
@@ -0,0 +1,281 @@
+namespace TestClient
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose( bool disposing )
+ {
+ if( disposing && ( components != null ) )
+ {
+ components.Dispose();
+ }
+ base.Dispose( disposing );
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.serverTextBox = new System.Windows.Forms.TextBox();
+ this.portNumeric = new System.Windows.Forms.NumericUpDown();
+ this.connectButton = new System.Windows.Forms.Button();
+ this.usernameTextbox = new System.Windows.Forms.TextBox();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.sendTextbox = new System.Windows.Forms.TextBox();
+ this.encryptButton = new System.Windows.Forms.Button();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.signButton = new System.Windows.Forms.Button();
+ this.receiveTextbox = new System.Windows.Forms.TextBox();
+ this.groupBox3 = new System.Windows.Forms.GroupBox();
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.disconnectButton = 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(13, 13);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(41, 13);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Server:";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(13, 40);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(29, 13);
+ this.label2.TabIndex = 1;
+ this.label2.Text = "Port:";
+ //
+ // serverTextBox
+ //
+ this.serverTextBox.Location = new System.Drawing.Point(60, 10);
+ this.serverTextBox.Name = "serverTextBox";
+ this.serverTextBox.Size = new System.Drawing.Size(137, 20);
+ this.serverTextBox.TabIndex = 2;
+ //
+ // portNumeric
+ //
+ this.portNumeric.Location = new System.Drawing.Point(60, 40);
+ 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(82, 20);
+ this.portNumeric.TabIndex = 3;
+ this.portNumeric.Value = new decimal(new int[] {
+ 10000,
+ 0,
+ 0,
+ 0});
+ //
+ // connectButton
+ //
+ this.connectButton.Location = new System.Drawing.Point(224, 8);
+ this.connectButton.Name = "connectButton";
+ this.connectButton.Size = new System.Drawing.Size(75, 23);
+ this.connectButton.TabIndex = 4;
+ this.connectButton.Text = "Connect..";
+ this.connectButton.UseVisualStyleBackColor = true;
+ //
+ // 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(82, 27);
+ this.usernameTextbox.Name = "usernameTextbox";
+ this.usernameTextbox.ReadOnly = true;
+ this.usernameTextbox.Size = new System.Drawing.Size(229, 20);
+ this.usernameTextbox.TabIndex = 5;
+ //
+ // 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.label3);
+ this.groupBox1.Controls.Add(this.usernameTextbox);
+ this.groupBox1.Location = new System.Drawing.Point(335, 10);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(317, 74);
+ this.groupBox1.TabIndex = 6;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Client credentials";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(6, 30);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(58, 13);
+ this.label3.TabIndex = 6;
+ this.label3.Text = "Username:";
+ //
+ // sendTextbox
+ //
+ this.sendTextbox.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.sendTextbox.Location = new System.Drawing.Point(6, 19);
+ this.sendTextbox.Multiline = true;
+ this.sendTextbox.Name = "sendTextbox";
+ this.sendTextbox.Size = new System.Drawing.Size(302, 298);
+ this.sendTextbox.TabIndex = 7;
+ //
+ // encryptButton
+ //
+ this.encryptButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.encryptButton.Location = new System.Drawing.Point(6, 325);
+ this.encryptButton.Name = "encryptButton";
+ this.encryptButton.Size = new System.Drawing.Size(126, 23);
+ this.encryptButton.TabIndex = 8;
+ this.encryptButton.Text = "Encrypt and send";
+ this.encryptButton.UseVisualStyleBackColor = true;
+ //
+ // groupBox2
+ //
+ this.groupBox2.Controls.Add(this.signButton);
+ this.groupBox2.Controls.Add(this.sendTextbox);
+ this.groupBox2.Controls.Add(this.encryptButton);
+ 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(314, 357);
+ this.groupBox2.TabIndex = 9;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Send a message to the server";
+ //
+ // signButton
+ //
+ this.signButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.signButton.Location = new System.Drawing.Point(138, 325);
+ this.signButton.Name = "signButton";
+ this.signButton.Size = new System.Drawing.Size(118, 23);
+ this.signButton.TabIndex = 9;
+ this.signButton.Text = "Sign and send";
+ this.signButton.UseVisualStyleBackColor = true;
+ //
+ // receiveTextbox
+ //
+ this.receiveTextbox.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.receiveTextbox.Location = new System.Drawing.Point(3, 16);
+ this.receiveTextbox.Multiline = true;
+ this.receiveTextbox.Name = "receiveTextbox";
+ this.receiveTextbox.Size = new System.Drawing.Size(308, 338);
+ this.receiveTextbox.TabIndex = 10;
+ //
+ // groupBox3
+ //
+ this.groupBox3.Controls.Add(this.receiveTextbox);
+ this.groupBox3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.groupBox3.Location = new System.Drawing.Point(323, 3);
+ this.groupBox3.Name = "groupBox3";
+ this.groupBox3.Size = new System.Drawing.Size(314, 357);
+ this.groupBox3.TabIndex = 11;
+ this.groupBox3.TabStop = false;
+ this.groupBox3.Text = "Receive messages from the server";
+ //
+ // 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.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+ this.tableLayoutPanel1.Controls.Add(this.groupBox2, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.groupBox3, 1, 0);
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 99);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.RowCount = 1;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(640, 363);
+ this.tableLayoutPanel1.TabIndex = 12;
+ //
+ // disconnectButton
+ //
+ this.disconnectButton.Location = new System.Drawing.Point(224, 36);
+ this.disconnectButton.Name = "disconnectButton";
+ this.disconnectButton.Size = new System.Drawing.Size(75, 23);
+ this.disconnectButton.TabIndex = 13;
+ this.disconnectButton.Text = "Disconnect";
+ this.disconnectButton.UseVisualStyleBackColor = true;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(664, 472);
+ this.Controls.Add(this.disconnectButton);
+ this.Controls.Add(this.tableLayoutPanel1);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.connectButton);
+ this.Controls.Add(this.portNumeric);
+ this.Controls.Add(this.serverTextBox);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Name = "Form1";
+ this.Text = "Form1";
+ ((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.Label label2;
+ private System.Windows.Forms.TextBox serverTextBox;
+ private System.Windows.Forms.NumericUpDown portNumeric;
+ private System.Windows.Forms.Button connectButton;
+ private System.Windows.Forms.TextBox usernameTextbox;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox sendTextbox;
+ private System.Windows.Forms.Button encryptButton;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.Button signButton;
+ private System.Windows.Forms.TextBox receiveTextbox;
+ private System.Windows.Forms.GroupBox groupBox3;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+ private System.Windows.Forms.Button disconnectButton;
+ }
+}
+
diff --git a/TestClient/Form1.cs b/TestClient/Form1.cs
new file mode 100644
index 0000000..e37c2ce
--- /dev/null
+++ b/TestClient/Form1.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using NSspi;
+using NSspi.Contexts;
+using NSspi.Credentials;
+
+namespace TestClient
+{
+ public partial class Form1 : Form
+ {
+ private ClientContext context;
+ private ClientCredential cred;
+
+ private CustomConnection connection;
+
+ private bool connected;
+
+ private bool initializing;
+
+ private byte[] lastServerToken;
+
+ public Form1()
+ {
+ this.connected = false;
+ this.initializing = false;
+ this.lastServerToken = null;
+
+ // --- UI ---
+ InitializeComponent();
+
+ this.connectButton.Click += connectButton_Click;
+
+ this.disconnectButton.Click += disconnectButton_Click;
+
+
+ this.encryptButton.Click += encryptButton_Click;
+
+ this.signButton.Click += signButton_Click;
+
+ // --- SSPI ---
+ this.cred = new ClientCredential( SecurityPackage.Negotiate );
+
+ this.context = new ClientContext(
+ cred,
+ "",
+ ContextAttrib.InitIntegrity |
+ ContextAttrib.ReplayDetect |
+ ContextAttrib.SequenceDetect |
+ ContextAttrib.MutualAuth |
+ ContextAttrib.Delegate |
+ ContextAttrib.Confidentiality
+ );
+
+ this.connection = new CustomConnection();
+ this.connection.Received += connection_Received;
+
+ // --- UI Fillout ---
+ this.usernameTextbox.Text = this.cred.Name;
+
+ UpdateButtons();
+ }
+
+ private void connectButton_Click( object sender, EventArgs e )
+ {
+ if( string.IsNullOrWhiteSpace( this.serverTextBox.Text ) )
+ {
+ MessageBox.Show( "Please enter a server to connect to" );
+ }
+ else
+ {
+ try
+ {
+ this.connection.StartClient( this.serverTextBox.Text, (int)this.portNumeric.Value );
+ }
+ catch( SocketException socketExcept )
+ {
+ if( socketExcept.SocketErrorCode == SocketError.ConnectionRefused ||
+ socketExcept.SocketErrorCode == SocketError.HostDown ||
+ socketExcept.SocketErrorCode == SocketError.HostNotFound ||
+ socketExcept.SocketErrorCode == SocketError.HostUnreachable ||
+ socketExcept.SocketErrorCode == SocketError.NetworkUnreachable ||
+ socketExcept.SocketErrorCode == SocketError.TimedOut
+ )
+ {
+ MessageBox.Show( "Could not connect to the server:\r\n\r\n\t" + socketExcept.Message );
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ this.initializing = true;
+ }
+ }
+
+ private void disconnectButton_Click( object sender, EventArgs e )
+ {
+ this.connection.Stop();
+ }
+
+
+ private void encryptButton_Click( object sender, EventArgs e )
+ {
+ byte[] plaintext;
+ byte[] cipherText;
+ Message message;
+
+ plaintext = Encoding.UTF8.GetBytes( this.sendTextbox.Text );
+
+ cipherText = this.context.Encrypt( plaintext );
+
+ message = new Message( ProtocolOp.EncryptedMessage, cipherText );
+
+ this.connection.Send( message );
+ }
+
+ private void signButton_Click( object sender, EventArgs e )
+ {
+ // Signing not yet supported in the NSspi library;
+ MessageBox.Show( "Signing not yet supported" );
+ return;
+
+ /*
+ byte[] plaintext;
+ byte[] cipherText;
+ Message message;
+
+ plaintext = Encoding.UTF8.GetBytes( this.sendTextbox.Text );
+
+ cipherText = this.context.Sign( plaintext );
+
+ message = new Message( ProtocolOp.SignedMessage, cipherText );
+
+ this.connection.Send( message );
+ */
+ }
+
+ private void connection_Received( Message message )
+ {
+ this.Invoke( (Action)delegate()
+ {
+ if( message.Operation == ProtocolOp.ServerToken )
+ {
+ if( initializing )
+ {
+ this.lastServerToken = message.Data;
+ DoInit();
+ }
+ else
+ {
+ MessageBox.Show( "Read unexpected operation from server: " + message.Operation );
+ }
+ }
+ else if( message.Operation == ProtocolOp.EncryptedMessage )
+ {
+ HandleEncrypted( message );
+ }
+ else if( message.Operation == ProtocolOp.SignedMessage )
+ {
+ // Not yet supported
+ }
+ } );
+ }
+
+ private void DoInit()
+ {
+ SecurityStatus status;
+ byte[] outToken;
+
+ status = this.context.Init( this.lastServerToken, out outToken );
+
+ if( status == SecurityStatus.ContinueNeeded )
+ {
+ Message message = new Message( ProtocolOp.ClientToken, outToken );
+ this.connection.Send( message );
+ }
+ else if( status == SecurityStatus.OK )
+ {
+ this.lastServerToken = null;
+ this.initializing = false;
+ this.connected = true;
+ UpdateButtons();
+ }
+ }
+
+ private void HandleEncrypted( Message message )
+ {
+ byte[] plainText = this.context.Decrypt( message.Data );
+
+ string text = Encoding.UTF8.GetString( plainText );
+
+ this.receiveTextbox.Text += "Received encrypted message from server:\r\n" + text + "\r\n";
+ }
+
+
+ private void UpdateButtons()
+ {
+ this.connectButton.Enabled = this.connected == false;
+ this.disconnectButton.Enabled = this.connected;
+
+ this.encryptButton.Enabled = this.connected;
+ this.signButton.Enabled = this.connected;
+ }
+ }
+}
diff --git a/TestClient/Form1.resx b/TestClient/Form1.resx
new file mode 100644
index 0000000..29dcb1b
--- /dev/null
+++ b/TestClient/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestClient/Message.cs b/TestClient/Message.cs
new file mode 100644
index 0000000..517a66a
--- /dev/null
+++ b/TestClient/Message.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestClient
+{
+ public class Message
+ {
+ public Message(ProtocolOp op, byte[] data)
+ {
+ this.Operation = op;
+ this.Data = data;
+ }
+
+ public ProtocolOp Operation { get; private set; }
+
+ public byte[] Data { get; private set; }
+ }
+}
diff --git a/TestClient/Program.cs b/TestClient/Program.cs
new file mode 100644
index 0000000..3990eb0
--- /dev/null
+++ b/TestClient/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace TestClient
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault( false );
+ Application.Run( new Form1() );
+ }
+ }
+}
diff --git a/TestClient/Properties/AssemblyInfo.cs b/TestClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5f4bac3
--- /dev/null
+++ b/TestClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle( "TestClient" )]
+[assembly: AssemblyDescription( "" )]
+[assembly: AssemblyConfiguration( "" )]
+[assembly: AssemblyCompany( "Kevin Thompson" )]
+[assembly: AssemblyProduct( "TestClient" )]
+[assembly: AssemblyCopyright( "Copyright © Kevin Thompson 2014" )]
+[assembly: AssemblyTrademark( "" )]
+[assembly: AssemblyCulture( "" )]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible( false )]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid( "23b8a06a-ea66-4c1b-bce5-ee56db607f97" )]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion( "1.0.0.0" )]
+[assembly: AssemblyFileVersion( "1.0.0.0" )]
\ No newline at end of file
diff --git a/TestClient/Properties/Resources.Designer.cs b/TestClient/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..fd753b4
--- /dev/null
+++ b/TestClient/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18444
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestClient.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0" )]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if( ( resourceMan == null ) )
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager( "TestClient.Properties.Resources", typeof( Resources ).Assembly );
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/TestClient/Properties/Resources.resx b/TestClient/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/TestClient/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestClient/Properties/Settings.Designer.cs b/TestClient/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..0ef77a5
--- /dev/null
+++ b/TestClient/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18444
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestClient.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0" )]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ( (Settings)( global::System.Configuration.ApplicationSettingsBase.Synchronized( new Settings() ) ) );
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/TestClient/Properties/Settings.settings b/TestClient/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/TestClient/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/TestClient/ProtocolOp.cs b/TestClient/ProtocolOp.cs
new file mode 100644
index 0000000..89b6d74
--- /dev/null
+++ b/TestClient/ProtocolOp.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestClient
+{
+ public enum ProtocolOp : uint
+ {
+ ClientToken = 1,
+ ServerToken = 2,
+
+ EncryptedMessage = 3,
+ SignedMessage = 4,
+ }
+}
diff --git a/TestClient/TestClient.csproj b/TestClient/TestClient.csproj
new file mode 100644
index 0000000..94b038d
--- /dev/null
+++ b/TestClient/TestClient.csproj
@@ -0,0 +1,100 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E93FBF1A-5198-44D6-BDF0-880D17F2B81A}
+ WinExe
+ Properties
+ TestClient
+ TestClient
+ v4.5
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+ Code
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+ {4b4cd933-bf62-4f92-b8fa-6771758c5197}
+ NSspi
+
+
+ {9bfd94e1-d9fb-44d7-a6e7-8bac2620e535}
+ TestProtocol
+
+
+
+
+
\ No newline at end of file
diff --git a/TestClient/TestClient.csproj.user b/TestClient/TestClient.csproj.user
new file mode 100644
index 0000000..76fe5a5
--- /dev/null
+++ b/TestClient/TestClient.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ ProjectFiles
+
+
\ No newline at end of file
diff --git a/TestProtocol/App.config b/TestProtocol/App.config
new file mode 100644
index 0000000..fad249e
--- /dev/null
+++ b/TestProtocol/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestProtocol/CustomConnection.cs b/TestProtocol/CustomConnection.cs
new file mode 100644
index 0000000..b8468f0
--- /dev/null
+++ b/TestProtocol/CustomConnection.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using NSspi;
+
+namespace TestClient
+{
+ public class CustomConnection
+ {
+ private Thread receiveThread;
+
+ private Socket socket;
+
+ private bool running;
+
+ public CustomConnection()
+ {
+ this.running = false;
+ }
+
+ public delegate void ReceivedAction( Message message );
+
+ public event ReceivedAction Received;
+
+ public void StartClient( string server, int port )
+ {
+ if( this.running )
+ {
+ throw new InvalidOperationException("Already running");
+ }
+
+ this.socket = new Socket( SocketType.Stream, ProtocolType.Tcp );
+
+ this.socket.Connect( server, port );
+
+ this.running = true;
+
+ this.receiveThread = new Thread( ReceiveThreadEntry );
+ this.receiveThread.Name = "SSPI Client Receive Thread";
+ this.receiveThread.Start();
+ }
+
+ public void Stop()
+ {
+ if( this.running == false )
+ {
+ throw new InvalidOperationException( "Already stopped" );
+ }
+
+ this.socket.Close();
+ this.receiveThread.Join();
+ }
+
+ public void Send( Message message )
+ {
+ if( this.running == false )
+ {
+ throw new InvalidOperationException( "Not connected" );
+ }
+
+ byte[] outBuffer = new byte[ message.Data.Length + 8 ];
+
+ ByteWriter.WriteInt32_BE( (int)message.Operation, outBuffer, 0 );
+ ByteWriter.WriteInt32_BE( message.Data.Length, outBuffer, 4 );
+
+ Array.Copy( message.Data, 0, outBuffer, 8, message.Data.Length );
+
+ this.socket.Send( outBuffer, 0, outBuffer.Length, SocketFlags.None );
+ }
+
+ private void ReceiveThreadEntry()
+ {
+ try
+ {
+ ReadLoop();
+ }
+ catch( Exception e )
+ {
+ MessageBox.Show( "The SspiConnection receive thread crashed:\r\n\r\n" + e.ToString() );
+ this.running = false;
+ }
+ }
+
+ private void ReadLoop()
+ {
+ byte[] readBuffer = new byte[65536];
+
+ ProtocolOp operation;
+ int length;
+
+ while( this.running )
+ {
+ try
+ {
+ // |--4 bytes--|--4 bytes--|---N--|
+ // Every command is a TLV - | Operation | Length | Data |
+
+
+ // Read the operation.
+ this.socket.Receive( readBuffer, 4, SocketFlags.None );
+
+ // Check if we popped out of a receive call after we were shut down.
+ if( this.running == false ) { break; }
+
+ operation = (ProtocolOp)ByteWriter.ReadInt32_BE( readBuffer, 0 );
+
+ // Read the length
+ this.socket.Receive( readBuffer, 4, SocketFlags.None );
+ length = ByteWriter.ReadInt32_BE( readBuffer, 0 );
+
+ // Read the data
+ this.socket.Receive( readBuffer, length, SocketFlags.None );
+
+ }
+ catch( SocketException e )
+ {
+ if( e.SocketErrorCode == SocketError.ConnectionAborted ||
+ e.SocketErrorCode == SocketError.Interrupted ||
+ e.SocketErrorCode == SocketError.OperationAborted ||
+ e.SocketErrorCode == SocketError.Shutdown )
+ {
+ // Shutting down.
+ break;
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+
+ if( this.Received != null )
+ {
+ byte[] dataCopy = new byte[length];
+ Array.Copy( readBuffer, 0, dataCopy, 0, length );
+ Message message = new Message( operation, dataCopy );
+
+ try
+ {
+ this.Received( message );
+ }
+ catch( Exception e )
+ { }
+ }
+
+ }
+ }
+ }
+}
diff --git a/TestProtocol/Message.cs b/TestProtocol/Message.cs
new file mode 100644
index 0000000..517a66a
--- /dev/null
+++ b/TestProtocol/Message.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestClient
+{
+ public class Message
+ {
+ public Message(ProtocolOp op, byte[] data)
+ {
+ this.Operation = op;
+ this.Data = data;
+ }
+
+ public ProtocolOp Operation { get; private set; }
+
+ public byte[] Data { get; private set; }
+ }
+}
diff --git a/TestProtocol/Properties/AssemblyInfo.cs b/TestProtocol/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0b7b848
--- /dev/null
+++ b/TestProtocol/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle( "TestProtocol" )]
+[assembly: AssemblyDescription( "" )]
+[assembly: AssemblyConfiguration( "" )]
+[assembly: AssemblyCompany( "Kevin Thompson" )]
+[assembly: AssemblyProduct( "TestProtocol" )]
+[assembly: AssemblyCopyright( "Copyright © Kevin Thompson 2014" )]
+[assembly: AssemblyTrademark( "" )]
+[assembly: AssemblyCulture( "" )]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible( false )]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid( "f7a11dfd-c91c-47df-8e4d-d3ddb6169343" )]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion( "1.0.0.0" )]
+[assembly: AssemblyFileVersion( "1.0.0.0" )]
diff --git a/TestProtocol/Properties/Resources.Designer.cs b/TestProtocol/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..4a3a6b1
--- /dev/null
+++ b/TestProtocol/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18444
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestProtocol.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0" )]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if( ( resourceMan == null ) )
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager( "TestProtocol.Properties.Resources", typeof( Resources ).Assembly );
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/TestProtocol/Properties/Resources.resx b/TestProtocol/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/TestProtocol/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestProtocol/Properties/Settings.Designer.cs b/TestProtocol/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..6849db1
--- /dev/null
+++ b/TestProtocol/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18444
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestProtocol.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0" )]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ( (Settings)( global::System.Configuration.ApplicationSettingsBase.Synchronized( new Settings() ) ) );
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/TestProtocol/Properties/Settings.settings b/TestProtocol/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/TestProtocol/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/TestProtocol/ProtocolOp.cs b/TestProtocol/ProtocolOp.cs
new file mode 100644
index 0000000..89b6d74
--- /dev/null
+++ b/TestProtocol/ProtocolOp.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestClient
+{
+ public enum ProtocolOp : uint
+ {
+ ClientToken = 1,
+ ServerToken = 2,
+
+ EncryptedMessage = 3,
+ SignedMessage = 4,
+ }
+}
diff --git a/TestProtocol/TestProtocol.csproj b/TestProtocol/TestProtocol.csproj
new file mode 100644
index 0000000..c5aa8a5
--- /dev/null
+++ b/TestProtocol/TestProtocol.csproj
@@ -0,0 +1,90 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {9BFD94E1-D9FB-44D7-A6E7-8BAC2620E535}
+ Library
+ Properties
+ TestProtocol
+ TestProtocol
+ v4.5
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+ {4b4cd933-bf62-4f92-b8fa-6771758c5197}
+ NSspi
+
+
+
+
+
\ No newline at end of file
diff --git a/TestServer/App.config b/TestServer/App.config
new file mode 100644
index 0000000..fad249e
--- /dev/null
+++ b/TestServer/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestServer/Form1.Designer.cs b/TestServer/Form1.Designer.cs
new file mode 100644
index 0000000..fe5c6aa
--- /dev/null
+++ b/TestServer/Form1.Designer.cs
@@ -0,0 +1,39 @@
+namespace TestServer
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose( bool disposing )
+ {
+ if( disposing && ( components != null ) )
+ {
+ components.Dispose();
+ }
+ base.Dispose( disposing );
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Text = "Form1";
+ }
+
+ #endregion
+ }
+}
+
diff --git a/TestServer/Form1.cs b/TestServer/Form1.cs
new file mode 100644
index 0000000..d30bc15
--- /dev/null
+++ b/TestServer/Form1.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace TestServer
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/TestServer/Program.cs b/TestServer/Program.cs
new file mode 100644
index 0000000..efafb34
--- /dev/null
+++ b/TestServer/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace TestServer
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault( false );
+ Application.Run( new Form1() );
+ }
+ }
+}
diff --git a/TestServer/Properties/AssemblyInfo.cs b/TestServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..37de13b
--- /dev/null
+++ b/TestServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle( "TestServer" )]
+[assembly: AssemblyDescription( "" )]
+[assembly: AssemblyConfiguration( "" )]
+[assembly: AssemblyCompany( "Kevin Thompson" )]
+[assembly: AssemblyProduct( "TestServer" )]
+[assembly: AssemblyCopyright( "Copyright © Kevin Thompson 2014" )]
+[assembly: AssemblyTrademark( "" )]
+[assembly: AssemblyCulture( "" )]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible( false )]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid( "ccc5f303-782b-427d-855d-b86452c40033" )]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion( "1.0.0.0" )]
+[assembly: AssemblyFileVersion( "1.0.0.0" )]
diff --git a/TestServer/Properties/Resources.Designer.cs b/TestServer/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..4172b6f
--- /dev/null
+++ b/TestServer/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18444
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestServer.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0" )]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute( "Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode" )]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if( ( resourceMan == null ) )
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager( "TestServer.Properties.Resources", typeof( Resources ).Assembly );
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute( global::System.ComponentModel.EditorBrowsableState.Advanced )]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/TestServer/Properties/Resources.resx b/TestServer/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/TestServer/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/TestServer/Properties/Settings.Designer.cs b/TestServer/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..20a86e7
--- /dev/null
+++ b/TestServer/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.18444
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TestServer.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute( "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0" )]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ( (Settings)( global::System.Configuration.ApplicationSettingsBase.Synchronized( new Settings() ) ) );
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/TestServer/Properties/Settings.settings b/TestServer/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/TestServer/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/TestServer/TestServer.csproj b/TestServer/TestServer.csproj
new file mode 100644
index 0000000..936a7be
--- /dev/null
+++ b/TestServer/TestServer.csproj
@@ -0,0 +1,85 @@
+
+
+
+
+ Debug
+ AnyCPU
+ ccc5f303-782b-427d-855d-b86452c40033
+ WinExe
+ Properties
+ TestServer
+ TestServer
+ v4.5
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
\ No newline at end of file