.TH ssh_file 3erl "ssh 4.15.3.4" "Ericsson AB" "Erlang Module Definition" .SH NAME ssh_file \- Default callback module for the client's and server's database operations in the ssh application .SH DESCRIPTION .LP This module is the default callback handler for the client\&'s and the server\&'s user and host "database" operations\&. All data, for instance key pairs, are stored in files in the normal file system\&. This page documents the files, where they are stored and configuration options for this callback module\&. .LP The intention is to be compatible with the OpenSSH storage in files\&. Therefore it mimics directories and filenames of OpenSSH\&. .LP Ssh_file implements the ssh_server_key_api and the ssh_client_key_api\&. This enables the user to make an own interface using for example a database handler\&. .LP Such another callback module could be used by setting the option \fIkey_cb\fR\& when starting a client or a server (with for example ssh:connect, ssh:daemon of ssh:shell )\&. .LP .RS -4 .B Note: .RE The functions are \fICallbacks\fR\& for the SSH app\&. They are not intended to be called from the user\&'s code! .SH "FILES, DIRECTORIES AND WHO USES THEM" .SS "Daemons" .LP Daemons uses all files stored in the SYSDIR directory\&. .LP Optionally, in case of \fIpublickey\fR\& authorization, one or more of the remote user\&'s public keys in the USERDIR directory are used\&. See the files \fIUSERDIR/authorized_keys\fR\& and \fIUSERDIR/authorized_keys2\fR\&\&. .SS "Clients" .LP Clients uses all files stored in the USERDIR directory\&. .SS "Directory contents" .RS 2 .TP 2 .B LOCALUSER: The user name of the OS process running the Erlang virtual machine (emulator)\&. .TP 2 .B SYSDIR: This is the directory holding the server\&'s files: .RS 2 .TP 2 * \fIssh_host_dsa_key\fR\& - private dss host key (optional) .LP .TP 2 * \fIssh_host_rsa_key\fR\& - private rsa host key (optional) .LP .TP 2 * \fIssh_host_ecdsa_key\fR\& - private ecdsa host key (optional) .LP .TP 2 * \fIssh_host_ed25519_key\fR\& - private eddsa host key for curve 25519 (optional) .LP .TP 2 * \fIssh_host_ed448_key\fR\& - private eddsa host key for curve 448 (optional) .LP .RE .RS 2 .LP The key files could be generated with OpenSSH\&'s ssh-keygen command\&. .RE .RS 2 .LP At least one host key must be defined\&. The default value of SYSDIR is \fI/etc/ssh\fR\&\&. .RE .RS 2 .LP For security reasons, this directory is normally accessible only to the root user\&. .RE .RS 2 .LP To change the SYSDIR, see the system_dir option\&. .RE .TP 2 .B USERDIR: This is the directory holding the files: .RS 2 .TP 2 * \fIauthorized_keys\fR\& and, as second alternative \fIauthorized_keys2\fR\& - the user\&'s public keys are stored concatenated in one of those files\&. .RS 2 .LP It is composed of lines as for OpenSSH: .RE .LP .nf (options)? keytype base64-encoded-key comment .fi .RS 2 .LP where .RE .LP .nf options :: option(,option)* option :: % All options are skipped keytype :: 'ssh-dsa' | 'ssh-rsa' | 'ssh-ecdsa-nistp256' | 'ssh-ecdsa-nistp384' | 'ssh-ecdsa-nistp521' | 'ssh-ed25519' | 'ssh-ed448' base64-encoded-key :: % The user's public key comment :: % Comments are skipped .fi .LP .TP 2 * \fIknown_hosts\fR\& - host keys from hosts visited concatenated\&. The file is created and used by the client\&. .RS 2 .LP It is composed of lines as for OpenSSH: .RE .LP .nf (option)? pattern(,pattern)* keytype key (comment)? .fi .RS 2 .LP where .RE .LP .nf option :: '@revoked' pattern :: host | '[' host ']:' port host :: ip-address | hostname | '*' port :: portnumber | '*' keytype :: 'ssh-dsa' | 'ssh-rsa' | 'ssh-ecdsa-nistp256' | 'ssh-ecdsa-nistp384' | 'ssh-ecdsa-nistp521' | 'ssh-ed25519' | 'ssh-ed448' key :: % encoded key from eg ssh_host_*.pub .fi .LP .TP 2 * \fIid_dsa\fR\& - private dss user key (optional) .LP .TP 2 * \fIid_rsa\fR\& - private rsa user key (optional) .LP .TP 2 * \fIid_ecdsa\fR\& - private ecdsa user key (optional) .LP .TP 2 * \fIid_ed25519\fR\& - private eddsa user key for curve 25519 (optional) .LP .TP 2 * \fIid_ed448\fR\& - private eddsa user key for curve 448 (optional) .LP .RE .RS 2 .LP The key files could be generated with OpenSSH\&'s ssh-keygen command\&. .RE .RS 2 .LP The default value of USERDIR is \fI/home/\fR\&\fILOCALUSER\fR\&\fI/\&.ssh\fR\&\&. .RE .RS 2 .LP To change the USERDIR, see the user_dir option .RE .RE .SH DATA TYPES .SS Options for the default ssh_file callback module .nf \fBuser_dir_common_option()\fR\& = {user_dir, string()} .br .fi .RS .LP Sets the user directory\&. .RE .nf \fBuser_dir_fun_common_option()\fR\& = {user_dir_fun, user2dir()} .br .fi .nf \fBuser2dir()\fR\& = .br fun((RemoteUserName :: string()) -> UserDir :: string()) .br .fi .RS .LP Sets the user directory dynamically by evaluating the \fIuser2dir\fR\& function\&. .RE .nf \fBsystem_dir_daemon_option()\fR\& = {system_dir, string()} .br .fi .RS .LP Sets the system directory\&. .RE .nf \fBpubkey_passphrase_client_options()\fR\& = .br {dsa_pass_phrase, string()} | .br {rsa_pass_phrase, string()} | .br {ecdsa_pass_phrase, string()} .br .fi .RS .LP If the user\&'s DSA, RSA or ECDSA key is protected by a passphrase, it can be supplied with thoose options\&. .LP Note that EdDSA passhrases (Curves 25519 and 448) are not implemented\&. .RE .nf \fBoptimize_key_lookup()\fR\& = {optimize, time | space} .br .fi .RS .LP Make the handling of large files fast by setting \fItime\fR\&, but this will use more memory\&. The \fIspace\fR\& variant shrinks the memory requirements, but with a higher time consumption\&. .LP To set it, set the option \fI{key_cb, {ssh_file, [{optimize,TimeOrSpace}]}\fR\& in the call of "ssh:connect/3, ssh:daemon/2 or similar function call that initiates an ssh connection\&. .RE .nf \fBkey()\fR\& = public_key:public_key() | public_key:private_key() .br .fi .RS .LP The key representation .RE .nf \fBexperimental_openssh_key_v1()\fR\& = .br [{key(), openssh_key_v1_attributes()}] .br .fi .nf \fBopenssh_key_v1_attributes()\fR\& = [{atom(), term()}] .br .fi .RS .LP Types for the experimental implementaition of the \fIopenssh_key_v1\fR\& format\&. .RE .SH EXPORTS .LP .nf .B host_key(Algorithm, Options) -> Result .br .fi .br .RS .LP Types: .RS 3 Algorithm = ssh:pubkey_alg() .br Result = {ok, public_key:private_key()} | {error, term()} .br Options = ssh_server_key_api:daemon_key_cb_options(none()) .br .RE .RE .RS .LP \fBTypes and description\fR\& .LP See the api description in ssh_server_key_api, Module:host_key/2\&. .LP \fBOptions\fR\& .RS 2 .TP 2 * system_dir .LP .RE .LP \fBFiles\fR\& .RS 2 .TP 2 * \fISYSDIR/ssh_host_rsa_key\fR\& .LP .TP 2 * \fISYSDIR/ssh_host_dsa_key\fR\& .LP .TP 2 * \fISYSDIR/ssh_host_ecdsa_key\fR\& .LP .TP 2 * \fISYSDIR/ssh_host_ed25519_key\fR\& .LP .TP 2 * \fISYSDIR/ssh_host_ed448_key\fR\& .LP .RE .RE .LP .nf .B is_auth_key(Key, User, Options) -> boolean() .br .fi .br .RS .LP Types: .RS 3 Key = public_key:public_key() .br User = string() .br Options = .br ssh_server_key_api:daemon_key_cb_options(optimize_key_lookup()) .br .RE .RE .RS .LP \fBTypes and description\fR\& .LP See the api description in ssh_server_key_api: Module:is_auth_key/3\&. .LP \fBOptions\fR\& .RS 2 .TP 2 * user_dir_fun .LP .TP 2 * user_dir .LP .RE .LP \fBFiles\fR\& .RS 2 .TP 2 * \fIUSERDIR/authorized_keys\fR\& .LP .TP 2 * \fIUSERDIR/authorized_keys2\fR\& .LP .RE .LP This functions discards all options in the beginning of the lines of thoose files when reading them\&. .RE .LP .nf .B add_host_key(Host, Port, Key, Options) -> Result .br .fi .br .RS .LP Types: .RS 3 Host = .br inet:ip_address() | .br inet:hostname() | .br [inet:ip_address() | inet:hostname()] .br Port = inet:port_number() .br Key = public_key:public_key() .br Options = ssh_client_key_api:client_key_cb_options(none()) .br Result = ok | {error, term()} .br .RE .RE .RS .LP \fBTypes and description\fR\& .LP See the api description in ssh_client_key_api, Module:add_host_key/4\&. .LP Note that the alternative, the old Module:add_host_key/3 is no longer supported by \fIssh_file\fR\&\&. .LP \fBOption\fR\& .RS 2 .TP 2 * user_dir .LP .RE .LP \fBFile\fR\& .RS 2 .TP 2 * \fIUSERDIR/known_hosts\fR\& .LP .RE .RE .LP .nf .B is_host_key(Key, Host, Port, Algorithm, Options) -> Result .br .fi .br .RS .LP Types: .RS 3 Key = public_key:public_key() .br Host = .br inet:ip_address() | .br inet:hostname() | .br [inet:ip_address() | inet:hostname()] .br Port = inet:port_number() .br Algorithm = ssh:pubkey_alg() .br Options = .br ssh_client_key_api:client_key_cb_options(optimize_key_lookup()) .br Result = boolean() | {error, term()} .br .RE .RE .RS .LP \fBTypes and description\fR\& .LP See the api description in ssh_client_key_api, Module:is_host_key/5\&. .LP Note that the alternative, the old Module:is_host_key/4 is no longer supported by \fIssh_file\fR\&\&. .LP \fBOption\fR\& .RS 2 .TP 2 * user_dir .LP .RE .LP \fBFile\fR\& .RS 2 .TP 2 * \fIUSERDIR/known_hosts\fR\& .LP .RE .RE .LP .nf .B user_key(Algorithm, Options) -> Result .br .fi .br .RS .LP Types: .RS 3 Algorithm = ssh:pubkey_alg() .br Result = {ok, public_key:private_key()} | {error, string()} .br Options = ssh_client_key_api:client_key_cb_options(none()) .br .RE .RE .RS .LP \fBTypes and description\fR\& .LP See the api description in ssh_client_key_api, Module:user_key/2\&. .LP \fBOptions\fR\& .RS 2 .TP 2 * user_dir .LP .TP 2 * dsa_pass_phrase .LP .TP 2 * rsa_pass_phrase .LP .TP 2 * ecdsa_pass_phrase .LP .RE .LP Note that EdDSA passhrases (Curves 25519 and 448) are not implemented\&. .LP \fBFiles\fR\& .RS 2 .TP 2 * \fIUSERDIR/id_dsa\fR\& .LP .TP 2 * \fIUSERDIR/id_rsa\fR\& .LP .TP 2 * \fIUSERDIR/id_ecdsa\fR\& .LP .TP 2 * \fIUSERDIR/id_ed25519\fR\& .LP .TP 2 * \fIUSERDIR/id_ed448\fR\& .LP .RE .RE .LP .nf .B decode(SshBin, Type) -> Decoded | {error, term()} .br .fi .br .RS .LP Types: .RS 3 SshBin = binary() .br Type = .br ssh2_pubkey | public_key | openssh_key | rfc4716_key | .br openssh_key_v1 | known_hosts | auth_keys .br Decoded = .br Decoded_ssh2_pubkey | Decoded_public | Decoded_openssh | .br Decoded_rfc4716 | Decoded_openssh_key_v1 | .br Decoded_known_hosts | Decoded_auth_keys .br Decoded_ssh2_pubkey = public_key:public_key() .br Decoded_public = .br Decoded_rfc4716 | Decoded_openssh_key_v1 | Decoded_openssh .br Decoded_openssh = .br [{public_key:public_key(), [{comment, string()}]}] .br Decoded_rfc4716 = [{key(), [{headers, Attrs}]}] .br Decoded_openssh_key_v1 = experimental_openssh_key_v1() .br Decoded_known_hosts = .br [{public_key:public_key(), .br [{comment, string()} | {hostnames, [string()]}]}] .br Decoded_auth_keys = .br [{public_key:public_key(), .br [{comment, string()} | {options, [string()]}]}] .br Attrs = {Key :: string(), Value :: string()} .br .RE .RE .RS .LP Decodes an SSH file-binary\&. .LP If \fIType\fR\& is \fIpublic_key\fR\& the binary can be either an RFC4716 public key or an OpenSSH public key\&. .LP .RS -4 .B Note: .RE The following key types have been renamed from the deprecated \fIpublic_key:ssh_decode/2\fR\&: .RS 2 .TP 2 * rfc4716_public_key -> rfc4716_key .LP .TP 2 * openssh_public_key -> openssh_key .LP .RE .LP .RS -4 .B Note: .RE The implementation of the \fIopenssh_key_v1\fR\& format is still experimental\&. .RE .LP .nf .B encode(InData, Type) -> binary() | {error, term()} .br .fi .br .RS .LP Types: .RS 3 Type = .br ssh2_pubkey | openssh_key | rfc4716_key | openssh_key_v1 | .br known_hosts | auth_keys .br InData = .br InData_ssh2_pubkey | InData_openssh | InData_rfc4716 | .br InData_openssh_key_v1 | InData_known_hosts | InData_auth_keys .br InData_ssh2_pubkey = public_key:public_key() .br InData_openssh = .br [{public_key:public_key(), [{comment, string()}]}] .br InData_rfc4716 = [{key(), [{headers, Attrs}]}] .br InData_openssh_key_v1 = experimental_openssh_key_v1() .br InData_known_hosts = .br [{public_key:public_key(), .br [{comment, string()} | {hostnames, [string()]}]}] .br InData_auth_keys = .br [{public_key:public_key(), .br [{comment, string()} | {options, [string()]}]}] .br Attrs = {Key :: string(), Value :: string()} .br .RE .RE .RS .LP Encodes a list of SSH file entries (public keys and attributes) to a binary\&. .LP .RS -4 .B Note: .RE The following key types have been renamed from the removed \fIpublic_key:ssh_encode/2\fR\&: .RS 2 .TP 2 * rfc4716_public_key -> rfc4716_key .LP .TP 2 * openssh_public_key -> openssh_key .LP .RE .LP .RS -4 .B Note: .RE The implementation of the \fIopenssh_key_v1\fR\& format is still experimental\&. .RE .LP .nf .B extract_public_key(PrivKey) -> PubKey .br .fi .br .RS .LP Types: .RS 3 PrivKey = public_key:private_key() .br PubKey = public_key:public_key() .br .RE .RE .RS .LP Fetches the public key from a private key\&. .RE