aboutsummaryrefslogtreecommitdiff
path: root/lib/app.js
diff options
context:
space:
mode:
authorcel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2018-11-30 14:57:12 -1000
committercel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2018-11-30 14:58:13 -1000
commita61c80c4140564b1a4daf19d9086c05a8f276c20 (patch)
tree858bb36795bd5699d99639f637bd3492e3fe1fa6 /lib/app.js
parent328b6ffd8dc1a0cb66111a0ae8b346c5c2aad8f5 (diff)
downloadpatchfoo-a61c80c4140564b1a4daf19d9086c05a8f276c20.tar.gz
patchfoo-a61c80c4140564b1a4daf19d9086c05a8f276c20.zip
Show git signatures
- Add /git/signature page to verify signatures using gpg - Show link to signature pages for tag and commit objects
Diffstat (limited to 'lib/app.js')
-rw-r--r--lib/app.js62
1 files changed, 62 insertions, 0 deletions
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()
+ })
+ })
+ })
+ }
+}