};
struct vpn_option {
- const char *option;
- const char *value;
+ char *option;
+ char *value;
struct vpn_option *next;
};
char xmlsha1[(SHA_DIGEST_LENGTH * 2) + 1];
const char *cookie;
+ struct vpn_option *cookies;
struct vpn_option *cstp_options;
struct vpn_option *dtls_options;
}
}
if (!strcmp(buf, "Set-Cookie")) {
+ struct vpn_option *new, **this;
char *semicolon = strchr(colon, ';');
- if (semicolon)
- *semicolon = 0;
- if (!strncmp(colon, "webvpn=", 7)) {
- vpninfo->cookie = strdup(colon + 7);
+ char *equals = strchr(colon, '=');
+
+ if (!semicolon || !equals) {
+ fprintf(stderr, "Invalid cookie offered: %s\n", buf);
+ return -EINVAL;
+ }
+ *semicolon = *(equals++) = 0;
+
+ new = malloc(sizeof(*new));
+ if (!new) {
+ fprintf(stderr, "No memory for allocating cookies\n");
+ return -ENOMEM;
+ }
+ new->next = NULL;
+ new->option = strdup(colon);
+ new->value = strdup(equals);
+
+ for (this = &vpninfo->cookies; *this; this = &(*this)->next) {
+ if (!strcmp(new->option, (*this)->option)) {
+ /* Replace existing cookie */
+ new->next = (*this)->next;
+ free((*this)->option);
+ free((*this)->value);
+ free(*this);
+ *this = new;
+ break;
+ }
+ }
+ if (!*this) {
+ *this = new;
+ new->next = NULL;
}
- /* FIXME: Handle other cookies, including the webvpnc one
- which tells us whether to update the XML config file */
-
}
if (!strcmp(buf, "Transfer-Encoding")) {
if (!strcmp(colon, "chunked"))
int obtain_cookie_cert(struct anyconnect_info *vpninfo)
{
+ struct vpn_option *opt, *next;
char buf[65536];
int result;
SSL_free(vpninfo->https_ssl);
vpninfo->https_ssl = NULL;
+ for (opt = vpninfo->cookies; opt; opt = next) {
+ next = opt->next;
+ printf("Discard cookie %s\n", opt->option);
+ free(opt->option);
+ free(opt->value);
+ free(opt);
+ }
+ vpninfo->cookies = NULL;
goto retry;
} else if (vpninfo->redirect_url[0] == '/') {
/* Absolute redirect within same host */
return -EINVAL;
}
}
- if (vpninfo->cookie) {
- return 0;
+
+ for (opt = vpninfo->cookies; opt; opt = opt->next) {
+
+ if (!strcmp(opt->option, "webvpn"))
+ vpninfo->cookie = opt->value;
+ else if (!strcmp(opt->option, "webvpnc")) {
+ char *amp = opt->value;
+
+ while ((amp = strchr(amp, '&'))) {
+ amp++;
+ if (!strncmp(amp, "fh:", 3)) {
+ if (strncasecmp(amp+3, vpninfo->xmlsha1,
+ SHA_DIGEST_LENGTH * 2)) {
+ /* FIXME. Obviously */
+ printf("SHA1 changed; need new config\n");
+ /* URL is $bu: + $fu: */
+ } else if (verbose)
+ printf("XML config SHA1 match\n");
+ }
+ }
+ }
}
+ if (vpninfo->cookie)
+ return 0;
+
return -1;
}