sslfd - routines useful for SSL servers and clients
This library provides routines that encapsulate much of the logic needed by applications using Eric Young's SSLeay library.
A server (such as SSLrshd) typically needs to call:
ssld_init(cert_file, key_file, cipher_list, verify_flag, init_flags);
and clients (such as SSLrsh) call:
sslc_init(cert_file, key_file, cipher_list, verify_flag, init_flags);
Both the above simply interface to
ssl_init(cert_file, key_file, cipher_list, verify_flag, verify_cb, log_lev, init_flags):
and provide appropriate callback and log_lev arguments. Each end must call one of:
ssl_start(sock, log_lev,
active)
ssl_start_cb(sock, log_lev, active, verify_cb, verify_flag)
with one side using active = 1 and the other active = 0. The end with active = 0 will call SSL_accept() and must always provide a certificate. For applications where client to server authentication is most important, it makes sense to reverse the accept/connect roles at the SSL level.
If bit 2 in init_flags is set, then the key_file will not be read until ssl_start() is called, it is often useful for clients that want to defer prompting the user for a pass phrase until it is known that the key is likely to be used.
The client can call ssl_start() via:
ssl_rcmd(ahost, rport, locuser, remuser, cmd, fd2p);
which is analgous to rcmd(3), though reserved ports are not used. If rport is -1, then the routine will lookup ``sshell/tcp'' for itself.
The server for ssl_rcmd() is SSLrshd. If the client's certificate is valid, it calls:
ssld_auth(socket, remuser, locuser)
which determines the remote hostname. If the connection came from the loopback address, then gethostname(2) is used otherwise getpeername(2). Normally, hostname is only used for logging purposes. ssld_auth() then calls get_x509_name(0, 0) to extract the common name (/CN) field from the client's certificate. If the name contains any ``.'' it is looked up via gethostbyname(2) and if found, the certificate is assumed to be a host cert. In this case hostname is important, and we attempt to qualify it by calling gethostbyname(2) and checking that the calling address is listed. If all goes well, the name found via the DNS must match the name in the certificate or permission is denied.
If not already rejected, ssld_auth() calls:
To lookup ssl_auth_cert in the /etc/ssl.users file. If the certificate is found and either locuser or root is listed as a valid target user, permission is granted, otherwise it is denied.
Command line options compatible with Tim Hudson's SSLtelnet and SSLftp, can be processed by simply calling:
where optarg is one of:
Applications which need multiple SSL channels can use one of
ssl_clone(sock, old, log_lev,
active)
ssl_clone_cb(sock, old, log_lev, active, verify_cb,
verify_flag)
to establish an SSL session on sock using information cloned from the SSL session previously established on socket old (via a call to ssl_start()).
Applications that want certain actions to be performed when close(), read() or write() are called, can register a hook function for a descriptor by calling:
set_hook(fd, flags, fp)
The flags is a combination of:
The fp should be a pointer to a function that takes the same args as close(2), read(2) or write(2) (as appropriate) except that the read and write hooks will be passed an additional arg flags as used by recv(2), send(2), and should return the number of bytes in the buffer. If the function needs to modify the content of the buffer such that the content will increase, then is should take a u_char ** for the buffer arg and use the HK_INDIRECT flag when calling set_hook().
The current version of SSLeay can be obtained from: ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.xx.tar.gz
The SSLeay FAQ by Tim Hudson <tjh@mincom.oz.au> can be found at http://www.psy.uq.oz.au/~ftp/Crypto
Tim Hudson also maintains SSL patches for several applications. The logic for the certificate permission checks using /etc/ssl.users in ssld_auth() is borrowed from Tim's verify callback routine from SSLtelnet.
Simon J. Gerraty <sjg@crufty.net>