@symbiosis-lab/moss 0.12.1 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/fetch.js +41 -8
- package/package.json +1 -1
package/lib/fetch.js
CHANGED
|
@@ -92,26 +92,57 @@ async function download(url) {
|
|
|
92
92
|
return Buffer.from(await res.arrayBuffer());
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
//
|
|
96
|
-
//
|
|
95
|
+
// The first release that published a SHA256SUMS file. Before it there is
|
|
96
|
+
// nothing to verify against; from it on, every release has one.
|
|
97
|
+
const CHECKSUMS_SINCE = [0, 11, 2];
|
|
98
|
+
|
|
99
|
+
// Must a missing checksum be fatal for this version? Anything unparseable
|
|
100
|
+
// answers yes: an unrecognised version string is not a licence to skip the
|
|
101
|
+
// only check on bytes we are about to mark executable.
|
|
102
|
+
function checksumsRequired(version) {
|
|
103
|
+
const parts = String(version).split('-')[0].split('.').map(Number);
|
|
104
|
+
if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n))) return true;
|
|
105
|
+
for (let i = 0; i < 3; i += 1) {
|
|
106
|
+
if (parts[i] !== CHECKSUMS_SINCE[i]) return parts[i] > CHECKSUMS_SINCE[i];
|
|
107
|
+
}
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Verifies bytes against the release's SHA256SUMS.
|
|
112
|
+
//
|
|
113
|
+
// Every reason we might not reach a checksum — a non-200, a network error, a
|
|
114
|
+
// SHA256SUMS with no line for this asset — is reached over the same connection
|
|
115
|
+
// that just served the binary. So on a version that publishes checksums, taking
|
|
116
|
+
// any of them as permission to skip verification hands the skip to whoever
|
|
117
|
+
// controls that connection: suppress one small request and the binary installs
|
|
118
|
+
// unverified. Fail closed there, and keep the warning only for the pre-v0.11.2
|
|
119
|
+
// releases where the file genuinely does not exist.
|
|
97
120
|
async function verifyChecksum(bytes, asset, version) {
|
|
121
|
+
const unverified = (reason) => {
|
|
122
|
+
if (checksumsRequired(version)) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`moss-npm: cannot verify moss v${version} (${asset}): ${reason}.\n` +
|
|
125
|
+
' Every release from v0.11.2 on publishes SHA256SUMS, so this is either a\n' +
|
|
126
|
+
' transient network fault or a tampered download. Not installing.'
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
console.warn(`moss-npm: ${reason}; skipping checksum verification (v${version} predates SHA256SUMS)`);
|
|
130
|
+
};
|
|
131
|
+
|
|
98
132
|
let sums;
|
|
99
133
|
try {
|
|
100
134
|
const res = await fetch(`${RELEASES}/v${version}/SHA256SUMS`, { redirect: 'follow' });
|
|
101
135
|
if (!res.ok) {
|
|
102
|
-
|
|
103
|
-
return;
|
|
136
|
+
return unverified(`no SHA256SUMS published for v${version} (${res.status})`);
|
|
104
137
|
}
|
|
105
138
|
sums = await res.text();
|
|
106
139
|
} catch (err) {
|
|
107
|
-
|
|
108
|
-
return;
|
|
140
|
+
return unverified(`could not fetch SHA256SUMS (${err.message})`);
|
|
109
141
|
}
|
|
110
142
|
|
|
111
143
|
const line = sums.split('\n').find((l) => l.trim().endsWith(asset));
|
|
112
144
|
if (!line) {
|
|
113
|
-
|
|
114
|
-
return;
|
|
145
|
+
return unverified(`SHA256SUMS has no entry for ${asset}`);
|
|
115
146
|
}
|
|
116
147
|
|
|
117
148
|
const expected = line.trim().split(/\s+/)[0];
|
|
@@ -141,10 +172,12 @@ async function fetchBinary() {
|
|
|
141
172
|
}
|
|
142
173
|
|
|
143
174
|
module.exports = {
|
|
175
|
+
checksumsRequired,
|
|
144
176
|
fetchBinary,
|
|
145
177
|
vendorBinary,
|
|
146
178
|
resolveAsset,
|
|
147
179
|
resolveBinary,
|
|
148
180
|
resolveVersion,
|
|
149
181
|
skipDownloadReason,
|
|
182
|
+
verifyChecksum,
|
|
150
183
|
};
|