Initial commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+4
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
lib/protocol/crypto/poly1305.js
|
||||
.eslint-plugins
|
||||
!.eslintrc.js
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
extends: '@mscdex/eslint-config',
|
||||
};
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
CI_CHECK_FAIL: ssh2
|
||||
OPENSSL_CONF: /dev/null
|
||||
|
||||
jobs:
|
||||
tests-linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [10.16.0, 10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Check npm version
|
||||
run: npm -v
|
||||
- name: Install Python 2.7 (node <16.x)
|
||||
if: ${{ contains(fromJSON('["10.16.0", "10.x", "12.x", "14.x"]'), matrix.node-version) }}
|
||||
uses: LizardByte/setup-python-action@v2024.1105.190605
|
||||
with:
|
||||
python-version: '2.7'
|
||||
- name: Use Python 2.7 (node <16.x)
|
||||
if: ${{ contains(fromJSON('["10.16.0", "10.x", "12.x", "14.x"]'), matrix.node-version) }}
|
||||
run: echo "PYTHON=$(which python2.7)" >> "$GITHUB_ENV"
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
tests-macos:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install Python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Check npm version
|
||||
run: npm -v
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
tests-macos-homebrew:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js (latest)
|
||||
run: brew install node
|
||||
- name: Install Python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Check npm version
|
||||
run: npm -v
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
tests-windows:
|
||||
runs-on: windows-2022
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [16.x, 18.x, 20.x, 22.x, 24.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Check npm version
|
||||
run: npm -v
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
name: lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
NODE_VERSION: 18.x
|
||||
|
||||
jobs:
|
||||
lint-js:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- name: Check Node.js version
|
||||
run: node -pe process.versions
|
||||
- name: Install ESLint + ESLint configs/plugins
|
||||
run: npm install --only=dev
|
||||
- name: Lint files
|
||||
run: npm run lint
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright Brian White. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
+1529
File diff suppressed because it is too large
Load Diff
+413
@@ -0,0 +1,413 @@
|
||||
SFTP events
|
||||
-----------
|
||||
|
||||
**Client/Server events**
|
||||
|
||||
* **ready**() - Emitted after initial protocol version check has passed.
|
||||
|
||||
**Server-only events**
|
||||
|
||||
_Responses to these client requests are sent using one of the methods listed further in this document under `Server-only methods`. The valid response(s) for each request are documented below._
|
||||
|
||||
* **OPEN**(< _integer_ >reqID, < _string_ >filename, < _integer_ >flags, < _ATTRS_ >attrs)
|
||||
|
||||
`flags` is a bitfield containing any of the flags defined in `OPEN_MODE`.
|
||||
Use the static method `flagsToString()` to convert the value to a mode
|
||||
string to be used by `fs.open()` (e.g. `'r'`).
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `handle()` - This indicates a successful opening of the file and passes
|
||||
the given handle back to the client to use to refer to this open file for
|
||||
future operations (e.g. reading, writing, closing).
|
||||
|
||||
* `status()` - Use this to indicate a failure to open the requested file.
|
||||
|
||||
* **READ**(< _integer_ >reqID, < _Buffer_ >handle, < _integer_ >offset, < _integer_ >length)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `data()` - Use this to send the requested chunk of data back to the client.
|
||||
The amount of data sent is allowed to be less than the `length` requested,
|
||||
for example if the file ends between `offset` and `offset + length`.
|
||||
|
||||
* `status()` - Use this to indicate either end of file (`STATUS_CODE.EOF`)
|
||||
has been reached (`offset` is past the end of the file) or if an error
|
||||
occurred while reading the requested part of the file.
|
||||
|
||||
* **WRITE**(< _integer_ >reqID, < _Buffer_ >handle, < _integer_ >offset, < _Buffer_ >data)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success/failure of the write to the file.
|
||||
|
||||
* **FSTAT**(< _integer_ >reqID, < _Buffer_ >handle)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `attrs()` - Use this to send the attributes for the requested
|
||||
file/directory back to the client.
|
||||
|
||||
* `status()` - Use this to indicate an error occurred while accessing the
|
||||
file/directory.
|
||||
|
||||
* **FSETSTAT**(< _integer_ >reqID, < _Buffer_ >handle, < _ATTRS_ >attrs)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicates success/failure of the setting of the
|
||||
given file/directory attributes.
|
||||
|
||||
* **CLOSE**(< _integer_ >reqID, < _Buffer_ >handle)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success (`STATUS_CODE.OK`) or failure of
|
||||
the closing of the file identified by `handle`.
|
||||
|
||||
* **OPENDIR**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `handle()` - This indicates a successful opening of the directory and
|
||||
passes the given handle back to the client to use to refer to this open
|
||||
directory for future operations (e.g. reading directory contents, closing).
|
||||
|
||||
* `status()` - Use this to indicate a failure to open the requested
|
||||
directory.
|
||||
|
||||
* **READDIR**(< _integer_ >reqID, < _Buffer_ >handle)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `name()` - Use this to send one or more directory listings for the open
|
||||
directory back to the client.
|
||||
|
||||
* `status()` - Use this to indicate either end of directory contents
|
||||
(`STATUS_CODE.EOF`) or if an error occurred while reading the directory
|
||||
contents.
|
||||
|
||||
* **LSTAT**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `attrs()` - Use this to send the attributes for the requested
|
||||
file/directory back to the client.
|
||||
|
||||
* `status()` - Use this to indicate an error occurred while accessing the
|
||||
file/directory.
|
||||
|
||||
* **STAT**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `attrs()` - Use this to send the attributes for the requested
|
||||
file/directory back to the client.
|
||||
|
||||
* `status()` - Use this to indicate an error occurred while accessing the
|
||||
file/directory.
|
||||
|
||||
* **REMOVE**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success/failure of the removal of the
|
||||
file at `path`.
|
||||
|
||||
* **RMDIR**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success/failure of the removal of the
|
||||
directory at `path`.
|
||||
|
||||
* **REALPATH**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `name()` - Use this to respond with a normalized version of `path`.
|
||||
No file/directory attributes are required to be sent in this response.
|
||||
|
||||
* `status()` - Use this to indicate a failure in normalizing `path`.
|
||||
|
||||
* **READLINK**(< _integer_ >reqID, < _string_ >path)
|
||||
|
||||
Respond using one of the following:
|
||||
|
||||
* `name()` - Use this to respond with the target of the symlink at `path`.
|
||||
No file/directory attributes are required to be sent in this response.
|
||||
|
||||
* `status()` - Use this to indicate a failure in reading the symlink at
|
||||
`path`.
|
||||
|
||||
* **SETSTAT**(< _integer_ >reqID, < _string_ >path, < _ATTRS_ >attrs)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicates success/failure of the setting of the
|
||||
given file/directory attributes.
|
||||
|
||||
* **MKDIR**(< _integer_ >reqID, < _string_ >path, < _ATTRS_ >attrs)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success/failure of the creation of the
|
||||
directory at `path`.
|
||||
|
||||
* **RENAME**(< _integer_ >reqID, < _string_ >oldPath, < _string_ >newPath)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success/failure of the renaming of the
|
||||
file/directory at `oldPath` to `newPath`.
|
||||
|
||||
* **SYMLINK**(< _integer_ >reqID, < _string_ >linkPath, < _string_ >targetPath)
|
||||
|
||||
Respond using:
|
||||
|
||||
* `status()` - Use this to indicate success/failure of the symlink creation.
|
||||
|
||||
|
||||
Useful standalone data structures
|
||||
---------------------------------
|
||||
|
||||
* **STATUS_CODE** - _object_ - Contains the various status codes (for use especially with `status()`):
|
||||
|
||||
* `OK`
|
||||
|
||||
* `EOF`
|
||||
|
||||
* `NO_SUCH_FILE`
|
||||
|
||||
* `PERMISSION_DENIED`
|
||||
|
||||
* `FAILURE`
|
||||
|
||||
* `BAD_MESSAGE`
|
||||
|
||||
* `OP_UNSUPPORTED`
|
||||
|
||||
* **OPEN_MODE** - _object_ - Contains the various open file flags:
|
||||
|
||||
* `READ`
|
||||
|
||||
* `WRITE`
|
||||
|
||||
* `APPEND`
|
||||
|
||||
* `CREAT`
|
||||
|
||||
* `TRUNC`
|
||||
|
||||
* `EXCL`
|
||||
|
||||
|
||||
Useful standalone methods
|
||||
-------------------------
|
||||
|
||||
* **stringToFlags**(< _string_ >flagsStr) - _integer_ - Converts string flags (e.g. `'r'`, `'a+'`, etc.) to the appropriate `OPEN_MODE` flag mask. Returns `null` if conversion failed.
|
||||
|
||||
* **flagsToString**(< _integer_ >flagsMask) - _string_ - Converts flag mask (e.g. number containing `OPEN_MODE` values) to the appropriate string value. Returns `null` if conversion failed.
|
||||
|
||||
|
||||
SFTP methods
|
||||
------------
|
||||
|
||||
* **(constructor)**(< _object_ >config[, < _string_ >remoteIdentRaw]) - Creates and returns a new SFTP instance. `remoteIdentRaw` can be the raw SSH identification string of the remote party. This is used to change internal behavior based on particular SFTP implementations. `config` can contain:
|
||||
|
||||
* **server** - _boolean_ - Set to `true` to create an instance in server mode. **Default:** `false`
|
||||
|
||||
* **debug** - _function_ - Set this to a function that receives a single string argument to get detailed (local) debug information. **Default:** (none)
|
||||
|
||||
|
||||
|
||||
**Client-only methods**
|
||||
|
||||
* **fastGet**(< _string_ >remotePath, < _string_ >localPath[, < _object_ >options], < _function_ >callback) - _(void)_ - Downloads a file at `remotePath` to `localPath` using parallel reads for faster throughput. `options` can have the following properties:
|
||||
|
||||
* **concurrency** - _integer_ - Number of concurrent reads **Default:** `64`
|
||||
|
||||
* **chunkSize** - _integer_ - Size of each read in bytes **Default:** `32768`
|
||||
|
||||
* **step** - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred
|
||||
|
||||
`callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **fastPut**(< _string_ >localPath, < _string_ >remotePath[, < _object_ >options], < _function_ >callback) - _(void)_ - Uploads a file from `localPath` to `remotePath` using parallel reads for faster throughput. `options` can have the following properties:
|
||||
|
||||
* **concurrency** - _integer_ - Number of concurrent reads **Default:** `64`
|
||||
|
||||
* **chunkSize** - _integer_ - Size of each read in bytes **Default:** `32768`
|
||||
|
||||
* **step** - _function_(< _integer_ >total_transferred, < _integer_ >chunk, < _integer_ >total) - Called every time a part of a file was transferred
|
||||
|
||||
* **mode** - _mixed_ - Integer or string representing the file mode to set for the uploaded file.
|
||||
|
||||
`callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **createReadStream**(< _string_ >path[, < _object_ >options]) - _ReadStream_ - Returns a new readable stream for `path`. `options` has the following defaults:
|
||||
|
||||
```javascript
|
||||
{ flags: 'r',
|
||||
encoding: null,
|
||||
handle: null,
|
||||
mode: 0o666,
|
||||
autoClose: true
|
||||
}
|
||||
```
|
||||
|
||||
`options` can include `start` and `end` values to read a range of bytes from the file instead of the entire file. Both `start` and `end` are inclusive and start at 0. The `encoding` can be `'utf8'`, `'ascii'`, or `'base64'`.
|
||||
|
||||
If `autoClose` is false, then the file handle won't be closed, even if there's an error. It is your responsibility to close it and make sure there's no file handle leak. If `autoClose` is set to true (default behavior), on `error` or `end` the file handle will be closed automatically.
|
||||
|
||||
An example to read the last 10 bytes of a file which is 100 bytes long:
|
||||
|
||||
```javascript
|
||||
sftp.createReadStream('sample.txt', {start: 90, end: 99});
|
||||
```
|
||||
|
||||
* **createWriteStream**(< _string_ >path[, < _object_ >options]) - _WriteStream_ - Returns a new writable stream for `path`. `options` has the following defaults:
|
||||
|
||||
```javascript
|
||||
{
|
||||
flags: 'w',
|
||||
encoding: null,
|
||||
mode: 0o666,
|
||||
autoClose: true
|
||||
}
|
||||
```
|
||||
|
||||
`options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a flags mode of 'r+' rather than the default mode 'w'.
|
||||
|
||||
If 'autoClose' is set to false and you pipe to this stream, this stream will not automatically close after there is no more data upstream -- allowing future pipes and/or manual writes.
|
||||
|
||||
* **open**(< _string_ >filename, < _string_ >flags, [< _mixed_ >attrs_mode, ]< _function_ >callback) - _(void)_ - Opens a file `filename` with `flags` with optional _ATTRS_ object or file mode `attrs_mode`. `flags` is any of the flags supported by `fs.open` (except sync flag). `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle.
|
||||
|
||||
* **close**(< _Buffer_ >handle, < _function_ >callback) - _(void)_ - Closes the resource associated with `handle` given by open() or opendir(). `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **read**(< _Buffer_ >handle, < _Buffer_ >buffer, < _integer_ >offset, < _integer_ >length, < _integer_ >position, < _function_ >callback) - _(void)_ - Reads `length` bytes from the resource associated with `handle` starting at `position` and stores the bytes in `buffer` starting at `offset`. `callback` has 4 parameters: < _Error_ >err, < _integer_ >bytesRead, < _Buffer_ >buffer (offset adjusted), < _integer_ >position.
|
||||
|
||||
* **write**(< _Buffer_ >handle, < _Buffer_ >buffer, < _integer_ >offset, < _integer_ >length, < _integer_ >position, < _function_ >callback) - _(void)_ - Writes `length` bytes from `buffer` starting at `offset` to the resource associated with `handle` starting at `position`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **fstat**(< _Buffer_ >handle, < _function_ >callback) - _(void)_ - Retrieves attributes for the resource associated with `handle`. `callback` has 2 parameters: < _Error_ >err, < _Stats_ >stats.
|
||||
|
||||
* **fsetstat**(< _Buffer_ >handle, < _ATTRS_ >attributes, < _function_ >callback) - _(void)_ - Sets the attributes defined in `attributes` for the resource associated with `handle`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **futimes**(< _Buffer_ >handle, < _mixed_ >atime, < _mixed_ >mtime, < _function_ >callback) - _(void)_ - Sets the access time and modified time for the resource associated with `handle`. `atime` and `mtime` can be Date instances or UNIX timestamps. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **fchown**(< _Buffer_ >handle, < _integer_ >uid, < _integer_ >gid, < _function_ >callback) - _(void)_ - Sets the owner for the resource associated with `handle`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **fchmod**(< _Buffer_ >handle, < _mixed_ >mode, < _function_ >callback) - _(void)_ - Sets the mode for the resource associated with `handle`. `mode` can be an integer or a string containing an octal number. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **opendir**(< _string_ >path, < _function_ >callback) - _(void)_ - Opens a directory `path`. `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle.
|
||||
|
||||
* **readdir**(< _mixed_ >location, < _function_ >callback) - _(void)_ - Retrieves a directory listing. `location` can either be a _Buffer_ containing a valid directory handle from opendir() or a _string_ containing the path to a directory. `callback` has 2 parameters: < _Error_ >err, < _mixed_ >list. `list` is an _Array_ of `{ filename: 'foo', longname: '....', attrs: {...} }` style objects (attrs is of type _ATTR_). If `location` is a directory handle, this function may need to be called multiple times until `list` is boolean false, which indicates that no more directory entries are available for that directory handle.
|
||||
|
||||
* **unlink**(< _string_ >path, < _function_ >callback) - _(void)_ - Removes the file/symlink at `path`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **rename**(< _string_ >srcPath, < _string_ >destPath, < _function_ >callback) - _(void)_ - Renames/moves `srcPath` to `destPath`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **mkdir**(< _string_ >path, [< _ATTRS_ >attributes, ]< _function_ >callback) - _(void)_ - Creates a new directory `path`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **rmdir**(< _string_ >path, < _function_ >callback) - _(void)_ - Removes the directory at `path`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **stat**(< _string_ >path, < _function_ >callback) - _(void)_ - Retrieves attributes for `path`. `callback` has 2 parameter: < _Error_ >err, < _Stats_ >stats.
|
||||
|
||||
* **lstat**(< _string_ >path, < _function_ >callback) - _(void)_ - Retrieves attributes for `path`. If `path` is a symlink, the link itself is stat'ed instead of the resource it refers to. `callback` has 2 parameters: < _Error_ >err, < _Stats_ >stats.
|
||||
|
||||
* **setstat**(< _string_ >path, < _ATTRS_ >attributes, < _function_ >callback) - _(void)_ - Sets the attributes defined in `attributes` for `path`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **utimes**(< _string_ >path, < _mixed_ >atime, < _mixed_ >mtime, < _function_ >callback) - _(void)_ - Sets the access time and modified time for `path`. `atime` and `mtime` can be Date instances or UNIX timestamps. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **chown**(< _string_ >path, < _integer_ >uid, < _integer_ >gid, < _function_ >callback) - _(void)_ - Sets the owner for `path`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **chmod**(< _string_ >path, < _mixed_ >mode, < _function_ >callback) - _(void)_ - Sets the mode for `path`. `mode` can be an integer or a string containing an octal number. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **readlink**(< _string_ >path, < _function_ >callback) - _(void)_ - Retrieves the target for a symlink at `path`. `callback` has 2 parameters: < _Error_ >err, < _string_ >target.
|
||||
|
||||
* **symlink**(< _string_ >targetPath, < _string_ >linkPath, < _function_ >callback) - _(void)_ - Creates a symlink at `linkPath` to `targetPath`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **realpath**(< _string_ >path, < _function_ >callback) - _(void)_ - Resolves `path` to an absolute path. `callback` has 2 parameters: < _Error_ >err, < _string_ >absPath.
|
||||
|
||||
* **ext_openssh_rename**(< _string_ >srcPath, < _string_ >destPath, < _function_ >callback) - _(void)_ - **OpenSSH extension** Performs POSIX rename(3) from `srcPath` to `destPath`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **ext_openssh_statvfs**(< _string_ >path, < _function_ >callback) - _(void)_ - **OpenSSH extension** Performs POSIX statvfs(2) on `path`. `callback` has 2 parameters: < _Error_ >err, < _object_ >fsInfo. `fsInfo` contains the information as found in the [statvfs struct](http://linux.die.net/man/2/statvfs).
|
||||
|
||||
* **ext_openssh_fstatvfs**(< _Buffer_ >handle, < _function_ >callback) - _(void)_ - **OpenSSH extension** Performs POSIX fstatvfs(2) on open handle `handle`. `callback` has 2 parameters: < _Error_ >err, < _object_ >fsInfo. `fsInfo` contains the information as found in the [statvfs struct](http://linux.die.net/man/2/statvfs).
|
||||
|
||||
* **ext_openssh_hardlink**(< _string_ >targetPath, < _string_ >linkPath, < _function_ >callback) - _(void)_ - **OpenSSH extension** Performs POSIX link(2) to create a hard link to `targetPath` at `linkPath`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **ext_openssh_fsync**(< _Buffer_ >handle, < _function_ >callback) - _(void)_ - **OpenSSH extension** Performs POSIX fsync(3) on the open handle `handle`. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **ext_openssh_lsetstat**(< _string_ >path, < _ATTRS_ >attributes, < _function_ >callback) - _(void)_ - **OpenSSH extension** Similar to `setstat()`, but instead sets attributes on symlinks. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **ext_openssh_expandPath**(< _string_ >path, < _function_ >callback) - _(void)_ - **OpenSSH extension** Similar to `realpath()`, but supports tilde-expansion, i.e. "\~", "\~/..." and "\~user/...". These paths are expanded using shell-like rules. `callback` has 2 parameters: < _Error_ >err, < _string_ >expandedPath.
|
||||
|
||||
* **ext_copy_data**(< _Buffer_ >srcHandle, < _number_ >srcOffset, < _number_ >length, < _Buffer_ >dstHandle, < _number_ >dstOffset, < _function_ >callback) - _(void)_ - Performs a remote file copy. If `length` is 0, then the server will read from `srcHandle` until EOF is reached. `callback` has 1 parameter: < _Error_ >err.
|
||||
|
||||
* **ext_home_dir**(< _string_ >username, < _function_ >callback) - _(void)_ - Retrieves the home directory of the user identified by `username`. Use an empty string to refer to the current user. `callback` has 2 parameters: < _Error_ >err, < _string_ >homeDirectory.
|
||||
|
||||
* **ext_users_groups**(< _array_ >uids, < _array_ >gids, < _function_ >callback) - _(void)_ - Retrieves the user names and group names associated with the user IDs in `uids` and group IDs in `gids` respectively. Either array can be empty or contain one or more 32-bit unsigned integers. The retrieved user names and group names match the same order as the IDs in `uids` and `gids` respectively. If the server was unable to find a name for a given ID, it will use an empty string. `callback` has 3 parameters: < _Error_ >err, < _array_ >userNames, < _array_ >groupNames.
|
||||
|
||||
|
||||
**Server-only methods**
|
||||
|
||||
* **status**(< _integer_ >reqID, < _integer_ >statusCode[, < _string_ >message]) - _(void)_ - Sends a status response for the request identified by `id`.
|
||||
|
||||
* **handle**(< _integer_ >reqID, < _Buffer_ >handle) - _(void)_ - Sends a handle response for the request identified by `id`. `handle` must be less than 256 bytes and is an opaque value that could merely contain the value of a backing file descriptor or some other unique, custom value.
|
||||
|
||||
* **data**(< _integer_ >reqID, < _mixed_ >data[, < _string_ >encoding]) - _(void)_ - Sends a data response for the request identified by `id`. `data` can be a _Buffer_ or _string_. If `data` is a string, `encoding` is the encoding of `data`.
|
||||
|
||||
* **name**(< _integer_ >reqID, < _array_ >names) - _(void)_ - Sends a name response for the request identified by `id`. `names` must be an _array_ of _object_ where each _object_ can contain:
|
||||
|
||||
* **filename** - _string_ - The entry's name.
|
||||
|
||||
* **longname** - _string_ - This is the `ls -l`-style format for the entry (e.g. `-rwxr--r-- 1 bar bar 718 Dec 8 2009 foo`)
|
||||
|
||||
* **attrs** - _ATTRS_ - This is an optional _ATTRS_ object that contains requested/available attributes for the entry.
|
||||
|
||||
* **attrs**(< _integer_ >reqID, < _ATTRS_ >attrs) - _(void)_ - Sends an attrs response for the request identified by `id`. `attrs` contains the requested/available attributes.
|
||||
|
||||
|
||||
ATTRS
|
||||
-----
|
||||
|
||||
An object with the following valid properties:
|
||||
|
||||
* **mode** - _integer_ - Mode/permissions for the resource.
|
||||
|
||||
* **uid** - _integer_ - User ID of the resource.
|
||||
|
||||
* **gid** - _integer_ - Group ID of the resource.
|
||||
|
||||
* **size** - _integer_ - Resource size in bytes.
|
||||
|
||||
* **atime** - _integer_ - UNIX timestamp of the access time of the resource.
|
||||
|
||||
* **mtime** - _integer_ - UNIX timestamp of the modified time of the resource.
|
||||
|
||||
When supplying an ATTRS object to one of the SFTP methods:
|
||||
|
||||
* `atime` and `mtime` can be either a Date instance or a UNIX timestamp.
|
||||
|
||||
* `mode` can either be an integer or a string containing an octal number.
|
||||
|
||||
|
||||
Stats
|
||||
-----
|
||||
|
||||
An object with the same attributes as an ATTRS object with the addition of the following methods:
|
||||
|
||||
* `stats.isDirectory()`
|
||||
|
||||
* `stats.isFile()`
|
||||
|
||||
* `stats.isBlockDevice()`
|
||||
|
||||
* `stats.isCharacterDevice()`
|
||||
|
||||
* `stats.isSymbolicLink()`
|
||||
|
||||
* `stats.isFIFO()`
|
||||
|
||||
* `stats.isSocket()`
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
// **BEFORE RUNNING THIS SCRIPT:**
|
||||
// 1. The server portion is best run on non-Windows systems because they have
|
||||
// terminfo databases which are needed to properly work with different
|
||||
// terminal types of client connections
|
||||
// 2. Install `blessed`: `npm install blessed`
|
||||
// 3. Create a server host key in this same directory and name it `host.key`
|
||||
'use strict';
|
||||
|
||||
const { readFileSync } = require('fs');
|
||||
|
||||
const blessed = require('blessed');
|
||||
const { Server } = require('ssh2');
|
||||
|
||||
const RE_SPECIAL =
|
||||
// eslint-disable-next-line no-control-regex
|
||||
/[\x00-\x1F\x7F]+|(?:\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K])/g;
|
||||
const MAX_MSG_LEN = 128;
|
||||
const MAX_NAME_LEN = 10;
|
||||
const PROMPT_NAME = `Enter a nickname to use (max ${MAX_NAME_LEN} chars): `;
|
||||
|
||||
const users = [];
|
||||
|
||||
function formatMessage(msg, output) {
|
||||
output.parseTags = true;
|
||||
msg = output._parseTags(msg);
|
||||
output.parseTags = false;
|
||||
return msg;
|
||||
}
|
||||
|
||||
function userBroadcast(msg, source) {
|
||||
const sourceMsg = `> ${msg}`;
|
||||
const name = `{cyan-fg}{bold}${source.name}{/}`;
|
||||
msg = `: ${msg}`;
|
||||
for (const user of users) {
|
||||
const output = user.output;
|
||||
if (source === user)
|
||||
output.add(sourceMsg);
|
||||
else
|
||||
output.add(formatMessage(name, output) + msg);
|
||||
}
|
||||
}
|
||||
|
||||
function localMessage(msg, source) {
|
||||
const output = source.output;
|
||||
output.add(formatMessage(msg, output));
|
||||
}
|
||||
|
||||
function noop(v) {}
|
||||
|
||||
new Server({
|
||||
hostKeys: [readFileSync('host.key')],
|
||||
}, (client) => {
|
||||
let stream;
|
||||
let name;
|
||||
|
||||
client.on('authentication', (ctx) => {
|
||||
let nick = ctx.username;
|
||||
let prompt = PROMPT_NAME;
|
||||
let lowered;
|
||||
|
||||
// Try to use username as nickname
|
||||
if (nick.length > 0 && nick.length <= MAX_NAME_LEN) {
|
||||
lowered = nick.toLowerCase();
|
||||
let ok = true;
|
||||
for (const user of users) {
|
||||
if (user.name.toLowerCase() === lowered) {
|
||||
ok = false;
|
||||
prompt = `That nickname is already in use.\n${PROMPT_NAME}`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
name = nick;
|
||||
return ctx.accept();
|
||||
}
|
||||
} else if (nick.length === 0) {
|
||||
prompt = 'A nickname is required.\n' + PROMPT_NAME;
|
||||
} else {
|
||||
prompt = 'That nickname is too long.\n' + PROMPT_NAME;
|
||||
}
|
||||
|
||||
if (ctx.method !== 'keyboard-interactive')
|
||||
return ctx.reject(['keyboard-interactive']);
|
||||
|
||||
ctx.prompt(prompt, function retryPrompt(answers) {
|
||||
if (answers.length === 0)
|
||||
return ctx.reject(['keyboard-interactive']);
|
||||
nick = answers[0];
|
||||
if (nick.length > MAX_NAME_LEN) {
|
||||
return ctx.prompt(`That nickname is too long.\n${PROMPT_NAME}`,
|
||||
retryPrompt);
|
||||
} else if (nick.length === 0) {
|
||||
return ctx.prompt(`A nickname is required.\n${PROMPT_NAME}`,
|
||||
retryPrompt);
|
||||
}
|
||||
lowered = nick.toLowerCase();
|
||||
for (const user of users) {
|
||||
if (user.name.toLowerCase() === lowered) {
|
||||
return ctx.prompt(`That nickname is already in use.\n${PROMPT_NAME}`,
|
||||
retryPrompt);
|
||||
}
|
||||
}
|
||||
name = nick;
|
||||
ctx.accept();
|
||||
});
|
||||
}).on('ready', () => {
|
||||
let rows;
|
||||
let cols;
|
||||
let term;
|
||||
client.once('session', (accept, reject) => {
|
||||
accept().once('pty', (accept, reject, info) => {
|
||||
rows = info.rows;
|
||||
cols = info.cols;
|
||||
term = info.term;
|
||||
accept && accept();
|
||||
}).on('window-change', (accept, reject, info) => {
|
||||
rows = info.rows;
|
||||
cols = info.cols;
|
||||
if (stream) {
|
||||
stream.rows = rows;
|
||||
stream.columns = cols;
|
||||
stream.emit('resize');
|
||||
}
|
||||
accept && accept();
|
||||
}).once('shell', (accept, reject) => {
|
||||
stream = accept();
|
||||
users.push(stream);
|
||||
|
||||
stream.name = name;
|
||||
stream.rows = rows || 24;
|
||||
stream.columns = cols || 80;
|
||||
stream.isTTY = true;
|
||||
stream.setRawMode = noop;
|
||||
stream.on('error', noop);
|
||||
|
||||
const screen = new blessed.screen({
|
||||
autoPadding: true,
|
||||
smartCSR: true,
|
||||
program: new blessed.program({
|
||||
input: stream,
|
||||
output: stream
|
||||
}),
|
||||
terminal: term || 'ansi'
|
||||
});
|
||||
|
||||
screen.title = 'SSH Chatting as ' + name;
|
||||
// Disable local echo
|
||||
screen.program.attr('invisible', true);
|
||||
|
||||
const output = stream.output = new blessed.log({
|
||||
screen: screen,
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
bottom: 2,
|
||||
scrollOnInput: true
|
||||
});
|
||||
screen.append(output);
|
||||
|
||||
screen.append(new blessed.box({
|
||||
screen: screen,
|
||||
height: 1,
|
||||
bottom: 1,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
type: 'line',
|
||||
ch: '='
|
||||
}));
|
||||
|
||||
const input = new blessed.textbox({
|
||||
screen: screen,
|
||||
bottom: 0,
|
||||
height: 1,
|
||||
width: '100%',
|
||||
inputOnFocus: true
|
||||
});
|
||||
screen.append(input);
|
||||
|
||||
input.focus();
|
||||
|
||||
// Local greetings
|
||||
localMessage('{blue-bg}{white-fg}{bold}Welcome to SSH Chat!{/}\n'
|
||||
+ 'There are {bold}'
|
||||
+ (users.length - 1)
|
||||
+ '{/} other user(s) connected.\n'
|
||||
+ 'Type /quit or /exit to exit the chat.',
|
||||
stream);
|
||||
|
||||
// Let everyone else know that this user just joined
|
||||
for (const user of users) {
|
||||
const output = user.output;
|
||||
if (user === stream)
|
||||
continue;
|
||||
output.add(formatMessage('{green-fg}*** {bold}', output)
|
||||
+ name
|
||||
+ formatMessage('{/bold} has joined the chat{/}', output));
|
||||
}
|
||||
|
||||
screen.render();
|
||||
// XXX This fake resize event is needed for some terminals in order to
|
||||
// have everything display correctly
|
||||
screen.program.emit('resize');
|
||||
|
||||
// Read a line of input from the user
|
||||
input.on('submit', (line) => {
|
||||
input.clearValue();
|
||||
screen.render();
|
||||
if (!input.focused)
|
||||
input.focus();
|
||||
line = line.replace(RE_SPECIAL, '').trim();
|
||||
if (line.length > MAX_MSG_LEN)
|
||||
line = line.substring(0, MAX_MSG_LEN);
|
||||
if (line.length > 0) {
|
||||
if (line === '/quit' || line === '/exit')
|
||||
stream.end();
|
||||
else
|
||||
userBroadcast(line, stream);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}).on('close', () => {
|
||||
if (stream !== undefined) {
|
||||
users.splice(users.indexOf(stream), 1);
|
||||
// Let everyone else know that this user just left
|
||||
for (const user of users) {
|
||||
const output = user.output;
|
||||
output.add(formatMessage('{magenta-fg}*** {bold}', output)
|
||||
+ name
|
||||
+ formatMessage('{/bold} has left the chat{/}', output));
|
||||
}
|
||||
}
|
||||
}).on('error', (err) => {
|
||||
// Ignore errors
|
||||
});
|
||||
}).listen(0, function() {
|
||||
console.log('Listening on port ' + this.address().port);
|
||||
});
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
'use strict';
|
||||
|
||||
const { timingSafeEqual } = require('crypto');
|
||||
const { constants, readFileSync } = require('fs');
|
||||
|
||||
const { Server, sftp: { OPEN_MODE, STATUS_CODE } } = require('ssh2');
|
||||
|
||||
const allowedUser = Buffer.from('foo');
|
||||
const allowedPassword = Buffer.from('bar');
|
||||
|
||||
function checkValue(input, allowed) {
|
||||
const autoReject = (input.length !== allowed.length);
|
||||
if (autoReject) {
|
||||
// Prevent leaking length information by always making a comparison with the
|
||||
// same input when lengths don't match what we expect ...
|
||||
allowed = input;
|
||||
}
|
||||
const isMatch = timingSafeEqual(input, allowed);
|
||||
return (!autoReject && isMatch);
|
||||
}
|
||||
|
||||
new Server({
|
||||
hostKeys: [readFileSync('host.key')]
|
||||
}, (client) => {
|
||||
console.log('Client connected!');
|
||||
|
||||
client.on('authentication', (ctx) => {
|
||||
let allowed = true;
|
||||
if (!checkValue(Buffer.from(ctx.username), allowedUser))
|
||||
allowed = false;
|
||||
|
||||
switch (ctx.method) {
|
||||
case 'password':
|
||||
if (!checkValue(Buffer.from(ctx.password), allowedPassword))
|
||||
return ctx.reject();
|
||||
break;
|
||||
default:
|
||||
return ctx.reject();
|
||||
}
|
||||
|
||||
if (allowed)
|
||||
ctx.accept();
|
||||
else
|
||||
ctx.reject();
|
||||
}).on('ready', () => {
|
||||
console.log('Client authenticated!');
|
||||
|
||||
client.on('session', (accept, reject) => {
|
||||
const session = accept();
|
||||
session.on('sftp', (accept, reject) => {
|
||||
console.log('Client SFTP session');
|
||||
|
||||
const openFiles = new Map();
|
||||
let handleCount = 0;
|
||||
const sftp = accept();
|
||||
sftp.on('OPEN', (reqid, filename, flags, attrs) => {
|
||||
// Only allow opening /tmp/foo.txt for writing
|
||||
if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.READ))
|
||||
return sftp.status(reqid, STATUS_CODE.FAILURE);
|
||||
|
||||
// Create a fake handle to return to the client, this could easily
|
||||
// be a real file descriptor number for example if actually opening
|
||||
// the file on the disk
|
||||
const handle = Buffer.alloc(4);
|
||||
openFiles.set(handleCount, { read: false });
|
||||
handle.writeUInt32BE(handleCount++, 0, true);
|
||||
|
||||
console.log('Opening file for read');
|
||||
sftp.handle(reqid, handle);
|
||||
}).on('READ', (reqid, handle, offset, length) => {
|
||||
let fnum;
|
||||
if (handle.length !== 4
|
||||
|| !openFiles.has(fnum = handle.readUInt32BE(0, true))) {
|
||||
return sftp.status(reqid, STATUS_CODE.FAILURE);
|
||||
}
|
||||
|
||||
// Fake the read
|
||||
const state = openFiles.get(fnum);
|
||||
if (state.read) {
|
||||
sftp.status(reqid, STATUS_CODE.EOF);
|
||||
} else {
|
||||
state.read = true;
|
||||
|
||||
console.log(
|
||||
'Read from file at offset %d, length %d', offset, length
|
||||
);
|
||||
sftp.data(reqid, 'bar');
|
||||
}
|
||||
}).on('CLOSE', (reqid, handle) => {
|
||||
let fnum;
|
||||
if (handle.length !== 4
|
||||
|| !openFiles.has(fnum = handle.readUInt32BE(0))) {
|
||||
return sftp.status(reqid, STATUS_CODE.FAILURE);
|
||||
}
|
||||
|
||||
openFiles.delete(fnum);
|
||||
|
||||
console.log('Closing file');
|
||||
sftp.status(reqid, STATUS_CODE.OK);
|
||||
}).on('REALPATH', function(reqid, path) {
|
||||
const name = [{
|
||||
filename: '/tmp/foo.txt',
|
||||
longname: '-rwxrwxrwx 1 foo foo 3 Dec 8 2009 foo.txt',
|
||||
attrs: {}
|
||||
}];
|
||||
sftp.name(reqid, name);
|
||||
}).on('STAT', onSTAT)
|
||||
.on('LSTAT', onSTAT);
|
||||
|
||||
function onSTAT(reqid, path) {
|
||||
if (path !== '/tmp/foo.txt')
|
||||
return sftp.status(reqid, STATUS_CODE.FAILURE);
|
||||
|
||||
let mode = constants.S_IFREG; // Regular file
|
||||
mode |= constants.S_IRWXU; // Read, write, execute for user
|
||||
mode |= constants.S_IRWXG; // Read, write, execute for group
|
||||
mode |= constants.S_IRWXO; // Read, write, execute for other
|
||||
sftp.attrs(reqid, {
|
||||
mode: mode,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
size: 3,
|
||||
atime: Date.now(),
|
||||
mtime: Date.now(),
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}).on('close', () => {
|
||||
console.log('Client disconnected');
|
||||
});
|
||||
}).listen(0, '127.0.0.1', function() {
|
||||
console.log(`Listening on port ${this.address().port}`);
|
||||
});
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const { spawnSync } = require('child_process');
|
||||
|
||||
const forceFailOnNonZero = (process.env.CI_CHECK_FAIL === 'ssh2');
|
||||
|
||||
// Attempt to build the bundled optional binding
|
||||
const args = [
|
||||
`--target=${process.version}`,
|
||||
`--real_openssl_major=${/^\d+/.exec(process.versions.openssl)[0]}`,
|
||||
'rebuild',
|
||||
];
|
||||
const result = spawnSync('node-gyp', args, {
|
||||
cwd: 'lib/protocol/crypto',
|
||||
encoding: 'utf8',
|
||||
shell: true,
|
||||
stdio: 'inherit',
|
||||
windowsHide: true,
|
||||
});
|
||||
if (result.error || result.status !== 0) {
|
||||
console.log('Failed to build optional crypto binding');
|
||||
if (forceFailOnNonZero)
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log('Succeeded in building optional crypto binding');
|
||||
}
|
||||
process.exit(0);
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
Duplex: DuplexStream,
|
||||
Readable: ReadableStream,
|
||||
Writable: WritableStream,
|
||||
} = require('stream');
|
||||
|
||||
const {
|
||||
CHANNEL_EXTENDED_DATATYPE: { STDERR },
|
||||
} = require('./protocol/constants.js');
|
||||
const { bufferSlice } = require('./protocol/utils.js');
|
||||
|
||||
const PACKET_SIZE = 32 * 1024;
|
||||
const MAX_WINDOW = 2 * 1024 * 1024;
|
||||
const WINDOW_THRESHOLD = MAX_WINDOW / 2;
|
||||
|
||||
class ClientStderr extends ReadableStream {
|
||||
constructor(channel, streamOpts) {
|
||||
super(streamOpts);
|
||||
|
||||
this._channel = channel;
|
||||
}
|
||||
_read(n) {
|
||||
if (this._channel._waitChanDrain) {
|
||||
this._channel._waitChanDrain = false;
|
||||
if (this._channel.incoming.window <= WINDOW_THRESHOLD)
|
||||
windowAdjust(this._channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ServerStderr extends WritableStream {
|
||||
constructor(channel) {
|
||||
super({ highWaterMark: MAX_WINDOW });
|
||||
|
||||
this._channel = channel;
|
||||
}
|
||||
|
||||
_write(data, encoding, cb) {
|
||||
const channel = this._channel;
|
||||
const protocol = channel._client._protocol;
|
||||
const outgoing = channel.outgoing;
|
||||
const packetSize = outgoing.packetSize;
|
||||
const id = outgoing.id;
|
||||
let window = outgoing.window;
|
||||
const len = data.length;
|
||||
let p = 0;
|
||||
|
||||
if (outgoing.state !== 'open')
|
||||
return;
|
||||
|
||||
while (len - p > 0 && window > 0) {
|
||||
let sliceLen = len - p;
|
||||
if (sliceLen > window)
|
||||
sliceLen = window;
|
||||
if (sliceLen > packetSize)
|
||||
sliceLen = packetSize;
|
||||
|
||||
if (p === 0 && sliceLen === len)
|
||||
protocol.channelExtData(id, data, STDERR);
|
||||
else
|
||||
protocol.channelExtData(id, bufferSlice(data, p, p + sliceLen), STDERR);
|
||||
|
||||
p += sliceLen;
|
||||
window -= sliceLen;
|
||||
}
|
||||
|
||||
outgoing.window = window;
|
||||
|
||||
if (len - p > 0) {
|
||||
if (window === 0)
|
||||
channel._waitWindow = true;
|
||||
if (p > 0)
|
||||
channel._chunkErr = bufferSlice(data, p, len);
|
||||
else
|
||||
channel._chunkErr = data;
|
||||
channel._chunkcbErr = cb;
|
||||
return;
|
||||
}
|
||||
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
class Channel extends DuplexStream {
|
||||
constructor(client, info, opts) {
|
||||
const streamOpts = {
|
||||
highWaterMark: MAX_WINDOW,
|
||||
allowHalfOpen: (!opts || (opts && opts.allowHalfOpen !== false)),
|
||||
emitClose: false,
|
||||
};
|
||||
super(streamOpts);
|
||||
this.allowHalfOpen = streamOpts.allowHalfOpen;
|
||||
|
||||
const server = !!(opts && opts.server);
|
||||
|
||||
this.server = server;
|
||||
this.type = info.type;
|
||||
this.subtype = undefined;
|
||||
|
||||
/*
|
||||
incoming and outgoing contain these properties:
|
||||
{
|
||||
id: undefined,
|
||||
window: undefined,
|
||||
packetSize: undefined,
|
||||
state: 'closed'
|
||||
}
|
||||
*/
|
||||
this.incoming = info.incoming;
|
||||
this.outgoing = info.outgoing;
|
||||
this._callbacks = [];
|
||||
|
||||
this._client = client;
|
||||
this._hasX11 = false;
|
||||
this._exit = {
|
||||
code: undefined,
|
||||
signal: undefined,
|
||||
dump: undefined,
|
||||
desc: undefined,
|
||||
};
|
||||
|
||||
this.stdin = this.stdout = this;
|
||||
|
||||
if (server)
|
||||
this.stderr = new ServerStderr(this);
|
||||
else
|
||||
this.stderr = new ClientStderr(this, streamOpts);
|
||||
|
||||
// Outgoing data
|
||||
this._waitWindow = false; // SSH-level backpressure
|
||||
|
||||
// Incoming data
|
||||
this._waitChanDrain = false; // Channel Readable side backpressure
|
||||
|
||||
this._chunk = undefined;
|
||||
this._chunkcb = undefined;
|
||||
this._chunkErr = undefined;
|
||||
this._chunkcbErr = undefined;
|
||||
|
||||
this.on('finish', onFinish)
|
||||
.on('prefinish', onFinish); // For node v0.11+
|
||||
|
||||
this.on('end', onEnd).on('close', onEnd);
|
||||
}
|
||||
|
||||
_read(n) {
|
||||
if (this._waitChanDrain) {
|
||||
this._waitChanDrain = false;
|
||||
if (this.incoming.window <= WINDOW_THRESHOLD)
|
||||
windowAdjust(this);
|
||||
}
|
||||
}
|
||||
|
||||
_write(data, encoding, cb) {
|
||||
const protocol = this._client._protocol;
|
||||
const outgoing = this.outgoing;
|
||||
const packetSize = outgoing.packetSize;
|
||||
const id = outgoing.id;
|
||||
let window = outgoing.window;
|
||||
const len = data.length;
|
||||
let p = 0;
|
||||
|
||||
if (outgoing.state !== 'open')
|
||||
return;
|
||||
|
||||
while (len - p > 0 && window > 0) {
|
||||
let sliceLen = len - p;
|
||||
if (sliceLen > window)
|
||||
sliceLen = window;
|
||||
if (sliceLen > packetSize)
|
||||
sliceLen = packetSize;
|
||||
|
||||
if (p === 0 && sliceLen === len)
|
||||
protocol.channelData(id, data);
|
||||
else
|
||||
protocol.channelData(id, bufferSlice(data, p, p + sliceLen));
|
||||
|
||||
p += sliceLen;
|
||||
window -= sliceLen;
|
||||
}
|
||||
|
||||
outgoing.window = window;
|
||||
|
||||
if (len - p > 0) {
|
||||
if (window === 0)
|
||||
this._waitWindow = true;
|
||||
if (p > 0)
|
||||
this._chunk = bufferSlice(data, p, len);
|
||||
else
|
||||
this._chunk = data;
|
||||
this._chunkcb = cb;
|
||||
return;
|
||||
}
|
||||
|
||||
cb();
|
||||
}
|
||||
|
||||
eof() {
|
||||
if (this.outgoing.state === 'open') {
|
||||
this.outgoing.state = 'eof';
|
||||
this._client._protocol.channelEOF(this.outgoing.id);
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.outgoing.state === 'open' || this.outgoing.state === 'eof') {
|
||||
this.outgoing.state = 'closing';
|
||||
this._client._protocol.channelClose(this.outgoing.id);
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.end();
|
||||
this.close();
|
||||
return this;
|
||||
}
|
||||
|
||||
// Session type-specific methods =============================================
|
||||
setWindow(rows, cols, height, width) {
|
||||
if (this.server)
|
||||
throw new Error('Client-only method called in server mode');
|
||||
|
||||
if (this.type === 'session'
|
||||
&& (this.subtype === 'shell' || this.subtype === 'exec')
|
||||
&& this.writable
|
||||
&& this.outgoing.state === 'open') {
|
||||
this._client._protocol.windowChange(this.outgoing.id,
|
||||
rows,
|
||||
cols,
|
||||
height,
|
||||
width);
|
||||
}
|
||||
}
|
||||
|
||||
signal(signalName) {
|
||||
if (this.server)
|
||||
throw new Error('Client-only method called in server mode');
|
||||
|
||||
if (this.type === 'session'
|
||||
&& this.writable
|
||||
&& this.outgoing.state === 'open') {
|
||||
this._client._protocol.signal(this.outgoing.id, signalName);
|
||||
}
|
||||
}
|
||||
|
||||
exit(statusOrSignal, coreDumped, msg) {
|
||||
if (!this.server)
|
||||
throw new Error('Server-only method called in client mode');
|
||||
|
||||
if (this.type === 'session'
|
||||
&& this.writable
|
||||
&& this.outgoing.state === 'open') {
|
||||
if (typeof statusOrSignal === 'number') {
|
||||
this._client._protocol.exitStatus(this.outgoing.id, statusOrSignal);
|
||||
} else {
|
||||
this._client._protocol.exitSignal(this.outgoing.id,
|
||||
statusOrSignal,
|
||||
coreDumped,
|
||||
msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onFinish() {
|
||||
this.eof();
|
||||
if (this.server || !this.allowHalfOpen)
|
||||
this.close();
|
||||
this.writable = false;
|
||||
}
|
||||
|
||||
function onEnd() {
|
||||
this.readable = false;
|
||||
}
|
||||
|
||||
function windowAdjust(self) {
|
||||
if (self.outgoing.state === 'closed')
|
||||
return;
|
||||
const amt = MAX_WINDOW - self.incoming.window;
|
||||
if (amt <= 0)
|
||||
return;
|
||||
self.incoming.window += amt;
|
||||
self._client._protocol.channelWindowAdjust(self.outgoing.id, amt);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Channel,
|
||||
MAX_WINDOW,
|
||||
PACKET_SIZE,
|
||||
windowAdjust,
|
||||
WINDOW_THRESHOLD,
|
||||
};
|
||||
+1123
File diff suppressed because it is too large
Load Diff
+2176
File diff suppressed because it is too large
Load Diff
+84
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const { Agent: HttpAgent } = require('http');
|
||||
const { Agent: HttpsAgent } = require('https');
|
||||
const { connect: tlsConnect } = require('tls');
|
||||
|
||||
let Client;
|
||||
|
||||
for (const ctor of [HttpAgent, HttpsAgent]) {
|
||||
class SSHAgent extends ctor {
|
||||
constructor(connectCfg, agentOptions) {
|
||||
super(agentOptions);
|
||||
|
||||
this._connectCfg = connectCfg;
|
||||
this._defaultSrcIP = (agentOptions && agentOptions.srcIP) || 'localhost';
|
||||
}
|
||||
|
||||
createConnection(options, cb) {
|
||||
const srcIP = (options && options.localAddress) || this._defaultSrcIP;
|
||||
const srcPort = (options && options.localPort) || 0;
|
||||
const dstIP = options.host;
|
||||
const dstPort = options.port;
|
||||
|
||||
if (Client === undefined)
|
||||
Client = require('./client.js');
|
||||
|
||||
const client = new Client();
|
||||
let triedForward = false;
|
||||
client.on('ready', () => {
|
||||
client.forwardOut(srcIP, srcPort, dstIP, dstPort, (err, stream) => {
|
||||
triedForward = true;
|
||||
if (err) {
|
||||
client.end();
|
||||
return cb(err);
|
||||
}
|
||||
stream.once('close', () => client.end());
|
||||
cb(null, decorateStream(stream, ctor, options));
|
||||
});
|
||||
}).on('error', cb).on('close', () => {
|
||||
if (!triedForward)
|
||||
cb(new Error('Unexpected connection close'));
|
||||
}).connect(this._connectCfg);
|
||||
}
|
||||
}
|
||||
|
||||
exports[ctor === HttpAgent ? 'SSHTTPAgent' : 'SSHTTPSAgent'] = SSHAgent;
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
|
||||
function decorateStream(stream, ctor, options) {
|
||||
if (ctor === HttpAgent) {
|
||||
// HTTP
|
||||
stream.setKeepAlive = noop;
|
||||
stream.setNoDelay = noop;
|
||||
stream.setTimeout = noop;
|
||||
stream.ref = noop;
|
||||
stream.unref = noop;
|
||||
stream.destroySoon = stream.destroy;
|
||||
return stream;
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
options.socket = stream;
|
||||
const wrapped = tlsConnect(options);
|
||||
|
||||
// This is a workaround for a regression in node v12.16.3+
|
||||
// https://github.com/nodejs/node/issues/35904
|
||||
const onClose = (() => {
|
||||
let called = false;
|
||||
return () => {
|
||||
if (called)
|
||||
return;
|
||||
called = true;
|
||||
if (stream.isPaused())
|
||||
stream.resume();
|
||||
};
|
||||
})();
|
||||
// 'end' listener is needed because 'close' is not emitted in some scenarios
|
||||
// in node v12.x for some unknown reason
|
||||
wrapped.on('end', onClose).on('close', onClose);
|
||||
|
||||
return wrapped;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
AgentProtocol,
|
||||
BaseAgent,
|
||||
createAgent,
|
||||
CygwinAgent,
|
||||
OpenSSHAgent,
|
||||
PageantAgent,
|
||||
} = require('./agent.js');
|
||||
const {
|
||||
SSHTTPAgent: HTTPAgent,
|
||||
SSHTTPSAgent: HTTPSAgent,
|
||||
} = require('./http-agents.js');
|
||||
const { parseKey } = require('./protocol/keyParser.js');
|
||||
const {
|
||||
flagsToString,
|
||||
OPEN_MODE,
|
||||
STATUS_CODE,
|
||||
stringToFlags,
|
||||
} = require('./protocol/SFTP.js');
|
||||
|
||||
module.exports = {
|
||||
AgentProtocol,
|
||||
BaseAgent,
|
||||
createAgent,
|
||||
Client: require('./client.js'),
|
||||
CygwinAgent,
|
||||
HTTPAgent,
|
||||
HTTPSAgent,
|
||||
OpenSSHAgent,
|
||||
PageantAgent,
|
||||
Server: require('./server.js'),
|
||||
utils: {
|
||||
parseKey,
|
||||
...require('./keygen.js'),
|
||||
sftp: {
|
||||
flagsToString,
|
||||
OPEN_MODE,
|
||||
STATUS_CODE,
|
||||
stringToFlags,
|
||||
},
|
||||
},
|
||||
};
|
||||
+582
@@ -0,0 +1,582 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
createCipheriv,
|
||||
generateKeyPair: generateKeyPair_,
|
||||
generateKeyPairSync: generateKeyPairSync_,
|
||||
getCurves,
|
||||
randomBytes,
|
||||
} = require('crypto');
|
||||
|
||||
const { Ber } = require('asn1');
|
||||
const bcrypt_pbkdf = require('bcrypt-pbkdf').pbkdf;
|
||||
|
||||
const { CIPHER_INFO } = require('./protocol/crypto.js');
|
||||
|
||||
const SALT_LEN = 16;
|
||||
const DEFAULT_ROUNDS = 16;
|
||||
|
||||
const curves = getCurves();
|
||||
const ciphers = new Map(Object.entries(CIPHER_INFO));
|
||||
|
||||
function makeArgs(type, opts) {
|
||||
if (typeof type !== 'string')
|
||||
throw new TypeError('Key type must be a string');
|
||||
|
||||
const publicKeyEncoding = { type: 'spki', format: 'der' };
|
||||
const privateKeyEncoding = { type: 'pkcs8', format: 'der' };
|
||||
|
||||
switch (type.toLowerCase()) {
|
||||
case 'rsa': {
|
||||
if (typeof opts !== 'object' || opts === null)
|
||||
throw new TypeError('Missing options object for RSA key');
|
||||
const modulusLength = opts.bits;
|
||||
if (!Number.isInteger(modulusLength))
|
||||
throw new TypeError('RSA bits must be an integer');
|
||||
if (modulusLength <= 0 || modulusLength > 16384)
|
||||
throw new RangeError('RSA bits must be non-zero and <= 16384');
|
||||
return ['rsa', { modulusLength, publicKeyEncoding, privateKeyEncoding }];
|
||||
}
|
||||
case 'ecdsa': {
|
||||
if (typeof opts !== 'object' || opts === null)
|
||||
throw new TypeError('Missing options object for ECDSA key');
|
||||
if (!Number.isInteger(opts.bits))
|
||||
throw new TypeError('ECDSA bits must be an integer');
|
||||
let namedCurve;
|
||||
switch (opts.bits) {
|
||||
case 256:
|
||||
namedCurve = 'prime256v1';
|
||||
break;
|
||||
case 384:
|
||||
namedCurve = 'secp384r1';
|
||||
break;
|
||||
case 521:
|
||||
namedCurve = 'secp521r1';
|
||||
break;
|
||||
default:
|
||||
throw new Error('ECDSA bits must be 256, 384, or 521');
|
||||
}
|
||||
if (!curves.includes(namedCurve))
|
||||
throw new Error('Unsupported ECDSA bits value');
|
||||
return ['ec', { namedCurve, publicKeyEncoding, privateKeyEncoding }];
|
||||
}
|
||||
case 'ed25519':
|
||||
return ['ed25519', { publicKeyEncoding, privateKeyEncoding }];
|
||||
default:
|
||||
throw new Error(`Unsupported key type: ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseDERs(keyType, pub, priv) {
|
||||
switch (keyType) {
|
||||
case 'rsa': {
|
||||
// Note: we don't need to parse the public key since the PKCS8 private key
|
||||
// already includes the public key parameters
|
||||
|
||||
// Parse private key
|
||||
let reader = new Ber.Reader(priv);
|
||||
reader.readSequence();
|
||||
|
||||
// - Version
|
||||
if (reader.readInt() !== 0)
|
||||
throw new Error('Unsupported version in RSA private key');
|
||||
|
||||
// - Algorithm
|
||||
reader.readSequence();
|
||||
if (reader.readOID() !== '1.2.840.113549.1.1.1')
|
||||
throw new Error('Bad RSA private OID');
|
||||
// - Algorithm parameters (RSA has none)
|
||||
if (reader.readByte() !== Ber.Null)
|
||||
throw new Error('Malformed RSA private key (expected null)');
|
||||
if (reader.readByte() !== 0x00) {
|
||||
throw new Error(
|
||||
'Malformed RSA private key (expected zero-length null)'
|
||||
);
|
||||
}
|
||||
|
||||
reader = new Ber.Reader(reader.readString(Ber.OctetString, true));
|
||||
reader.readSequence();
|
||||
if (reader.readInt() !== 0)
|
||||
throw new Error('Unsupported version in RSA private key');
|
||||
const n = reader.readString(Ber.Integer, true);
|
||||
const e = reader.readString(Ber.Integer, true);
|
||||
const d = reader.readString(Ber.Integer, true);
|
||||
const p = reader.readString(Ber.Integer, true);
|
||||
const q = reader.readString(Ber.Integer, true);
|
||||
reader.readString(Ber.Integer, true); // dmp1
|
||||
reader.readString(Ber.Integer, true); // dmq1
|
||||
const iqmp = reader.readString(Ber.Integer, true);
|
||||
|
||||
/*
|
||||
OpenSSH RSA private key:
|
||||
string "ssh-rsa"
|
||||
string n -- public
|
||||
string e -- public
|
||||
string d -- private
|
||||
string iqmp -- private
|
||||
string p -- private
|
||||
string q -- private
|
||||
*/
|
||||
const keyName = Buffer.from('ssh-rsa');
|
||||
const privBuf = Buffer.allocUnsafe(
|
||||
4 + keyName.length
|
||||
+ 4 + n.length
|
||||
+ 4 + e.length
|
||||
+ 4 + d.length
|
||||
+ 4 + iqmp.length
|
||||
+ 4 + p.length
|
||||
+ 4 + q.length
|
||||
);
|
||||
let pos = 0;
|
||||
|
||||
privBuf.writeUInt32BE(keyName.length, pos += 0);
|
||||
privBuf.set(keyName, pos += 4);
|
||||
privBuf.writeUInt32BE(n.length, pos += keyName.length);
|
||||
privBuf.set(n, pos += 4);
|
||||
privBuf.writeUInt32BE(e.length, pos += n.length);
|
||||
privBuf.set(e, pos += 4);
|
||||
privBuf.writeUInt32BE(d.length, pos += e.length);
|
||||
privBuf.set(d, pos += 4);
|
||||
privBuf.writeUInt32BE(iqmp.length, pos += d.length);
|
||||
privBuf.set(iqmp, pos += 4);
|
||||
privBuf.writeUInt32BE(p.length, pos += iqmp.length);
|
||||
privBuf.set(p, pos += 4);
|
||||
privBuf.writeUInt32BE(q.length, pos += p.length);
|
||||
privBuf.set(q, pos += 4);
|
||||
|
||||
/*
|
||||
OpenSSH RSA public key:
|
||||
string "ssh-rsa"
|
||||
string e -- public
|
||||
string n -- public
|
||||
*/
|
||||
const pubBuf = Buffer.allocUnsafe(
|
||||
4 + keyName.length
|
||||
+ 4 + e.length
|
||||
+ 4 + n.length
|
||||
);
|
||||
pos = 0;
|
||||
|
||||
pubBuf.writeUInt32BE(keyName.length, pos += 0);
|
||||
pubBuf.set(keyName, pos += 4);
|
||||
pubBuf.writeUInt32BE(e.length, pos += keyName.length);
|
||||
pubBuf.set(e, pos += 4);
|
||||
pubBuf.writeUInt32BE(n.length, pos += e.length);
|
||||
pubBuf.set(n, pos += 4);
|
||||
|
||||
return { sshName: keyName.toString(), priv: privBuf, pub: pubBuf };
|
||||
}
|
||||
case 'ec': {
|
||||
// Parse public key
|
||||
let reader = new Ber.Reader(pub);
|
||||
reader.readSequence();
|
||||
|
||||
reader.readSequence();
|
||||
if (reader.readOID() !== '1.2.840.10045.2.1')
|
||||
throw new Error('Bad ECDSA public OID');
|
||||
// Skip curve OID, we'll get it from the private key
|
||||
reader.readOID();
|
||||
let pubBin = reader.readString(Ber.BitString, true);
|
||||
{
|
||||
// Remove leading zero bytes
|
||||
let i = 0;
|
||||
for (; i < pubBin.length && pubBin[i] === 0x00; ++i);
|
||||
if (i > 0)
|
||||
pubBin = pubBin.slice(i);
|
||||
}
|
||||
|
||||
// Parse private key
|
||||
reader = new Ber.Reader(priv);
|
||||
reader.readSequence();
|
||||
|
||||
// - Version
|
||||
if (reader.readInt() !== 0)
|
||||
throw new Error('Unsupported version in ECDSA private key');
|
||||
|
||||
reader.readSequence();
|
||||
if (reader.readOID() !== '1.2.840.10045.2.1')
|
||||
throw new Error('Bad ECDSA private OID');
|
||||
const curveOID = reader.readOID();
|
||||
let sshCurveName;
|
||||
switch (curveOID) {
|
||||
case '1.2.840.10045.3.1.7':
|
||||
// prime256v1/secp256r1
|
||||
sshCurveName = 'nistp256';
|
||||
break;
|
||||
case '1.3.132.0.34':
|
||||
// secp384r1
|
||||
sshCurveName = 'nistp384';
|
||||
break;
|
||||
case '1.3.132.0.35':
|
||||
// secp521r1
|
||||
sshCurveName = 'nistp521';
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unsupported curve in ECDSA private key');
|
||||
}
|
||||
|
||||
reader = new Ber.Reader(reader.readString(Ber.OctetString, true));
|
||||
reader.readSequence();
|
||||
|
||||
// - Version
|
||||
if (reader.readInt() !== 1)
|
||||
throw new Error('Unsupported version in ECDSA private key');
|
||||
|
||||
// Add leading zero byte to prevent negative bignum in private key
|
||||
const privBin = Buffer.concat([
|
||||
Buffer.from([0x00]),
|
||||
reader.readString(Ber.OctetString, true)
|
||||
]);
|
||||
|
||||
/*
|
||||
OpenSSH ECDSA private key:
|
||||
string "ecdsa-sha2-<sshCurveName>"
|
||||
string curve name
|
||||
string Q -- public
|
||||
string d -- private
|
||||
*/
|
||||
const keyName = Buffer.from(`ecdsa-sha2-${sshCurveName}`);
|
||||
sshCurveName = Buffer.from(sshCurveName);
|
||||
const privBuf = Buffer.allocUnsafe(
|
||||
4 + keyName.length
|
||||
+ 4 + sshCurveName.length
|
||||
+ 4 + pubBin.length
|
||||
+ 4 + privBin.length
|
||||
);
|
||||
let pos = 0;
|
||||
|
||||
privBuf.writeUInt32BE(keyName.length, pos += 0);
|
||||
privBuf.set(keyName, pos += 4);
|
||||
privBuf.writeUInt32BE(sshCurveName.length, pos += keyName.length);
|
||||
privBuf.set(sshCurveName, pos += 4);
|
||||
privBuf.writeUInt32BE(pubBin.length, pos += sshCurveName.length);
|
||||
privBuf.set(pubBin, pos += 4);
|
||||
privBuf.writeUInt32BE(privBin.length, pos += pubBin.length);
|
||||
privBuf.set(privBin, pos += 4);
|
||||
|
||||
/*
|
||||
OpenSSH ECDSA public key:
|
||||
string "ecdsa-sha2-<sshCurveName>"
|
||||
string curve name
|
||||
string Q -- public
|
||||
*/
|
||||
const pubBuf = Buffer.allocUnsafe(
|
||||
4 + keyName.length
|
||||
+ 4 + sshCurveName.length
|
||||
+ 4 + pubBin.length
|
||||
);
|
||||
pos = 0;
|
||||
|
||||
pubBuf.writeUInt32BE(keyName.length, pos += 0);
|
||||
pubBuf.set(keyName, pos += 4);
|
||||
pubBuf.writeUInt32BE(sshCurveName.length, pos += keyName.length);
|
||||
pubBuf.set(sshCurveName, pos += 4);
|
||||
pubBuf.writeUInt32BE(pubBin.length, pos += sshCurveName.length);
|
||||
pubBuf.set(pubBin, pos += 4);
|
||||
|
||||
return { sshName: keyName.toString(), priv: privBuf, pub: pubBuf };
|
||||
}
|
||||
case 'ed25519': {
|
||||
// Parse public key
|
||||
let reader = new Ber.Reader(pub);
|
||||
reader.readSequence();
|
||||
|
||||
// - Algorithm
|
||||
reader.readSequence();
|
||||
if (reader.readOID() !== '1.3.101.112')
|
||||
throw new Error('Bad ED25519 public OID');
|
||||
// - Attributes (absent for ED25519)
|
||||
|
||||
let pubBin = reader.readString(Ber.BitString, true);
|
||||
{
|
||||
// Remove leading zero bytes
|
||||
let i = 0;
|
||||
for (; i < pubBin.length && pubBin[i] === 0x00; ++i);
|
||||
if (i > 0)
|
||||
pubBin = pubBin.slice(i);
|
||||
}
|
||||
|
||||
// Parse private key
|
||||
reader = new Ber.Reader(priv);
|
||||
reader.readSequence();
|
||||
|
||||
// - Version
|
||||
if (reader.readInt() !== 0)
|
||||
throw new Error('Unsupported version in ED25519 private key');
|
||||
|
||||
// - Algorithm
|
||||
reader.readSequence();
|
||||
if (reader.readOID() !== '1.3.101.112')
|
||||
throw new Error('Bad ED25519 private OID');
|
||||
// - Attributes (absent)
|
||||
|
||||
reader = new Ber.Reader(reader.readString(Ber.OctetString, true));
|
||||
const privBin = reader.readString(Ber.OctetString, true);
|
||||
|
||||
/*
|
||||
OpenSSH ed25519 private key:
|
||||
string "ssh-ed25519"
|
||||
string public key
|
||||
string private key + public key
|
||||
*/
|
||||
const keyName = Buffer.from('ssh-ed25519');
|
||||
const privBuf = Buffer.allocUnsafe(
|
||||
4 + keyName.length
|
||||
+ 4 + pubBin.length
|
||||
+ 4 + (privBin.length + pubBin.length)
|
||||
);
|
||||
let pos = 0;
|
||||
|
||||
privBuf.writeUInt32BE(keyName.length, pos += 0);
|
||||
privBuf.set(keyName, pos += 4);
|
||||
privBuf.writeUInt32BE(pubBin.length, pos += keyName.length);
|
||||
privBuf.set(pubBin, pos += 4);
|
||||
privBuf.writeUInt32BE(
|
||||
privBin.length + pubBin.length,
|
||||
pos += pubBin.length
|
||||
);
|
||||
privBuf.set(privBin, pos += 4);
|
||||
privBuf.set(pubBin, pos += privBin.length);
|
||||
|
||||
/*
|
||||
OpenSSH ed25519 public key:
|
||||
string "ssh-ed25519"
|
||||
string public key
|
||||
*/
|
||||
const pubBuf = Buffer.allocUnsafe(
|
||||
4 + keyName.length
|
||||
+ 4 + pubBin.length
|
||||
);
|
||||
pos = 0;
|
||||
|
||||
pubBuf.writeUInt32BE(keyName.length, pos += 0);
|
||||
pubBuf.set(keyName, pos += 4);
|
||||
pubBuf.writeUInt32BE(pubBin.length, pos += keyName.length);
|
||||
pubBuf.set(pubBin, pos += 4);
|
||||
|
||||
return { sshName: keyName.toString(), priv: privBuf, pub: pubBuf };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertKeys(keyType, pub, priv, opts) {
|
||||
let format = 'new';
|
||||
let encrypted;
|
||||
let comment = '';
|
||||
if (typeof opts === 'object' && opts !== null) {
|
||||
if (typeof opts.comment === 'string' && opts.comment)
|
||||
comment = opts.comment;
|
||||
if (typeof opts.format === 'string' && opts.format)
|
||||
format = opts.format;
|
||||
if (opts.passphrase) {
|
||||
let passphrase;
|
||||
if (typeof opts.passphrase === 'string')
|
||||
passphrase = Buffer.from(opts.passphrase);
|
||||
else if (Buffer.isBuffer(opts.passphrase))
|
||||
passphrase = opts.passphrase;
|
||||
else
|
||||
throw new Error('Invalid passphrase');
|
||||
|
||||
if (opts.cipher === undefined)
|
||||
throw new Error('Missing cipher name');
|
||||
const cipher = ciphers.get(opts.cipher);
|
||||
if (cipher === undefined)
|
||||
throw new Error('Invalid cipher name');
|
||||
|
||||
if (format === 'new') {
|
||||
let rounds = DEFAULT_ROUNDS;
|
||||
if (opts.rounds !== undefined) {
|
||||
if (!Number.isInteger(opts.rounds))
|
||||
throw new TypeError('rounds must be an integer');
|
||||
if (opts.rounds > 0)
|
||||
rounds = opts.rounds;
|
||||
}
|
||||
|
||||
const gen = Buffer.allocUnsafe(cipher.keyLen + cipher.ivLen);
|
||||
const salt = randomBytes(SALT_LEN);
|
||||
const r = bcrypt_pbkdf(
|
||||
passphrase,
|
||||
passphrase.length,
|
||||
salt,
|
||||
salt.length,
|
||||
gen,
|
||||
gen.length,
|
||||
rounds
|
||||
);
|
||||
if (r !== 0)
|
||||
return new Error('Failed to generate information to encrypt key');
|
||||
|
||||
/*
|
||||
string salt
|
||||
uint32 rounds
|
||||
*/
|
||||
const kdfOptions = Buffer.allocUnsafe(4 + salt.length + 4);
|
||||
{
|
||||
let pos = 0;
|
||||
kdfOptions.writeUInt32BE(salt.length, pos += 0);
|
||||
kdfOptions.set(salt, pos += 4);
|
||||
kdfOptions.writeUInt32BE(rounds, pos += salt.length);
|
||||
}
|
||||
|
||||
encrypted = {
|
||||
cipher,
|
||||
cipherName: opts.cipher,
|
||||
kdfName: 'bcrypt',
|
||||
kdfOptions,
|
||||
key: gen.slice(0, cipher.keyLen),
|
||||
iv: gen.slice(cipher.keyLen),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case 'new': {
|
||||
let privateB64 = '-----BEGIN OPENSSH PRIVATE KEY-----\n';
|
||||
let publicB64;
|
||||
/*
|
||||
byte[] "openssh-key-v1\0"
|
||||
string ciphername
|
||||
string kdfname
|
||||
string kdfoptions
|
||||
uint32 number of keys N
|
||||
string publickey1
|
||||
string encrypted, padded list of private keys
|
||||
uint32 checkint
|
||||
uint32 checkint
|
||||
byte[] privatekey1
|
||||
string comment1
|
||||
byte 1
|
||||
byte 2
|
||||
byte 3
|
||||
...
|
||||
byte padlen % 255
|
||||
*/
|
||||
const cipherName = Buffer.from(encrypted ? encrypted.cipherName : 'none');
|
||||
const kdfName = Buffer.from(encrypted ? encrypted.kdfName : 'none');
|
||||
const kdfOptions = (encrypted ? encrypted.kdfOptions : Buffer.alloc(0));
|
||||
const blockLen = (encrypted ? encrypted.cipher.blockLen : 8);
|
||||
|
||||
const parsed = parseDERs(keyType, pub, priv);
|
||||
|
||||
const checkInt = randomBytes(4);
|
||||
const commentBin = Buffer.from(comment);
|
||||
const privBlobLen = (4 + 4 + parsed.priv.length + 4 + commentBin.length);
|
||||
let padding = [];
|
||||
for (let i = 1; ((privBlobLen + padding.length) % blockLen); ++i)
|
||||
padding.push(i & 0xFF);
|
||||
padding = Buffer.from(padding);
|
||||
|
||||
let privBlob = Buffer.allocUnsafe(privBlobLen + padding.length);
|
||||
let extra;
|
||||
{
|
||||
let pos = 0;
|
||||
privBlob.set(checkInt, pos += 0);
|
||||
privBlob.set(checkInt, pos += 4);
|
||||
privBlob.set(parsed.priv, pos += 4);
|
||||
privBlob.writeUInt32BE(commentBin.length, pos += parsed.priv.length);
|
||||
privBlob.set(commentBin, pos += 4);
|
||||
privBlob.set(padding, pos += commentBin.length);
|
||||
}
|
||||
|
||||
if (encrypted) {
|
||||
const options = { authTagLength: encrypted.cipher.authLen };
|
||||
const cipher = createCipheriv(
|
||||
encrypted.cipher.sslName,
|
||||
encrypted.key,
|
||||
encrypted.iv,
|
||||
options
|
||||
);
|
||||
cipher.setAutoPadding(false);
|
||||
privBlob = Buffer.concat([ cipher.update(privBlob), cipher.final() ]);
|
||||
if (encrypted.cipher.authLen > 0)
|
||||
extra = cipher.getAuthTag();
|
||||
else
|
||||
extra = Buffer.alloc(0);
|
||||
encrypted.key.fill(0);
|
||||
encrypted.iv.fill(0);
|
||||
} else {
|
||||
extra = Buffer.alloc(0);
|
||||
}
|
||||
|
||||
const magicBytes = Buffer.from('openssh-key-v1\0');
|
||||
const privBin = Buffer.allocUnsafe(
|
||||
magicBytes.length
|
||||
+ 4 + cipherName.length
|
||||
+ 4 + kdfName.length
|
||||
+ 4 + kdfOptions.length
|
||||
+ 4
|
||||
+ 4 + parsed.pub.length
|
||||
+ 4 + privBlob.length
|
||||
+ extra.length
|
||||
);
|
||||
{
|
||||
let pos = 0;
|
||||
privBin.set(magicBytes, pos += 0);
|
||||
privBin.writeUInt32BE(cipherName.length, pos += magicBytes.length);
|
||||
privBin.set(cipherName, pos += 4);
|
||||
privBin.writeUInt32BE(kdfName.length, pos += cipherName.length);
|
||||
privBin.set(kdfName, pos += 4);
|
||||
privBin.writeUInt32BE(kdfOptions.length, pos += kdfName.length);
|
||||
privBin.set(kdfOptions, pos += 4);
|
||||
privBin.writeUInt32BE(1, pos += kdfOptions.length);
|
||||
privBin.writeUInt32BE(parsed.pub.length, pos += 4);
|
||||
privBin.set(parsed.pub, pos += 4);
|
||||
privBin.writeUInt32BE(privBlob.length, pos += parsed.pub.length);
|
||||
privBin.set(privBlob, pos += 4);
|
||||
privBin.set(extra, pos += privBlob.length);
|
||||
}
|
||||
|
||||
{
|
||||
const b64 = privBin.base64Slice(0, privBin.length);
|
||||
let formatted = b64.replace(/.{64}/g, '$&\n');
|
||||
if (b64.length & 63)
|
||||
formatted += '\n';
|
||||
privateB64 += formatted;
|
||||
}
|
||||
|
||||
{
|
||||
const b64 = parsed.pub.base64Slice(0, parsed.pub.length);
|
||||
publicB64 = `${parsed.sshName} ${b64}${comment ? ` ${comment}` : ''}`;
|
||||
}
|
||||
|
||||
privateB64 += '-----END OPENSSH PRIVATE KEY-----\n';
|
||||
return {
|
||||
private: privateB64,
|
||||
public: publicB64,
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw new Error('Invalid output key format');
|
||||
}
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
|
||||
module.exports = {
|
||||
generateKeyPair: (keyType, opts, cb) => {
|
||||
if (typeof opts === 'function') {
|
||||
cb = opts;
|
||||
opts = undefined;
|
||||
}
|
||||
if (typeof cb !== 'function')
|
||||
cb = noop;
|
||||
const args = makeArgs(keyType, opts);
|
||||
generateKeyPair_(...args, (err, pub, priv) => {
|
||||
if (err)
|
||||
return cb(err);
|
||||
let ret;
|
||||
try {
|
||||
ret = convertKeys(args[0], pub, priv, opts);
|
||||
} catch (ex) {
|
||||
return cb(ex);
|
||||
}
|
||||
cb(null, ret);
|
||||
});
|
||||
},
|
||||
generateKeyPairSync: (keyType, opts) => {
|
||||
const args = makeArgs(keyType, opts);
|
||||
const { publicKey: pub, privateKey: priv } = generateKeyPairSync_(...args);
|
||||
return convertKeys(args[0], pub, priv, opts);
|
||||
}
|
||||
};
|
||||
+2136
File diff suppressed because it is too large
Load Diff
+4052
File diff suppressed because it is too large
Load Diff
+356
@@ -0,0 +1,356 @@
|
||||
'use strict';
|
||||
|
||||
const crypto = require('crypto');
|
||||
|
||||
let cpuInfo;
|
||||
try {
|
||||
cpuInfo = require('cpu-features')();
|
||||
} catch {}
|
||||
|
||||
const { bindingAvailable, CIPHER_INFO, MAC_INFO } = require('./crypto.js');
|
||||
|
||||
const eddsaSupported = (() => {
|
||||
if (typeof crypto.sign === 'function'
|
||||
&& typeof crypto.verify === 'function') {
|
||||
const key =
|
||||
'-----BEGIN PRIVATE KEY-----\r\nMC4CAQAwBQYDK2VwBCIEIHKj+sVa9WcD'
|
||||
+ '/q2DJUJaf43Kptc8xYuUQA4bOFj9vC8T\r\n-----END PRIVATE KEY-----';
|
||||
const data = Buffer.from('a');
|
||||
let sig;
|
||||
let verified;
|
||||
try {
|
||||
sig = crypto.sign(null, data, key);
|
||||
verified = crypto.verify(null, data, key, sig);
|
||||
} catch {}
|
||||
return (Buffer.isBuffer(sig) && sig.length === 64 && verified === true);
|
||||
}
|
||||
|
||||
return false;
|
||||
})();
|
||||
|
||||
const curve25519Supported = (typeof crypto.diffieHellman === 'function'
|
||||
&& typeof crypto.generateKeyPairSync === 'function'
|
||||
&& typeof crypto.createPublicKey === 'function');
|
||||
|
||||
const DEFAULT_KEX = [
|
||||
// https://tools.ietf.org/html/rfc5656#section-10.1
|
||||
'ecdh-sha2-nistp256',
|
||||
'ecdh-sha2-nistp384',
|
||||
'ecdh-sha2-nistp521',
|
||||
|
||||
// https://tools.ietf.org/html/rfc4419#section-4
|
||||
'diffie-hellman-group-exchange-sha256',
|
||||
|
||||
// https://tools.ietf.org/html/rfc8268
|
||||
'diffie-hellman-group14-sha256',
|
||||
'diffie-hellman-group15-sha512',
|
||||
'diffie-hellman-group16-sha512',
|
||||
'diffie-hellman-group17-sha512',
|
||||
'diffie-hellman-group18-sha512',
|
||||
];
|
||||
if (curve25519Supported) {
|
||||
DEFAULT_KEX.unshift('curve25519-sha256');
|
||||
DEFAULT_KEX.unshift('curve25519-sha256@libssh.org');
|
||||
}
|
||||
const SUPPORTED_KEX = DEFAULT_KEX.concat([
|
||||
// https://tools.ietf.org/html/rfc4419#section-4
|
||||
'diffie-hellman-group-exchange-sha1',
|
||||
|
||||
'diffie-hellman-group14-sha1', // REQUIRED
|
||||
'diffie-hellman-group1-sha1', // REQUIRED
|
||||
]);
|
||||
|
||||
|
||||
const DEFAULT_SERVER_HOST_KEY = [
|
||||
'ecdsa-sha2-nistp256',
|
||||
'ecdsa-sha2-nistp384',
|
||||
'ecdsa-sha2-nistp521',
|
||||
'rsa-sha2-512', // RFC 8332
|
||||
'rsa-sha2-256', // RFC 8332
|
||||
'ssh-rsa',
|
||||
];
|
||||
if (eddsaSupported)
|
||||
DEFAULT_SERVER_HOST_KEY.unshift('ssh-ed25519');
|
||||
const SUPPORTED_SERVER_HOST_KEY = DEFAULT_SERVER_HOST_KEY.concat([
|
||||
'ssh-dss',
|
||||
]);
|
||||
|
||||
|
||||
const canUseCipher = (() => {
|
||||
const ciphers = crypto.getCiphers();
|
||||
return (name) => ciphers.includes(CIPHER_INFO[name].sslName);
|
||||
})();
|
||||
let DEFAULT_CIPHER = [
|
||||
// http://tools.ietf.org/html/rfc5647
|
||||
'aes128-gcm@openssh.com',
|
||||
'aes256-gcm@openssh.com',
|
||||
|
||||
// http://tools.ietf.org/html/rfc4344#section-4
|
||||
'aes128-ctr',
|
||||
'aes192-ctr',
|
||||
'aes256-ctr',
|
||||
];
|
||||
if (cpuInfo && cpuInfo.flags && !cpuInfo.flags.aes) {
|
||||
// We know for sure the CPU does not support AES acceleration
|
||||
if (bindingAvailable)
|
||||
DEFAULT_CIPHER.unshift('chacha20-poly1305@openssh.com');
|
||||
else
|
||||
DEFAULT_CIPHER.push('chacha20-poly1305@openssh.com');
|
||||
} else if (bindingAvailable && cpuInfo && cpuInfo.arch === 'x86') {
|
||||
// Places chacha20-poly1305 immediately after GCM ciphers since GCM ciphers
|
||||
// seem to outperform it on x86, but it seems to be faster than CTR ciphers
|
||||
DEFAULT_CIPHER.splice(4, 0, 'chacha20-poly1305@openssh.com');
|
||||
} else {
|
||||
DEFAULT_CIPHER.push('chacha20-poly1305@openssh.com');
|
||||
}
|
||||
DEFAULT_CIPHER = DEFAULT_CIPHER.filter(canUseCipher);
|
||||
const SUPPORTED_CIPHER = DEFAULT_CIPHER.concat([
|
||||
'aes256-cbc',
|
||||
'aes192-cbc',
|
||||
'aes128-cbc',
|
||||
'blowfish-cbc',
|
||||
'3des-cbc',
|
||||
'aes128-gcm',
|
||||
'aes256-gcm',
|
||||
|
||||
// http://tools.ietf.org/html/rfc4345#section-4:
|
||||
'arcfour256',
|
||||
'arcfour128',
|
||||
|
||||
'cast128-cbc',
|
||||
'arcfour',
|
||||
].filter(canUseCipher));
|
||||
|
||||
|
||||
const canUseMAC = (() => {
|
||||
const hashes = crypto.getHashes();
|
||||
return (name) => hashes.includes(MAC_INFO[name].sslName);
|
||||
})();
|
||||
const DEFAULT_MAC = [
|
||||
'hmac-sha2-256-etm@openssh.com',
|
||||
'hmac-sha2-512-etm@openssh.com',
|
||||
'hmac-sha1-etm@openssh.com',
|
||||
'hmac-sha2-256',
|
||||
'hmac-sha2-512',
|
||||
'hmac-sha1',
|
||||
].filter(canUseMAC);
|
||||
const SUPPORTED_MAC = DEFAULT_MAC.concat([
|
||||
'hmac-md5',
|
||||
'hmac-sha2-256-96', // first 96 bits of HMAC-SHA256
|
||||
'hmac-sha2-512-96', // first 96 bits of HMAC-SHA512
|
||||
'hmac-ripemd160',
|
||||
'hmac-sha1-96', // first 96 bits of HMAC-SHA1
|
||||
'hmac-md5-96', // first 96 bits of HMAC-MD5
|
||||
].filter(canUseMAC));
|
||||
|
||||
const DEFAULT_COMPRESSION = [
|
||||
'none',
|
||||
'zlib@openssh.com', // ZLIB (LZ77) compression, except
|
||||
// compression/decompression does not start until after
|
||||
// successful user authentication
|
||||
'zlib', // ZLIB (LZ77) compression
|
||||
];
|
||||
const SUPPORTED_COMPRESSION = DEFAULT_COMPRESSION.concat([
|
||||
]);
|
||||
|
||||
|
||||
const COMPAT = {
|
||||
BAD_DHGEX: 1 << 0,
|
||||
OLD_EXIT: 1 << 1,
|
||||
DYN_RPORT_BUG: 1 << 2,
|
||||
BUG_DHGEX_LARGE: 1 << 3,
|
||||
IMPLY_RSA_SHA2_SIGALGS: 1 << 4,
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
MESSAGE: {
|
||||
// Transport layer protocol -- generic (1-19)
|
||||
DISCONNECT: 1,
|
||||
IGNORE: 2,
|
||||
UNIMPLEMENTED: 3,
|
||||
DEBUG: 4,
|
||||
SERVICE_REQUEST: 5,
|
||||
SERVICE_ACCEPT: 6,
|
||||
EXT_INFO: 7, // RFC 8308
|
||||
|
||||
// Transport layer protocol -- algorithm negotiation (20-29)
|
||||
KEXINIT: 20,
|
||||
NEWKEYS: 21,
|
||||
|
||||
// Transport layer protocol -- key exchange method-specific (30-49)
|
||||
KEXDH_INIT: 30,
|
||||
KEXDH_REPLY: 31,
|
||||
|
||||
KEXDH_GEX_GROUP: 31,
|
||||
KEXDH_GEX_INIT: 32,
|
||||
KEXDH_GEX_REPLY: 33,
|
||||
KEXDH_GEX_REQUEST: 34,
|
||||
|
||||
KEXECDH_INIT: 30,
|
||||
KEXECDH_REPLY: 31,
|
||||
|
||||
// User auth protocol -- generic (50-59)
|
||||
USERAUTH_REQUEST: 50,
|
||||
USERAUTH_FAILURE: 51,
|
||||
USERAUTH_SUCCESS: 52,
|
||||
USERAUTH_BANNER: 53,
|
||||
|
||||
// User auth protocol -- user auth method-specific (60-79)
|
||||
USERAUTH_PASSWD_CHANGEREQ: 60,
|
||||
|
||||
USERAUTH_PK_OK: 60,
|
||||
|
||||
USERAUTH_INFO_REQUEST: 60,
|
||||
USERAUTH_INFO_RESPONSE: 61,
|
||||
|
||||
// Connection protocol -- generic (80-89)
|
||||
GLOBAL_REQUEST: 80,
|
||||
REQUEST_SUCCESS: 81,
|
||||
REQUEST_FAILURE: 82,
|
||||
|
||||
// Connection protocol -- channel-related (90-127)
|
||||
CHANNEL_OPEN: 90,
|
||||
CHANNEL_OPEN_CONFIRMATION: 91,
|
||||
CHANNEL_OPEN_FAILURE: 92,
|
||||
CHANNEL_WINDOW_ADJUST: 93,
|
||||
CHANNEL_DATA: 94,
|
||||
CHANNEL_EXTENDED_DATA: 95,
|
||||
CHANNEL_EOF: 96,
|
||||
CHANNEL_CLOSE: 97,
|
||||
CHANNEL_REQUEST: 98,
|
||||
CHANNEL_SUCCESS: 99,
|
||||
CHANNEL_FAILURE: 100
|
||||
|
||||
// Reserved for client protocols (128-191)
|
||||
|
||||
// Local extensions (192-155)
|
||||
},
|
||||
DISCONNECT_REASON: {
|
||||
HOST_NOT_ALLOWED_TO_CONNECT: 1,
|
||||
PROTOCOL_ERROR: 2,
|
||||
KEY_EXCHANGE_FAILED: 3,
|
||||
RESERVED: 4,
|
||||
MAC_ERROR: 5,
|
||||
COMPRESSION_ERROR: 6,
|
||||
SERVICE_NOT_AVAILABLE: 7,
|
||||
PROTOCOL_VERSION_NOT_SUPPORTED: 8,
|
||||
HOST_KEY_NOT_VERIFIABLE: 9,
|
||||
CONNECTION_LOST: 10,
|
||||
BY_APPLICATION: 11,
|
||||
TOO_MANY_CONNECTIONS: 12,
|
||||
AUTH_CANCELED_BY_USER: 13,
|
||||
NO_MORE_AUTH_METHODS_AVAILABLE: 14,
|
||||
ILLEGAL_USER_NAME: 15,
|
||||
},
|
||||
DISCONNECT_REASON_STR: undefined,
|
||||
CHANNEL_OPEN_FAILURE: {
|
||||
ADMINISTRATIVELY_PROHIBITED: 1,
|
||||
CONNECT_FAILED: 2,
|
||||
UNKNOWN_CHANNEL_TYPE: 3,
|
||||
RESOURCE_SHORTAGE: 4
|
||||
},
|
||||
TERMINAL_MODE: {
|
||||
TTY_OP_END: 0, // Indicates end of options.
|
||||
VINTR: 1, // Interrupt character; 255 if none. Similarly for the
|
||||
// other characters. Not all of these characters are
|
||||
// supported on all systems.
|
||||
VQUIT: 2, // The quit character (sends SIGQUIT signal on POSIX
|
||||
// systems).
|
||||
VERASE: 3, // Erase the character to left of the cursor.
|
||||
VKILL: 4, // Kill the current input line.
|
||||
VEOF: 5, // End-of-file character (sends EOF from the
|
||||
// terminal).
|
||||
VEOL: 6, // End-of-line character in addition to carriage
|
||||
// return and/or linefeed.
|
||||
VEOL2: 7, // Additional end-of-line character.
|
||||
VSTART: 8, // Continues paused output (normally control-Q).
|
||||
VSTOP: 9, // Pauses output (normally control-S).
|
||||
VSUSP: 10, // Suspends the current program.
|
||||
VDSUSP: 11, // Another suspend character.
|
||||
VREPRINT: 12, // Reprints the current input line.
|
||||
VWERASE: 13, // Erases a word left of cursor.
|
||||
VLNEXT: 14, // Enter the next character typed literally, even if
|
||||
// it is a special character
|
||||
VFLUSH: 15, // Character to flush output.
|
||||
VSWTCH: 16, // Switch to a different shell layer.
|
||||
VSTATUS: 17, // Prints system status line (load, command, pid,
|
||||
// etc).
|
||||
VDISCARD: 18, // Toggles the flushing of terminal output.
|
||||
IGNPAR: 30, // The ignore parity flag. The parameter SHOULD be 0
|
||||
// if this flag is FALSE, and 1 if it is TRUE.
|
||||
PARMRK: 31, // Mark parity and framing errors.
|
||||
INPCK: 32, // Enable checking of parity errors.
|
||||
ISTRIP: 33, // Strip 8th bit off characters.
|
||||
INLCR: 34, // Map NL into CR on input.
|
||||
IGNCR: 35, // Ignore CR on input.
|
||||
ICRNL: 36, // Map CR to NL on input.
|
||||
IUCLC: 37, // Translate uppercase characters to lowercase.
|
||||
IXON: 38, // Enable output flow control.
|
||||
IXANY: 39, // Any char will restart after stop.
|
||||
IXOFF: 40, // Enable input flow control.
|
||||
IMAXBEL: 41, // Ring bell on input queue full.
|
||||
ISIG: 50, // Enable signals INTR, QUIT, [D]SUSP.
|
||||
ICANON: 51, // Canonicalize input lines.
|
||||
XCASE: 52, // Enable input and output of uppercase characters by
|
||||
// preceding their lowercase equivalents with "\".
|
||||
ECHO: 53, // Enable echoing.
|
||||
ECHOE: 54, // Visually erase chars.
|
||||
ECHOK: 55, // Kill character discards current line.
|
||||
ECHONL: 56, // Echo NL even if ECHO is off.
|
||||
NOFLSH: 57, // Don't flush after interrupt.
|
||||
TOSTOP: 58, // Stop background jobs from output.
|
||||
IEXTEN: 59, // Enable extensions.
|
||||
ECHOCTL: 60, // Echo control characters as ^(Char).
|
||||
ECHOKE: 61, // Visual erase for line kill.
|
||||
PENDIN: 62, // Retype pending input.
|
||||
OPOST: 70, // Enable output processing.
|
||||
OLCUC: 71, // Convert lowercase to uppercase.
|
||||
ONLCR: 72, // Map NL to CR-NL.
|
||||
OCRNL: 73, // Translate carriage return to newline (output).
|
||||
ONOCR: 74, // Translate newline to carriage return-newline
|
||||
// (output).
|
||||
ONLRET: 75, // Newline performs a carriage return (output).
|
||||
CS7: 90, // 7 bit mode.
|
||||
CS8: 91, // 8 bit mode.
|
||||
PARENB: 92, // Parity enable.
|
||||
PARODD: 93, // Odd parity, else even.
|
||||
TTY_OP_ISPEED: 128, // Specifies the input baud rate in bits per second.
|
||||
TTY_OP_OSPEED: 129, // Specifies the output baud rate in bits per second.
|
||||
},
|
||||
CHANNEL_EXTENDED_DATATYPE: {
|
||||
STDERR: 1,
|
||||
},
|
||||
|
||||
SIGNALS: [
|
||||
'ABRT', 'ALRM', 'FPE', 'HUP', 'ILL', 'INT', 'QUIT', 'SEGV', 'TERM', 'USR1',
|
||||
'USR2', 'KILL', 'PIPE'
|
||||
].reduce((cur, val) => ({ ...cur, [val]: 1 }), {}),
|
||||
|
||||
COMPAT,
|
||||
COMPAT_CHECKS: [
|
||||
[ 'Cisco-1.25', COMPAT.BAD_DHGEX ],
|
||||
[ /^Cisco-1[.]/, COMPAT.BUG_DHGEX_LARGE ],
|
||||
[ /^[0-9.]+$/, COMPAT.OLD_EXIT ], // old SSH.com implementations
|
||||
[ /^OpenSSH_5[.][0-9]+/, COMPAT.DYN_RPORT_BUG ],
|
||||
[ /^OpenSSH_7[.]4/, COMPAT.IMPLY_RSA_SHA2_SIGALGS ],
|
||||
],
|
||||
|
||||
// KEX proposal-related
|
||||
DEFAULT_KEX,
|
||||
SUPPORTED_KEX,
|
||||
DEFAULT_SERVER_HOST_KEY,
|
||||
SUPPORTED_SERVER_HOST_KEY,
|
||||
DEFAULT_CIPHER,
|
||||
SUPPORTED_CIPHER,
|
||||
DEFAULT_MAC,
|
||||
SUPPORTED_MAC,
|
||||
DEFAULT_COMPRESSION,
|
||||
SUPPORTED_COMPRESSION,
|
||||
|
||||
curve25519Supported,
|
||||
eddsaSupported,
|
||||
};
|
||||
|
||||
module.exports.DISCONNECT_REASON_BY_VALUE =
|
||||
Array.from(Object.entries(module.exports.DISCONNECT_REASON))
|
||||
.reduce((obj, [key, value]) => ({ ...obj, [value]: key }), {});
|
||||
+1602
File diff suppressed because it is too large
Load Diff
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
'variables': {
|
||||
'real_openssl_major%': '0',
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'sshcrypto',
|
||||
'include_dirs': [
|
||||
"<!(node -e \"require('nan')\")",
|
||||
],
|
||||
'sources': [
|
||||
'src/binding.cc'
|
||||
],
|
||||
'cflags': [ '-O3' ],
|
||||
|
||||
# Needed for OpenSSL 3.x/node.js v17.x+
|
||||
'defines': [
|
||||
'OPENSSL_API_COMPAT=0x10100000L',
|
||||
'REAL_OPENSSL_MAJOR=<(real_openssl_major)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<ProjectOutputs>
|
||||
<ProjectOutput>
|
||||
<FullPath>C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\sshcrypto.node</FullPath>
|
||||
</ProjectOutput>
|
||||
</ProjectOutputs>
|
||||
<ContentFiles />
|
||||
<SatelliteDlls />
|
||||
<NonRecipeFileRefs />
|
||||
</Project>
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\src\binding.cc;C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\obj\sshcrypto\src\binding.obj
|
||||
C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\src\win_delay_load_hook.cc;C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\obj\sshcrypto\win_delay_load_hook.obj
|
||||
node_modules/ssh2/lib/protocol/crypto/build/Release/obj/sshcrypto/sshcrypto.tlog/link.command.1.tlog
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
^C:\USERS\DIMIR\SSH-UPDATER\NODE_MODULES\SSH2\LIB\PROTOCOL\CRYPTO\BUILD\RELEASE\OBJ\SSHCRYPTO\SRC\BINDING.OBJ|C:\USERS\DIMIR\SSH-UPDATER\NODE_MODULES\SSH2\LIB\PROTOCOL\CRYPTO\BUILD\RELEASE\OBJ\SSHCRYPTO\WIN_DELAY_LOAD_HOOK.OBJ
|
||||
C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\sshcrypto.LIB
|
||||
C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\sshcrypto.EXP
|
||||
C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\sshcrypto.IPDB
|
||||
C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\Release\sshcrypto.IOBJ
|
||||
Generated
Vendored
BIN
Binary file not shown.
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.44.35207:TargetPlatformVersion=10.0.26100.0:
|
||||
Release|x64|C:\Users\dimir\ssh-updater\node_modules\ssh2\lib\protocol\crypto\build\|
|
||||
Generated
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+19
@@ -0,0 +1,19 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2015
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sshcrypto", "sshcrypto.vcxproj", "{529648C8-47C1-F1B5-2925-8170DD79C9A4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{529648C8-47C1-F1B5-2925-8170DD79C9A4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{529648C8-47C1-F1B5-2925-8170DD79C9A4}.Debug|x64.Build.0 = Debug|x64
|
||||
{529648C8-47C1-F1B5-2925-8170DD79C9A4}.Release|x64.ActiveCfg = Release|x64
|
||||
{529648C8-47C1-F1B5-2925-8170DD79C9A4}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+528
@@ -0,0 +1,528 @@
|
||||
# Do not edit. File was generated by node-gyp's "configure" step
|
||||
{
|
||||
"target_defaults": {
|
||||
"cflags": [],
|
||||
"configurations": {
|
||||
"Debug": {
|
||||
"v8_enable_v8_checks": 0,
|
||||
"variables": {}
|
||||
},
|
||||
"Release": {
|
||||
"v8_enable_v8_checks": 1,
|
||||
"variables": {}
|
||||
}
|
||||
},
|
||||
"default_configuration": "Release",
|
||||
"defines": [],
|
||||
"include_dirs": [],
|
||||
"libraries": [],
|
||||
"msbuild_toolset": "v143",
|
||||
"msvs_windows_target_platform_version": "10.0.26100.0"
|
||||
},
|
||||
"variables": {
|
||||
"asan": 0,
|
||||
"clang": 0,
|
||||
"control_flow_guard": "false",
|
||||
"coverage": "false",
|
||||
"dcheck_always_on": 0,
|
||||
"debug_nghttp2": "false",
|
||||
"debug_node": "false",
|
||||
"enable_lto": "false",
|
||||
"enable_pgo_generate": "false",
|
||||
"enable_pgo_use": "false",
|
||||
"error_on_warn": "false",
|
||||
"force_dynamic_crt": 0,
|
||||
"host_arch": "x64",
|
||||
"icu_data_in": "..\\..\\deps\\icu-tmp\\icudt77l.dat",
|
||||
"icu_endianness": "l",
|
||||
"icu_gyp_path": "tools/icu/icu-generic.gyp",
|
||||
"icu_path": "deps/icu-small",
|
||||
"icu_small": "false",
|
||||
"icu_ver_major": "77",
|
||||
"libdir": "lib",
|
||||
"llvm_version": "19.1.5",
|
||||
"napi_build_version": "10",
|
||||
"nasm_version": "3.01",
|
||||
"node_builtin_shareable_builtins": [
|
||||
"deps/cjs-module-lexer/lexer.js",
|
||||
"deps/cjs-module-lexer/dist/lexer.js",
|
||||
"deps/undici/undici.js",
|
||||
"deps/amaro/dist/index.js"
|
||||
],
|
||||
"node_byteorder": "little",
|
||||
"node_cctest_sources": [
|
||||
"src/node_snapshot_stub.cc",
|
||||
"test/cctest/inspector/test_network_requests_buffer.cc",
|
||||
"test/cctest/inspector/test_node_protocol.cc",
|
||||
"test/cctest/node_test_fixture.cc",
|
||||
"test/cctest/test_aliased_buffer.cc",
|
||||
"test/cctest/test_base64.cc",
|
||||
"test/cctest/test_base_object_ptr.cc",
|
||||
"test/cctest/test_cppgc.cc",
|
||||
"test/cctest/test_crypto_clienthello.cc",
|
||||
"test/cctest/test_dataqueue.cc",
|
||||
"test/cctest/test_environment.cc",
|
||||
"test/cctest/test_inspector_socket.cc",
|
||||
"test/cctest/test_inspector_socket_server.cc",
|
||||
"test/cctest/test_json_utils.cc",
|
||||
"test/cctest/test_linked_binding.cc",
|
||||
"test/cctest/test_lru_cache.cc",
|
||||
"test/cctest/test_node_api.cc",
|
||||
"test/cctest/test_node_crypto.cc",
|
||||
"test/cctest/test_node_crypto_env.cc",
|
||||
"test/cctest/test_node_postmortem_metadata.cc",
|
||||
"test/cctest/test_node_task_runner.cc",
|
||||
"test/cctest/test_path.cc",
|
||||
"test/cctest/test_per_process.cc",
|
||||
"test/cctest/test_platform.cc",
|
||||
"test/cctest/test_quic_cid.cc",
|
||||
"test/cctest/test_quic_error.cc",
|
||||
"test/cctest/test_quic_tokens.cc",
|
||||
"test/cctest/test_report.cc",
|
||||
"test/cctest/test_sockaddr.cc",
|
||||
"test/cctest/test_string_bytes.cc",
|
||||
"test/cctest/test_traced_value.cc",
|
||||
"test/cctest/test_util.cc",
|
||||
"test/cctest/node_test_fixture.h"
|
||||
],
|
||||
"node_debug_lib": "false",
|
||||
"node_enable_d8": "false",
|
||||
"node_enable_v8_vtunejit": "false",
|
||||
"node_enable_v8windbg": "false",
|
||||
"node_fipsinstall": "false",
|
||||
"node_install_corepack": "true",
|
||||
"node_install_npm": "true",
|
||||
"node_library_files": [
|
||||
"lib/_http_agent.js",
|
||||
"lib/_http_client.js",
|
||||
"lib/_http_common.js",
|
||||
"lib/_http_incoming.js",
|
||||
"lib/_http_outgoing.js",
|
||||
"lib/_http_server.js",
|
||||
"lib/_stream_duplex.js",
|
||||
"lib/_stream_passthrough.js",
|
||||
"lib/_stream_readable.js",
|
||||
"lib/_stream_transform.js",
|
||||
"lib/_stream_wrap.js",
|
||||
"lib/_stream_writable.js",
|
||||
"lib/_tls_common.js",
|
||||
"lib/_tls_wrap.js",
|
||||
"lib/assert.js",
|
||||
"lib/assert/strict.js",
|
||||
"lib/async_hooks.js",
|
||||
"lib/buffer.js",
|
||||
"lib/child_process.js",
|
||||
"lib/cluster.js",
|
||||
"lib/console.js",
|
||||
"lib/constants.js",
|
||||
"lib/crypto.js",
|
||||
"lib/dgram.js",
|
||||
"lib/diagnostics_channel.js",
|
||||
"lib/dns.js",
|
||||
"lib/dns/promises.js",
|
||||
"lib/domain.js",
|
||||
"lib/events.js",
|
||||
"lib/fs.js",
|
||||
"lib/fs/promises.js",
|
||||
"lib/http.js",
|
||||
"lib/http2.js",
|
||||
"lib/https.js",
|
||||
"lib/inspector.js",
|
||||
"lib/inspector/promises.js",
|
||||
"lib/internal/abort_controller.js",
|
||||
"lib/internal/assert.js",
|
||||
"lib/internal/assert/assertion_error.js",
|
||||
"lib/internal/assert/calltracker.js",
|
||||
"lib/internal/assert/myers_diff.js",
|
||||
"lib/internal/assert/utils.js",
|
||||
"lib/internal/async_context_frame.js",
|
||||
"lib/internal/async_hooks.js",
|
||||
"lib/internal/async_local_storage/async_context_frame.js",
|
||||
"lib/internal/async_local_storage/async_hooks.js",
|
||||
"lib/internal/blob.js",
|
||||
"lib/internal/blocklist.js",
|
||||
"lib/internal/bootstrap/node.js",
|
||||
"lib/internal/bootstrap/realm.js",
|
||||
"lib/internal/bootstrap/shadow_realm.js",
|
||||
"lib/internal/bootstrap/switches/does_not_own_process_state.js",
|
||||
"lib/internal/bootstrap/switches/does_own_process_state.js",
|
||||
"lib/internal/bootstrap/switches/is_main_thread.js",
|
||||
"lib/internal/bootstrap/switches/is_not_main_thread.js",
|
||||
"lib/internal/bootstrap/web/exposed-wildcard.js",
|
||||
"lib/internal/bootstrap/web/exposed-window-or-worker.js",
|
||||
"lib/internal/buffer.js",
|
||||
"lib/internal/child_process.js",
|
||||
"lib/internal/child_process/serialization.js",
|
||||
"lib/internal/cli_table.js",
|
||||
"lib/internal/cluster/child.js",
|
||||
"lib/internal/cluster/primary.js",
|
||||
"lib/internal/cluster/round_robin_handle.js",
|
||||
"lib/internal/cluster/shared_handle.js",
|
||||
"lib/internal/cluster/utils.js",
|
||||
"lib/internal/cluster/worker.js",
|
||||
"lib/internal/console/constructor.js",
|
||||
"lib/internal/console/global.js",
|
||||
"lib/internal/constants.js",
|
||||
"lib/internal/crypto/aes.js",
|
||||
"lib/internal/crypto/argon2.js",
|
||||
"lib/internal/crypto/certificate.js",
|
||||
"lib/internal/crypto/cfrg.js",
|
||||
"lib/internal/crypto/chacha20_poly1305.js",
|
||||
"lib/internal/crypto/cipher.js",
|
||||
"lib/internal/crypto/diffiehellman.js",
|
||||
"lib/internal/crypto/ec.js",
|
||||
"lib/internal/crypto/hash.js",
|
||||
"lib/internal/crypto/hashnames.js",
|
||||
"lib/internal/crypto/hkdf.js",
|
||||
"lib/internal/crypto/kem.js",
|
||||
"lib/internal/crypto/keygen.js",
|
||||
"lib/internal/crypto/keys.js",
|
||||
"lib/internal/crypto/mac.js",
|
||||
"lib/internal/crypto/ml_dsa.js",
|
||||
"lib/internal/crypto/ml_kem.js",
|
||||
"lib/internal/crypto/pbkdf2.js",
|
||||
"lib/internal/crypto/random.js",
|
||||
"lib/internal/crypto/rsa.js",
|
||||
"lib/internal/crypto/scrypt.js",
|
||||
"lib/internal/crypto/sig.js",
|
||||
"lib/internal/crypto/util.js",
|
||||
"lib/internal/crypto/webcrypto.js",
|
||||
"lib/internal/crypto/webidl.js",
|
||||
"lib/internal/crypto/x509.js",
|
||||
"lib/internal/data_url.js",
|
||||
"lib/internal/debugger/inspect.js",
|
||||
"lib/internal/debugger/inspect_client.js",
|
||||
"lib/internal/debugger/inspect_repl.js",
|
||||
"lib/internal/dgram.js",
|
||||
"lib/internal/dns/callback_resolver.js",
|
||||
"lib/internal/dns/promises.js",
|
||||
"lib/internal/dns/utils.js",
|
||||
"lib/internal/encoding.js",
|
||||
"lib/internal/error_serdes.js",
|
||||
"lib/internal/errors.js",
|
||||
"lib/internal/errors/error_source.js",
|
||||
"lib/internal/event_target.js",
|
||||
"lib/internal/events/abort_listener.js",
|
||||
"lib/internal/events/symbols.js",
|
||||
"lib/internal/file.js",
|
||||
"lib/internal/fixed_queue.js",
|
||||
"lib/internal/freelist.js",
|
||||
"lib/internal/freeze_intrinsics.js",
|
||||
"lib/internal/fs/cp/cp-sync.js",
|
||||
"lib/internal/fs/cp/cp.js",
|
||||
"lib/internal/fs/dir.js",
|
||||
"lib/internal/fs/glob.js",
|
||||
"lib/internal/fs/promises.js",
|
||||
"lib/internal/fs/read/context.js",
|
||||
"lib/internal/fs/recursive_watch.js",
|
||||
"lib/internal/fs/rimraf.js",
|
||||
"lib/internal/fs/streams.js",
|
||||
"lib/internal/fs/sync_write_stream.js",
|
||||
"lib/internal/fs/utils.js",
|
||||
"lib/internal/fs/watchers.js",
|
||||
"lib/internal/heap_utils.js",
|
||||
"lib/internal/histogram.js",
|
||||
"lib/internal/http.js",
|
||||
"lib/internal/http2/compat.js",
|
||||
"lib/internal/http2/core.js",
|
||||
"lib/internal/http2/util.js",
|
||||
"lib/internal/inspector/network.js",
|
||||
"lib/internal/inspector/network_http.js",
|
||||
"lib/internal/inspector/network_http2.js",
|
||||
"lib/internal/inspector/network_resources.js",
|
||||
"lib/internal/inspector/network_undici.js",
|
||||
"lib/internal/inspector_async_hook.js",
|
||||
"lib/internal/inspector_network_tracking.js",
|
||||
"lib/internal/js_stream_socket.js",
|
||||
"lib/internal/legacy/processbinding.js",
|
||||
"lib/internal/linkedlist.js",
|
||||
"lib/internal/locks.js",
|
||||
"lib/internal/main/check_syntax.js",
|
||||
"lib/internal/main/embedding.js",
|
||||
"lib/internal/main/eval_stdin.js",
|
||||
"lib/internal/main/eval_string.js",
|
||||
"lib/internal/main/inspect.js",
|
||||
"lib/internal/main/mksnapshot.js",
|
||||
"lib/internal/main/print_help.js",
|
||||
"lib/internal/main/prof_process.js",
|
||||
"lib/internal/main/repl.js",
|
||||
"lib/internal/main/run_main_module.js",
|
||||
"lib/internal/main/test_runner.js",
|
||||
"lib/internal/main/watch_mode.js",
|
||||
"lib/internal/main/worker_thread.js",
|
||||
"lib/internal/mime.js",
|
||||
"lib/internal/modules/cjs/loader.js",
|
||||
"lib/internal/modules/customization_hooks.js",
|
||||
"lib/internal/modules/esm/assert.js",
|
||||
"lib/internal/modules/esm/create_dynamic_module.js",
|
||||
"lib/internal/modules/esm/formats.js",
|
||||
"lib/internal/modules/esm/get_format.js",
|
||||
"lib/internal/modules/esm/hooks.js",
|
||||
"lib/internal/modules/esm/initialize_import_meta.js",
|
||||
"lib/internal/modules/esm/load.js",
|
||||
"lib/internal/modules/esm/loader.js",
|
||||
"lib/internal/modules/esm/module_job.js",
|
||||
"lib/internal/modules/esm/module_map.js",
|
||||
"lib/internal/modules/esm/resolve.js",
|
||||
"lib/internal/modules/esm/shared_constants.js",
|
||||
"lib/internal/modules/esm/translators.js",
|
||||
"lib/internal/modules/esm/utils.js",
|
||||
"lib/internal/modules/esm/worker.js",
|
||||
"lib/internal/modules/helpers.js",
|
||||
"lib/internal/modules/package_json_reader.js",
|
||||
"lib/internal/modules/run_main.js",
|
||||
"lib/internal/modules/typescript.js",
|
||||
"lib/internal/navigator.js",
|
||||
"lib/internal/net.js",
|
||||
"lib/internal/options.js",
|
||||
"lib/internal/per_context/domexception.js",
|
||||
"lib/internal/per_context/messageport.js",
|
||||
"lib/internal/per_context/primordials.js",
|
||||
"lib/internal/perf/event_loop_delay.js",
|
||||
"lib/internal/perf/event_loop_utilization.js",
|
||||
"lib/internal/perf/nodetiming.js",
|
||||
"lib/internal/perf/observe.js",
|
||||
"lib/internal/perf/performance.js",
|
||||
"lib/internal/perf/performance_entry.js",
|
||||
"lib/internal/perf/resource_timing.js",
|
||||
"lib/internal/perf/timerify.js",
|
||||
"lib/internal/perf/usertiming.js",
|
||||
"lib/internal/perf/utils.js",
|
||||
"lib/internal/priority_queue.js",
|
||||
"lib/internal/process/execution.js",
|
||||
"lib/internal/process/finalization.js",
|
||||
"lib/internal/process/per_thread.js",
|
||||
"lib/internal/process/permission.js",
|
||||
"lib/internal/process/pre_execution.js",
|
||||
"lib/internal/process/promises.js",
|
||||
"lib/internal/process/report.js",
|
||||
"lib/internal/process/signal.js",
|
||||
"lib/internal/process/task_queues.js",
|
||||
"lib/internal/process/warning.js",
|
||||
"lib/internal/process/worker_thread_only.js",
|
||||
"lib/internal/promise_hooks.js",
|
||||
"lib/internal/querystring.js",
|
||||
"lib/internal/quic/quic.js",
|
||||
"lib/internal/quic/state.js",
|
||||
"lib/internal/quic/stats.js",
|
||||
"lib/internal/quic/symbols.js",
|
||||
"lib/internal/readline/callbacks.js",
|
||||
"lib/internal/readline/emitKeypressEvents.js",
|
||||
"lib/internal/readline/interface.js",
|
||||
"lib/internal/readline/promises.js",
|
||||
"lib/internal/readline/utils.js",
|
||||
"lib/internal/repl.js",
|
||||
"lib/internal/repl/await.js",
|
||||
"lib/internal/repl/history.js",
|
||||
"lib/internal/repl/utils.js",
|
||||
"lib/internal/socket_list.js",
|
||||
"lib/internal/socketaddress.js",
|
||||
"lib/internal/source_map/prepare_stack_trace.js",
|
||||
"lib/internal/source_map/source_map.js",
|
||||
"lib/internal/source_map/source_map_cache.js",
|
||||
"lib/internal/source_map/source_map_cache_map.js",
|
||||
"lib/internal/stream_base_commons.js",
|
||||
"lib/internal/streams/add-abort-signal.js",
|
||||
"lib/internal/streams/compose.js",
|
||||
"lib/internal/streams/destroy.js",
|
||||
"lib/internal/streams/duplex.js",
|
||||
"lib/internal/streams/duplexify.js",
|
||||
"lib/internal/streams/duplexpair.js",
|
||||
"lib/internal/streams/end-of-stream.js",
|
||||
"lib/internal/streams/fast-utf8-stream.js",
|
||||
"lib/internal/streams/from.js",
|
||||
"lib/internal/streams/lazy_transform.js",
|
||||
"lib/internal/streams/legacy.js",
|
||||
"lib/internal/streams/operators.js",
|
||||
"lib/internal/streams/passthrough.js",
|
||||
"lib/internal/streams/pipeline.js",
|
||||
"lib/internal/streams/readable.js",
|
||||
"lib/internal/streams/state.js",
|
||||
"lib/internal/streams/transform.js",
|
||||
"lib/internal/streams/utils.js",
|
||||
"lib/internal/streams/writable.js",
|
||||
"lib/internal/test/binding.js",
|
||||
"lib/internal/test/transfer.js",
|
||||
"lib/internal/test_runner/assert.js",
|
||||
"lib/internal/test_runner/coverage.js",
|
||||
"lib/internal/test_runner/harness.js",
|
||||
"lib/internal/test_runner/mock/loader.js",
|
||||
"lib/internal/test_runner/mock/mock.js",
|
||||
"lib/internal/test_runner/mock/mock_timers.js",
|
||||
"lib/internal/test_runner/reporter/dot.js",
|
||||
"lib/internal/test_runner/reporter/junit.js",
|
||||
"lib/internal/test_runner/reporter/lcov.js",
|
||||
"lib/internal/test_runner/reporter/rerun.js",
|
||||
"lib/internal/test_runner/reporter/spec.js",
|
||||
"lib/internal/test_runner/reporter/tap.js",
|
||||
"lib/internal/test_runner/reporter/utils.js",
|
||||
"lib/internal/test_runner/reporter/v8-serializer.js",
|
||||
"lib/internal/test_runner/runner.js",
|
||||
"lib/internal/test_runner/snapshot.js",
|
||||
"lib/internal/test_runner/test.js",
|
||||
"lib/internal/test_runner/tests_stream.js",
|
||||
"lib/internal/test_runner/utils.js",
|
||||
"lib/internal/timers.js",
|
||||
"lib/internal/tls/secure-context.js",
|
||||
"lib/internal/trace_events_async_hooks.js",
|
||||
"lib/internal/tty.js",
|
||||
"lib/internal/url.js",
|
||||
"lib/internal/util.js",
|
||||
"lib/internal/util/colors.js",
|
||||
"lib/internal/util/comparisons.js",
|
||||
"lib/internal/util/debuglog.js",
|
||||
"lib/internal/util/diff.js",
|
||||
"lib/internal/util/inspect.js",
|
||||
"lib/internal/util/inspector.js",
|
||||
"lib/internal/util/parse_args/parse_args.js",
|
||||
"lib/internal/util/parse_args/utils.js",
|
||||
"lib/internal/util/trace_sigint.js",
|
||||
"lib/internal/util/types.js",
|
||||
"lib/internal/v8/startup_snapshot.js",
|
||||
"lib/internal/v8_prof_polyfill.js",
|
||||
"lib/internal/v8_prof_processor.js",
|
||||
"lib/internal/validators.js",
|
||||
"lib/internal/vm.js",
|
||||
"lib/internal/vm/module.js",
|
||||
"lib/internal/wasm_web_api.js",
|
||||
"lib/internal/watch_mode/files_watcher.js",
|
||||
"lib/internal/watchdog.js",
|
||||
"lib/internal/webidl.js",
|
||||
"lib/internal/webstorage.js",
|
||||
"lib/internal/webstreams/adapters.js",
|
||||
"lib/internal/webstreams/compression.js",
|
||||
"lib/internal/webstreams/encoding.js",
|
||||
"lib/internal/webstreams/queuingstrategies.js",
|
||||
"lib/internal/webstreams/readablestream.js",
|
||||
"lib/internal/webstreams/transfer.js",
|
||||
"lib/internal/webstreams/transformstream.js",
|
||||
"lib/internal/webstreams/util.js",
|
||||
"lib/internal/webstreams/writablestream.js",
|
||||
"lib/internal/worker.js",
|
||||
"lib/internal/worker/clone_dom_exception.js",
|
||||
"lib/internal/worker/io.js",
|
||||
"lib/internal/worker/js_transferable.js",
|
||||
"lib/internal/worker/messaging.js",
|
||||
"lib/module.js",
|
||||
"lib/net.js",
|
||||
"lib/os.js",
|
||||
"lib/path.js",
|
||||
"lib/path/posix.js",
|
||||
"lib/path/win32.js",
|
||||
"lib/perf_hooks.js",
|
||||
"lib/process.js",
|
||||
"lib/punycode.js",
|
||||
"lib/querystring.js",
|
||||
"lib/quic.js",
|
||||
"lib/readline.js",
|
||||
"lib/readline/promises.js",
|
||||
"lib/repl.js",
|
||||
"lib/sea.js",
|
||||
"lib/sqlite.js",
|
||||
"lib/stream.js",
|
||||
"lib/stream/consumers.js",
|
||||
"lib/stream/promises.js",
|
||||
"lib/stream/web.js",
|
||||
"lib/string_decoder.js",
|
||||
"lib/sys.js",
|
||||
"lib/test.js",
|
||||
"lib/test/reporters.js",
|
||||
"lib/timers.js",
|
||||
"lib/timers/promises.js",
|
||||
"lib/tls.js",
|
||||
"lib/trace_events.js",
|
||||
"lib/tty.js",
|
||||
"lib/url.js",
|
||||
"lib/util.js",
|
||||
"lib/util/types.js",
|
||||
"lib/v8.js",
|
||||
"lib/vm.js",
|
||||
"lib/wasi.js",
|
||||
"lib/worker_threads.js",
|
||||
"lib/zlib.js"
|
||||
],
|
||||
"node_module_version": 137,
|
||||
"node_no_browser_globals": "false",
|
||||
"node_prefix": "\\usr\\local",
|
||||
"node_quic": "false",
|
||||
"node_release_urlbase": "https://nodejs.org/download/release/",
|
||||
"node_shared": "false",
|
||||
"node_shared_ada": "false",
|
||||
"node_shared_brotli": "false",
|
||||
"node_shared_cares": "false",
|
||||
"node_shared_http_parser": "false",
|
||||
"node_shared_libuv": "false",
|
||||
"node_shared_nghttp2": "false",
|
||||
"node_shared_nghttp3": "false",
|
||||
"node_shared_ngtcp2": "false",
|
||||
"node_shared_openssl": "false",
|
||||
"node_shared_simdjson": "false",
|
||||
"node_shared_simdutf": "false",
|
||||
"node_shared_sqlite": "false",
|
||||
"node_shared_uvwasi": "false",
|
||||
"node_shared_zlib": "false",
|
||||
"node_shared_zstd": "false",
|
||||
"node_tag": "",
|
||||
"node_target_type": "executable",
|
||||
"node_use_amaro": "true",
|
||||
"node_use_bundled_v8": "true",
|
||||
"node_use_node_code_cache": "true",
|
||||
"node_use_node_snapshot": "true",
|
||||
"node_use_openssl": "true",
|
||||
"node_use_sqlite": "true",
|
||||
"node_use_v8_platform": "true",
|
||||
"node_with_ltcg": "true",
|
||||
"node_without_node_options": "false",
|
||||
"node_write_snapshot_as_array_literals": "true",
|
||||
"openssl_is_fips": "false",
|
||||
"openssl_quic": "false",
|
||||
"ossfuzz": "false",
|
||||
"shlib_suffix": "so.137",
|
||||
"single_executable_application": "true",
|
||||
"suppress_all_error_on_warn": "false",
|
||||
"target_arch": "x64",
|
||||
"ubsan": 0,
|
||||
"use_ccache_win": 0,
|
||||
"use_prefix_to_find_headers": "false",
|
||||
"v8_enable_31bit_smis_on_64bit_arch": 0,
|
||||
"v8_enable_extensible_ro_snapshot": 0,
|
||||
"v8_enable_external_code_space": 0,
|
||||
"v8_enable_gdbjit": 0,
|
||||
"v8_enable_hugepage": 0,
|
||||
"v8_enable_i18n_support": 1,
|
||||
"v8_enable_inspector": 1,
|
||||
"v8_enable_javascript_promise_hooks": 1,
|
||||
"v8_enable_lite_mode": 0,
|
||||
"v8_enable_maglev": 1,
|
||||
"v8_enable_object_print": 1,
|
||||
"v8_enable_pointer_compression": 0,
|
||||
"v8_enable_pointer_compression_shared_cage": 0,
|
||||
"v8_enable_sandbox": 0,
|
||||
"v8_enable_short_builtin_calls": 1,
|
||||
"v8_enable_wasm_simd256_revec": 1,
|
||||
"v8_enable_webassembly": 1,
|
||||
"v8_optimized_debug": 1,
|
||||
"v8_promise_internal_field_count": 1,
|
||||
"v8_random_seed": 0,
|
||||
"v8_trace_maps": 0,
|
||||
"v8_use_siphash": 1,
|
||||
"want_separate_host_toolset": 0,
|
||||
"nodedir": "C:\\Users\\dimir\\AppData\\Local\\node-gyp\\Cache\\24.11.1",
|
||||
"python": "C:\\Users\\dimir\\AppData\\Local\\Programs\\Python\\Python312\\python.exe",
|
||||
"standalone_static_library": 1,
|
||||
"msbuild_path": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\MSBuild\\Current\\Bin\\MSBuild.exe",
|
||||
"target": "v24.11.1",
|
||||
"real_openssl_major": "3",
|
||||
"user_agent": "npm/11.12.0 node/v24.11.1 win32 x64 workspaces/false",
|
||||
"userconfig": "C:\\Users\\dimir\\.npmrc",
|
||||
"save_dev": "true",
|
||||
"prefix": "C:\\Users\\dimir\\AppData\\Roaming\\npm",
|
||||
"npm_version": "11.12.0",
|
||||
"node_gyp": "C:\\Users\\dimir\\AppData\\Roaming\\npm\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js",
|
||||
"local_prefix": "C:\\Users\\dimir\\ssh-updater",
|
||||
"init_module": "C:\\Users\\dimir\\.npm-init.js",
|
||||
"global_prefix": "C:\\Users\\dimir\\AppData\\Roaming\\npm",
|
||||
"globalconfig": "C:\\Users\\dimir\\AppData\\Roaming\\npm\\etc\\npmrc",
|
||||
"cache": "C:\\Users\\dimir\\AppData\\Local\\npm-cache"
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{529648C8-47C1-F1B5-2925-8170DD79C9A4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>sshcrypto</RootNamespace>
|
||||
<IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Locals">
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props"/>
|
||||
<ImportGroup Label="ExtensionSettings"/>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros"/>
|
||||
<PropertyGroup>
|
||||
<ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\..\bin\;$(MSBuildProjectDirectory)\..\bin\</ExecutablePath>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<IntDir>$(Configuration)\obj\$(ProjectName)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.node</TargetExt>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.node</TargetExt>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.node</TargetExt>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.node</TargetExt>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
<TargetPath>$(OutDir)\$(ProjectName).node</TargetPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\include\node;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\src;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\config;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\openssl\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\uv\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\zlib;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\v8\include;..\..\..\..\..\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/Zc:__cplusplus -std:c++20 /Zm2000 %(AdditionalOptions)</AdditionalOptions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4351;4355;4800;4251;4275;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=sshcrypto;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;_GLIBCXX_USE_CXX11_ABI=1;_FILE_OFFSET_BITS=64;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;NOMINMAX;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;OPENSSL_API_COMPAT=0x10100000L;REAL_OPENSSL_MAJOR=3;BUILDING_NODE_EXTENSION;HOST_BINARY="node.exe";DEBUG;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<AdditionalOptions>/LTCG:INCREMENTAL %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
<Link>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;delayimp.lib;"C:\\Users\\dimir\\AppData\\Local\\node-gyp\\Cache\\24.11.1\\x64\\node.lib"</AdditionalDependencies>
|
||||
<AdditionalOptions>/LTCG:INCREMENTAL /ignore:4199 %(AdditionalOptions)</AdditionalOptions>
|
||||
<DelayLoadDLLs>node.exe;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<OutputFile>$(OutDir)$(ProjectName).node</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetExt>.node</TargetExt>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\include\node;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\src;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\config;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\openssl\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\uv\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\zlib;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\v8\include;..\..\..\..\..\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=sshcrypto;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;_GLIBCXX_USE_CXX11_ABI=1;_FILE_OFFSET_BITS=64;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;NOMINMAX;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;OPENSSL_API_COMPAT=0x10100000L;REAL_OPENSSL_MAJOR=3;BUILDING_NODE_EXTENSION;HOST_BINARY="node.exe";DEBUG;_DEBUG;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\include\node;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\src;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\config;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\openssl\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\uv\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\zlib;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\v8\include;..\..\..\..\..\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/Zc:__cplusplus -std:c++20 /Zm2000 %(AdditionalOptions)</AdditionalOptions>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4351;4355;4800;4251;4275;4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<Optimization>Full</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=sshcrypto;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;_GLIBCXX_USE_CXX11_ABI=1;_FILE_OFFSET_BITS=64;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;NOMINMAX;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;OPENSSL_API_COMPAT=0x10100000L;REAL_OPENSSL_MAJOR=3;BUILDING_NODE_EXTENSION;HOST_BINARY="node.exe";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<StringPooling>true</StringPooling>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<AdditionalOptions>/LTCG:INCREMENTAL %(AdditionalOptions)</AdditionalOptions>
|
||||
</Lib>
|
||||
<Link>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;delayimp.lib;"C:\\Users\\dimir\\AppData\\Local\\node-gyp\\Cache\\24.11.1\\x64\\node.lib"</AdditionalDependencies>
|
||||
<AdditionalOptions>/LTCG:INCREMENTAL /ignore:4199 %(AdditionalOptions)</AdditionalOptions>
|
||||
<DelayLoadDLLs>node.exe;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<OutputFile>$(OutDir)$(ProjectName).node</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetExt>.node</TargetExt>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\include\node;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\src;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\config;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\openssl\openssl\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\uv\include;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\zlib;C:\Users\dimir\AppData\Local\node-gyp\Cache\24.11.1\deps\v8\include;..\..\..\..\..\nan;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>NODE_GYP_MODULE_NAME=sshcrypto;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;_GLIBCXX_USE_CXX11_ABI=1;_FILE_OFFSET_BITS=64;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;NOMINMAX;OPENSSL_NO_PINSHARED;OPENSSL_THREADS;OPENSSL_API_COMPAT=0x10100000L;REAL_OPENSSL_MAJOR=3;BUILDING_NODE_EXTENSION;HOST_BINARY="node.exe";%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\binding.gyp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\binding.cc">
|
||||
<ObjectFileName>$(IntDir)\src\binding.obj</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\src\win_delay_load_hook.cc"/>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets"/>
|
||||
<ImportGroup Label="ExtensionTargets"/>
|
||||
</Project>
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="..">
|
||||
<UniqueIdentifier>{13ED4249-1F9C-5F0F-2651-29A73F3A7059}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="..\src">
|
||||
<UniqueIdentifier>{F1003AD6-4B6D-45DF-3F56-5CAC869BF55E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:">
|
||||
<UniqueIdentifier>{F87FD356-0FEB-9BC5-D1FA-368C81420008}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users">
|
||||
<UniqueIdentifier>{707347A1-1ABA-A9B2-9AF4-DE122F5D7F08}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir">
|
||||
<UniqueIdentifier>{9110070F-34CE-9DE2-A12E-05D95C34015C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData">
|
||||
<UniqueIdentifier>{DABCEBCE-33D1-4D68-EC67-0BC19A2A0901}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming">
|
||||
<UniqueIdentifier>{06897101-0A2C-F34A-36C2-4D0BE8BF5EB9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming\npm">
|
||||
<UniqueIdentifier>{E6F3EBE6-A3A6-AA7E-34C1-5CE4364854E4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming\npm\node_modules">
|
||||
<UniqueIdentifier>{126A39EA-1D28-5689-C126-0DA0AB5837A0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming\npm\node_modules\npm">
|
||||
<UniqueIdentifier>{E6F3EBE6-A3A6-AA7E-34C1-5CE4364854E4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules">
|
||||
<UniqueIdentifier>{126A39EA-1D28-5689-C126-0DA0AB5837A0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp">
|
||||
<UniqueIdentifier>{49558BB4-6D34-CA91-A65D-85A65792DC11}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\src">
|
||||
<UniqueIdentifier>{F1003AD6-4B6D-45DF-3F56-5CAC869BF55E}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="..">
|
||||
<UniqueIdentifier>{13ED4249-1F9C-5F0F-2651-29A73F3A7059}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\binding.cc">
|
||||
<Filter>..\src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\src\win_delay_load_hook.cc">
|
||||
<Filter>C:\Users\dimir\AppData\Roaming\npm\node_modules\npm\node_modules\node-gyp\src</Filter>
|
||||
</ClCompile>
|
||||
<None Include="..\binding.gyp">
|
||||
<Filter>..</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+43
File diff suppressed because one or more lines are too long
+2300
File diff suppressed because it is too large
Load Diff
+16
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
const MESSAGE_HANDLERS = new Array(256);
|
||||
[
|
||||
require('./kex.js').HANDLERS,
|
||||
require('./handlers.misc.js'),
|
||||
].forEach((handlers) => {
|
||||
// eslint-disable-next-line prefer-const
|
||||
for (let [type, handler] of Object.entries(handlers)) {
|
||||
type = +type;
|
||||
if (isFinite(type) && type >= 0 && type < MESSAGE_HANDLERS.length)
|
||||
MESSAGE_HANDLERS[type] = handler;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = MESSAGE_HANDLERS;
|
||||
+1285
File diff suppressed because it is too large
Load Diff
+1908
File diff suppressed because it is too large
Load Diff
+1484
File diff suppressed because it is too large
Load Diff
+115
@@ -0,0 +1,115 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { inspect } = require('util');
|
||||
|
||||
// Only use this for integers! Decimal numbers do not work with this function.
|
||||
function addNumericalSeparator(val) {
|
||||
let res = '';
|
||||
let i = val.length;
|
||||
const start = val[0] === '-' ? 1 : 0;
|
||||
for (; i >= start + 4; i -= 3)
|
||||
res = `_${val.slice(i - 3, i)}${res}`;
|
||||
return `${val.slice(0, i)}${res}`;
|
||||
}
|
||||
|
||||
function oneOf(expected, thing) {
|
||||
assert(typeof thing === 'string', '`thing` has to be of type string');
|
||||
if (Array.isArray(expected)) {
|
||||
const len = expected.length;
|
||||
assert(len > 0, 'At least one expected value needs to be specified');
|
||||
expected = expected.map((i) => String(i));
|
||||
if (len > 2) {
|
||||
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or `
|
||||
+ expected[len - 1];
|
||||
} else if (len === 2) {
|
||||
return `one of ${thing} ${expected[0]} or ${expected[1]}`;
|
||||
}
|
||||
return `of ${thing} ${expected[0]}`;
|
||||
}
|
||||
return `of ${thing} ${String(expected)}`;
|
||||
}
|
||||
|
||||
|
||||
exports.ERR_INTERNAL_ASSERTION = class ERR_INTERNAL_ASSERTION extends Error {
|
||||
constructor(message) {
|
||||
super();
|
||||
Error.captureStackTrace(this, ERR_INTERNAL_ASSERTION);
|
||||
|
||||
const suffix = 'This is caused by either a bug in ssh2 '
|
||||
+ 'or incorrect usage of ssh2 internals.\n'
|
||||
+ 'Please open an issue with this stack trace at '
|
||||
+ 'https://github.com/mscdex/ssh2/issues\n';
|
||||
|
||||
this.message = (message === undefined ? suffix : `${message}\n${suffix}`);
|
||||
}
|
||||
};
|
||||
|
||||
const MAX_32BIT_INT = 2 ** 32;
|
||||
const MAX_32BIT_BIGINT = (() => {
|
||||
try {
|
||||
return new Function('return 2n ** 32n')();
|
||||
} catch {}
|
||||
})();
|
||||
exports.ERR_OUT_OF_RANGE = class ERR_OUT_OF_RANGE extends RangeError {
|
||||
constructor(str, range, input, replaceDefaultBoolean) {
|
||||
super();
|
||||
Error.captureStackTrace(this, ERR_OUT_OF_RANGE);
|
||||
|
||||
assert(range, 'Missing "range" argument');
|
||||
let msg = (replaceDefaultBoolean
|
||||
? str
|
||||
: `The value of "${str}" is out of range.`);
|
||||
let received;
|
||||
if (Number.isInteger(input) && Math.abs(input) > MAX_32BIT_INT) {
|
||||
received = addNumericalSeparator(String(input));
|
||||
} else if (typeof input === 'bigint') {
|
||||
received = String(input);
|
||||
if (input > MAX_32BIT_BIGINT || input < -MAX_32BIT_BIGINT)
|
||||
received = addNumericalSeparator(received);
|
||||
received += 'n';
|
||||
} else {
|
||||
received = inspect(input);
|
||||
}
|
||||
msg += ` It must be ${range}. Received ${received}`;
|
||||
|
||||
this.message = msg;
|
||||
}
|
||||
};
|
||||
|
||||
class ERR_INVALID_ARG_TYPE extends TypeError {
|
||||
constructor(name, expected, actual) {
|
||||
super();
|
||||
Error.captureStackTrace(this, ERR_INVALID_ARG_TYPE);
|
||||
|
||||
assert(typeof name === 'string', `'name' must be a string`);
|
||||
|
||||
// determiner: 'must be' or 'must not be'
|
||||
let determiner;
|
||||
if (typeof expected === 'string' && expected.startsWith('not ')) {
|
||||
determiner = 'must not be';
|
||||
expected = expected.replace(/^not /, '');
|
||||
} else {
|
||||
determiner = 'must be';
|
||||
}
|
||||
|
||||
let msg;
|
||||
if (name.endsWith(' argument')) {
|
||||
// For cases like 'first argument'
|
||||
msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`;
|
||||
} else {
|
||||
const type = (name.includes('.') ? 'property' : 'argument');
|
||||
msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`;
|
||||
}
|
||||
|
||||
msg += `. Received type ${typeof actual}`;
|
||||
|
||||
this.message = msg;
|
||||
}
|
||||
}
|
||||
exports.ERR_INVALID_ARG_TYPE = ERR_INVALID_ARG_TYPE;
|
||||
|
||||
exports.validateNumber = function validateNumber(value, name) {
|
||||
if (typeof value !== 'number')
|
||||
throw new ERR_INVALID_ARG_TYPE(name, 'number', value);
|
||||
};
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
'use strict';
|
||||
|
||||
const Ber = require('asn1').Ber;
|
||||
|
||||
let DISCONNECT_REASON;
|
||||
|
||||
const FastBuffer = Buffer[Symbol.species];
|
||||
const TypedArrayFill = Object.getPrototypeOf(Uint8Array.prototype).fill;
|
||||
|
||||
function readUInt32BE(buf, offset) {
|
||||
return (buf[offset++] * 16777216)
|
||||
+ (buf[offset++] * 65536)
|
||||
+ (buf[offset++] * 256)
|
||||
+ buf[offset];
|
||||
}
|
||||
|
||||
function bufferCopy(src, dest, srcStart, srcEnd, destStart) {
|
||||
if (!destStart)
|
||||
destStart = 0;
|
||||
if (srcEnd > src.length)
|
||||
srcEnd = src.length;
|
||||
let nb = srcEnd - srcStart;
|
||||
const destLeft = (dest.length - destStart);
|
||||
if (nb > destLeft)
|
||||
nb = destLeft;
|
||||
dest.set(new Uint8Array(src.buffer, src.byteOffset + srcStart, nb),
|
||||
destStart);
|
||||
return nb;
|
||||
}
|
||||
|
||||
function bufferSlice(buf, start, end) {
|
||||
if (end === undefined)
|
||||
end = buf.length;
|
||||
return new FastBuffer(buf.buffer, buf.byteOffset + start, end - start);
|
||||
}
|
||||
|
||||
function makeBufferParser() {
|
||||
let pos = 0;
|
||||
let buffer;
|
||||
|
||||
const self = {
|
||||
init: (buf, start) => {
|
||||
buffer = buf;
|
||||
pos = (typeof start === 'number' ? start : 0);
|
||||
},
|
||||
pos: () => pos,
|
||||
length: () => (buffer ? buffer.length : 0),
|
||||
avail: () => (buffer && pos < buffer.length ? buffer.length - pos : 0),
|
||||
clear: () => {
|
||||
buffer = undefined;
|
||||
},
|
||||
readUInt32BE: () => {
|
||||
if (!buffer || pos + 3 >= buffer.length)
|
||||
return;
|
||||
return (buffer[pos++] * 16777216)
|
||||
+ (buffer[pos++] * 65536)
|
||||
+ (buffer[pos++] * 256)
|
||||
+ buffer[pos++];
|
||||
},
|
||||
readUInt64BE: (behavior) => {
|
||||
if (!buffer || pos + 7 >= buffer.length)
|
||||
return;
|
||||
switch (behavior) {
|
||||
case 'always':
|
||||
return BigInt(`0x${buffer.hexSlice(pos, pos += 8)}`);
|
||||
case 'maybe':
|
||||
if (buffer[pos] > 0x1F)
|
||||
return BigInt(`0x${buffer.hexSlice(pos, pos += 8)}`);
|
||||
// FALLTHROUGH
|
||||
default:
|
||||
return (buffer[pos++] * 72057594037927940)
|
||||
+ (buffer[pos++] * 281474976710656)
|
||||
+ (buffer[pos++] * 1099511627776)
|
||||
+ (buffer[pos++] * 4294967296)
|
||||
+ (buffer[pos++] * 16777216)
|
||||
+ (buffer[pos++] * 65536)
|
||||
+ (buffer[pos++] * 256)
|
||||
+ buffer[pos++];
|
||||
}
|
||||
},
|
||||
skip: (n) => {
|
||||
if (buffer && n > 0)
|
||||
pos += n;
|
||||
},
|
||||
skipString: () => {
|
||||
const len = self.readUInt32BE();
|
||||
if (len === undefined)
|
||||
return;
|
||||
pos += len;
|
||||
return (pos <= buffer.length ? len : undefined);
|
||||
},
|
||||
readByte: () => {
|
||||
if (buffer && pos < buffer.length)
|
||||
return buffer[pos++];
|
||||
},
|
||||
readBool: () => {
|
||||
if (buffer && pos < buffer.length)
|
||||
return !!buffer[pos++];
|
||||
},
|
||||
readList: () => {
|
||||
const list = self.readString(true);
|
||||
if (list === undefined)
|
||||
return;
|
||||
return (list ? list.split(',') : []);
|
||||
},
|
||||
readString: (dest, maxLen) => {
|
||||
if (typeof dest === 'number') {
|
||||
maxLen = dest;
|
||||
dest = undefined;
|
||||
}
|
||||
|
||||
const len = self.readUInt32BE();
|
||||
if (len === undefined)
|
||||
return;
|
||||
|
||||
if ((buffer.length - pos) < len
|
||||
|| (typeof maxLen === 'number' && len > maxLen)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dest) {
|
||||
if (Buffer.isBuffer(dest))
|
||||
return bufferCopy(buffer, dest, pos, pos += len);
|
||||
return buffer.utf8Slice(pos, pos += len);
|
||||
}
|
||||
return bufferSlice(buffer, pos, pos += len);
|
||||
},
|
||||
readRaw: (len) => {
|
||||
if (!buffer)
|
||||
return;
|
||||
if (typeof len !== 'number')
|
||||
return bufferSlice(buffer, pos, pos += (buffer.length - pos));
|
||||
if ((buffer.length - pos) >= len)
|
||||
return bufferSlice(buffer, pos, pos += len);
|
||||
},
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
function makeError(msg, level, fatal) {
|
||||
const err = new Error(msg);
|
||||
if (typeof level === 'boolean') {
|
||||
fatal = level;
|
||||
err.level = 'protocol';
|
||||
} else {
|
||||
err.level = level || 'protocol';
|
||||
}
|
||||
err.fatal = !!fatal;
|
||||
return err;
|
||||
}
|
||||
|
||||
function writeUInt32BE(buf, value, offset) {
|
||||
buf[offset++] = (value >>> 24);
|
||||
buf[offset++] = (value >>> 16);
|
||||
buf[offset++] = (value >>> 8);
|
||||
buf[offset++] = value;
|
||||
return offset;
|
||||
}
|
||||
|
||||
const utilBufferParser = makeBufferParser();
|
||||
|
||||
module.exports = {
|
||||
bufferCopy,
|
||||
bufferSlice,
|
||||
FastBuffer,
|
||||
bufferFill: (buf, value, start, end) => {
|
||||
return TypedArrayFill.call(buf, value, start, end);
|
||||
},
|
||||
makeError,
|
||||
doFatalError: (protocol, msg, level, reason) => {
|
||||
let err;
|
||||
if (DISCONNECT_REASON === undefined)
|
||||
({ DISCONNECT_REASON } = require('./constants.js'));
|
||||
if (msg instanceof Error) {
|
||||
// doFatalError(protocol, err[, reason])
|
||||
err = msg;
|
||||
if (typeof level !== 'number')
|
||||
reason = DISCONNECT_REASON.PROTOCOL_ERROR;
|
||||
else
|
||||
reason = level;
|
||||
} else {
|
||||
// doFatalError(protocol, msg[, level[, reason]])
|
||||
err = makeError(msg, level, true);
|
||||
}
|
||||
if (typeof reason !== 'number')
|
||||
reason = DISCONNECT_REASON.PROTOCOL_ERROR;
|
||||
protocol.disconnect(reason);
|
||||
protocol._destruct();
|
||||
protocol._onError(err);
|
||||
return Infinity;
|
||||
},
|
||||
readUInt32BE,
|
||||
writeUInt32BE,
|
||||
writeUInt32LE: (buf, value, offset) => {
|
||||
buf[offset++] = value;
|
||||
buf[offset++] = (value >>> 8);
|
||||
buf[offset++] = (value >>> 16);
|
||||
buf[offset++] = (value >>> 24);
|
||||
return offset;
|
||||
},
|
||||
makeBufferParser,
|
||||
bufferParser: makeBufferParser(),
|
||||
readString: (buffer, start, dest, maxLen) => {
|
||||
if (typeof dest === 'number') {
|
||||
maxLen = dest;
|
||||
dest = undefined;
|
||||
}
|
||||
|
||||
if (start === undefined)
|
||||
start = 0;
|
||||
|
||||
const left = (buffer.length - start);
|
||||
if (start < 0 || start >= buffer.length || left < 4)
|
||||
return;
|
||||
|
||||
const len = readUInt32BE(buffer, start);
|
||||
if (left < (4 + len) || (typeof maxLen === 'number' && len > maxLen))
|
||||
return;
|
||||
|
||||
start += 4;
|
||||
const end = start + len;
|
||||
buffer._pos = end;
|
||||
|
||||
if (dest) {
|
||||
if (Buffer.isBuffer(dest))
|
||||
return bufferCopy(buffer, dest, start, end);
|
||||
return buffer.utf8Slice(start, end);
|
||||
}
|
||||
return bufferSlice(buffer, start, end);
|
||||
},
|
||||
sigSSHToASN1: (sig, type) => {
|
||||
switch (type) {
|
||||
case 'ssh-dss': {
|
||||
if (sig.length > 40)
|
||||
return sig;
|
||||
// Change bare signature r and s values to ASN.1 BER values for OpenSSL
|
||||
const asnWriter = new Ber.Writer();
|
||||
asnWriter.startSequence();
|
||||
let r = sig.slice(0, 20);
|
||||
let s = sig.slice(20);
|
||||
if (r[0] & 0x80) {
|
||||
const rNew = Buffer.allocUnsafe(21);
|
||||
rNew[0] = 0x00;
|
||||
r.copy(rNew, 1);
|
||||
r = rNew;
|
||||
} else if (r[0] === 0x00 && !(r[1] & 0x80)) {
|
||||
r = r.slice(1);
|
||||
}
|
||||
if (s[0] & 0x80) {
|
||||
const sNew = Buffer.allocUnsafe(21);
|
||||
sNew[0] = 0x00;
|
||||
s.copy(sNew, 1);
|
||||
s = sNew;
|
||||
} else if (s[0] === 0x00 && !(s[1] & 0x80)) {
|
||||
s = s.slice(1);
|
||||
}
|
||||
asnWriter.writeBuffer(r, Ber.Integer);
|
||||
asnWriter.writeBuffer(s, Ber.Integer);
|
||||
asnWriter.endSequence();
|
||||
return asnWriter.buffer;
|
||||
}
|
||||
case 'ecdsa-sha2-nistp256':
|
||||
case 'ecdsa-sha2-nistp384':
|
||||
case 'ecdsa-sha2-nistp521': {
|
||||
utilBufferParser.init(sig, 0);
|
||||
const r = utilBufferParser.readString();
|
||||
const s = utilBufferParser.readString();
|
||||
utilBufferParser.clear();
|
||||
if (r === undefined || s === undefined)
|
||||
return;
|
||||
|
||||
const asnWriter = new Ber.Writer();
|
||||
asnWriter.startSequence();
|
||||
asnWriter.writeBuffer(r, Ber.Integer);
|
||||
asnWriter.writeBuffer(s, Ber.Integer);
|
||||
asnWriter.endSequence();
|
||||
return asnWriter.buffer;
|
||||
}
|
||||
default:
|
||||
return sig;
|
||||
}
|
||||
},
|
||||
convertSignature: (signature, keyType) => {
|
||||
switch (keyType) {
|
||||
case 'ssh-dss': {
|
||||
if (signature.length <= 40)
|
||||
return signature;
|
||||
// This is a quick and dirty way to get from BER encoded r and s that
|
||||
// OpenSSL gives us, to just the bare values back to back (40 bytes
|
||||
// total) like OpenSSH (and possibly others) are expecting
|
||||
const asnReader = new Ber.Reader(signature);
|
||||
asnReader.readSequence();
|
||||
let r = asnReader.readString(Ber.Integer, true);
|
||||
let s = asnReader.readString(Ber.Integer, true);
|
||||
let rOffset = 0;
|
||||
let sOffset = 0;
|
||||
if (r.length < 20) {
|
||||
const rNew = Buffer.allocUnsafe(20);
|
||||
rNew.set(r, 1);
|
||||
r = rNew;
|
||||
r[0] = 0;
|
||||
}
|
||||
if (s.length < 20) {
|
||||
const sNew = Buffer.allocUnsafe(20);
|
||||
sNew.set(s, 1);
|
||||
s = sNew;
|
||||
s[0] = 0;
|
||||
}
|
||||
if (r.length > 20 && r[0] === 0)
|
||||
rOffset = 1;
|
||||
if (s.length > 20 && s[0] === 0)
|
||||
sOffset = 1;
|
||||
const newSig =
|
||||
Buffer.allocUnsafe((r.length - rOffset) + (s.length - sOffset));
|
||||
bufferCopy(r, newSig, rOffset, r.length, 0);
|
||||
bufferCopy(s, newSig, sOffset, s.length, r.length - rOffset);
|
||||
return newSig;
|
||||
}
|
||||
case 'ecdsa-sha2-nistp256':
|
||||
case 'ecdsa-sha2-nistp384':
|
||||
case 'ecdsa-sha2-nistp521': {
|
||||
if (signature[0] === 0)
|
||||
return signature;
|
||||
// Convert SSH signature parameters to ASN.1 BER values for OpenSSL
|
||||
const asnReader = new Ber.Reader(signature);
|
||||
asnReader.readSequence();
|
||||
const r = asnReader.readString(Ber.Integer, true);
|
||||
const s = asnReader.readString(Ber.Integer, true);
|
||||
if (r === null || s === null)
|
||||
return;
|
||||
const newSig = Buffer.allocUnsafe(4 + r.length + 4 + s.length);
|
||||
writeUInt32BE(newSig, r.length, 0);
|
||||
newSig.set(r, 4);
|
||||
writeUInt32BE(newSig, s.length, 4 + r.length);
|
||||
newSig.set(s, 4 + 4 + r.length);
|
||||
return newSig;
|
||||
}
|
||||
}
|
||||
|
||||
return signature;
|
||||
},
|
||||
sendPacket: (proto, packet, bypass) => {
|
||||
if (!bypass && proto._kexinit !== undefined) {
|
||||
// We're currently in the middle of a handshake
|
||||
|
||||
if (proto._queue === undefined)
|
||||
proto._queue = [];
|
||||
proto._queue.push(packet);
|
||||
proto._debug && proto._debug('Outbound: ... packet queued');
|
||||
return false;
|
||||
}
|
||||
proto._cipher.encrypt(packet);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
'use strict';
|
||||
|
||||
const { kMaxLength } = require('buffer');
|
||||
const {
|
||||
createInflate,
|
||||
constants: {
|
||||
DEFLATE,
|
||||
INFLATE,
|
||||
Z_DEFAULT_CHUNK,
|
||||
Z_DEFAULT_COMPRESSION,
|
||||
Z_DEFAULT_MEMLEVEL,
|
||||
Z_DEFAULT_STRATEGY,
|
||||
Z_DEFAULT_WINDOWBITS,
|
||||
Z_PARTIAL_FLUSH,
|
||||
}
|
||||
} = require('zlib');
|
||||
const ZlibHandle = createInflate()._handle.constructor;
|
||||
|
||||
function processCallback() {
|
||||
throw new Error('Should not get here');
|
||||
}
|
||||
|
||||
function zlibOnError(message, errno, code) {
|
||||
const self = this._owner;
|
||||
// There is no way to cleanly recover.
|
||||
// Continuing only obscures problems.
|
||||
|
||||
const error = new Error(message);
|
||||
error.errno = errno;
|
||||
error.code = code;
|
||||
self._err = error;
|
||||
}
|
||||
|
||||
function _close(engine) {
|
||||
// Caller may invoke .close after a zlib error (which will null _handle).
|
||||
if (!engine._handle)
|
||||
return;
|
||||
|
||||
engine._handle.close();
|
||||
engine._handle = null;
|
||||
}
|
||||
|
||||
class Zlib {
|
||||
constructor(mode) {
|
||||
const windowBits = Z_DEFAULT_WINDOWBITS;
|
||||
const level = Z_DEFAULT_COMPRESSION;
|
||||
const memLevel = Z_DEFAULT_MEMLEVEL;
|
||||
const strategy = Z_DEFAULT_STRATEGY;
|
||||
const dictionary = undefined;
|
||||
|
||||
this._err = undefined;
|
||||
this._writeState = new Uint32Array(2);
|
||||
this._chunkSize = Z_DEFAULT_CHUNK;
|
||||
this._maxOutputLength = kMaxLength;
|
||||
this._outBuffer = Buffer.allocUnsafe(this._chunkSize);
|
||||
this._outOffset = 0;
|
||||
|
||||
this._handle = new ZlibHandle(mode);
|
||||
this._handle._owner = this;
|
||||
this._handle.onerror = zlibOnError;
|
||||
this._handle.init(windowBits,
|
||||
level,
|
||||
memLevel,
|
||||
strategy,
|
||||
this._writeState,
|
||||
processCallback,
|
||||
dictionary);
|
||||
}
|
||||
|
||||
writeSync(chunk, retChunks) {
|
||||
const handle = this._handle;
|
||||
if (!handle)
|
||||
throw new Error('Invalid Zlib instance');
|
||||
|
||||
let availInBefore = chunk.length;
|
||||
let availOutBefore = this._chunkSize - this._outOffset;
|
||||
let inOff = 0;
|
||||
let availOutAfter;
|
||||
let availInAfter;
|
||||
|
||||
let buffers;
|
||||
let nread = 0;
|
||||
const state = this._writeState;
|
||||
let buffer = this._outBuffer;
|
||||
let offset = this._outOffset;
|
||||
const chunkSize = this._chunkSize;
|
||||
|
||||
while (true) {
|
||||
handle.writeSync(Z_PARTIAL_FLUSH,
|
||||
chunk, // in
|
||||
inOff, // in_off
|
||||
availInBefore, // in_len
|
||||
buffer, // out
|
||||
offset, // out_off
|
||||
availOutBefore); // out_len
|
||||
if (this._err)
|
||||
throw this._err;
|
||||
|
||||
availOutAfter = state[0];
|
||||
availInAfter = state[1];
|
||||
|
||||
const inDelta = availInBefore - availInAfter;
|
||||
const have = availOutBefore - availOutAfter;
|
||||
|
||||
if (have > 0) {
|
||||
const out = (offset === 0 && have === buffer.length
|
||||
? buffer
|
||||
: buffer.slice(offset, offset + have));
|
||||
offset += have;
|
||||
if (!buffers)
|
||||
buffers = out;
|
||||
else if (buffers.push === undefined)
|
||||
buffers = [buffers, out];
|
||||
else
|
||||
buffers.push(out);
|
||||
nread += out.byteLength;
|
||||
|
||||
if (nread > this._maxOutputLength) {
|
||||
_close(this);
|
||||
throw new Error(
|
||||
`Output length exceeded maximum of ${this._maxOutputLength}`
|
||||
);
|
||||
}
|
||||
} else if (have !== 0) {
|
||||
throw new Error('have should not go down');
|
||||
}
|
||||
|
||||
// Exhausted the output buffer, or used all the input create a new one.
|
||||
if (availOutAfter === 0 || offset >= chunkSize) {
|
||||
availOutBefore = chunkSize;
|
||||
offset = 0;
|
||||
buffer = Buffer.allocUnsafe(chunkSize);
|
||||
}
|
||||
|
||||
if (availOutAfter === 0) {
|
||||
// Not actually done. Need to reprocess.
|
||||
// Also, update the availInBefore to the availInAfter value,
|
||||
// so that if we have to hit it a third (fourth, etc.) time,
|
||||
// it'll have the correct byte counts.
|
||||
inOff += inDelta;
|
||||
availInBefore = availInAfter;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._outBuffer = buffer;
|
||||
this._outOffset = offset;
|
||||
|
||||
if (nread === 0)
|
||||
buffers = Buffer.alloc(0);
|
||||
|
||||
if (retChunks) {
|
||||
buffers.totalLen = nread;
|
||||
return buffers;
|
||||
}
|
||||
|
||||
if (buffers.push === undefined)
|
||||
return buffers;
|
||||
|
||||
const output = Buffer.allocUnsafe(nread);
|
||||
for (let i = 0, p = 0; i < buffers.length; ++i) {
|
||||
const buf = buffers[i];
|
||||
output.set(buf, p);
|
||||
p += buf.length;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
class ZlibPacketWriter {
|
||||
constructor(protocol) {
|
||||
this.allocStart = 0;
|
||||
this.allocStartKEX = 0;
|
||||
this._protocol = protocol;
|
||||
this._zlib = new Zlib(DEFLATE);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this._zlib)
|
||||
_close(this._zlib);
|
||||
}
|
||||
|
||||
alloc(payloadSize, force) {
|
||||
return Buffer.allocUnsafe(payloadSize);
|
||||
}
|
||||
|
||||
finalize(payload, force) {
|
||||
if (this._protocol._kexinit === undefined || force) {
|
||||
const output = this._zlib.writeSync(payload, true);
|
||||
const packet = this._protocol._cipher.allocPacket(output.totalLen);
|
||||
if (output.push === undefined) {
|
||||
packet.set(output, 5);
|
||||
} else {
|
||||
for (let i = 0, p = 5; i < output.length; ++i) {
|
||||
const chunk = output[i];
|
||||
packet.set(chunk, p);
|
||||
p += chunk.length;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
class PacketWriter {
|
||||
constructor(protocol) {
|
||||
this.allocStart = 5;
|
||||
this.allocStartKEX = 5;
|
||||
this._protocol = protocol;
|
||||
}
|
||||
|
||||
cleanup() {}
|
||||
|
||||
alloc(payloadSize, force) {
|
||||
if (this._protocol._kexinit === undefined || force)
|
||||
return this._protocol._cipher.allocPacket(payloadSize);
|
||||
return Buffer.allocUnsafe(payloadSize);
|
||||
}
|
||||
|
||||
finalize(packet, force) {
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
class ZlibPacketReader {
|
||||
constructor() {
|
||||
this._zlib = new Zlib(INFLATE);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this._zlib)
|
||||
_close(this._zlib);
|
||||
}
|
||||
|
||||
read(data) {
|
||||
return this._zlib.writeSync(data, false);
|
||||
}
|
||||
}
|
||||
|
||||
class PacketReader {
|
||||
cleanup() {}
|
||||
|
||||
read(data) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
PacketReader,
|
||||
PacketWriter,
|
||||
ZlibPacketReader,
|
||||
ZlibPacketWriter,
|
||||
};
|
||||
+1380
File diff suppressed because it is too large
Load Diff
+336
@@ -0,0 +1,336 @@
|
||||
'use strict';
|
||||
|
||||
const { SFTP } = require('./protocol/SFTP.js');
|
||||
|
||||
const MAX_CHANNEL = 2 ** 32 - 1;
|
||||
|
||||
function onChannelOpenFailure(self, recipient, info, cb) {
|
||||
self._chanMgr.remove(recipient);
|
||||
if (typeof cb !== 'function')
|
||||
return;
|
||||
|
||||
let err;
|
||||
if (info instanceof Error) {
|
||||
err = info;
|
||||
} else if (typeof info === 'object' && info !== null) {
|
||||
err = new Error(`(SSH) Channel open failure: ${info.description}`);
|
||||
err.reason = info.reason;
|
||||
} else {
|
||||
err = new Error(
|
||||
'(SSH) Channel open failure: server closed channel unexpectedly'
|
||||
);
|
||||
err.reason = '';
|
||||
}
|
||||
|
||||
cb(err);
|
||||
}
|
||||
|
||||
function onCHANNEL_CLOSE(self, recipient, channel, err, dead) {
|
||||
if (typeof channel === 'function') {
|
||||
// We got CHANNEL_CLOSE instead of CHANNEL_OPEN_FAILURE when
|
||||
// requesting to open a channel
|
||||
onChannelOpenFailure(self, recipient, err, channel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof channel !== 'object' || channel === null)
|
||||
return;
|
||||
|
||||
if (channel.incoming && channel.incoming.state === 'closed')
|
||||
return;
|
||||
|
||||
self._chanMgr.remove(recipient);
|
||||
|
||||
if (channel.server && channel.constructor.name === 'Session')
|
||||
return;
|
||||
|
||||
channel.incoming.state = 'closed';
|
||||
|
||||
if (channel.readable)
|
||||
channel.push(null);
|
||||
if (channel.server) {
|
||||
if (channel.stderr.writable)
|
||||
channel.stderr.end();
|
||||
} else if (channel.stderr.readable) {
|
||||
channel.stderr.push(null);
|
||||
}
|
||||
|
||||
if (channel.constructor !== SFTP
|
||||
&& (channel.outgoing.state === 'open'
|
||||
|| channel.outgoing.state === 'eof')
|
||||
&& !dead) {
|
||||
channel.close();
|
||||
}
|
||||
if (channel.outgoing.state === 'closing')
|
||||
channel.outgoing.state = 'closed';
|
||||
|
||||
const readState = channel._readableState;
|
||||
const writeState = channel._writableState;
|
||||
if (writeState && !writeState.ending && !writeState.finished && !dead)
|
||||
channel.end();
|
||||
|
||||
// Take care of any outstanding channel requests
|
||||
const chanCallbacks = channel._callbacks;
|
||||
channel._callbacks = [];
|
||||
for (let i = 0; i < chanCallbacks.length; ++i)
|
||||
chanCallbacks[i](true);
|
||||
|
||||
if (channel.server) {
|
||||
if (!channel.readable
|
||||
|| channel.destroyed
|
||||
|| (readState && readState.endEmitted)) {
|
||||
channel.emit('close');
|
||||
} else {
|
||||
channel.once('end', () => channel.emit('close'));
|
||||
}
|
||||
} else {
|
||||
let doClose;
|
||||
switch (channel.type) {
|
||||
case 'direct-streamlocal@openssh.com':
|
||||
case 'direct-tcpip':
|
||||
doClose = () => channel.emit('close');
|
||||
break;
|
||||
default: {
|
||||
// Align more with node child processes, where the close event gets
|
||||
// the same arguments as the exit event
|
||||
const exit = channel._exit;
|
||||
doClose = () => {
|
||||
if (exit.code === null)
|
||||
channel.emit('close', exit.code, exit.signal, exit.dump, exit.desc);
|
||||
else
|
||||
channel.emit('close', exit.code);
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!channel.readable
|
||||
|| channel.destroyed
|
||||
|| (readState && readState.endEmitted)) {
|
||||
doClose();
|
||||
} else {
|
||||
channel.once('end', doClose);
|
||||
}
|
||||
|
||||
const errReadState = channel.stderr._readableState;
|
||||
if (!channel.stderr.readable
|
||||
|| channel.stderr.destroyed
|
||||
|| (errReadState && errReadState.endEmitted)) {
|
||||
channel.stderr.emit('close');
|
||||
} else {
|
||||
channel.stderr.once('end', () => channel.stderr.emit('close'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChannelManager {
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
this._channels = {};
|
||||
this._cur = -1;
|
||||
this._count = 0;
|
||||
}
|
||||
add(val) {
|
||||
// Attempt to reserve an id
|
||||
|
||||
let id;
|
||||
// Optimized paths
|
||||
if (this._cur < MAX_CHANNEL) {
|
||||
id = ++this._cur;
|
||||
} else if (this._count === 0) {
|
||||
// Revert and reset back to fast path once we no longer have any channels
|
||||
// open
|
||||
this._cur = 0;
|
||||
id = 0;
|
||||
} else {
|
||||
// Slower lookup path
|
||||
|
||||
// This path is triggered we have opened at least MAX_CHANNEL channels
|
||||
// while having at least one channel open at any given time, so we have
|
||||
// to search for a free id.
|
||||
const channels = this._channels;
|
||||
for (let i = 0; i < MAX_CHANNEL; ++i) {
|
||||
if (channels[i] === undefined) {
|
||||
id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (id === undefined)
|
||||
return -1;
|
||||
|
||||
this._channels[id] = (val || true);
|
||||
++this._count;
|
||||
|
||||
return id;
|
||||
}
|
||||
update(id, val) {
|
||||
if (typeof id !== 'number' || id < 0 || id >= MAX_CHANNEL || !isFinite(id))
|
||||
throw new Error(`Invalid channel id: ${id}`);
|
||||
|
||||
if (val && this._channels[id])
|
||||
this._channels[id] = val;
|
||||
}
|
||||
get(id) {
|
||||
if (typeof id !== 'number' || id < 0 || id >= MAX_CHANNEL || !isFinite(id))
|
||||
throw new Error(`Invalid channel id: ${id}`);
|
||||
|
||||
return this._channels[id];
|
||||
}
|
||||
remove(id) {
|
||||
if (typeof id !== 'number' || id < 0 || id >= MAX_CHANNEL || !isFinite(id))
|
||||
throw new Error(`Invalid channel id: ${id}`);
|
||||
|
||||
if (this._channels[id]) {
|
||||
delete this._channels[id];
|
||||
if (this._count)
|
||||
--this._count;
|
||||
}
|
||||
}
|
||||
cleanup(err) {
|
||||
const channels = this._channels;
|
||||
this._channels = {};
|
||||
this._cur = -1;
|
||||
this._count = 0;
|
||||
|
||||
const chanIDs = Object.keys(channels);
|
||||
const client = this._client;
|
||||
for (let i = 0; i < chanIDs.length; ++i) {
|
||||
const id = +chanIDs[i];
|
||||
const channel = channels[id];
|
||||
onCHANNEL_CLOSE(client, id, channel._channel || channel, err, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isRegExp = (() => {
|
||||
const toString = Object.prototype.toString;
|
||||
return (val) => toString.call(val) === '[object RegExp]';
|
||||
})();
|
||||
|
||||
function generateAlgorithmList(algoList, defaultList, supportedList) {
|
||||
if (Array.isArray(algoList) && algoList.length > 0) {
|
||||
// Exact list
|
||||
for (let i = 0; i < algoList.length; ++i) {
|
||||
if (supportedList.indexOf(algoList[i]) === -1)
|
||||
throw new Error(`Unsupported algorithm: ${algoList[i]}`);
|
||||
}
|
||||
return algoList;
|
||||
}
|
||||
|
||||
if (typeof algoList === 'object' && algoList !== null) {
|
||||
// Operations based on the default list
|
||||
const keys = Object.keys(algoList);
|
||||
let list = defaultList;
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
const key = keys[i];
|
||||
let val = algoList[key];
|
||||
switch (key) {
|
||||
case 'append':
|
||||
if (!Array.isArray(val))
|
||||
val = [val];
|
||||
if (Array.isArray(val)) {
|
||||
for (let j = 0; j < val.length; ++j) {
|
||||
const append = val[j];
|
||||
if (typeof append === 'string') {
|
||||
if (!append || list.indexOf(append) !== -1)
|
||||
continue;
|
||||
if (supportedList.indexOf(append) === -1)
|
||||
throw new Error(`Unsupported algorithm: ${append}`);
|
||||
if (list === defaultList)
|
||||
list = list.slice();
|
||||
list.push(append);
|
||||
} else if (isRegExp(append)) {
|
||||
for (let k = 0; k < supportedList.length; ++k) {
|
||||
const algo = supportedList[k];
|
||||
if (append.test(algo)) {
|
||||
if (list.indexOf(algo) !== -1)
|
||||
continue;
|
||||
if (list === defaultList)
|
||||
list = list.slice();
|
||||
list.push(algo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'prepend':
|
||||
if (!Array.isArray(val))
|
||||
val = [val];
|
||||
if (Array.isArray(val)) {
|
||||
for (let j = val.length; j >= 0; --j) {
|
||||
const prepend = val[j];
|
||||
if (typeof prepend === 'string') {
|
||||
if (!prepend || list.indexOf(prepend) !== -1)
|
||||
continue;
|
||||
if (supportedList.indexOf(prepend) === -1)
|
||||
throw new Error(`Unsupported algorithm: ${prepend}`);
|
||||
if (list === defaultList)
|
||||
list = list.slice();
|
||||
list.unshift(prepend);
|
||||
} else if (isRegExp(prepend)) {
|
||||
for (let k = supportedList.length; k >= 0; --k) {
|
||||
const algo = supportedList[k];
|
||||
if (prepend.test(algo)) {
|
||||
if (list.indexOf(algo) !== -1)
|
||||
continue;
|
||||
if (list === defaultList)
|
||||
list = list.slice();
|
||||
list.unshift(algo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'remove':
|
||||
if (!Array.isArray(val))
|
||||
val = [val];
|
||||
if (Array.isArray(val)) {
|
||||
for (let j = 0; j < val.length; ++j) {
|
||||
const search = val[j];
|
||||
if (typeof search === 'string') {
|
||||
if (!search)
|
||||
continue;
|
||||
const idx = list.indexOf(search);
|
||||
if (idx === -1)
|
||||
continue;
|
||||
if (list === defaultList)
|
||||
list = list.slice();
|
||||
list.splice(idx, 1);
|
||||
} else if (isRegExp(search)) {
|
||||
for (let k = 0; k < list.length; ++k) {
|
||||
if (search.test(list[k])) {
|
||||
if (list === defaultList)
|
||||
list = list.slice();
|
||||
list.splice(k, 1);
|
||||
--k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return defaultList;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ChannelManager,
|
||||
generateAlgorithmList,
|
||||
onChannelOpenFailure,
|
||||
onCHANNEL_CLOSE,
|
||||
isWritable: (stream) => {
|
||||
// XXX: hack to workaround regression in node
|
||||
// See: https://github.com/nodejs/node/issues/36029
|
||||
return (stream
|
||||
&& stream.writable
|
||||
&& stream._readableState
|
||||
&& stream._readableState.ended === false);
|
||||
},
|
||||
};
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "ssh2",
|
||||
"version": "1.17.0",
|
||||
"author": "Brian White <mscdex@mscdex.net>",
|
||||
"description": "SSH2 client and server modules written in pure JavaScript for node.js",
|
||||
"main": "./lib/index.js",
|
||||
"engines": {
|
||||
"node": ">=10.16.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"asn1": "^0.2.6",
|
||||
"bcrypt-pbkdf": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mscdex/eslint-config": "^1.1.0",
|
||||
"eslint": "^7.32.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"cpu-features": "~0.0.10",
|
||||
"nan": "^2.23.0"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "node install.js",
|
||||
"rebuild": "node install.js",
|
||||
"test": "node test/test.js",
|
||||
"lint": "eslint --cache --report-unused-disable-directives --ext=.js .eslintrc.js examples lib test",
|
||||
"lint:fix": "npm run lint -- --fix"
|
||||
},
|
||||
"keywords": [
|
||||
"ssh",
|
||||
"ssh2",
|
||||
"sftp",
|
||||
"secure",
|
||||
"shell",
|
||||
"exec",
|
||||
"remote",
|
||||
"client"
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/mscdex/ssh2/raw/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/mscdex/ssh2.git"
|
||||
}
|
||||
}
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { readFileSync } = require('fs');
|
||||
const { join } = require('path');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const Client = require('../lib/client.js');
|
||||
const Server = require('../lib/server.js');
|
||||
const { parseKey } = require('../lib/protocol/keyParser.js');
|
||||
|
||||
const mustCallChecks = [];
|
||||
|
||||
const DEFAULT_TEST_TIMEOUT = 30 * 1000;
|
||||
|
||||
function noop() {}
|
||||
|
||||
function runCallChecks(exitCode) {
|
||||
if (exitCode !== 0) return;
|
||||
|
||||
const failed = mustCallChecks.filter((context) => {
|
||||
if ('minimum' in context) {
|
||||
context.messageSegment = `at least ${context.minimum}`;
|
||||
return context.actual < context.minimum;
|
||||
}
|
||||
context.messageSegment = `exactly ${context.exact}`;
|
||||
return context.actual !== context.exact;
|
||||
});
|
||||
|
||||
failed.forEach((context) => {
|
||||
console.error('Mismatched %s function calls. Expected %s, actual %d.',
|
||||
context.name,
|
||||
context.messageSegment,
|
||||
context.actual);
|
||||
console.error(context.stack.split('\n').slice(2).join('\n'));
|
||||
});
|
||||
|
||||
if (failed.length)
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function mustCall(fn, exact) {
|
||||
return _mustCallInner(fn, exact, 'exact');
|
||||
}
|
||||
|
||||
function mustCallAtLeast(fn, minimum) {
|
||||
return _mustCallInner(fn, minimum, 'minimum');
|
||||
}
|
||||
|
||||
function _mustCallInner(fn, criteria = 1, field) {
|
||||
if (process._exiting)
|
||||
throw new Error('Cannot use common.mustCall*() in process exit handler');
|
||||
|
||||
if (typeof fn === 'number') {
|
||||
criteria = fn;
|
||||
fn = noop;
|
||||
} else if (fn === undefined) {
|
||||
fn = noop;
|
||||
}
|
||||
|
||||
if (typeof criteria !== 'number')
|
||||
throw new TypeError(`Invalid ${field} value: ${criteria}`);
|
||||
|
||||
const context = {
|
||||
[field]: criteria,
|
||||
actual: 0,
|
||||
stack: inspect(new Error()),
|
||||
name: fn.name || '<anonymous>'
|
||||
};
|
||||
|
||||
// Add the exit listener only once to avoid listener leak warnings
|
||||
if (mustCallChecks.length === 0)
|
||||
process.on('exit', runCallChecks);
|
||||
|
||||
mustCallChecks.push(context);
|
||||
|
||||
function wrapped(...args) {
|
||||
++context.actual;
|
||||
return fn.call(this, ...args);
|
||||
}
|
||||
// TODO: remove origFn?
|
||||
wrapped.origFn = fn;
|
||||
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
function getCallSite(top) {
|
||||
const originalStackFormatter = Error.prepareStackTrace;
|
||||
Error.prepareStackTrace = (err, stack) =>
|
||||
`${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
|
||||
const err = new Error();
|
||||
Error.captureStackTrace(err, top);
|
||||
// With the V8 Error API, the stack is not formatted until it is accessed
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
err.stack;
|
||||
Error.prepareStackTrace = originalStackFormatter;
|
||||
return err.stack;
|
||||
}
|
||||
|
||||
function mustNotCall(msg) {
|
||||
const callSite = getCallSite(mustNotCall);
|
||||
return function mustNotCall(...args) {
|
||||
args = args.map(inspect).join(', ');
|
||||
const argsInfo = (args.length > 0
|
||||
? `\ncalled with arguments: ${args}`
|
||||
: '');
|
||||
assert.fail(
|
||||
`${msg || 'function should not have been called'} at ${callSite}`
|
||||
+ argsInfo);
|
||||
};
|
||||
}
|
||||
|
||||
function setup(title, configs) {
|
||||
const {
|
||||
client: clientCfg_,
|
||||
server: serverCfg_,
|
||||
allReady: allReady_,
|
||||
timeout: timeout_,
|
||||
debug,
|
||||
noForceClientReady,
|
||||
noForceServerReady,
|
||||
noClientError,
|
||||
noServerError,
|
||||
} = configs;
|
||||
|
||||
// Make shallow copies of client/server configs to avoid mutating them when
|
||||
// multiple tests share the same config object reference
|
||||
let clientCfg;
|
||||
if (clientCfg_)
|
||||
clientCfg = { ...clientCfg_ };
|
||||
let serverCfg;
|
||||
if (serverCfg_)
|
||||
serverCfg = { ...serverCfg_ };
|
||||
|
||||
let clientClose = false;
|
||||
let clientReady = false;
|
||||
let serverClose = false;
|
||||
let serverReady = false;
|
||||
const msg = (text) => {
|
||||
return `${title}: ${text}`;
|
||||
};
|
||||
|
||||
const timeout = (typeof timeout_ === 'number'
|
||||
? timeout_
|
||||
: DEFAULT_TEST_TIMEOUT);
|
||||
|
||||
const allReady = (typeof allReady_ === 'function' ? allReady_ : undefined);
|
||||
|
||||
if (debug) {
|
||||
if (clientCfg) {
|
||||
clientCfg.debug = (...args) => {
|
||||
console.log(`[${title}][CLIENT]`, ...args);
|
||||
};
|
||||
}
|
||||
if (serverCfg) {
|
||||
serverCfg.debug = (...args) => {
|
||||
console.log(`[${title}][SERVER]`, ...args);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let timer;
|
||||
let client;
|
||||
let clientReadyFn;
|
||||
let server;
|
||||
let serverReadyFn;
|
||||
if (clientCfg) {
|
||||
client = new Client();
|
||||
if (!noClientError)
|
||||
client.on('error', onError);
|
||||
clientReadyFn = (noForceClientReady ? onReady : mustCall(onReady));
|
||||
client.on('ready', clientReadyFn)
|
||||
.on('close', mustCall(onClose));
|
||||
} else {
|
||||
clientReady = clientClose = true;
|
||||
}
|
||||
|
||||
if (serverCfg) {
|
||||
server = new Server(serverCfg);
|
||||
if (!noServerError)
|
||||
server.on('error', onError);
|
||||
serverReadyFn = (noForceServerReady ? onReady : mustCall(onReady));
|
||||
server.on('connection', mustCall((conn) => {
|
||||
if (!noServerError)
|
||||
conn.on('error', onError);
|
||||
conn.on('ready', serverReadyFn);
|
||||
server.close();
|
||||
})).on('close', mustCall(onClose));
|
||||
} else {
|
||||
serverReady = serverClose = true;
|
||||
}
|
||||
|
||||
function onError(err) {
|
||||
const which = (this === client ? 'client' : 'server');
|
||||
assert(false, msg(`Unexpected ${which} error: ${err.stack}\n`));
|
||||
}
|
||||
|
||||
function onReady() {
|
||||
if (this === client) {
|
||||
assert(!clientReady,
|
||||
msg('Received multiple ready events for client'));
|
||||
clientReady = true;
|
||||
} else {
|
||||
assert(!serverReady,
|
||||
msg('Received multiple ready events for server'));
|
||||
serverReady = true;
|
||||
}
|
||||
clientReady && serverReady && allReady && allReady();
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
if (this === client) {
|
||||
assert(!clientClose,
|
||||
msg('Received multiple close events for client'));
|
||||
clientClose = true;
|
||||
} else {
|
||||
assert(!serverClose,
|
||||
msg('Received multiple close events for server'));
|
||||
serverClose = true;
|
||||
}
|
||||
if (clientClose && serverClose)
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
process.nextTick(mustCall(() => {
|
||||
function connectClient() {
|
||||
if (clientCfg.sock) {
|
||||
clientCfg.sock.connect(server.address().port, 'localhost');
|
||||
} else {
|
||||
clientCfg.host = 'localhost';
|
||||
clientCfg.port = server.address().port;
|
||||
}
|
||||
try {
|
||||
client.connect(clientCfg);
|
||||
} catch (ex) {
|
||||
ex.message = msg(ex.message);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (server) {
|
||||
server.listen(0, 'localhost', mustCall(() => {
|
||||
if (timeout >= 0) {
|
||||
timer = setTimeout(() => {
|
||||
assert(false, msg('Test timed out'));
|
||||
}, timeout);
|
||||
}
|
||||
if (client)
|
||||
connectClient();
|
||||
}));
|
||||
}
|
||||
}));
|
||||
|
||||
return { client, server };
|
||||
}
|
||||
|
||||
const FIXTURES_DIR = join(__dirname, 'fixtures');
|
||||
const fixture = (() => {
|
||||
const cache = new Map();
|
||||
return (file) => {
|
||||
const existing = cache.get(file);
|
||||
if (existing !== undefined)
|
||||
return existing;
|
||||
|
||||
const result = readFileSync(join(FIXTURES_DIR, file));
|
||||
cache.set(file, result);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
const fixtureKey = (() => {
|
||||
const cache = new Map();
|
||||
return (file, passphrase, bypass) => {
|
||||
if (typeof passphrase === 'boolean') {
|
||||
bypass = passphrase;
|
||||
passphrase = undefined;
|
||||
}
|
||||
if (typeof bypass !== 'boolean' || !bypass) {
|
||||
const existing = cache.get(file);
|
||||
if (existing !== undefined)
|
||||
return existing;
|
||||
}
|
||||
const fullPath = join(FIXTURES_DIR, file);
|
||||
const raw = fixture(file);
|
||||
let key = parseKey(raw, passphrase);
|
||||
if (Array.isArray(key))
|
||||
key = key[0];
|
||||
const result = { key, raw, fullPath };
|
||||
cache.set(file, result);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
|
||||
function setupSimple(debug, title) {
|
||||
const { client, server } = setup(title, {
|
||||
client: { username: 'Password User', password: '12345' },
|
||||
server: { hostKeys: [ fixtureKey('ssh_host_rsa_key').raw ] },
|
||||
debug,
|
||||
});
|
||||
server.on('connection', mustCall((conn) => {
|
||||
conn.on('authentication', mustCall((ctx) => {
|
||||
ctx.accept();
|
||||
}));
|
||||
}));
|
||||
return { client, server };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fixture,
|
||||
fixtureKey,
|
||||
FIXTURES_DIR,
|
||||
mustCall,
|
||||
mustCallAtLeast,
|
||||
mustNotCall,
|
||||
setup,
|
||||
setupSimple,
|
||||
};
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAz7MF4vhgw6HxNf3KtVf3VULTYgrRSlv+cCZdB1xxI1p/nGyu
|
||||
/eekUn5C+mGeDS488DX5ulzicxVpL7pamc/tFNcp91MrR7PiIMK2l+bwbZJubbLj
|
||||
DHhNcBklnFOSKxtmQRfuorGakpy/kXmIxF5of0xXGns6DlHRq9dGCJIXvrkqhcEb
|
||||
k4n2y4aV4VOiMHdo6FrFQVPzA8DlbJP2SjIFZ/0VdK7O7eiyiqV1p1xlbTQQ5rAX
|
||||
LdsshBn/GvoBOTCVupMXurn2582vgGh26Mmovj2QGzScMGUVttkMlnxUmKT/aQka
|
||||
mC0vR54QOW7lyWPjAitOV0qgmtGm3/cl7W7NjwIDAQABAoIBAFxH0C+951BEXWV9
|
||||
s1jLEqshG8YNxFtjcDLn+KFSoznv9Y7MgxtwlgPI8X1Jbe2xQ4X+lUwGBN7Y/nkk
|
||||
NSjtxwphZtXqb+pVs/yWRoZLJzunucSnnFVoBg/uPFWuk9zvOYlmVrKWcnT9i+fY
|
||||
tbl5sLgOdQzg/zRpidztssIQFti3o2jnpyrEGcepPWLkfCgqPfGmNv78BAIt/6iT
|
||||
zYDB4GMSq/LnPTIOFsIOvlkZg3RCcLWeAPRC+lvFQVY+M/uJL5WIbA5il1IMMKH7
|
||||
MULWpRO3lnb1JVrkZlBldK5uew6AN3tHDQOmg+C2JuIbOZ35J9dcnwsE+IptWWBj
|
||||
XiFRJCECgYEA8BeuufkslureqOycaPLMkqchMTue1OxbLJFvPN+dh/cW6Lng3b8+
|
||||
xAyzZrc0vccH/jl9WVHhIZ7TcKXDzSmmrtnZ/3m1c4gANGqIPwO+emL1ZzzkIKGd
|
||||
FrLeBZKP4TWry9kjg4cG1SKGpcB5ngJMPXUxMZNe74tC4Hk820PkFjcCgYEA3XXn
|
||||
ngRCgH9N1eKSD2daxxlBhTTSnTgjU+dDaDFQzPIhJCcS8HwyQBQmNTOSXXK9sShC
|
||||
fdXAsmiBby5WEBq/K5+cXeDG2ZlFLyPovEgTUrLgraw42PYs0+A8Ls7dFk7PuMez
|
||||
3G2gUPkY039JiyXKfcog9/dIRfbWCwzQ6s7TV2kCgYEArsme81cahhgg1zvCNokk
|
||||
M1Omz2/HFt2nFpAeOmPVDGnu7Kh9sxGKgTF53bpclBh0kjiKL99zFYXKCoUzQYYk
|
||||
CcEhemLBnYUSGRbBb5arMfAfFfR3Y+YkNaUsC0SCqILpOfMvbo57g+ipu7ufDlA/
|
||||
7rIFiUDvaVap7j909W+8egsCgYEAsuc/0DBixMmSyHl7QwRcmkC15HVSu32RVIOb
|
||||
ub01KAtmaH1EWJAMTCW64/mggOtjgI0kgeE/BSFVhsqo7eOdkhEj0db27OxbroRU
|
||||
zF1xdrpYtRRO7D6a4iLgm3OzuQS72+tASo8pFqDUxG6sq8NAvLOgRJE4ioSoT07w
|
||||
KvAgXRkCgYEAmWgcsX/BdNcKOteSDtPkys5NRtWCBz7Coxb+xXXoXz1FVegBolpY
|
||||
wXVePvXTIbU8VJOLunMyH5wpmMUiJbTX9v2o/yfpsH0ci4GaAeVtqpA=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFuzCCA6OgAwIBAgIUPtNIRfp8v8RsObCr+9LVosWVD/QwDQYJKoZIhvcNAQEL
|
||||
BQAwbTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcM
|
||||
CVNvbWUtQ2l0eTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIw
|
||||
EAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAxMjIwMDQwNTM1WhcNMzAxMjE4MDQwNTM1
|
||||
WjBtMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJ
|
||||
U29tZS1DaXR5MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQ
|
||||
BgNVBAMMCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
|
||||
AJ/m96/mBMFoUWUOFSvvmJjHj/XxnO89ClCcCIFA6bJNCJMFZV3m853HAhP9g3kF
|
||||
M3hL0c96GKS5IsRJiNUMrIUYrWCPh1yUJCNfczyGbBJNcEoRhfqCuuzjA5U7jAil
|
||||
jqLWBP+ZI0tKRuQXX4bDHp51qDESscxNHZQp0+Lho86y4XjZPnT1OYd5rl3D6D82
|
||||
AElOrGOtsj7KmHl3eYhQoKNDlCGa5ZK+L05rsClU5m/LXyGmf5QtOIF00JqJ7KS4
|
||||
mX3ZF+XE/+3gkXLJyOCOYFDLjGY7WjsJXz3Wm6pktW8NGqhMaaRfIINqtCQkDgMk
|
||||
gTjF3TtEA/M2DsGU2edL3qm/ibQ4z88dMVkLGZ6DWZg5oGwZR0W8jRAauhWO01Qq
|
||||
JSLF3Rhvj4VasF4Hj6sI2HQcgGlDFqPNs/ErTA91mN/+yzXzCYIGBUeF5cSbIsLL
|
||||
TNo6fCHKRIYqpHYCQjwBYQh/2R4/o/BHHkePVWDN0dg2VAyrp/YhV3YTfs3M4ond
|
||||
yx2CoW1FJHPlhsmGH3A6PlWe2dRgu9f0ZejOX+eefqkkJtrVbmxfVCB9KET7TrV1
|
||||
lBX/V6bnFwmT0fygeBHd0aR+h8dvIs3E/wovLp4MZjtT97p+IMcGUcH9AmbFlXgi
|
||||
VOnYx4/3WLuqGpyurDaCWwJDmtdCDoclZeZ3ef+IEi3/AgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBTQsY4pBOEhu4+hJb5KqaxKNBMPLTAfBgNVHSMEGDAWgBTQsY4pBOEhu4+h
|
||||
Jb5KqaxKNBMPLTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBf
|
||||
+YfOSlOw79aCdtU40OH51QFJxuK54ryxpzRcpBeDE57HfnuNHAM+z+5xVu8+qaRn
|
||||
jo27ylmLLmzlWV946Yb+fyxIZb37KNXiIYehPTYyiG9MYmE3kEH/kLEvU8SQ6zO5
|
||||
6CVP3RN+HP1ZdgHi4Zq6DLsngr/ma8nAXuRUgsvLogB2yrtTJTlMB5631ahdD3U8
|
||||
kInPa1FlWYjq0QvllzMJ2q/uUG8kMLZRArqKMxb6j5hqHZuA2PAhb1h2K54doOWt
|
||||
26HdGPVBxZcnE7HUUqKMAxAf++vmYicDTSv6rsEONxmG9cn0SQWzUnr3G6zZ4uxF
|
||||
9wlvl5/VN6jT9XtS9rpZfwOVLigmuhMFkUCxTTN0eHOh0u76QSk2nphxumIj1vc+
|
||||
I9G/KNk0R3G+7AyjDK2WIxaqUTChpBfytQoiiQCOYEL+KlJboWhYL7mfeBT2flzH
|
||||
H3/LfF61Y8V2H5pjX1x+e/FghA5OFiHsrgoJVegVYu6v0JyCzNwGaSvnpu8QZcOZ
|
||||
lT6d4UKS8JmIuq2w7iru6cURBRzMfBZ4qaX3Gm/NSDfi6q/8aL/mogzQHg91lrFz
|
||||
AXZUkb+WGikJ6TEgL9M4qBHwgssk7ayEejBhIuLxQD654Py8P8diEt/77iY0qsS9
|
||||
EEw/onPXr9nLLeIcigQEa2+14msAb2I7a2/RhlUW+Q==
|
||||
-----END CERTIFICATE-----
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQCf5vev5gTBaFFl
|
||||
DhUr75iYx4/18ZzvPQpQnAiBQOmyTQiTBWVd5vOdxwIT/YN5BTN4S9HPehikuSLE
|
||||
SYjVDKyFGK1gj4dclCQjX3M8hmwSTXBKEYX6grrs4wOVO4wIpY6i1gT/mSNLSkbk
|
||||
F1+Gwx6edagxErHMTR2UKdPi4aPOsuF42T509TmHea5dw+g/NgBJTqxjrbI+yph5
|
||||
d3mIUKCjQ5QhmuWSvi9Oa7ApVOZvy18hpn+ULTiBdNCaieykuJl92RflxP/t4JFy
|
||||
ycjgjmBQy4xmO1o7CV891puqZLVvDRqoTGmkXyCDarQkJA4DJIE4xd07RAPzNg7B
|
||||
lNnnS96pv4m0OM/PHTFZCxmeg1mYOaBsGUdFvI0QGroVjtNUKiUixd0Yb4+FWrBe
|
||||
B4+rCNh0HIBpQxajzbPxK0wPdZjf/ss18wmCBgVHheXEmyLCy0zaOnwhykSGKqR2
|
||||
AkI8AWEIf9keP6PwRx5Hj1VgzdHYNlQMq6f2IVd2E37NzOKJ3csdgqFtRSRz5YbJ
|
||||
hh9wOj5VntnUYLvX9GXozl/nnn6pJCba1W5sX1QgfShE+061dZQV/1em5xcJk9H8
|
||||
oHgR3dGkfofHbyLNxP8KLy6eDGY7U/e6fiDHBlHB/QJmxZV4IlTp2MeP91i7qhqc
|
||||
rqw2glsCQ5rXQg6HJWXmd3n/iBIt/wIDAQABAoICAQCb0z8o4WVc/UXkzvZ+3Hy+
|
||||
1itKp+whkECPEZ+QJiwXn85tR+LiwYBDD37M8E7BDvp7jpemMvv0+p4Q3wBDbphp
|
||||
FAVRhk2JQKx+9DOelfiXVXPKGo2P9Poog4ooUeFDQ+NeeGZil1+3rWisOsLS1y7t
|
||||
iQcg23D9AWGD08cy4GT7t4LWfA7Ld3ZauY/cvF+FyiA5UDva35hGbLRuGqoK11fU
|
||||
ArVGkmaKvF/pcjQ38w6lf3DzoAfP5MmeDrKDB0nftC2QYJFTTsmBjUjwrgfeHaFq
|
||||
2xG1Rr3FrnpsDsmgIYhV8lU6EU0Z68IJj2CBn8kv8tEi/F99s+iNiO6UY3R+XIdd
|
||||
Jng5zPxHwprzKjvdfl6e4KhwkV8YJbPW0SFDj6Y0Ie0CdSysdJ8BhT7dk7LvJH1Q
|
||||
DhQSAFftSna4MW5fzAogyQVL+KF3JnQ9BvFZX1swlIqBDHc6DeM+sFg0U++7qFyl
|
||||
nZellskBgfLXlGCjgGEC/W5pUOaZzBk1BGa8x8Zm3vA//uaoOw/BKizfa+p0VqoU
|
||||
bC4E8HEK+Rqj9oB07wVliqU9mCqrc5offhjeft9YbUAqx6GPG+1kPiKW1F4++iT2
|
||||
Yils/euv+gtK9d9JbMUCCH6mp1wIy40a14XisA8/O8NONjF63VTZX3try7rjOKxd
|
||||
D0W68FGzACIkRkmTTc2NsQKCAQEAzKq7Lk/6cf2bzSQc0oH0XWxuA497czTQYj7l
|
||||
k4UkGcUeEu9qOp3qU66KjmqLXLJnF233tQ2ArpiwX7tHNmhXZmIufNxa0Gue2VGx
|
||||
eyRO/aTCnD1FsSayX1KcaLrwvg5gvwOPQLNCacMc47RCyI6/05irXfNtRlqKKm+R
|
||||
ZgnhHxcwMzX5lLX9Rr54AWp0yuLEK+i0lcKsNnypAMl/C9GTqk3dEpao0y6SGHiW
|
||||
Ih8Q2Cy4LbRD48PWuf9rBvb3iZyiLe0xemD8wuNN0j7/Xt9tcL4OuzkmkzWCyslM
|
||||
Qi3yNw6eRziFhzdpDdHpJjFjEnGI94jgt1AYJtesFvSf8Tz7jQKCAQEAyAH7JQKx
|
||||
mYvaRioAaUKQHiLImPxypt5cEGiyrPdiBBrU+3fBTC/EZJn/VK7ApM+7YRqvO/vz
|
||||
d9orkvsWfzxpQM1xhBZ3bwTWXXWRz7g5vzKwJk4pZkXaUk+QAUwp79OrZFTcQokJ
|
||||
d/l1wj5sUQCrs0l5gD5M3O6ZXPWLoSv1gBI7ktBxXY3VBrQ0uAwE9mQHjyrO+Utc
|
||||
fcdFEtOqwOxyQQmcsj0vjGm385FmtuIG/pSzhvPXGyo3VYrQjTXT7pYnghu3LBgg
|
||||
JJuE8kOAlSVTL0ccSO9GLqvj2bTyLlrFcKPBReXHNLwl5kij2w7WBTPGQn61u+ye
|
||||
+bmSunIkjE2muwKCAQEAr/k4OcjAgJRbCpY7RfBAyLb7HIqYzWSiq2aDBEUc1h97
|
||||
DTLXNpEislLHhU4sh0ZJh4agzgZPF0/njlg7EZfDVh+i8u6QEtYF3br1C/kbBdFN
|
||||
FwND0d6AzZ79JrtdVTyNiI8p86pttvvw8gPCzCiY3PlOltg/o5cjZvtIm+BwtMe+
|
||||
RLnq3ydfHx2TlzwOMYeqvko2QvIAGlUzBp85YlMPUQXjyCDMBc/sA6hjBfGKDSTe
|
||||
M0XkfYicLo5jWrir+6E2fKCNwzhy+6pu9g/+iHc45RA1IFsyRK5kx7EupVRWB2rF
|
||||
Ql1hyfIlnKFYguNB2NDPwG3rMRJnwbX8nDw27TfO3QKCAQEAlHAb82DnbFzGF3LO
|
||||
sVBMY4FPPXOGp9+5lhgOG57SKNe9IBDF7gQ5jqxYOoIjyW2+1JeYXD1meZn64u/k
|
||||
x3OPbh/LUsvVwhhl/CDoobBJc2RsJVG3GgdXu+T+rGfZa/u9ZQ4yFlNcKqWCxzHK
|
||||
8+c6hypNuWcDZqjSO5KlGW3lmzJs8k4vBM7hvkL6KWoKOM8OaSvNRmmu8E53LjzX
|
||||
qq0RMsGugP42DtDbTDKqd6qSpFi6ULsh9zBCtwL6OwMrEhRwp/hn3prdKC4f4ilF
|
||||
Aewcq6bsEBk9DiBWT1oir1KA3FM8euLJEJNe0WUx7r85Cc1eJDWkLR+08QPQKP3T
|
||||
sCllRwKCAQBQgSFFI65dlLJf/iJrZPuP3sCzZNABe4y7lxZK2Gij4FXzf2KA1SAl
|
||||
dyxuUU+Hv98l52pJIWmoNYWKEXOorsu+TuadgiK11DSx/ajQ9y8OEbscOVTJwrv3
|
||||
aVbaz4f0z2AKRLrBLsln2aVLQVPF5dsPNmsYIUWOrvBJ+DFFeXQG+QWimS2VbS+P
|
||||
wrDdpVej8sEaUVfCqvCAx8gWtrFtE401BmfNla1xFGHiHhcLrsqKj3uxIojQ0Met
|
||||
fFCrKqxES0OQ6pY/9VlrBmfihw/Bt1LWMPUo90atFArbwGaUxXLwi4FwRafkW5Di
|
||||
k77w3OGObcFv4zxCOoFxcXXc3MCyw3r8
|
||||
-----END PRIVATE KEY-----
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
MIIBuwIBAAKBgQC3/2VIGHgqHuxvhPa6rryqqLy6sQmjeSIwyrIW5F/o8W4sz/mE
|
||||
0noDSW4PaoXjgPQv5egj1EByws6dMOUqLaZHNWNn+Lh/jkKlwKyhbSCAjqoWH3v3
|
||||
uI1j58GO/eZ2+REijfyA0XJxdm7kqEexxbg0UpFr1F/eLBUxpLIbhhS1cwIVAKcB
|
||||
B9DnAObuPJGTwYTCaIIBQDy9AoGAJicW0pIFwgoTYsIeywmUQopJ3FQ4M3eDwQ0U
|
||||
T33pzWvBZFN2OsUDTFg64PNm9ow09wk042qMg168eKCUTp2iR/Y9R4xTj8dls8iv
|
||||
aMGMZ/B32eURIjUREGiXYTyG1pfuB2znSvr/5pavhuz5yG9M0AJCiYiexdaQKO3N
|
||||
oJp6T3ACgYEAsep79p4WljnawrJc928zGq6dLYjs+5apYhqx4vf2l3Z2u26VqVNG
|
||||
i5zZkUzhWQYV3/qtEOpO43dyZTHW+d9L8ni6HbXFWRVx60WE+5WKkzkimHJ6gox2
|
||||
kDvOqPudiS34KJOCEYYLEnJmK8aUZBZzWFORXkN8QgA/h9ts8AU785UCFAVXZMWq
|
||||
CteWCH2HzcY2x/65dMwL
|
||||
-----END DSA PRIVATE KEY-----
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPMZuWP7fMsZeyC1XXVUALVebJOX7PTwmsPql9qG25SeoAoGCCqGSM49
|
||||
AwEHoUQDQgAEB/B6mC5lrekKPWfGEkKpnCk08+dRnzFUg2jUHpaIrOTt4jGdvq6T
|
||||
yAN57asB+PYmFyVIpi35NcmicF18qX3ayg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDL0yFO4W4xbdrJk/i+CW3itPATvhRkS+x+gKmkdH739AqWYP6r
|
||||
kTFAmFTw9gLJ/c2tN7ow0T0QUR9iUsv/3QzTuwsjBu0feo3CVxwMkaJTo5ks9XBo
|
||||
OW0R3tyCcOLlAcQ1WjC7cv5Ifn4gXLLM+k8/y/m3u8ERtidNxbRqpQ/gPQIDAQAB
|
||||
AoGABirSRC/ABNDdIOJQUXe5knWFGiPTPCGr+zvrZiV8PgZtV5WBvzE6e0jgsRXQ
|
||||
icobMhWQla+PGHJL786vi4NlwuhwKcF7Pd908ofej1eeBOd1u/HQ/qsfxPdxI0zF
|
||||
dcWPYgAOo9ydOMGcSx4v1zDIgFInELJzKbv64LJQD0/xhoUCQQD7KhJ7M8Nkwsr2
|
||||
iKCyWTFM2M8/VKltgaiSmsNKZETashk5tKOrM3EWX4RcB/DnvHe8VNyYpC6Sd1uQ
|
||||
AHwPDfxDAkEAz7+7hDybH6Cfvmr8kUOlDXiJJWXp5lP37FLzMDU6a9wTKZFnh57F
|
||||
e91zRmKlQTegFet93MXaFYljRkI+4lMpfwJBAPPLbNEF973Qjq4rBMDZbs9HDDRO
|
||||
+35+AqD7dGC7X1Jg2bd3rf66GiU7ZgDm/GIUQK0gOlg31bT6AniO39zFGH0CQFBh
|
||||
Yd9HR8nT7xrQ8EoQPzNYGNBUf0xz3rAcZCWZ4rHK48sojEMoBkbnputrzX7PU+xH
|
||||
QlqCXuAIWVXc2dHd1WcCQQDIUJHPOsgeAfTLoRRRURp/m8zZ9IpbaPTyDstPVNYe
|
||||
zARW3Oa/tzPqdO6NWaetCp17u7Kb6X9np7Vz17i/4KED
|
||||
-----END RSA PRIVATE KEY-----
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
PuTTY-User-Key-File-2: ssh-rsa
|
||||
Encryption: none
|
||||
Comment: rsa-key-20150522
|
||||
Public-Lines: 6
|
||||
AAAAB3NzaC1yc2EAAAABJQAAAQB1quqP0rhl78NOLD4lj+1x5FGAqZ3aqo6GiEPz
|
||||
KOaQmy86FuJMK0nHj3gUKTa/Kvaa+8PZyeu+uVseHg47YrynCOcJEEnpqvbArc8M
|
||||
xMWuUnTUMrjvokGDOBBiQu4UAE4bybpgXkNHJfbrcDVgivmv3Ikn8PVIZ1rLBMLZ
|
||||
6Lzn0rjPjFD0X4WqsAJW2SFiZnsjMZtVL2TWadNTyyfjjm2NCRBvd32VLohkSe9Q
|
||||
BZBD6MW8YQyBKUnEF/7WNY0eehDVrfx1YqPOV1bDwFUhRaAYpLDLDR0KCAPvx7qb
|
||||
8G5Cq0TIBsEr3H8ztNRcOTQoaKgn0T18M7cyS4ykoNLYW4Zx
|
||||
Private-Lines: 14
|
||||
AAABACyF3DZraF3sBLXLjSL4MFSblHXfUHxAiPSiQzlpa/9dUCPRTrUJddzOgHZU
|
||||
yJtcXU9mLm4VDRe7wZyxbSs6Hd5WZUGzIuLLEUH8k4hKdE/MLDSdkhV7qhX5iaij
|
||||
tAeRaammRoVUGXTd7rnzGx2cXnnkvkZ22VmqkQ6MLg1DTmWNfOO9cdwFGdQawf/n
|
||||
yUV0nTkWsHXy5Qrozq9wRFk8eyw+pFllxqavsNftZX8VDiQt27JLZPTU4LGkH660
|
||||
3gq1KhNS/l05TlXnMZGjlcPN8UEaBzmCWRezhJSttjs5Kgp1K3yDf4ozMR/HWOCj
|
||||
Jq8fd3VIgli6ML8yjr/c0A0T9MUAAACBAL1/byxHiCvY/2C+/L5T+ZZq13jdZuYK
|
||||
MmOFaNITgEdNGWSIFYRzhLKGXj7awQWOIW6chj470GNOfQjFL1TvXhbwfqW6esDa
|
||||
kETOYQPYQHZijABcn7uurMUm/bu5x/z9gYkAfniOCI5vmvMvJ09JcZ0iUmFWDZZY
|
||||
fAutBvrt+n/vAAAAgQCe9jrA51wn1/wzKmWF+2+OWFUG9usheIcEbHB8mxLguLfU
|
||||
+x4i+2vLo0FtXEPAw+Bt7Tge4t0m6USiVZXtW/QKsh0kMj4mNVHFz+XXw4l1QOYv
|
||||
n5TjnLepiP7majXv4GHI2eOcHkyly4sIkj4jNLYqvT86hMxW4IC+jtJEWhn/nwAA
|
||||
AIEAlJ8cExu2WrWukTDJQHrVegtvdJUhNjol2wLucPuWwSxKuB8FHYwaPRYRkf3d
|
||||
DkZ53hhjJZ0BVkAaQ28uqM09xKD+q1H4/r0nnbtlV4uHLl3cCD5mGrH8I/iDPJX4
|
||||
fFIqCa0+n1D6RzvDqs1QIu+PGSp0K6vHOOS5fP0ZpuT025E=
|
||||
Private-MAC: 4ca26008c85b901f4d2766b0924c25e527678d7e
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,CCE70744FB28F2EFB1D74377281A780C
|
||||
|
||||
1WiGnqpSGXFIg+WYr7T2XN72C1YrNQ1jmRISb32TB/Rh2Zo47fjyQnv9impz8b6m
|
||||
91R/qF7uCLI0fswvT5oqwn1L0vUAA0YtW/E2IQJEx5GPiaexoDJYYfu2yy036Kca
|
||||
e9VtCajgrV+kycg1CknCxQKMcKXNq8Czvq66PM4Bzknek5hhdmxHxOl0QAE+8EXt
|
||||
pnasOGz3szTUKkD6givwWgvDXY3BnVG46fXff99Xqgb6fx5IDbAkVKaxWIN/c81E
|
||||
b0rcfyoLb7yjPgNYn9vUI6Z+24NMYUYARzb3dG5geaeX0BYb/VlCtJUsP0Rp2P2P
|
||||
jl+cdvBKaeOvA9gPo/jAtSOFexQRs7AzKzoOLYU1fokd8HhqxOKAljn9ujmEqif7
|
||||
qcimk2s7ff6tSSlxtRzDP+Uq9d1u5tyaONRV2lwj+GdP1gRoOmdZL5chdvoAi0I8
|
||||
5eMf58hEuN2d4h4FryO6z7K+XQ9oo6/N/xHU0U/t2Pco9oY2L6oWMDxKwbfPhaD5
|
||||
CcoEElsK4XFArYDielEq9Y1sXaEuwR5I0ksDDsANp74r9Bhcqz60gJa6hVz0ouEU
|
||||
QA67wV9+TRmulKRxwANvqxQwqPuxqcTPeJjXSUN/ZCaDwYmI+d1poxMx2fQzT82M
|
||||
onlgOWq+3HbCotyoeFpCameymwDQzmrYdMBr7oWLgnOrxmJ89zDc6+jkHFgQJvnU
|
||||
atyeVDqe866ZvvIGWS+r/EsDjV3cTW/cJvdsC+5BpnoXoVF4LqxE3LFbEbQBvqio
|
||||
4enCZpspQSMOJra37vSofbD+DyI5Wd+y8SBmfDLjyDFhT0spW9aN99uFqSc3UElA
|
||||
SAmnFmpYBFEQrRGpvpu5sC0c/YjZeRXr0/F1xPpIT1SWzpRsbcsWRBDzWjLOKWQx
|
||||
8ytwc2QS7eKedfqkPWpYKW0Qtps+XgnGWA6PBX42IYhLsKANRfhFXQv5LPqLNNOn
|
||||
3EsG9pd+0dBpfxFQfyyAKAUuvpJNgJ6kNx8VSj8Ppj8lyUdGa9YucgB02m7gHC9U
|
||||
A4YyJsIcjo6IcrjM+ez1govRRS0nE8AUb8ups9tn8mdBwqcPCrgcJhV7JkOYNJYh
|
||||
NAh0vgmneOq8LSVs2SRaL3uuLNbjh1LR9iViwbIY8kMQXkiXa2/V+PFwt5oqeX5f
|
||||
2x3yzCeGBiQW10InyBBnKutbPD85R4YJhQ55bOMDSFfGGqwOU1QURiO1NUzf9n/2
|
||||
+E8VE7J/IQoO0TrJpC+EV0ROKME9W6+AvEFdmdIigbq3bkdEgSixyLnrhV8V8T4N
|
||||
nbKlLoqfXt8DmT+h8XPzgsu0Fq/PNi6xBaiUsaN9tK6OP2ZVjr9ihbeLTI0rcKDr
|
||||
XX2cWPvTcboRLt+S4wmqchMf7Kxa2PfX5Tf+KCcdZNQO4YqS23wQZgk61kuOQCsS
|
||||
uOop+ICI7yWZkjqCOzGOeHLl/7FyFeprsFDIwD1g20y9bzibbJlbQPhwXSalqDQT
|
||||
MWLH3rdFuvgLH7ujtjxSakES+VzkOhbnmb/Wypbl1D7P7GT2seau16EEGQDhDzcJ
|
||||
Q4d/BjR2WqqxmC79MOAvUWAu6fZQjPD30/gYPGpMaEuiLrDlzDqvf+oi4A9+EtRL
|
||||
-----END RSA PRIVATE KEY-----
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABsgAAAAdzc2gtZH
|
||||
NzAAAAgQDg+DsMAituSW/NJpWVy2w7xN6Uu/IfCqpy38CFBW+mBnOX7OzPulI+1uZxXRLy
|
||||
UKiQDAegXCqSHMCo5ACZhw2BRwq74J4VA5fOFGdwcacTQo1zKDF64wvyVSgQE/E2PSFLKu
|
||||
NHHtRFnjvq6WrgTQsL9aif2FBWS5q0MGahzXhNkQAAABUAn1ASRSRcIVsWqrrZubFQq4pU
|
||||
OlMAAACBALcKIRLTtYG5+N/vzEULdsXSGToDRth6X5Yjb7c0UotAmy9VGrnmN5IO+//1em
|
||||
2USHeSoO+5shRq92zdggdQwNaXXzU301huIETztfRwGHOfUGZbzJmIqdzLhdziFhneAzaN
|
||||
zVeUFyIqvWL1Q89WgC2Uh3DY/lK/gIhRK7WD0cDAAAAAgC882WUEEig48DVyjbNi1xf8rG
|
||||
svyypMHSs2rj6pja2Upfm+C5AKKU387x8Vj/Kz291ROIl7h/AhmKOlwdxwPZOG5ffDygaW
|
||||
Tlo4/JagwP9HmTsK1Tyd1chuyMk9cNLdgWFsCGGHY2RcEwccq9panvvtKp57HqDaT1W7AS
|
||||
g2spT9AAAB8G4oDW5uKA1uAAAAB3NzaC1kc3MAAACBAOD4OwwCK25Jb80mlZXLbDvE3pS7
|
||||
8h8KqnLfwIUFb6YGc5fs7M+6Uj7W5nFdEvJQqJAMB6BcKpIcwKjkAJmHDYFHCrvgnhUDl8
|
||||
4UZ3BxpxNCjXMoMXrjC/JVKBAT8TY9IUsq40ce1EWeO+rpauBNCwv1qJ/YUFZLmrQwZqHN
|
||||
eE2RAAAAFQCfUBJFJFwhWxaqutm5sVCrilQ6UwAAAIEAtwohEtO1gbn43+/MRQt2xdIZOg
|
||||
NG2HpfliNvtzRSi0CbL1UaueY3kg77//V6bZRId5Kg77myFGr3bN2CB1DA1pdfNTfTWG4g
|
||||
RPO19HAYc59QZlvMmYip3MuF3OIWGd4DNo3NV5QXIiq9YvVDz1aALZSHcNj+Ur+AiFErtY
|
||||
PRwMAAAACALzzZZQQSKDjwNXKNs2LXF/ysay/LKkwdKzauPqmNrZSl+b4LkAopTfzvHxWP
|
||||
8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PKBpZOWjj8lqDA/0eZOwrVPJ3VyG7IyT1w0t2BYW
|
||||
wIYYdjZFwTBxyr2lqe++0qnnseoNpPVbsBKDaylP0AAAAVAIoWASGAfFqckLwvtPRNCzow
|
||||
TTl1AAAAEm5ldyBvcGVuc3NoIGZvcm1hdAECAwQFBgc=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ssh-dss AAAAB3NzaC1kc3MAAACBAOD4OwwCK25Jb80mlZXLbDvE3pS78h8KqnLfwIUFb6YGc5fs7M+6Uj7W5nFdEvJQqJAMB6BcKpIcwKjkAJmHDYFHCrvgnhUDl84UZ3BxpxNCjXMoMXrjC/JVKBAT8TY9IUsq40ce1EWeO+rpauBNCwv1qJ/YUFZLmrQwZqHNeE2RAAAAFQCfUBJFJFwhWxaqutm5sVCrilQ6UwAAAIEAtwohEtO1gbn43+/MRQt2xdIZOgNG2HpfliNvtzRSi0CbL1UaueY3kg77//V6bZRId5Kg77myFGr3bN2CB1DA1pdfNTfTWG4gRPO19HAYc59QZlvMmYip3MuF3OIWGd4DNo3NV5QXIiq9YvVDz1aALZSHcNj+Ur+AiFErtYPRwMAAAACALzzZZQQSKDjwNXKNs2LXF/ysay/LKkwdKzauPqmNrZSl+b4LkAopTfzvHxWP8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PKBpZOWjj8lqDA/0eZOwrVPJ3VyG7IyT1w0t2BYWwIYYdjZFwTBxyr2lqe++0qnnseoNpPVbsBKDaylP0= new openssh format
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-dss",
|
||||
"comment": "new openssh format",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOD4OwwCK25Jb80mlZXLbDvE3pS78h8K\nqnLfwIUFb6YGc5fs7M+6Uj7W5nFdEvJQqJAMB6BcKpIcwKjkAJmHDYFHCrvgnhUD\nl84UZ3BxpxNCjXMoMXrjC/JVKBAT8TY9IUsq40ce1EWeO+rpauBNCwv1qJ/YUFZL\nmrQwZqHNeE2RAhUAn1ASRSRcIVsWqrrZubFQq4pUOlMCgYEAtwohEtO1gbn43+/M\nRQt2xdIZOgNG2HpfliNvtzRSi0CbL1UaueY3kg77//V6bZRId5Kg77myFGr3bN2C\nB1DA1pdfNTfTWG4gRPO19HAYc59QZlvMmYip3MuF3OIWGd4DNo3NV5QXIiq9YvVD\nz1aALZSHcNj+Ur+AiFErtYPRwMADgYQAAoGALzzZZQQSKDjwNXKNs2LXF/ysay/L\nKkwdKzauPqmNrZSl+b4LkAopTfzvHxWP8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PK\nBpZOWjj8lqDA/0eZOwrVPJ3VyG7IyT1w0t2BYWwIYYdjZFwTBxyr2lqe++0qnnse\noNpPVbsBKDaylP0=\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1kc3MAAACBAOD4OwwCK25Jb80mlZXLbDvE3pS78h8KqnLfwIUFb6YGc5fs7M+6Uj7W5nFdEvJQqJAMB6BcKpIcwKjkAJmHDYFHCrvgnhUDl84UZ3BxpxNCjXMoMXrjC/JVKBAT8TY9IUsq40ce1EWeO+rpauBNCwv1qJ/YUFZLmrQwZqHNeE2RAAAAFQCfUBJFJFwhWxaqutm5sVCrilQ6UwAAAIEAtwohEtO1gbn43+/MRQt2xdIZOgNG2HpfliNvtzRSi0CbL1UaueY3kg77//V6bZRId5Kg77myFGr3bN2CB1DA1pdfNTfTWG4gRPO19HAYc59QZlvMmYip3MuF3OIWGd4DNo3NV5QXIiq9YvVDz1aALZSHcNj+Ur+AiFErtYPRwMAAAACALzzZZQQSKDjwNXKNs2LXF/ysay/LKkwdKzauPqmNrZSl+b4LkAopTfzvHxWP8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PKBpZOWjj8lqDA/0eZOwrVPJ3VyG7IyT1w0t2BYWwIYYdjZFwTBxyr2lqe++0qnnseoNpPVbsBKDaylP0=",
|
||||
"private": null
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-dss",
|
||||
"comment": "new openssh format",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBtzCCASwGByqGSM44BAEwggEfAoGBAOD4OwwCK25Jb80mlZXLbDvE3pS78h8K\nqnLfwIUFb6YGc5fs7M+6Uj7W5nFdEvJQqJAMB6BcKpIcwKjkAJmHDYFHCrvgnhUD\nl84UZ3BxpxNCjXMoMXrjC/JVKBAT8TY9IUsq40ce1EWeO+rpauBNCwv1qJ/YUFZL\nmrQwZqHNeE2RAhUAn1ASRSRcIVsWqrrZubFQq4pUOlMCgYEAtwohEtO1gbn43+/M\nRQt2xdIZOgNG2HpfliNvtzRSi0CbL1UaueY3kg77//V6bZRId5Kg77myFGr3bN2C\nB1DA1pdfNTfTWG4gRPO19HAYc59QZlvMmYip3MuF3OIWGd4DNo3NV5QXIiq9YvVD\nz1aALZSHcNj+Ur+AiFErtYPRwMADgYQAAoGALzzZZQQSKDjwNXKNs2LXF/ysay/L\nKkwdKzauPqmNrZSl+b4LkAopTfzvHxWP8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PK\nBpZOWjj8lqDA/0eZOwrVPJ3VyG7IyT1w0t2BYWwIYYdjZFwTBxyr2lqe++0qnnse\noNpPVbsBKDaylP0=\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1kc3MAAACBAOD4OwwCK25Jb80mlZXLbDvE3pS78h8KqnLfwIUFb6YGc5fs7M+6Uj7W5nFdEvJQqJAMB6BcKpIcwKjkAJmHDYFHCrvgnhUDl84UZ3BxpxNCjXMoMXrjC/JVKBAT8TY9IUsq40ce1EWeO+rpauBNCwv1qJ/YUFZLmrQwZqHNeE2RAAAAFQCfUBJFJFwhWxaqutm5sVCrilQ6UwAAAIEAtwohEtO1gbn43+/MRQt2xdIZOgNG2HpfliNvtzRSi0CbL1UaueY3kg77//V6bZRId5Kg77myFGr3bN2CB1DA1pdfNTfTWG4gRPO19HAYc59QZlvMmYip3MuF3OIWGd4DNo3NV5QXIiq9YvVDz1aALZSHcNj+Ur+AiFErtYPRwMAAAACALzzZZQQSKDjwNXKNs2LXF/ysay/LKkwdKzauPqmNrZSl+b4LkAopTfzvHxWP8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PKBpZOWjj8lqDA/0eZOwrVPJ3VyG7IyT1w0t2BYWwIYYdjZFwTBxyr2lqe++0qnnseoNpPVbsBKDaylP0=",
|
||||
"private": "-----BEGIN DSA PRIVATE KEY-----\nMIIBvAIBAAKBgQDg+DsMAituSW/NJpWVy2w7xN6Uu/IfCqpy38CFBW+mBnOX7OzP\nulI+1uZxXRLyUKiQDAegXCqSHMCo5ACZhw2BRwq74J4VA5fOFGdwcacTQo1zKDF6\n4wvyVSgQE/E2PSFLKuNHHtRFnjvq6WrgTQsL9aif2FBWS5q0MGahzXhNkQIVAJ9Q\nEkUkXCFbFqq62bmxUKuKVDpTAoGBALcKIRLTtYG5+N/vzEULdsXSGToDRth6X5Yj\nb7c0UotAmy9VGrnmN5IO+//1em2USHeSoO+5shRq92zdggdQwNaXXzU301huIETz\ntfRwGHOfUGZbzJmIqdzLhdziFhneAzaNzVeUFyIqvWL1Q89WgC2Uh3DY/lK/gIhR\nK7WD0cDAAoGALzzZZQQSKDjwNXKNs2LXF/ysay/LKkwdKzauPqmNrZSl+b4LkAop\nTfzvHxWP8rPb3VE4iXuH8CGYo6XB3HA9k4bl98PKBpZOWjj8lqDA/0eZOwrVPJ3V\nyG7IyT1w0t2BYWwIYYdjZFwTBxyr2lqe++0qnnseoNpPVbsBKDaylP0CFQCKFgEh\ngHxanJC8L7T0TQs6ME05dQ==\n-----END DSA PRIVATE KEY-----"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBgJ5gXYn
|
||||
/2IFE2+CrAxYR8AAAAEAAAAAEAAAGxAAAAB3NzaC1kc3MAAACBAPKhVnFGWb0KLibdYnJz
|
||||
0RwFy/mt98KMIdByHKQWRm9UjoVJk1ypuQpnj+bqFnxCzCFSU9OUj0/Xe0Wuk+kF2BtMO0
|
||||
w+ZYfVHCqEaaIJ1D/iLqi8aBbYs552l9+P0DsFUlTE0D/AvKTQ2PsztFq7wHUTQVmnj4vy
|
||||
k1bw7ske+ImLAAAAFQDnXsk6hdenasLyE8ylLHSE+0XR3QAAAIBsMerhmMT0/416hJV/pr
|
||||
s7crOX0e0gF8C7kar/ILj5WULX7k143+4lgluoogrPXbd5fXgOnqdQawow8a/IjU62Sz6n
|
||||
/qfHLJtQ2sJOK2Vkj5NF2UCcRHrewqJw9nDCS7yYh3c+gUfIBcIRkEJK6eRJfrZuaq0Yue
|
||||
nUa9AuFwnjPAAAAIBwjDUjp9jaJu46eobNK8CWJL/Noi2fXTtFZFgUFRwkr/FXLLsOckQT
|
||||
mYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuCx6dIgiOf2gRClQU5OlqhrnMW2BQXlR
|
||||
hBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/C2XBGgEuRdgyqQAAAgDIGP0oYyi7sTk0HdU9
|
||||
uWZLaDhHpW4Z8xTzfgUDbxoTYQ2igO90O32vSqW/cC2QKWTFuPCFnsCerHAIGzX/eyxlCQ
|
||||
VyNa7VrhbNjIKAHBF3XMcRVRbW2SdYq8tHSkeZHr5EuO5dRfJ7wsR8flkPb4O4viNlIbvF
|
||||
Ake8dsZEOhcnVNiv+NMR9mTq8l91wR60tr3XiWzCMkEYrJiWOfQuZSvzYi7dUmFxQuEZfQ
|
||||
vIPkZD3L6XdaAz/r6YAONFAbtUMAOaUxOGV9puSsunSosAvmi+NcJ9iUM2FpAu561gp+Tv
|
||||
RRcgXHxLGuzTNASiMaTN3M+HenqUh3RWmWauL5wSR7DbrH7Vq47YTnVjtg8xcZnMCfOx2D
|
||||
Wz775hD6uyLwbkxKMaNMf8p4sOcXsSpHNqKmfkUxQBpNRp6Vg5W+AVaAkyXQng2LRt6txJ
|
||||
Xv5zBiSFdsobkrWko/ONfGKfG+zVP+LIVcghLpp71GZQX6Ci02vB55pvk8k0G91H3INn/c
|
||||
t6Q5zY5pK9VZwxjZ29psm7V+FdeD1g8VQ1Rp9muq6zDXHKKyqkBK/oGCM9UhBHFjki0gBR
|
||||
v6LY/iXsz/eG14svhLjM5zYFSX7jUOI9b/PnhhL7Mos4wguHN2EjfGWuC07PkkqDPoqSwn
|
||||
cC91OKhub6yqZsqvBz9BcV+2FxVNPNKzRdzA==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ssh-dss AAAAB3NzaC1kc3MAAACBAPKhVnFGWb0KLibdYnJz0RwFy/mt98KMIdByHKQWRm9UjoVJk1ypuQpnj+bqFnxCzCFSU9OUj0/Xe0Wuk+kF2BtMO0w+ZYfVHCqEaaIJ1D/iLqi8aBbYs552l9+P0DsFUlTE0D/AvKTQ2PsztFq7wHUTQVmnj4vyk1bw7ske+ImLAAAAFQDnXsk6hdenasLyE8ylLHSE+0XR3QAAAIBsMerhmMT0/416hJV/prs7crOX0e0gF8C7kar/ILj5WULX7k143+4lgluoogrPXbd5fXgOnqdQawow8a/IjU62Sz6n/qfHLJtQ2sJOK2Vkj5NF2UCcRHrewqJw9nDCS7yYh3c+gUfIBcIRkEJK6eRJfrZuaq0YuenUa9AuFwnjPAAAAIBwjDUjp9jaJu46eobNK8CWJL/Noi2fXTtFZFgUFRwkr/FXLLsOckQTmYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuCx6dIgiOf2gRClQU5OlqhrnMW2BQXlRhBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/C2XBGgEuRdgyqQ==
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-dss",
|
||||
"comment": "",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBtjCCASsGByqGSM44BAEwggEeAoGBAPKhVnFGWb0KLibdYnJz0RwFy/mt98KM\nIdByHKQWRm9UjoVJk1ypuQpnj+bqFnxCzCFSU9OUj0/Xe0Wuk+kF2BtMO0w+ZYfV\nHCqEaaIJ1D/iLqi8aBbYs552l9+P0DsFUlTE0D/AvKTQ2PsztFq7wHUTQVmnj4vy\nk1bw7ske+ImLAhUA517JOoXXp2rC8hPMpSx0hPtF0d0CgYBsMerhmMT0/416hJV/\nprs7crOX0e0gF8C7kar/ILj5WULX7k143+4lgluoogrPXbd5fXgOnqdQawow8a/I\njU62Sz6n/qfHLJtQ2sJOK2Vkj5NF2UCcRHrewqJw9nDCS7yYh3c+gUfIBcIRkEJK\n6eRJfrZuaq0YuenUa9AuFwnjPAOBhAACgYBwjDUjp9jaJu46eobNK8CWJL/Noi2f\nXTtFZFgUFRwkr/FXLLsOckQTmYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuC\nx6dIgiOf2gRClQU5OlqhrnMW2BQXlRhBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/\nC2XBGgEuRdgyqQ==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1kc3MAAACBAPKhVnFGWb0KLibdYnJz0RwFy/mt98KMIdByHKQWRm9UjoVJk1ypuQpnj+bqFnxCzCFSU9OUj0/Xe0Wuk+kF2BtMO0w+ZYfVHCqEaaIJ1D/iLqi8aBbYs552l9+P0DsFUlTE0D/AvKTQ2PsztFq7wHUTQVmnj4vyk1bw7ske+ImLAAAAFQDnXsk6hdenasLyE8ylLHSE+0XR3QAAAIBsMerhmMT0/416hJV/prs7crOX0e0gF8C7kar/ILj5WULX7k143+4lgluoogrPXbd5fXgOnqdQawow8a/IjU62Sz6n/qfHLJtQ2sJOK2Vkj5NF2UCcRHrewqJw9nDCS7yYh3c+gUfIBcIRkEJK6eRJfrZuaq0YuenUa9AuFwnjPAAAAIBwjDUjp9jaJu46eobNK8CWJL/Noi2fXTtFZFgUFRwkr/FXLLsOckQTmYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuCx6dIgiOf2gRClQU5OlqhrnMW2BQXlRhBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/C2XBGgEuRdgyqQ==",
|
||||
"private": null
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-dss",
|
||||
"comment": "new openssh format encrypted",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBtjCCASsGByqGSM44BAEwggEeAoGBAPKhVnFGWb0KLibdYnJz0RwFy/mt98KM\nIdByHKQWRm9UjoVJk1ypuQpnj+bqFnxCzCFSU9OUj0/Xe0Wuk+kF2BtMO0w+ZYfV\nHCqEaaIJ1D/iLqi8aBbYs552l9+P0DsFUlTE0D/AvKTQ2PsztFq7wHUTQVmnj4vy\nk1bw7ske+ImLAhUA517JOoXXp2rC8hPMpSx0hPtF0d0CgYBsMerhmMT0/416hJV/\nprs7crOX0e0gF8C7kar/ILj5WULX7k143+4lgluoogrPXbd5fXgOnqdQawow8a/I\njU62Sz6n/qfHLJtQ2sJOK2Vkj5NF2UCcRHrewqJw9nDCS7yYh3c+gUfIBcIRkEJK\n6eRJfrZuaq0YuenUa9AuFwnjPAOBhAACgYBwjDUjp9jaJu46eobNK8CWJL/Noi2f\nXTtFZFgUFRwkr/FXLLsOckQTmYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuC\nx6dIgiOf2gRClQU5OlqhrnMW2BQXlRhBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/\nC2XBGgEuRdgyqQ==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1kc3MAAACBAPKhVnFGWb0KLibdYnJz0RwFy/mt98KMIdByHKQWRm9UjoVJk1ypuQpnj+bqFnxCzCFSU9OUj0/Xe0Wuk+kF2BtMO0w+ZYfVHCqEaaIJ1D/iLqi8aBbYs552l9+P0DsFUlTE0D/AvKTQ2PsztFq7wHUTQVmnj4vyk1bw7ske+ImLAAAAFQDnXsk6hdenasLyE8ylLHSE+0XR3QAAAIBsMerhmMT0/416hJV/prs7crOX0e0gF8C7kar/ILj5WULX7k143+4lgluoogrPXbd5fXgOnqdQawow8a/IjU62Sz6n/qfHLJtQ2sJOK2Vkj5NF2UCcRHrewqJw9nDCS7yYh3c+gUfIBcIRkEJK6eRJfrZuaq0YuenUa9AuFwnjPAAAAIBwjDUjp9jaJu46eobNK8CWJL/Noi2fXTtFZFgUFRwkr/FXLLsOckQTmYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuCx6dIgiOf2gRClQU5OlqhrnMW2BQXlRhBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/C2XBGgEuRdgyqQ==",
|
||||
"private": "-----BEGIN DSA PRIVATE KEY-----\nMIIBugIBAAKBgQDyoVZxRlm9Ci4m3WJyc9EcBcv5rffCjCHQchykFkZvVI6FSZNc\nqbkKZ4/m6hZ8QswhUlPTlI9P13tFrpPpBdgbTDtMPmWH1RwqhGmiCdQ/4i6ovGgW\n2LOedpffj9A7BVJUxNA/wLyk0Nj7M7Rau8B1E0FZp4+L8pNW8O7JHviJiwIVAOde\nyTqF16dqwvITzKUsdIT7RdHdAoGAbDHq4ZjE9P+NeoSVf6a7O3Kzl9HtIBfAu5Gq\n/yC4+VlC1+5NeN/uJYJbqKIKz123eX14Dp6nUGsKMPGvyI1Otks+p/6nxyybUNrC\nTitlZI+TRdlAnER63sKicPZwwku8mId3PoFHyAXCEZBCSunkSX62bmqtGLnp1GvQ\nLhcJ4zwCgYBwjDUjp9jaJu46eobNK8CWJL/Noi2fXTtFZFgUFRwkr/FXLLsOckQT\nmYxaWcxP4NwuvMyI25tOueM0RvAIR7J3Afc5pbuCx6dIgiOf2gRClQU5OlqhrnMW\n2BQXlRhBKBNMp5LjM5t46KTBkjh/30//s4Kimrp/C2XBGgEuRdgyqQIUSNLlRVPv\nMC3Q3P3ajY1DdZvi9z8=\n-----END DSA PRIVATE KEY-----"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAAFmFlczEyOC1nY21Ab3BlbnNzaC5jb20AAAAGYmNyeXB0AA
|
||||
AAGAAAABD01pNY1+DTCAHuI6mcjB0YAAAAEAAAAAEAAAGyAAAAB3NzaC1kc3MAAACBAPLA
|
||||
N0jFExSJiCvw7p2W2v5tqvXIG4YwCglrl2wnGOMBGmfaeIcxZErzW00hOxq+NvDIlK43kJ
|
||||
iP98Vz0XTHIW6DpkE9DcC5GGA6nDZn9L+BSrBL8NhuBlz2ekgWOTCqnDC7Il/iyUCMi79s
|
||||
ZPOEg/bMExWJlB5AosJr7v5twVftAAAAFQC5AGsioHKAc2Cd2QwKLUZSmDZAVwAAAIBxYf
|
||||
EThMIXPQkSer3snKJfDz0uvc1y/6htsjXLk93TAAi3LSD2dGqYs5s0WfzO4RnFso0EovrL
|
||||
OnIbqU1XApr6CPKAVX2REsXFWWF3VixEHIEF1Q9gIvHdYgAxSxtwYvOPpAwDmaPxWeV5/q
|
||||
MsMu2RSKkK6f08J0vsESnKU4nmnwAAAIEAxH8NZyntzihIAHnx1Lbo7h1sPi4RhcpKK5pS
|
||||
UiaKoWxkjseqUsyWENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3qhq/B3bspx1GWjL
|
||||
qLfKbeVi4un8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi7GdZG8Q0tuyfXxsAAAIA
|
||||
PDupGK4wMtROtFZqo7vduzkHJuDrE/tAwGqiD2pKMova7WaKM0EUznwcl3gtmhHvFeY+NJ
|
||||
3Uc9sQcX/9n3y6NAYsC+eZeqe7Sy2GWVyqxOUJHpZqfsKYJidG61TBgKgx+JXAeidYdz4L
|
||||
4cEapwwocOptbY3ZRFmszekq5xPomnkP9DeSQG6l4eYSv7OpeAHlFj2KCmJMVEZDOl6RyJ
|
||||
KCqOpfEJIIVoCmna/hQdd9ptLVFmbX/VShgLjvUwfBggJtZNPb5jx+PMy+I0ylywaCIG5K
|
||||
JQAqust6dzFBx3mBoO4kZPBHlb8XwQ4HYLYph0Ur/lINsHrpLxgmtEw7zzs73Nshl6go2V
|
||||
uvBtcZ5ywAMk+8CLP5ZgpiGBxlMtFGowp/5zuJxRpc9FgdfxnnVWDyzcQ/YvX9lwzb6cNz
|
||||
bXeLPsKjOSLPV7G/RFIiuCAOa97ZCM8Ho4FhdNYOGilmjuxV7FJiTc7KP2r+Wh3oxsV7AB
|
||||
Q6Thj06b2mX3iE4hqLaMKIVE1zs22nMlUtFJv8YY1ZWBihUVlnR9vWgIH7ODoZOwNWBlLd
|
||||
Qfyfi8w3KgJWj5oVNAM7WniNFQjfNxEbrPklfYg93deVE/LhPghs9I7fsIeHY/p8GtsO/S
|
||||
amTcjkYi6pUuT8m7IeFYQ8cWvGnbaYz6/9+ni+0aoUL93GKHQw1+mBUVuswVZXBF1WVCf+
|
||||
LMgZ
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ssh-dss AAAAB3NzaC1kc3MAAACBAPLAN0jFExSJiCvw7p2W2v5tqvXIG4YwCglrl2wnGOMBGmfaeIcxZErzW00hOxq+NvDIlK43kJiP98Vz0XTHIW6DpkE9DcC5GGA6nDZn9L+BSrBL8NhuBlz2ekgWOTCqnDC7Il/iyUCMi79sZPOEg/bMExWJlB5AosJr7v5twVftAAAAFQC5AGsioHKAc2Cd2QwKLUZSmDZAVwAAAIBxYfEThMIXPQkSer3snKJfDz0uvc1y/6htsjXLk93TAAi3LSD2dGqYs5s0WfzO4RnFso0EovrLOnIbqU1XApr6CPKAVX2REsXFWWF3VixEHIEF1Q9gIvHdYgAxSxtwYvOPpAwDmaPxWeV5/qMsMu2RSKkK6f08J0vsESnKU4nmnwAAAIEAxH8NZyntzihIAHnx1Lbo7h1sPi4RhcpKK5pSUiaKoWxkjseqUsyWENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3qhq/B3bspx1GWjLqLfKbeVi4un8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi7GdZG8Q0tuyfXxs=
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-dss",
|
||||
"comment": "",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBtzCCASsGByqGSM44BAEwggEeAoGBAPLAN0jFExSJiCvw7p2W2v5tqvXIG4Yw\nCglrl2wnGOMBGmfaeIcxZErzW00hOxq+NvDIlK43kJiP98Vz0XTHIW6DpkE9DcC5\nGGA6nDZn9L+BSrBL8NhuBlz2ekgWOTCqnDC7Il/iyUCMi79sZPOEg/bMExWJlB5A\nosJr7v5twVftAhUAuQBrIqBygHNgndkMCi1GUpg2QFcCgYBxYfEThMIXPQkSer3s\nnKJfDz0uvc1y/6htsjXLk93TAAi3LSD2dGqYs5s0WfzO4RnFso0EovrLOnIbqU1X\nApr6CPKAVX2REsXFWWF3VixEHIEF1Q9gIvHdYgAxSxtwYvOPpAwDmaPxWeV5/qMs\nMu2RSKkK6f08J0vsESnKU4nmnwOBhQACgYEAxH8NZyntzihIAHnx1Lbo7h1sPi4R\nhcpKK5pSUiaKoWxkjseqUsyWENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3q\nhq/B3bspx1GWjLqLfKbeVi4un8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi\n7GdZG8Q0tuyfXxs=\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1kc3MAAACBAPLAN0jFExSJiCvw7p2W2v5tqvXIG4YwCglrl2wnGOMBGmfaeIcxZErzW00hOxq+NvDIlK43kJiP98Vz0XTHIW6DpkE9DcC5GGA6nDZn9L+BSrBL8NhuBlz2ekgWOTCqnDC7Il/iyUCMi79sZPOEg/bMExWJlB5AosJr7v5twVftAAAAFQC5AGsioHKAc2Cd2QwKLUZSmDZAVwAAAIBxYfEThMIXPQkSer3snKJfDz0uvc1y/6htsjXLk93TAAi3LSD2dGqYs5s0WfzO4RnFso0EovrLOnIbqU1XApr6CPKAVX2REsXFWWF3VixEHIEF1Q9gIvHdYgAxSxtwYvOPpAwDmaPxWeV5/qMsMu2RSKkK6f08J0vsESnKU4nmnwAAAIEAxH8NZyntzihIAHnx1Lbo7h1sPi4RhcpKK5pSUiaKoWxkjseqUsyWENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3qhq/B3bspx1GWjLqLfKbeVi4un8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi7GdZG8Q0tuyfXxs=",
|
||||
"private": null
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-dss",
|
||||
"comment": "new openssh format encrypted gcm",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBtzCCASsGByqGSM44BAEwggEeAoGBAPLAN0jFExSJiCvw7p2W2v5tqvXIG4Yw\nCglrl2wnGOMBGmfaeIcxZErzW00hOxq+NvDIlK43kJiP98Vz0XTHIW6DpkE9DcC5\nGGA6nDZn9L+BSrBL8NhuBlz2ekgWOTCqnDC7Il/iyUCMi79sZPOEg/bMExWJlB5A\nosJr7v5twVftAhUAuQBrIqBygHNgndkMCi1GUpg2QFcCgYBxYfEThMIXPQkSer3s\nnKJfDz0uvc1y/6htsjXLk93TAAi3LSD2dGqYs5s0WfzO4RnFso0EovrLOnIbqU1X\nApr6CPKAVX2REsXFWWF3VixEHIEF1Q9gIvHdYgAxSxtwYvOPpAwDmaPxWeV5/qMs\nMu2RSKkK6f08J0vsESnKU4nmnwOBhQACgYEAxH8NZyntzihIAHnx1Lbo7h1sPi4R\nhcpKK5pSUiaKoWxkjseqUsyWENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3q\nhq/B3bspx1GWjLqLfKbeVi4un8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi\n7GdZG8Q0tuyfXxs=\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1kc3MAAACBAPLAN0jFExSJiCvw7p2W2v5tqvXIG4YwCglrl2wnGOMBGmfaeIcxZErzW00hOxq+NvDIlK43kJiP98Vz0XTHIW6DpkE9DcC5GGA6nDZn9L+BSrBL8NhuBlz2ekgWOTCqnDC7Il/iyUCMi79sZPOEg/bMExWJlB5AosJr7v5twVftAAAAFQC5AGsioHKAc2Cd2QwKLUZSmDZAVwAAAIBxYfEThMIXPQkSer3snKJfDz0uvc1y/6htsjXLk93TAAi3LSD2dGqYs5s0WfzO4RnFso0EovrLOnIbqU1XApr6CPKAVX2REsXFWWF3VixEHIEF1Q9gIvHdYgAxSxtwYvOPpAwDmaPxWeV5/qMsMu2RSKkK6f08J0vsESnKU4nmnwAAAIEAxH8NZyntzihIAHnx1Lbo7h1sPi4RhcpKK5pSUiaKoWxkjseqUsyWENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3qhq/B3bspx1GWjLqLfKbeVi4un8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi7GdZG8Q0tuyfXxs=",
|
||||
"private": "-----BEGIN DSA PRIVATE KEY-----\nMIIBuwIBAAKBgQDywDdIxRMUiYgr8O6dltr+bar1yBuGMAoJa5dsJxjjARpn2niH\nMWRK81tNITsavjbwyJSuN5CYj/fFc9F0xyFug6ZBPQ3AuRhgOpw2Z/S/gUqwS/DY\nbgZc9npIFjkwqpwwuyJf4slAjIu/bGTzhIP2zBMViZQeQKLCa+7+bcFX7QIVALkA\nayKgcoBzYJ3ZDAotRlKYNkBXAoGAcWHxE4TCFz0JEnq97JyiXw89Lr3Ncv+obbI1\ny5Pd0wAIty0g9nRqmLObNFn8zuEZxbKNBKL6yzpyG6lNVwKa+gjygFV9kRLFxVlh\nd1YsRByBBdUPYCLx3WIAMUsbcGLzj6QMA5mj8Vnlef6jLDLtkUipCun9PCdL7BEp\nylOJ5p8CgYEAxH8NZyntzihIAHnx1Lbo7h1sPi4RhcpKK5pSUiaKoWxkjseqUsyW\nENt6DTByIdGhBNrOp9/vw2R5CSUkxuI0TlI8bj3qhq/B3bspx1GWjLqLfKbeVi4u\nn8CrooRRq2g8+nYLu2EWbF/56pEEzws6DptlDJQi7GdZG8Q0tuyfXxsCFG8ERflm\nOIBFUymTHP8ZeVOgNm/1\n-----END DSA PRIVATE KEY-----"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
|
||||
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQTjIb0On/AzYDLFRi+g3fGdAIF72KFG
|
||||
iZBpP8oKZ8bsncH9ULtVV9517cNcRNuDETQtvLqoCdIn7TipYo8Jv/lKAAAAsA6ULqEOlC
|
||||
6hAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOMhvQ6f8DNgMsVG
|
||||
L6Dd8Z0AgXvYoUaJkGk/ygpnxuydwf1Qu1VX3nXtw1xE24MRNC28uqgJ0iftOKlijwm/+U
|
||||
oAAAAfVd3jjve28r7FhY6Uo//cKIM1rBeWZG16b8bjyVyFswAAABJuZXcgb3BlbnNzaCBm
|
||||
b3JtYXQBAgMEBQYH
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOMhvQ6f8DNgMsVGL6Dd8Z0AgXvYoUaJkGk/ygpnxuydwf1Qu1VX3nXtw1xE24MRNC28uqgJ0iftOKlijwm/+Uo= new openssh format
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ecdsa-sha2-nistp256",
|
||||
"comment": "new openssh format",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4yG9Dp/wM2AyxUYvoN3xnQCBe9ih\nRomQaT/KCmfG7J3B/VC7VVfede3DXETbgxE0Lby6qAnSJ+04qWKPCb/5Sg==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOMhvQ6f8DNgMsVGL6Dd8Z0AgXvYoUaJkGk/ygpnxuydwf1Qu1VX3nXtw1xE24MRNC28uqgJ0iftOKlijwm/+Uo=",
|
||||
"private": null
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ecdsa-sha2-nistp256",
|
||||
"comment": "new openssh format",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4yG9Dp/wM2AyxUYvoN3xnQCBe9ih\nRomQaT/KCmfG7J3B/VC7VVfede3DXETbgxE0Lby6qAnSJ+04qWKPCb/5Sg==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOMhvQ6f8DNgMsVGL6Dd8Z0AgXvYoUaJkGk/ygpnxuydwf1Qu1VX3nXtw1xE24MRNC28uqgJ0iftOKlijwm/+Uo=",
|
||||
"private": "-----BEGIN EC PRIVATE KEY-----\nMHYCAQEEH1Xd4473tvK+xYWOlKP/3CiDNawXlmRtem/G48lchbOgCgYIKoZIzj0D\nAQehRANCAATjIb0On/AzYDLFRi+g3fGdAIF72KFGiZBpP8oKZ8bsncH9ULtVV951\n7cNcRNuDETQtvLqoCdIn7TipYo8Jv/lK\n-----END EC PRIVATE KEY-----"
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBqNbb13W
|
||||
CKfO7B1vpwJDwbAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz
|
||||
dHAyNTYAAABBBJibjz7zvP/EhMZrW/JDdKvYgiEATNUKMfg2NOVxKlf++eTRypLFc1doTp
|
||||
r+04Ebm1fkyp8RgpFsmvLXLt/dKU0AAADA86k3lHnP6pfD977mwEtKxHOJm44wx8NsdBwN
|
||||
mNLqxlxUE520nsXjDgpgNU0MF9JDnc1kdhSy8PcdTAAH5+k6bpf3gotPrltPUBMFQdPqst
|
||||
5kVS7zOgaxv1qZnlyhOqEdNR3Hee09gJByRrAojtcs+sPI7Nba879NPMb5c5K+gKhONHsa
|
||||
wLAnz66eFQH5iLjd2MwrV4gJe0x6NGCSI2kyzNlxFsoIl7IcHlJHyyuaSlEOFWQJB8cbB4
|
||||
BVZB+/8yAx
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJibjz7zvP/EhMZrW/JDdKvYgiEATNUKMfg2NOVxKlf++eTRypLFc1doTpr+04Ebm1fkyp8RgpFsmvLXLt/dKU0=
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "ecdsa-sha2-nistp256",
|
||||
"comment": "",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmJuPPvO8/8SExmtb8kN0q9iCIQBM\n1Qox+DY05XEqV/755NHKksVzV2hOmv7TgRubV+TKnxGCkWya8tcu390pTQ==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJibjz7zvP/EhMZrW/JDdKvYgiEATNUKMfg2NOVxKlf++eTRypLFc1doTpr+04Ebm1fkyp8RgpFsmvLXLt/dKU0=",
|
||||
"private": null
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ecdsa-sha2-nistp256",
|
||||
"comment": "new openssh format encrypted",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmJuPPvO8/8SExmtb8kN0q9iCIQBM\n1Qox+DY05XEqV/755NHKksVzV2hOmv7TgRubV+TKnxGCkWya8tcu390pTQ==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJibjz7zvP/EhMZrW/JDdKvYgiEATNUKMfg2NOVxKlf++eTRypLFc1doTpr+04Ebm1fkyp8RgpFsmvLXLt/dKU0=",
|
||||
"private": "-----BEGIN EC PRIVATE KEY-----\nMHgCAQEEIQDG2nALLBBmkBnw1QvdW4ClRfF3Zl3CcRHujsYz9CLvf6AKBggqhkjO\nPQMBB6FEA0IABJibjz7zvP/EhMZrW/JDdKvYgiEATNUKMfg2NOVxKlf++eTRypLF\nc1doTpr+04Ebm1fkyp8RgpFsmvLXLt/dKU0=\n-----END EC PRIVATE KEY-----"
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAAFmFlczEyOC1nY21Ab3BlbnNzaC5jb20AAAAGYmNyeXB0AA
|
||||
AAGAAAABAHURyWtYwqVbjholNpL6opAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlz
|
||||
dHAyNTYAAAAIbmlzdHAyNTYAAABBBM+ppawNxvkdHbOaB3ygsRueTdIKiT+OQkAH/5LpDx
|
||||
XcD6i5AR8T/vrCsZ9/y+8GxU8gmvg4Uszr6LDfaQBZnsUAAADAFqKM/ylVkJ/ZA40ZROrW
|
||||
LNgrttf2+lpVkADwXWzhuESFPPzERKlbHVsVtbiiYmPkLnY1s5VM4zXIj7xyO9YNA9KcM5
|
||||
GHOKUL2/NmDaTyGgc9s3BGu/ibpjSeOd1rtGAB4cw1s9ifbXBQd3qDbqzaEmovs3MGaGHD
|
||||
c3VagdxhsppjrPjZ+B40Pzs9QkSGutsSJDpH9wVIu4OLr89TquTU3PVACDRU03lPPENVbt
|
||||
rh2IMJeEQyNINQHtfVwordj8LMOEsBjyQ1aqHNva/iKyTBiw==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM+ppawNxvkdHbOaB3ygsRueTdIKiT+OQkAH/5LpDxXcD6i5AR8T/vrCsZ9/y+8GxU8gmvg4Uszr6LDfaQBZnsU=
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "ecdsa-sha2-nistp256",
|
||||
"comment": "",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEz6mlrA3G+R0ds5oHfKCxG55N0gqJ\nP45CQAf/kukPFdwPqLkBHxP++sKxn3/L7wbFTyCa+DhSzOvosN9pAFmexQ==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM+ppawNxvkdHbOaB3ygsRueTdIKiT+OQkAH/5LpDxXcD6i5AR8T/vrCsZ9/y+8GxU8gmvg4Uszr6LDfaQBZnsU=",
|
||||
"private": null
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ecdsa-sha2-nistp256",
|
||||
"comment": "new openssh format encrypted gcm",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEz6mlrA3G+R0ds5oHfKCxG55N0gqJ\nP45CQAf/kukPFdwPqLkBHxP++sKxn3/L7wbFTyCa+DhSzOvosN9pAFmexQ==\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM+ppawNxvkdHbOaB3ygsRueTdIKiT+OQkAH/5LpDxXcD6i5AR8T/vrCsZ9/y+8GxU8gmvg4Uszr6LDfaQBZnsU=",
|
||||
"private": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIHQfJ+4ZNcwSBaCR5kwrR6HjUsTF//R1F983RSTR8vbJoAoGCCqGSM49\nAwEHoUQDQgAEz6mlrA3G+R0ds5oHfKCxG55N0gqJP45CQAf/kukPFdwPqLkBHxP+\n+sKxn3/L7wbFTyCa+DhSzOvosN9pAFmexQ==\n-----END EC PRIVATE KEY-----"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACCyOMGts0WaAdug9NeXbGn2Jrt4wwiO64dumxV2a1IgKQAAAJBOfs+eTn7P
|
||||
ngAAAAtzc2gtZWQyNTUxOQAAACCyOMGts0WaAdug9NeXbGn2Jrt4wwiO64dumxV2a1IgKQ
|
||||
AAAEBgQKxJoToGE/Xi4UkYR+FXfin4jG8NTcZ13rJ4CDnCfLI4wa2zRZoB26D015dsafYm
|
||||
u3jDCI7rh26bFXZrUiApAAAAB3Rlc3RpbmcBAgMEBQY=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILI4wa2zRZoB26D015dsafYmu3jDCI7rh26bFXZrUiAp testing
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-ed25519",
|
||||
"comment": "testing",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAsjjBrbNFmgHboPTXl2xp9ia7eMMIjuuHbpsVdmtSICk=\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAC3NzaC1lZDI1NTE5AAAAILI4wa2zRZoB26D015dsafYmu3jDCI7rh26bFXZrUiAp",
|
||||
"private": null
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-ed25519",
|
||||
"comment": "testing",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAsjjBrbNFmgHboPTXl2xp9ia7eMMIjuuHbpsVdmtSICk=\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAC3NzaC1lZDI1NTE5AAAAILI4wa2zRZoB26D015dsafYmu3jDCI7rh26bFXZrUiAp",
|
||||
"private": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIGBArEmhOgYT9eLhSRhH4Vd+KfiMbw1NxnXesngIOcJ8\n-----END PRIVATE KEY-----"
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAQEA4q6eZdx7LYh46PcZNcS3CnO7GuYsEJZeTj5LQSgp21IyTelaBPpr
|
||||
ijnMwKa+pLQt5TEobpKFFNecPdT6oPoOKKMe6oH/pX0BNyAEB9KFZfZgh0v4J4IOiO0KHM
|
||||
BNkoTFeGrursPkqYRJ0HL4CqYqRdINy1sgDU6jUIOuDD5XZzlpDXb1ftZoCei9OHSWrMKb
|
||||
zibJc64JFM7tUoK6Vl64YiPgxsNXOJYMTrelVJYebtsNrJFmh3XXQABDVutWMYb8I6IrNs
|
||||
8zjxsf6c6N2tKXkk9G4EDKKip4g0bzDmD/fREPQ9vLi59N+ZsyjWCKKE3PZSvwtoyLQN38
|
||||
KvTx3wjNQwAAA8hLhVBxS4VQcQAAAAdzc2gtcnNhAAABAQDirp5l3HstiHjo9xk1xLcKc7
|
||||
sa5iwQll5OPktBKCnbUjJN6VoE+muKOczApr6ktC3lMShukoUU15w91Pqg+g4oox7qgf+l
|
||||
fQE3IAQH0oVl9mCHS/gngg6I7QocwE2ShMV4au6uw+SphEnQcvgKpipF0g3LWyANTqNQg6
|
||||
4MPldnOWkNdvV+1mgJ6L04dJaswpvOJslzrgkUzu1SgrpWXrhiI+DGw1c4lgxOt6VUlh5u
|
||||
2w2skWaHdddAAENW61Yxhvwjois2zzOPGx/pzo3a0peST0bgQMoqKniDRvMOYP99EQ9D28
|
||||
uLn035mzKNYIooTc9lK/C2jItA3fwq9PHfCM1DAAAAAwEAAQAAAQAmShSbZBiyYkD6KPLr
|
||||
MCUy8MWED6kVzDB1yvPvN5eKYmH44xe/i4UqvgSl7gR50a2G7zzDIKC2Go1brGQBWPuXRa
|
||||
ZtOjQygeD4rMHBiH/b7zfy4pQyKDfITTHOFXWE8ERiyL00bAZt09icCy92rQaq8IY/+U56
|
||||
sPPJH9UAYG9nEev8opFjAWToFDu0U2+dC+lbqLlXDqDRo75NlnDFmgUoja3y2eFr9A0Cc+
|
||||
hjecrdxyJFsCJfEfaLWtBnZb886gqzzvfbHImSQtBAKERcSxuki7uxMoP67g3iQOXa65uz
|
||||
8kFWRNmbQTGQttakoUaybh1t9eLpBqvVON/4Kg0THShRAAAAgFBTz2ajBK/R/crOSL9VK1
|
||||
f7oQv2iJTRVfnUs0r+qPGgf/a/5UwkGRj0KfEWBp3qYD+keShnPr6PDPFrm8UmIdUX8AY7
|
||||
3tWT2K/JQVlzJNuINsw+DNjn4M17Z25q0LPmReRWL0nRc2w6W/hmQ/Jmqz6w8Qc4+xpeqS
|
||||
/HG5feliVnAAAAgQD90a+5Ky3o/2YtueqRf/3dKoiMgGB7JAOzye4dDKGABSlWuQ4N4xEI
|
||||
CW5MSTp7i/uobTF/tyFO3tTSyb5b2Xwbn/kLO0vgvFCdUGR2BQfN3mcT92T0Gn3JDF3Wym
|
||||
i2mgU6qnPf+eu+RKZQ9IiyNGny61ROUQa0R0z0pgiAfA89xwAAAIEA5KE9i6hHmigJwfD7
|
||||
/AGI4ujyWIVpNyrTdXG3HAPhsdoFuG5ggHggrPuuBF9wNcosrhL20VNOQGHg15gWZIVudu
|
||||
0qxky4ivQs67Sk9XUjuvTnf+VubM51rIsmh4atKJFSSZo78DEcTRt8aXLrSNvGQ4WPRweM
|
||||
2Z0YGfMMDM9KJKUAAAASbmV3IG9wZW5zc2ggZm9ybWF0AQ==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDirp5l3HstiHjo9xk1xLcKc7sa5iwQll5OPktBKCnbUjJN6VoE+muKOczApr6ktC3lMShukoUU15w91Pqg+g4oox7qgf+lfQE3IAQH0oVl9mCHS/gngg6I7QocwE2ShMV4au6uw+SphEnQcvgKpipF0g3LWyANTqNQg64MPldnOWkNdvV+1mgJ6L04dJaswpvOJslzrgkUzu1SgrpWXrhiI+DGw1c4lgxOt6VUlh5u2w2skWaHdddAAENW61Yxhvwjois2zzOPGx/pzo3a0peST0bgQMoqKniDRvMOYP99EQ9D28uLn035mzKNYIooTc9lK/C2jItA3fwq9PHfCM1D new openssh format
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-rsa",
|
||||
"comment": "new openssh format",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4q6eZdx7LYh46PcZNcS3\nCnO7GuYsEJZeTj5LQSgp21IyTelaBPprijnMwKa+pLQt5TEobpKFFNecPdT6oPoO\nKKMe6oH/pX0BNyAEB9KFZfZgh0v4J4IOiO0KHMBNkoTFeGrursPkqYRJ0HL4CqYq\nRdINy1sgDU6jUIOuDD5XZzlpDXb1ftZoCei9OHSWrMKbzibJc64JFM7tUoK6Vl64\nYiPgxsNXOJYMTrelVJYebtsNrJFmh3XXQABDVutWMYb8I6IrNs8zjxsf6c6N2tKX\nkk9G4EDKKip4g0bzDmD/fREPQ9vLi59N+ZsyjWCKKE3PZSvwtoyLQN38KvTx3wjN\nQwIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDirp5l3HstiHjo9xk1xLcKc7sa5iwQll5OPktBKCnbUjJN6VoE+muKOczApr6ktC3lMShukoUU15w91Pqg+g4oox7qgf+lfQE3IAQH0oVl9mCHS/gngg6I7QocwE2ShMV4au6uw+SphEnQcvgKpipF0g3LWyANTqNQg64MPldnOWkNdvV+1mgJ6L04dJaswpvOJslzrgkUzu1SgrpWXrhiI+DGw1c4lgxOt6VUlh5u2w2skWaHdddAAENW61Yxhvwjois2zzOPGx/pzo3a0peST0bgQMoqKniDRvMOYP99EQ9D28uLn035mzKNYIooTc9lK/C2jItA3fwq9PHfCM1D",
|
||||
"private": null
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-rsa",
|
||||
"comment": "new openssh format",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4q6eZdx7LYh46PcZNcS3\nCnO7GuYsEJZeTj5LQSgp21IyTelaBPprijnMwKa+pLQt5TEobpKFFNecPdT6oPoO\nKKMe6oH/pX0BNyAEB9KFZfZgh0v4J4IOiO0KHMBNkoTFeGrursPkqYRJ0HL4CqYq\nRdINy1sgDU6jUIOuDD5XZzlpDXb1ftZoCei9OHSWrMKbzibJc64JFM7tUoK6Vl64\nYiPgxsNXOJYMTrelVJYebtsNrJFmh3XXQABDVutWMYb8I6IrNs8zjxsf6c6N2tKX\nkk9G4EDKKip4g0bzDmD/fREPQ9vLi59N+ZsyjWCKKE3PZSvwtoyLQN38KvTx3wjN\nQwIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDirp5l3HstiHjo9xk1xLcKc7sa5iwQll5OPktBKCnbUjJN6VoE+muKOczApr6ktC3lMShukoUU15w91Pqg+g4oox7qgf+lfQE3IAQH0oVl9mCHS/gngg6I7QocwE2ShMV4au6uw+SphEnQcvgKpipF0g3LWyANTqNQg64MPldnOWkNdvV+1mgJ6L04dJaswpvOJslzrgkUzu1SgrpWXrhiI+DGw1c4lgxOt6VUlh5u2w2skWaHdddAAENW61Yxhvwjois2zzOPGx/pzo3a0peST0bgQMoqKniDRvMOYP99EQ9D28uLn035mzKNYIooTc9lK/C2jItA3fwq9PHfCM1D",
|
||||
"private": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEA4q6eZdx7LYh46PcZNcS3CnO7GuYsEJZeTj5LQSgp21IyTela\nBPprijnMwKa+pLQt5TEobpKFFNecPdT6oPoOKKMe6oH/pX0BNyAEB9KFZfZgh0v4\nJ4IOiO0KHMBNkoTFeGrursPkqYRJ0HL4CqYqRdINy1sgDU6jUIOuDD5XZzlpDXb1\nftZoCei9OHSWrMKbzibJc64JFM7tUoK6Vl64YiPgxsNXOJYMTrelVJYebtsNrJFm\nh3XXQABDVutWMYb8I6IrNs8zjxsf6c6N2tKXkk9G4EDKKip4g0bzDmD/fREPQ9vL\ni59N+ZsyjWCKKE3PZSvwtoyLQN38KvTx3wjNQwIDAQABAoIBACZKFJtkGLJiQPoo\n8uswJTLwxYQPqRXMMHXK8+83l4piYfjjF7+LhSq+BKXuBHnRrYbvPMMgoLYajVus\nZAFY+5dFpm06NDKB4PiswcGIf9vvN/LilDIoN8hNMc4VdYTwRGLIvTRsBm3T2JwL\nL3atBqrwhj/5Tnqw88kf1QBgb2cR6/yikWMBZOgUO7RTb50L6VuouVcOoNGjvk2W\ncMWaBSiNrfLZ4Wv0DQJz6GN5yt3HIkWwIl8R9ota0GdlvzzqCrPO99sciZJC0EAo\nRFxLG6SLu7Eyg/ruDeJA5drrm7PyQVZE2ZtBMZC21qShRrJuHW314ukGq9U43/gq\nDRMdKFECgYEA/dGvuSst6P9mLbnqkX/93SqIjIBgeyQDs8nuHQyhgAUpVrkODeMR\nCAluTEk6e4v7qG0xf7chTt7U0sm+W9l8G5/5CztL4LxQnVBkdgUHzd5nE/dk9Bp9\nyQxd1spotpoFOqpz3/nrvkSmUPSIsjRp8utUTlEGtEdM9KYIgHwPPccCgYEA5KE9\ni6hHmigJwfD7/AGI4ujyWIVpNyrTdXG3HAPhsdoFuG5ggHggrPuuBF9wNcosrhL2\n0VNOQGHg15gWZIVudu0qxky4ivQs67Sk9XUjuvTnf+VubM51rIsmh4atKJFSSZo7\n8DEcTRt8aXLrSNvGQ4WPRweM2Z0YGfMMDM9KJKUCgYB7Yh0b1EOjCdQv0jqWtDNB\n+dUbB6Te92jdUwHvGR7AzsGDqL2OPp0e3QbDCq3lNO0GuN3hCbKlVmj6dpuUpqpP\n+3ni3dZKzwAZGOVdAaEDkGNnL1Hh36bZvqs3KHmymjiEhiuB60mP2mtG2zg/+H6w\nWXlIANdTd32PR87GNohqLQKBgA36ic/LJy2Wuxn/iPicg2kUQxUEey1jUfCBVmfB\nGQCNywG+xem07pKFBNvBlhPD27187VhZFpS7J0snQl89BUcCMzZSpIniagizT86u\nLdQVez4HohvG98zn6SAqLNYpJHXZl0aVShywzIeJ/jbDMTkZpmv6WzNG9p1HjfoO\nhoL9AoGAUFPPZqMEr9H9ys5Iv1UrV/uhC/aIlNFV+dSzSv6o8aB/9r/lTCQZGPQp\n8RYGnepgP6R5KGc+vo8M8WubxSYh1RfwBjve1ZPYr8lBWXMk24g2zD4M2OfgzXtn\nbmrQs+ZF5FYvSdFzbDpb+GZD8marPrDxBzj7Gl6pL8cbl96WJWc=\n-----END RSA PRIVATE KEY-----"
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAS8H9Cyk
|
||||
rueA/Ue6tOb1MOAAAAEAAAAAEAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQC8hCiCPnRs
|
||||
0ucZeyn3pNYKN63dVoxbMB4Yzjs7gvo7XKDby/6GXoU/CFQ/Q9zXRxRZmFglMYh2pOD8iW
|
||||
dwpLBdd+GmHb4a6xxKtoPpz1+yCPYvi6nXzKPO3B9Wbg8dtTpV23l8MZDxSRUQ9HIkYHQO
|
||||
oOjJx/AaMdZyHZP+eYK7UqmX1+dtCzr5vvLyEABxrsoFxH/oW/iKO6cDmTxoMyFl9DfUhD
|
||||
TS7cL1OVBulSBav3aJPxjsCEIs6OE94wLJfFtZAPe4GqWWcC7uG1uUL5Muy2N+SfXHOHLa
|
||||
I5n1vozt7lIO5TqvykcqTxipKblMW4Y7Iwlhh0YKJxzH3KJ+Qkn7AAAD4GeinUMcN5H0RP
|
||||
KnXzIsYGq4rG+pEYNL0WyXCOFnyHzr6cASFYa/ViRVRN5H2dDoc0i2tcQStvDt2AfBxP97
|
||||
xbTEmRhLkKW7Sxif+bRRpNt2sO1y7ThufOZ8ZSJdbUYf9nc++k5GMZZUTtkFGhFIyhdyl+
|
||||
ZReuQFrc1Fv0/JV0K72uLSMSSMvunFjnGchch98Z1t0jEuiym8AIAwFtlvRpbOOySJhHun
|
||||
fClEOahNvgzkgpqvviged7Gl9Kh3Fpp57ke1087WUF4hdgG2wuLqRq3Jq2kNvTKVi6+PMv
|
||||
Kz5cLl6beqAJpbkJCpujzrmffo5NHh94R/v8DbAWCyrkjB6NHjOPIVnKaDmXixkcJ489W3
|
||||
PQF0kZ9kLrNU2yP1hBLjikr1zollw6xXC5eEpUsIrNcAHrofTMCMsGKuZhlEgTNe0cEATp
|
||||
ycxi4gHdA6kNSDnMPwOv9rLDZDkgqCqIzxjZCWabqRHwiyoN3CrdDsJNrk8jSqF5epuzXA
|
||||
EjrPUvu+sgFHIWDJOij+HQCvCgmdO/W7NkL/xCEx6QagjoJhapGICnq6CXPO5vBQeK7AMV
|
||||
KWUPB1jdxxlHdrSUYU9v11j0SPUM51AMpWA89GZmuQbe/tK14W35VjtL9aGKsz9Ubio029
|
||||
O23HJXMxM9Dd6EYXAR9xMLFDTcLT03kjRlL/4XFS4fJqbTGDtuQNqRO3QK/myVAYjgnXwz
|
||||
X1s77WeIK3sOMwTIXaHReUiQ1Cw+WmkXOhefePT+HrkyDlJk3ikgPUy2s5QW5/d6Lmolwb
|
||||
mcS9JUfaai0ysP3v1bew8go/IHiUD/X9AkjkKM2kfS1NcPSi18r2721e6RqZiIHxSoyKvq
|
||||
yUmwiS1kUklSuhlTORBvbclbv4HTwp1iJfu/6zsMqVJc2E8H6WUw3kTeh9fhDMpTY5NArF
|
||||
KD2aRIYHFvOKav+0vSbQ/KqmKeiTvyZaV7q6giRxVLxBddl4+ucD+FybPJZSebRQ+0QT1j
|
||||
aUDSpp541zW0rX7sCiZ6sFUybCPVDM1uA5gTAP015OD/FS342gi+Y04K0jBSjlApuy6BQx
|
||||
sMEQbR3weMmnodbhCtbcgDZDagSFNPlDud0GJl9IWV4hO/K1f9a+Ox3G27Jq4YC2PFgTDb
|
||||
aYib4xAXPUHJpoWsstSjpMnfgKcS3AGRdJ/jxlKRWV/NXFf4DYIwpzITqFMF+4VqXCa2AS
|
||||
JWOcSxOK92UqCcZEs8RED3x9dF9E2yBBwHeuwDvH3c9x/nsM/cjDY+EE9VcEUOxF6qMOhO
|
||||
CiRtEihEAYM46XeFzcSOQrwWPcKu3WTv3IpnzTaofBxV065CUn
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
+1
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hCiCPnRs0ucZeyn3pNYKN63dVoxbMB4Yzjs7gvo7XKDby/6GXoU/CFQ/Q9zXRxRZmFglMYh2pOD8iWdwpLBdd+GmHb4a6xxKtoPpz1+yCPYvi6nXzKPO3B9Wbg8dtTpV23l8MZDxSRUQ9HIkYHQOoOjJx/AaMdZyHZP+eYK7UqmX1+dtCzr5vvLyEABxrsoFxH/oW/iKO6cDmTxoMyFl9DfUhDTS7cL1OVBulSBav3aJPxjsCEIs6OE94wLJfFtZAPe4GqWWcC7uG1uUL5Muy2N+SfXHOHLaI5n1vozt7lIO5TqvykcqTxipKblMW4Y7Iwlhh0YKJxzH3KJ+Qkn7
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "ssh-rsa",
|
||||
"comment": "",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIQogj50bNLnGXsp96TW\nCjet3VaMWzAeGM47O4L6O1yg28v+hl6FPwhUP0Pc10cUWZhYJTGIdqTg/IlncKSw\nXXfhph2+GuscSraD6c9fsgj2L4up18yjztwfVm4PHbU6Vdt5fDGQ8UkVEPRyJGB0\nDqDoycfwGjHWch2T/nmCu1Kpl9fnbQs6+b7y8hAAca7KBcR/6Fv4ijunA5k8aDMh\nZfQ31IQ00u3C9TlQbpUgWr92iT8Y7AhCLOjhPeMCyXxbWQD3uBqllnAu7htblC+T\nLstjfkn1xzhy2iOZ9b6M7e5SDuU6r8pHKk8YqSm5TFuGOyMJYYdGCiccx9yifkJJ\n+wIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hCiCPnRs0ucZeyn3pNYKN63dVoxbMB4Yzjs7gvo7XKDby/6GXoU/CFQ/Q9zXRxRZmFglMYh2pOD8iWdwpLBdd+GmHb4a6xxKtoPpz1+yCPYvi6nXzKPO3B9Wbg8dtTpV23l8MZDxSRUQ9HIkYHQOoOjJx/AaMdZyHZP+eYK7UqmX1+dtCzr5vvLyEABxrsoFxH/oW/iKO6cDmTxoMyFl9DfUhDTS7cL1OVBulSBav3aJPxjsCEIs6OE94wLJfFtZAPe4GqWWcC7uG1uUL5Muy2N+SfXHOHLaI5n1vozt7lIO5TqvykcqTxipKblMW4Y7Iwlhh0YKJxzH3KJ+Qkn7",
|
||||
"private": null
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "ssh-rsa",
|
||||
"comment": "new openssh format encrypted",
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIQogj50bNLnGXsp96TW\nCjet3VaMWzAeGM47O4L6O1yg28v+hl6FPwhUP0Pc10cUWZhYJTGIdqTg/IlncKSw\nXXfhph2+GuscSraD6c9fsgj2L4up18yjztwfVm4PHbU6Vdt5fDGQ8UkVEPRyJGB0\nDqDoycfwGjHWch2T/nmCu1Kpl9fnbQs6+b7y8hAAca7KBcR/6Fv4ijunA5k8aDMh\nZfQ31IQ00u3C9TlQbpUgWr92iT8Y7AhCLOjhPeMCyXxbWQD3uBqllnAu7htblC+T\nLstjfkn1xzhy2iOZ9b6M7e5SDuU6r8pHKk8YqSm5TFuGOyMJYYdGCiccx9yifkJJ\n+wIDAQAB\n-----END PUBLIC KEY-----",
|
||||
"publicSSH": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hCiCPnRs0ucZeyn3pNYKN63dVoxbMB4Yzjs7gvo7XKDby/6GXoU/CFQ/Q9zXRxRZmFglMYh2pOD8iWdwpLBdd+GmHb4a6xxKtoPpz1+yCPYvi6nXzKPO3B9Wbg8dtTpV23l8MZDxSRUQ9HIkYHQOoOjJx/AaMdZyHZP+eYK7UqmX1+dtCzr5vvLyEABxrsoFxH/oW/iKO6cDmTxoMyFl9DfUhDTS7cL1OVBulSBav3aJPxjsCEIs6OE94wLJfFtZAPe4GqWWcC7uG1uUL5Muy2N+SfXHOHLaI5n1vozt7lIO5TqvykcqTxipKblMW4Y7Iwlhh0YKJxzH3KJ+Qkn7",
|
||||
"private": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAvIQogj50bNLnGXsp96TWCjet3VaMWzAeGM47O4L6O1yg28v+\nhl6FPwhUP0Pc10cUWZhYJTGIdqTg/IlncKSwXXfhph2+GuscSraD6c9fsgj2L4up\n18yjztwfVm4PHbU6Vdt5fDGQ8UkVEPRyJGB0DqDoycfwGjHWch2T/nmCu1Kpl9fn\nbQs6+b7y8hAAca7KBcR/6Fv4ijunA5k8aDMhZfQ31IQ00u3C9TlQbpUgWr92iT8Y\n7AhCLOjhPeMCyXxbWQD3uBqllnAu7htblC+TLstjfkn1xzhy2iOZ9b6M7e5SDuU6\nr8pHKk8YqSm5TFuGOyMJYYdGCiccx9yifkJJ+wIDAQABAoIBAD1UXX1p5iSVRHvk\nttWLOdsfHCA7DPSJpfD5/wkwZkozq112czqxu3WzNv1SDaG3zSYMyvhmsfevUka2\nSQG7gmkWHEIXwQYu4Qhpcmb5gS+BfN4g+MNtHwmoUUWkDqTilbTi7xX5ZicpWIIo\nlI3DF16++JzUwAc1mYeMmd4bF+3quh93xW7hhrcQ31+D9kzqt6nLG1d9+IVpMbhD\nnNB9zapkZHwnz6YYhb5waMOHr6U902TyGgKyjq3Z/PkMJ0zKg01roUtQs9oQOIZF\nvueF2hwyzHqeIgpqhWJl9HMpfdym6Lh2lwguK3KYwNIMFQg+gNBWruYlH6SGfylq\n0wB5xIECgYEA8FdyEDd4TbVBKIXzzmY6zYmN/Q9uiz0IjbeYYzuRxZ4a7stE/t8n\nM5UxxkqeD8rtRAQJyFDGPAhFeeOpIfzEVPG+5s72pI69+9aE/gCGA91+sOSnLoiJ\nPW1I7SouZfCeaaRQxSSIMjsCea2s6yraujGZJyPEWSkG5TijY8+vzDsCgYEAyMxX\nCYvqlRTaT5lAkRTFLqf0/NSpRoCnG7qSPUyJjxJsVfYFLv1FZCyyrA+SaIyufjoT\nKutKE31r7wre5bkjRRenIcTkR/tdNRdkWsB/ysZ9Cp43FIPTXS5gxTQxOaJyRGvJ\n9MW0m8N1pMvPIsagzoxxvzgU9ZOejs2NQ69qXUECgYBq7DxOgp7+0zhdsto4ZLqc\nXinQ/2CKiWiYw6kD3KiJZkFNIxla2iQyiplOQjv3gqvzqmg/uc+3PWbLR0EjYbRm\npfXr8P9BTk+vDky0Q79bUNrgD5lg1lVYApqDCFUD/Pw8u2FDk3EUB7SeNWnMZZBR\nbWdZRkw/7kSnDX+DFA59qQKBgG9v0AHxT4/LEdlJEOczYrcg6TqDfyosbhFaepxg\nZJstO0h9j6TjVGZi1AnfXn59TL2q10ZjbCni2krAerF9DNDkbpG0Joi4PKMhR0WC\nPam4fF6vLZxKCLxW58epzoPQ3p+QPnWEX1ZupFR/84W2PDpFAT+BDUi40y8nbnWY\n3WvBAoGADjh0hEkq3sy6oWt0m1NjGU1yxKV+geg48BFnu2LVSFv1rw1V7X8XFEYl\nP1B3sEpOOpPGuoz+r2E9PrsdMuYNOmVlRFRpe7pm7zyhzdFYBvLE2btJqv1PmxFu\ncEkrXJS/ETxkKdMaoUbYHcKiTIMi2pDrdJtg6oHcipm0yTBZkKs=\n-----END RSA PRIVATE KEY-----"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user