mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-08 23:00:58 +00:00
Merge branch '3.0'
This commit is contained in:
commit
b722a4f002
92
.github/workflows/ci.yml
vendored
Normal file
92
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
timeout-minutes: 5
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
tools: php-parallel-lint/php-parallel-lint:1
|
||||
- name: Lint
|
||||
run: parallel-lint --show-deprecated build phpseclib tests
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
|
||||
quality_tools:
|
||||
name: Quality Tools
|
||||
timeout-minutes: 5
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
tools: squizlabs/php_codesniffer:3, friendsofphp/php-cs-fixer:3, vimeo/psalm:4
|
||||
- name: Composer Install
|
||||
run: composer install --classmap-authoritative --no-interaction --no-cache
|
||||
- name: PHP_CodeSniffer
|
||||
run: phpcs --standard=build/php_codesniffer.xml
|
||||
- name: PHP CS Fixer
|
||||
run: php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no
|
||||
- name: Psalm
|
||||
run: psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false
|
||||
tests:
|
||||
name: Tests
|
||||
timeout-minutes: 10
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
- name: Composer Install
|
||||
run: composer install --classmap-authoritative --no-interaction --no-cache
|
||||
- name: Make Tests Compatiable With New PHPUnit Versions
|
||||
if: matrix.php-version != '5.6' && matrix.php-version != '7.0'
|
||||
run: php tests/make_compatible_with_new_phpunit_versions.php
|
||||
- name: Setup Secure Shell Functional Tests
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: |
|
||||
PHPSECLIB_SSH_USERNAME='phpseclib'
|
||||
PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0'
|
||||
|
||||
sudo useradd --create-home --base-dir /home "$PHPSECLIB_SSH_USERNAME"
|
||||
echo "$PHPSECLIB_SSH_USERNAME:$PHPSECLIB_SSH_PASSWORD" | sudo chpasswd
|
||||
ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N ""
|
||||
eval `ssh-agent -s`
|
||||
ssh-add "$HOME/.ssh/id_rsa"
|
||||
sudo mkdir -p "/home/$PHPSECLIB_SSH_USERNAME/.ssh/"
|
||||
sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/authorized_keys"
|
||||
sudo ssh-keyscan -t rsa localhost > "/tmp/known_hosts"
|
||||
sudo cp "/tmp/known_hosts" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/known_hosts"
|
||||
sudo chown "$PHPSECLIB_SSH_USERNAME:$PHPSECLIB_SSH_USERNAME" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/" -R
|
||||
|
||||
echo "PHPSECLIB_SSH_HOSTNAME=localhost" >> $GITHUB_ENV
|
||||
echo "PHPSECLIB_SSH_USERNAME=$PHPSECLIB_SSH_USERNAME" >> $GITHUB_ENV
|
||||
echo "PHPSECLIB_SSH_PASSWORD=$PHPSECLIB_SSH_PASSWORD" >> $GITHUB_ENV
|
||||
echo "PHPSECLIB_SSH_HOME=/home/phpseclib" >> $GITHUB_ENV
|
||||
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV
|
||||
- name: PHPUnit
|
||||
run: vendor/bin/phpunit --verbose --configuration tests/phpunit.xml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']
|
||||
experimental: [false]
|
||||
include:
|
||||
- {os: ubuntu-latest, php-version: '8.2', experimental: true}
|
||||
- {os: windows-latest, php-version: '8.2', experimental: true}
|
||||
- {os: macos-latest, php-version: '8.2', experimental: true}
|
39
.travis.yml
39
.travis.yml
@ -1,39 +0,0 @@
|
||||
language: php
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.6
|
||||
dist: xenial
|
||||
- php: 7.0
|
||||
dist: xenial
|
||||
- php: 7.1
|
||||
dist: xenial
|
||||
- php: 7.2
|
||||
dist: xenial
|
||||
- php: 7.3
|
||||
dist: xenial
|
||||
- php: 7.4
|
||||
dist: xenial
|
||||
- php: 8.0
|
||||
dist: bionic
|
||||
- php: 8.1.0
|
||||
dist: bionic
|
||||
- php: nightly
|
||||
dist: bionic
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
|
||||
before_install: true
|
||||
|
||||
install:
|
||||
- phpenv config-rm xdebug.ini
|
||||
- eval `ssh-agent -s`
|
||||
- travis/setup-secure-shell.sh
|
||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' -a `php -r "echo (int) version_compare(PHP_VERSION, '7.0', '<');"` = "1" ]; then travis/install-php-extensions.sh; fi"
|
||||
- travis/setup-composer.sh
|
||||
|
||||
script:
|
||||
- sh -c "if [ -d build/vendor ]; then build/vendor/bin/phpcs --standard=build/phpcs_ruleset.xml; fi"
|
||||
- sh -c "if [ -d build/vendor ]; then build/vendor/bin/php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run; fi"
|
||||
- sh -c "if [ -d build/vendor ]; then build/vendor/bin/psalm --config="build/psalm.xml" --no-cache --long-progress --report-show-info=false --output-format=text; fi"
|
||||
- travis/run-phpunit.sh
|
14
README.md
14
README.md
@ -1,6 +1,6 @@
|
||||
# phpseclib - PHP Secure Communications Library
|
||||
|
||||
[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=master)](https://travis-ci.com/github/phpseclib/phpseclib)
|
||||
[![CI Status](https://github.com/phpseclib/phpseclib/actions/workflows/ci.yml/badge.svg?branch=master&event=push "CI Status")](https://github.com/phpseclib/phpseclib)
|
||||
|
||||
## Supporting phpseclib
|
||||
|
||||
@ -82,19 +82,17 @@ Special Thanks to our $50+ sponsors!:
|
||||
3. Install Development Dependencies
|
||||
```sh
|
||||
composer install
|
||||
composer install --no-interaction --working-dir=build
|
||||
```
|
||||
|
||||
4. Create a Feature Branch
|
||||
|
||||
5. Run continuous integration checks:
|
||||
```sh
|
||||
vendor/bin/phpunit
|
||||
|
||||
# The following tools are from the build specific composer.json using the most recent PHP version:
|
||||
build/vendor/bin/phpcs --standard=build/phpcs_ruleset.xml
|
||||
build/vendor/bin/php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run
|
||||
build/vendor/bin/psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text
|
||||
composer global require php:^8.1 squizlabs/php_codesniffer friendsofphp/php-cs-fixer vimeo/psalm
|
||||
phpcs --standard=build/php_codesniffer.xml
|
||||
php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no
|
||||
psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text
|
||||
vendor/bin/phpunit --verbose --configuration tests/phpunit.xml
|
||||
```
|
||||
|
||||
6. Send us a Pull Request
|
||||
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "phpseclib/build",
|
||||
"description": "A separate composer.json file to house build related dependencies.",
|
||||
"minimum-stability": "stable",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.1.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.5",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"vimeo/psalm": "^4.19"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
@ -51,12 +51,12 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.1",
|
||||
"paragonie/constant_time_encoding": "^1|^2",
|
||||
"paragonie/random_compat": "^1.4|^2.0|^9.99.99",
|
||||
"php": ">=5.6.1"
|
||||
"paragonie/random_compat": "^1.4|^2.0|^9.99.99"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7|^6.0|^9.4"
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
|
||||
@ -76,5 +76,8 @@
|
||||
"psr-4": {
|
||||
"phpseclib3\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="tests/bootstrap.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="phpseclib Unit Test Suite">
|
||||
<directory>./tests/Unit/</directory>
|
||||
</testsuite>
|
||||
<testsuite name="phpseclib Functional Test Suite">
|
||||
<directory>./tests/Functional/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<!-- Code Coverage -->
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./phpseclib/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
@ -15,7 +15,7 @@ use phpseclib3\Crypt\RSA\PrivateKey;
|
||||
use phpseclib3\Crypt\RSA\PublicKey;
|
||||
use phpseclib3\Tests\PhpseclibTestCase;
|
||||
|
||||
class CreateKeyTestRSA extends PhpseclibTestCase
|
||||
class CreateKeyTest extends PhpseclibTestCase
|
||||
{
|
||||
public function testCreateKey()
|
||||
{
|
||||
|
@ -190,13 +190,16 @@ HERE;
|
||||
public function testPKCS1SigWithoutNull()
|
||||
{
|
||||
$rsa = PublicKeyLoader::load([
|
||||
'n' => new BigInteger('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD
|
||||
4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7
|
||||
72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779
|
||||
AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB
|
||||
FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81
|
||||
2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB
|
||||
E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7', 16),
|
||||
'n' => new BigInteger(
|
||||
'E932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD' .
|
||||
'4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7' .
|
||||
'72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779' .
|
||||
'AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB' .
|
||||
'FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81' .
|
||||
'2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB' .
|
||||
'E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7',
|
||||
16
|
||||
),
|
||||
'e' => new BigInteger('3')
|
||||
]);
|
||||
|
||||
|
31
tests/make_compatible_with_new_phpunit_versions.php
Executable file
31
tests/make_compatible_with_new_phpunit_versions.php
Executable file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/** @var iterable<SplFileInfo> $files */
|
||||
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__));
|
||||
foreach ($files as $file) {
|
||||
if ($file->getExtension() === 'php' && $file->getPathname() !== __FILE__) {
|
||||
$fileContents = file_get_contents($file->getPathname());
|
||||
if ($fileContents === false) {
|
||||
throw new \RuntimeException('file_get_contents() failed: ' . $file->getPathname());
|
||||
}
|
||||
$patternToReplacementMap = [
|
||||
'~ function setUpBeforeClass\(\)~' => ' function setUpBeforeClass(): void',
|
||||
'~ function setUp\(\)~' => ' function setUp(): void',
|
||||
'~ function tearDown\(\)~' => ' function tearDown(): void',
|
||||
'~ function assertIsArray\(\$actual, \$message = \'\'\)~' => ' function assertIsArray($actual, string $message = \'\'): void',
|
||||
'~ function assertIsResource\(\$actual, \$message = \'\'\)~' => ' function assertIsResource($actual, string $message = \'\'): void',
|
||||
'~ function assertIsObject\(\$actual, \$message = \'\'\)~' => ' function assertIsObject($actual, string $message = \'\'): void',
|
||||
'~ function assertIsString\(\$actual, \$message = \'\'\)~' => ' function assertIsString($actual, string $message = \'\'): void',
|
||||
'~ function assertStringContainsString\(\$needle, \$haystack, \$message = \'\'\)~' => ' function assertStringContainsString(string $needle, string $haystack, string $message = \'\'): void',
|
||||
'~ function assertStringNotContainsString\(\$needle, \$haystack, \$message = \'\'\)~' => ' function assertStringNotContainsString(string $needle, string $haystack, string $message = \'\'): void',
|
||||
];
|
||||
$updatedFileContents = preg_replace(
|
||||
array_keys($patternToReplacementMap),
|
||||
array_values($patternToReplacementMap),
|
||||
$fileContents
|
||||
);
|
||||
if (file_put_contents($file->getPathname(), $updatedFileContents) === false) {
|
||||
throw new \RuntimeException('file_put_contents() failed: ' . $file->getPathname());
|
||||
}
|
||||
}
|
||||
}
|
21
tests/phpunit.xml
Normal file
21
tests/phpunit.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
bootstrap="bootstrap.php"
|
||||
colors="true"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="phpseclib Unit Test Suite">
|
||||
<directory>./Unit/</directory>
|
||||
</testsuite>
|
||||
<testsuite name="phpseclib Functional Test Suite">
|
||||
<directory>./Functional/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory>../phpseclib/</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
</phpunit>
|
@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of the phpseclib project.
|
||||
#
|
||||
# (c) Andreas Fischer <bantu@phpbb.com>
|
||||
#
|
||||
# For the full copyright and license information, please view the LICENSE
|
||||
# file that was distributed with this source code.
|
||||
#
|
||||
set -e
|
||||
|
||||
function install_php_extension
|
||||
{
|
||||
cd "$1"
|
||||
phpize
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
echo "extension=$1.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
|
||||
}
|
||||
|
||||
# runkit
|
||||
git clone https://github.com/zenovich/runkit.git
|
||||
install_php_extension 'runkit'
|
@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
export PHPSECLIB_SSH_HOSTNAME='localhost'
|
||||
export PHPSECLIB_SSH_USERNAME='phpseclib'
|
||||
export PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0'
|
||||
export PHPSECLIB_SSH_HOME='/home/phpseclib'
|
||||
|
||||
if [ "$TRAVIS_PHP_VERSION" = '5.2' ]
|
||||
then
|
||||
PHPUNIT="phpunit"
|
||||
else
|
||||
PHPUNIT="$(dirname "$0")/../vendor/bin/phpunit"
|
||||
fi
|
||||
|
||||
PHPUNIT_ARGS='--verbose'
|
||||
if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.4', '<');"` = "1" ]
|
||||
then
|
||||
PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0"
|
||||
fi
|
||||
|
||||
if $PHPUNIT --atleast-version 9
|
||||
then
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUpBeforeClass()/n setUpBeforeClass(): void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUp()/n setUp(): void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n tearDown()/n tearDown(): void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsArray([^)]*)\)/\1: void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsString([^)]*)\)/\1: void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsResource([^)]*)\)/\1: void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsObject([^)]*)\)/\1: void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringContainsString([^)]*)\)/\1: void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringNotContainsString([^)]*)\)/\1: void/g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_Crypt_\(AES\|DSA\|EC\|RSA\)_/class /g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_File_\(X509\)_/class /g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_Math_\(BigInteger\)_/class /g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_\(Crypt\|File\|Math\|Net\)_/class /g'
|
||||
find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Functional_Net_/class /g'
|
||||
fi
|
||||
|
||||
"$PHPUNIT" \
|
||||
$PHPUNIT_ARGS \
|
||||
--coverage-text \
|
||||
--coverage-clover code_coverage/clover.xml \
|
||||
--coverage-html code_coverage/
|
@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
composer self-update --no-interaction
|
||||
composer install --no-interaction
|
||||
if [ "$TRAVIS_PHP_VERSION" = '8.1.0' ]; then
|
||||
composer install --no-interaction --working-dir=build
|
||||
fi
|
@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file is part of the phpseclib project.
|
||||
#
|
||||
# (c) Andreas Fischer <bantu@phpbb.com>
|
||||
#
|
||||
# For the full copyright and license information, please view the LICENSE
|
||||
# file that was distributed with this source code.
|
||||
#
|
||||
set -e
|
||||
set -x
|
||||
|
||||
USERNAME='phpseclib'
|
||||
PASSWORD='EePoov8po1aethu2kied1ne0'
|
||||
|
||||
# Create phpseclib user and home directory
|
||||
sudo useradd --create-home --base-dir /home "$USERNAME"
|
||||
|
||||
# Set phpseclib user password
|
||||
echo "$USERNAME:$PASSWORD" | sudo chpasswd
|
||||
|
||||
# Create a 1024 bit RSA SSH key pair without passphrase for the travis user
|
||||
ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N ""
|
||||
|
||||
# Add the generated private key to SSH agent of travis user
|
||||
ssh-add "$HOME/.ssh/id_rsa"
|
||||
|
||||
# Allow the private key of the travis user to log in as phpseclib user
|
||||
sudo mkdir -p "/home/$USERNAME/.ssh/"
|
||||
sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$USERNAME/.ssh/authorized_keys"
|
||||
sudo ssh-keyscan -t rsa localhost > "/tmp/known_hosts"
|
||||
sudo cp "/tmp/known_hosts" "/home/$USERNAME/.ssh/known_hosts"
|
||||
sudo chown "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh/" -R
|
Loading…
Reference in New Issue
Block a user