Create a common process_auth_form() wrapper function

This will be used to show/hide options based on the authgroup setting.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
auth: Remove outdated comment for parse_auth_choice()

We do offer <select> choices to the user (and have for some time).

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
auth: Introduce free_opt() helper function

This frees the name/label/value (as appropriate) and fixes a potential
leak in parse_auth_choice().

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
library: Change oc_form_opt_select->choices to a pointer array

This will allow the library to store internal data at the end of each
oc_choice struct, and potentially at the end of the oc_form_opt_select
struct as well.

This change breaks the public API.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
auth: Provide information on which auth choice is currently selected

In XML POST mode, the gateway keeps track of which authgroup is selected.
Provide this information to the UI so that the interface can be rendered
correctly.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
process_auth_form: Add code to support NEWGROUP return status from UI

In order to support refreshing the <opaque> data (XML POST) or the
secondary_* fields (non XML POST) on the auth form, it is necessary for
the process_auth_form() callback to return to libopenconnect to refresh
the form fields whenever the user changes the value of a <select>
dropdown.

This change should not break existing implementations.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
auth: Parse second-auth-related properties from the auth form

Add new fields/flags to the oc_form_opt and oc_choice structs.

Note that it isn't possible to add private fields at the end of
oc_form_opt, because the layout of oc_form_opt_select depends on the
length of oc_form_opt.  So we will add a publicly visible flags
field (which also supports internal flags) and reserve space for future
expansion.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
auth: Hide unused form fields based on the selected authgroup

Non-aggregate-auth servers have limited support for customizing the login
form based on which authgroup is currently selected.  Flag the appropriate
fields as OC_FORM_OPT_IGNORE based on these attributes:

  <input second-auth="1"> (for text/password fields)

  <option                 (for authgroup options)
          second-auth="1"
          secondary_username="foo"
          secondary_username_editable="true"
          noaaa="1" >

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
main: Avoid infinite "303 See Other" loops on certificate-only authgroups

Since we are now caching the authgroup selection, it is possible to
receive a form from the server that skips all user prompts.  If the
selected authgroup is set up for certificate auth only (no l/p) and the
client certificate is not valid, the server will render a new form which
shows only the authgroup dropdown.  Since our CLI caches this response,
we need to make sure it doesn't keep resubmitting the same response over
and over again.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
library: Bump API version to 3.0 and document changes

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Unconditionally redirect CSD stdout to stderr

CSD output breaks --cookieonly, so let's make a rule that
openconnect_obtain_cookie() will never print to stdout.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
dtls: Don't send packets to a dead socket during rekeying

vpninfo->{dtls_fd,dtls_ssl} are typically invalid when dtls_restart()
returns, as the new handshake has not completed at that point.  Under some
circumstances, FD_CLR() may be called on a negative fd, resulting in a
crash:

    (gdb) bt
    #0  0x00007f749201df77 in __GI_raise (sig=sig@entry=6)
        at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
    #1  0x00007f74920215e8 in __GI_abort () at abort.c:90
    #2  0x00007f749205b4fb in __libc_message (do_abort=do_abort@entry=2,
        fmt=fmt@entry=0x7f749216cf10 "*** %s ***: %s terminated\n")
        at ../sysdeps/unix/sysv/linux/libc_fatal.c:199
    #3  0x00007f74920f908c in __GI___fortify_fail (msg=<optimized out>,
        msg@entry=0x7f749216cea7 "buffer overflow detected") at fortify_fail.c:37
    #4  0x00007f74920f8020 in __GI___chk_fail () at chk_fail.c:28
    #5  0x00007f74920f8fd7 in __fdelt_chk (d=<optimized out>) at fdelt_chk.c:25
    #6  0x00007f749388b86c in ?? ()
    #7  0x00007f749388e271 in ?? ()
    #8  0x00007f74938883a2 in ?? ()
    #9  0x00007f7492008de5 in __libc_start_main (main=0x7f7493887010, argc=5,
        ubp_av=0x7fff01f1fe98, init=<optimized out>, fini=<optimized out>,
        rtld_fini=<optimized out>, stack_end=0x7fff01f1fe88) at libc-start.c:260
    #10 0x00007f74938885e3 in ?? ()

So we should return back to the mainloop instead of trying to send out
queued packets over DTLS.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
main: --cookie-on-stdin doesn't work with ocserv cookies

ocserv's cookie strings are typically much longer (512 characters) than
the cookies generated by a Cisco ASA (<100 characters).  So when
network-manager-openconnect tries to connect to ocserv, the connection
will abruptly drop, and this will show up in syslog:

    NetworkManager[717]: <info> VPN plugin state changed: starting (3)
    NetworkManager[717]: <info> VPN connection 'ocserv' (Connect) reply received.
    openconnect[23054]: Attempting to connect to server 192.168.0.1:443
    openconnect[23054]: SSL negotiation with 192.168.0.1
    openconnect[23054]: Connected to HTTPS on 192.168.0.1
    openconnect[23054]: VPN service unavailable; reason: <unknown>

Quick fix is to allow up to 1024 bytes + NUL termination for the cookie
string.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
ssl: Set FD_CLOEXEC on all sockets

It was recently discovered that open CSTP sockets were being inherited
by the tunnel script.  Use FD_CLOEXEC so this no longer happens.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
www: Fix quoting in v5.01 changelog

Using "&lt;" instead of "&amp;lt", the entry renders as "Attempt to
handle in aggregate auth mode."  Which does not make any sense.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
www: Update changelog

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
gnutls: Remove unused local variable

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Introduce new helper functions for cancel_fd checking

The same code shows up in 12 places, so we'll move it into a common
location.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
library: Rename cancel_fd to cmd_fd

Applications which use libopenconnect may need to interrupt the mainloop
for a couple of reasons:

 - Cancel/disconnect
 - Force reconnect: in case the IP configuration changed
 - Retrieving bytecounts or other internal information

The cancel_fd mechanism provides a convenient way to send these commands,
but first we need to make it more generic (while preserving backward
compatibility).

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
library: Add new openconnect_setup_cmd_pipe() call

Most callers will use a simple nonblocking UNIX pipe as their cmd_fd,
so provide a convenience function for creating it.  Also, libopenconnect
will take care of cleaning up pipes created in this manner when the
library instance is freed.

Pipes created through this function will be able to send new commands,
such as "reconnect".  Pipes passed in via openconnect_set_cancel_fd()
can only be used to cancel the connection, for backward compatibility.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>