From 8a6316228e898008cbf22c8292cd110d87578a76 Mon Sep 17 00:00:00 2001 From: "Franc[e]sco" Date: Thu, 4 Jun 2020 19:39:07 +0000 Subject: [PATCH] Add external sasl with with key/cert (tested on freenode) --- config.sample.yaml | 14 +++++++++++++- config.schema.yml | 6 ++++++ package.json | 2 +- src/irc/ConnectionInstance.ts | 12 ++++++++++-- src/irc/IrcServer.ts | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/config.sample.yaml b/config.sample.yaml index 184443cb5..e5c14ea08 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -74,6 +74,8 @@ ircService: # Should the connection attempt to identify via SASL (if a server or user password is given) # If false, this will use PASS instead. If SASL fails, we do not fallback to PASS. sasl: false + # Sasl authentication type. EXTERNAL or PLAIN are supported at the moment. + saslType: "PLAIN" # Whether to allow expired certs when connecting to the IRC server. # Usually this should be off. Default: false. allowExpiredCerts: false @@ -82,7 +84,17 @@ ircService: # -----BEGIN CERTIFICATE----- # ... # -----END CERTIFICATE----- - + # + # Explicit key/cert to use when connecting. Optional. + # When setting up with https://freenode.net/kb/answer/certfp , you can copy these from the .pem file + #key: | + # -----BEGIN PRIVATE KEY----- + # ... + # -----END PRIVATE KEY----- + #cert: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- # # The connection password to send for all clients as a PASS (or SASL, if enabled above) command. Optional. # password: 'pa$$w0rd' diff --git a/config.schema.yml b/config.schema.yml index 09b4a2c68..0e4731770 100644 --- a/config.schema.yml +++ b/config.schema.yml @@ -154,6 +154,12 @@ properties: type: "boolean" sasl: type: "boolean" + saslType: + type: "string" + key: + type: "string" + cert: + type: "string" allowExpiredCerts: type: "boolean" password: diff --git a/package.json b/package.json index 52067fcf5..d61bc7ff7 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "extend": "^2.0.0", "he": "^1.1.1", "iconv": "^2.3.4", - "irc": "matrix-org/node-irc#9028c2197c216dd8e6fc2cb3cc07ce2d6bf741a7", + "irc": "matrix-org/node-irc#f222abe47897044aef89ee568e7edcb6b6260828", "js-yaml": "^3.2.7", "logform": "^2.1.2", "matrix-appservice": "^0.4.1", diff --git a/src/irc/ConnectionInstance.ts b/src/irc/ConnectionInstance.ts index 2ce6ab993..4a1eb3ece 100644 --- a/src/irc/ConnectionInstance.ts +++ b/src/irc/ConnectionInstance.ts @@ -73,6 +73,8 @@ export interface ConnectionOpts { nick: string; secure?: { ca?: string; + key?: string; + cert?: string; }; encodingFallback: string; } @@ -368,6 +370,9 @@ export class ConnectionInstance { if (!opts.nick || !server) { throw new Error("Bad inputs. Nick: " + opts.nick); } + if (!opts.password && server.saslType() !== "EXTERNAL") { + throw new Error("Using sasl with no password is invalid"); + } const connectionOpts = { userName: opts.username, realName: opts.realname, @@ -383,8 +388,11 @@ export class ConnectionInstance { retryCount: 0, family: server.getIpv6Prefix() || server.getIpv6Only() ? 6 : null, bustRfc3484: true, - sasl: opts.password ? server.useSasl() : false, - secure: server.useSsl() ? { ca: server.getCA() } : undefined, + sasl: server.useSasl(), + saslType: server.saslType(), + secure: server.useSsl() ? { + ca: server.getCA(), key: server.getKey(), cert: server.getCert() + } : undefined, encodingFallback: opts.encodingFallback }; diff --git a/src/irc/IrcServer.ts b/src/irc/IrcServer.ts index 5dca18c35..738d42d9d 100644 --- a/src/irc/IrcServer.ts +++ b/src/irc/IrcServer.ts @@ -229,6 +229,14 @@ export class IrcServer { return this.config.ca; } + public getKey() { + return this.config.key; + } + + public getCert() { + return this.config.cert; + } + public useSsl() { return Boolean(this.config.ssl); } @@ -241,6 +249,10 @@ export class IrcServer { return Boolean(this.config.sasl); } + public saslType() { + return this.config.saslType; + } + public allowExpiredCerts() { return Boolean(this.config.allowExpiredCerts); } @@ -634,10 +646,13 @@ export interface IrcServerConfig { port?: number; icon?: string; ca?: string; + key?: string; + cert?: string; networkId?: string; ssl?: boolean; sslselfsign?: boolean; sasl?: boolean; + saslType?: string; password?: string; allowExpiredCerts?: boolean; additionalAddresses?: string[];