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;
4using System.Security.Cryptography.X509Certificates;
5using System.Threading.Tasks;
6using Waher.Content;
13
14namespace Waher.Things.Ip
15{
20 {
21 private int listeningPort = 0;
22 private string remoteIpsExpression = string.Empty;
23 private string proxyKey = null;
24 private bool trustServer = false;
25 private bool authorizedAccess = false;
26 private IpCidr[] remoteIps = null;
27
33 public override Task<bool> AcceptsChildAsync(INode Child)
34 {
35 return Task.FromResult(false);
36 }
37
43 public override Task<string> GetTypeNameAsync(Language Language)
44 {
45 return Language.GetStringAsync(typeof(IpHostPort), 24, "Proxy Port");
46 }
47
51 [Page(1, "IP")]
52 [Header(28, "Trust Server", 80)]
53 [ToolTip(29, "Check if Server Certificate should be trusted.")]
54 public bool TrustServer
55 {
56 get => this.trustServer;
57 set => this.trustServer = value;
58 }
59
63 [Page(1, "IP")]
64 [Header(25, "Listening Port Number:", 90)]
65 [ToolTip(26, "Port number to listen on for incoming conncetions.")]
66 [DefaultValue(0)]
67 [Range(0, 65535)]
68 public int ListeningPort
69 {
70 get => this.listeningPort;
71 set => this.listeningPort = value;
72 }
73
77 [Page(33, "Security")]
78 [Header(34, "Authorized Access Only (mTLS)", 80)]
79 [ToolTip(35, "If checked, mTLS will be used, requiring connecting clients to provide a client certificate authorizing access to port.")]
80 [DefaultValue(false)]
81 public bool AuthorizedAccess
82 {
83 get => this.authorizedAccess;
84 set => this.authorizedAccess = value;
85 }
86
91 [Page(33, "Security")]
92 [Header(36, "Restrict to Remote IPs", 80)]
93 [ToolTip(37, "IP Addresses are specified using a comma-delimited list of IP Addresses or IP CIDR ranges.")]
94 [RegularExpression(@"\s*\d+\.\d+\.\d+\.\d+(\/\d+)?(\s*,\s*\d+\.\d+\.\d+\.\d+(\/\d+)?)*")]
95 [DefaultValueStringEmpty]
96 public string RemoteIps
97 {
98 get => this.remoteIpsExpression;
99 set
100 {
101 if (string.IsNullOrEmpty(value))
102 this.remoteIps = null;
103 else
104 {
105 List<IpCidr> Ranges = new List<IpCidr>();
106 string[] Parts = value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
107
108 foreach (string Part in Parts)
109 {
110 if (!IpCidr.TryParse(Part, out IpCidr Parsed))
111 throw new Exception("Invalid IP Address or CIDR specification.");
112
113 Ranges.Add(Parsed);
114 }
115
116 if (Ranges.Count == 0)
117 this.remoteIps = null;
118 else
119 this.remoteIps = Ranges.ToArray();
120 }
121
122 this.remoteIpsExpression = value;
123 }
124 }
125
132 public async override Task<IEnumerable<Parameter>> GetDisplayableParametersAsync(Language Language, RequestOrigin Caller)
133 {
134 LinkedList<Parameter> Result = await base.GetDisplayableParametersAsync(Language, Caller) as LinkedList<Parameter>;
135
136 Result.AddLast(new Int32Parameter("ListeningPort", await Language.GetStringAsync(typeof(IpHost), 27, "Listening Port"), this.listeningPort));
137
138 ProxyPort Proxy = await this.GetProxy();
139
140 Result.AddLast(new Int32Parameter("NrConnections", await Language.GetStringAsync(typeof(IpHost), 32, "#Connections"), Proxy.NrConnctions));
141 Result.AddLast(new Int64Parameter("NrUplink", await Language.GetStringAsync(typeof(IpHost), 30, "#Bytes Up"), Proxy.NrBytesUplink));
142 Result.AddLast(new Int64Parameter("NrDownlink", await Language.GetStringAsync(typeof(IpHost), 31, "#Bytes Down"), Proxy.NrBytesDownlink));
143
144 return Result;
145 }
146
150 public override Task DestroyAsync()
151 {
152 if (!string.IsNullOrEmpty(this.proxyKey))
153 ProxyPorts.DestroyProxy(this.proxyKey);
154
155 return base.DestroyAsync();
156 }
157
161 [IgnoreMember]
162 public string Key
163 {
164 get
165 {
166 string PrevKey = this.proxyKey;
167 this.proxyKey = ProxyPorts.GetKey(this.Host, this.Port, this.Tls, this.trustServer, this.listeningPort, this.authorizedAccess, this.remoteIps);
168
169 if (PrevKey != this.proxyKey && !string.IsNullOrEmpty(PrevKey))
170 ProxyPorts.DestroyProxy(PrevKey);
171
172 return this.proxyKey;
173 }
174 }
175
179 protected override async Task NodeUpdated()
180 {
181 await this.GetProxy();
182 await base.NodeUpdated();
183 }
184
185 internal Task<ProxyPort> GetProxy()
186 {
187 return ProxyPorts.GetProxy(this, this.Key, this.Host, this.Port, this.Tls, this.trustServer, this.listeningPort, this.authorizedAccess, this.remoteIps);
188 }
189
195 public static string[] GetCertificateIdentities(X509Certificate Certificate)
196 {
197 List<string> Domains = new List<string>();
198 bool HasAlternativeNames = false;
199
200 foreach (string Part in Certificate.Subject.Split(certificateSubjectSeparator, StringSplitOptions.None))
201 {
202 if (Part.StartsWith("CN="))
203 Domains.Add(Part[3..]);
204 else if (Part.StartsWith("SAN="))
205 {
206 Domains.Add(Part[4..]);
207 HasAlternativeNames = true;
208 }
209 }
210
211 if (!HasAlternativeNames)
212 {
213 if (!(Certificate is X509Certificate2 Cert2))
214 {
215 byte[] Bin = Certificate.GetRawCertData();
216 Cert2 = new X509Certificate2(Bin);
217 }
218
219 foreach (X509Extension Extension in Cert2.Extensions)
220 {
221 if (Extension.Oid.Value == "2.5.29.17") // Subject Alternative Name
222 {
223 AsnEncodedData Parsed = new AsnEncodedData(Extension.Oid, Extension.RawData);
224 string[] SAN = Parsed.Format(true).Split(CommonTypes.CRLF, StringSplitOptions.RemoveEmptyEntries);
225
226 foreach (string Name in SAN)
227 {
228 int i = Name.LastIndexOf('=');
229 if (i > 0)
230 Domains.Add(Name[(i + 1)..]);
231 }
232 }
233 }
234 }
235
236 return Domains.ToArray();
237 }
238
239 private readonly static string[] certificateSubjectSeparator = new string[] { ", " };
240
241 }
242}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:15
static readonly char[] CRLF
Contains the CR LF character sequence.
Definition: CommonTypes.cs:19
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
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
Node representing an IP Host machine.
Definition: IpHost.cs:25
string Host
Host name or IP address.
Definition: IpHost.cs:73
Node representing a port on an IP Host machine.
Definition: IpHostPort.cs:24
bool Tls
If connection is encrypted using TLS or not.
Definition: IpHostPort.cs:70
int Port
Port number.
Definition: IpHostPort.cs:58
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:27
long NrBytesUplink
Number of bytes send uplink
Definition: ProxyPort.cs:508
int NrConnctions
Number of connections.
Definition: ProxyPort.cs:519
long NrBytesDownlink
Number of bytes send downlink
Definition: ProxyPort.cs:513
Static class managing Port Proxies.
Definition: ProxyPorts.cs:13
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:63
static void DestroyProxy(string Key)
Destroys a proxy node
Definition: ProxyPorts.cs:100
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:27
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