2using System.Collections.Generic;
5using System.Threading.Tasks;
38 private const string DefaultDataProtectionAgreementTemplate =
"25e2a2b5-4184-5cc8-a824-8b9e562c081b@legal.waher.se";
44 private readonly ManualResetEvent p2pInitiationComplete =
new ManualResetEvent(
false);
47 private bool disposeE2eEncryption =
false;
48 private bool started =
false;
49 private bool presenceSent =
false;
66 if (this.provider is
null)
71 Database.ObjectInserted += Database_ObjectInserted;
72 Database.ObjectUpdated += Database_ObjectUpdated;
73 Database.ObjectDeleted += Database_ObjectDeleted;
74 Database.CollectionCleared += this.Database_CollectionCleared;
75 Database.CollectionRepaired += Database_CollectionRepaired;
77 RosterConfiguration.OnGetGroupSuggestions += this.RosterConfiguration_OnGetGroupSuggestions;
79 Gateway.OnAfterBackup += this.AfterBackup;
81 Gateway.XmppClient.EntityHashFunction = Security.HashFunction.SHA256;
82 Gateway.XmppClient.EntityNode =
"http://waher.se/NL";
85 List<ISniffer> P2PSniffers =
new List<ISniffer>();
87 bool HasSniffers =
false;
103 Gateway.XmppClient.OnStateChanged += this.XmppClient_OnStateChanged;
105 this.p2pInitiationComplete.Reset();
109 this.serverlessMessaging.Network.OnStateChange += this.P2PNetwork_OnStateChange;
110 this.serverlessMessaging.OnNewXmppClient += this.ServerlessMessaging_OnNewXmppClient;
111 this.serverlessMessaging.OnResynch += this.ServerlessMessaging_OnResynch;
122 this.disposeE2eEncryption =
true;
130 this.e2eEncryption.PeerUnavailable += this.E2eEncryption_PeerUnavailable;
132 Gateway.AvatarClient.E2E = this.e2eEncryption;
137 Gateway.XmppClient.OnReceiveText += Counter.ShortenChunks;
138 Gateway.XmppClient.OnInformation += Counter.RemoveChunkMessage;
139 Gateway.XmppClient.OnDisposed += Counter.Client_OnDisposed;
142 Gateway.XmppClient.OnTransmitText += Counter.ShortenChunks;
143 Gateway.XmppClient.OnDisposed += Counter.Client_OnDisposed;
149 Gateway.HttpxProxy.ServerlessMessaging = this.serverlessMessaging;
152 Gateway.HttpxProxy.DefaultHttpxClient.E2e = this.e2eEncryption;
156 Gateway.HttpxServer.RequiresE2e =
true;
158 Gateway.ContractsClient.PetitionForIdentityReceived += this.ContractsClient_PetitionForIdentityReceived;
163 this.p2pInitiationComplete.WaitOne(60000);
170 if (!this.presenceSent)
171 await this.SetPresence();
173 await this.CheckContracts();
186 bool Accept = !(Id.State == IdentityState.Compromised || Id.State ==
IdentityState.Rejected);
189 List<KeyValuePair<string, object>> Tags =
new List<KeyValuePair<string, object>>()
196 Tags.Add(
new KeyValuePair<string, object>(P.
Name, P.
Value));
204 private Task RosterConfiguration_OnGetGroupSuggestions(
object Sender,
SuggestionEventArgs e)
212 return Task.CompletedTask;
221 this.started =
false;
223 if (!(this.client is
null))
228 if (this.disposeE2eEncryption)
234 this.e2eEncryption =
null;
236 if (!(this.serverlessMessaging is
null))
239 this.serverlessMessaging =
null;
242 Gateway.OnAfterBackup -= this.AfterBackup;
244 RosterConfiguration.OnGetGroupSuggestions -= this.RosterConfiguration_OnGetGroupSuggestions;
246 Database.ObjectInserted -= Database_ObjectInserted;
247 Database.ObjectUpdated -= Database_ObjectUpdated;
248 Database.ObjectDeleted -= Database_ObjectDeleted;
249 Database.CollectionCleared -= this.Database_CollectionCleared;
250 Database.CollectionRepaired -= Database_CollectionRepaired;
252 Gateway.XmppClient.OnStateChanged -= this.XmppClient_OnStateChanged;
254 Gateway.ContractsClient.PetitionForIdentityReceived -= this.ContractsClient_PetitionForIdentityReceived;
257 this.synchronizationResource =
null;
261 private Task CheckContracts()
263 return this.CheckContracts(
null);
266 private async Task CheckContracts(
object P)
284 string Xml = File.ReadAllText(Path.Combine(
Gateway.
AppDataFolder,
"Contracts",
"BlockSubscription.xml"));
285 XmlDocument Doc =
new XmlDocument()
287 PreserveWhitespace =
true
294 string TemplateId = await
RuntimeSettings.
GetAsync(
"NL.DPA.TemplateId", DefaultDataProtectionAgreementTemplate);
295 if (
string.IsNullOrEmpty(TemplateId))
310 Value = Gateway.XmppClient.BareJID
318 Log.
Error(
"Unable to create Data Protection Smart Contract.",
319 new KeyValuePair<string, object>(
"Message", ex.Message));
323 LedgerConfiguration.Instance.DataProtectionAgreementId = Dpa.
ContractId;
327 bool GeneratorSigned =
false;
329 if (!(Dpa?.ClientSignatures is
null))
335 GeneratorSigned =
true;
341 if (!GeneratorSigned)
344 "designated parties before they can access blocks generated by the Neuro-Ledger on this machine.");
348 private static readonly Dictionary<Type, bool> processInLedger =
new Dictionary<Type, bool>();
350 private static async Task<bool> Process(
object Object)
352 Type T = Object.GetType();
355 lock (processInLedger)
357 if (processInLedger.TryGetValue(T, out Result))
369 lock (processInLedger)
371 processInLedger[T] = Result;
377 private static async
void Database_ObjectInserted(
object Sender,
ObjectEventArgs e)
381 if (!await Process(e.
Object))
393 private static async
void Database_ObjectUpdated(
object Sender,
ObjectEventArgs e)
397 if (!await Process(e.
Object))
409 private static async
void Database_ObjectDeleted(
object Sender,
ObjectEventArgs e)
413 if (!await Process(e.
Object))
431 if (Array.IndexOf(
this.provider.Collections, Collection) >= 0)
440 private async Task XmppClient_OnStateChanged(
object Sender,
XmppState NewState)
450 if (!(this.serverlessMessaging is
null))
461 await this.CheckContracts();
477 PostResource = Gateway.HttpxProxy.PostResource
480 bool Sniffers =
false;
482 HttpxServer.RequiresE2e =
true;
486 Client.
SetTag(
"ShowE2E",
false);
489 Client.OnValidateSender += this.PeerClient_OnValidateSender;
490 Client.OnDisposed += this.P2PClient_OnDisposed;
504 e.
RemoteJid + Path.DirectorySeparatorChar +
"XMPP Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml",
505 AppDataFolder +
"Transforms" + Path.DirectorySeparatorChar +
"SnifferXmlToHtml.xslt",
521 ChunkCounter Counter =
new ChunkCounter(
true, Client,
true);
522 Client.OnReceiveText += Counter.ShortenChunks;
523 Client.OnInformation += Counter.RemoveChunkMessage;
524 Client.OnDisposed += Counter.Client_OnDisposed;
526 Counter =
new ChunkCounter(
false, Client,
true);
527 Client.OnTransmitText += Counter.ShortenChunks;
528 Client.OnDisposed += Counter.Client_OnDisposed;
531 return Task.CompletedTask;
534 private Task ServerlessMessaging_OnResynch(
object Sender,
ResynchEventArgs e)
539 return Task.CompletedTask;
542 return Task.CompletedTask;
547 if (!e.
Client.
TryGetTag(
"ExpectedSender", out
object Obj) || !(Obj is
string s) ||
string.Compare(e.
From, s,
true) != 0)
550 return Task.CompletedTask;
553 private Task P2PClient_OnDisposed(
object Sender, EventArgs e)
559 if (Client.TryGetTag(
"HttpxServer", out
object Obj) && Obj is IDisposable Disposable)
560 Disposable.Dispose();
562 if (Client.TryGetTag(
"HttpxClient", out Obj) && Obj is IDisposable Disposable2)
563 Disposable2.Dispose();
566 return Task.CompletedTask;
571 if (this.serverlessMessaging is
null)
590 await this.SetPresence();
592 this.p2pInitiationComplete.Set();
596 P2P.DesiredLocalPort = 0;
597 P2P.DesiredExternalPort = 0;
599 this.p2pInitiationComplete.Set();
612 return Task.CompletedTask;
620 get {
return instance?.serverlessMessaging; }
628 get {
return instance?.e2eEncryption; }
631 private async Task SetPresence()
636 this.presenceSent =
true;
640 private async Task AfterBackup(
object Sender, EventArgs e)
645 await this.SetPresence();
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
Static class managing the runtime environment of the IoT Gateway.
static HttpxProxy HttpxProxy
HTTPX Proxy resource
static HttpServer HttpServer
HTTP Server
static string AppDataFolder
Application data folder.
static async Task RequestContractSignature(Contract Contract, string Role, string Purpose)
Requests the operator to sign a smart contract.
static ContractsClient ContractsClient
XMPP Contracts Client, if such a compoent is available on the XMPP broker.
static HttpxServer HttpxServer
HTTPX Server
static DateTime ScheduleEvent(ScheduledEventCallback Callback, DateTime When, object State)
Schedules a one-time event.
static XmppClient XmppClient
XMPP Client connection of gateway.
Configures legal identity for the gateway.
static bool TryGetMyIdentity(CaseInsensitiveString LegalId, out LegalIdentity Identity)
Tries to get one of the legal identities belonging to the current instance.
Event arguments for suggestion event handlers.
void AddSuggestion(string Suggestion)
Adds a suggestion.
ISniffer[] Sniffers
Registered sniffers.
virtual void Add(ISniffer Sniffer)
ICommunicationLayer.Add
Base class for all HTTP resources.
Represets a response of an HTTP client request.
HttpResource Register(HttpResource Resource)
Registers a resource with the server.
bool Unregister(HttpResource Resource)
Unregisters a resource from the server.
Manages a peer-to-peer network that can receive connections from outside of a NAT-enabled firewall.
IPEndPoint ExternalEndpoint
External IP Endpoint.
ushort DesiredExternalPort
Desired external port number. If 0, a dynamic port number will be assigned.
IPEndPoint LocalEndpoint
Local IP Endpoint.
Outputs sniffed data to an XML file.
Represents a digital signature on a contract.
Contains the definition of a contract
static Task< ParsedContract > Parse(XmlDocument Xml)
Validates a contract XML Document, and returns the contract definition in it.
Parameter[] Parameters
Defined parameters for the smart contract.
Duration? ArchiveRequired
Requied time to archive a signed smart contract, after it becomes obsolete.
ClientSignature[] ClientSignatures
Client signatures of the contract.
HumanReadableText[] ForHumans
Human-readable contents of the contract.
Duration? ArchiveOptional
Optional time to archive a signed smart contract, after it becomes obsolete, and after its required a...
XmlElement ForMachines
Machine-readable contents of the contract.
Role[] Roles
Roles defined in the smart contract.
DateTime? SignAfter
Signatures will only be accepted after this point in time.
ContractParts PartsMode
How parts are defined in the smart contract.
string ContractId
Contract identity
Part[] Parts
Defined parts for the smart contract.
Duration? Duration
Duration of the contract. Is counted from the time it is signed by the required parties.
DateTime? SignBefore
Signatures will only be accepted until this point in time.
ContractVisibility Visibility
Contrat Visibility
Task PetitionIdentityResponseAsync(string LegalId, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition for information about a legal identity. When a petition is received,...
Task< Contract > GetContractAsync(string ContractId)
Gets a contract
Task< Contract > CreateContractAsync(XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate)
Creates a new contract.
Event arguments for legal identity petitions
LegalIdentity RequestorIdentity
Legal Identity of requesting entity.
string PetitionId
Petition ID
string RequestorFullJid
Full JID of requestor.
string RequestedIdentityId
Requested identity ID
string Provider
Provider where the identity is maintained.
Property[] Properties
Properties detailing the legal identity.
Abstract base class for contractual parameters
Contains information about a parsed contract.
Contract Contract
Contract object
Class defining a part in a contract
string Name
Name of property
string Value
Property value
Abstract base class of signatures
String-valued contractual parameter
string Id
ID attribute of message stanza.
Event arguments for presence events.
string From
From where the presence was received.
Event arguments for sender validation events.
string From
From where the stanza was received.
XmppClient Client
XMPP Client.
void Reject()
Called from an event handler to reject the sender.
IEndToEndEncryption E2e
Optional end-to-end encryption interface to use in requests.
XmppServerlessMessaging ServerlessMessaging
Serverless messaging manager.
HttpxClient DefaultHttpxClient
Default HTTPX client.
Task ProcessBlockRequest(HTTP.HeaderFields.HttpFieldAccept Accept, HTTP.HttpResponse Response, BlockReference Ref)
TODO
override void Dispose()
IDisposable.Dispose
Class managing end-to-end encryption.
virtual void RegisterHandlers(XmppClient Client)
Registers XMPP stanza handlers
virtual void UnregisterHandlers(XmppClient Client)
Unregisters XMPP stanza handlers
Task SynchronizeE2e(string FullJID, EventHandlerAsync< IqResultEventArgs > Callback)
Synchronizes End-to-End Encryption and Peer-to-Peer connectivity parameters with a remote entity.
void GenerateNewKey()
Generates new local keys.
virtual void Dispose()
IDisposable.Dispose
Peer connection event arguments.
XmppClient Client
XMPP client, if aquired, or null otherwise.
string RemoteJid
JID of the remote end-point.
Peer connection event arguments.
string RemoteFullJid
JID of the remote end-point.
Class managing peer-to-peer serveless XMPP communication.
PeerToPeerNetwork Network
Peer-to-peer network.
async Task RemovePeerAddresses(string FullJID)
Removes a JID from the recognized set of JIDs.
async Task DisposeAsync()
IDisposable.Dispose
Maintains information about an item in the roster.
string BareJid
Bare JID of the roster item.
PendingSubscription PendingSubscription
If there's a pending unanswered presence subscription or unsubscription request made to the contact.
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
XmppState State
Current state of connection.
Task RequestPresenceSubscription(string BareJid)
Requests subscription of presence information from a contact.
bool RemoveTag(string TagName)
Removes a tag from the client.
void SetTag(string TagName, object Tag)
Sets a tag value.
Task SetPresence()
Sets the presence of the connection. Add a CustomPresenceXml event handler to add custom presence XML...
bool TryGetTag(string TagName, out object Tag)
Tries to get a tag from the client. Tags can be used to attached application specific objects to the ...
RosterItem[] Roster
Items in the roster.
Event arguments for collection events.
string Collection
Collection
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static async Task Update(object Object)
Updates an object in the database.
static Task< GenericObject > Generalize(object Object)
Creates a generalized representation of an object.
Static interface for ledger persistence. In order to work, a ledger provider has to be assigned to it...
static async Task DeletedEntry(object Object)
Deletes an entry in the ledger.
static ILedgerProvider Provider
Registered ledger provider.
static async Task NewEntry(object Object)
Adds an entry to the ledger.
static async Task ClearedCollection(string Collection)
Clears a collection in the ledger.
static async Task UpdatedEntry(object Object)
Updates an entry in the ledger.
string[] Collections
Array of collections archived in the ledger.
Task< ObjectSerializer > GetObjectSerializerEx(object Object)
Gets the object serializer corresponding to a specific object.
Contains a reference to a block in the ledger.
Event arguments for database object events.
Generic object. Contains a sequence of properties.
Serializes a class, taking into account attributes defined in Attributes.
bool ArchiveObjects
If objects of this type can be archived.
Static class that dynamically manages types and interfaces available in the runtime environment.
static bool TryGetModuleParameter(string Name, out object Value)
Tries to get a module parameter value.
Static class managing persistent settings.
static async Task< string > GetAsync(string Key, string DefaultValue)
Gets a string-valued setting.
static async Task< bool > SetAsync(string Key, string Value)
Sets a string-valued setting.
Static class of application-wide semaphores that can be used to order access to editable objects.
static Task EndWrite(string Key)
Ends a writing session of the semaphore identified by Key . Must be called once for each call to Begi...
static async Task< Semaphore > BeginWrite(string Key)
Waits until the semaphore identified by Key is ready for writing. Each call to BeginWrite must be fo...
static Task ProcessBlockRequest(Networking.HTTP.HeaderFields.HttpFieldAccept Accept, HttpResponse Response, BlockReference Ref)
TODO
static XmppServerlessMessaging ServerlessMessaging
TODO
static EndpointSecurity E2eEncryption
TODO
string DataProtectionAgreementId
Data Protection Agreement to use before allowing access to the Neuro-Ledger.
static LedgerConfiguration Instance
Current instance of configuration.
Allows operators to manually start network synchronization.
Interface for sniffers. Sniffers can be added to ICommunicationLayer classes to eavesdrop on communic...
Interface for late-bound modules loaded at runtime.
PeerToPeerNetworkState
State of Peer-to-peer network.
BinaryPresentationMethod
How binary data is to be presented.
IdentityState
Lists recognized legal identity states.
ContractParts
How the parts of the contract are defined.
ContractVisibility
Visibility types for contracts.
Availability
Resource availability.
XmppState
State of XMPP connection.
PendingSubscription
Pending subscription states.