@serve.zone/dcrouter 5.0.2 → 5.0.3
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.
- package/dist_serve/bundle.js +30539 -0
- package/dist_serve/bundle.js.map +7 -0
- package/dist_serve/index.html +1 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/cache/classes.cache.cleaner.d.ts +47 -0
- package/dist_ts/cache/classes.cache.cleaner.js +130 -0
- package/dist_ts/cache/classes.cached.document.d.ts +76 -0
- package/dist_ts/cache/classes.cached.document.js +100 -0
- package/dist_ts/cache/classes.cachedb.d.ts +60 -0
- package/dist_ts/cache/classes.cachedb.js +125 -0
- package/dist_ts/cache/documents/classes.cached.email.d.ts +125 -0
- package/dist_ts/cache/documents/classes.cached.email.js +337 -0
- package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +119 -0
- package/dist_ts/cache/documents/classes.cached.ip.reputation.js +323 -0
- package/dist_ts/cache/documents/index.d.ts +2 -0
- package/dist_ts/cache/documents/index.js +3 -0
- package/dist_ts/cache/index.d.ts +4 -0
- package/dist_ts/cache/index.js +7 -0
- package/dist_ts/classes.dcrouter.d.ts +276 -0
- package/dist_ts/classes.dcrouter.js +1033 -0
- package/dist_ts/config/index.d.ts +1 -0
- package/dist_ts/config/index.js +3 -0
- package/dist_ts/config/validator.d.ts +104 -0
- package/dist_ts/config/validator.js +152 -0
- package/dist_ts/errors/base.errors.d.ts +224 -0
- package/dist_ts/errors/base.errors.js +320 -0
- package/dist_ts/errors/error-handler.d.ts +98 -0
- package/dist_ts/errors/error-handler.js +282 -0
- package/dist_ts/errors/error.codes.d.ts +115 -0
- package/dist_ts/errors/error.codes.js +136 -0
- package/dist_ts/errors/index.d.ts +54 -0
- package/dist_ts/errors/index.js +136 -0
- package/dist_ts/errors/reputation.errors.d.ts +183 -0
- package/dist_ts/errors/reputation.errors.js +292 -0
- package/dist_ts/index.d.ts +6 -0
- package/dist_ts/index.js +9 -0
- package/dist_ts/logger.d.ts +17 -0
- package/dist_ts/logger.js +76 -0
- package/dist_ts/monitoring/classes.metricscache.d.ts +32 -0
- package/dist_ts/monitoring/classes.metricscache.js +63 -0
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +112 -0
- package/dist_ts/monitoring/classes.metricsmanager.js +446 -0
- package/dist_ts/monitoring/index.d.ts +1 -0
- package/dist_ts/monitoring/index.js +2 -0
- package/dist_ts/opsserver/classes.opsserver.d.ts +22 -0
- package/dist_ts/opsserver/classes.opsserver.js +56 -0
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +31 -0
- package/dist_ts/opsserver/handlers/admin.handler.js +180 -0
- package/dist_ts/opsserver/handlers/config.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/config.handler.js +67 -0
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +12 -0
- package/dist_ts/opsserver/handlers/email-ops.handler.js +219 -0
- package/dist_ts/opsserver/handlers/index.d.ts +7 -0
- package/dist_ts/opsserver/handlers/index.js +8 -0
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +10 -0
- package/dist_ts/opsserver/handlers/logs.handler.js +122 -0
- package/dist_ts/opsserver/handlers/radius.handler.d.ts +8 -0
- package/dist_ts/opsserver/handlers/radius.handler.js +296 -0
- package/dist_ts/opsserver/handlers/security.handler.d.ts +11 -0
- package/dist_ts/opsserver/handlers/security.handler.js +217 -0
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +13 -0
- package/dist_ts/opsserver/handlers/stats.handler.js +366 -0
- package/dist_ts/opsserver/helpers/guards.d.ts +25 -0
- package/dist_ts/opsserver/helpers/guards.js +41 -0
- package/dist_ts/opsserver/index.d.ts +1 -0
- package/dist_ts/opsserver/index.js +2 -0
- package/dist_ts/paths.d.ts +14 -0
- package/dist_ts/paths.js +39 -0
- package/dist_ts/plugins.d.ts +78 -0
- package/dist_ts/plugins.js +112 -0
- package/dist_ts/radius/classes.accounting.manager.d.ts +218 -0
- package/dist_ts/radius/classes.accounting.manager.js +417 -0
- package/dist_ts/radius/classes.radius.server.d.ts +171 -0
- package/dist_ts/radius/classes.radius.server.js +385 -0
- package/dist_ts/radius/classes.vlan.manager.d.ts +128 -0
- package/dist_ts/radius/classes.vlan.manager.js +272 -0
- package/dist_ts/radius/index.d.ts +13 -0
- package/dist_ts/radius/index.js +14 -0
- package/dist_ts/security/classes.contentscanner.d.ts +160 -0
- package/dist_ts/security/classes.contentscanner.js +637 -0
- package/dist_ts/security/classes.ipreputationchecker.d.ts +150 -0
- package/dist_ts/security/classes.ipreputationchecker.js +512 -0
- package/dist_ts/security/classes.securitylogger.d.ts +140 -0
- package/dist_ts/security/classes.securitylogger.js +235 -0
- package/dist_ts/security/index.d.ts +3 -0
- package/dist_ts/security/index.js +4 -0
- package/dist_ts/sms/classes.smsservice.d.ts +15 -0
- package/dist_ts/sms/classes.smsservice.js +72 -0
- package/dist_ts/sms/config/sms.config.d.ts +93 -0
- package/dist_ts/sms/config/sms.config.js +2 -0
- package/dist_ts/sms/config/sms.schema.d.ts +5 -0
- package/dist_ts/sms/config/sms.schema.js +121 -0
- package/dist_ts/sms/index.d.ts +1 -0
- package/dist_ts/sms/index.js +2 -0
- package/dist_ts/storage/classes.storagemanager.d.ts +82 -0
- package/dist_ts/storage/classes.storagemanager.js +344 -0
- package/dist_ts/storage/index.d.ts +1 -0
- package/dist_ts/storage/index.js +3 -0
- package/dist_ts_interfaces/data/auth.d.ts +8 -0
- package/dist_ts_interfaces/data/auth.js +2 -0
- package/dist_ts_interfaces/data/index.d.ts +2 -0
- package/dist_ts_interfaces/data/index.js +3 -0
- package/dist_ts_interfaces/data/stats.d.ts +120 -0
- package/dist_ts_interfaces/data/stats.js +2 -0
- package/{ts_interfaces/index.ts → dist_ts_interfaces/index.d.ts} +1 -5
- package/dist_ts_interfaces/index.js +8 -0
- package/{ts_interfaces/plugins.ts → dist_ts_interfaces/plugins.d.ts} +1 -5
- package/dist_ts_interfaces/plugins.js +4 -0
- package/dist_ts_interfaces/requests/admin.d.ts +31 -0
- package/dist_ts_interfaces/requests/admin.js +3 -0
- package/dist_ts_interfaces/requests/combined.stats.d.ts +24 -0
- package/dist_ts_interfaces/requests/combined.stats.js +2 -0
- package/dist_ts_interfaces/requests/config.d.ts +13 -0
- package/dist_ts_interfaces/requests/config.js +3 -0
- package/dist_ts_interfaces/requests/email-ops.d.ts +139 -0
- package/dist_ts_interfaces/requests/email-ops.js +3 -0
- package/{ts_interfaces/requests/index.ts → dist_ts_interfaces/requests/index.d.ts} +1 -1
- package/dist_ts_interfaces/requests/index.js +8 -0
- package/dist_ts_interfaces/requests/logs.d.ts +34 -0
- package/dist_ts_interfaces/requests/logs.js +4 -0
- package/dist_ts_interfaces/requests/radius.d.ts +268 -0
- package/dist_ts_interfaces/requests/radius.js +3 -0
- package/dist_ts_interfaces/requests/stats.d.ts +131 -0
- package/dist_ts_interfaces/requests/stats.js +4 -0
- package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
- package/dist_ts_web/00_commitinfo_data.js +9 -0
- package/dist_ts_web/appstate.d.ts +96 -0
- package/dist_ts_web/appstate.js +587 -0
- package/dist_ts_web/elements/index.d.ts +8 -0
- package/dist_ts_web/elements/index.js +9 -0
- package/dist_ts_web/elements/ops-dashboard.d.ts +23 -0
- package/dist_ts_web/elements/ops-dashboard.js +271 -0
- package/dist_ts_web/elements/ops-view-config.d.ts +17 -0
- package/dist_ts_web/elements/ops-view-config.js +414 -0
- package/dist_ts_web/elements/ops-view-emails.d.ts +44 -0
- package/dist_ts_web/elements/ops-view-emails.js +880 -0
- package/dist_ts_web/elements/ops-view-logs.d.ts +13 -0
- package/dist_ts_web/elements/ops-view-logs.js +249 -0
- package/dist_ts_web/elements/ops-view-network.d.ts +65 -0
- package/dist_ts_web/elements/ops-view-network.js +579 -0
- package/dist_ts_web/elements/ops-view-overview.d.ts +14 -0
- package/dist_ts_web/elements/ops-view-overview.js +344 -0
- package/dist_ts_web/elements/ops-view-security.d.ts +21 -0
- package/dist_ts_web/elements/ops-view-security.js +568 -0
- package/dist_ts_web/elements/shared/css.d.ts +1 -0
- package/dist_ts_web/elements/shared/css.js +10 -0
- package/dist_ts_web/elements/shared/index.d.ts +2 -0
- package/dist_ts_web/elements/shared/index.js +3 -0
- package/dist_ts_web/elements/shared/ops-sectionheading.d.ts +5 -0
- package/dist_ts_web/elements/shared/ops-sectionheading.js +82 -0
- package/dist_ts_web/index.d.ts +1 -0
- package/dist_ts_web/index.js +10 -0
- package/dist_ts_web/plugins.d.ts +4 -0
- package/dist_ts_web/plugins.js +7 -0
- package/dist_ts_web/router.d.ts +25 -0
- package/dist_ts_web/router.js +165 -0
- package/package.json +14 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/.dockerignore +0 -1
- package/.gitea/workflows/docker_nottags.yaml +0 -71
- package/.gitea/workflows/docker_tags.yaml +0 -106
- package/.playwright-mcp/dcrouter-scrollbar-issue.png +0 -0
- package/.playwright-mcp/page-2026-02-01T23-10-23-737Z.png +0 -0
- package/.playwright-mcp/page-2026-02-01T23-11-19-449Z.png +0 -0
- package/.playwright-mcp/page-2026-02-01T23-12-03-126Z.png +0 -0
- package/.playwright-mcp/page-2026-02-01T23-12-15-576Z.png +0 -0
- package/.vscode/launch.json +0 -11
- package/.vscode/settings.json +0 -26
- package/Dockerfile +0 -46
- package/changelog.md +0 -350
- package/cli.child.js +0 -4
- package/cli.child.ts +0 -4
- package/cli.ts.js +0 -5
- package/html/index.html +0 -121
- package/test/readme.md +0 -443
- package/test/test.config.md +0 -175
- package/test/test.contentscanner.ts +0 -265
- package/test/test.dcrouter.email.ts +0 -159
- package/test/test.dns-server-config.ts +0 -140
- package/test/test.dns-socket-handler.ts +0 -148
- package/test/test.errors.ts +0 -274
- package/test/test.ipreputationchecker.ts +0 -179
- package/test/test.jwt-auth.ts +0 -131
- package/test/test.opsserver-api.ts +0 -84
- package/test/test.protected-endpoint.ts +0 -120
- package/test/test.storagemanager.ts +0 -289
- package/test_watch/devserver.ts +0 -35
- package/ts_interfaces/data/auth.ts +0 -8
- package/ts_interfaces/data/index.ts +0 -2
- package/ts_interfaces/data/stats.ts +0 -131
- package/ts_interfaces/readme.md +0 -205
- package/ts_interfaces/requests/admin.ts +0 -46
- package/ts_interfaces/requests/combined.stats.ts +0 -25
- package/ts_interfaces/requests/config.ts +0 -18
- package/ts_interfaces/requests/email-ops.ts +0 -239
- package/ts_interfaces/requests/logs.ts +0 -44
- package/ts_interfaces/requests/radius.ts +0 -329
- package/ts_interfaces/requests/stats.ts +0 -162
- package/ts_interfaces/tspublish.json +0 -3
- package/tsconfig.json +0 -12
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages MAC address to VLAN mappings with support for:
|
|
5
|
+
* - Exact MAC address matching
|
|
6
|
+
* - OUI (vendor prefix) pattern matching
|
|
7
|
+
* - Wildcard patterns
|
|
8
|
+
* - Default VLAN for unknown devices
|
|
9
|
+
*/
|
|
10
|
+
export class VlanManager {
|
|
11
|
+
mappings = new Map();
|
|
12
|
+
config;
|
|
13
|
+
storageManager;
|
|
14
|
+
// Cache for normalized MAC lookups
|
|
15
|
+
normalizedMacCache = new Map();
|
|
16
|
+
constructor(config, storageManager) {
|
|
17
|
+
this.config = {
|
|
18
|
+
defaultVlan: config?.defaultVlan ?? 1,
|
|
19
|
+
allowUnknownMacs: config?.allowUnknownMacs ?? true,
|
|
20
|
+
storagePrefix: config?.storagePrefix ?? '/radius/vlan-mappings',
|
|
21
|
+
};
|
|
22
|
+
this.storageManager = storageManager;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the VLAN manager and load persisted mappings
|
|
26
|
+
*/
|
|
27
|
+
async initialize() {
|
|
28
|
+
if (this.storageManager) {
|
|
29
|
+
await this.loadMappings();
|
|
30
|
+
}
|
|
31
|
+
logger.log('info', `VlanManager initialized with ${this.mappings.size} mappings, default VLAN: ${this.config.defaultVlan}`);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Normalize a MAC address to lowercase with colons
|
|
35
|
+
* Accepts formats: 00:11:22:33:44:55, 00-11-22-33-44-55, 001122334455
|
|
36
|
+
*/
|
|
37
|
+
normalizeMac(mac) {
|
|
38
|
+
// Check cache first
|
|
39
|
+
const cached = this.normalizedMacCache.get(mac);
|
|
40
|
+
if (cached) {
|
|
41
|
+
return cached;
|
|
42
|
+
}
|
|
43
|
+
// Remove all separators and convert to lowercase
|
|
44
|
+
const cleaned = mac.toLowerCase().replace(/[-:]/g, '');
|
|
45
|
+
// Format with colons
|
|
46
|
+
const normalized = cleaned.match(/.{1,2}/g)?.join(':') || mac.toLowerCase();
|
|
47
|
+
// Cache the result
|
|
48
|
+
this.normalizedMacCache.set(mac, normalized);
|
|
49
|
+
return normalized;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if a MAC address matches a pattern
|
|
53
|
+
* Supports:
|
|
54
|
+
* - Exact match: "00:11:22:33:44:55"
|
|
55
|
+
* - OUI match: "00:11:22" (matches any device with this vendor prefix)
|
|
56
|
+
* - Wildcard: "*" (matches all)
|
|
57
|
+
*/
|
|
58
|
+
macMatchesPattern(mac, pattern) {
|
|
59
|
+
const normalizedMac = this.normalizeMac(mac);
|
|
60
|
+
const normalizedPattern = this.normalizeMac(pattern);
|
|
61
|
+
// Wildcard matches all
|
|
62
|
+
if (pattern === '*') {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// Exact match
|
|
66
|
+
if (normalizedMac === normalizedPattern) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// OUI/prefix match (pattern is shorter than full MAC)
|
|
70
|
+
if (normalizedPattern.length < 17 && normalizedMac.startsWith(normalizedPattern)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Add or update a MAC to VLAN mapping
|
|
77
|
+
*/
|
|
78
|
+
async addMapping(mapping) {
|
|
79
|
+
const normalizedMac = this.normalizeMac(mapping.mac);
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
const existingMapping = this.mappings.get(normalizedMac);
|
|
82
|
+
const fullMapping = {
|
|
83
|
+
...mapping,
|
|
84
|
+
mac: normalizedMac,
|
|
85
|
+
createdAt: existingMapping?.createdAt || now,
|
|
86
|
+
updatedAt: now,
|
|
87
|
+
};
|
|
88
|
+
this.mappings.set(normalizedMac, fullMapping);
|
|
89
|
+
// Persist to storage
|
|
90
|
+
if (this.storageManager) {
|
|
91
|
+
await this.saveMappings();
|
|
92
|
+
}
|
|
93
|
+
logger.log('info', `VLAN mapping ${existingMapping ? 'updated' : 'added'}: ${normalizedMac} -> VLAN ${mapping.vlan}`);
|
|
94
|
+
return fullMapping;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Remove a MAC to VLAN mapping
|
|
98
|
+
*/
|
|
99
|
+
async removeMapping(mac) {
|
|
100
|
+
const normalizedMac = this.normalizeMac(mac);
|
|
101
|
+
const removed = this.mappings.delete(normalizedMac);
|
|
102
|
+
if (removed && this.storageManager) {
|
|
103
|
+
await this.saveMappings();
|
|
104
|
+
logger.log('info', `VLAN mapping removed: ${normalizedMac}`);
|
|
105
|
+
}
|
|
106
|
+
return removed;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get a specific mapping by MAC
|
|
110
|
+
*/
|
|
111
|
+
getMapping(mac) {
|
|
112
|
+
return this.mappings.get(this.normalizeMac(mac));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get all mappings
|
|
116
|
+
*/
|
|
117
|
+
getAllMappings() {
|
|
118
|
+
return Array.from(this.mappings.values());
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Determine VLAN assignment for a MAC address
|
|
122
|
+
* Returns the most specific matching rule (exact > OUI > wildcard > default)
|
|
123
|
+
*/
|
|
124
|
+
assignVlan(mac) {
|
|
125
|
+
const normalizedMac = this.normalizeMac(mac);
|
|
126
|
+
// First, try exact match
|
|
127
|
+
const exactMatch = this.mappings.get(normalizedMac);
|
|
128
|
+
if (exactMatch && exactMatch.enabled) {
|
|
129
|
+
return {
|
|
130
|
+
assigned: true,
|
|
131
|
+
vlan: exactMatch.vlan,
|
|
132
|
+
matchedRule: exactMatch,
|
|
133
|
+
isDefault: false,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// Try OUI/prefix matches (sorted by specificity - longer patterns first)
|
|
137
|
+
const patternMatches = [];
|
|
138
|
+
for (const mapping of this.mappings.values()) {
|
|
139
|
+
if (mapping.enabled && mapping.mac !== normalizedMac && this.macMatchesPattern(normalizedMac, mapping.mac)) {
|
|
140
|
+
patternMatches.push(mapping);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Sort by pattern length (most specific first)
|
|
144
|
+
patternMatches.sort((a, b) => b.mac.length - a.mac.length);
|
|
145
|
+
if (patternMatches.length > 0) {
|
|
146
|
+
const bestMatch = patternMatches[0];
|
|
147
|
+
return {
|
|
148
|
+
assigned: true,
|
|
149
|
+
vlan: bestMatch.vlan,
|
|
150
|
+
matchedRule: bestMatch,
|
|
151
|
+
isDefault: false,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// No match - use default VLAN if allowed
|
|
155
|
+
if (this.config.allowUnknownMacs) {
|
|
156
|
+
return {
|
|
157
|
+
assigned: true,
|
|
158
|
+
vlan: this.config.defaultVlan,
|
|
159
|
+
isDefault: true,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// Unknown MAC and not allowed
|
|
163
|
+
return {
|
|
164
|
+
assigned: false,
|
|
165
|
+
vlan: 0,
|
|
166
|
+
isDefault: false,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Bulk import mappings
|
|
171
|
+
*/
|
|
172
|
+
async importMappings(mappings) {
|
|
173
|
+
let imported = 0;
|
|
174
|
+
for (const mapping of mappings) {
|
|
175
|
+
await this.addMapping(mapping);
|
|
176
|
+
imported++;
|
|
177
|
+
}
|
|
178
|
+
logger.log('info', `Imported ${imported} VLAN mappings`);
|
|
179
|
+
return imported;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Export all mappings
|
|
183
|
+
*/
|
|
184
|
+
exportMappings() {
|
|
185
|
+
return this.getAllMappings();
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Update configuration
|
|
189
|
+
*/
|
|
190
|
+
updateConfig(config) {
|
|
191
|
+
if (config.defaultVlan !== undefined) {
|
|
192
|
+
this.config.defaultVlan = config.defaultVlan;
|
|
193
|
+
}
|
|
194
|
+
if (config.allowUnknownMacs !== undefined) {
|
|
195
|
+
this.config.allowUnknownMacs = config.allowUnknownMacs;
|
|
196
|
+
}
|
|
197
|
+
logger.log('info', `VlanManager config updated: defaultVlan=${this.config.defaultVlan}, allowUnknown=${this.config.allowUnknownMacs}`);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get current configuration
|
|
201
|
+
*/
|
|
202
|
+
getConfig() {
|
|
203
|
+
return { ...this.config };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get statistics
|
|
207
|
+
*/
|
|
208
|
+
getStats() {
|
|
209
|
+
let exactMatches = 0;
|
|
210
|
+
let ouiPatterns = 0;
|
|
211
|
+
let wildcardPatterns = 0;
|
|
212
|
+
let enabledMappings = 0;
|
|
213
|
+
for (const mapping of this.mappings.values()) {
|
|
214
|
+
if (mapping.enabled) {
|
|
215
|
+
enabledMappings++;
|
|
216
|
+
}
|
|
217
|
+
if (mapping.mac === '*') {
|
|
218
|
+
wildcardPatterns++;
|
|
219
|
+
}
|
|
220
|
+
else if (mapping.mac.length < 17) {
|
|
221
|
+
// OUI patterns are shorter than full MAC (17 chars with colons)
|
|
222
|
+
ouiPatterns++;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
exactMatches++;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
totalMappings: this.mappings.size,
|
|
230
|
+
enabledMappings,
|
|
231
|
+
exactMatches,
|
|
232
|
+
ouiPatterns,
|
|
233
|
+
wildcardPatterns,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Load mappings from storage
|
|
238
|
+
*/
|
|
239
|
+
async loadMappings() {
|
|
240
|
+
if (!this.storageManager) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const data = await this.storageManager.getJSON(this.config.storagePrefix);
|
|
245
|
+
if (data && Array.isArray(data)) {
|
|
246
|
+
for (const mapping of data) {
|
|
247
|
+
this.mappings.set(this.normalizeMac(mapping.mac), mapping);
|
|
248
|
+
}
|
|
249
|
+
logger.log('info', `Loaded ${data.length} VLAN mappings from storage`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
logger.log('warn', `Failed to load VLAN mappings from storage: ${error.message}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Save mappings to storage
|
|
258
|
+
*/
|
|
259
|
+
async saveMappings() {
|
|
260
|
+
if (!this.storageManager) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const mappings = Array.from(this.mappings.values());
|
|
265
|
+
await this.storageManager.setJSON(this.config.storagePrefix, mappings);
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
logger.log('error', `Failed to save VLAN mappings to storage: ${error.message}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy52bGFuLm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9yYWRpdXMvY2xhc3Nlcy52bGFuLm1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQStDdEM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFDZCxRQUFRLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQsTUFBTSxDQUErQjtJQUNyQyxjQUFjLENBQWtCO0lBRXhDLG1DQUFtQztJQUMzQixrQkFBa0IsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUU1RCxZQUFZLE1BQTJCLEVBQUUsY0FBK0I7UUFDdEUsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNaLFdBQVcsRUFBRSxNQUFNLEVBQUUsV0FBVyxJQUFJLENBQUM7WUFDckMsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixJQUFJLElBQUk7WUFDbEQsYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLElBQUksdUJBQXVCO1NBQ2hFLENBQUM7UUFDRixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsVUFBVTtRQUNkLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzVCLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxnQ0FBZ0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLDRCQUE0QixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDOUgsQ0FBQztJQUVEOzs7T0FHRztJQUNILFlBQVksQ0FBQyxHQUFXO1FBQ3RCLG9CQUFvQjtR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
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RADIUS module for DcRouter
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - MAC Authentication Bypass (MAB) for network device authentication
|
|
6
|
+
* - VLAN assignment based on MAC addresses
|
|
7
|
+
* - OUI (vendor prefix) pattern matching for device categorization
|
|
8
|
+
* - RADIUS accounting for session tracking and billing
|
|
9
|
+
* - Integration with StorageManager for persistence
|
|
10
|
+
*/
|
|
11
|
+
export * from './classes.radius.server.js';
|
|
12
|
+
export * from './classes.vlan.manager.js';
|
|
13
|
+
export * from './classes.accounting.manager.js';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RADIUS module for DcRouter
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - MAC Authentication Bypass (MAB) for network device authentication
|
|
6
|
+
* - VLAN assignment based on MAC addresses
|
|
7
|
+
* - OUI (vendor prefix) pattern matching for device categorization
|
|
8
|
+
* - RADIUS accounting for session tracking and billing
|
|
9
|
+
* - Integration with StorageManager for persistence
|
|
10
|
+
*/
|
|
11
|
+
export * from './classes.radius.server.js';
|
|
12
|
+
export * from './classes.vlan.manager.js';
|
|
13
|
+
export * from './classes.accounting.manager.js';
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9yYWRpdXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsaUNBQWlDLENBQUMifQ==
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Email } from '@push.rocks/smartmta';
|
|
2
|
+
/**
|
|
3
|
+
* Scan result information
|
|
4
|
+
*/
|
|
5
|
+
export interface IScanResult {
|
|
6
|
+
isClean: boolean;
|
|
7
|
+
threatType?: string;
|
|
8
|
+
threatDetails?: string;
|
|
9
|
+
threatScore: number;
|
|
10
|
+
scannedElements: string[];
|
|
11
|
+
timestamp: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Options for content scanner configuration
|
|
15
|
+
*/
|
|
16
|
+
export interface IContentScannerOptions {
|
|
17
|
+
maxCacheSize?: number;
|
|
18
|
+
cacheTTL?: number;
|
|
19
|
+
scanSubject?: boolean;
|
|
20
|
+
scanBody?: boolean;
|
|
21
|
+
scanAttachments?: boolean;
|
|
22
|
+
maxAttachmentSizeToScan?: number;
|
|
23
|
+
scanAttachmentNames?: boolean;
|
|
24
|
+
blockExecutables?: boolean;
|
|
25
|
+
blockMacros?: boolean;
|
|
26
|
+
customRules?: Array<{
|
|
27
|
+
pattern: string | RegExp;
|
|
28
|
+
type: string;
|
|
29
|
+
score: number;
|
|
30
|
+
description: string;
|
|
31
|
+
}>;
|
|
32
|
+
minThreatScore?: number;
|
|
33
|
+
highThreatScore?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Threat categories
|
|
37
|
+
*/
|
|
38
|
+
export declare enum ThreatCategory {
|
|
39
|
+
SPAM = "spam",
|
|
40
|
+
PHISHING = "phishing",
|
|
41
|
+
MALWARE = "malware",
|
|
42
|
+
EXECUTABLE = "executable",
|
|
43
|
+
SUSPICIOUS_LINK = "suspicious_link",
|
|
44
|
+
MALICIOUS_MACRO = "malicious_macro",
|
|
45
|
+
XSS = "xss",
|
|
46
|
+
SENSITIVE_DATA = "sensitive_data",
|
|
47
|
+
BLACKLISTED_CONTENT = "blacklisted_content",
|
|
48
|
+
CUSTOM_RULE = "custom_rule"
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Content Scanner for detecting malicious email content
|
|
52
|
+
*/
|
|
53
|
+
export declare class ContentScanner {
|
|
54
|
+
private static instance;
|
|
55
|
+
private scanCache;
|
|
56
|
+
private options;
|
|
57
|
+
private static readonly MALICIOUS_PATTERNS;
|
|
58
|
+
private static readonly EXECUTABLE_EXTENSIONS;
|
|
59
|
+
private static readonly MACRO_DOCUMENT_EXTENSIONS;
|
|
60
|
+
/**
|
|
61
|
+
* Default options for the content scanner
|
|
62
|
+
*/
|
|
63
|
+
private static readonly DEFAULT_OPTIONS;
|
|
64
|
+
/**
|
|
65
|
+
* Constructor for the ContentScanner
|
|
66
|
+
* @param options Configuration options
|
|
67
|
+
*/
|
|
68
|
+
constructor(options?: IContentScannerOptions);
|
|
69
|
+
/**
|
|
70
|
+
* Get the singleton instance of the scanner
|
|
71
|
+
* @param options Configuration options
|
|
72
|
+
* @returns Singleton scanner instance
|
|
73
|
+
*/
|
|
74
|
+
static getInstance(options?: IContentScannerOptions): ContentScanner;
|
|
75
|
+
/**
|
|
76
|
+
* Scan an email for malicious content
|
|
77
|
+
* @param email The email to scan
|
|
78
|
+
* @returns Scan result
|
|
79
|
+
*/
|
|
80
|
+
scanEmail(email: Email): Promise<IScanResult>;
|
|
81
|
+
/**
|
|
82
|
+
* Generate a cache key from an email
|
|
83
|
+
* @param email The email to generate a key for
|
|
84
|
+
* @returns Cache key
|
|
85
|
+
*/
|
|
86
|
+
private generateCacheKey;
|
|
87
|
+
/**
|
|
88
|
+
* Scan email subject for threats
|
|
89
|
+
* @param subject The subject to scan
|
|
90
|
+
* @param result The scan result to update
|
|
91
|
+
*/
|
|
92
|
+
private scanSubject;
|
|
93
|
+
/**
|
|
94
|
+
* Scan plain text content for threats
|
|
95
|
+
* @param text The text content to scan
|
|
96
|
+
* @param result The scan result to update
|
|
97
|
+
*/
|
|
98
|
+
private scanTextContent;
|
|
99
|
+
/**
|
|
100
|
+
* Scan HTML content for threats
|
|
101
|
+
* @param html The HTML content to scan
|
|
102
|
+
* @param result The scan result to update
|
|
103
|
+
*/
|
|
104
|
+
private scanHtmlContent;
|
|
105
|
+
/**
|
|
106
|
+
* Scan an attachment for threats
|
|
107
|
+
* @param attachment The attachment to scan
|
|
108
|
+
* @param result The scan result to update
|
|
109
|
+
*/
|
|
110
|
+
private scanAttachment;
|
|
111
|
+
/**
|
|
112
|
+
* Extract links from HTML content
|
|
113
|
+
* @param html HTML content
|
|
114
|
+
* @returns Array of extracted links
|
|
115
|
+
*/
|
|
116
|
+
private extractLinksFromHtml;
|
|
117
|
+
/**
|
|
118
|
+
* Extract plain text from HTML
|
|
119
|
+
* @param html HTML content
|
|
120
|
+
* @returns Extracted text
|
|
121
|
+
*/
|
|
122
|
+
private extractTextFromHtml;
|
|
123
|
+
/**
|
|
124
|
+
* Extract text from a binary buffer for scanning
|
|
125
|
+
* @param buffer Binary content
|
|
126
|
+
* @returns Extracted text (may be partial)
|
|
127
|
+
*/
|
|
128
|
+
private extractTextFromBuffer;
|
|
129
|
+
/**
|
|
130
|
+
* Check if an Office document likely contains macros
|
|
131
|
+
* This is a simplified check - real implementation would use specialized libraries
|
|
132
|
+
* @param attachment The attachment to check
|
|
133
|
+
* @returns Whether the file likely contains macros
|
|
134
|
+
*/
|
|
135
|
+
private likelyContainsMacros;
|
|
136
|
+
/**
|
|
137
|
+
* Map a pattern category to a threat type
|
|
138
|
+
* @param category The pattern category
|
|
139
|
+
* @returns The corresponding threat type
|
|
140
|
+
*/
|
|
141
|
+
private mapCategoryToThreatType;
|
|
142
|
+
/**
|
|
143
|
+
* Log a high threat finding to the security logger
|
|
144
|
+
* @param email The email containing the threat
|
|
145
|
+
* @param result The scan result
|
|
146
|
+
*/
|
|
147
|
+
private logHighThreatFound;
|
|
148
|
+
/**
|
|
149
|
+
* Log a threat finding to the security logger
|
|
150
|
+
* @param email The email containing the threat
|
|
151
|
+
* @param result The scan result
|
|
152
|
+
*/
|
|
153
|
+
private logThreatFound;
|
|
154
|
+
/**
|
|
155
|
+
* Get threat level description based on score
|
|
156
|
+
* @param score Threat score
|
|
157
|
+
* @returns Threat level description
|
|
158
|
+
*/
|
|
159
|
+
static getThreatLevel(score: number): 'none' | 'low' | 'medium' | 'high';
|
|
160
|
+
}
|