Make certificate expiry warning time variable (still default 60 days)
[platform/upstream/openconnect.git] / library.c
1 /*
2  * OpenConnect (SSL + DTLS) VPN client
3  *
4  * Copyright © 2008-2011 Intel Corporation.
5  *
6  * Authors: David Woodhouse <dwmw2@infradead.org>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * version 2.1, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to:
19  *
20  *   Free Software Foundation, Inc.
21  *   51 Franklin Street, Fifth Floor,
22  *   Boston, MA 02110-1301 USA
23  */
24
25 #include "openconnect-internal.h"
26
27 struct openconnect_info *openconnect_vpninfo_new_with_cbdata (char *useragent,
28                                                   openconnect_validate_peer_cert_vfn validate_peer_cert,
29                                                   openconnect_write_new_config_vfn write_new_config,
30                                                   openconnect_process_auth_form_vfn process_auth_form,
31                                                   openconnect_progress_vfn progress,
32                                                   void *privdata)
33 {
34         struct openconnect_info *vpninfo = calloc (sizeof(*vpninfo), 1);
35
36         vpninfo->mtu = 1406;
37         vpninfo->ssl_fd = -1;
38         vpninfo->cert_expire_warning = 60 * 86400;
39         vpninfo->useragent = openconnect_create_useragent (useragent);
40         vpninfo->validate_peer_cert = validate_peer_cert;
41         vpninfo->write_new_config = write_new_config;
42         vpninfo->process_auth_form = process_auth_form;
43         vpninfo->progress = progress;
44         vpninfo->cbdata = privdata?:vpninfo;
45
46         return vpninfo;
47 }
48
49 struct openconnect_info *openconnect_vpninfo_new (char *useragent,
50                                                   openconnect_validate_peer_cert_fn validate_peer_cert,
51                                                   openconnect_write_new_config_fn write_new_config,
52                                                   openconnect_process_auth_form_fn process_auth_form,
53                                                   openconnect_progress_fn progress)
54 {
55         return openconnect_vpninfo_new_with_cbdata (useragent,
56                                                     (void *)validate_peer_cert,
57                                                     (void *)write_new_config,
58                                                     (void *)process_auth_form,
59                                                     (void *)progress, NULL);
60 }
61
62 static void free_optlist (struct vpn_option *opt)
63 {
64         struct vpn_option *next;
65
66         for (; opt; opt = next) {
67                 next = opt->next;
68                 free(opt->option);
69                 free(opt->value);
70                 free(opt);
71         }
72 }
73
74 void openconnect_vpninfo_free (struct openconnect_info *vpninfo)
75 {
76         openconnect_reset_ssl(vpninfo);
77         free_optlist(vpninfo->cookies);
78         free_optlist(vpninfo->cstp_options);
79         free_optlist(vpninfo->dtls_options);
80         free(vpninfo->hostname);
81         free(vpninfo->urlpath);
82         free(vpninfo->redirect_url);
83         free(vpninfo->proxy_type);
84         free(vpninfo->proxy);
85         free(vpninfo->csd_scriptname);
86         free(vpninfo->csd_stuburl);
87         /* These are const in openconnect itself, but for consistency of
88            the library API we do take ownership of the strings we're given,
89            and thus we have to free them too. */
90         free((void *)vpninfo->cafile);
91         if (vpninfo->cert != vpninfo->sslkey)
92                 free((void *)vpninfo->sslkey);
93         free((void *)vpninfo->cert);
94         /* No need to free deflate streams; they weren't initialised */
95         free(vpninfo);
96 }
97
98 char *openconnect_get_hostname (struct openconnect_info *vpninfo)
99 {
100         return vpninfo->hostname;
101 }
102
103 void openconnect_set_hostname (struct openconnect_info *vpninfo, char *hostname)
104 {
105         vpninfo->hostname = hostname;
106 }
107
108 char *openconnect_get_urlpath (struct openconnect_info *vpninfo)
109 {
110         return vpninfo->urlpath;
111 }
112
113 void openconnect_set_urlpath (struct openconnect_info *vpninfo, char *urlpath)
114 {
115         vpninfo->urlpath = urlpath;
116 }
117
118 void openconnect_set_xmlsha1 (struct openconnect_info *vpninfo, char *xmlsha1, int size)
119 {
120         if (size != sizeof (vpninfo->xmlsha1))
121                 return;
122
123         memcpy (&vpninfo->xmlsha1, xmlsha1, size);
124 }
125
126 void openconnect_set_cafile (struct openconnect_info *vpninfo, char *cafile)
127 {
128         vpninfo->cafile = cafile;
129 }
130
131 void openconnect_setup_csd (struct openconnect_info *vpninfo, uid_t uid, int silent, char *wrapper)
132 {
133         vpninfo->uid_csd = uid;
134         vpninfo->uid_csd_given = silent?2:1;
135         vpninfo->csd_wrapper = wrapper;
136 }
137
138 void openconnect_set_client_cert (struct openconnect_info *vpninfo, char *cert, char *sslkey)
139 {
140         vpninfo->cert = cert;
141         if (sslkey)
142                 vpninfo->sslkey = sslkey;
143         else
144                 vpninfo->sslkey = cert;
145 }
146
147 struct x509_st *openconnect_get_peer_cert (struct openconnect_info *vpninfo)
148 {
149         return SSL_get_peer_certificate(vpninfo->https_ssl);
150 }
151
152 int openconnect_get_port (struct openconnect_info *vpninfo)
153 {
154         return vpninfo->port;
155 }
156
157 char *openconnect_get_cookie (struct openconnect_info *vpninfo)
158 {
159         return vpninfo->cookie;
160 }
161
162 void openconnect_clear_cookie (struct openconnect_info *vpninfo)
163 {
164         if (vpninfo->cookie)
165                 memset(vpninfo->cookie, 0, strlen(vpninfo->cookie));
166 }
167
168 void openconnect_reset_ssl (struct openconnect_info *vpninfo)
169 {
170         if (vpninfo->https_ssl) {
171                 openconnect_close_https(vpninfo);
172         }
173         if (vpninfo->peer_addr) {
174                 free(vpninfo->peer_addr);
175                 vpninfo->peer_addr = NULL;
176         }
177         if (vpninfo->https_ctx) {
178                 SSL_CTX_free(vpninfo->https_ctx);
179                 vpninfo->https_ctx = NULL;
180         }
181 }
182
183 int openconnect_parse_url (struct openconnect_info *vpninfo, char *url)
184 {
185         if (vpninfo->peer_addr) {
186                 free(vpninfo->peer_addr);
187                 vpninfo->peer_addr = NULL;
188         }
189
190         return internal_parse_url (url, NULL, &vpninfo->hostname,
191                                    &vpninfo->port, &vpninfo->urlpath, 443);
192 }
193
194 const char *openconnect_get_version (void)
195 {
196         return openconnect_version;
197 }