Merge branch 'master' of gitlab.libraryofcode.org:engineering/cloudservices
commit
a2213ae014
|
@ -1,4 +1,4 @@
|
||||||
import { writeFile } from 'fs-extra';
|
import { writeFile, unlink } from 'fs-extra';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Message } from 'eris';
|
import { Message } from 'eris';
|
||||||
import { Command } from '../class';
|
import { Command } from '../class';
|
||||||
|
@ -20,7 +20,7 @@ export default class CWG_UpdateCert extends Command {
|
||||||
if (!args[2]) return this.client.commands.get('help').run(message, ['cwg', this.name]);
|
if (!args[2]) return this.client.commands.get('help').run(message, ['cwg', this.name]);
|
||||||
const dom = await this.client.db.Domain.findOne({ $or: [{ domain: args[0] }, { port: Number(args[0]) || '' }] });
|
const dom = await this.client.db.Domain.findOne({ $or: [{ domain: args[0] }, { port: Number(args[0]) || '' }] });
|
||||||
if (!dom) return message.channel.createMessage(`***${this.client.stores.emojis.error} The domain or port you provided could not be found.***`);
|
if (!dom) return message.channel.createMessage(`***${this.client.stores.emojis.error} The domain or port you provided could not be found.***`);
|
||||||
const { domain, port, x509 } = dom;
|
const { domain, port, x509, account } = dom;
|
||||||
const { cert, key } = x509;
|
const { cert, key } = x509;
|
||||||
|
|
||||||
const urls = args.slice(1, 3); // eslint-disable-line
|
const urls = args.slice(1, 3); // eslint-disable-line
|
||||||
|
@ -32,7 +32,16 @@ export default class CWG_UpdateCert extends Command {
|
||||||
if (!this.isValidCertificateChain(certAndPrivateKey[0])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Certificate Chain***`);
|
if (!this.isValidCertificateChain(certAndPrivateKey[0])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Certificate Chain***`);
|
||||||
if (!this.isValidPrivateKey(certAndPrivateKey[1])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Private Key***`);
|
if (!this.isValidPrivateKey(certAndPrivateKey[1])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Private Key***`);
|
||||||
|
|
||||||
const writeTasks = [writeFile(cert, certAndPrivateKey[0], { encoding: 'utf8' }), writeFile(key, certAndPrivateKey[1], { encoding: 'utf8' })];
|
const path = `/var/CloudServices/temp/${account.id}`;
|
||||||
|
const temp = [writeFile(`${path}.chain.crt`, certAndPrivateKey[0]), writeFile(`${path}.key.pem`, certAndPrivateKey[1])];
|
||||||
|
const removeFiles = [unlink(`${path}.chain.crt`), unlink(`${path}.key.pem`)];
|
||||||
|
await Promise.all(temp);
|
||||||
|
if (!this.isMatchingPair(`${path}.chain.crt`, `${path}.key.pem`)) {
|
||||||
|
await Promise.all(removeFiles);
|
||||||
|
return message.channel.createMessage(`${this.client.stores.emojis.error} ***Certificate and private key do not match***`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const writeTasks = [writeFile(cert, certAndPrivateKey[0], { encoding: 'utf8' }), writeFile(key, certAndPrivateKey[1], { encoding: 'utf8' }), ...removeFiles];
|
||||||
await Promise.all(writeTasks);
|
await Promise.all(writeTasks);
|
||||||
|
|
||||||
return message.channel.createMessage(`${this.client.stores.emojis.success} ***Updated certificate for ${domain} on port ${port}***`);
|
return message.channel.createMessage(`${this.client.stores.emojis.success} ***Updated certificate for ${domain} on port ${port}***`);
|
||||||
|
@ -60,4 +69,10 @@ export default class CWG_UpdateCert extends Command {
|
||||||
if (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----END PRIVATE KEY-----') !== 1) return false;
|
if (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----END PRIVATE KEY-----') !== 1) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async isMatchingPair(cert: string, privateKey: string) {
|
||||||
|
const result: string = await this.client.util.exec(`${__dirname}/../bin/checkCertSignatures ${cert} ${privateKey}`);
|
||||||
|
const { ok }: { ok: boolean } = JSON.parse(result);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { parseCert } from '@ghaiklor/x509';
|
||||||
import { Message } from 'eris';
|
import { Message } from 'eris';
|
||||||
import { Client } from '..';
|
import { Client } from '..';
|
||||||
import { Command, RichEmbed } from '../class';
|
import { Command, RichEmbed } from '../class';
|
||||||
|
import { parseCertificate } from '../functions';
|
||||||
|
|
||||||
export default class Parse extends Command {
|
export default class Parse extends Command {
|
||||||
constructor(client: Client) {
|
constructor(client: Client) {
|
||||||
|
@ -25,18 +26,19 @@ export default class Parse extends Command {
|
||||||
return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate Validation directory.***`);
|
return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate Validation directory.***`);
|
||||||
}
|
}
|
||||||
if (!dir.length) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate certificate.***`);
|
if (!dir.length) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate certificate.***`);
|
||||||
const cert = parseCert(`${account.homepath}/Validation/${dir[0]}`);
|
const cert = await parseCertificate(this.client, `${account.homepath}/Validation/${dir[0]}`);
|
||||||
const subjectCommonName = cert.subject.commonName ? cert.subject.commonName : 'Not Specified';
|
// const cert = parseCert(`${account.homepath}/Validation/${dir[0]}`);
|
||||||
const subjectEmailAddress = cert.subject.emailAddress ? cert.subject.emailAddress : 'Not Specified';
|
const subjectCommonName = cert.subject.commonName || 'Not Specified';
|
||||||
const subjectOrganization = cert.subject.organizationName ? cert.subject.organizationName : 'Not Specified';
|
const subjectEmailAddress = cert.subject.emailAddress || 'Not Specified';
|
||||||
const subjectOrganizationalUnit = cert.subject.organizationalUnitName ? cert.subject.organizationalUnitName : 'Not Specified';
|
const subjectOrganization = cert.subject.organizationName || 'Not Specified';
|
||||||
const subjectCountry = cert.subject.countryName ? cert.subject.countryName : 'Not Specified';
|
const subjectOrganizationalUnit = cert.subject.organizationalUnitName || 'Not Specified';
|
||||||
const issuerCommonName = cert.issuer.commonName ? cert.issuer.commonName : 'Not Specified';
|
const subjectCountry = cert.subject.countryName || 'Not Specified';
|
||||||
const issuerEmailAddress = cert.issuer.emailAddress ? cert.issuer.emailAddress : 'Not Specified';
|
const issuerCommonName = cert.issuer.commonName || 'Not Specified';
|
||||||
const issuerOrganization = cert.issuer.organizationName ? cert.issuer.organizationName : 'Not Specified';
|
const issuerEmailAddress = cert.issuer.emailAddress || 'Not Specified';
|
||||||
const issuerOrganizationalUnit = cert.issuer.organizationalUnitName ? cert.issuer.organizationalUnitName : 'Not Specified';
|
const issuerOrganization = cert.issuer.organizationName || 'Not Specified';
|
||||||
const issuerCountry = cert.issuer.countryName ? cert.issuer.countryName : 'Not Specified';
|
const issuerOrganizationalUnit = cert.issuer.organizationalUnitName || 'Not Specified';
|
||||||
const user = this.client.users.get(account.userID) ? this.client.users.get(account.userID) : await this.client.getRESTUser(account.userID);
|
const issuerCountry = cert.issuer.countryName || 'Not Specified';
|
||||||
|
const user = this.client.users.get(account.userID) || await this.client.getRESTUser(account.userID);
|
||||||
const embed = new RichEmbed();
|
const embed = new RichEmbed();
|
||||||
embed.setTitle('Parse x509 Certificate');
|
embed.setTitle('Parse x509 Certificate');
|
||||||
embed.setDescription(`${account.homepath}/Validation/${dir[0]} | ${account.username} <@${user.id}>`);
|
embed.setDescription(`${account.homepath}/Validation/${dir[0]} | ${account.username} <@${user.id}>`);
|
||||||
|
@ -46,10 +48,10 @@ export default class Parse extends Command {
|
||||||
embed.addField('Serial Number', cert.serial, true);
|
embed.addField('Serial Number', cert.serial, true);
|
||||||
embed.addField('Fingerprint', cert.fingerPrint, true);
|
embed.addField('Fingerprint', cert.fingerPrint, true);
|
||||||
embed.addField('Signature Algorithm', cert.signatureAlgorithm, true);
|
embed.addField('Signature Algorithm', cert.signatureAlgorithm, true);
|
||||||
embed.addField('Public Key Algorithm', cert.publicKey.algorithm, true);
|
embed.addField('Public Key Algorithm', cert.publicKeyAlgorithm, true);
|
||||||
embed.addField('Key Usage', cert.extensions.keyUsage, true);
|
embed.addField('Key Usage', cert.extensions.keyUsage, true);
|
||||||
embed.addField('Extended Key Usage', cert.extensions.extendedKeyUsage, true);
|
embed.addField('Extended Key Usage', cert.extensions.extendedKeyUsage.join(', '), true);
|
||||||
embed.addField('Policies', cert.extensions.certificatePolicies, true);
|
embed.addField('Policies', cert.extensions.certificatePolicies.join(', '), true);
|
||||||
embed.addField('Issued On', new Date(cert.notBefore).toLocaleString('en-us'), true);
|
embed.addField('Issued On', new Date(cert.notBefore).toLocaleString('en-us'), true);
|
||||||
embed.addField('Expires On', new Date(cert.notAfter).toLocaleString('en-us'), true);
|
embed.addField('Expires On', new Date(cert.notAfter).toLocaleString('en-us'), true);
|
||||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||||
|
|
|
@ -24,20 +24,29 @@ export default class Parseall extends Command {
|
||||||
embed.setFooter(`Requested by ${message.member.username}#${message.member.discriminator}`, message.member.avatarURL);
|
embed.setFooter(`Requested by ${message.member.username}#${message.member.discriminator}`, message.member.avatarURL);
|
||||||
embed.setTimestamp();
|
embed.setTimestamp();
|
||||||
const search = await this.client.db.Account.find();
|
const search = await this.client.db.Account.find();
|
||||||
const accounts = search.map((acc) => acc.homepath);
|
const accounts = search;
|
||||||
const final: string[] = [];
|
const final: string[] = [];
|
||||||
|
|
||||||
accounts.forEach(async (a) => {
|
accounts.forEach(async (a) => {
|
||||||
try {
|
try {
|
||||||
const certFile = readdirSync(`${a}/Validation`)[0];
|
const certFile = readdirSync(`${a.homepath}/Validation`)[0];
|
||||||
const { notAfter } = parseCert(`${a}/Validation/${certFile}`);
|
const { notAfter } = parseCert(`${a.homepath}/Validation/${certFile}`);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const time = moment.preciseDiff(new Date(), notAfter);
|
const timeObject: {years: number, months: number, days: number, hours: number, minutes: number, seconds: number, firstDateWasLater: boolean} = moment.preciseDiff(new Date(), notAfter, true);
|
||||||
|
const precise: [number, string][] = [];
|
||||||
|
// @ts-ignore
|
||||||
|
const timeArray: number[] = Object.values(timeObject).filter((v) => typeof v === 'number');
|
||||||
|
timeArray.forEach((t) => { // eslint-disable-line
|
||||||
|
const index = timeArray.indexOf(t);
|
||||||
|
const measurements = ['yr', 'mo', 'd', 'h', 'm', 's'];
|
||||||
|
precise.push([t, measurements[index]]);
|
||||||
|
});
|
||||||
|
const time = precise.filter((n) => n[0]).map(((v) => v.join(''))).join(', ');
|
||||||
|
|
||||||
if (notAfter < new Date()) final.push(`${this.client.stores.emojis.error} **${a}** Certificate expired ${time} ago`);
|
if (notAfter < new Date()) final.push(`${this.client.stores.emojis.error} **${a.username}** Certificate expired ${time} ago`);
|
||||||
else final.push(`${this.client.stores.emojis.success} **${a}** Certificate expires in ${time}`);
|
else final.push(`${this.client.stores.emojis.success} **${a.username}** Certificate expires in ${time}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.message.includes('no such file or directory') || error.message.includes('File doesn\'t exist.')) final.push(`${this.client.stores.emojis.error} **${a}** Unable to locate certificate`);
|
if (error.message.includes('no such file or directory') || error.message.includes('File doesn\'t exist.')) final.push(`${this.client.stores.emojis.error} **${a.username}** Unable to locate certificate`);
|
||||||
else throw error;
|
else throw error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
export { default as checkLock } from './checkLock';
|
export { default as checkLock } from './checkLock';
|
||||||
export { default as dataConversion } from './dataConversion';
|
export { default as dataConversion } from './dataConversion';
|
||||||
|
export { default as checkSS } from './checkSS';
|
||||||
|
export { default as parseCertificate } from './parseCertificate';
|
||||||
|
|
|
@ -35,16 +35,16 @@ export default async function parseCertificate(client: Client, pathToCertificate
|
||||||
subject: {
|
subject: {
|
||||||
commonName: parsedObject.RawParse.Subject.CommonName,
|
commonName: parsedObject.RawParse.Subject.CommonName,
|
||||||
emailAddress: parsedObject.AbstractParse.EmailAddress,
|
emailAddress: parsedObject.AbstractParse.EmailAddress,
|
||||||
organizationName: parsedObject.RawParse.Subject.Organization[0],
|
organizationName: parsedObject.RawParse.Subject.Organization ? parsedObject.RawParse.Subject.Organization[0] : null,
|
||||||
organizationalUnitName: parsedObject.RawParse.Subject.OrganizationalUnit[0],
|
organizationalUnitName: parsedObject.RawParse.Subject.OrganizationalUnit ? parsedObject.RawParse.Subject.OrganizationalUnit[0] : null,
|
||||||
countryName: parsedObject.RawParse.Subject.Country[0],
|
countryName: parsedObject.RawParse.Subject.Country ? parsedObject.RawParse.Subject.Country[0] : null,
|
||||||
},
|
},
|
||||||
issuer: {
|
issuer: {
|
||||||
commonName: parsedObject.RawParse.Issuer.CommonName,
|
commonName: parsedObject.RawParse.Issuer.CommonName,
|
||||||
emailAddress: null,
|
emailAddress: null,
|
||||||
organizationName: parsedObject.RawParse.Issuer.Organization[0],
|
organizationName: parsedObject.RawParse.Issuer.Organization ? parsedObject.RawParse.Issuer.Organization[0] : null,
|
||||||
organizationalUnitName: parsedObject.RawParse.Issuer.OrganizationalUnit[0],
|
organizationalUnitName: parsedObject.RawParse.Issuer.OrganizationalUnit ? parsedObject.RawParse.Issuer.OrganizationalUnit[0] : null,
|
||||||
countryName: parsedObject.RawParse.Issuer.Country[0],
|
countryName: parsedObject.RawParse.Issuer.Country ? parsedObject.RawParse.Issuer.Country[0] : null,
|
||||||
},
|
},
|
||||||
extensions: {
|
extensions: {
|
||||||
keyUsage: '[ Not implemented by executable ]',
|
keyUsage: '[ Not implemented by executable ]',
|
||||||
|
|
Loading…
Reference in New Issue