mirror of
https://git.sr.ht/~noisytoot/randomsync
synced 2025-04-01 06:00:53 +01:00
Add support for authenticated control commands
This commit is contained in:
parent
6fce1c32e4
commit
b534e18447
3 changed files with 87 additions and 3 deletions
22
keygen.js
Normal file
22
keygen.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
// -*- mode: javascript; indent-tabs-mode: nil -*-
|
||||
// Copyright (C) 2021 Noisytoot
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const ed25519 = require('ed25519')
|
||||
const crypto = require('crypto')
|
||||
|
||||
let keypair = ed25519.MakeKeypair(crypto.randomBytes(32))
|
||||
console.log('private key: ' + keypair.privateKey.toString('base64'))
|
||||
console.log('public key: ' + keypair.publicKey.toString('base64'))
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
const fs = require('fs')
|
||||
const irc = require('irc-framework')
|
||||
const ed25519 = require('ed25519')
|
||||
|
||||
const random = fs.openSync('/dev/urandom', 'r+')
|
||||
function getRandom(bytes) {
|
||||
|
@ -46,14 +47,20 @@ const config = JSON.parse(fs.readFileSync('./config.json', 'utf8')),
|
|||
LEADER_PROBABLILITY = config['leader-probability'] || 0.75,
|
||||
PASSWORD = config.password,
|
||||
SASL_USERNAME = config['sasl-username'],
|
||||
SASL_PASSWORD = config['sasl-password']
|
||||
SASL_PASSWORD = config['sasl-password'],
|
||||
CONTROL_ID = config['control-id']
|
||||
|
||||
let SASL_MECHANISM = config['sasl-mechanism']
|
||||
let SASL_MECHANISM = config['sasl-mechanism'],
|
||||
CONTROL_KEY = config['control-key']
|
||||
|
||||
// Make SASL_MECHANISM uppercase if defined
|
||||
if (SASL_MECHANISM)
|
||||
SASL_MECHANISM = SASL_MECHANISM.toUpperCase()
|
||||
|
||||
// Decode control key if defined
|
||||
if (CONTROL_KEY)
|
||||
CONTROL_KEY = Buffer.from(CONTROL_KEY, 'base64')
|
||||
|
||||
let key, cert
|
||||
if (TLS_KEY && TLS_CERT) {
|
||||
key = fs.readFileSync(TLS_KEY, 'utf8')
|
||||
|
@ -61,7 +68,8 @@ if (TLS_KEY && TLS_CERT) {
|
|||
}
|
||||
|
||||
let lastSync = 0,
|
||||
syncLeader = false
|
||||
syncLeader = false,
|
||||
otps = new Set()
|
||||
|
||||
let client = new irc.Client({
|
||||
nick: NICK,
|
||||
|
@ -97,6 +105,36 @@ client.on('registered', event => {
|
|||
client.on('privmsg', msg => {
|
||||
if (CHANNELS.includes(msg.target)) {
|
||||
putRandom(msg.message)
|
||||
if (msg.message.includes('$RANDSYNC-OTP$ ' + CONTROL_ID || client.user.nick)) {
|
||||
let otp = getRandom(32).toString('base64')
|
||||
otps.add(otp)
|
||||
client.say(msg.target, otp)
|
||||
}
|
||||
if (msg.message.includes('$RANDSYNC-CONTROL$ ' + CONTROL_ID || client.user.nick)
|
||||
&& CONTROL_KEY) {
|
||||
let args = msg.message.split(' ')
|
||||
args = args.slice(args.indexOf('$RANDSYNC-CONTROL$') + 2)
|
||||
if (args.length >= 3) {
|
||||
let signature = Buffer.from(args[0], 'base64')
|
||||
let otp = args[1]
|
||||
if (signature.length == 64
|
||||
&& ed25519.Verify(Buffer.from(args.slice(1).join(' '), 'utf8'), signature, CONTROL_KEY)
|
||||
&& otps.has(otp)) {
|
||||
args = args.slice(2)
|
||||
otps.delete(otp)
|
||||
switch (args[0]) {
|
||||
case "OTPS":
|
||||
client.say(msg.target, Array.from(otps).join(' '))
|
||||
break
|
||||
case "CLEAROTPS":
|
||||
otps = new Set()
|
||||
break
|
||||
}
|
||||
} else {
|
||||
client.say(msg.target, 'Invalid signature or OTP')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (msg.message.includes('$RANDSYNCv2$')) {
|
||||
let args = msg.message.split(' ')
|
||||
args = args.slice(args.indexOf('$RANDSYNCv2$') + 1)
|
||||
|
|
24
sign.js
Normal file
24
sign.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
// -*- mode: javascript; indent-tabs-mode: nil -*-
|
||||
// Copyright (C) 2021 Noisytoot
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const fs = require('fs')
|
||||
const ed25519 = require('ed25519')
|
||||
|
||||
let privatekey = Buffer.from(fs.readFileSync(process.argv[2]).toString('utf8'), 'base64')
|
||||
|
||||
process.stdin.on('data', function (data) {
|
||||
console.log(ed25519.Sign(Buffer.from(data, 'utf8'), privatekey).toString('base64') + ' ' + data)
|
||||
})
|
Loading…
Add table
Reference in a new issue