David Woodhouse [Tue, 5 Jun 2012 00:15:10 +0000 (01:15 +0100)]
Fix config_arg handling
The ->cert_password field must always be allocated, and it turns out I never
did fix the keep_config_arg() macro to do the right thing for options from
a file, despite deliberately introducing it for precisely that purpose.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Fri, 1 Jun 2012 18:58:26 +0000 (19:58 +0100)]
Fix FreeBSD tun handling with net.link.tun.devfs_cloning=0
Try to use SIOCIFCREATE to create an interface if it doesn't already exists.
Also try opening /dev/tun to get the next available device, before falling
back to the loop over tun0-tun255.
There is still strangeness here; sometimes the interface doesn't get an
IPv6 link-local address, and the IFDISABLED flag remains set.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Thu, 31 May 2012 15:20:14 +0000 (16:20 +0100)]
Make GnuTLS parse_pkcs12() return extra certificates from the PKCS#12 too
Create a separate list, return them for the caller to do with as it sees fit.
This also cleans up the error handling a little. When this was a purely
internal GnuTLS function, it was fine to leave things (like *key) allocated
and return an error. If my intention is to make this exportable, then it
ought to clean up after itself when returning an error.
I think this actually fixes a potential memory leak for the GnuTLS internal
caller of this function, too.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Thu, 31 May 2012 14:07:31 +0000 (15:07 +0100)]
Import pkcs12_parse() function from GnuTLS to fix PKCS#12 handling
An immediate effect is that this fixes the checking of cert expiry for
PKCS#12 certificates.
But it also means we can include the full supporting chain of
intermediate CAs (which has to be pre-assembled before we ever call
gnutls_certificate_set_x509_key() and can't be appended later), and we
can use the extra certs from the PKCS#12 file too, which parse_pkcs12()
currently doesn't bother to give us.
The plan is to fix parse_pkcs12(), submit the changes back upstream and
make it an exported function there, then stick a version-conditional on
our local copy and look forward to the day when we can rip it out again.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Thu, 31 May 2012 12:43:56 +0000 (13:43 +0100)]
Add server certificate validation for GnuTLS
It's broken with trust chains at the moment, at least with GnuTLS
2.12.x, because it looks up issuer certs by *name* and then when it
picks the wrong one the signature unsurprisingly fails. And then it
returns GNUTLS_CERT_INVALID without any specific *reason* for the
failure, which is even more joyful. At least with OpenSSL I can get a
reason string out of it.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Wed, 30 May 2012 22:47:27 +0000 (23:47 +0100)]
Add client certificate support for GnuTLS
Argh. Why is there not just a function I can call to do this all *for* me?
249 lines of code for this one, which is more than the OpenSSL one I ranted
about at http://www.advogato.org/person/dwmw2/diary/205.html
Oh well, at least the password handling is *slightly* more consistent, if
not entirely so.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Wed, 30 May 2012 16:42:08 +0000 (17:42 +0100)]
Improve GnuTLS compatibility options
TLSv1.0, no safe renegotiation, no padding.
For some reason, large amounts of padding are causing the Intel servers to
kick me off — although gnutls-cli is allowed to use large amounts of padding
with getting disconnected, and I can't see *why* there's a difference.
So there's something else odd going on here, and disabling padding is just
a workaround. I bet I forget about this, and I bet it comes back to bite
me one day. And it'll serve me right for being lazy and not following it
up properly right now. But still, there's plenty more GnuTLS porting work
to be done and I've spent long enough staring at packet traces already
today.
Disable safe renegotiation because we've previously observed that some
servers are behind crappy firewalls that'll block *any* extension.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Wed, 30 May 2012 00:22:16 +0000 (01:22 +0100)]
Make CSTP connection in a single SSL record
By creating a buffer with the request and sending it in a single SSL record,
I roughly halve the amount of time it takes for the round trip from 215ms
to 116ms.
Introduce a buf_append() function to help with processing the buffer, since
I shouldn't just be using sprintf() like other places do. Will fix those
next...
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Tue, 29 May 2012 22:53:38 +0000 (23:53 +0100)]
Add barely functional GnuTLS support
It has no DTLS, doesn't do any server certificate validation, doesn't
support client certificates and there are odd bugs with it even in the
bits that *are* implemented. But we're getting there...
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Tue, 29 May 2012 15:41:35 +0000 (16:41 +0100)]
Introduce semi-opaque OPENCONNECT_X509 type in library API
We offer functions to do everything that a user might want to do with the
cert, including one that returns it in DER form. The *only* reason this
isn't a completely opaque type is backward-compatibility.
When we change the soname, it'll be opaque. For now, let it actually be
an X509* for OpenSSL or a gnutls_x509_crt_t for GnuTLS.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Tue, 29 May 2012 11:55:55 +0000 (12:55 +0100)]
Add openconnect_get_cert_details() function
Another aspect of the certificate handling becomes ssl-library-agnostic.
This is marked OPENCONNECT_PRIVATE for now. It probably *won't* be private,
but there are other changes to come and probably an soname bump, so there's
no point in exporting it for now.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Tue, 29 May 2012 11:33:08 +0000 (12:33 +0100)]
Move peer_cert handling to openconnect_open_https()
There's no real need to do this in openconnect_obtain_cookie(). It doesn't
really matter if we do it for other connections, since any connections we
make *after* obtaining the cookie will be to the same server anyway.
This moves another OpenSSL-specific snippet out of what should be generic
code.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Mon, 28 May 2012 13:58:36 +0000 (14:58 +0100)]
Make openconnect_open_https() and openconnect_close_https() more forgiving.
If openconnect_open_https() is called with the connection already open,
return immediate success. Thus, the caller doesn't have to poke at
vpninfo->https_ssl to check it.
And if openconnect_close_https() is called when the connection isn't open,
don't attempt to close/free things that don't exist.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Thu, 17 May 2012 15:41:07 +0000 (16:41 +0100)]
Stash peer certificate before fetching HTTP response
If the server closes the connection by giving an HTTP 1.0-style response,
then the SSL connection will be gone by the time the GUI auth dialog calls
openconnect_get_peer_cert(). So remember it in order to give it out later.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Mon, 14 May 2012 03:31:29 +0000 (22:31 -0500)]
Call BIO_set_nbio() for SSL BIO at startup
Oops, this was still in CSTP code where we *used* to make the socket
non-blocking, and now it should be like that from the beginning.
It's not entirely clear what difference it makes; all my testing of the
non-blocking code through authentication and CSTP connection was working
fine in non-blocking mode without it, when all I'd done was set O_NONBLOCK
on the socket.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Mon, 14 May 2012 03:29:30 +0000 (22:29 -0500)]
Clean up BIO_set_nbio() calls for DTLS
It's not necessary to do it twice for the same BIO, and it's not necessary
to get that BIO back from the SSL with SSL_get_[rw]bio() when we already
have it in a local variable.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Now the library namespace is entirely prefixed by openconnect_ with no
inappropriate pollution. At least on platforms where the linker version
scripts work.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Sun, 13 May 2012 17:56:22 +0000 (10:56 -0700)]
Remove internal_parse_url() from the library exports.
The only thing that main.c was really doing differently to the public
openconnect_parse_url() function was allowing 'urlpath' to be superseded
by the --usergroup command line argument. Which we can handle simply
by storing that in a separate variable and applying it afterwards.
The other thing it did differently was check that the scheme is https.
But openconnect_parse_url() arguably should have been doing that anyway.
Fix potential memory leak of old strings in openconnect_parse_url()
while we're at it.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Sun, 13 May 2012 17:31:33 +0000 (10:31 -0700)]
Refuse to redirect to a non-https URL
Not good:
$ ./openconnect www.cam.ac.uk
Attempting to connect to 131.111.8.46:443
SSL negotiation with www.cam.ac.uk
Connected to HTTPS on www.cam.ac.uk
GET https://www.cam.ac.uk/
Got HTTP response: HTTP/1.1 301 Moved Permanently
GET https://www.cam.ac.uk/http://www.cam.ac.uk:80/
Got HTTP response: HTTP/1.1 301 Moved Permanently
GET https://www.cam.ac.uk/http://www.cam.ac.uk:80/http://www.cam.ac.uk:80/
Got HTTP response: HTTP/1.1 301 Moved Permanently
GET https://www.cam.ac.uk/http://www.cam.ac.uk:80/http://www.cam.ac.uk:80/http://www.cam.ac.uk:80/
OK, I asked it to do a stupid thing, but a polite refusal is much better.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Sun, 13 May 2012 16:54:11 +0000 (09:54 -0700)]
Remove duplicate library API version number from Makefile.am
Pick it up from openconnect.h automatically. This means that the
configure script will run, and the makefiles will be regenerated,
whenever openconnect.h changes — but openconnect.h shouldn't be changing
in non-cosmetic ways without the version being bumped anyway, and if the
version is bumped then the makefile needs to be rebuilt too.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Sun, 13 May 2012 16:28:53 +0000 (09:28 -0700)]
Add library.c and compat.c to POTFILES.in for translation
There are no translatable strings in them yet, but I'm never going to
remember to add them if they ever *do* grow strings. So add them now
while I think of it.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Sun, 13 May 2012 03:49:39 +0000 (20:49 -0700)]
Fix corruption of input string to openconnect_parse_url()
Well, kind of. This is the approach which was partially implemented in
commit 382d05dd1929788be151e96d80e7b8289b8f7c08 but missed restoring the
colon before the port number. It's still fairly dodgy that we're scribbling
on the input string at all, even if we do put it back again afterwards.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
David Woodhouse [Sat, 12 May 2012 23:42:40 +0000 (16:42 -0700)]
Export openconnect_version as a pointer rather than an array
Otherwise, the binary seems to *know* the length of the string that it
expected to be in the library, and when bitching of a mismatch it still
truncates the library version to the length that it *expected* the library
version string to be.
Change the name of it to 'openconnect_version_str' at the same time as we
change the datatype, to avoid crashes when linking against an older/newer
library.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>