opt->_value = (char *)xmlGetProp(xml_node, (unsigned char *)"value");
} else if (!strcmp(input_type, "text")) {
opt->type = OC_FORM_OPT_TEXT;
+ } else if (!strcmp(input_type, "sso")) {
+ opt->type = OC_FORM_OPT_SSO;
} else if (!strcmp(input_type, "password")) {
if (!cstp_can_gen_tokencode(vpninfo, form, opt))
opt->type = OC_FORM_OPT_TOKEN;
xmlnode_get_text(xml_node, "banner", &form->banner);
xmlnode_get_text(xml_node, "message", &form->message);
xmlnode_get_text(xml_node, "error", &form->error);
+ xmlnode_get_text(xml_node, "sso-v2-login", &vpninfo->sso_login);
+ xmlnode_get_text(xml_node, "sso-v2-login-final", &vpninfo->sso_login_final);
+ xmlnode_get_text(xml_node, "sso-v2-token-cookie-name", &vpninfo->sso_token_cookie);
+ xmlnode_get_text(xml_node, "sso-v2-error-cookie-name", &vpninfo->sso_error_cookie);
if (xmlnode_is_named(xml_node, "form")) {
xmlNodePtr *rootp)
{
xmlDocPtr doc;
- xmlNodePtr root, node;
+ xmlNodePtr root, node, capabilities;
doc = xmlNewDoc(XCAST("1.0"));
if (!doc)
goto bad;
if (!xmlNewProp(root, XCAST("type"), XCAST(type)))
goto bad;
+ if (!xmlNewProp(root, XCAST("aggregate-auth-version"), XCAST("2")))
+ goto bad;
node = xmlNewTextChild(root, NULL, XCAST("version"),
XCAST(vpninfo->version_string ? : openconnect_version_str));
goto bad;
}
+ capabilities = xmlNewNode(NULL, XCAST("capabilities"));
+ if (!capabilities)
+ goto bad;
+ capabilities = xmlAddChild(root, capabilities);
+ if (!capabilities)
+ goto bad;
+
+ node = xmlNewTextChild(capabilities, NULL, XCAST("auth-method"), XCAST("single-sign-on"));
+ if (!node)
+ goto bad;
+
+ node = xmlNewTextChild(capabilities, NULL, XCAST("auth-method"), XCAST("single-sign-on-v2"));
+ if (!node)
+ goto bad;
+
*rootp = root;
return doc;
int second_auth = opt->flags & OC_FORM_OPT_SECOND_AUTH;
opt->flags &= ~OC_FORM_OPT_IGNORE;
+ if (opt->type == OC_FORM_OPT_SSO && vpninfo->open_webview) {
+ vpninfo->sso_cookie_value = NULL;
+ vpninfo->open_webview(vpninfo, vpninfo->sso_login, NULL);
+ opt->_value = vpninfo->sso_cookie_value;
+ vpninfo->sso_cookie_value = NULL;
+ }
+
if (!auth_choice ||
(opt->type != OC_FORM_OPT_TEXT && opt->type != OC_FORM_OPT_PASSWORD))
continue;
void openconnect_set_webview_callback(struct openconnect_info *vpninfo,
openconnect_open_webview_vfn webview_fn)
{
- return;
+ vpninfo->open_webview = webview_fn;
+ vpninfo->try_http_auth = 0;
}
int openconnect_webview_load_changed(struct openconnect_info *vpninfo,
const struct oc_webview_result *result)
{
- return -EOPNOTSUPP;
+ int i;
+
+ // If we're not at the final URI, tell the webview to keep going
+ if (strcmp(result->uri, vpninfo->sso_login_final)) {
+ return 1;
+ }
+
+ for (i=0; result->cookies[i] != NULL; i+=2) {
+ if (!strcmp(vpninfo->sso_token_cookie, result->cookies[i]))
+ {
+ vpninfo->sso_cookie_value = strdup(result->cookies[i+1]);
+ break;
+ }
+ }
+
+ // Tell the webview to terminate
+ return 0;
}
DELAY_CLOSE_IMMEDIATE_CALLBACK,
} delay_close; /* Delay close of mainloop */
+ char *sso_login;
+ char *sso_login_final;
+ char *sso_token_cookie;
+ char *sso_error_cookie;
+ char *sso_cookie_value;
+
int verbose;
void *cbdata;
openconnect_validate_peer_cert_vfn validate_peer_cert;
openconnect_write_new_config_vfn write_new_config;
+ openconnect_open_webview_vfn open_webview;
openconnect_process_auth_form_vfn process_auth_form;
openconnect_progress_vfn progress;
openconnect_protect_socket_vfn protect_socket;