Repository navigation
Expand file tree
/
Copy pathPortProfile.cs
More file actions
166 lines (142 loc) · 7.18 KB
/
Copy pathPortProfile.cs
File metadata and controls
166 lines (142 loc) · 7.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System.Collections.Generic;
using System.Linq;
using NETworkManager.Utilities;
namespace NETworkManager.Models.Network;
public static class PortProfile
{
/// <summary>
/// Separator of the entries of a ports input (e.g. "Webserver; 8080").
/// </summary>
private const char EntrySeparator = NamedReferenceInput.EntrySeparator;
/// <summary>
/// Finds a port profile by its name (case-insensitive, leading / trailing spaces are ignored).
/// </summary>
/// <param name="portProfiles">Port profiles.</param>
/// <param name="name">Name of the port profile.</param>
/// <returns>Port profile, or null if there is none with the name.</returns>
public static PortProfileInfo FindByName(IEnumerable<PortProfileInfo> portProfiles, string name)
{
return NamedReferenceInput.FindByName(portProfiles, name);
}
/// <summary>
/// Checks if a name can be used for a port profile: the name can be entered in a ports input, so it must not
/// contain the entry separator ";" and must not be a port or port range (e.g. "80" would be read as port).
/// </summary>
/// <param name="name">Name to check.</param>
/// <returns>True if the name can be used.</returns>
public static bool IsValidName(string name)
{
return !string.IsNullOrWhiteSpace(name) && !name.Contains(EntrySeparator) &&
!PortRangeHelper.IsValidPortOrPortRange(name);
}
/// <summary>
/// Resolves a ports input into ports. Every entry (separated by ";") is a port (e.g. "80"), a port range (e.g.
/// "1-1024") or the name of a port profile (e.g. "Webserver"), which is replaced by its ports - e.g.
/// "Webserver; 8080" -> "80; 443; 8080".
/// </summary>
/// <param name="input">Ports input.</param>
/// <param name="portProfiles">Port profiles that can be used by their name.</param>
/// <param name="ports">Ports (ports and port ranges separated by ";"), null if the input is not valid.</param>
/// <returns>True if every entry is a port, port range or port profile.</returns>
public static bool TryResolvePorts(string input, IEnumerable<PortProfileInfo> portProfiles, out string ports)
{
ports = null;
if (string.IsNullOrWhiteSpace(input))
return false;
List<string> resolvedEntries = [];
foreach (var entry in input.Split(EntrySeparator))
{
if (PortRangeHelper.IsValidPortOrPortRange(entry))
{
resolvedEntries.Add(entry.Replace(" ", ""));
continue;
}
var portProfile = FindByName(portProfiles, entry);
if (portProfile == null)
return false;
resolvedEntries.Add(portProfile.Ports);
}
ports = string.Join("; ", resolvedEntries);
return true;
}
/// <summary>
/// Replaces the names of port profiles in a ports input by references to their ID (e.g. "Webserver; 8080" ->
/// "{8f1c...}; 8080"), so a profile still finds the port profile after it was renamed. Entries that are no
/// port profile (ports, unknown names) are kept.
/// </summary>
/// <param name="input">Ports input (see <see cref="TryResolvePorts" />).</param>
/// <param name="portProfiles">Port profiles.</param>
/// <returns>Input with references, null if it contains no port profile.</returns>
public static string EncodeReferences(string input, IEnumerable<PortProfileInfo> portProfiles)
{
var portProfileList = portProfiles.ToList();
// A port or port range is never a port profile (see TryResolvePorts)
return NamedReferenceInput.EncodeReferences(input,
entry => PortRangeHelper.IsValidPortOrPortRange(entry) ? null : FindByName(portProfileList, entry));
}
/// <summary>
/// Replaces the references in a ports input (see <see cref="EncodeReferences" />) by the current names of the
/// port profiles (e.g. "{8f1c...}; 8080" -> "Webserver; 8080").
/// </summary>
/// <param name="inputWithReferences">Ports input with references.</param>
/// <param name="portProfiles">Port profiles.</param>
/// <param name="input">Ports input with the names of the port profiles, null if a port profile was not found.</param>
/// <returns>True if every referenced port profile was found.</returns>
public static bool TryDecodeReferences(string inputWithReferences, IEnumerable<PortProfileInfo> portProfiles,
out string input)
{
return NamedReferenceInput.TryDecodeReferences(inputWithReferences, portProfiles, out input);
}
/// <summary>
/// Converts a ports input (e.g. of a profile or group) to the values that are saved: the ports (port profiles
/// replaced by their ports, used if a port profile can't be found later, e.g. a profile file from another
/// computer) and the input with references to the port profiles (see <see cref="EncodeReferences" />).
/// </summary>
/// <param name="input">Ports input.</param>
/// <param name="portProfiles">Port profiles.</param>
/// <returns>Ports and ports input with references (null if it contains no port profile).</returns>
public static (string Ports, string PortsInput) Encode(string input, IEnumerable<PortProfileInfo> portProfiles)
{
var portProfileList = portProfiles.ToList();
return (TryResolvePorts(input, portProfileList, out var ports) ? ports : input?.Trim(),
EncodeReferences(input, portProfileList));
}
/// <summary>
/// Converts the saved values (see <see cref="Encode" />) back to the ports input: the port profiles with their
/// current name (also after a rename), or the saved ports if a port profile can't be found.
/// </summary>
/// <param name="ports">Saved ports.</param>
/// <param name="portsInput">Saved ports input with references.</param>
/// <param name="portProfiles">Port profiles.</param>
/// <param name="portProfileNotFound">True if a port profile can't be found.</param>
/// <returns>Ports input.</returns>
public static string Decode(string ports, string portsInput, IEnumerable<PortProfileInfo> portProfiles,
out bool portProfileNotFound)
{
portProfileNotFound = false;
if (string.IsNullOrEmpty(portsInput))
return ports;
if (TryDecodeReferences(portsInput, portProfiles, out var input))
return input;
portProfileNotFound = true;
return ports;
}
public static List<PortProfileInfo> GetDefaultList()
{
return new List<PortProfileInfo>
{
new("DNS (via TCP)", "53"),
new("NTP (via TCP)", "123"),
new("Webserver", "80; 443"),
new("Webserver (Other)", "80; 443; 8080; 8443"),
new("Remote access", "22; 23; 3389; 5900"),
new("Mailserver", "25; 110; 143; 465; 587; 993; 995"),
new("Filetransfer", "20-21; 22; 989-990; 2049"),
new("Database", "1433-1434; 1521; 1830; 3306; 5432"),
new("SMB", "139; 445"),
new("LDAP", "389; 636"),
new("HTTP proxy", "3128"),
new("Well-known ports", "1-1024")
};
}
}