diff options
Diffstat (limited to 'lib/app.js')
-rw-r--r-- | lib/app.js | 62 |
1 files changed, 62 insertions, 0 deletions
@@ -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() + }) + }) + }) + } +} |