From 63bc5e4161b212b6895ee26a4cca054a5736282f Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 18 Sep 2018 11:31:11 -0400 Subject: [PATCH] ssl options for ldap --- src/app/tabs/settings.component.html | 32 ++++++++++++++++++++++---- src/app/tabs/settings.component.ts | 18 +++++++++++++-- src/locales/en/messages.json | 15 ++++++++++++ src/models/ldapConfiguration.ts | 6 +++-- src/services/ldap-directory.service.ts | 29 ++++++++++++++++++++--- 5 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/app/tabs/settings.component.html b/src/app/tabs/settings.component.html index 883f257b..5536a03f 100644 --- a/src/app/tabs/settings.component.html +++ b/src/app/tabs/settings.component.html @@ -27,14 +27,38 @@
- - + +
- - + + +
+
+
+

{{'ldapSslUntrustedDesc' | i18n}}

+
+ + + +
+
+ + + +
+
+ + + +
+
+
+ + +
diff --git a/src/app/tabs/settings.component.ts b/src/app/tabs/settings.component.ts index eacbaecd..548d1308 100644 --- a/src/app/tabs/settings.component.ts +++ b/src/app/tabs/settings.component.ts @@ -111,7 +111,7 @@ export class SettingsComponent implements OnInit, OnDestroy { await this.configurationService.saveSync(this.sync); } - async parseKeyFile() { + parseKeyFile() { const filePicker = (document.getElementById('keyFile') as HTMLInputElement); if (filePicker.files == null || filePicker.files.length < 0) { return; @@ -122,7 +122,7 @@ export class SettingsComponent implements OnInit, OnDestroy { reader.onload = (evt) => { this.ngZone.run(async () => { try { - const result = JSON.parse((evt.target as FileReader).result); + const result = JSON.parse((evt.target as FileReader).result as string); if (result.client_email != null && result.private_key != null) { this.gsuite.clientEmail = result.client_email; this.gsuite.privateKey = result.private_key; @@ -138,4 +138,18 @@ export class SettingsComponent implements OnInit, OnDestroy { filePicker.value = ''; }; } + + setSslPath(id: string) { + const filePicker = (document.getElementById(id + '_file') as HTMLInputElement); + if (filePicker.files == null || filePicker.files.length < 0) { + return; + } + + (this.ldap as any)[id] = filePicker.files[0].path; + // reset file input + // ref: https://stackoverflow.com/a/20552042 + filePicker.type = ''; + filePicker.type = 'file'; + filePicker.value = ''; + } } diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index dbb02027..b4900c75 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -417,6 +417,21 @@ "ldapSsl": { "message": "This server uses SSL (LDAPS)" }, + "ldapSslUntrustedDesc": { + "message": "If your LDAPS server uses an untrusted certificate you can configure certificate options below." + }, + "ldapSslCa": { + "message": "Certificate CA Chain (PEM)" + }, + "ldapSslCert": { + "message": "Certificate (PEM)" + }, + "ldapSslKey": { + "message": "Certificate Private Key (PEM)" + }, + "ldapSslAllowUnauthorized": { + "message": "Allow untrusted SSL connections (not recommended)." + }, "ldapAd": { "message": "This server uses Active Directory" }, diff --git a/src/models/ldapConfiguration.ts b/src/models/ldapConfiguration.ts index d853acfe..2060d81e 100644 --- a/src/models/ldapConfiguration.ts +++ b/src/models/ldapConfiguration.ts @@ -1,7 +1,9 @@ -import { DirectoryType } from '../enums/directoryType'; - export class LdapConfiguration { ssl = false; + sslAllowUnauthorized = false; + sslCertPath: string; + sslKeyPath: string; + sslCaPath: string; hostname: string; port = 389; domain: string; diff --git a/src/services/ldap-directory.service.ts b/src/services/ldap-directory.service.ts index 50fe88e5..aecabdce 100644 --- a/src/services/ldap-directory.service.ts +++ b/src/services/ldap-directory.service.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs'; import * as ldap from 'ldapjs'; import { DirectoryType } from '../enums/directoryType'; @@ -326,10 +327,32 @@ export class LdapDirectoryService implements DirectoryService { const url = 'ldap' + (this.dirConfig.ssl ? 's' : '') + '://' + this.dirConfig.hostname + ':' + this.dirConfig.port; - - this.client = ldap.createClient({ + const options: ldap.ClientOptions = { url: url.trim().toLowerCase(), - }); + }; + if (this.dirConfig.ssl) { + const tlsOptions: any = {}; + if (this.dirConfig.sslAllowUnauthorized != null) { + tlsOptions.rejectUnauthorized = !this.dirConfig.sslAllowUnauthorized; + } + if (this.dirConfig.sslCaPath != null && this.dirConfig.sslCaPath !== '' && + fs.existsSync(this.dirConfig.sslCaPath)) { + tlsOptions.ca = [fs.readFileSync(this.dirConfig.sslCaPath)]; + } + if (this.dirConfig.sslCertPath != null && this.dirConfig.sslCertPath !== '' && + fs.existsSync(this.dirConfig.sslCertPath)) { + tlsOptions.cert = fs.readFileSync(this.dirConfig.sslCertPath); + } + if (this.dirConfig.sslKeyPath != null && this.dirConfig.sslKeyPath !== '' && + fs.existsSync(this.dirConfig.sslKeyPath)) { + tlsOptions.key = fs.readFileSync(this.dirConfig.sslKeyPath); + } + if (Object.keys(tlsOptions).length > 0) { + options.tlsOptions = tlsOptions; + } + } + + this.client = ldap.createClient(options); const user = this.dirConfig.username == null || this.dirConfig.username.trim() === '' ? null : this.dirConfig.username;