4using System.Security.Cryptography.X509Certificates;
5using System.Threading.Tasks;
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;
35 return Task.FromResult(
false);
52 [Header(28,
"Trust Server", 80)]
53 [ToolTip(29,
"Check if Server Certificate should be trusted.")]
56 get => this.trustServer;
57 set => this.trustServer = value;
64 [Header(25,
"Listening Port Number:", 90)]
65 [ToolTip(26,
"Port number to listen on for incoming conncetions.")]
70 get => this.listeningPort;
71 set => this.listeningPort = value;
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.")]
83 get => this.authorizedAccess;
84 set => this.authorizedAccess = value;
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]
98 get => this.remoteIpsExpression;
101 if (
string.IsNullOrEmpty(value))
102 this.remoteIps =
null;
105 List<IpCidr> Ranges =
new List<IpCidr>();
106 string[] Parts = value.Split(
new char[] {
',' }, StringSplitOptions.RemoveEmptyEntries);
108 foreach (
string Part
in Parts)
111 throw new Exception(
"Invalid IP Address or CIDR specification.");
116 if (Ranges.Count == 0)
117 this.remoteIps =
null;
119 this.remoteIps = Ranges.ToArray();
122 this.remoteIpsExpression = value;
134 LinkedList<Parameter> Result = await base.GetDisplayableParametersAsync(
Language, Caller) as LinkedList<Parameter>;
152 if (!
string.IsNullOrEmpty(this.proxyKey))
155 return base.DestroyAsync();
166 string PrevKey = this.proxyKey;
167 this.proxyKey =
ProxyPorts.
GetKey(this.
Host, this.
Port, this.
Tls, this.trustServer, this.listeningPort, this.authorizedAccess, this.remoteIps);
169 if (PrevKey != this.proxyKey && !
string.IsNullOrEmpty(PrevKey))
172 return this.proxyKey;
181 await this.GetProxy();
182 await base.NodeUpdated();
185 internal Task<ProxyPort> GetProxy()
197 List<string> Domains =
new List<string>();
198 bool HasAlternativeNames =
false;
200 foreach (
string Part
in Certificate.Subject.Split(certificateSubjectSeparator, StringSplitOptions.None))
202 if (Part.StartsWith(
"CN="))
203 Domains.Add(Part[3..]);
204 else if (Part.StartsWith(
"SAN="))
206 Domains.Add(Part[4..]);
207 HasAlternativeNames =
true;
211 if (!HasAlternativeNames)
213 if (!(Certificate is X509Certificate2 Cert2))
215 byte[] Bin = Certificate.GetRawCertData();
216 Cert2 =
new X509Certificate2(Bin);
219 foreach (X509Extension Extension
in Cert2.Extensions)
221 if (Extension.Oid.Value ==
"2.5.29.17")
223 AsnEncodedData Parsed =
new AsnEncodedData(Extension.Oid, Extension.RawData);
224 string[] SAN = Parsed.Format(
true).Split(
CommonTypes.
CRLF, StringSplitOptions.RemoveEmptyEntries);
226 foreach (
string Name in SAN)
228 int i =
Name.LastIndexOf(
'=');
230 Domains.Add(
Name[(i + 1)..]);
236 return Domains.ToArray();
239 private readonly
static string[] certificateSubjectSeparator =
new string[] {
", " };
Helps with parsing of commong data types.
static readonly char[] CRLF
Contains the CR LF character sequence.
IP Address Rangee, expressed using CIDR format.
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...
Contains information about a language.
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 ...
Node representing an IP Host machine.
string Host
Host name or IP address.
Node representing a port on an IP Host machine.
bool Tls
If connection is encrypted using TLS or not.
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...
long NrBytesUplink
Number of bytes send uplink
int NrConnctions
Number of connections.
long NrBytesDownlink
Number of bytes send downlink
Static class managing Port Proxies.
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
static void DestroyProxy(string Key)
Destroys a proxy node
static string GetKey(string Host, int Port, bool Tls, bool TrustServer, int ListeningPort, bool AuthorizedAccess, IpCidr[] RemoteIps)
Gets sort key for Port Proxy
Tokens available in request.
Interface for nodes that are published through the concentrator interface.