fix(ipsec): исключить чужие сессии при сопоставлении CN
This commit is contained in:
1 parent
2aa93ad365
commit
7815e00a1c
15 files changed
+604
-13
No files matched your search
@@ -304,7 +304,10 @@ export function mapClients(state: IpsecServerState): IpsecClientDto[] {
|
||||
const subject = routerOsCertificateDn(cert)
|
||||
const bySubject = subject && subjectCounts.get(subject) === 1 ? activeByRemote.get(subject) : undefined
|
||||
const uniqueCn = cn && cnCounts.get(cn) === 1
|
||||
const active = (uniqueCn ? findActive(cn) : undefined) ?? bySubject
|
||||
// A literal CN is not a typed remote-id. It may also resemble another
|
||||
// certificate's complete DN, in which case the bare-CN alias is unsafe.
|
||||
const byCommonName = uniqueCn && !subjectCounts.has(cn) ? activeByRemote.get(cn) : undefined
|
||||
const active = bySubject ?? byCommonName
|
||||
?? (identity?.["remote-id"] ? findActive(String(identity["remote-id"]).trim()) : undefined)
|
||||
out.push({
|
||||
id: `${server.id}:${identity ? "identity" : "cert"}:${String(identity?.[".id"] ?? cert[".id"] ?? certName)}`,
|
||||
|
||||
@@ -129,4 +129,27 @@ state.active[0]!.id = 'C=US, S=New York, L=Albany, O=Example, Ltd, OU=QA+Operati
|
||||
assert.equal(mapClients(state).find(c => c.certName === "client")?.online, true); checks++
|
||||
certificate.organization = "bad\nsubject"
|
||||
assert.equal(mapClients(state).find(c => c.certName === "client")?.online, false); checks++
|
||||
const namespaceState = {
|
||||
...state,
|
||||
identities: [],
|
||||
certs: [
|
||||
{ ".id": "*PLAIN", name: "ipsec-user-plain", "common-name": "alice", ca: "ca", "key-usage": "tls-client" },
|
||||
{ ".id": "*DNNAME", name: "ipsec-user-dn-name", "common-name": "CN=alice", ca: "ca", "key-usage": "tls-client" },
|
||||
{ ".id": "*TYPEDNAME", name: "ipsec-user-typed-name", "common-name": "key-id:alice", ca: "ca", "key-usage": "tls-client" },
|
||||
],
|
||||
active: [{ ".id": "*NATIVE", id: "CN=alice", state: "established", "dynamic-address": "198.18.111.250" }],
|
||||
} as typeof state
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-plain")?.online, true); checks++
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-dn-name")?.online, false); checks++
|
||||
namespaceState.active[0]!.id = "alice"
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-plain")?.online, true); checks++
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-typed-name")?.online, false); checks++
|
||||
namespaceState.active[0]!.id = "key-id:alice"
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-typed-name")?.online, true); checks++
|
||||
// Type normalization belongs to an explicitly configured remote ID, not a CN.
|
||||
namespaceState.identities = [{ ".id": "*EXPLICIT", peer: "ike", "auth-method": "digital-signature", "remote-certificate": "ipsec-user-plain", "remote-id": "fqdn:explicit.example", comment: "explicit certificate" }]
|
||||
namespaceState.active[0]!.id = "explicit.example"
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-plain")?.online, true); checks++
|
||||
namespaceState.identities[0]!["remote-id"] = "unknown:explicit.example"
|
||||
assert.equal(mapClients(namespaceState).find(c => c.certName === "ipsec-user-plain")?.online, false); checks++
|
||||
console.log(`ipsec-state: ${checks} checks passed`)
|
||||
Reference in new issue
Block a user