From a61c80c4140564b1a4daf19d9086c05a8f276c20 Mon Sep 17 00:00:00 2001 From: cel Date: Fri, 30 Nov 2018 14:57:12 -1000 Subject: Show git signatures - Add /git/signature page to verify signatures using gpg - Show link to signature pages for tag and commit objects --- lib/app.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'lib/app.js') diff --git a/lib/app.js b/lib/app.js index b4da954..6689a0e 100644 --- a/lib/app.js +++ b/lib/app.js @@ -19,6 +19,9 @@ var toPull = require('stream-to-pull-stream') var BoxStream = require('pull-box-stream') var crypto = require('crypto') var SsbNpmRegistry = require('ssb-npm-registry') +var os = require('os') +var path = require('path') +var fs = require('fs') var zeros = new Buffer(24); zeros.fill(0) @@ -1141,3 +1144,62 @@ App.prototype.sbotStatus = function (cb) { } if (typeof status === 'object' && status !== null) return cb(null, status) } + +function writeAll(fd, buf, cb) { + var offset = 0 + var remaining = buf.length + fs.write(fd, buf, function onWrite(err, bytesWritten) { + if (err) return cb(err) + offset += bytesWritten + remaining -= bytesWritten + if (remaining > 0) fs.write(fd, buf, offset, remaining, null, onWrite) + else cb() + }) +} + +App.prototype.verifyGitObjectSignature = function (obj, cb) { + var self = this + var tmpPath = path.join(os.tmpdir(), '.git_vtag_tmp' + Math.random().toString('36')) + // use a temp file to work around https://github.com/nodejs/node/issues/13542 + function closeEnd(err) { + fs.close(fd, function (err1) { + fs.unlink(tmpPath, function (err2) { + cb(err2 || err1 || err) + }) + }) + } + fs.open(tmpPath, 'w+', function (err, fd) { + if (err) return cb(err) + self.git.extractSignature(obj, function (err, parts) { + if (err) return closeEnd(err) + writeAll(fd, parts.signature, function (err) { + if (err) return closeEnd(err) + try { next(fd, parts) } + catch(e) { closeEnd(e) } + }) + }) + }) + function next(fd, parts) { + var readSig = fs.createReadStream(null, {fd: fd, start: 0}) + var done = multicb({pluck: 1, spread: true}) + var gpg = proc.spawn('gpg', ['--status-fd=1', '--keyid-format=long', + '--verify', '/dev/fd/3', '-'], { + stdio: ['pipe', 'pipe', 'pipe', readSig] + }).on('close', done().bind(null, null)) + .on('error', console.error.bind(console, 'gpg')) + gpg.stdin.end(parts.payload) + pull(toPull.source(gpg.stdout), u.pullConcat(done())) + pull(toPull.source(gpg.stderr), u.pullConcat(done())) + done(function (err, code, status, output) { + if (err) return closeEnd(err) + fs.unlink(tmpPath, function (err) { + if (err) return cb(err) + cb(null, { + goodsig: status.includes('\n[GNUPG:] GOODSIG '), + status: status.toString(), + output: output.toString() + }) + }) + }) + } +} -- cgit v1.2.3