@coffeerunhobby/mcp-ha-connect 2.4.6 → 2.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,595 @@
1
+ /**
2
+ * net_ rules on Omada (2.4.7): the neutral Rule <-> Omada gateway ACL.
3
+ *
4
+ * The gateway (ER605) routes between the VLANs, so network-to-network policy lives in
5
+ * gateway ACLs with direction LAN→LAN; rules towards the internet are LAN→WAN.
6
+ *
7
+ * Verified on the live controller (6.3.0.45, ER605 v2, 2026-10-20):
8
+ * - LAN→LAN rules between networks (endpoint type 0) and towards an IP-port group
9
+ * (endpoint type 2); IP-port groups {type: 1, ipList, portType: 0, portList: ["1883"]};
10
+ * - stateMode 0 ("Auto") is stateful on the ER605: TP-Link's one-way VLAN guide (deny
11
+ * IoT→LAN, Auto) leaves the LAN able to reach IoT and IoT unable to reach the LAN, so a
12
+ * block rule does not drop replies. "Manual" connection states are not verified, so a
13
+ * rule that also matches replies is refused.
14
+ * Not offered through the API, so refused: the gateway itself as a destination (gateway
15
+ * ACLs filter traffic passing through it), one device by MAC, schedules (the omada_
16
+ * time-range tools do those).
17
+ *
18
+ * Addresses given in a rule become an IP group (or IP-port group) the rule owns: its
19
+ * name starts with the rule's tag "[net:<key>]", which also ends the ACL description, so
20
+ * they are listed as part of the rule and removed with it.
21
+ */
22
+ import { randomBytes } from 'node:crypto';
23
+ import { parseCidr, subnetsOverlap } from '../../utils/ipv4.js';
24
+ import { NetError } from '../model.js';
25
+ import { checkName } from '../validate.js';
26
+ export const POLICY = { block: 0, allow: 1 };
27
+ const PROTOCOL = { any: 256, tcp: 6, udp: 17, icmp: 1 };
28
+ export const ENDPOINT = { network: 0, ipGroup: 1, ipPortGroup: 2, ssid: 4 };
29
+ export const GROUP_TYPE = { ip: 0, ipPort: 1 };
30
+ const PORT_TYPE_LIST = 0;
31
+ const ANY_GROUP = 'IPGroup_Any';
32
+ /** Omada's ACL description limit, minus room for the " [net:xxxxxxxx]" tag. */
33
+ export const MAX_RULE_NAME = 512 - 16;
34
+ const MAX_PORTS = 16;
35
+ const TAG = /\s*\[net:([0-9a-f]{8})\]$/;
36
+ /** The exact name of a group some rule owns (ownedGroupName); the omada_ group tools refuse the "[net:" prefix. */
37
+ const OWNED = /^\[net:[0-9a-f]{8}\] (from|to) [0-9a-f]{16}$/;
38
+ // ---- tags and names ---------------------------------------------------------------------
39
+ export function ruleKey(description) {
40
+ return TAG.exec(description)?.[1];
41
+ }
42
+ export function ruleName(description) {
43
+ return description.replace(TAG, '');
44
+ }
45
+ export function newRuleKey() {
46
+ return randomBytes(4).toString('hex');
47
+ }
48
+ export function tagged(name, key) {
49
+ return key ? `${name} [net:${key}]` : name;
50
+ }
51
+ /** A name for a group the rule owns, not among `taken` (an update must never reuse the name of the group it replaces). */
52
+ export function ownedGroupName(key, side, taken) {
53
+ for (let i = 0; i < 5; i++) {
54
+ const name = `[net:${key}] ${side} ${randomBytes(8).toString('hex')}`;
55
+ if (!taken.has(name))
56
+ return name;
57
+ }
58
+ throw new NetError('CONFLICT', 'Could not find an unused group name; try again');
59
+ }
60
+ export function ownsGroup(key, group) {
61
+ return key !== undefined && isOwnedGroup(group) && String(group.name).startsWith(`[net:${key}] `);
62
+ }
63
+ /** Whether a group belongs to some net_ rule (never shared: it goes when its last user does). */
64
+ export function isOwnedGroup(group) {
65
+ return OWNED.test(String(group.name));
66
+ }
67
+ /** The rule's direction as stored on the controller, when it is a plain one. */
68
+ export function rawDirection(raw) {
69
+ const dir = (raw.direction ?? {});
70
+ const inbound = (dir.wanInIds?.length ?? 0) > 0 || (dir.vpnInIds?.length ?? 0) > 0;
71
+ if (inbound)
72
+ return undefined;
73
+ if (dir.lanToLan === true && dir.lanToWan !== true)
74
+ return 'lanToLan';
75
+ if (dir.lanToWan === true && dir.lanToLan !== true)
76
+ return 'lanToWan';
77
+ return undefined;
78
+ }
79
+ // ---- references ---------------------------------------------------------------------------
80
+ /** By id, or by unique name (case-insensitive); an exact id given as a name wins. */
81
+ export function resolve(items, ref, what) {
82
+ if ('id' in ref) {
83
+ const byId = items.find((i) => i.id === ref.id);
84
+ if (byId)
85
+ return byId;
86
+ throw new NetError('NOT_FOUND', `No ${what} with id '${ref.id}'`);
87
+ }
88
+ // Tools pass what the user typed as { name }; an exact id match wins.
89
+ const byId = items.find((i) => i.id === ref.name);
90
+ if (byId)
91
+ return byId;
92
+ const wanted = ref.name.trim().toLowerCase();
93
+ const matches = items.filter((i) => i.name.toLowerCase() === wanted);
94
+ if (matches.length === 1)
95
+ return matches[0];
96
+ if (matches.length > 1)
97
+ throw new NetError('AMBIGUOUS', `Several ${what}s are named '${ref.name}'; use the id`);
98
+ throw new NetError('NOT_FOUND', `${what[0].toUpperCase()}${what.slice(1)} '${ref.name}' not found. Available: ${items.map((i) => i.name).join(', ') || '(none)'}`);
99
+ }
100
+ function groupItems(groups) {
101
+ return groups.map((g) => ({ id: String(g.groupId), name: String(g.name), raw: g }));
102
+ }
103
+ /**
104
+ * By name when that name is unique and no other item has it as its id (resolve tries ids
105
+ * first), else by id: readable, and resolving back to the same item.
106
+ */
107
+ function refTo(items, id) {
108
+ const item = items.find((i) => i.id === id);
109
+ if (!item)
110
+ return { id };
111
+ const unique = items.filter((i) => i.name.toLowerCase() === item.name.toLowerCase()).length === 1;
112
+ const shadowedById = items.some((i) => i.id === item.name && i.id !== item.id);
113
+ return unique && !shadowedById ? { name: item.name } : { id };
114
+ }
115
+ // ---- Omada -> neutral -------------------------------------------------------------------
116
+ export function toRule(raw, position, world) {
117
+ const description = String(raw.description ?? '');
118
+ const key = ruleKey(description);
119
+ const foreign = [];
120
+ const dir = (raw.direction ?? {});
121
+ const inbound = (dir.wanInIds?.length ?? 0) > 0 || (dir.vpnInIds?.length ?? 0) > 0;
122
+ const direction = rawDirection(raw);
123
+ if (!direction)
124
+ foreign.push(inbound ? 'traffic coming in from the WAN or a VPN' : 'several directions in one rule');
125
+ const networkItems = world.networks.map((n) => ({ id: n.id, name: n.name }));
126
+ const ipGroups = groupItems(world.ipGroups);
127
+ const ipPortGroups = groupItems(world.ipPortGroups);
128
+ const endpoint = (type, ids, side) => {
129
+ if (type === ENDPOINT.network)
130
+ return { selectors: ids.map((id) => ({ network: refTo(networkItems, id) })) };
131
+ if (type === ENDPOINT.ssid && side === 'from')
132
+ return { selectors: ids.map((id) => ({ wifi: refTo(world.ssids, id) })) };
133
+ if (type === ENDPOINT.ipPortGroup && side === 'from') {
134
+ // The model has no source ports: such a rule can't be shown (or protected) faithfully.
135
+ foreign.push('a source with ports');
136
+ return { selectors: [] };
137
+ }
138
+ if (type === ENDPOINT.ipGroup || type === ENDPOINT.ipPortGroup) {
139
+ const pool = type === ENDPOINT.ipGroup ? ipGroups : ipPortGroups;
140
+ const selectors = [];
141
+ let ports;
142
+ for (const id of ids) {
143
+ const group = pool.find((g) => g.id === id);
144
+ if (!group) {
145
+ foreign.push(`an unknown group ${id}`);
146
+ continue;
147
+ }
148
+ if (type === ENDPOINT.ipPortGroup) {
149
+ ports = (group.raw.portList ?? []).map(String).join(',');
150
+ // The model writes ports only into groups it owns; one made elsewhere can't be kept or rewritten faithfully.
151
+ if (!ownsGroup(key, group.raw))
152
+ foreign.push(`the port group ${group.name} made elsewhere`);
153
+ }
154
+ if (side === 'to' && direction === 'lanToWan' && group.name === ANY_GROUP) {
155
+ selectors.push({ internet: true });
156
+ continue;
157
+ }
158
+ if (side === 'to' && direction && directionOf(group.raw, world) !== direction) {
159
+ // Editing would recompute the direction from the addresses and change what the rule applies to.
160
+ foreign.push(`a ${direction === 'lanToLan' ? 'LAN to LAN' : 'LAN to internet'} rule whose destination ${group.name} doesn't match that direction`);
161
+ }
162
+ if (ownsGroup(key, group.raw))
163
+ selectors.push({ addresses: addressesOf(group.raw) });
164
+ else
165
+ selectors.push({ group: refTo(pool, id) });
166
+ }
167
+ return { selectors, ...(ports !== undefined ? { ports } : {}) };
168
+ }
169
+ foreign.push(`a ${side === 'from' ? 'source' : 'destination'} of type ${type}`);
170
+ return { selectors: [] };
171
+ };
172
+ const from = endpoint(Number(raw.sourceType), raw.sourceIds ?? [], 'from');
173
+ const to = endpoint(Number(raw.destinationType), raw.destinationIds ?? [], 'to');
174
+ if (direction === 'lanToWan' && Number(raw.destinationType) === ENDPOINT.network)
175
+ foreign.push('a LAN network as the destination of a LAN to internet rule (it never matches)');
176
+ const protocols = (raw.protocols ?? []).slice().sort((a, b) => a - b);
177
+ let protocol = 'any';
178
+ if (to.ports !== undefined) {
179
+ if (protocols.join() === `${PROTOCOL.tcp},${PROTOCOL.udp}`)
180
+ protocol = { tcpUdpPorts: to.ports };
181
+ else
182
+ foreign.push('ports on only one of TCP/UDP');
183
+ }
184
+ else {
185
+ const named = Object.keys(PROTOCOL).find((p) => protocols.length === 1 && protocols[0] === PROTOCOL[p]);
186
+ if (named)
187
+ protocol = named;
188
+ else
189
+ foreign.push(`protocols ${protocols.join(', ')}`);
190
+ }
191
+ if (Number(raw.stateMode ?? 0) !== 0)
192
+ foreign.push('manual connection states');
193
+ if (raw.timeRangeId)
194
+ foreign.push('a schedule (edit it with the omada_ gateway ACL tools)');
195
+ return {
196
+ id: String(raw.id),
197
+ name: ruleName(description),
198
+ action: raw.policy === POLICY.allow ? 'allow' : 'block',
199
+ from: from.selectors,
200
+ to: to.selectors,
201
+ protocol,
202
+ replies: 'allow',
203
+ schedule: { kind: 'always' },
204
+ enabled: raw.status === true,
205
+ position,
206
+ ...(foreign.length ? { foreign: { reason: `Not editable through net_: ${foreign.join('; ')}.` } } : {}),
207
+ };
208
+ }
209
+ /** The direction a group's addresses call for, or undefined when they mix (or can't be read). */
210
+ function directionOf(group, world) {
211
+ try {
212
+ return classify(group.ipList ?? [], world, String(group.name));
213
+ }
214
+ catch {
215
+ return undefined;
216
+ }
217
+ }
218
+ function addressesOf(group) {
219
+ return (group.ipList ?? []).map((e) => (Number(e.mask) === 32 ? e.ip : `${e.ip}/${e.mask}`));
220
+ }
221
+ // ---- neutral -> Omada -------------------------------------------------------------------
222
+ /**
223
+ * Validates a rule and works out its Omada shape. `self` is the rule being changed (its
224
+ * own name doesn't collide; on update, sides that didn't change keep their Omada objects).
225
+ */
226
+ export function draftRule(value, world, self) {
227
+ const name = checkName(value.name, MAX_RULE_NAME, 'Rule');
228
+ // The tag marks what a rule owns; a name carrying one could pass for another rule (or for none).
229
+ if (/\[net:/i.test(name))
230
+ throw new NetError('INVALID', "A rule name can't contain '[net:': it is reserved for the tag that ties a rule to its groups");
231
+ // Names never carry a tag, so comparing against the untagged part of each description is enough.
232
+ const taken = world.acls.some((a) => String(a.id) !== String(self?.raw.id) && ruleName(String(a.description)).toLowerCase() === name.toLowerCase());
233
+ if (taken)
234
+ throw new NetError('EXISTS', `A rule named '${name}' already exists`);
235
+ if (value.replies === 'match') {
236
+ throw unsupported("rules that also match replies (stateless). Omada's rules let replies through (Auto); its manual connection states aren't verified", 'rules.stateful');
237
+ }
238
+ if (value.schedule.kind !== 'always')
239
+ throw unsupported('schedules on net_ rules yet (use omada_createTimeRange with omada_createGatewayAcl)', 'rules.schedule');
240
+ const ports = typeof value.protocol === 'object' ? parsePorts(value.protocol.tcpUdpPorts) : undefined;
241
+ const { endpoint: destination, direction } = destinationOf(value.to, world, ports, value.protocol, self);
242
+ const source = sourceOf(value.from, world, self);
243
+ const protocols = ports ? [PROTOCOL.tcp, PROTOCOL.udp] : [PROTOCOL[value.protocol]];
244
+ if (source.type === ENDPOINT.network && destination.type === ENDPOINT.network && 'ids' in source && 'ids' in destination) {
245
+ const same = source.ids.filter((id) => destination.ids.includes(id));
246
+ if (same.length)
247
+ throw new NetError('INVALID', "A network can't be both source and destination: traffic inside one network never passes the gateway");
248
+ }
249
+ const verb = value.action === 'allow' ? 'may reach' : 'can no longer start connections to';
250
+ const what = ports ? ` on TCP/UDP ${ports.join(', ')}` : value.protocol === 'any' ? '' : ` (${String(value.protocol).toUpperCase()} only)`;
251
+ const effects = [`${source.label} ${verb} ${destination.label}${what}.`];
252
+ if (value.action === 'block')
253
+ effects.push('Replies to connections started from the other side still pass (stateful).');
254
+ if (!value.enabled)
255
+ effects.push('The rule is created switched off.');
256
+ return { name, direction, policy: POLICY[value.action], protocols, source, destination, enabled: value.enabled, effects };
257
+ }
258
+ function sourceOf(selectors, world, self) {
259
+ const kind = singleKind(selectors, 'source');
260
+ if (self && sameSelectors(selectors, self.rule.from)) {
261
+ return { type: Number(self.raw.sourceType), ids: self.raw.sourceIds ?? [], label: label(selectors, world) };
262
+ }
263
+ switch (kind) {
264
+ case 'network':
265
+ return { type: ENDPOINT.network, ids: routedNetworks(selectors, world).map((n) => n.id), label: label(selectors, world) };
266
+ case 'group':
267
+ return { type: ENDPOINT.ipGroup, ids: selectors.map((s) => sharedGroup(world, s.group).id), label: label(selectors, world) };
268
+ case 'addresses': {
269
+ const entries = selectors.flatMap((s) => s.addresses).map(parseAddress);
270
+ return { type: ENDPOINT.ipGroup, newGroup: { groupType: GROUP_TYPE.ip, body: { type: GROUP_TYPE.ip, ipList: entries } }, label: label(selectors, world) };
271
+ }
272
+ case 'device':
273
+ throw unsupported('matching one device (give its address in addresses; a DHCP reservation keeps it fixed)', 'rules.deviceMatch');
274
+ case 'wifi':
275
+ throw unsupported('a Wi-Fi network as a net_ rule source (omada_createGatewayAcl does it for LAN to internet rules)', 'rules.wifiMatch');
276
+ default:
277
+ throw new NetError('INVALID', 'A rule starts from networks, a group or addresses, not from the internet or the gateway');
278
+ }
279
+ }
280
+ function destinationOf(selectors, world, ports, protocol, self) {
281
+ const kind = singleKind(selectors, 'destination');
282
+ if (ports && kind !== 'addresses')
283
+ throw new NetError('INVALID', 'Ports go with addresses as the destination (e.g. to: [{ addresses: ["192.0.2.10"] }])');
284
+ switch (kind) {
285
+ case 'network': {
286
+ const keep = self && sameSelectors(selectors, self.rule.to) && Number(self.raw.destinationType) === ENDPOINT.network;
287
+ const ids = keep ? (self.raw.destinationIds ?? []) : routedNetworks(selectors, world).map((n) => n.id);
288
+ return { endpoint: { type: ENDPOINT.network, ids, label: label(selectors, world) }, direction: 'lanToLan' };
289
+ }
290
+ case 'internet': {
291
+ const any = world.ipGroups.find((g) => g.name === ANY_GROUP);
292
+ if (!any)
293
+ throw new NetError('NOT_FOUND', `The built-in IP group ${ANY_GROUP} is missing on the controller`);
294
+ return { endpoint: { type: ENDPOINT.ipGroup, ids: [String(any.groupId)], label: 'the internet' }, direction: 'lanToWan' };
295
+ }
296
+ case 'group': {
297
+ const groups = selectors.map((s) => sharedGroup(world, s.group));
298
+ const entries = groups.flatMap((g) => g.raw.ipList ?? []);
299
+ // An existing rule whose stored direction differs from what its addresses call for is
300
+ // foreign (toRule), so recomputing it here never flips an editable rule.
301
+ return { endpoint: { type: ENDPOINT.ipGroup, ids: groups.map((g) => g.id), label: label(selectors, world) }, direction: classify(entries, world, label(selectors, world)) };
302
+ }
303
+ case 'addresses': {
304
+ const entries = selectors.flatMap((s) => s.addresses).map(parseAddress);
305
+ // Never flips an editable rule: a stored direction that differs is foreign (toRule).
306
+ const direction = classify(entries, world, 'These addresses');
307
+ // Same addresses and the same protocol/ports: keep the group the rule already has.
308
+ const sameAsBefore = self && sameSelectors(selectors, self.rule.to) && protocolKey(self.rule.protocol) === protocolKey(protocol);
309
+ if (sameAsBefore) {
310
+ return { endpoint: { type: Number(self.raw.destinationType), ids: self.raw.destinationIds ?? [], label: label(selectors, world) }, direction };
311
+ }
312
+ if (ports) {
313
+ if (direction === 'lanToWan')
314
+ throw unsupported('ports on a rule towards the internet through net_ yet (verified only between your networks)', 'rules.toInternet');
315
+ return {
316
+ endpoint: {
317
+ type: ENDPOINT.ipPortGroup,
318
+ newGroup: { groupType: GROUP_TYPE.ipPort, body: { type: GROUP_TYPE.ipPort, ipList: entries, portType: PORT_TYPE_LIST, portList: ports } },
319
+ label: label(selectors, world),
320
+ },
321
+ direction,
322
+ };
323
+ }
324
+ return { endpoint: { type: ENDPOINT.ipGroup, newGroup: { groupType: GROUP_TYPE.ip, body: { type: GROUP_TYPE.ip, ipList: entries } }, label: label(selectors, world) }, direction };
325
+ }
326
+ case 'gateway':
327
+ throw unsupported("the gateway itself as a destination: gateway rules filter traffic passing through the gateway, and the API has no option for the gateway's own addresses", 'rules.gateway');
328
+ case 'device':
329
+ throw unsupported('matching one device (give its address in addresses; a DHCP reservation keeps it fixed)', 'rules.deviceMatch');
330
+ default:
331
+ throw new NetError('INVALID', 'A Wi-Fi network is not a destination; use its network');
332
+ }
333
+ }
334
+ /** Comparable form of a protocol ("1883, 8123" and "1883,8123" are the same ports). */
335
+ function protocolKey(protocol) {
336
+ if (typeof protocol !== 'object')
337
+ return protocol;
338
+ return `ports:${protocol.tcpUdpPorts.split(',').map((p) => String(Number(p.trim()))).join(',')}`;
339
+ }
340
+ /** An IP group a rule may reference by name: not one another rule owns (those are never shared). */
341
+ function sharedGroup(world, ref) {
342
+ const group = resolve(groupItems(world.ipGroups), ref, 'IP group');
343
+ if (isOwnedGroup(group.raw))
344
+ throw new NetError('INVALID', `IP group '${group.name}' belongs to another rule; give the addresses instead`);
345
+ return group;
346
+ }
347
+ function kindOf(selector) {
348
+ return Object.keys(selector)[0];
349
+ }
350
+ /** Omada takes one kind of endpoint per side; mixing kinds needs several rules. */
351
+ function singleKind(selectors, side) {
352
+ if (selectors.length === 0)
353
+ throw new NetError('INVALID', `The rule needs a ${side}`);
354
+ const kinds = [...new Set(selectors.map(kindOf))];
355
+ if (kinds.length > 1)
356
+ throw new NetError('INVALID', `Omada takes one kind of ${side} per rule (got ${kinds.join(' and ')}); split it into several rules`);
357
+ if ((kinds[0] === 'internet' || kinds[0] === 'gateway') && selectors.length > 1)
358
+ throw new NetError('INVALID', `Give the ${kinds[0]} once`);
359
+ return kinds[0];
360
+ }
361
+ function sameSelectors(a, b) {
362
+ return JSON.stringify(a) === JSON.stringify(b);
363
+ }
364
+ /** Networks the gateway routes (a switch-only network's traffic never reaches it). */
365
+ function routedNetworks(selectors, world) {
366
+ return selectors.map((s) => {
367
+ const network = resolve(world.networks, s.network, 'network');
368
+ if (network.purpose === 'vlanOnly' || !network.gateway)
369
+ throw new NetError('INVALID', `'${network.name}' is switch-only: its traffic never passes the gateway, so a gateway rule can't apply to it`);
370
+ return network;
371
+ });
372
+ }
373
+ /** Whether addresses are on the site's own networks (LAN→LAN) or beyond them (LAN→WAN). */
374
+ function classify(entries, world, what) {
375
+ const lans = world.networks.filter((n) => n.gateway).map((n) => n.gateway);
376
+ let inside = 0;
377
+ for (const e of entries) {
378
+ const cidr = `${e.ip}/${e.mask}`;
379
+ const range = parseCidr(cidr);
380
+ const within = lans.some((lan) => {
381
+ const l = parseCidr(lan);
382
+ return range.network >= l.network && range.broadcast <= l.broadcast;
383
+ });
384
+ if (within)
385
+ inside++;
386
+ else if (lans.some((lan) => subnetsOverlap(cidr, lan))) {
387
+ throw new NetError('INVALID', `${what}: ${cidr} is partly inside one of your networks; split it into a rule for your networks and one for the internet`);
388
+ }
389
+ }
390
+ if (inside === entries.length)
391
+ return 'lanToLan';
392
+ if (inside === 0)
393
+ return 'lanToWan';
394
+ throw new NetError('INVALID', `${what} mix your own networks and the internet; make one rule for each`);
395
+ }
396
+ /**
397
+ * The rules that may apply to the controller's (and this server's) internet traffic, in
398
+ * the order the gateway checks them: enabled, towards the internet, with a source that
399
+ * may hold the controller (also when that can't be read or its address is unknown),
400
+ * whatever destination, protocol or schedule they name.
401
+ * - `active`: those that can still decide, up to and including the first complete
402
+ * exception (an allow of everything, all protocols, no schedule, Auto states, whose
403
+ * source surely holds the controller); `shadowed`: those after it, which never apply.
404
+ * - `certain`: the first active rule is a complete block that surely holds the
405
+ * controller, so it is cut off today whatever else the list says.
406
+ */
407
+ export function controllerPath(acls, world) {
408
+ const any = world.ipGroups.find((g) => g.name === ANY_GROUP)?.groupId;
409
+ const active = [];
410
+ const shadowed = new Set();
411
+ let ended = false;
412
+ for (const a of acls) {
413
+ if (a.status !== true)
414
+ continue;
415
+ if (a.direction?.lanToWan !== true)
416
+ continue;
417
+ const source = { type: Number(a.sourceType), ids: (a.sourceIds ?? []).map(String), label: '' };
418
+ if (protectedSourceHit(source, world) === undefined)
419
+ continue;
420
+ const description = String(a.description ?? '');
421
+ const entry = { key: blockerKey(a), name: ruleName(description) || description || String(a.id), allow: a.policy === POLICY.allow };
422
+ if (ended) {
423
+ shadowed.add(entry.key);
424
+ continue;
425
+ }
426
+ active.push(entry);
427
+ const toEverything = Number(a.destinationType) === ENDPOINT.ipGroup && (a.destinationIds ?? []).map(String).includes(String(any));
428
+ const complete = toEverything && JSON.stringify(a.protocols) === JSON.stringify([PROTOCOL.any]) && !a.timeRangeId && Number(a.stateMode ?? 0) === 0 && surelyHoldsController(source, world);
429
+ if (complete) {
430
+ if (!entry.allow && active.length === 1)
431
+ return { active, shadowed: new Set(), certain: true };
432
+ if (entry.allow)
433
+ ended = true;
434
+ }
435
+ }
436
+ return { active, shadowed, certain: false };
437
+ }
438
+ /**
439
+ * Why a change would put the controller's internet traffic at risk, or undefined if it
440
+ * can't. Conservative: among the rules that may apply to that traffic, a change may only
441
+ * add allows and remove blocks. A new or changed block, a removed or changed allow, or
442
+ * a different order among them could expose some of its traffic to a block.
443
+ */
444
+ export function controllerRisk(before, after) {
445
+ if (before.certain)
446
+ return undefined; // already cut off: nothing left to protect
447
+ const was = new Map(before.active.map((r) => [r.key, r]));
448
+ const now = new Map(after.active.map((r) => [r.key, r]));
449
+ const block = after.active.find((r) => !r.allow && !was.has(r.key));
450
+ if (block)
451
+ return `rule '${block.name}' would then be in the way of its traffic`;
452
+ const allow = before.active.find((r) => r.allow && !now.has(r.key) && !after.shadowed.has(r.key));
453
+ if (allow)
454
+ return `rule '${allow.name}', which lets some of its traffic through, would be removed or changed`;
455
+ const common = (list, other) => list.filter((r) => other.has(r.key)).map((r) => r.key).join('|');
456
+ if (common(before.active, now) !== common(after.active, was))
457
+ return 'the order of the rules that apply to its traffic would change';
458
+ return undefined;
459
+ }
460
+ function blockerKey(a) {
461
+ const fields = ['id', 'policy', 'protocols', 'sourceType', 'sourceIds', 'destinationType', 'destinationIds', 'direction', 'stateMode', 'timeRangeId'];
462
+ return JSON.stringify(fields.map((f) => a[f] ?? null));
463
+ }
464
+ /** Whether a source certainly includes the controller's (known) address. */
465
+ function surelyHoldsController(source, world) {
466
+ if (world.controllerAddresses === 'unknown' || world.controllerAddresses.length === 0)
467
+ return false;
468
+ const addresses = world.controllerAddresses;
469
+ const ranges = [];
470
+ if (source.type === ENDPOINT.network && 'ids' in source) {
471
+ for (const n of world.networks)
472
+ if (source.ids.includes(n.id) && n.gateway)
473
+ ranges.push(parseCidr(n.gateway));
474
+ }
475
+ else if (source.type === ENDPOINT.ipGroup && 'ids' in source) {
476
+ for (const g of world.ipGroups) {
477
+ if (!source.ids.includes(String(g.groupId)))
478
+ continue;
479
+ for (const e of g.ipList ?? [])
480
+ ranges.push(parseCidr(`${e.ip}/${e.mask}`));
481
+ }
482
+ }
483
+ return addresses.every((a) => ranges.some((r) => a >= r.network && a <= r.broadcast));
484
+ }
485
+ /**
486
+ * The ACL a draft will become, for evaluating rule lists before anything is written: a
487
+ * group the rule will create is added to `world` under a placeholder id.
488
+ */
489
+ export function draftAsAcl(draft, id, world, status = draft.enabled) {
490
+ const extra = [];
491
+ const ids = (e, side) => {
492
+ if ('ids' in e)
493
+ return e.ids;
494
+ const groupId = `${id}:${side}`;
495
+ if (e.newGroup.groupType === GROUP_TYPE.ip)
496
+ extra.push({ groupId, name: `[net:00000000] ${side}`, ...e.newGroup.body });
497
+ return [groupId];
498
+ };
499
+ const acl = {
500
+ id,
501
+ description: draft.name,
502
+ status,
503
+ policy: draft.policy,
504
+ protocols: draft.protocols,
505
+ sourceType: draft.source.type,
506
+ sourceIds: ids(draft.source, 'from'),
507
+ destinationType: draft.destination.type,
508
+ destinationIds: ids(draft.destination, 'to'),
509
+ direction: { lanToWan: draft.direction === 'lanToWan', lanToLan: draft.direction === 'lanToLan', wanInIds: [], vpnInIds: [] },
510
+ stateMode: 0,
511
+ };
512
+ return { acl, world: extra.length ? { ...world, ipGroups: [...world.ipGroups, ...extra] } : world };
513
+ }
514
+ /**
515
+ * What a block-to-internet rule would cut off that must stay reachable, if anything: a
516
+ * whole protected network, or addresses covering the controller (this server runs next
517
+ * to it). One device on that network may be blocked (a curfew does exactly that). When
518
+ * the controller's address is unknown, any address on a protected network counts.
519
+ */
520
+ function protectedSourceHit(source, world) {
521
+ const protectedNets = world.networks.filter((n) => n.protected && n.gateway);
522
+ if (source.type === ENDPOINT.network && 'ids' in source) {
523
+ const hit = protectedNets.find((n) => source.ids.includes(n.id));
524
+ return hit ? `'${hit.name}'` : undefined;
525
+ }
526
+ // Fail closed: a source whose addresses this check can't read may hold the controller.
527
+ if (source.type !== ENDPOINT.ipGroup)
528
+ return 'a source this check cannot read';
529
+ const entries = 'newGroup' in source
530
+ ? source.newGroup.body.ipList
531
+ : source.ids.flatMap((id) => world.ipGroups.find((g) => String(g.groupId) === id)?.ipList ?? []);
532
+ for (const e of entries) {
533
+ const range = parseCidr(`${e.ip}/${e.mask}`);
534
+ if (world.controllerAddresses === 'unknown') {
535
+ const hit = protectedNets.find((n) => subnetsOverlap(`${e.ip}/${e.mask}`, n.gateway));
536
+ if (hit)
537
+ return `devices on '${hit.name}' (${e.ip}/${e.mask}; the controller's address is unknown, so it may be among them)`;
538
+ }
539
+ else if (world.controllerAddresses.some((a) => a >= range.network && a <= range.broadcast)) {
540
+ return `the controller (${e.ip}/${e.mask} includes its address)`;
541
+ }
542
+ }
543
+ return undefined;
544
+ }
545
+ function label(selectors, world) {
546
+ const names = selectors.map((s) => {
547
+ if ('network' in s) {
548
+ const ref = s.network;
549
+ const n = world.networks.find((x) => ('id' in ref ? x.id === ref.id : x.id === ref.name || x.name.toLowerCase() === ref.name.trim().toLowerCase()));
550
+ return n ? n.name : 'id' in ref ? ref.id : ref.name;
551
+ }
552
+ if ('group' in s)
553
+ return `group ${'id' in s.group ? s.group.id : s.group.name}`;
554
+ if ('addresses' in s)
555
+ return s.addresses.join(', ');
556
+ if ('internet' in s)
557
+ return 'the internet';
558
+ return Object.keys(s)[0];
559
+ });
560
+ return names.join(', ');
561
+ }
562
+ /** "a.b.c.d" (= /32) or "a.b.c.d/n", n 1-32. */
563
+ function parseAddress(value) {
564
+ let parsed;
565
+ try {
566
+ parsed = parseCidr(value);
567
+ }
568
+ catch (error) {
569
+ throw new NetError('INVALID', `'${value}': ${error.message}`);
570
+ }
571
+ if (parsed.prefix < 1)
572
+ throw new NetError('INVALID', `'${value}': use { internet: true } for everything`);
573
+ return { ip: parsed.ip.trim(), mask: parsed.prefix };
574
+ }
575
+ /** "1883, 8123" -> ["1883", "8123"]: single ports only (ranges aren't verified on Omada). */
576
+ function parsePorts(value) {
577
+ const ports = value.split(',').map((p) => p.trim()).filter(Boolean);
578
+ if (ports.length === 0)
579
+ throw new NetError('INVALID', 'Give at least one port, e.g. "1883, 8123"');
580
+ if (ports.length > MAX_PORTS)
581
+ throw new NetError('INVALID', `At most ${MAX_PORTS} ports per rule`);
582
+ for (const p of ports) {
583
+ if (p.includes('-'))
584
+ throw unsupported(`port ranges ('${p}') through net_ yet; list single ports`, 'rules.ports');
585
+ if (!/^\d{1,5}$/.test(p) || Number(p) < 1 || Number(p) > 65535)
586
+ throw new NetError('INVALID', `'${p}' is not a port (1-65535)`);
587
+ }
588
+ if (new Set(ports).size !== ports.length)
589
+ throw new NetError('INVALID', 'A port is listed twice');
590
+ return ports.map((p) => String(Number(p)));
591
+ }
592
+ function unsupported(what, capability) {
593
+ return new NetError('UNSUPPORTED', `Omada can't do ${what}`, { capability });
594
+ }
595
+ //# sourceMappingURL=omadaRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"omadaRules.js","sourceRoot":"","sources":["../../../src/net/adapters/omadaRules.ts"],"names":[],"mappings":"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"}