2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-05-06 03:32:57 +00:00
This commit is contained in:
Ahmed Zamil 2024-06-21 16:37:48 +03:00
parent c04fc29810
commit 3a89a108db
49 changed files with 2095 additions and 1373 deletions

View File

@ -43,5 +43,7 @@ public enum ExceptionCode : ushort
AlreadyUnlistened, AlreadyUnlistened,
NotListenable, NotListenable,
ParseError, ParseError,
Timeout Timeout,
NotSupported,
NotImplemented
} }

View File

@ -63,15 +63,22 @@ public interface IMap
public class Map<KT, VT> : IEnumerable<KeyValuePair<KT, VT>>, IMap public class Map<KT, VT> : IEnumerable<KeyValuePair<KT, VT>>, IMap
{ {
//public struct StructureMetadata private Dictionary<KT, VT> dic = new Dictionary<KT, VT>();
//{
// public KT[] Keys;
// public VT[] Types;
//}
private Dictionary<KT, VT> dic = new Dictionary<KT, VT>();// StringComparer.OrdinalIgnoreCase);
private object syncRoot = new object(); private object syncRoot = new object();
// Change map types
public Map<NewKeyType, NewValueType> Select<NewKeyType, NewValueType>
(Func<KeyValuePair<KT, VT>, KeyValuePair<NewKeyType, NewValueType>> selector)
{
var rt = new Map<NewKeyType, NewValueType>();
foreach(var kv in dic)
{
var nt = selector(kv);
rt.dic.Add(nt.Key, nt.Value);
}
return rt;
}
public bool ContainsKey(KT key) public bool ContainsKey(KT key)
{ {

View File

@ -49,6 +49,7 @@
<ItemGroup> <ItemGroup>
<Folder Include="Net\DataLink\Sources\" /> <Folder Include="Net\DataLink\Sources\" />
<Folder Include="Net\Packets\IIP\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -318,7 +318,6 @@ public static class Global
} }
public static byte[] GenerateBytes(int length) public static byte[] GenerateBytes(int length)
{ {
var b = new byte[length]; var b = new byte[length];

View File

@ -33,10 +33,11 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Esiur.Net.Sockets; using Esiur.Net.Sockets;
using Esiur.Data; using Esiur.Data;
using Esiur.Net.Packets;
using Esiur.Misc; using Esiur.Misc;
using System.Security.Cryptography; using System.Security.Cryptography;
using Esiur.Core; using Esiur.Core;
using Esiur.Net.Packets.WebSocket;
using Esiur.Net.Packets.HTTP;
namespace Esiur.Net.HTTP; namespace Esiur.Net.HTTP;
public class HTTPConnection : NetworkConnection public class HTTPConnection : NetworkConnection
@ -131,7 +132,7 @@ public class HTTPConnection : NetworkConnection
response.Headers["Sec-WebSocket-Protocol"] = request.Headers["Sec-WebSocket-Protocol"]; response.Headers["Sec-WebSocket-Protocol"] = request.Headers["Sec-WebSocket-Protocol"];
response.Number = HTTPResponsePacket.ResponseCode.Switching; response.Number = HTTPResponseCode.Switching;
response.Text = "Switching Protocols"; response.Text = "Switching Protocols";
return true; return true;
@ -172,7 +173,7 @@ public class HTTPConnection : NetworkConnection
Send(); Send();
} }
public void Send(HTTPResponsePacket.ComposeOptions Options = HTTPResponsePacket.ComposeOptions.AllCalculateLength) public void Send(HTTPComposeOption Options = HTTPComposeOption.AllCalculateLength)
{ {
if (Response.Handled) if (Response.Handled)
return; return;
@ -210,7 +211,7 @@ public class HTTPConnection : NetworkConnection
// Create a new one // Create a new one
session = Server.CreateSession(Global.GenerateCode(12), 60 * 20); session = Server.CreateSession(Global.GenerateCode(12), 60 * 20);
HTTPResponsePacket.HTTPCookie cookie = new HTTPResponsePacket.HTTPCookie("SID", session.Id); HTTPCookie cookie = new HTTPCookie("SID", session.Id);
cookie.Expires = DateTime.MaxValue; cookie.Expires = DateTime.MaxValue;
cookie.Path = "/"; cookie.Path = "/";
cookie.HttpOnly = true; cookie.HttpOnly = true;
@ -253,7 +254,7 @@ public class HTTPConnection : NetworkConnection
if (BL == 0) if (BL == 0)
{ {
if (Request.Method == HTTPRequestPacket.HTTPMethod.UNKNOWN) if (Request.Method == HTTPMethod.UNKNOWN)
{ {
Close(); Close();
return; return;
@ -312,7 +313,7 @@ public class HTTPConnection : NetworkConnection
{ {
if (!Server.Execute(this)) if (!Server.Execute(this))
{ {
Response.Number = HTTPResponsePacket.ResponseCode.InternalServerError; Response.Number = HTTPResponseCode.InternalServerError;
Send("Bad Request"); Send("Bad Request");
Close(); Close();
} }
@ -361,7 +362,7 @@ public class HTTPConnection : NetworkConnection
if (!File.Exists(filename)) if (!File.Exists(filename))
{ {
Response.Number = HTTPResponsePacket.ResponseCode.NotFound; Response.Number = HTTPResponseCode.NotFound;
Send("File Not Found"); Send("File Not Found");
return true; return true;
} }
@ -375,10 +376,10 @@ public class HTTPConnection : NetworkConnection
var ims = DateTime.Parse(Request.Headers["if-modified-since"]); var ims = DateTime.Parse(Request.Headers["if-modified-since"]);
if ((fileEditTime - ims).TotalSeconds < 2) if ((fileEditTime - ims).TotalSeconds < 2)
{ {
Response.Number = HTTPResponsePacket.ResponseCode.NotModified; Response.Number = HTTPResponseCode.NotModified;
Response.Headers.Clear(); Response.Headers.Clear();
//Response.Text = "Not Modified"; //Response.Text = "Not Modified";
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly); Send(HTTPComposeOption.SpecifiedHeadersOnly);
return true; return true;
} }
} }
@ -390,12 +391,12 @@ public class HTTPConnection : NetworkConnection
Response.Number = HTTPResponsePacket.ResponseCode.OK; Response.Number = HTTPResponseCode.OK;
// Fri, 30 Oct 2007 14:19:41 GMT // Fri, 30 Oct 2007 14:19:41 GMT
Response.Headers["Last-Modified"] = fileEditTime.ToString("ddd, dd MMM yyyy HH:mm:ss"); Response.Headers["Last-Modified"] = fileEditTime.ToString("ddd, dd MMM yyyy HH:mm:ss");
FileInfo fi = new FileInfo(filename); FileInfo fi = new FileInfo(filename);
Response.Headers["Content-Length"] = fi.Length.ToString(); Response.Headers["Content-Length"] = fi.Length.ToString();
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly); Send(HTTPComposeOption.SpecifiedHeadersOnly);
//var fd = File.ReadAllBytes(filename); //var fd = File.ReadAllBytes(filename);

View File

@ -35,12 +35,12 @@ using Esiur.Net.Sockets;
using Esiur.Data; using Esiur.Data;
using Esiur.Misc; using Esiur.Misc;
using Esiur.Core; using Esiur.Core;
using Esiur.Net.Packets;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using Esiur.Resource; using Esiur.Resource;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Esiur.Net.Packets.HTTP;
namespace Esiur.Net.HTTP; namespace Esiur.Net.HTTP;
public class HTTPServer : NetworkServer<HTTPConnection>, IResource public class HTTPServer : NetworkServer<HTTPConnection>, IResource
@ -48,17 +48,17 @@ public class HTTPServer : NetworkServer<HTTPConnection>, IResource
Dictionary<string, HTTPSession> sessions = new Dictionary<string, HTTPSession>(); Dictionary<string, HTTPSession> sessions = new Dictionary<string, HTTPSession>();
HTTPFilter[] filters = new HTTPFilter[0]; HTTPFilter[] filters = new HTTPFilter[0];
Dictionary<HTTPRequestPacket.HTTPMethod, List<RouteInfo>> routes = new() Dictionary<HTTPMethod, List<RouteInfo>> routes = new()
{ {
[HTTPRequestPacket.HTTPMethod.GET] = new List<RouteInfo>(), [HTTPMethod.GET] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.POST] = new List<RouteInfo>(), [HTTPMethod.POST] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.HEAD] = new List<RouteInfo>(), [HTTPMethod.HEAD] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.OPTIONS] = new List<RouteInfo>(), [HTTPMethod.OPTIONS] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.UNKNOWN] = new List<RouteInfo>(), [HTTPMethod.UNKNOWN] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.DELETE] = new List<RouteInfo>(), [HTTPMethod.DELETE] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.TRACE] = new List<RouteInfo>(), [HTTPMethod.TRACE] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.CONNECT] = new List<RouteInfo>(), [HTTPMethod.CONNECT] = new List<RouteInfo>(),
[HTTPRequestPacket.HTTPMethod.PUT] = new List<RouteInfo>() [HTTPMethod.PUT] = new List<RouteInfo>()
}; };
//List<RouteInfo> GetRoutes = new List<RouteInfo>(); //List<RouteInfo> GetRoutes = new List<RouteInfo>();
@ -243,14 +243,14 @@ public class HTTPServer : NetworkServer<HTTPConnection>, IResource
public void MapGet(string pattern, Delegate handler) public void MapGet(string pattern, Delegate handler)
{ {
var regex = Global.GetRouteRegex(pattern); var regex = Global.GetRouteRegex(pattern);
var list = routes[HTTPRequestPacket.HTTPMethod.GET]; var list = routes[HTTPMethod.GET];
list.Add(new RouteInfo(handler, regex)); list.Add(new RouteInfo(handler, regex));
} }
public void MapPost(string pattern, Delegate handler) public void MapPost(string pattern, Delegate handler)
{ {
var regex = Global.GetRouteRegex(pattern); var regex = Global.GetRouteRegex(pattern);
var list = routes[HTTPRequestPacket.HTTPMethod.POST]; var list = routes[HTTPMethod.POST];
list.Add(new RouteInfo(handler, regex)); list.Add(new RouteInfo(handler, regex));
} }

View File

@ -17,9 +17,9 @@ public class IIPoHTTP : HTTPFilter
if (sender.Request.URL != "iip") if (sender.Request.URL != "iip")
return new AsyncReply<bool>(false); return new AsyncReply<bool>(false);
IIPPacket.IIPPacketAction action = (IIPPacket.IIPPacketAction)Convert.ToByte(sender.Request.Query["a"]); IIPPacketAction action = (IIPPacketAction)Convert.ToByte(sender.Request.Query["a"]);
if (action == IIPPacket.IIPPacketAction.QueryLink) if (action == IIPPacketAction.QueryLink)
{ {
EntryPoint.Query(sender.Request.Query["l"], null).Then(x => EntryPoint.Query(sender.Request.Query["l"], null).Then(x =>
{ {

View File

@ -70,48 +70,6 @@ public class IIPoWS : HTTPFilter
return new AsyncReply<bool>(false); return new AsyncReply<bool>(false);
/*
if (sender.Request.Filename.StartsWith("/iip/"))
{
// find the service
var path = sender.Request.Filename.Substring(5);// sender.Request.Query["path"];
Warehouse.Get(path).Then((r) =>
{
if (r is DistributedServer)
{
var httpServer = sender.Parent;
var iipServer = r as DistributedServer;
var tcpSocket = sender.Unassign();
if (tcpSocket == null)
return;
var wsSocket = new WSSocket(tcpSocket);
httpServer.RemoveConnection(sender);
//httpServer.Connections.Remove(sender);
var iipConnection = new DistributedConnection();
// iipConnection.OnReady += IipConnection_OnReady;
// iipConnection.Server = iipServer;
// iipConnection.Assign(wsSocket);
iipServer.AddConnection(iipConnection);
iipConnection.Assign(wsSocket);
wsSocket.Begin();
}
});
return true;
}
return false;
*/
}
private void IipConnection_OnReady(DistributedConnection sender)
{
Warehouse.Put(sender.RemoteUsername, sender, null, sender.Server).Wait();
} }
public override AsyncReply<bool> Trigger(ResourceTrigger trigger) public override AsyncReply<bool> Trigger(ResourceTrigger trigger)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
using Esiur.Core;
using Esiur.Data;
using Esiur.Net.Packets;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.IIP
{
public class DistributedConnectionConfig
{
public ExceptionLevel ExceptionLevel { get; set; }
= ExceptionLevel.Code | ExceptionLevel.Message | ExceptionLevel.Source | ExceptionLevel.Trace;
public Func<Map<IIPAuthPacketIAuthHeader, object>, AsyncReply<object>> Authenticator { get; set; }
public bool AutoReconnect { get; set; } = false;
public uint ReconnectInterval { get; set; } = 5;
public string Username { get; set; }
public bool UseWebSocket { get; set; }
public bool SecureWebSocket { get; set; }
public string Password { get; set; }
public string Token { get; set; }
public ulong TokenIndex { get; set; }
public string Domain { get; set; }
}
}

View File

@ -24,7 +24,6 @@ SOFTWARE.
using Esiur.Data; using Esiur.Data;
using Esiur.Core; using Esiur.Core;
using Esiur.Net.Packets;
using Esiur.Resource; using Esiur.Resource;
using Esiur.Resource.Template; using Esiur.Resource.Template;
using Esiur.Security.Authority; using Esiur.Security.Authority;
@ -38,6 +37,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using Esiur.Misc; using Esiur.Misc;
using Esiur.Net.Packets;
namespace Esiur.Net.IIP; namespace Esiur.Net.IIP;
@ -69,7 +69,6 @@ partial class DistributedConnection
AsyncQueue<DistributedResourceQueueItem> queue = new AsyncQueue<DistributedResourceQueueItem>(); AsyncQueue<DistributedResourceQueueItem> queue = new AsyncQueue<DistributedResourceQueueItem>();
DateTime? lastKeepAliveReceived;
/// <summary> /// <summary>
/// Send IIP request. /// Send IIP request.
@ -77,7 +76,7 @@ partial class DistributedConnection
/// <param name="action">Packet action.</param> /// <param name="action">Packet action.</param>
/// <param name="args">Arguments to send.</param> /// <param name="args">Arguments to send.</param>
/// <returns></returns> /// <returns></returns>
internal SendList SendRequest(IIPPacket.IIPPacketAction action) internal SendList SendRequest(IIPPacketAction action)
{ {
var reply = new AsyncReply<object[]>(); var reply = new AsyncReply<object[]>();
var c = callbackCounter++; // avoid thread racing var c = callbackCounter++; // avoid thread racing
@ -101,12 +100,12 @@ partial class DistributedConnection
//uint maxcallerid = 0; //uint maxcallerid = 0;
internal SendList SendReply(IIPPacket.IIPPacketAction action, uint callbackId) internal SendList SendReply(IIPPacketAction action, uint callbackId)
{ {
return (SendList)SendParams().AddUInt8((byte)(0x80 | (byte)action)).AddUInt32(callbackId); return (SendList)SendParams().AddUInt8((byte)(0x80 | (byte)action)).AddUInt32(callbackId);
} }
internal SendList SendEvent(IIPPacket.IIPPacketEvent evt) internal SendList SendEvent(IIPPacketEvent evt)
{ {
return (SendList)SendParams().AddUInt8((byte)(evt)); return (SendList)SendParams().AddUInt8((byte)(evt));
} }
@ -117,7 +116,7 @@ partial class DistributedConnection
var c = callbackCounter++; var c = callbackCounter++;
requests.Add(c, reply); requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)Packets.IIPPacket.IIPPacketAction.Listen)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketAction.Listen))
.AddUInt32(c) .AddUInt32(c)
.AddUInt32(instanceId) .AddUInt32(instanceId)
.AddUInt8(index) .AddUInt8(index)
@ -132,7 +131,7 @@ partial class DistributedConnection
var c = callbackCounter++; var c = callbackCounter++;
requests.Add(c, reply); requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)Packets.IIPPacket.IIPPacketAction.Unlisten)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketAction.Unlisten))
.AddUInt32(c) .AddUInt32(c)
.AddUInt32(instanceId) .AddUInt32(instanceId)
.AddUInt8(index) .AddUInt8(index)
@ -151,7 +150,7 @@ partial class DistributedConnection
requests.Add(c, reply); requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacket.IIPPacketAction.StaticCall)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketAction.StaticCall))
.AddUInt32(c) .AddUInt32(c)
.AddGuid(classId) .AddGuid(classId)
.AddUInt8(index) .AddUInt8(index)
@ -179,7 +178,7 @@ partial class DistributedConnection
var callName = DC.ToBytes(procedureCall); var callName = DC.ToBytes(procedureCall);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacket.IIPPacketAction.ProcedureCall)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketAction.ProcedureCall))
.AddUInt32(c) .AddUInt32(c)
.AddUInt16((ushort)callName.Length) .AddUInt16((ushort)callName.Length)
.AddUInt8Array(callName) .AddUInt8Array(callName)
@ -197,7 +196,7 @@ partial class DistributedConnection
var c = callbackCounter++; var c = callbackCounter++;
requests.Add(c, reply); requests.Add(c, reply);
SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacket.IIPPacketAction.InvokeFunction)) SendParams().AddUInt8((byte)(0x40 | (byte)IIPPacketAction.InvokeFunction))
.AddUInt32(c) .AddUInt32(c)
.AddUInt32(instanceId) .AddUInt32(instanceId)
.AddUInt8(index) .AddUInt8(index)
@ -210,7 +209,7 @@ partial class DistributedConnection
{ {
try try
{ {
return SendRequest(IIPPacket.IIPPacketAction.DetachResource).AddUInt32(instanceId).Done(); return SendRequest(IIPPacketAction.DetachResource).AddUInt32(instanceId).Done();
} }
catch catch
{ {
@ -241,13 +240,13 @@ partial class DistributedConnection
var msg = DC.ToBytes(errorMessage); var msg = DC.ToBytes(errorMessage);
if (type == ErrorType.Management) if (type == ErrorType.Management)
SendParams() SendParams()
.AddUInt8((byte)(0xC0 | (byte)IIPPacket.IIPPacketReport.ManagementError)) .AddUInt8((byte)(0xC0 | (byte)IIPPacketReport.ManagementError))
.AddUInt32(callbackId) .AddUInt32(callbackId)
.AddUInt16(errorCode) .AddUInt16(errorCode)
.Done(); .Done();
else if (type == ErrorType.Exception) else if (type == ErrorType.Exception)
SendParams() SendParams()
.AddUInt8((byte)(0xC0 | (byte)IIPPacket.IIPPacketReport.ExecutionError)) .AddUInt8((byte)(0xC0 | (byte)IIPPacketReport.ExecutionError))
.AddUInt32(callbackId) .AddUInt32(callbackId)
.AddUInt16(errorCode) .AddUInt16(errorCode)
.AddUInt16((ushort)msg.Length) .AddUInt16((ushort)msg.Length)
@ -258,7 +257,7 @@ partial class DistributedConnection
void SendProgress(uint callbackId, int value, int max) void SendProgress(uint callbackId, int value, int max)
{ {
SendParams() SendParams()
.AddUInt8((byte)(0xC0 | (byte)IIPPacket.IIPPacketReport.ProgressReport)) .AddUInt8((byte)(0xC0 | (byte)IIPPacketReport.ProgressReport))
.AddUInt32(callbackId) .AddUInt32(callbackId)
.AddInt32(value) .AddInt32(value)
.AddInt32(max) .AddInt32(max)
@ -270,7 +269,7 @@ partial class DistributedConnection
{ {
var c = Codec.Compose(chunk, this); var c = Codec.Compose(chunk, this);
SendParams() SendParams()
.AddUInt8((byte)(0xC0 | (byte)IIPPacket.IIPPacketReport.ChunkStream)) .AddUInt8((byte)(0xC0 | (byte)IIPPacketReport.ChunkStream))
.AddUInt32(callbackId) .AddUInt32(callbackId)
.AddUInt8Array(c) .AddUInt8Array(c)
.Done(); .Done();
@ -555,7 +554,7 @@ partial class DistributedConnection
if (r is DistributedResource) if (r is DistributedResource)
{ {
// reply ok // reply ok
SendReply(IIPPacket.IIPPacketAction.AttachResource, callback) SendReply(IIPPacketAction.AttachResource, callback)
.AddGuid(r.Instance.Template.ClassId) .AddGuid(r.Instance.Template.ClassId)
.AddUInt64(r.Instance.Age) .AddUInt64(r.Instance.Age)
.AddUInt16((ushort)link.Length) .AddUInt16((ushort)link.Length)
@ -567,7 +566,7 @@ partial class DistributedConnection
else else
{ {
// reply ok // reply ok
SendReply(IIPPacket.IIPPacketAction.AttachResource, callback) SendReply(IIPPacketAction.AttachResource, callback)
.AddGuid(r.Instance.Template.ClassId) .AddGuid(r.Instance.Template.ClassId)
.AddUInt64(r.Instance.Age) .AddUInt64(r.Instance.Age)
.AddUInt16((ushort)link.Length) .AddUInt16((ushort)link.Length)
@ -611,7 +610,7 @@ partial class DistributedConnection
{ {
var instance = (sender.Owner as Instance); var instance = (sender.Owner as Instance);
var name = DC.ToBytes(newValue.ToString()); var name = DC.ToBytes(newValue.ToString());
SendEvent(IIPPacket.IIPPacketEvent.ChildRemoved) SendEvent(IIPPacketEvent.ChildRemoved)
.AddUInt32(instance.Id) .AddUInt32(instance.Id)
.AddUInt16((ushort)name.Length) .AddUInt16((ushort)name.Length)
.AddUInt8Array(name) .AddUInt8Array(name)
@ -621,7 +620,7 @@ partial class DistributedConnection
private void Children_OnRemoved(Instance sender, IResource value) private void Children_OnRemoved(Instance sender, IResource value)
{ {
SendEvent(IIPPacket.IIPPacketEvent.ChildRemoved) SendEvent(IIPPacketEvent.ChildRemoved)
.AddUInt32(sender.Id) .AddUInt32(sender.Id)
.AddUInt32(value.Instance.Id) .AddUInt32(value.Instance.Id)
.Done(); .Done();
@ -630,7 +629,7 @@ partial class DistributedConnection
private void Children_OnAdd(Instance sender, IResource value) private void Children_OnAdd(Instance sender, IResource value)
{ {
//if (sender.Applicable(sender.Resource, this.session, ActionType.)) //if (sender.Applicable(sender.Resource, this.session, ActionType.))
SendEvent(IIPPacket.IIPPacketEvent.ChildAdded) SendEvent(IIPPacketEvent.ChildAdded)
.AddUInt32(sender.Id) .AddUInt32(sender.Id)
.AddUInt32(value.Instance.Id) .AddUInt32(value.Instance.Id)
.Done(); .Done();
@ -639,7 +638,7 @@ partial class DistributedConnection
public bool RemoveChild(IResource parent, IResource child) public bool RemoveChild(IResource parent, IResource child)
{ {
SendEvent(IIPPacket.IIPPacketEvent.ChildRemoved) SendEvent(IIPPacketEvent.ChildRemoved)
.AddUInt32((parent as DistributedResource).DistributedResourceInstanceId) .AddUInt32((parent as DistributedResource).DistributedResourceInstanceId)
.AddUInt32((child as DistributedResource).DistributedResourceInstanceId) .AddUInt32((child as DistributedResource).DistributedResourceInstanceId)
.Done(); .Done();
@ -649,7 +648,7 @@ partial class DistributedConnection
public bool AddChild(IResource parent, IResource child) public bool AddChild(IResource parent, IResource child)
{ {
SendEvent(IIPPacket.IIPPacketEvent.ChildAdded) SendEvent(IIPPacketEvent.ChildAdded)
.AddUInt32((parent as DistributedResource).DistributedResourceInstanceId) .AddUInt32((parent as DistributedResource).DistributedResourceInstanceId)
.AddUInt32((child as DistributedResource).DistributedResourceInstanceId) .AddUInt32((child as DistributedResource).DistributedResourceInstanceId)
.Done(); .Done();
@ -691,7 +690,7 @@ partial class DistributedConnection
//r.Instance.Attributes.OnModified += Attributes_OnModified; //r.Instance.Attributes.OnModified += Attributes_OnModified;
// reply ok // reply ok
SendReply(IIPPacket.IIPPacketAction.ReattachResource, callback) SendReply(IIPPacketAction.ReattachResource, callback)
.AddUInt64(r.Instance.Age) .AddUInt64(r.Instance.Age)
.AddUInt8Array(Codec.Compose(r.Instance.Serialize(), this)) .AddUInt8Array(Codec.Compose(r.Instance.Serialize(), this))
.Done(); .Done();
@ -720,7 +719,7 @@ partial class DistributedConnection
//attachedResources.Remove(res); //attachedResources.Remove(res);
// reply ok // reply ok
SendReply(IIPPacket.IIPPacketAction.DetachResource, callback).Done(); SendReply(IIPPacketAction.DetachResource, callback).Done();
} }
else else
{ {
@ -847,7 +846,7 @@ partial class DistributedConnection
Warehouse.Put(name, resource, store as IStore, parent).Then(ok => Warehouse.Put(name, resource, store as IStore, parent).Then(ok =>
{ {
SendReply(IIPPacket.IIPPacketAction.CreateResource, callback) SendReply(IIPPacketAction.CreateResource, callback)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.Done(); .Done();
@ -880,7 +879,7 @@ partial class DistributedConnection
} }
if (Warehouse.Remove(r)) if (Warehouse.Remove(r))
SendReply(IIPPacket.IIPPacketAction.DeleteResource, callback).Done(); SendReply(IIPPacketAction.DeleteResource, callback).Done();
//SendParams((byte)0x84, callback); //SendParams((byte)0x84, callback);
else else
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.DeleteFailed); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.DeleteFailed);
@ -912,7 +911,7 @@ partial class DistributedConnection
var st = r.Instance.GetAttributes(attrs); var st = r.Instance.GetAttributes(attrs);
if (st != null) if (st != null)
SendReply(all ? IIPPacket.IIPPacketAction.GetAllAttributes : IIPPacket.IIPPacketAction.GetAttributes, callback) SendReply(all ? IIPPacketAction.GetAllAttributes : IIPPacketAction.GetAttributes, callback)
.AddUInt8Array(Codec.Compose(st, this)) .AddUInt8Array(Codec.Compose(st, this))
.Done(); .Done();
else else
@ -953,7 +952,7 @@ partial class DistributedConnection
parent.Instance.Store.AddChild(parent, child); parent.Instance.Store.AddChild(parent, child);
SendReply(IIPPacket.IIPPacketAction.AddChild, callback).Done(); SendReply(IIPPacketAction.AddChild, callback).Done();
//child.Instance.Parents //child.Instance.Parents
}); });
@ -992,7 +991,7 @@ partial class DistributedConnection
parent.Instance.Store.RemoveChild(parent, child);// Children.Remove(child); parent.Instance.Store.RemoveChild(parent, child);// Children.Remove(child);
SendReply(IIPPacket.IIPPacketAction.RemoveChild, callback).Done(); SendReply(IIPPacketAction.RemoveChild, callback).Done();
//child.Instance.Parents //child.Instance.Parents
}); });
@ -1017,7 +1016,7 @@ partial class DistributedConnection
resource.Instance.Name = name; resource.Instance.Name = name;
SendReply(IIPPacket.IIPPacketAction.RenameResource, callback).Done(); SendReply(IIPPacketAction.RenameResource, callback).Done();
}); });
} }
@ -1033,7 +1032,7 @@ partial class DistributedConnection
resource.Instance.Children<IResource>().Then(children => resource.Instance.Children<IResource>().Then(children =>
{ {
SendReply(IIPPacket.IIPPacketAction.ResourceChildren, callback) SendReply(IIPPacketAction.ResourceChildren, callback)
.AddUInt8Array(Codec.Compose(children, this))// Codec.ComposeResourceArray(children, this, true)) .AddUInt8Array(Codec.Compose(children, this))// Codec.ComposeResourceArray(children, this, true))
.Done(); .Done();
@ -1055,7 +1054,7 @@ partial class DistributedConnection
resource.Instance.Parents<IResource>().Then(parents => resource.Instance.Parents<IResource>().Then(parents =>
{ {
SendReply(IIPPacket.IIPPacketAction.ResourceParents, callback) SendReply(IIPPacketAction.ResourceParents, callback)
.AddUInt8Array(Codec.Compose(parents, this)) .AddUInt8Array(Codec.Compose(parents, this))
//.AddUInt8Array(Codec.ComposeResourceArray(parents, this, true)) //.AddUInt8Array(Codec.ComposeResourceArray(parents, this, true))
.Done(); .Done();
@ -1087,7 +1086,7 @@ partial class DistributedConnection
attrs = attributes.GetStringArray(0, (uint)attributes.Length); attrs = attributes.GetStringArray(0, (uint)attributes.Length);
if (r.Instance.RemoveAttributes(attrs)) if (r.Instance.RemoveAttributes(attrs))
SendReply(all ? IIPPacket.IIPPacketAction.ClearAllAttributes : IIPPacket.IIPPacketAction.ClearAttributes, callback).Done(); SendReply(all ? IIPPacketAction.ClearAllAttributes : IIPPacketAction.ClearAttributes, callback).Done();
else else
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed);
@ -1114,7 +1113,7 @@ partial class DistributedConnection
DataDeserializer.TypedMapParser(attributes, 0, (uint)attributes.Length, this, null).Then(attrs => DataDeserializer.TypedMapParser(attributes, 0, (uint)attributes.Length, this, null).Then(attrs =>
{ {
if (r.Instance.SetAttributes((Map<string, object>)attrs, clearAttributes)) if (r.Instance.SetAttributes((Map<string, object>)attrs, clearAttributes))
SendReply(clearAttributes ? IIPPacket.IIPPacketAction.ClearAllAttributes : IIPPacket.IIPPacketAction.ClearAttributes, SendReply(clearAttributes ? IIPPacketAction.ClearAllAttributes : IIPPacketAction.ClearAttributes,
callback).Done(); callback).Done();
else else
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.UpdateAttributeFailed);
@ -1153,7 +1152,7 @@ partial class DistributedConnection
} }
// digggg // digggg
SendReply(IIPPacket.IIPPacketAction.LinkTemplates, callback) SendReply(IIPPacketAction.LinkTemplates, callback)
//.AddInt32(msg.Length) //.AddInt32(msg.Length)
//.AddUInt8Array(msg.ToArray()) //.AddUInt8Array(msg.ToArray())
.AddUInt8Array(TransmissionType.Compose(TransmissionTypeIdentifier.RawData, msg.ToArray())) .AddUInt8Array(TransmissionType.Compose(TransmissionTypeIdentifier.RawData, msg.ToArray()))
@ -1173,7 +1172,7 @@ partial class DistributedConnection
var t = Warehouse.GetTemplateByClassName(className); var t = Warehouse.GetTemplateByClassName(className);
if (t != null) if (t != null)
SendReply(IIPPacket.IIPPacketAction.TemplateFromClassName, callback) SendReply(IIPPacketAction.TemplateFromClassName, callback)
.AddUInt8Array(TransmissionType.Compose(TransmissionTypeIdentifier.RawData, t.Content)) .AddUInt8Array(TransmissionType.Compose(TransmissionTypeIdentifier.RawData, t.Content))
//.AddInt32(t.Content.Length) //.AddInt32(t.Content.Length)
//.AddUInt8Array(t.Content) //.AddUInt8Array(t.Content)
@ -1190,7 +1189,7 @@ partial class DistributedConnection
var t = Warehouse.GetTemplateByClassId(classId); var t = Warehouse.GetTemplateByClassId(classId);
if (t != null) if (t != null)
SendReply(IIPPacket.IIPPacketAction.TemplateFromClassId, callback) SendReply(IIPPacketAction.TemplateFromClassId, callback)
.AddUInt8Array(TransmissionType.Compose(TransmissionTypeIdentifier.RawData, t.Content)) .AddUInt8Array(TransmissionType.Compose(TransmissionTypeIdentifier.RawData, t.Content))
//.AddInt32(t.Content.Length) //.AddInt32(t.Content.Length)
//.AddUInt8Array(t.Content) //.AddUInt8Array(t.Content)
@ -1209,7 +1208,7 @@ partial class DistributedConnection
Warehouse.GetById(resourceId).Then((r) => Warehouse.GetById(resourceId).Then((r) =>
{ {
if (r != null) if (r != null)
SendReply(IIPPacket.IIPPacketAction.TemplateFromResourceId, callback) SendReply(IIPPacketAction.TemplateFromResourceId, callback)
.AddInt32(r.Instance.Template.Content.Length) .AddInt32(r.Instance.Template.Content.Length)
.AddUInt8Array(r.Instance.Template.Content) .AddUInt8Array(r.Instance.Template.Content)
.Done(); .Done();
@ -1238,7 +1237,7 @@ partial class DistributedConnection
if (list.Length == 0) if (list.Length == 0)
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.ResourceNotFound);
else else
SendReply(IIPPacket.IIPPacketAction.QueryLink, callback) SendReply(IIPPacketAction.QueryLink, callback)
.AddUInt8Array(Codec.Compose(list, this)) .AddUInt8Array(Codec.Compose(list, this))
//.AddUInt8Array(Codec.ComposeResourceArray(list, this, true)) //.AddUInt8Array(Codec.ComposeResourceArray(list, this, true))
.Done(); .Done();
@ -1304,7 +1303,7 @@ partial class DistributedConnection
// return; // return;
//} //}
InvokeFunction(call.Value.Template, callback, arguments, IIPPacket.IIPPacketAction.ProcedureCall, call.Value.Delegate.Target); InvokeFunction(call.Value.Template, callback, arguments, IIPPacketAction.ProcedureCall, call.Value.Delegate.Target);
}).Error(x => }).Error(x =>
{ {
@ -1357,7 +1356,7 @@ partial class DistributedConnection
// return; // return;
//} //}
InvokeFunction(ft, callback, arguments, IIPPacket.IIPPacketAction.StaticCall, null); InvokeFunction(ft, callback, arguments, IIPPacketAction.StaticCall, null);
}).Error(x => }).Error(x =>
{ {
@ -1403,7 +1402,7 @@ partial class DistributedConnection
{ {
rt.Then(res => rt.Then(res =>
{ {
SendReply(IIPPacket.IIPPacketAction.InvokeFunction, callback) SendReply(IIPPacketAction.InvokeFunction, callback)
.AddUInt8Array(Codec.Compose(res, this)) .AddUInt8Array(Codec.Compose(res, this))
.Done(); .Done();
}); });
@ -1434,7 +1433,7 @@ partial class DistributedConnection
return; return;
} }
InvokeFunction(ft, callback, arguments, IIPPacket.IIPPacketAction.InvokeFunction, r); InvokeFunction(ft, callback, arguments, IIPPacketAction.InvokeFunction, r);
} }
}); });
}); });
@ -1442,7 +1441,7 @@ partial class DistributedConnection
void InvokeFunction(FunctionTemplate ft, uint callback, Map<byte, object> arguments, IIPPacket.IIPPacketAction actionType, object target = null) void InvokeFunction(FunctionTemplate ft, uint callback, Map<byte, object> arguments, IIPPacketAction actionType, object target = null)
{ {
// cast arguments // cast arguments
@ -1575,7 +1574,7 @@ partial class DistributedConnection
{ {
(r as DistributedResource).Listen(et).Then(x => (r as DistributedResource).Listen(et).Then(x =>
{ {
SendReply(IIPPacket.IIPPacketAction.Listen, callback).Done(); SendReply(IIPPacketAction.Listen, callback).Done();
}).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure)); }).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure));
} }
else else
@ -1596,7 +1595,7 @@ partial class DistributedConnection
subscriptions[r].Add(index); subscriptions[r].Add(index);
SendReply(IIPPacket.IIPPacketAction.Listen, callback).Done(); SendReply(IIPPacketAction.Listen, callback).Done();
} }
} }
} }
@ -1629,7 +1628,7 @@ partial class DistributedConnection
{ {
(r as DistributedResource).Unlisten(et).Then(x => (r as DistributedResource).Unlisten(et).Then(x =>
{ {
SendReply(IIPPacket.IIPPacketAction.Unlisten, callback).Done(); SendReply(IIPPacketAction.Unlisten, callback).Done();
}).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure)); }).Error(x => SendError(ErrorType.Exception, callback, (ushort)ExceptionCode.GeneralFailure));
} }
else else
@ -1650,7 +1649,7 @@ partial class DistributedConnection
subscriptions[r].Remove(index); subscriptions[r].Remove(index);
SendReply(IIPPacket.IIPPacketAction.Unlisten, callback).Done(); SendReply(IIPPacketAction.Unlisten, callback).Done();
} }
} }
} }
@ -1743,7 +1742,7 @@ partial class DistributedConnection
}*/ }*/
SendReply(IIPPacket.IIPPacketAction.ResourceHistory, callback) SendReply(IIPPacketAction.ResourceHistory, callback)
.AddUInt8Array(history) .AddUInt8Array(history)
.Done(); .Done();
@ -1820,7 +1819,7 @@ partial class DistributedConnection
// propagation // propagation
(r as DistributedResource)._Set(index, value).Then((x) => (r as DistributedResource)._Set(index, value).Then((x) =>
{ {
SendReply(IIPPacket.IIPPacketAction.SetProperty, callback).Done(); SendReply(IIPPacketAction.SetProperty, callback).Done();
}).Error(x => }).Error(x =>
{ {
SendError(x.Type, callback, (ushort)x.Code, x.Message); SendError(x.Type, callback, (ushort)x.Code, x.Message);
@ -1871,7 +1870,7 @@ partial class DistributedConnection
{ {
pi.SetValue(r, value); pi.SetValue(r, value);
SendReply(IIPPacket.IIPPacketAction.SetProperty, callback).Done(); SendReply(IIPPacketAction.SetProperty, callback).Done();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -2053,7 +2052,7 @@ partial class DistributedConnection
var reply = new AsyncReply<TypeTemplate>(); var reply = new AsyncReply<TypeTemplate>();
templateRequests.Add(classId, reply); templateRequests.Add(classId, reply);
SendRequest(IIPPacket.IIPPacketAction.TemplateFromClassId) SendRequest(IIPPacketAction.TemplateFromClassId)
.AddGuid(classId) .AddGuid(classId)
.Done() .Done()
.Then((rt) => .Then((rt) =>
@ -2085,7 +2084,7 @@ partial class DistributedConnection
var classNameBytes = DC.ToBytes(className); var classNameBytes = DC.ToBytes(className);
SendRequest(IIPPacket.IIPPacketAction.TemplateFromClassName) SendRequest(IIPPacketAction.TemplateFromClassName)
.AddUInt8((byte)classNameBytes.Length) .AddUInt8((byte)classNameBytes.Length)
.AddUInt8Array(classNameBytes) .AddUInt8Array(classNameBytes)
.Done() .Done()
@ -2179,7 +2178,7 @@ partial class DistributedConnection
var l = DC.ToBytes(link); var l = DC.ToBytes(link);
SendRequest(IIPPacket.IIPPacketAction.LinkTemplates) SendRequest(IIPPacketAction.LinkTemplates)
.AddUInt16((ushort)l.Length) .AddUInt16((ushort)l.Length)
.AddUInt8Array(l) .AddUInt8Array(l)
.Done() .Done()
@ -2249,7 +2248,7 @@ partial class DistributedConnection
var newSequence = requestSequence != null ? requestSequence.Concat(new uint[] { id }).ToArray() : new uint[] { id }; var newSequence = requestSequence != null ? requestSequence.Concat(new uint[] { id }).ToArray() : new uint[] { id };
SendRequest(IIPPacket.IIPPacketAction.AttachResource) SendRequest(IIPPacketAction.AttachResource)
.AddUInt32(id) .AddUInt32(id)
.Done() .Done()
.Then((rt) => .Then((rt) =>
@ -2352,7 +2351,7 @@ partial class DistributedConnection
{ {
var rt = new AsyncReply<IResource[]>(); var rt = new AsyncReply<IResource[]>();
SendRequest(IIPPacket.IIPPacketAction.ResourceChildren) SendRequest(IIPPacketAction.ResourceChildren)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.Done() .Done()
.Then(ar => .Then(ar =>
@ -2378,7 +2377,7 @@ partial class DistributedConnection
{ {
var rt = new AsyncReply<IResource[]>(); var rt = new AsyncReply<IResource[]>();
SendRequest(IIPPacket.IIPPacketAction.ResourceParents) SendRequest(IIPPacketAction.ResourceParents)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.Done() .Done()
.Then(ar => .Then(ar =>
@ -2404,7 +2403,7 @@ partial class DistributedConnection
var rt = new AsyncReply<bool>(); var rt = new AsyncReply<bool>();
if (attributes == null) if (attributes == null)
SendRequest(IIPPacket.IIPPacketAction.ClearAllAttributes) SendRequest(IIPPacketAction.ClearAllAttributes)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.Done() .Done()
.Then(ar => rt.Trigger(true)) .Then(ar => rt.Trigger(true))
@ -2412,7 +2411,7 @@ partial class DistributedConnection
else else
{ {
var attrs = DC.ToBytes(attributes); var attrs = DC.ToBytes(attributes);
SendRequest(IIPPacket.IIPPacketAction.ClearAttributes) SendRequest(IIPPacketAction.ClearAttributes)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.AddInt32(attrs.Length) .AddInt32(attrs.Length)
.AddUInt8Array(attrs) .AddUInt8Array(attrs)
@ -2428,7 +2427,7 @@ partial class DistributedConnection
{ {
var rt = new AsyncReply<bool>(); var rt = new AsyncReply<bool>();
SendRequest(clearAttributes ? IIPPacket.IIPPacketAction.UpdateAllAttributes : IIPPacket.IIPPacketAction.UpdateAttributes) SendRequest(clearAttributes ? IIPPacketAction.UpdateAllAttributes : IIPPacketAction.UpdateAttributes)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
//.AddUInt8Array(Codec.ComposeStructure(attributes, this, true, true, true)) //.AddUInt8Array(Codec.ComposeStructure(attributes, this, true, true, true))
.AddUInt8Array(Codec.Compose(attributes, this)) .AddUInt8Array(Codec.Compose(attributes, this))
@ -2445,7 +2444,7 @@ partial class DistributedConnection
if (attributes == null) if (attributes == null)
{ {
SendRequest(IIPPacket.IIPPacketAction.GetAllAttributes) SendRequest(IIPPacketAction.GetAllAttributes)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.Done() .Done()
.Then(ar => .Then(ar =>
@ -2466,7 +2465,7 @@ partial class DistributedConnection
else else
{ {
var attrs = DC.ToBytes(attributes); var attrs = DC.ToBytes(attributes);
SendRequest(IIPPacket.IIPPacketAction.GetAttributes) SendRequest(IIPPacketAction.GetAttributes)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.AddInt32(attrs.Length) .AddInt32(attrs.Length)
.AddUInt8Array(attrs) .AddUInt8Array(attrs)
@ -2508,7 +2507,7 @@ partial class DistributedConnection
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>(); var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
SendRequest(IIPPacket.IIPPacketAction.ResourceHistory) SendRequest(IIPPacketAction.ResourceHistory)
.AddUInt32(dr.DistributedResourceInstanceId) .AddUInt32(dr.DistributedResourceInstanceId)
.AddDateTime(fromDate) .AddDateTime(fromDate)
.AddDateTime(toDate) .AddDateTime(toDate)
@ -2538,7 +2537,7 @@ partial class DistributedConnection
var str = DC.ToBytes(path); var str = DC.ToBytes(path);
var reply = new AsyncReply<IResource[]>(); var reply = new AsyncReply<IResource[]>();
SendRequest(IIPPacket.IIPPacketAction.QueryLink) SendRequest(IIPPacketAction.QueryLink)
.AddUInt16((ushort)str.Length) .AddUInt16((ushort)str.Length)
.AddUInt8Array(str) .AddUInt8Array(str)
.Done() .Done()
@ -2584,7 +2583,7 @@ partial class DistributedConnection
pkt.InsertInt32(8, pkt.Length); pkt.InsertInt32(8, pkt.Length);
SendRequest(IIPPacket.IIPPacketAction.CreateResource) SendRequest(IIPPacketAction.CreateResource)
.AddUInt8Array(pkt.ToArray()) .AddUInt8Array(pkt.ToArray())
.Done() .Done()
.Then(args => .Then(args =>
@ -2650,7 +2649,7 @@ partial class DistributedConnection
Unsubscribe(resource); Unsubscribe(resource);
// compose the packet // compose the packet
SendEvent(IIPPacket.IIPPacketEvent.ResourceDestroyed) SendEvent(IIPPacketEvent.ResourceDestroyed)
.AddUInt32(resource.Instance.Id) .AddUInt32(resource.Instance.Id)
.Done(); .Done();
@ -2663,7 +2662,7 @@ partial class DistributedConnection
// if (pt == null) // if (pt == null)
// return; // return;
SendEvent(IIPPacket.IIPPacketEvent.PropertyUpdated) SendEvent(IIPPacketEvent.PropertyUpdated)
.AddUInt32(info.Resource.Instance.Id) .AddUInt32(info.Resource.Instance.Id)
.AddUInt8(info.PropertyTemplate.Index) .AddUInt8(info.PropertyTemplate.Index)
.AddUInt8Array(Codec.Compose(info.Value, this)) .AddUInt8Array(Codec.Compose(info.Value, this))
@ -2696,7 +2695,7 @@ partial class DistributedConnection
// compose the packet // compose the packet
SendEvent(IIPPacket.IIPPacketEvent.EventOccurred) SendEvent(IIPPacketEvent.EventOccurred)
.AddUInt32(info.Resource.Instance.Id) .AddUInt32(info.Resource.Instance.Id)
.AddUInt8((byte)info.EventTemplate.Index) .AddUInt8((byte)info.EventTemplate.Index)
.AddUInt8Array(Codec.Compose(info.Value, this)) .AddUInt8Array(Codec.Compose(info.Value, this))
@ -2722,7 +2721,7 @@ partial class DistributedConnection
return; return;
// compose the packet // compose the packet
SendEvent(IIPPacket.IIPPacketEvent.EventOccurred) SendEvent(IIPPacketEvent.EventOccurred)
.AddUInt32(info.Resource.Instance.Id) .AddUInt32(info.Resource.Instance.Id)
.AddUInt8((byte)info.EventTemplate.Index) .AddUInt8((byte)info.EventTemplate.Index)
.AddUInt8Array(Codec.Compose(info.Value, this)) .AddUInt8Array(Codec.Compose(info.Value, this))
@ -2747,7 +2746,7 @@ partial class DistributedConnection
} }
SendParams() SendParams()
.AddUInt8((byte)(0x80 | (byte)IIPPacket.IIPPacketAction.KeepAlive)) .AddUInt8((byte)(0x80 | (byte)IIPPacketAction.KeepAlive))
.AddUInt32(callbackId) .AddUInt32(callbackId)
.AddDateTime(now) .AddDateTime(now)
.AddUInt32(jitter) .AddUInt32(jitter)

View File

@ -41,6 +41,7 @@ using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Esiur.Resource; using Esiur.Resource;
using Esiur.Resource.Template; using Esiur.Resource.Template;
using Esiur.Net.Packets;
namespace Esiur.Net.IIP; namespace Esiur.Net.IIP;
@ -459,7 +460,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
var reply = new AsyncReply<object>(); var reply = new AsyncReply<object>();
var parameters = Codec.Compose(value, connection); var parameters = Codec.Compose(value, connection);
connection.SendRequest(Packets.IIPPacket.IIPPacketAction.SetProperty) connection.SendRequest(IIPPacketAction.SetProperty)
.AddUInt32(instanceId) .AddUInt32(instanceId)
.AddUInt8(index) .AddUInt8(index)
.AddUInt8Array(parameters) .AddUInt8Array(parameters)

View File

@ -41,7 +41,6 @@ namespace Esiur.Net.IIP;
public class DistributedServer : NetworkServer<DistributedConnection>, IResource public class DistributedServer : NetworkServer<DistributedConnection>, IResource
{ {
[Attribute] [Attribute]
public string IP public string IP
@ -50,11 +49,30 @@ public class DistributedServer : NetworkServer<DistributedConnection>, IResource
set; set;
} }
IMembership membership;
[Attribute] [Attribute]
public IMembership Membership public IMembership Membership
{ {
get; get => membership;
set; set
{
if (membership != null)
membership.Authorization -= Membership_Authorization;
membership = value;
if (membership != null)
membership.Authorization += Membership_Authorization;
}
}
private void Membership_Authorization(AuthorizationIndication indication)
{
lock (Connections.SyncRoot)
foreach (var connection in Connections)
if (connection.Session == indication.Session)
connection.ProcessAuthorization(indication.Results);
} }
[Attribute] [Attribute]
@ -116,41 +134,6 @@ public class DistributedServer : NetworkServer<DistributedConnection>, IResource
//protected override void DataReceived(DistributedConnection sender, NetworkBuffer data)
//{
// //throw new NotImplementedException();
//}
//protected override void ClientConnected(DistributedConnection sender)
//{
// //Console.WriteLine("DistributedConnection Client Connected");
//}
//private void ConnectionReadyEventReceiver(DistributedConnection sender)
//{
// sender.OnReady -= ConnectionReadyEventReceiver;
// Warehouse.Put(sender, sender.LocalUsername, null, this);
//}
//public override void RemoveConnection(DistributedConnection connection)
//{
// connection.OnReady -= Sender_OnReady;
// //connection.Server = null;
// base.RemoveConnection(connection);
//}
//public override void AddConnection(DistributedConnection connection)
//{
// connection.OnReady += Sender_OnReady;
// connection.Server = this;
// base.AddConnection(connection);
//}
protected override void ClientConnected(DistributedConnection connection) protected override void ClientConnected(DistributedConnection connection)
{ {
//Task.Delay(10000).ContinueWith((x) => //Task.Delay(10000).ContinueWith((x) =>
@ -180,8 +163,6 @@ public class DistributedServer : NetworkServer<DistributedConnection>, IResource
{ {
//connection.OnReady -= ConnectionReadyEventReceiver; //connection.OnReady -= ConnectionReadyEventReceiver;
//Warehouse.Remove(connection); //Warehouse.Remove(connection);
} }
public KeyList<string, CallInfo?> Calls { get; } = new KeyList<string, CallInfo?>(); public KeyList<string, CallInfo?> Calls { get; } = new KeyList<string, CallInfo?>();
@ -195,7 +176,7 @@ public class DistributedServer : NetworkServer<DistributedConnection>, IResource
public DistributedServer MapCall(string call, Delegate handler) public DistributedServer MapCall(string call, Delegate handler)
{ {
var ft = FunctionTemplate.MakeFunctionTemplate(null, handler.Method); var ft = FunctionTemplate.MakeFunctionTemplate(null, handler.Method);
Calls.Add(call, new CallInfo(){ Delegate = handler, Template = ft}); Calls.Add(call, new CallInfo() { Delegate = handler, Template = ft });
return this; return this;
} }

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets.HTTP
{
public enum HTTPComposeOption : int
{
AllCalculateLength,
AllDontCalculateLength,
SpecifiedHeadersOnly,
DataOnly
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets.HTTP
{
public struct HTTPCookie
{
public string Name;
public string Value;
public DateTime Expires;
public string Path;
public bool HttpOnly;
public string Domain;
public HTTPCookie(string name, string value)
{
Name = name;
Value = value;
Path = null;
Expires = DateTime.MinValue;
HttpOnly = false;
Domain = null;
}
public HTTPCookie(string name, string value, DateTime expires)
{
Name = name;
Value = value;
Expires = expires;
HttpOnly = false;
Domain = null;
Path = null;
}
public override string ToString()
{
//Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2001 21:00:00 GMT; domain=.com.au; path=/
//Set-Cookie: SessionID=another; expires=Fri, 29 Jun 2006 20:47:11 UTC; path=/
var cookie = Name + "=" + Value;
if (Expires.Ticks != 0)
cookie += "; expires=" + Expires.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
if (Domain != null)
cookie += "; domain=" + Domain;
if (Path != null)
cookie += "; path=" + Path;
if (HttpOnly)
cookie += "; HttpOnly";
return cookie;
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets.HTTP
{
public enum HTTPMethod : byte
{
GET,
POST,
HEAD,
PUT,
DELETE,
OPTIONS,
TRACE,
CONNECT,
UNKNOWN
}
}

View File

@ -32,22 +32,10 @@ using Esiur.Data;
using System.Net; using System.Net;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Esiur.Net.Packets; namespace Esiur.Net.Packets.HTTP;
public class HTTPRequestPacket : Packet public class HTTPRequestPacket : Packet
{ {
public enum HTTPMethod : byte
{
GET,
POST,
HEAD,
PUT,
DELETE,
OPTIONS,
TRACE,
CONNECT,
UNKNOWN
}
public StringKeyList Query; public StringKeyList Query;
public HTTPMethod Method; public HTTPMethod Method;
@ -59,12 +47,12 @@ public class HTTPRequestPacket : Packet
public StringKeyList Cookies; // String public StringKeyList Cookies; // String
public string URL; /// With query public string URL; /// With query
public string Filename; /// Without query public string Filename; /// Without query
//public byte[] PostContents;
public KeyList<string, object> PostForms; public KeyList<string, object> PostForms;
public byte[] Message; public byte[] Message;
private HTTPMethod getMethod(string method) private HTTPMethod GetMethod(string method)
{ {
switch (method.ToLower()) switch (method.ToLower())
{ {
@ -127,7 +115,7 @@ public class HTTPRequestPacket : Packet
Headers = new StringKeyList(); Headers = new StringKeyList();
sMethod = sLines[0].Split(' '); sMethod = sLines[0].Split(' ');
Method = getMethod(sMethod[0].Trim()); Method = GetMethod(sMethod[0].Trim());
if (sMethod.Length == 3) if (sMethod.Length == 3)
{ {
@ -163,7 +151,7 @@ public class HTTPRequestPacket : Packet
for (int i = 1; i < sLines.Length; i++) for (int i = 1; i < sLines.Length; i++)
{ {
if (sLines[i] == String.Empty) if (sLines[i] == string.Empty)
{ {
// Invalid header // Invalid header
return 0; return 0;
@ -191,14 +179,14 @@ public class HTTPRequestPacket : Packet
string[] splitCookie = cookie.Split('='); string[] splitCookie = cookie.Split('=');
splitCookie[0] = splitCookie[0].Trim(); splitCookie[0] = splitCookie[0].Trim();
splitCookie[1] = splitCookie[1].Trim(); splitCookie[1] = splitCookie[1].Trim();
if (!(Cookies.ContainsKey(splitCookie[0].Trim()))) if (!Cookies.ContainsKey(splitCookie[0].Trim()))
Cookies.Add(splitCookie[0], splitCookie[1]); Cookies.Add(splitCookie[0], splitCookie[1]);
} }
else else
{ {
if (!(Cookies.ContainsKey(cookie.Trim()))) if (!Cookies.ContainsKey(cookie.Trim()))
{ {
Cookies.Add(cookie.Trim(), String.Empty); Cookies.Add(cookie.Trim(), string.Empty);
} }
} }
} }
@ -222,7 +210,7 @@ public class HTTPRequestPacket : Packet
} }
else else
{ {
if (!(Query.ContainsKey(WebUtility.UrlDecode(S)))) if (!Query.ContainsKey(WebUtility.UrlDecode(S)))
{ {
Query.Add(WebUtility.UrlDecode(S), null); Query.Add(WebUtility.UrlDecode(S), null);
} }
@ -236,7 +224,7 @@ public class HTTPRequestPacket : Packet
try try
{ {
uint postSize = uint.Parse((string)Headers["content-length"]); uint postSize = uint.Parse(Headers["content-length"]);
// check limit // check limit
if (postSize > data.Length - headerSize) if (postSize > data.Length - headerSize)
@ -298,7 +286,7 @@ public class HTTPRequestPacket : Packet
else else
{ {
//PostForms.Add(Headers["content-type"], Encoding.Default.GetString( )); //PostForms.Add(Headers["content-type"], Encoding.Default.GetString( ));
Message = DC.Clip(data, headerSize, postSize); Message = data.Clip(headerSize, postSize);
} }
return headerSize + postSize; return headerSize + postSize;

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets.HTTP
{
public enum HTTPResponseCode : int
{
Switching = 101,
OK = 200,
Created = 201,
Accepted = 202,
NoContent = 204,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
TemporaryRedirect = 307,
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
PreconditionFailed = 412,
UnsupportedMediaType = 415,
InternalServerError = 500,
NotImplemented = 501,
}
}

View File

@ -28,98 +28,15 @@ using System.Text;
using Esiur.Misc; using Esiur.Misc;
using Esiur.Data; using Esiur.Data;
namespace Esiur.Net.Packets; namespace Esiur.Net.Packets.HTTP;
public class HTTPResponsePacket : Packet public class HTTPResponsePacket : Packet
{ {
public enum ComposeOptions : int
{
AllCalculateLength,
AllDontCalculateLength,
SpecifiedHeadersOnly,
DataOnly
}
public enum ResponseCode : int
{
Switching = 101,
OK = 200,
Created = 201,
Accepted = 202,
NoContent = 204,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
TemporaryRedirect = 307,
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
PreconditionFailed = 412,
UnsupportedMediaType = 415,
InternalServerError = 500,
NotImplemented = 501,
}
public struct HTTPCookie
{
public string Name;
public string Value;
public DateTime Expires;
public string Path;
public bool HttpOnly;
public string Domain;
public HTTPCookie(string name, string value)
{
this.Name = name;
this.Value = value;
this.Path = null;
this.Expires = DateTime.MinValue;
this.HttpOnly = false;
this.Domain = null;
}
public HTTPCookie(string name, string value, DateTime expires)
{
this.Name = name;
this.Value = value;
this.Expires = expires;
this.HttpOnly = false;
this.Domain = null;
this.Path = null;
}
public override string ToString()
{
//Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2001 21:00:00 GMT; domain=.com.au; path=/
//Set-Cookie: SessionID=another; expires=Fri, 29 Jun 2006 20:47:11 UTC; path=/
var cookie = Name + "=" + Value;
if (Expires.Ticks != 0)
cookie += "; expires=" + Expires.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
if (Domain != null)
cookie += "; domain=" + Domain;
if (Path != null)
cookie += "; path=" + Path;
if (HttpOnly)
cookie += "; HttpOnly";
return cookie;
}
}
public StringKeyList Headers { get; } = new StringKeyList(true); public StringKeyList Headers { get; } = new StringKeyList(true);
public string Version { get; set; } = "HTTP/1.1"; public string Version { get; set; } = "HTTP/1.1";
public byte[] Message; public byte[] Message;
public ResponseCode Number { get; set; } = ResponseCode.OK; public HTTPResponseCode Number { get; set; } = HTTPResponseCode.OK;
public string Text; public string Text;
public List<HTTPCookie> Cookies { get; } = new List<HTTPCookie>(); public List<HTTPCookie> Cookies { get; } = new List<HTTPCookie>();
@ -134,11 +51,11 @@ public class HTTPResponsePacket : Packet
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL"); + "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
} }
private string MakeHeader(ComposeOptions options) private string MakeHeader(HTTPComposeOption options)
{ {
string header = $"{Version} {(int)Number} {Text}\r\nServer: Esiur {Global.Version}\r\nDate: {DateTime.Now.ToUniversalTime().ToString("r")}\r\n"; string header = $"{Version} {(int)Number} {Text}\r\nServer: Esiur {Global.Version}\r\nDate: {DateTime.Now.ToUniversalTime().ToString("r")}\r\n";
if (options == ComposeOptions.AllCalculateLength) if (options == HTTPComposeOption.AllCalculateLength)
Headers["Content-Length"] = Message?.Length.ToString() ?? "0"; Headers["Content-Length"] = Message?.Length.ToString() ?? "0";
foreach (var kv in Headers) foreach (var kv in Headers)
@ -158,16 +75,16 @@ public class HTTPResponsePacket : Packet
} }
public bool Compose(ComposeOptions options) public bool Compose(HTTPComposeOption options)
{ {
List<byte> msg = new List<byte>(); List<byte> msg = new List<byte>();
if (options != ComposeOptions.DataOnly) if (options != HTTPComposeOption.DataOnly)
{ {
msg.AddRange(Encoding.UTF8.GetBytes(MakeHeader(options))); msg.AddRange(Encoding.UTF8.GetBytes(MakeHeader(options)));
} }
if (options != ComposeOptions.SpecifiedHeadersOnly) if (options != HTTPComposeOption.SpecifiedHeadersOnly)
{ {
if (Message != null) if (Message != null)
msg.AddRange(Message); msg.AddRange(Message);
@ -180,7 +97,7 @@ public class HTTPResponsePacket : Packet
public override bool Compose() public override bool Compose()
{ {
return Compose(ComposeOptions.AllDontCalculateLength); return Compose(HTTPComposeOption.AllDontCalculateLength);
} }
public override long Parse(byte[] data, uint offset, uint ends) public override long Parse(byte[] data, uint offset, uint ends)
@ -212,7 +129,7 @@ public class HTTPResponsePacket : Packet
if (sMethod.Length == 3) if (sMethod.Length == 3)
{ {
Version = sMethod[0].Trim(); Version = sMethod[0].Trim();
Number = (ResponseCode)(Convert.ToInt32(sMethod[1].Trim())); Number = (HTTPResponseCode)Convert.ToInt32(sMethod[1].Trim());
Text = sMethod[2]; Text = sMethod[2];
} }
@ -220,7 +137,7 @@ public class HTTPResponsePacket : Packet
for (int i = 1; i < sLines.Length; i++) for (int i = 1; i < sLines.Length; i++)
{ {
if (sLines[i] == String.Empty) if (sLines[i] == string.Empty)
{ {
// Invalid header // Invalid header
return 0; return 0;
@ -279,7 +196,7 @@ public class HTTPResponsePacket : Packet
try try
{ {
uint contentLength = uint.Parse((string)Headers["content-length"]); uint contentLength = uint.Parse(Headers["content-length"]);
// check limit // check limit
if (contentLength > data.Length - headerSize) if (contentLength > data.Length - headerSize)
@ -287,7 +204,7 @@ public class HTTPResponsePacket : Packet
return contentLength - (data.Length - headerSize); return contentLength - (data.Length - headerSize);
} }
Message = DC.Clip(data, offset, contentLength); Message = data.Clip(offset, contentLength);
return headerSize + contentLength; return headerSize + contentLength;

View File

@ -0,0 +1,25 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public static class IIPAuthExtensions
{
public static IIPAuthPacketIAuthFormat GetIAuthFormat(this object value)
{
if (value is string)
return IIPAuthPacketIAuthFormat.Text;
else if (value is int || value is uint
|| value is byte || value is sbyte
|| value is short || value is ushort
|| value is long || value is ulong)
return IIPAuthPacketIAuthFormat.Number;
else if (value.GetType().IsArray)
return IIPAuthPacketIAuthFormat.Choice;
throw new Exception("Unknown IAuth format");
}
}
}

View File

@ -26,55 +26,47 @@ using Esiur.Data;
using Esiur.Security.Authority; using Esiur.Security.Authority;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Common;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers;
namespace Esiur.Net.Packets; namespace Esiur.Net.Packets;
class IIPAuthPacket : Packet
public class IIPAuthPacket : Packet
{ {
public enum IIPAuthPacketCommand : byte
{
Action = 0,
Declare = 0x1,
Acknowledge = 0x2,
Report = 0x3,
DeclareEncrypted = 0x5,
AcknowledgeEncrypted = 0x6
}
public enum IIPAuthPacketAction : byte
{
AuthenticateHash = 0x0,
AuthenticatePublicHash = 0x1,
AuthenticatePrivateHash,
EstablishRequest,
EstablishReply,
TwoFactorAuthtenticate,
NewConnection = 0x20,
ResumeConnection,
ConnectionEstablished = 0x28
}
public IIPAuthPacketCommand Command public IIPAuthPacketCommand Command
{ {
get; get;
set; set;
} }
public IIPAuthPacketInitialize Initialization
{
get;
set;
}
public IIPAuthPacketAcknowledge Acknowledgement
{
get;
set;
}
public IIPAuthPacketAction Action public IIPAuthPacketAction Action
{ {
get; get;
set; set;
} }
public byte ErrorCode { get; set; } public IIPAuthPacketEvent Event
public string ErrorMessage { get; set; } {
get;
set;
}
public AuthenticationMethod LocalMethod public AuthenticationMethod LocalMethod
{ {
@ -82,71 +74,45 @@ class IIPAuthPacket : Packet
set; set;
} }
public byte[] SourceInfo
{
get;
set;
}
public byte[] Hash
{
get;
set;
}
public byte[] SessionId
{
get;
set;
}
public AuthenticationMethod RemoteMethod public AuthenticationMethod RemoteMethod
{ {
get; get;
set; set;
} }
public string Domain public byte ErrorCode
{ {
get; get;
set; set;
} }
public long CertificateId public string Message
{
get; set;
}
public string LocalUsername
{ {
get; get;
set; set;
} }
public string RemoteUsername
public IIPAuthPacketPublicKeyAlgorithm PublicKeyAlgorithm
{ {
get; get;
set; set;
} }
public byte[] LocalPassword public IIPAuthPacketHashAlgorithm HashAlgorithm
{
get;
set;
}
public byte[] RemotePassword
{ {
get; get;
set; set;
} }
public byte[] LocalToken
public byte[] Certificate
{ {
get; get;
set; set;
} }
public byte[] RemoteToken public byte[] Challenge
{ {
get; get;
set; set;
@ -158,19 +124,27 @@ class IIPAuthPacket : Packet
set; set;
} }
public byte[] LocalNonce
public byte[] SessionId
{ {
get; get;
set; set;
} }
public byte[] RemoteNonce public TransmissionType? DataType
{ {
get; get;
set; set;
} }
public ulong RemoteTokenIndex { get; set; } // IAuth Reference
public uint Reference
{
get;
set;
}
private uint dataLengthNeeded; private uint dataLengthNeeded;
@ -199,174 +173,178 @@ class IIPAuthPacket : Packet
Command = (IIPAuthPacketCommand)(data[offset] >> 6); Command = (IIPAuthPacketCommand)(data[offset] >> 6);
if (Command == IIPAuthPacketCommand.Action) if (Command == IIPAuthPacketCommand.Initialize)
{ {
Action = (IIPAuthPacketAction)(data[offset++] & 0x3f); LocalMethod = (AuthenticationMethod)(data[offset] >> 4 & 0x3);
RemoteMethod = (AuthenticationMethod)(data[offset] >> 2 & 0x3);
if (Action == IIPAuthPacketAction.AuthenticateHash)
{
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
Hash = data.Clip(offset, 32);
//var hash = new byte[32];
//Buffer.BlockCopy(data, (int)offset, hash, 0, 32);
//Hash = hash;
offset += 32;
}
else if (Action == IIPAuthPacketAction.NewConnection)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var length = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, length))
return -dataLengthNeeded;
SourceInfo = data.Clip(offset, length);
//var sourceInfo = new byte[length];
//Buffer.BlockCopy(data, (int)offset, sourceInfo, 0, length);
//SourceInfo = sourceInfo;
offset += 32;
}
else if (Action == IIPAuthPacketAction.ResumeConnection
|| Action == IIPAuthPacketAction.ConnectionEstablished)
{
//var sessionId = new byte[32];
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
SessionId = data.Clip(offset, 32);
//Buffer.BlockCopy(data, (int)offset, sessionId, 0, 32);
//SessionId = sessionId;
offset += 32;
}
}
else if (Command == IIPAuthPacketCommand.Declare)
{
RemoteMethod = (AuthenticationMethod)((data[offset] >> 4) & 0x3);
LocalMethod = (AuthenticationMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
Initialization = (IIPAuthPacketInitialize)(data[offset++] & 0xFC); // remove last two reserved LSBs
if (NotEnough(offset, ends, 1)) if (NotEnough(offset, ends, 1))
return -dataLengthNeeded; return -dataLengthNeeded;
var domainLength = data[offset++]; (var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (NotEnough(offset, ends, domainLength))
return -dataLengthNeeded;
var domain = data.GetString(offset, domainLength); if (DataType == null)
return -(int)size;
Domain = domain;
offset += domainLength;
if (RemoteMethod == AuthenticationMethod.Certificate)
{
}
else if (RemoteMethod == AuthenticationMethod.Credentials)
{
if (LocalMethod == AuthenticationMethod.None)
{
if (NotEnough(offset, ends, 33))
return -dataLengthNeeded;
//var remoteNonce = new byte[32];
//Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
//RemoteNonce = remoteNonce;
RemoteNonce = data.Clip(offset, 32);
offset += 32;
var length = data[offset++];
if (NotEnough(offset, ends, length))
return -dataLengthNeeded;
RemoteUsername = data.GetString(offset, length);
offset += length; offset += (uint)size;
}
}
else if (RemoteMethod == AuthenticationMethod.Token)
{
if (LocalMethod == AuthenticationMethod.None)
{
if (NotEnough(offset, ends, 37))
return -dataLengthNeeded;
RemoteNonce = data.Clip(offset, 32);
offset += 32;
RemoteTokenIndex = data.GetUInt64(offset, Endian.Little);
offset += 8;
}
}
if (encrypt)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var keyLength = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded;
//var key = new byte[keyLength];
//Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
//AsymetricEncryptionKey = key;
AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength;
}
} }
else if (Command == IIPAuthPacketCommand.Acknowledge) else if (Command == IIPAuthPacketCommand.Acknowledge)
{ {
RemoteMethod = (AuthenticationMethod)((data[offset] >> 4) & 0x3);
LocalMethod = (AuthenticationMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
if (RemoteMethod == AuthenticationMethod.None) LocalMethod = (AuthenticationMethod)(data[offset] >> 4 & 0x3);
RemoteMethod = (AuthenticationMethod)(data[offset] >> 2 & 0x3);
Acknowledgement = (IIPAuthPacketAcknowledge)(data[offset++] & 0xFC); // remove last two reserved LSBs
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
}
else if (Command == IIPAuthPacketCommand.Action)
{
Action = (IIPAuthPacketAction)data[offset++]; // (IIPAuthPacketAction)(data[offset++] & 0x3f);
if (Action == IIPAuthPacketAction.AuthenticateHash
|| Action == IIPAuthPacketAction.AuthenticatePublicHash
|| Action == IIPAuthPacketAction.AuthenticatePrivateHash
|| Action == IIPAuthPacketAction.AuthenticatePublicPrivateHash)
{ {
if (LocalMethod == AuthenticationMethod.None) if (NotEnough(offset, ends, 3))
{ return -dataLengthNeeded;
// do nothing
} HashAlgorithm = (IIPAuthPacketHashAlgorithm)data[offset++];
var hashLength = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, hashLength))
return -dataLengthNeeded;
Challenge = data.Clip(offset, hashLength);
offset += hashLength;
} }
else if (RemoteMethod == AuthenticationMethod.Credentials else if (Action == IIPAuthPacketAction.AuthenticatePrivateHashCert
|| RemoteMethod == AuthenticationMethod.Token) || Action == IIPAuthPacketAction.AuthenticatePublicPrivateHashCert)
{ {
if (LocalMethod == AuthenticationMethod.None) if (NotEnough(offset, ends, 3))
{ return -dataLengthNeeded;
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
RemoteNonce = data.Clip(offset, 32); HashAlgorithm = (IIPAuthPacketHashAlgorithm)data[offset++];
offset += 32;
} var hashLength = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, hashLength))
return -dataLengthNeeded;
Challenge = data.Clip(offset, hashLength);
offset += hashLength;
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var certLength = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, certLength))
return -dataLengthNeeded;
Certificate = data.Clip(offset, certLength);
offset += certLength;
}
else if (Action == IIPAuthPacketAction.IAuthPlain)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
Reference = data.GetUInt32(offset, Endian.Little);
offset += 4;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
}
else if (Action == IIPAuthPacketAction.IAuthHashed)
{
if (NotEnough(offset, ends, 7))
return -dataLengthNeeded;
Reference = data.GetUInt32(offset, Endian.Little);
offset += 4;
HashAlgorithm = (IIPAuthPacketHashAlgorithm)data[offset++];
var cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Challenge = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPAuthPacketAction.IAuthEncrypted)
{
if (NotEnough(offset, ends, 7))
return -dataLengthNeeded;
Reference = data.GetUInt32(offset, Endian.Little);
offset += 4;
PublicKeyAlgorithm = (IIPAuthPacketPublicKeyAlgorithm)data[offset++];
var cl = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Challenge = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPAuthPacketAction.EstablishNewSession)
{
// Nothing here
}
else if (Action == IIPAuthPacketAction.EstablishResumeSession)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var sessionLength = data[offset++];
if (NotEnough(offset, ends, sessionLength))
return -dataLengthNeeded;
SessionId = data.Clip(offset, sessionLength);
offset += sessionLength;
} }
if (encrypt) else if (Action == IIPAuthPacketAction.EncryptKeyExchange)
{ {
if (NotEnough(offset, ends, 2)) if (NotEnough(offset, ends, 2))
return -dataLengthNeeded; return -dataLengthNeeded;
@ -378,33 +356,86 @@ class IIPAuthPacket : Packet
if (NotEnough(offset, ends, keyLength)) if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded; return -dataLengthNeeded;
//var key = new byte[keyLength];
//Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
//AsymetricEncryptionKey = key;
AsymetricEncryptionKey = data.Clip(offset, keyLength); AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength; offset += keyLength;
} }
else if (Action == IIPAuthPacketAction.RegisterEndToEndKey
|| Action == IIPAuthPacketAction.RegisterHomomorphic)
{
if (NotEnough(offset, ends, 3))
return -dataLengthNeeded;
PublicKeyAlgorithm = (IIPAuthPacketPublicKeyAlgorithm)data[offset++];
var keyLength = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded;
AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength;
}
} }
else if (Command == IIPAuthPacketCommand.Error) else if (Command == IIPAuthPacketCommand.Event)
{ {
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
offset++; Event = (IIPAuthPacketEvent)data[offset++];
ErrorCode = data[offset++];
if (Event == IIPAuthPacketEvent.ErrorTerminate
|| Event == IIPAuthPacketEvent.ErrorMustEncrypt
|| Event == IIPAuthPacketEvent.ErrorRetry)
{
if (NotEnough(offset, ends, 3))
return -dataLengthNeeded;
ErrorCode = data[offset++];
var msgLength = data.GetUInt16(offset, Endian.Little);
offset += 2;
if (NotEnough(offset, ends, msgLength))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset, Endian.Little); Message = data.GetString(offset, msgLength);
offset += 2;
if (NotEnough(offset, ends, cl)) offset += msgLength;
return -dataLengthNeeded; }
else if (Event == IIPAuthPacketEvent.IndicationEstablished)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl); var sessionLength = data[offset++];
offset += cl;
if (NotEnough(offset, ends, sessionLength))
return -dataLengthNeeded;
SessionId = data.Clip(offset, sessionLength);
offset += sessionLength;
}
else if (Event == IIPAuthPacketEvent.IAuthPlain
|| Event == IIPAuthPacketEvent.IAuthHashed
|| Event == IIPAuthPacketEvent.IAuthEncrypted)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
(var size, DataType) = TransmissionType.Parse(data, offset, ends);
if (DataType == null)
return -(int)size;
offset += (uint)size;
}
} }

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketAcknowledge : byte
{
NoAuthNoAuth = 0x40, // 0b01000000,
NoAuthCredentials = 0x44, // 0b01000100,
NoAuthToken = 0x48, //0b01001000,
NoAuthCertificate = 0x4c, //0b01001100,
CredentialsNoAuth = 0x50, //0b01010000,
CredentialsCredentials = 0x54, //0b01010100,
CredentialsToken = 0x58, //0b01011000,
CredentialsCertificate = 0x5c, //0b01011100,
TokenNoAuth = 0x60, //0b01100000,
TokenCredentials = 0x64, //0b01100100,
TokenToken = 0x68, //0b01101000,
TokenCertificate = 0x6c, //0b01101100,
CertificateNoAuth = 0x70, //0b01110000,
CertificateCredentials = 0x74, //0b01110100,
CertificateToken = 0x78, //0b01111000,
CertificateCertificate = 0x7c, // 0b01111100,
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketAction : byte
{
AuthenticateHash = 0x80,
AuthenticatePublicHash = 0x81,
AuthenticatePrivateHash = 0x82,
AuthenticatePublicPrivateHash = 0x83,
AuthenticatePrivateHashCert = 0x88,
AuthenticatePublicPrivateHashCert = 0x89,
IAuthPlain = 0x90,
IAuthHashed = 0x91,
IAuthEncrypted = 0x92,
EstablishNewSession = 0x98,
EstablishResumeSession = 0x99,
EncryptKeyExchange = 0xA0,
RegisterEndToEndKey = 0xA8,
RegisterHomomorphic = 0xA9,
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketCommand : byte
{
Initialize = 0x0,
Acknowledge = 0x1,
Action = 0x2,
Event = 0x3,
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketEvent : byte
{
ErrorTerminate = 0xC0,
ErrorMustEncrypt = 0xC1,
ErrorRetry = 0xC2,
IndicationEstablished = 0xC8,
IAuthPlain = 0xD0,
IAuthHashed = 0xD1,
IAuthEncrypted = 0xD2
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketHashAlgorithm
{
SHA256,
SHA3,
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketHeader
{
Version = 0,
Domain = 1,
SupportedAuthentications = 2,
SupportedHashAlgorithms = 3,
SupportedCiphers = 4,
SupportedCompression = 5,
SupportedPersonalAuth = 6,
Nonce = 7,
Username = 8,
TokenIndex = 9,
CertificateId = 10,
CachedCertificates = 11,
CipherType = 12,
CipherKey = 13,
SoftwareIdentity = 14,
Referrer = 15,
Time = 16,
Certificate = 17,
IPv4 = 18
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketIAuthDestination
{
Self = 0,
Device = 1, // logged in device
Email = 2,
SMS = 3,
App = 4, // Authenticator app
ThirdParty = 5, // usualy a second person
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketIAuthFormat
{
None = 0,
Number = 1,
Text = 2,
LowercaseText = 3,
Choice = 4,
Photo = 5,
Signature = 6,
Fingerprint = 7,
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketIAuthHeader : byte
{
Reference = 0,
Destination = 1,
Clue = 2,
RequiredFormat = 3,
ContentFormat = 4,
Content = 5,
Timeout = 6,
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketInitialize
{
NoAuthNoAuth = 0x0, //0b00000000,
NoAuthCredentials = 0x4, //0b00000100,
NoAuthToken = 0x8, //0b00001000,
NoAuthCertificate = 0xC, //0b00001100,
CredentialsNoAuth = 0x10, //0b00010000,
CredentialsCredentials = 0x14, //0b00010100,
CredentialsToken = 0x18, //0b00011000,
CredentialsCertificate = 0x1c, //0b00011100,
TokenNoAuth = 0x20, //0b00100000,
TokenCredentials = 0x24, //0b00100100,
TokenToken = 0x28, //0b00101000,
TokenCertificate = 0x2c, //0b00101100,
CertificateNoAuth = 0x30, //0b00110000,
CertificateCredentials = 0x34,// 0b00110100,
CertificateToken = 0x38, //0b00111000,
CertificateCertificate = 0x3c, //0b00111100,
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPAuthPacketPublicKeyAlgorithm
{
RSA = 0,
CKKS = 1,
}
}

View File

@ -25,7 +25,6 @@ SOFTWARE.
using Esiur.Data; using Esiur.Data;
using Esiur.Core; using Esiur.Core;
using Esiur.Misc; using Esiur.Misc;
using Esiur.Net.Packets;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -62,81 +61,6 @@ class IIPPacket : Packet
return rt; return rt;
} }
public enum IIPPacketCommand : byte
{
Event = 0,
Request,
Reply,
Report,
}
public enum IIPPacketEvent : byte
{
// Event Manage
ResourceReassigned = 0,
ResourceDestroyed,
ChildAdded,
ChildRemoved,
Renamed,
// Event Invoke
PropertyUpdated = 0x10,
EventOccurred,
// Attribute
AttributesUpdated = 0x18
}
public enum IIPPacketAction : byte
{
// Request Manage
AttachResource = 0,
ReattachResource,
DetachResource,
CreateResource,
DeleteResource,
AddChild,
RemoveChild,
RenameResource,
// Request Inquire
TemplateFromClassName = 0x8,
TemplateFromClassId,
TemplateFromResourceId,
QueryLink,
ResourceHistory,
ResourceChildren,
ResourceParents,
LinkTemplates,
// Request Invoke
InvokeFunction = 0x10,
Reserved,
Listen,
Unlisten,
SetProperty,
// Request Attribute
GetAllAttributes = 0x18,
UpdateAllAttributes,
ClearAllAttributes,
GetAttributes,
UpdateAttributes,
ClearAttributes,
// Static calling
KeepAlive = 0x20,
ProcedureCall,
StaticCall
}
public enum IIPPacketReport : byte
{
ManagementError,
ExecutionError,
ProgressReport = 0x8,
ChunkStream = 0x9
}
public IIPPacketReport Report public IIPPacketReport Report
@ -648,7 +572,7 @@ class IIPPacket : Packet
if (NotEnough(offset, ends, cl)) if (NotEnough(offset, ends, cl))
return -dataLengthNeeded; return -dataLengthNeeded;
Procedure = data.GetString(offset, cl); Procedure = data.GetString(offset, cl);
offset += cl; offset += cl;
@ -662,7 +586,8 @@ class IIPPacket : Packet
offset += (uint)size; offset += (uint)size;
} else if (Action == IIPPacketAction.StaticCall) }
else if (Action == IIPPacketAction.StaticCall)
{ {
if (NotEnough(offset, ends, 18)) if (NotEnough(offset, ends, 18))
return -dataLengthNeeded; return -dataLengthNeeded;

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPPacketAction : byte
{
// Request Manage
AttachResource = 0,
ReattachResource,
DetachResource,
CreateResource,
DeleteResource,
AddChild,
RemoveChild,
RenameResource,
// Request Inquire
TemplateFromClassName = 0x8,
TemplateFromClassId,
TemplateFromResourceId,
QueryLink,
ResourceHistory,
ResourceChildren,
ResourceParents,
LinkTemplates,
// Request Invoke
InvokeFunction = 0x10,
Reserved,
Listen,
Unlisten,
SetProperty,
// Request Attribute
GetAllAttributes = 0x18,
UpdateAllAttributes,
ClearAllAttributes,
GetAttributes,
UpdateAttributes,
ClearAttributes,
// Static calling
KeepAlive = 0x20,
ProcedureCall,
StaticCall
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPPacketCommand : byte
{
Event = 0,
Request,
Reply,
Report,
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPPacketEvent : byte
{
// Event Manage
ResourceReassigned = 0,
ResourceDestroyed,
ChildAdded,
ChildRemoved,
Renamed,
// Event Invoke
PropertyUpdated = 0x10,
EventOccurred,
// Attribute
AttributesUpdated = 0x18
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
public enum IIPPacketReport : byte
{
ManagementError,
ExecutionError,
ProgressReport = 0x8,
ChunkStream = 0x9
}
}

View File

@ -29,7 +29,7 @@ using System.Text;
using Esiur.Misc; using Esiur.Misc;
using Esiur.Data; using Esiur.Data;
namespace Esiur.Net.Packets; namespace Esiur.Net.Packets.WebSocket;
public class WebsocketPacket : Packet public class WebsocketPacket : Packet
{ {
public enum WSOpcode : byte public enum WSOpcode : byte
@ -84,17 +84,17 @@ public class WebsocketPacket : Packet
(byte)Opcode)); (byte)Opcode));
// calculate length // calculate length
if (Message.Length > UInt16.MaxValue) if (Message.Length > ushort.MaxValue)
// 4 bytes // 4 bytes
{ {
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 127)); pkt.Add((byte)((Mask ? 0x80 : 0x0) | 127));
pkt.AddRange(DC.ToBytes((UInt64)Message.LongCount(), Endian.Big)); pkt.AddRange(((ulong)Message.LongCount()).ToBytes(Endian.Big));
} }
else if (Message.Length > 125) else if (Message.Length > 125)
// 2 bytes // 2 bytes
{ {
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 126)); pkt.Add((byte)((Mask ? 0x80 : 0x0) | 126));
pkt.AddRange(DC.ToBytes((UInt16)Message.Length, Endian.Big)); pkt.AddRange(((ushort)Message.Length).ToBytes(Endian.Big));
} }
else else
{ {
@ -118,7 +118,7 @@ public class WebsocketPacket : Packet
try try
{ {
long needed = 2; long needed = 2;
var length = (ends - offset); var length = ends - offset;
if (length < needed) if (length < needed)
{ {
//Console.WriteLine("stage 1 " + needed); //Console.WriteLine("stage 1 " + needed);
@ -126,13 +126,13 @@ public class WebsocketPacket : Packet
} }
uint oOffset = offset; uint oOffset = offset;
FIN = ((data[offset] & 0x80) == 0x80); FIN = (data[offset] & 0x80) == 0x80;
RSV1 = ((data[offset] & 0x40) == 0x40); RSV1 = (data[offset] & 0x40) == 0x40;
RSV2 = ((data[offset] & 0x20) == 0x20); RSV2 = (data[offset] & 0x20) == 0x20;
RSV3 = ((data[offset] & 0x10) == 0x10); RSV3 = (data[offset] & 0x10) == 0x10;
Opcode = (WSOpcode)(data[offset++] & 0xF); Opcode = (WSOpcode)(data[offset++] & 0xF);
Mask = ((data[offset] & 0x80) == 0x80); Mask = (data[offset] & 0x80) == 0x80;
PayloadLength = (long)(data[offset++] & 0x7F); PayloadLength = data[offset++] & 0x7F;
if (Mask) if (Mask)
needed += 4; needed += 4;
@ -192,23 +192,23 @@ public class WebsocketPacket : Packet
MaskKey[2] = data[offset++]; MaskKey[2] = data[offset++];
MaskKey[3] = data[offset++]; MaskKey[3] = data[offset++];
Message = DC.Clip(data, offset, (uint)PayloadLength); Message = data.Clip(offset, (uint)PayloadLength);
//var aMask = BitConverter.GetBytes(MaskKey); //var aMask = BitConverter.GetBytes(MaskKey);
for (int i = 0; i < Message.Length; i++) for (int i = 0; i < Message.Length; i++)
Message[i] = (byte)(Message[i] ^ MaskKey[i % 4]); Message[i] = (byte)(Message[i] ^ MaskKey[i % 4]);
} }
else else
Message = DC.Clip(data, offset, (uint)PayloadLength); Message = data.Clip(offset, (uint)PayloadLength);
return (offset - oOffset) + (int)PayloadLength; return offset - oOffset + (int)PayloadLength;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.ToString()); Console.WriteLine(ex.ToString());
Console.WriteLine(offset + "::" + DC.ToHex(data)); Console.WriteLine(offset + "::" + data.ToHex());
throw ex; throw ex;
} }
} }

View File

@ -28,13 +28,13 @@ using System.Linq;
using System.Text; using System.Text;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net; using System.Net;
using Esiur.Net.Packets;
using Esiur.Misc; using Esiur.Misc;
using System.IO; using System.IO;
using Esiur.Core; using Esiur.Core;
using Esiur.Resource; using Esiur.Resource;
using Esiur.Data; using Esiur.Data;
using System.Globalization; using System.Globalization;
using Esiur.Net.Packets.WebSocket;
namespace Esiur.Net.Sockets; namespace Esiur.Net.Sockets;
public class WSocket : ISocket, INetworkReceiver<ISocket> public class WSocket : ISocket, INetworkReceiver<ISocket>

View File

@ -7,7 +7,7 @@ namespace Esiur.Security.Authority;
public enum AuthenticationMethod : byte public enum AuthenticationMethod : byte
{ {
None, None,
Certificate,
Credentials, Credentials,
Token Token,
Certificate
} }

View File

@ -31,34 +31,34 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Esiur.Security.Cryptography; using Esiur.Security.Cryptography;
using static System.Collections.Specialized.BitVector32;
using Esiur.Net.Packets;
namespace Esiur.Security.Authority; namespace Esiur.Security.Authority;
public class Session public class Session
{ {
public Authentication LocalAuthentication => localAuth;
public Authentication RemoteAuthentication => remoteAuth;
// public Source Source { get; }
public byte[] Id { get; set; } public byte[] Id { get; set; }
public DateTime Creation { get; } public DateTime Creation { get; }
public DateTime Modification { get; } public DateTime Modification { get; }
public KeyList<string, object> Variables { get; } = new KeyList<string, object>(); public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
//KeyList<string, object> Variables { get; }
//IStore Store { get; }
//string id;
Authentication localAuth, remoteAuth;
//string domain;
public IKeyExchanger KeyExchanger { get; set; } = null; public IKeyExchanger KeyExchanger { get; set; } = null;
public ISymetricCipher SymetricCipher { get; set; } = null; public ISymetricCipher SymetricCipher { get; set; } = null;
public Session(Authentication localAuthentication, Authentication remoteAuthentication) public Map<IIPAuthPacketHeader, object> LocalHeaders { get; set; } = new Map<IIPAuthPacketHeader, object>();
{ public Map<IIPAuthPacketHeader, object> RemoteHeaders { get; set; } = new Map<IIPAuthPacketHeader, object>();
this.localAuth = localAuthentication;
this.remoteAuth = remoteAuthentication; public AuthenticationMethod LocalMethod { get; set; }
} public AuthenticationMethod RemoteMethod { get; set; }
public AuthenticationType AuthenticationType { get; set; }
public string AuthorizedAccount { get; set; }
} }

View File

@ -5,9 +5,9 @@ using System.Text;
namespace Esiur.Security.Membership namespace Esiur.Security.Membership
{ {
public class AuthorizationResponse public class AuthorizationIndication
{ {
public Session Session { get; set; } public Session Session { get; set; }
public bool Succeeded { get; set; } public AuthorizationResults Results { get; set; }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using Esiur.Net.Packets;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -6,11 +7,16 @@ namespace Esiur.Security.Membership
{ {
public class AuthorizationResults public class AuthorizationResults
{ {
AuthorizationResultsResponse Response { get; set; } public AuthorizationResultsResponse Response { get; set; }
TwoFactorAuthorizationMethod TwoFactorMethod { get; set; } public IIPAuthPacketIAuthDestination Destination { get; set; }
public IIPAuthPacketIAuthFormat RequiredFormat { get; set; }
public string Clue { get; set; } public string Clue { get; set; }
public string AppName { get; set; }
public string Code { get; set; } public ushort Timeout { get; set; } // 0 means no timeout
public int Timeout { get; set; } public uint Reference { get; set; }
public DateTime Issue { get; set; } = DateTime.UtcNow;
public bool Expired => Timeout == 0 ? false : (DateTime.UtcNow - Issue).TotalSeconds > Timeout;
} }
} }

View File

@ -7,7 +7,11 @@ namespace Esiur.Security.Membership
public enum AuthorizationResultsResponse public enum AuthorizationResultsResponse
{ {
Success, Success,
Failed,
Expired,
ServiceUnavailable, ServiceUnavailable,
TwoFactoryAuthorization, IAuthPlain,
IAuthHashed,
IAuthEncrypted
} }
} }

View File

@ -32,21 +32,28 @@ using Esiur.Net.IIP;
using Esiur.Core; using Esiur.Core;
using Esiur.Security.Authority; using Esiur.Security.Authority;
using Esiur.Resource; using Esiur.Resource;
using Esiur.Net.Packets;
namespace Esiur.Security.Membership; namespace Esiur.Security.Membership;
public interface IMembership public interface IMembership
{ {
public event ResourceEventHandler<AuthorizationResponse> Authorization; public event ResourceEventHandler<AuthorizationIndication> Authorization;
AsyncReply<string> UserExists(string username, string domain);
AsyncReply<string> TokenExists(ulong tokenIndex, string domain);
AsyncReply<bool> UserExists(string username, string domain);
AsyncReply<byte[]> GetPassword(string username, string domain); AsyncReply<byte[]> GetPassword(string username, string domain);
AsyncReply<byte[]> GetToken(ulong tokenIndex, string domain); AsyncReply<byte[]> GetToken(ulong tokenIndex, string domain);
AsyncReply<AuthorizationResults> Authorize(Session session); AsyncReply<AuthorizationResults> Authorize(Session session);
AsyncReply<AuthorizationResults> AuthorizePlain(Session session, uint reference, object value);
AsyncReply<AuthorizationResults> AuthorizeHashed(Session session, uint reference, IIPAuthPacketHashAlgorithm algorithm, byte[] value);
AsyncReply<AuthorizationResults> AuthorizeEncrypted(Session session, uint reference, IIPAuthPacketPublicKeyAlgorithm algorithm, byte[] value);
AsyncReply<bool> Login(Session session); AsyncReply<bool> Login(Session session);
AsyncReply<bool> Logout(Session session); AsyncReply<bool> Logout(Session session);
bool GuestsAllowed { get; } bool GuestsAllowed { get; }
AsyncReply<string> TokenExists(ulong tokenIndex, string domain);
} }

View File

@ -0,0 +1,184 @@
using Esiur.Core;
using Esiur.Data;
using Esiur.Net.Packets;
using Esiur.Resource;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Esiur.Security.Membership
{
public class SimpleMembership : IMembership
{
public bool GuestsAllowed { get; set; } = false;
public event ResourceEventHandler<AuthorizationIndication> Authorization;
KeyList<string, UserInfo> users = new KeyList<string, UserInfo>();
KeyList<ulong, TokenInfo> tokens = new KeyList<ulong, TokenInfo>();
public class QuestionAnswer
{
public string Question { get; set; }
public object Answer { get; set; }
public bool Hashed { get; set; }
}
public class UserInfo
{
public string Username { get; set; }
public string Password { get; set; }
public QuestionAnswer[] Questions { get; set; }
public List<AuthorizationResults> Results { get; set; } = new List<AuthorizationResults>();
}
public class TokenInfo
{
public ulong Index { get; set; }
public string Token { get; set; }
public string Username { get; set; }
}
public void AddToken(ulong index, string value, string username)
{
if (users.ContainsKey(username))
throw new Exception("User not found.");
tokens.Add(index, new TokenInfo() { Index = index, Token = value, Username = username });
}
public void AddUser(string username, string password, QuestionAnswer[] questions)
{
users.Add(username, new UserInfo() { Password = password, Username = username, Questions = questions });
}
public void RemoveToken(ulong index) => tokens.Remove(index);
public void RemoveUser(string username) => users.Remove(username);
public AsyncReply<AuthorizationResults> Authorize(Session session)
{
if (session.AuthorizedAccount.StartsWith("g-"))
return new AsyncReply<AuthorizationResults>(new AuthorizationResults() { Response = AuthorizationResultsResponse.Success });
if (users[session.AuthorizedAccount].Questions.Length > 0)
{
var q = users[session.AuthorizedAccount].Questions.First();
var r = new Random();
var format = q.Answer.GetIAuthFormat();
var ar = new AuthorizationResults()
{
Clue = q.Question,
Destination = IIPAuthPacketIAuthDestination.Self,
Reference = (uint)r.Next(),
RequiredFormat = format,
Timeout = 30,
Response = q.Hashed ? AuthorizationResultsResponse.IAuthHashed : AuthorizationResultsResponse.IAuthPlain
};
users[session.AuthorizedAccount].Results.Add(ar);
return new AsyncReply<AuthorizationResults>(ar);
}
else
{
return new AsyncReply<AuthorizationResults>(new AuthorizationResults() { Response = AuthorizationResultsResponse.Success });
}
}
public AsyncReply<AuthorizationResults> AuthorizeEncrypted(Session session, uint reference, IIPAuthPacketPublicKeyAlgorithm algorithm, byte[] value)
{
throw new NotImplementedException();
}
public AsyncReply<AuthorizationResults> AuthorizeHashed(Session session, uint reference, IIPAuthPacketHashAlgorithm algorithm, byte[] value)
{
if (algorithm != IIPAuthPacketHashAlgorithm.SHA256)
throw new NotImplementedException();
var ar = users[session.AuthorizedAccount].Results.First(x => x.Reference == reference);
var qa = users[session.AuthorizedAccount].Questions.First(x => x.Question == ar.Clue);
// compute hash
var remoteNonce = (byte[])session.RemoteHeaders[IIPAuthPacketHeader.Nonce];
var localNonce = (byte[])session.LocalHeaders[IIPAuthPacketHeader.Nonce];
var hashFunc = SHA256.Create();
// local nonce + password or token + remote nonce
var challenge = hashFunc.ComputeHash(new BinaryList()
.AddUInt8Array(remoteNonce)
.AddUInt8Array(Codec.Compose(qa.Answer, null))
.AddUInt8Array(localNonce)
.ToArray());
if (challenge.SequenceEqual(value))
return new AsyncReply<AuthorizationResults>(new AuthorizationResults() { Response = AuthorizationResultsResponse.Success });
else
return new AsyncReply<AuthorizationResults>(new AuthorizationResults() { Response = AuthorizationResultsResponse.Failed });
}
public AsyncReply<AuthorizationResults> AuthorizePlain(Session session, uint reference, object value)
{
var ar = users[session.AuthorizedAccount].Results.First(x => x.Reference == reference);
var qa = users[session.AuthorizedAccount].Questions.First(x => x.Question == ar.Clue);
if (qa.Answer.ToString() == value.ToString())
return new AsyncReply<AuthorizationResults>(new AuthorizationResults() { Response = AuthorizationResultsResponse.Success });
else
return new AsyncReply<AuthorizationResults>(new AuthorizationResults() { Response = AuthorizationResultsResponse.Failed });
}
public AsyncReply<byte[]> GetPassword(string username, string domain)
{
return new AsyncReply<byte[]>(DC.ToBytes(users[username].Password));
}
public AsyncReply<byte[]> GetToken(ulong tokenIndex, string domain)
{
return new AsyncReply<byte[]>(DC.ToBytes(tokens[tokenIndex].Token));
}
public AsyncReply<bool> Login(Session session)
{
return new AsyncReply<bool>(true);
}
public AsyncReply<bool> Logout(Session session)
{
return new AsyncReply<bool>(true);
}
public AsyncReply<string> TokenExists(ulong tokenIndex, string domain)
{
if (!tokens.ContainsKey(tokenIndex))
return new AsyncReply<string>(null);
else
return new AsyncReply<string>(tokens[tokenIndex].Username);
}
public AsyncReply<string> UserExists(string username, string domain)
{
if (!users.ContainsKey(username))
return new AsyncReply<string>(null);
else
return new AsyncReply<string>(username);
}
}
}

View File

@ -44,8 +44,8 @@ public class UserPermissionsManager : IPermissionsManager
{ {
Map<string,object> userPermissions = null; Map<string,object> userPermissions = null;
if (settings.ContainsKey(session.RemoteAuthentication.FullName)) if (settings.ContainsKey(session.AuthorizedAccount))
userPermissions = settings[session.RemoteAuthentication.FullName] as Map<string, object>; userPermissions = settings[session.AuthorizedAccount] as Map<string, object>;
else if (settings.ContainsKey("public")) else if (settings.ContainsKey("public"))
userPermissions = settings["public"] as Map<string,object>; userPermissions = settings["public"] as Map<string,object>;
else else

View File

@ -46,6 +46,8 @@ using System.Reflection;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using Esiur.Security.Cryptography; using Esiur.Security.Cryptography;
using Esiur.Security.Membership;
using Esiur.Net.Packets;
namespace Test namespace Test
{ {
@ -67,9 +69,23 @@ namespace Test
Console.WriteLine(ska.ToHex()); Console.WriteLine(ska.ToHex());
Console.WriteLine(skb.ToHex()); Console.WriteLine(skb.ToHex());
// Simple membership provider
var membership = new SimpleMembership() { GuestsAllowed = true };
membership.AddUser("user", "123456", new SimpleMembership.QuestionAnswer[0]);
membership.AddUser("admin", "admin", new SimpleMembership.QuestionAnswer[]
{
new SimpleMembership.QuestionAnswer()
{
Question = "What is 5+5",
Answer = 10,
Hashed = true,
}
});
// Create stores to keep objects. // Create stores to keep objects.
var system = await Warehouse.Put("sys", new MemoryStore()); var system = await Warehouse.Put("sys", new MemoryStore());
var server = await Warehouse.Put("sys/server", new DistributedServer()); var server = await Warehouse.Put("sys/server", new DistributedServer() { Membership = membership });
var web = await Warehouse.Put("sys/web", new HTTPServer() { Port = 8088 }); var web = await Warehouse.Put("sys/web", new HTTPServer() { Port = 8088 });
@ -112,12 +128,33 @@ namespace Test
static AsyncReply<object> Authenticator(Map<IIPAuthPacketIAuthHeader, object> x)
{
Console.WriteLine($"Authenticator: {x[IIPAuthPacketIAuthHeader.Clue]}");
var format = (IIPAuthPacketIAuthFormat)x[IIPAuthPacketIAuthHeader.RequiredFormat];
if (format == IIPAuthPacketIAuthFormat.Number)
return new AsyncReply<object>(Convert.ToInt32(Console.ReadLine()));
else if (format == IIPAuthPacketIAuthFormat.Text)
return new AsyncReply<object>(Console.ReadLine().Trim());
throw new NotImplementedException("Not supported format.");
}
private static async void TestClient(IResource local) private static async void TestClient(IResource local)
{ {
var con = await Warehouse.Get<DistributedConnection>("iip://localhost", new { AutoReconnect = true }); var con = await Warehouse.Get<DistributedConnection>("iip://localhost", new DistributedConnectionConfig
{
AutoReconnect = true,
Username = "admin",
Password = "admin",
Authenticator = Authenticator
});
dynamic remote = await con.Get("sys/service"); dynamic remote = await con.Get("sys/service");
var pcall = await con.Call("Hello", "whats up ?", DateTime.UtcNow); var pcall = await con.Call("Hello", "whats up ?", DateTime.UtcNow);

View File

@ -6,7 +6,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Esiur.Generator\Esiur.Security.Cryptography.csproj" /> <ProjectReference Include="..\Esiur.Security.Cryptography\Esiur.Security.Cryptography.csproj" />
<ProjectReference Include="..\Esiur\Esiur.csproj" OutputItemType="Analyzer" /> <ProjectReference Include="..\Esiur\Esiur.csproj" OutputItemType="Analyzer" />
</ItemGroup> </ItemGroup>