}
int parse_input_node(struct openconnect_info *vpninfo, struct oc_auth_form *form,
- xmlNodePtr node, const char *submit_button, int flavor,
+ xmlNodePtr node, const char *submit_button,
int (*can_gen_tokencode)(struct openconnect_info *vpninfo, struct oc_auth_form *form, struct oc_form_opt *opt))
{
char *type = (char *)xmlGetProp(node, (unsigned char *)"type"), *style = (char *)xmlGetProp(node, (unsigned char *)"style");
ret = -ENOMEM;
goto out;
}
- if (flavor == FORM_FLAVOR_JUNIPER &&
+ if (vpninfo->proto->proto == PROTO_NC &&
!strcmp(form->auth_id, "loginForm") &&
!strcmp(opt->name, "VerificationCode") &&
can_gen_tokencode && !can_gen_tokencode(vpninfo, form, opt))
opt->type = OC_FORM_OPT_TOKEN;
- } else if (flavor == FORM_FLAVOR_JUNIPER && !strcasecmp(type, "submit")) {
+ } else if (vpninfo->proto->proto == PROTO_NC && !strcasecmp(type, "submit")) {
xmlnode_get_prop(node, "name", &opt->name);
if (opt->name && submit_button && (!strcmp(opt->name, submit_button) ||
}
int parse_select_node(struct openconnect_info *vpninfo, struct oc_auth_form *form,
- xmlNodePtr node, int flavor)
+ xmlNodePtr node)
{
xmlNodePtr child;
struct oc_form_opt_select *opt;
xmlnode_get_prop(node, "name", &opt->form.name);
opt->form.label = strdup(opt->form.name);
opt->form.type = OC_FORM_OPT_SELECT;
- if ((flavor == FORM_FLAVOR_JUNIPER && !strcmp(opt->form.name, "realm")) ||
- (flavor == FORM_FLAVOR_F5 && !strcmp(opt->form.name, "domain")))
+ if ((vpninfo->proto->proto == PROTO_NC && !strcmp(opt->form.name, "realm")) ||
+ (vpninfo->proto->proto == PROTO_F5 && !strcmp(opt->form.name, "domain")))
form->authgroup_opt = opt;
for (child = node->children; child; child = child->next) {
}
struct oc_auth_form *parse_form_node(struct openconnect_info *vpninfo,
- xmlNodePtr node, const char *submit_button, int flavor,
+ xmlNodePtr node, const char *submit_button,
int (*can_gen_tokencode)(struct openconnect_info *vpninfo, struct oc_auth_form *form, struct oc_form_opt *opt))
{
struct oc_auth_form *form = calloc(1, sizeof(*form));
return NULL;
}
- if (flavor == FORM_FLAVOR_JUNIPER) {
+ if (vpninfo->proto->proto == PROTO_NC) {
/* XX: some forms have 'id', but no 'name' */
if (!xmlnode_get_prop(node, "name", &form->auth_id) ||
!xmlnode_get_prop(node, "id", &form->auth_id))
form->banner = strdup(form->auth_id);
- } else if (flavor == FORM_FLAVOR_F5)
+ } else if (vpninfo->proto->proto == PROTO_F5)
xmlnode_get_prop(node, "id", &form->auth_id);
/* XX: fallback auth_id (since other functions expect it to exist) */
continue;
if (!strcasecmp((char *)child->name, "input"))
- parse_input_node(vpninfo, form, child, submit_button, flavor, can_gen_tokencode);
+ parse_input_node(vpninfo, form, child, submit_button, can_gen_tokencode);
else if (!strcasecmp((char *)child->name, "select")) {
- parse_select_node(vpninfo, form, child, flavor);
+ parse_select_node(vpninfo, form, child);
/* Skip its children */
while (child->children)
child = child->last;
- } else if (flavor == FORM_FLAVOR_F5
+ } else if (vpninfo->proto->proto == PROTO_F5
&& !strcasecmp((char *)child->name, "td")) {
char *id = (char *)xmlGetProp(child, (unsigned char *)"id");
}
free(id);
- } else if (flavor == FORM_FLAVOR_JUNIPER &&
+ } else if (vpninfo->proto->proto == PROTO_NC &&
!strcasecmp((char *)child->name, "textarea")) {
/* display the post sign-in message, if any */
_("Encountered form with no 'name' or 'id'\n"));
goto dump_form;
} else if (form_name && !strcmp(form_name, "frmLogin")) {
- form = parse_form_node(vpninfo, node, "btnSubmit", FORM_FLAVOR_JUNIPER, oncp_can_gen_tokencode);
+ form = parse_form_node(vpninfo, node, "btnSubmit", oncp_can_gen_tokencode);
} else if (form_id && !strcmp(form_id, "loginForm")) {
- form = parse_form_node(vpninfo, node, "submitButton", FORM_FLAVOR_JUNIPER, oncp_can_gen_tokencode);
+ form = parse_form_node(vpninfo, node, "submitButton", oncp_can_gen_tokencode);
} else if ((form_name && !strcmp(form_name, "frmDefender")) ||
(form_name && !strcmp(form_name, "frmNextToken"))) {
- form = parse_form_node(vpninfo, node, "btnAction", FORM_FLAVOR_JUNIPER, oncp_can_gen_tokencode);
+ form = parse_form_node(vpninfo, node, "btnAction", oncp_can_gen_tokencode);
} else if (form_name && !strcmp(form_name, "frmConfirmation")) {
- form = parse_form_node(vpninfo, node, "btnContinue", FORM_FLAVOR_JUNIPER, oncp_can_gen_tokencode);
+ form = parse_form_node(vpninfo, node, "btnContinue", oncp_can_gen_tokencode);
if (!form) {
ret = -EINVAL;
break;
form = parse_roles_form_node(node);
role_select = 1;
} else if (form_name && !strcmp(form_name, "frmTotpToken")) {
- form = parse_form_node(vpninfo, node, "totpactionEnter", FORM_FLAVOR_JUNIPER, oncp_can_gen_tokencode);
+ form = parse_form_node(vpninfo, node, "totpactionEnter", oncp_can_gen_tokencode);
} else if ((form_name && !strcmp(form_name, "hiddenform")) ||
(form_id && !strcmp(form_id, "formSAMLSSO"))) {
- form = parse_form_node(vpninfo, node, "submit", FORM_FLAVOR_JUNIPER, oncp_can_gen_tokencode);
+ form = parse_form_node(vpninfo, node, "submit", oncp_can_gen_tokencode);
} else {
char *form_action = (char *)xmlGetProp(node, (unsigned char *)"action");
if (form_action && strstr(form_action, "remediate.cgi")) {
if (!this)
break;
- if (vpninfo->proto->udp_send_probes == oncp_esp_send_probes) {
+ if (vpninfo->proto->proto == PROTO_NC ||
+ vpninfo->proto->proto == PROTO_PULSE) {
uint8_t dontsend;
/* Pulse/NC can only accept ESP of the same protocol as the one
if ((form = plain_auth_form()) == NULL)
goto nomem;
} else {
- form = parse_form_node(vpninfo, node, NULL, FORM_FLAVOR_F5, NULL);
+ form = parse_form_node(vpninfo, node, NULL, NULL);
if (form_order==1 && (xmlnode_get_prop(node, "id", &form_id) || strcmp(form_id, "auth_form"))) {
vpn_progress(vpninfo, PRG_ERR, _("Unknown form ID '%s' (expected 'auth_form')\n"),
form_id);
.name = "anyconnect",
.pretty_name = N_("Cisco AnyConnect or openconnect"),
.description = N_("Compatible with Cisco AnyConnect SSL VPN, as well as ocserv"),
+ .proto = PROTO_ANYCONNECT,
.flags = OC_PROTO_PROXY | OC_PROTO_CSD | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP | OC_PROTO_AUTH_STOKEN,
.vpn_close_session = cstp_bye,
.tcp_connect = cstp_connect,
.name = "nc",
.pretty_name = N_("Juniper Network Connect"),
.description = N_("Compatible with Juniper Network Connect"),
+ .proto = PROTO_NC,
.flags = OC_PROTO_PROXY | OC_PROTO_CSD | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP | OC_PROTO_PERIODIC_TROJAN,
.vpn_close_session = oncp_bye,
.tcp_connect = oncp_connect,
.name = "gp",
.pretty_name = N_("Palo Alto Networks GlobalProtect"),
.description = N_("Compatible with Palo Alto Networks (PAN) GlobalProtect SSL VPN"),
+ .proto = PROTO_GPST,
.flags = OC_PROTO_PROXY | OC_PROTO_CSD | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP | OC_PROTO_AUTH_STOKEN | OC_PROTO_PERIODIC_TROJAN,
.vpn_close_session = gpst_bye,
.tcp_connect = gpst_setup,
.name = "pulse",
.pretty_name = N_("Pulse Connect Secure"),
.description = N_("Compatible with Pulse Connect Secure SSL VPN"),
+ .proto = PROTO_PULSE,
.flags = OC_PROTO_PROXY | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP | OC_PROTO_AUTH_STOKEN,
.vpn_close_session = pulse_bye,
.tcp_connect = pulse_connect,
.name = "f5",
.pretty_name = N_("F5 BIG-IP SSL VPN"),
.description = N_("Compatible with F5 BIG-IP SSL VPN"),
+ .proto = PROTO_F5,
.flags = OC_PROTO_PROXY | OC_PROTO_AUTH_CERT,
.vpn_close_session = f5_bye,
.tcp_connect = f5_connect,
.name = "fortinet",
.pretty_name = N_("Fortinet SSL VPN"),
.description = N_("Compatible with FortiGate SSL VPN"),
+ .proto = PROTO_FORTINET,
.flags = OC_PROTO_PROXY | OC_PROTO_AUTH_CERT | OC_PROTO_AUTH_OTP | OC_PROTO_AUTH_STOKEN,
.vpn_close_session = fortinet_bye,
.tcp_connect = fortinet_connect,
.name = "nullppp",
.pretty_name = N_("PPP over TLS"),
.description = N_("Unauthenticated RFC1661/RFC1662 PPP over TLS, for testing"),
+ .proto = PROTO_NULLPPP,
.flags = OC_PROTO_PROXY | OC_PROTO_HIDDEN,
.tcp_connect = nullppp_connect,
.tcp_mainloop = nullppp_mainloop,
#define DTLS_CONNECTING 4 /* ESP probe received; must tell server */
#define DTLS_CONNECTED 5 /* Server informed and should be sending ESP */
-/* Flavors of HTML forms to screen-scrape */
-#define FORM_FLAVOR_JUNIPER 1
-#define FORM_FLAVOR_F5 2
-#define FORM_FLAVOR_FORTINET 3
+/* Not to be confused with OC_PROTO_xxx flags which are library-visible */
+#define PROTO_ANYCONNECT 0
+#define PROTO_NC 1
+#define PROTO_GPST 2
+#define PROTO_PULSE 3
+#define PROTO_F5 4
+#define PROTO_FORTINET 5
+#define PROTO_NULLPPP 6
/* All supported PPP packet framings/encapsulations */
#define PPP_ENCAP_RFC1661 1 /* Plain/synchronous/pre-framed PPP (RFC1661) */
const char *description;
const char *secure_cookie;
const char *udp_protocol;
+ int proto;
unsigned int flags;
int (*vpn_close_session)(struct openconnect_info *vpninfo, const char *reason);
unsigned char *buf, int len);
int compress_packet(struct openconnect_info *vpninfo, int compr_type, struct pkt *this);
-/* html-auth.c */
+/* auth-html.c */
xmlNodePtr htmlnode_next(xmlNodePtr top, xmlNodePtr node);
xmlNodePtr htmlnode_dive(xmlNodePtr top, xmlNodePtr node);
xmlNodePtr find_form_node(xmlDocPtr doc);
int parse_input_node(struct openconnect_info *vpninfo, struct oc_auth_form *form,
- xmlNodePtr node, const char *submit_button, int flavor,
+ xmlNodePtr node, const char *submit_button,
int (*can_gen_tokencode)(struct openconnect_info *vpninfo, struct oc_auth_form *form, struct oc_form_opt *opt));
int parse_select_node(struct openconnect_info *vpninfo, struct oc_auth_form *form,
- xmlNodePtr node, int flavor);
+ xmlNodePtr node);
struct oc_auth_form *parse_form_node(struct openconnect_info *vpninfo,
- xmlNodePtr node, const char *submit_button, int flavor,
+ xmlNodePtr node, const char *submit_button,
int (*can_gen_tokencode)(struct openconnect_info *vpninfo, struct oc_auth_form *form, struct oc_form_opt *opt));
/* auth-juniper.c */