blob: a26b6eea16d406558b9cb117a33a504048e33dbe [file] [log] [blame] [view]
## Configuration/data files parsing support
Most of the configuration data files parsing support resides in the _sshd-common_ artfiact:
```xml
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-common</artifactId>
<version>...same version as the rest of the artifacts...</version>
</dependency>
```
The code contains support for parsing the [_authorized_keys_](http://man.openbsd.org/sshd.8#AUTHORIZED_KEYS_FILE_FORMAT),
[_known\_hosts_](http://www.manpagez.com/man/8/sshd/), [_ssh\_config_, _sshd\_config_](https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5),
and [_~/config_](http://www.gsp.com/cgi-bin/man.cgi?topic=ssh_config) files. The code resides in the _sshd-common_ artifact - specifically
the `KeyUtils#getPublicKeyEntryDecoder`, `AuthorizedKeyEntry#readAuthorizedKeys`, `KnownHostEntry#readKnownHostEntries`
and `HostConfigEntry#readHostConfigEntries`.
### PEM/OpenSSH
The common code contains built-in support for parsing PEM and/or _OpenSSH_ formatted key files and using them for authentication purposes.
As mentioned previously, it can leverage _Bouncy Castle_ if available, but can do most of the work without it as well. For _ed25519_ support,
one must provide either `net.i2p.crypto.eddsa` or _Bouncy Castle_ as a dependency; if both are present `net.i2p.crypto.eddsa` is used.
### [PUTTY](https://www.putty.org/)
The code contains built-in support for parsing PUTTY key files (usually _.ppk_) and using them same as SSH ones as key-pair
providers for autentication purposes. The PUTTY key file(s) readers are contained in the `org.apache.sshd.common.config.keys.loader.putty`
package (specifically `PuttyKeyUtils#DEFAULT_INSTANCE KeyPairResourceParser`) of the _sshd-putty_ artifact. **Note:** the artifact should
be included as an extra dependency:
```xml
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-putty</artifactId>
<version>...same version as the rest of the artifacts...</version>
</dependency>
```
### [OpenPGP](https://www.openpgp.org/)
The code contains the _sshd-openpgp_ module that enables using _OpenPGP_ private key files as identity providers.
```xml
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-openpgp</artifactId>
<version>...same version as the rest of the artifacts...</version>
</dependency>
```
The [support](https://issues.apache.org/jira/browse/SSHD-757) for it is currently still in its infancy, and therefore
this feature should be considered **experimental** for the time being. However, within its limitations it supports
* RSA keys
* DSA keys
* ECDSA keys
(*) For now `ed25519` keys are not supported by this module.
The code reads **all** the available key pairs in the key file without any distinction between encryption, decryption,
authentication or signature ones.
This code relies on the [jpgpj](https://github.com/justinludwig/jpgpj) support module
```xml
<dependency>
<groupId>org.c02e.jpgpj</groupId>
<artifactId>jpgpj</artifactId>
<version>...</version>
</dependency>
```
(which in turn automatically uses _Bouncycastle_ - so if one does not want _Bouncycastle_ one cannot use this module).
#### Using OpenPGP authorized keys entries
In order to be able to read `authorized_keys` files that may contain _OpenPGP_ keys references, one needs to register
the relevant `PublicKeyEntryDataResolver`-s. This is done by calling `PGPPublicKeyEntryDataResolver#registerDefaultKeyEntryDataResolvers`
once during the _main_ code setup. This will enable the code to safely read authorized keys entries having the format
specified in the [OpenSSH PGP configuration](https://www.red-bean.com/~nemo/openssh-gpg/):
```
pgp-sign-dss 87C36E60187451050A4F26B134824FC95C781A18 with-comment
pgp-sign-rsa 87C36E60187451050A4F26B134824FC95C781A18
```
Where the key data following the key type specification is the fingerprint value of the referenced key. In order to
use a "mixed mode" file (i.e., one that has both SSH and _OpenPGP_ keys) one needs to replace the default `AuthorizedKeysAuthenticator`
instance with one that is derived from it and overrides the `createDelegateAuthenticator` method in a manner similar
as shown below:
```java
// Using PGPAuthorizedEntriesTracker
public class MyAuthorizedKeysAuthenticatorWithBothPGPAndSsh extends AuthorizedKeysAuthenticator {
... constructor(s) ...
@Override
protected PublickeyAuthenticator createDelegateAuthenticator(
String username, ServerSession session, Path path,
Collection<AuthorizedKeyEntry> entries, PublicKeyEntryResolver fallbackResolver)
throws IOException, GeneralSecurityException {
PGPAuthorizedEntriesTracker tracker = ... obtain an instance ...
// Note: need to catch the PGPException and transform it into either an IOException or a GeneralSecurityException
Collection<PublicKey> keys = tracker.resolveAuthorizedEntries(session, entries, fallbackResolver);
if (GenericUtils.isEmpty(keys)) {
return RejectAllPublickeyAuthenticator.INSTANCE;
} else {
return new KeySetPublickeyAuthenticator(id, keys);
}
}
}
// Using PGPPublicRingWatcher
public class MyAuthorizedKeysAuthenticatorWithBothPGPAndSsh extends AuthorizedKeysAuthenticator {
... constructor(s) ...
@Override
protected PublickeyAuthenticator createDelegateAuthenticator(
String username, ServerSession session, Path path,
Collection<AuthorizedKeyEntry> entries, PublicKeyEntryResolver fallbackResolver)
throws IOException, GeneralSecurityException {
PGPPublicRingWatcher watcher = ... obtain an instance ...
// Note: need to catch the PGPException and transform it into either an IOException or a GeneralSecurityException
Collection<PublicKey> keys = watcher.resolveAuthorizedEntries(session, entries, fallbackResolver);
if (GenericUtils.isEmpty(keys)) {
return RejectAllPublickeyAuthenticator.INSTANCE;
} else {
return new KeySetPublickeyAuthenticator(id, keys);
}
}
}
```
**Note:** in order to support GPG v2 `.kbx` files one requires up-to-date [Bouncycastle](https://mvnrepository.com/artifact/org.bouncycastle/bcpg-jdk15on/1.61)
and [jpgpj](https://mvnrepository.com/artifact/org.c02e.jpgpj/jpgpj/0.6.1) versions.