@push.rocks/smartlinuxrepo 1.1.2 → 1.2.0
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/alpine/apkindexreader.d.ts +87 -0
- package/dist_ts/alpine/apkindexreader.js +193 -0
- package/dist_ts/arch/indexreader.d.ts +35 -0
- package/dist_ts/arch/indexreader.js +45 -0
- package/dist_ts/arch/reader.js +1 -1
- package/dist_ts/debian/indexbuilder.js +8 -23
- package/dist_ts/debian/indexreader.d.ts +107 -0
- package/dist_ts/debian/indexreader.js +274 -0
- package/dist_ts/debian/reader.js +1 -1
- package/dist_ts/debian/rules.d.ts +18 -0
- package/dist_ts/debian/rules.js +81 -2
- package/dist_ts/index.d.ts +14 -4
- package/dist_ts/index.js +9 -3
- package/dist_ts/readers/decompress.d.ts +1 -2
- package/dist_ts/readers/decompress.js +1 -1
- package/dist_ts/readers/document.d.ts +36 -0
- package/dist_ts/readers/document.js +110 -0
- package/dist_ts/rpm/repodata.d.ts +3 -2
- package/dist_ts/rpm/repodata.js +5 -4
- package/dist_ts/rpm/repodatareader.d.ts +173 -0
- package/dist_ts/rpm/repodatareader.js +414 -0
- package/dist_ts/rpm/xmlreader.d.ts +70 -0
- package/dist_ts/rpm/xmlreader.js +576 -0
- package/dist_ts/shared/errors.d.ts +12 -4
- package/dist_ts/shared/errors.js +1 -1
- package/dist_ts/shared/limits.d.ts +8 -1
- package/dist_ts/shared/limits.js +5 -2
- package/dist_ts/shared/types.d.ts +2 -0
- package/dist_ts/signing/verifiers.d.ts +43 -0
- package/dist_ts/signing/verifiers.js +81 -2
- package/package.json +1 -1
- package/readme.md +53 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/alpine/apkindexreader.ts +265 -0
- package/ts/arch/indexreader.ts +66 -0
- package/ts/arch/reader.ts +2 -1
- package/ts/debian/indexbuilder.ts +13 -23
- package/ts/debian/indexreader.ts +372 -0
- package/ts/debian/reader.ts +2 -1
- package/ts/debian/rules.ts +83 -1
- package/ts/index.ts +40 -2
- package/ts/readers/decompress.ts +1 -3
- package/ts/readers/document.ts +136 -0
- package/ts/rpm/repodata.ts +4 -3
- package/ts/rpm/repodatareader.ts +582 -0
- package/ts/rpm/xmlreader.ts +680 -0
- package/ts/shared/errors.ts +13 -4
- package/ts/shared/limits.ts +9 -1
- package/ts/shared/types.ts +3 -0
- package/ts/signing/verifiers.ts +113 -1
|
@@ -5,7 +5,9 @@ import type { ILinuxPackageLimits } from './limits.js';
|
|
|
5
5
|
* - `unsupported-compression`: a compression the format does not allow.
|
|
6
6
|
* - `malformed-archive`: broken container structure (ar, tar, gzip, xz, zstd framing or data).
|
|
7
7
|
* - `malformed-header`: a broken package header (RPM lead and headers).
|
|
8
|
-
* - `missing-field` / `invalid-field`: package metadata that is absent or not acceptable
|
|
8
|
+
* - `missing-field` / `invalid-field`: package metadata that is absent or not acceptable; for the index
|
|
9
|
+
* readers, a unit without its key (`Filename`, `pkgid`, `id`, a `<data>` part, the `APKINDEX` member)
|
|
10
|
+
* or a Release checksum line that fails its grammar.
|
|
9
11
|
* - `unsupported-package-format`: input that is not the expected package format, or uses a form of it
|
|
10
12
|
* the codec does not read (the data of a sparse tar entry).
|
|
11
13
|
* - `truncated`: only a clean early end of input.
|
|
@@ -16,14 +18,20 @@ import type { ILinuxPackageLimits } from './limits.js';
|
|
|
16
18
|
* - `malformed-signature`: an OpenPGP signature or cleartext-signed message the verifier refuses before
|
|
17
19
|
* any cryptography: armor, encoding, framing, packet count, version, signature type, a hash outside
|
|
18
20
|
* SHA-256/384/512, a `Hash:` header that does not name the signature's hash, a missing creation time,
|
|
19
|
-
* a missing or wildcard issuer, or an unknown critical subpacket or notation
|
|
21
|
+
* a missing or wildcard issuer, or an unknown critical subpacket or notation; and an Alpine index
|
|
22
|
+
* whose signature member the Alpine verifier refuses (no `.SIGN.` entry, more than one, a type other
|
|
23
|
+
* than `RSA`, an entry that is not a regular `.SIGN.<type>.<keyName>` file).
|
|
20
24
|
* - `wrong-key`: the signature's issuer is neither the verifier's primary key nor one of its subkeys, or
|
|
21
|
-
* its issuer fingerprint disagrees (`detail.value` carries the issuer in hex)
|
|
25
|
+
* its issuer fingerprint disagrees (`detail.value` carries the issuer in hex); for the Alpine verifier,
|
|
26
|
+
* the `.SIGN.RSA.<keyName>` entry names another key (`detail.value` carries that key name).
|
|
22
27
|
* - `unusable-key`: the issuing key or subkey cannot sign at the signature's creation time or at the
|
|
23
28
|
* verification date: expired, revoked, no sign flag, a bad binding or back-signature, created after
|
|
24
29
|
* the signature, or below the algorithm floor.
|
|
25
30
|
* - `bad-signature`: the cryptographic check failed, the signature was created after the verification
|
|
26
31
|
* date, or it has expired at that date.
|
|
32
|
+
* - `malformed-index`: an index document an index reader refuses (1.2.0): line framing, block or
|
|
33
|
+
* stanza structure, XML well-formedness, a DOCTYPE, an unexpected root or child element, an
|
|
34
|
+
* ambiguous duplicate key line or element, or a tar member type an index does not hold.
|
|
27
35
|
*
|
|
28
36
|
* New codes arrive in minor releases: a consumer that switches over `code` needs a default branch.
|
|
29
37
|
*
|
|
@@ -31,7 +39,7 @@ import type { ILinuxPackageLimits } from './limits.js';
|
|
|
31
39
|
* source or from a caller-supplied signer propagates unchanged. An underlying
|
|
32
40
|
* error the codec reacts to is kept in the standard `cause`.
|
|
33
41
|
*/
|
|
34
|
-
export type TLinuxRepoErrorCode = 'limit-exceeded' | 'unsupported-compression' | 'malformed-archive' | 'malformed-header' | 'missing-field' | 'invalid-field' | 'unsupported-package-format' | 'truncated' | 'digest-mismatch' | 'invalid-input' | 'invalid-key' | 'signing-failed' | 'malformed-signature' | 'wrong-key' | 'unusable-key' | 'bad-signature';
|
|
42
|
+
export type TLinuxRepoErrorCode = 'limit-exceeded' | 'unsupported-compression' | 'malformed-archive' | 'malformed-header' | 'missing-field' | 'invalid-field' | 'unsupported-package-format' | 'truncated' | 'digest-mismatch' | 'invalid-input' | 'invalid-key' | 'signing-failed' | 'malformed-signature' | 'wrong-key' | 'unusable-key' | 'bad-signature' | 'malformed-index';
|
|
35
43
|
/** Names the field, structure or limit an error is about. */
|
|
36
44
|
export interface ILinuxRepoErrorDetail {
|
|
37
45
|
field?: string;
|
package/dist_ts/shared/errors.js
CHANGED
|
@@ -19,4 +19,4 @@ export function limitExceeded(limitArg, maximumArg, whatArg) {
|
|
|
19
19
|
export function truncated(whatArg) {
|
|
20
20
|
return new LinuxRepoError('truncated', `input ended inside ${whatArg}`, { field: whatArg });
|
|
21
21
|
}
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc2hhcmVkL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFvRUEsTUFBTSxPQUFPLGNBQWUsU0FBUSxLQUFLO0lBQ3ZCLElBQUksQ0FBc0I7SUFDMUIsTUFBTSxDQUFrQztJQUV4RCxZQUNFLE9BQTRCLEVBQzVCLFVBQWtCLEVBQ2xCLFNBQVMsR0FBMEIsRUFBRSxFQUNyQyxVQUFnQztRQUVoQyxLQUFLLENBQ0gsVUFBVSxFQUNWLFVBQVUsS0FBSyxTQUFTLElBQUksT0FBTyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQzVGLENBQUM7UUFDRixJQUFJLENBQUMsSUFBSSxHQUFHLGdCQUFnQixDQUFDO1FBQzdCLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUNoRCxDQUFDO0NBQ0Y7QUFFRCx1REFBdUQ7QUFDdkQsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsUUFBbUMsRUFDbkMsVUFBa0IsRUFDbEIsT0FBZTtJQUVmLE9BQU8sSUFBSSxjQUFjLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxPQUFPLFlBQVksUUFBUSxLQUFLLFVBQVUsR0FBRyxFQUFFO1FBQzVGLEtBQUssRUFBRSxRQUFRO1FBQ2YsS0FBSyxFQUFFLFVBQVU7S0FDbEIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSxNQUFNLFVBQVUsU0FBUyxDQUFDLE9BQWU7SUFDdkMsT0FBTyxJQUFJLGNBQWMsQ0FBQyxXQUFXLEVBQUUsc0JBQXNCLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDOUYsQ0FBQyJ9
|
|
@@ -27,6 +27,11 @@ export interface ILinuxPackageLimits {
|
|
|
27
27
|
* `maxMetadataBytes`, not here.
|
|
28
28
|
*/
|
|
29
29
|
maxHeaderBytes: number;
|
|
30
|
+
/**
|
|
31
|
+
* One decoded index document (decompressed output, or the plain input), in
|
|
32
|
+
* bytes. Only the index readers read it (1.2.0).
|
|
33
|
+
*/
|
|
34
|
+
maxIndexBytes: number;
|
|
30
35
|
}
|
|
31
36
|
/**
|
|
32
37
|
* The default limits. They accept anything a stock Gitea 28.2.0 stores in
|
|
@@ -37,7 +42,9 @@ export interface ILinuxPackageLimits {
|
|
|
37
42
|
* - `maxEntries` and `maxFileListBytes` are Gitea's Arch file-list caps
|
|
38
43
|
* (Alpine's 1024 `.PKGINFO` values fold into `maxEntries`);
|
|
39
44
|
* - `maxHeaderBytes` covers a full PAX + GNU long name + GNU long link chain at
|
|
40
|
-
* Go `archive/tar`'s 1 MiB per special record, and Gitea's 64 KiB line limit
|
|
45
|
+
* Go `archive/tar`'s 1 MiB per special record, and Gitea's 64 KiB line limit;
|
|
46
|
+
* - `maxIndexBytes` bounds the memory of one index reader call (the decoded
|
|
47
|
+
* document is buffered once); 256 MiB holds a full Debian `main` `Packages`.
|
|
41
48
|
*/
|
|
42
49
|
export declare const DEFAULT_LINUX_PACKAGE_LIMITS: Readonly<ILinuxPackageLimits>;
|
|
43
50
|
/**
|
package/dist_ts/shared/limits.js
CHANGED
|
@@ -11,7 +11,9 @@ const GiB = 1024 * MiB;
|
|
|
11
11
|
* - `maxEntries` and `maxFileListBytes` are Gitea's Arch file-list caps
|
|
12
12
|
* (Alpine's 1024 `.PKGINFO` values fold into `maxEntries`);
|
|
13
13
|
* - `maxHeaderBytes` covers a full PAX + GNU long name + GNU long link chain at
|
|
14
|
-
* Go `archive/tar`'s 1 MiB per special record, and Gitea's 64 KiB line limit
|
|
14
|
+
* Go `archive/tar`'s 1 MiB per special record, and Gitea's 64 KiB line limit;
|
|
15
|
+
* - `maxIndexBytes` bounds the memory of one index reader call (the decoded
|
|
16
|
+
* document is buffered once); 256 MiB holds a full Debian `main` `Packages`.
|
|
15
17
|
*/
|
|
16
18
|
export const DEFAULT_LINUX_PACKAGE_LIMITS = Object.freeze({
|
|
17
19
|
maxPackageBytes: 8 * GiB,
|
|
@@ -21,6 +23,7 @@ export const DEFAULT_LINUX_PACKAGE_LIMITS = Object.freeze({
|
|
|
21
23
|
maxEntries: 100_000,
|
|
22
24
|
maxFileListBytes: 16 * MiB,
|
|
23
25
|
maxHeaderBytes: 4 * MiB,
|
|
26
|
+
maxIndexBytes: 256 * MiB,
|
|
24
27
|
});
|
|
25
28
|
const LIMIT_KEYS = Object.keys(DEFAULT_LINUX_PACKAGE_LIMITS);
|
|
26
29
|
/**
|
|
@@ -54,4 +57,4 @@ export function resolveLinuxPackageLimits(overrides) {
|
|
|
54
57
|
}
|
|
55
58
|
return Object.freeze(resolved);
|
|
56
59
|
}
|
|
57
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGltaXRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc2hhcmVkL2xpbWl0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBc0M3QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDakIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsQ0FBQztBQUN2QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBRXZCOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUFrQyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZGLGVBQWUsRUFBRSxDQUFDLEdBQUcsR0FBRztJQUN4QixnQkFBZ0IsRUFBRSxFQUFFLEdBQUcsR0FBRztJQUMxQiw0QkFBNEIsRUFBRSxFQUFFLEdBQUcsR0FBRztJQUN0QyxlQUFlLEVBQUUsRUFBRSxHQUFHLEdBQUc7SUFDekIsVUFBVSxFQUFFLE9BQU87SUFDbkIsZ0JBQWdCLEVBQUUsRUFBRSxHQUFHLEdBQUc7SUFDMUIsY0FBYyxFQUFFLENBQUMsR0FBRyxHQUFHO0lBQ3ZCLGFBQWEsRUFBRSxHQUFHLEdBQUcsR0FBRztDQUN6QixDQUFDLENBQUM7QUFFSCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFxQyxDQUFDO0FBRWpHOzs7R0FHRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FDdkMsU0FBd0M7SUFFeEMsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDNUIsT0FBTyw0QkFBNEIsQ0FBQztJQUN0QyxDQUFDO0lBQ0QsSUFBSSxTQUFTLEtBQUssSUFBSSxJQUFJLE9BQU8sU0FBUyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDcEYsTUFBTSxJQUFJLGNBQWMsQ0FBQyxlQUFlLEVBQUUsMEJBQTBCLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUM3RixDQUFDO0lBQ0QsTUFBTSxRQUFRLEdBQXdCLEVBQUUsR0FBRyw0QkFBNEIsRUFBRSxDQUFDO0lBQzFFLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBRSxVQUF1QixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzVDLE1BQU0sSUFBSSxjQUFjLENBQUMsZUFBZSxFQUFFLGtCQUFrQixHQUFHLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDdkcsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLEdBQWdDLENBQUM7UUFDbEQsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2xDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLFNBQVM7UUFDWCxDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM1RSxNQUFNLElBQUksY0FBYyxDQUFDLGVBQWUsRUFBRSxTQUFTLFFBQVEsa0NBQWtDLEVBQUU7Z0JBQzdGLEtBQUssRUFBRSxRQUFRO2dCQUNmLEtBQUssRUFBRSxRQUFRO2FBQ2hCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDakMsQ0FBQyJ9
|
|
@@ -211,3 +211,5 @@ export interface ILinuxIndexFile {
|
|
|
211
211
|
/** Other paths serving the same bytes (Debian `by-hash/<ALGO>/<hex>` for every listed hash). */
|
|
212
212
|
aliases: string[];
|
|
213
213
|
}
|
|
214
|
+
/** The stream compressions the readers decode; the caller names it from the file name. */
|
|
215
|
+
export type TLinuxCompression = 'none' | 'gzip' | 'xz' | 'zstd';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ILinuxPackageLimits } from '../shared/limits.js';
|
|
1
2
|
/** The hash algorithms the verifier accepts. */
|
|
2
3
|
export type TOpenPgpHashAlgorithm = 'sha256' | 'sha384' | 'sha512';
|
|
3
4
|
/** A signature that verified. */
|
|
@@ -75,3 +76,45 @@ export interface IOpenPgpVerifier {
|
|
|
75
76
|
export declare function createOpenPgpVerifier(inputArg: {
|
|
76
77
|
publicKeyArmored: string;
|
|
77
78
|
}): Promise<IOpenPgpVerifier>;
|
|
79
|
+
/** An Alpine index signature that verified. */
|
|
80
|
+
export interface IAlpineSignatureVerification {
|
|
81
|
+
/** The key name of the `.SIGN.RSA.<keyName>` entry: the verifier's. */
|
|
82
|
+
readonly keyName: string;
|
|
83
|
+
readonly hashAlgorithm: 'sha1';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Verifies Alpine index signatures against one RSA public key. Fails closed
|
|
87
|
+
* with a `LinuxRepoError` and never returns a verdict of failure:
|
|
88
|
+
* `malformed-signature`, `wrong-key` or `bad-signature` (bad arguments are
|
|
89
|
+
* `invalid-input`; the index's own framing keeps its reader codes).
|
|
90
|
+
*/
|
|
91
|
+
export interface IAlpineVerifier {
|
|
92
|
+
/** The key name apk finds the public key under (`/etc/apk/keys/<keyName>`). */
|
|
93
|
+
readonly keyName: string;
|
|
94
|
+
/**
|
|
95
|
+
* Verifies the one `.SIGN.RSA.<keyName>` entry of an `APKINDEX.tar.gz` over
|
|
96
|
+
* its signed bytes (everything after the signature member): RSASSA-PKCS1-v1_5
|
|
97
|
+
* over SHA-1, as apk-tools 2 and Gitea sign. The split is
|
|
98
|
+
* `readAlpineIndex`'s; no signature member, more than one `.SIGN.` entry or
|
|
99
|
+
* a type other than `RSA` is `malformed-signature`, an entry naming another
|
|
100
|
+
* key `wrong-key` (`detail.value` the entry's key name), and a signature
|
|
101
|
+
* that does not verify `bad-signature`. The format carries no time.
|
|
102
|
+
*/
|
|
103
|
+
verifyIndexSignature(inputArg: {
|
|
104
|
+
index: Uint8Array;
|
|
105
|
+
limits?: Partial<ILinuxPackageLimits>;
|
|
106
|
+
}): Promise<IAlpineSignatureVerification>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Builds an Alpine verifier from one PKIX `PUBLIC KEY` PEM block, the form
|
|
110
|
+
* Gitea serves (`GET /alpine/key`, `util.GenerateKeyPair`) and Alpine installs
|
|
111
|
+
* in `/etc/apk/keys`, and the key name apk finds it under. The PEM must be
|
|
112
|
+
* exactly one block with nothing around it but one final LF, and an RSA key
|
|
113
|
+
* of at least 2047 bits (the OpenPGP verifier's floor); anything else is
|
|
114
|
+
* `invalid-key` (`publicKeyPem`). A `keyName` that is empty or holds `/` or a
|
|
115
|
+
* control character is `invalid-input`.
|
|
116
|
+
*/
|
|
117
|
+
export declare function createAlpineVerifier(inputArg: {
|
|
118
|
+
publicKeyPem: string;
|
|
119
|
+
keyName: string;
|
|
120
|
+
}): IAlpineVerifier;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
|
+
import { splitAlpineIndexSignature } from '../alpine/apkindexreader.js';
|
|
2
3
|
import { LinuxRepoError } from '../shared/errors.js';
|
|
3
|
-
import {
|
|
4
|
+
import { resolveLinuxPackageLimits } from '../shared/limits.js';
|
|
5
|
+
import { assertBytes, assertSegmentName, assertString, assertTimestamp } from '../shared/validation.js';
|
|
4
6
|
import { dearmor, decodeArmorBytes, readPacketTags, splitCleartextSignedMessage, } from './openpgpframing.js';
|
|
5
7
|
const HASH_ALGORITHMS = new Map([
|
|
6
8
|
[plugins.openpgp.enums.hash.sha256, 'sha256'],
|
|
@@ -260,4 +262,81 @@ async function verifySignature(inputArg) {
|
|
|
260
262
|
hashAlgorithm,
|
|
261
263
|
};
|
|
262
264
|
}
|
|
263
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyaWZpZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc2lnbmluZy92ZXJpZmllcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3JGLE9BQU8sRUFDTCxPQUFPLEVBQ1AsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCwyQkFBMkIsR0FFNUIsTUFBTSxxQkFBcUIsQ0FBQztBQWdFN0IsTUFBTSxlQUFlLEdBQStDLElBQUksR0FBRyxDQUFDO0lBQzFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7SUFDN0MsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQztJQUM3QyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO0NBQzlDLENBQUMsQ0FBQztBQUVILDhHQUE4RztBQUM5RyxNQUFNLHdCQUF3QixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRXZEOzs7O0dBSUc7QUFDSCxNQUFNLGFBQWEsR0FBMkI7SUFDNUMsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU07SUFDekIsd0JBQXdCLEVBQUUsS0FBSztJQUMvQixzQkFBc0IsRUFBRSxLQUFLO0lBQzdCLHVCQUF1QixFQUFFLEtBQUs7SUFDOUIsd0JBQXdCLEVBQUUsRUFBRTtJQUM1QixvQkFBb0IsRUFBRSxLQUFLO0lBQzNCLDRDQUE0QyxF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
|
|
265
|
+
/** The OpenPGP verifier's RSA floor (`VERIFY_CONFIG.minRSABits`), for the Alpine key too. */
|
|
266
|
+
const ALPINE_MIN_RSA_BITS = 2047;
|
|
267
|
+
const ALPINE_PUBLIC_KEY_PEM = /^-----BEGIN PUBLIC KEY-----\n(?:[A-Za-z0-9+/=]+\n)+-----END PUBLIC KEY-----\n?$/;
|
|
268
|
+
/**
|
|
269
|
+
* Builds an Alpine verifier from one PKIX `PUBLIC KEY` PEM block, the form
|
|
270
|
+
* Gitea serves (`GET /alpine/key`, `util.GenerateKeyPair`) and Alpine installs
|
|
271
|
+
* in `/etc/apk/keys`, and the key name apk finds it under. The PEM must be
|
|
272
|
+
* exactly one block with nothing around it but one final LF, and an RSA key
|
|
273
|
+
* of at least 2047 bits (the OpenPGP verifier's floor); anything else is
|
|
274
|
+
* `invalid-key` (`publicKeyPem`). A `keyName` that is empty or holds `/` or a
|
|
275
|
+
* control character is `invalid-input`.
|
|
276
|
+
*/
|
|
277
|
+
export function createAlpineVerifier(inputArg) {
|
|
278
|
+
if (inputArg === null || typeof inputArg !== 'object') {
|
|
279
|
+
throw new LinuxRepoError('invalid-input', 'input must be an object', { field: 'input' });
|
|
280
|
+
}
|
|
281
|
+
assertString(inputArg.publicKeyPem, 'publicKeyPem');
|
|
282
|
+
assertSegmentName(inputArg.keyName, 'keyName');
|
|
283
|
+
if (!ALPINE_PUBLIC_KEY_PEM.test(inputArg.publicKeyPem)) {
|
|
284
|
+
throw new LinuxRepoError('invalid-key', 'the Alpine public key must be exactly one PKIX "PUBLIC KEY" PEM block', {
|
|
285
|
+
field: 'publicKeyPem',
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
let key;
|
|
289
|
+
try {
|
|
290
|
+
key = plugins.crypto.createPublicKey({ key: inputArg.publicKeyPem, format: 'pem' });
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
throw new LinuxRepoError('invalid-key', 'the Alpine public key cannot be read', { field: 'publicKeyPem' }, {
|
|
294
|
+
cause: error,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
const modulusLength = key.asymmetricKeyDetails?.modulusLength ?? 0;
|
|
298
|
+
if (key.asymmetricKeyType !== 'rsa' || modulusLength < ALPINE_MIN_RSA_BITS) {
|
|
299
|
+
throw new LinuxRepoError('invalid-key', `the Alpine public key must be an RSA key of at least ${ALPINE_MIN_RSA_BITS} bits`, {
|
|
300
|
+
field: 'publicKeyPem',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
const keyName = inputArg.keyName;
|
|
304
|
+
return {
|
|
305
|
+
keyName,
|
|
306
|
+
verifyIndexSignature: async (input) => {
|
|
307
|
+
assertInputObject(input);
|
|
308
|
+
assertBytes(input.index, 'index');
|
|
309
|
+
const limits = resolveLinuxPackageLimits(input.limits);
|
|
310
|
+
const split = await splitAlpineIndexSignature(input.index, limits);
|
|
311
|
+
const malformed = (messageArg) => new LinuxRepoError('malformed-signature', messageArg, { field: 'index' });
|
|
312
|
+
if (split.signatures.length === 0) {
|
|
313
|
+
throw malformed('the index is not signed');
|
|
314
|
+
}
|
|
315
|
+
if (split.signatures.length > 1) {
|
|
316
|
+
throw malformed(`the index holds ${split.signatures.length} .SIGN. entries, expected one`);
|
|
317
|
+
}
|
|
318
|
+
const entry = split.signatures[0];
|
|
319
|
+
if (entry.type !== 'RSA') {
|
|
320
|
+
throw malformed(`the index signature type is ${JSON.stringify(entry.type)}, expected "RSA"`);
|
|
321
|
+
}
|
|
322
|
+
if (entry.keyName !== keyName) {
|
|
323
|
+
throw new LinuxRepoError('wrong-key', 'the index was signed under another key name', {
|
|
324
|
+
field: 'index',
|
|
325
|
+
value: entry.keyName,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
let verified;
|
|
329
|
+
try {
|
|
330
|
+
verified = plugins.crypto.verify('sha1', input.index.subarray(split.signedOffset), { key, padding: plugins.crypto.constants.RSA_PKCS1_PADDING }, entry.signature);
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
throw new LinuxRepoError('bad-signature', 'the index signature does not verify', { field: 'index' }, { cause: error });
|
|
334
|
+
}
|
|
335
|
+
if (!verified) {
|
|
336
|
+
throw new LinuxRepoError('bad-signature', 'the index signature does not verify', { field: 'index' });
|
|
337
|
+
}
|
|
338
|
+
return { keyName, hashAlgorithm: 'sha1' };
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyaWZpZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc2lnbmluZy92ZXJpZmllcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBRSx5QkFBeUIsRUFBNEIsTUFBTSxxQkFBcUIsQ0FBQztBQUMxRixPQUFPLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RyxPQUFPLEVBQ0wsT0FBTyxFQUNQLGdCQUFnQixFQUNoQixjQUFjLEVBQ2QsMkJBQTJCLEdBRTVCLE1BQU0scUJBQXFCLENBQUM7QUFnRTdCLE1BQU0sZUFBZSxHQUErQyxJQUFJLEdBQUcsQ0FBQztJQUMxRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO0lBQzdDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7SUFDN0MsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQztDQUM5QyxDQUFDLENBQUM7QUFFSCw4R0FBOEc7QUFDOUcsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUV2RDs7OztHQUlHO0FBQ0gsTUFBTSxhQUFhLEdBQTJCO0lBQzVDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNO0lBQ3pCLHdCQUF3QixFQUFFLEtBQUs7SUFD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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartlinuxrepo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A pure codec for Linux package repositories (Alpine apk, Debian apt, RPM dnf, Arch pacman): read packages into records, build index file sets and sign them.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
package/readme.md
CHANGED
|
@@ -16,7 +16,7 @@ Node.js `^24.20.0 || >=26.6.0`: the releases whose `node:zlib` reports a truncat
|
|
|
16
16
|
|
|
17
17
|
## Status
|
|
18
18
|
|
|
19
|
-
All four formats read, index and sign: `readAlpinePackage`, `readDebianPackage`, `readRpmPackage` and `readArchPackage` read packages into records; `buildAlpineIndex`, `buildDebianIndex`, `buildRpmIndex` and `buildArchIndex` build signed index file sets; `signRpmPackage` and `signArchPackage` sign packages at upload. Each format is checked against Gitea 28.2.0's own output and installed from with apk, apt, dnf and pacman. `createOpenPgpVerifier` verifies OpenPGP detached and cleartext signatures (see Verification). The built-in OpenPGP signer does not stream: openpgp.js 6.3.2 holds a detached-signed document in memory (see Signing).
|
|
19
|
+
All four formats read, index and sign: `readAlpinePackage`, `readDebianPackage`, `readRpmPackage` and `readArchPackage` read packages into records; `buildAlpineIndex`, `buildDebianIndex`, `buildRpmIndex` and `buildArchIndex` build signed index file sets; `signRpmPackage` and `signArchPackage` sign packages at upload. Each format is checked against Gitea 28.2.0's own output and installed from with apk, apt, dnf and pacman. `createOpenPgpVerifier` verifies OpenPGP detached and cleartext signatures (see Verification). The index readers read served index documents back into units, and `createAlpineVerifier` verifies `APKINDEX.tar.gz` signatures (see Index readers). The built-in OpenPGP signer does not stream: openpgp.js 6.3.2 holds a detached-signed document in memory (see Signing).
|
|
20
20
|
|
|
21
21
|
## Records
|
|
22
22
|
|
|
@@ -35,8 +35,9 @@ Readers take `Partial<ILinuxPackageLimits>` per call over `DEFAULT_LINUX_PACKAGE
|
|
|
35
35
|
| `maxEntries` | 100,000 | archive entries, Zstandard frames per zstd stream, values per multi-valued field |
|
|
36
36
|
| `maxFileListBytes` | 16 MiB | total Arch file-name bytes |
|
|
37
37
|
| `maxHeaderBytes` | 4 MiB | one tar header chain or metadata line |
|
|
38
|
+
| `maxIndexBytes` | 256 MiB | one decoded index document (index readers only) |
|
|
38
39
|
|
|
39
|
-
Every failure is a `LinuxRepoError` with a stable `code` (`limit-exceeded`, `unsupported-compression`, `malformed-archive`, `malformed-header`, `missing-field`, `invalid-field`, `unsupported-package-format`, `truncated`, `digest-mismatch`, `invalid-input`, `invalid-key`, `signing-failed`,
|
|
40
|
+
Every failure is a `LinuxRepoError` with a stable `code` (`limit-exceeded`, `unsupported-compression`, `malformed-archive`, `malformed-header`, `missing-field`, `invalid-field`, `unsupported-package-format`, `truncated`, `digest-mismatch`, `invalid-input`, `invalid-key`, `signing-failed`, from the verifiers `malformed-signature`, `wrong-key`, `unusable-key`, `bad-signature`, and from the index readers `malformed-index`) and a `detail` naming the field or limit. Errors from your own source or signer, and failures inside node:crypto or openpgp.js during key generation, are passed through unchanged. New codes arrive in minor releases (1.1.0 added the four verifier codes, 1.2.0 `malformed-index`), each raised only by a new function: a `switch` over `code` needs a default branch.
|
|
40
41
|
|
|
41
42
|
Compressed streams (a deb control member, an Arch package) are read to their end: concatenated gzip members and zstd frames are decoded, zstd skippable frames are skipped, and any other bytes after the last gzip member or zstd frame are `malformed-archive`.
|
|
42
43
|
|
|
@@ -100,6 +101,56 @@ The verdicts match gpgv as apt reads it (`EXPKEYSIG` and `REVKEYSIG` are refusal
|
|
|
100
101
|
|
|
101
102
|
Every builder returns the complete file set for its input as `ILinuxIndexFile[]` (`path`, `bytes`, `sha256`, `mediaType`, `stage`, `aliases`); a previously written file that is not in the set is stale. Write every `content` file before any `pointer` file: the pointer files are the signed documents that name the content files.
|
|
102
103
|
|
|
104
|
+
## Index readers
|
|
105
|
+
|
|
106
|
+
The index readers read served index documents back into units, for comparing two producers' indexes (the codec's and Gitea's, say) as multisets of units. A unit is its key, its exact bytes as served (never a re-rendering) and a small lexical view; the parts outside the units come back as raw bytes too.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import {
|
|
110
|
+
createAlpineVerifier,
|
|
111
|
+
readAlpineIndex,
|
|
112
|
+
readArchIndex,
|
|
113
|
+
readDebianPackagesIndex,
|
|
114
|
+
readDebianRelease,
|
|
115
|
+
readRpmRepodata,
|
|
116
|
+
readRpmRepomd,
|
|
117
|
+
readRpmUpdateInfo,
|
|
118
|
+
stripDebianIndexOwnedFields,
|
|
119
|
+
} from '@push.rocks/smartlinuxrepo';
|
|
120
|
+
|
|
121
|
+
const packages = await readDebianPackagesIndex({ bytes: packagesXz, compression: 'xz' });
|
|
122
|
+
for (const stanza of packages.stanzas) {
|
|
123
|
+
stanza.filename; // the key: the last Filename
|
|
124
|
+
stanza.bytes; // the stanza's exact bytes
|
|
125
|
+
stripDebianIndexOwnedFields(stanza.bytes); // without Filename, Size, MD5sum, SHA1, SHA256, SHA512
|
|
126
|
+
}
|
|
127
|
+
const release = await readDebianRelease({ bytes: releaseBytes }); // fields in order, files.{md5Sum,sha1,sha256,sha512}
|
|
128
|
+
const primary = await readRpmRepodata({ bytes: primaryGz, compression: 'gzip', document: 'primary' }); // packages by pkgid
|
|
129
|
+
const apkindex = await readAlpineIndex({ bytes: apkindexTarGz }); // signatures, signedBytes, members, blocks
|
|
130
|
+
await createAlpineVerifier({ publicKeyPem, keyName }).verifyIndexSignature({ index: apkindexTarGz });
|
|
131
|
+
const db = await readArchIndex({ bytes: packagesDb, compression: 'gzip' }); // desc and files members by name
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
| Reader | Document | Units and key | Also returned |
|
|
135
|
+
| --- | --- | --- | --- |
|
|
136
|
+
| `readDebianPackagesIndex` | `Packages`, `.gz`, `.xz` | stanzas; the last `Filename` | `decoded`; `package`, `version`, `architecture` |
|
|
137
|
+
| `readDebianRelease` | `Release` | fields in order | `files.md5Sum`, `sha1`, `sha256`, `sha512` as `{ path, size, digest }` |
|
|
138
|
+
| `readAlpineIndex` | `APKINDEX.tar.gz` | `APKINDEX` blocks; `P:`, `V:`, `A:` | the `.SIGN.*` entries, the signed bytes, the tar members |
|
|
139
|
+
| `readRpmRepodata` | `primary`, `filelists`, `other` | `<package>`; `pkgid` | `decoded`, the XML frame, name, arch, epoch/version/release, `<size>`, files |
|
|
140
|
+
| `readRpmUpdateInfo` | `updateinfo` | `<update>`; `<id>` | `decoded`, the XML frame, the package list |
|
|
141
|
+
| `readRpmRepomd` | `repomd.xml` | `<data>`; `type` | the XML frame, other root elements (`<revision>`, `<tags>`) raw |
|
|
142
|
+
| `readArchIndex` | `packages.db` | tar members; name | `decoded` |
|
|
143
|
+
|
|
144
|
+
- Every reader takes `{ bytes: Uint8Array, ..., limits?: Partial<ILinuxPackageLimits> }` and returns a `Promise`. The compression (`'none' | 'gzip' | 'xz' | 'zstd'`, `TLinuxCompression`) and the RPM `document` are named by the caller from the file name; nothing is sniffed. A stream with bytes after its last gzip member or zstd frame is `malformed-archive`.
|
|
145
|
+
- A reader fails the whole document with a `LinuxRepoError` and never returns a partial result. Every unit is returned in document order, duplicates included (two stanzas with one `Filename`, two packages with one `pkgid`); nothing is merged.
|
|
146
|
+
- Returned units are views into one buffer the reader allocated (`decoded`); `offset` indexes into it. `readAlpineIndex` has no `decoded`: its units are views into the `APKINDEX` member, and its `signedBytes` and signature bytes are its own copies. No result aliases your input.
|
|
147
|
+
- Bounds: the decoded document by `maxIndexBytes`, units (and values per parsed list, open XML elements, Zstandard frames of a zstd document) by `maxEntries`, one unit by `maxMetadataBytes`, one line or XML start tag by `maxHeaderBytes`.
|
|
148
|
+
- `Packages` and `Release` lines end in LF, the last one too; a line holding only spaces or tabs is `malformed-index`. A `Release` holds one stanza: no empty line, checksum lines of a digest, a size and a path separated by spaces or tabs (`invalid-field` otherwise). To read an `InRelease`, verify it with `createOpenPgpVerifier().verifyCleartextMessage` and pass its `signedText` to `readDebianRelease`, adding a final LF when it lacks one.
|
|
149
|
+
- RPM documents are read by a strict XML scanner: UTF-8 only, no DOCTYPE (so no entities), well-formed, the root the `document` names, only whitespace between units (not returned). The frame (`prolog`, `rootStartTag`, `rootAttributes`, `namespace`, `rootEndTag`, `trailer`) is returned as written; for Gitea's and the codec's documents the frame and the units rebuild `decoded`. `isRpmPrimaryPath` is createrepo_c's `cr_is_primary`, the rule the codec adds to Gitea's primary file list.
|
|
150
|
+
- `readAlpineIndex` splits the index as apk does: the first gzip member is the signature member when its tar's first entry is named `.SIGN.*`. `createAlpineVerifier({ publicKeyPem, keyName })` takes one PKIX `PUBLIC KEY` PEM (what Gitea serves at `/alpine/key` and Alpine installs in `/etc/apk/keys`) of an RSA key of at least 2047 bits and the key name apk finds it under, and verifies RSA PKCS#1 v1.5 over SHA-1 of the signed bytes. It fails closed: `malformed-signature` (unsigned, several `.SIGN.` entries, a type other than `RSA`), `wrong-key` (another key name, `detail.value`), `bad-signature`.
|
|
151
|
+
- `readArchIndex` returns regular files and skips directory entries (pacman's `repo-add` writes them); `desc` and `files` are not parsed. `compareArchVersions` is pacman's `vercmp`.
|
|
152
|
+
- `malformed-index` is an index document a reader refuses: line framing, block or stanza structure, XML well-formedness, an unexpected root or child element, an ambiguous duplicate key line or element (`P:` twice, two `<id>`), or a tar entry type an index does not hold. A unit without its key is `missing-field`.
|
|
153
|
+
|
|
103
154
|
## Alpine
|
|
104
155
|
|
|
105
156
|
```ts
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartlinuxrepo',
|
|
6
|
-
version: '1.
|
|
6
|
+
version: '1.2.0',
|
|
7
7
|
description: 'A pure codec for Linux package repositories (Alpine apk, Debian apt, RPM dnf, Arch pacman): read packages into records, build index file sets and sign them.'
|
|
8
8
|
}
|