Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
IpHostPortProxy.cs
1using System;
2using System.Collections.Generic;
3using System.Security.Cryptography;
4using System.Security.Cryptography.X509Certificates;
5using System.Threading.Tasks;
6using Waher.Content;
12
13namespace Waher.Things.Ip
14{
19 {
20 private int listeningPort = 0;
21 private string remoteIpsExpression = string.Empty;
22 private string proxyKey = null;
23 private bool trustServer = false;
24 private bool authorizedAccess = false;
25 private IpCidr[] remoteIps = null;
26
32 public override Task<bool> AcceptsChildAsync(INode Child)
33 {
34 return Task.FromResult(false);
35 }
36
42 public override Task<string> GetTypeNameAsync(Language Language)
43 {
44 return Language.GetStringAsync(typeof(IpHostPort), 24, "Proxy Port");
45 }
46
50 [Page(1, "IP")]
51 [Header(28, "Trust Server", 80)]
52 [ToolTip(29, "Check if Server Certificate should be trusted.")]
53 public bool TrustServer
54 {
55 get => this.trustServer;
56 set => this.trustServer = value;
57 }
58
62 [Page(1, "IP")]
63 [Header(25, "Listening Port Number:", 90)]
64 [ToolTip(26, "Port number to listen on for incoming conncetions.")]
65 [DefaultValue(0)]
66 [Range(0, 65535)]
67 public int ListeningPort
68 {
69 get => this.listeningPort;
70 set => this.listeningPort = value;
71 }
72
76 [Page(33, "Security")]
77 [Header(34, "Authorized Access Only (mTLS)", 80)]
78 [ToolTip(35, "If checked, mTLS will be used, requiring connecting clients to provide a client certificate authorizing access to port.")]
79 [DefaultValue(false)]
80 public bool AuthorizedAccess
81 {
82 get => this.authorizedAccess;
83 set => this.authorizedAccess = value;
84 }
85
90 [Page(33, "Security")]
91 [Header(36, "Restrict to Remote IPs", 80)]
92 [ToolTip(37, "IP Addresses are specified using a comma-delimited list of IP Addresses or IP CIDR ranges.")]
93 [RegularExpression(@"\s*\d+\.\d+\.\d+\.\d+(\/\d+)?(\s*,\s*\d+\.\d+\.\d+\.\d+(\/\d+)?)*")]
94 [DefaultValueStringEmpty]
95 public string RemoteIps
96 {
97 get => this.remoteIpsExpression;
98 set
99 {
100 if (string.IsNullOrEmpty(value))
101 this.remoteIps = null;
102 else
103 {
104 List<IpCidr> Ranges = new List<IpCidr>();
105 string[] Parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
106
107 foreach (string Part in Parts)
108 {
109 if (!IpCidr.TryParse(Part, out IpCidr Parsed))
110 throw new Exception("Invalid IP Address or CIDR specification.");
111
112 Ranges.Add(Parsed);
113 }
114
115 if (Ranges.Count == 0)
116 this.remoteIps = null;
117 else
118 this.remoteIps = Ranges.ToArray();
119 }
120
121 this.remoteIpsExpression = value;
122 }
123 }
124
131 public async override Task<IEnumerable<Parameter>> GetDisplayableParametersAsync(Language Language, RequestOrigin Caller)
132 {
133 LinkedList<Parameter> Result = await base.GetDisplayableParametersAsync(Language, Caller) as LinkedList<Parameter>;
134
135 Result.AddLast(new Int32Parameter("ListeningPort", await Language.GetStringAsync(typeof(IpHost), 27, "Listening Port"), this.listeningPort));
136
137 ProxyPort Proxy = await this.GetProxy();
138
139 Result.AddLast(new Int32Parameter("NrConnections", await Language.GetStringAsync(typeof(IpHost), 32, "#Connections"), Proxy.NrConnctions));
140 Result.AddLast(new Int64Parameter("NrUplink", await Language.GetStringAsync(typeof(IpHost), 30, "#Bytes Up"), Proxy.NrBytesUplink));
141 Result.AddLast(new Int64Parameter("NrDownlink", await Language.GetStringAsync(typeof(IpHost), 31, "#Bytes Down"), Proxy.NrBytesDownlink));
142
143 return Result;
144 }
145
149 public override Task DestroyAsync()
150 {
151 if (!string.IsNullOrEmpty(this.proxyKey))
152 ProxyPorts.DestroyProxy(this.proxyKey);
153
154 return base.DestroyAsync();
155 }
156
160 [IgnoreMember]
161 public string Key
162 {
163 get
164 {
165 string PrevKey = this.proxyKey;
166 this.proxyKey = ProxyPorts.GetKey(this.Host, this.Port, this.Tls, this.trustServer, this.listeningPort, this.authorizedAccess, this.remoteIps);
167
168 if (PrevKey != this.proxyKey && !string.IsNullOrEmpty(PrevKey))
169 ProxyPorts.DestroyProxy(PrevKey);
170
171 return this.proxyKey;
172 }
173 }
174
178 protected override async Task NodeUpdated()
179 {
180 await this.GetProxy();
181 await base.NodeUpdated();
182 }
183
184 internal Task<ProxyPort> GetProxy()
185 {
186 return ProxyPorts.GetProxy(this, this.Key, this.Host, this.Port, this.Tls, this.trustServer, this.listeningPort, this.authorizedAccess, this.remoteIps);
187 }
188
194 public static string[] GetCertificateIdentities(X509Certificate Certificate)
195 {
196 List<string> Domains = new List<string>();
197 bool HasAlternativeNames = false;
198
199 foreach (string Part in Certificate.Subject.Split(certificateSubjectSeparator, StringSplitOptions.None))
200 {
201 if (Part.StartsWith("CN="))
202 Domains.Add(Part.Substring(3));
203 else if (Part.StartsWith("SAN="))
204 {
205 Domains.Add(Part.Substring(4));
206 HasAlternativeNames = true;
207 }
208 }
209
210 if (!HasAlternativeNames)
211 {
212 if (!(Certificate is X509Certificate2 Cert2))
213 {
214 byte[] Bin = Certificate.GetRawCertData();
215 Cert2 = new X509Certificate2(Bin);
216 }
217
218 foreach (X509Extension Extension in Cert2.Extensions)
219 {
220 if (Extension.Oid.Value == "2.5.29.17") // Subject Alternative Name
221 {
222 AsnEncodedData Parsed = new AsnEncodedData(Extension.Oid, Extension.RawData);
223 string[] SAN = Parsed.Format(true).Split(CommonTypes.CRLF, StringSplitOptions.RemoveEmptyEntries);
224
225 foreach (string Name in SAN)
226 {
227 int i = Name.LastIndexOf('=');
228 if (i > 0)
229 Domains.Add(Name.Substring(i + 1));
230 }
231 }
232 }
233 }
234
235 return Domains.ToArray();
236 }
237
238 private readonly static string[] certificateSubjectSeparator = new string[] { ", " };
239
240 }
241}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static readonly char[] CRLF
Contains the CR LF character sequence.
Definition: CommonTypes.cs:17
Contains information about a language.
Definition: Language.cs:17
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Definition: Language.cs:209
IP Address Rangee, expressed using CIDR format.
Definition: IpCidr.cs:10
static bool TryParse(string s, out IpCidr Parsed)
Tries to parse an IP Range in CIDR format. (An IP Address alone is considered implicitly having a mas...
Definition: IpCidr.cs:54
Node representing an IP Host machine.
Definition: IpHost.cs:21
string Host
Host name or IP address.
Definition: IpHost.cs:63
Node representing a port on an IP Host machine.
Definition: IpHostPort.cs:21
bool Tls
If connection is encrypted using TLS or not.
Definition: IpHostPort.cs:67
int Port
Port number.
Definition: IpHostPort.cs:55
Node representing a proxy port node.
bool TrustServer
If connection is encrypted using TLS or not.
bool AuthorizedAccess
If connection is encrypted using TLS or not.
string Key
Key identifying node.
override Task DestroyAsync()
Destroys the node. If it is a child to a parent node, it is removed from the parent first.
override async Task NodeUpdated()
Persists changes to the node, and generates a node updated event.
override Task< string > GetTypeNameAsync(Language Language)
Gets the type name of the node.
async override Task< IEnumerable< Parameter > > GetDisplayableParametersAsync(Language Language, RequestOrigin Caller)
Gets displayable parameters.
override Task< bool > AcceptsChildAsync(INode Child)
If the node accepts a presumptive child, i.e. can receive as a child (if that child accepts the node ...
string RemoteIps
If connections should be restricted to the Remote IPs defined by this expression. IP Addresses are sp...
static string[] GetCertificateIdentities(X509Certificate Certificate)
Gets names (subject and alternative) encoded in a certificate.
int ListeningPort
Incoming Port number.
Node acting as a TCP/IP proxy opening a port for incoming communication and proxying it to another po...
Definition: ProxyPort.cs:25
long NrBytesUplink
Number of bytes send uplink
Definition: ProxyPort.cs:513
int NrConnctions
Number of connections.
Definition: ProxyPort.cs:524
long NrBytesDownlink
Number of bytes send downlink
Definition: ProxyPort.cs:518
Static class managing Port Proxies.
Definition: ProxyPorts.cs:12
static async Task< ProxyPort > GetProxy(IpHostPortProxy Node, string Key, string Host, int Port, bool Tls, bool TrustServer, int ListeningPort, bool AuthorizedAccess, IpCidr[] RemoteIps)
Gets a TCP/IP proxy node
Definition: ProxyPorts.cs:62
static void DestroyProxy(string Key)
Destroys a proxy node
Definition: ProxyPorts.cs:99
static string GetKey(string Host, int Port, bool Tls, bool TrustServer, int ListeningPort, bool AuthorizedAccess, IpCidr[] RemoteIps)
Gets sort key for Port Proxy
Definition: ProxyPorts.cs:26
string Name
If the node is provisioned is not. Property is editable.
Tokens available in request.
Definition: RequestOrigin.cs:9
Interface for nodes that are published through the concentrator interface.
Definition: INode.cs:49