SSL and TLS both provide encryption and certification. (Actually, TLS is just the latest version of SSL. From now on, I'll call it TLS.) Most of my description ignores the certification aspects.
This page is long because there are severals ways to enable TLS. But most of these are only of historical interest. Most people should find the following instructions (Recommended Approach) to be the best and easiest approach.
First, install TLS support for Tcl. To do that, go to tls.sourceforge.net, click on File Distributions and select the appropriate distribution for your system.
For example, on a Windows box, (as I type this) I see a distribution labelled tls1.5.0-win32.zip. Click on that, select a nearby mirror site from which to download and you should get a prompt to open or save the file. Open it and you should get a prompt to extract the files. Extract them to C:\Tcl\lib (or wherever you put your Tcl distribution).
Now edit your personal tkbiff configuration file and define:
set protocol(connectinit) "package require tls"
set protocol(connect) "tls::socket -async $protocol(host) $protocol(port)"
You can hardcode the host and port here in the connect specification or you can do it in the command-line or elsewhere in the configuration file.
That's it. You should be able to use tkbiff with secure ports now.
For historical purposes, here are some other approaches to TLS. In these approaches, you will need a package such as OpenSSL or SSLeay.
| OpenSSL | http://www.openssl.org |
| SSLeay | http://www.psy.uq.oz.au/~ftp/Crypto |
There are other TLS implementations, but at the time I wrote this, I only had experience with SSLeay so that's what appears in these examples.
In this approach, you'll use a TLS extension which is just some glue that allows Tcl to use a TLS implementation (e.g., OpenSSL).
As I write this, there are three TLS extensions for Tcl. tkbiff can use any of these extensions. In the examples, I'll use Matt Newman's tls extension since that is the best of them. The three Tcl TLS extensions currently available (listed in order of preference) are:
| tls | http://www.sensus.org/tcl/ |
| SSLtcl | http://www.abc.se/%7Em9339/prog/ssl/ |
| tclSSL | http://www.psy.uq.oz.au/%7Eftp/Crypto/ |
If you want to check for additional TLS extensions, try the list of Tcl extensions.
To tell tkbiff about an extension, use the following variables. Each variable must contain Tcl commands. You can define the variable in the tkbiff source itself (for system-wide defaults) or you can just put them in your personal configuration file.
protocol(connectinit)
protocol(connectpre)
protocol(connect)
protocol(connectpost)
protocol(starttls)
If you're on UNIX, defaults for the variables can be set at configure time by using the following flags:
--enable-connectinit=...
--enable-connectpre=...
--enable-connect=...
--enable-connectpost=...
--enable-starttls=...
These can also be set via command-line flags.
protocol(connectinit) is executed once before any connections have been made. For example, it could be used to load and initialize the tls extension as follows:
set protocol(connectinit) {
package require tls
tls::init -cadir ... -certfile ...
}
Assuming the server supports the STARTTLS command, TLS can be started after an insecure connection has been established. To have tkbiff dynamically enable TLS, define protocol(starttls) to start TLS. The open connection may be referenced in protocol(starttls) using $f. For example:
set protocol(starttls) {tls::import $f}Assuming there is no way of dynamically enabling TLS, it may be initialized at the outset of the connection, i.e., so that the client and server are using TLS immediately.
protocol(connectpre) is evaluated before each connection is established. protocol(connectpost) is evaluated immediately after each connection is established. tkbiff stores the connection handle in the variable f. Thus, the socket may be referenced in protocol(connectpost) using $f.
protocol(connect) is evaluated to establish the connection. It must return a Tcl channel (typically a socket). The default definition for protocol(connect) is:
set protocol(connect) {
socket -async $protocol(host) $protocol(port)
}
protocol(host) is predefined to contain the name of the mail host. protocol(port) is predefined to contain the IMAP or POP port.
For example, to have the tls extension require a valid certificate from the server, the -require flag must be added:
set protocol(connect) {
socket -async -require 1 $protocol(host) $protocol(port)
}
Here is pseudocode of tkbiff showing how these variables are used internally:
eval $protocol(connectinit)
while {1} {
eval $protocol(connectpre)
set f [eval $protocol(connect)]
eval $protocol(connectpost)
gets $f ...
puts $f ...
# and so on
close $f
sleep awhile
}
In this approach, tkbiff will communicate with a TLS client running in a separate process. No extension is needed.
First you need a TLS client. A TLS client is software that talks cleartext out of one side and TLS out the other. You can find such clients in SSLeay and OpenSSL. From now on, I'll just refer to a TLS client as s_client. (Happily, this is exactly what SSLeay and OpenSSL call it.)
There are two ways to implement this approach:
SSLeay and OpenSSL run on UNIX and Windows but I've no experience with running them on Windows, so I'll only explain how to run them on UNIX. (You can still use tkbiff on MacOS or Windows in this arrangement, as I'll explain.)
Read your system's inetd.conf manual page (or a sysadmin book) for info on installing a deamon this way. At some point the book will say now add the appropriate line to inetd.conf. The appropriate line refers to something like this:
imap stream tcp nowait tkbiff /etc/imapssld
where tkbiff is the name of some user that can access your TLS certificates, and /etc/imapssld is a shell script that invokes your s_client.
The shell script should look like this:
#!/bin/sh
/usr/local/bin/s_client -connect mail.yourdomain.com:993 -quiet 2> /dev/null
Of course, you'll have to modify it for the correct paths, host names, and certificates. You may also have to add or remove flags such as -ssl2 or -ssl3 for ancient or broken servers (see the s_client docs for more such flags). About the only part that should stay the same is the 993 which points to the IMAP port on the true mailhost which speaks TLS. The corresponding port for POP over TLS is 995.
Tell tkbiff that the name of your mail server is the one where s_client is running. (See step 2b in the INSTALL file.)
Caveat: If you run s_client and tkbiff on different hosts, your password and mail will be in the clear between your workstation and s_client's computer. In some environments, such an approach is entirely unacceptable. In other environments, such as when both are behind a common firewall in a relatively trusted environment, this approach may be fine.
If you are running tkbiff on the same host as s_client, you can have tkbiff invoke s_client directly. This removes the caveat in approach (2a).
On UNIX, use the configure flag:
--enable-connect=...
On all platforms, this can also be set inside tkbiff itself (or the configuration file) by setting:
set protocol(connect) ...
These can also be set via command-line flags.
protocol(connect) is evaluated to establish the connection. protocol(connectpost) is evaluated after the connection is established. (These variables are described in further detail in the previous approach.)
For example, this is what I use (simplified for readability) to make s_client connect to the real mailserver here at NIST:
set protocol(connect) {
open "|s_client -connect mail.nist.gov:993 -ssl2 -quiet 2> /dev/null" w+
}
Last edited: Thu Aug 24 17:59:01 EDT 2006 by Don Libes