Skip to content

Instantly share code, notes, and snippets.

@jlaundry
Created December 1, 2014 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlaundry/e54c6a152eafd7c2bb97 to your computer and use it in GitHub Desktop.
Save jlaundry/e54c6a152eafd7c2bb97 to your computer and use it in GitHub Desktop.
From 8f005fefbc8713535d59f95e3abee8a45b05399a Mon Sep 17 00:00:00 2001
From: "James E. Flemer" <jflemer@alum.rpi.edu>
Date: Sun, 20 May 2012 21:28:41 -0600
Subject: [PATCH] Add support for Juniper SRX Dynamic VPN
Support for Juniper SRX Dynamic VPN is based on patchset from Mikael Cam
at Nateis (http://www.nateis.fr/vpnc/vpnc-0.5.3-to-0.5.4beta.patch).
Also added explicit "IPSec IDType" option for IKE.
This change has been tested with one Cisco ASA and one Juniper SRX210h
(Junos 10.4R3.4).
---
ChangeLog | 10 +++++
VERSION | 2 +-
config.c | 37 ++++++++++++++++++-
config.h | 3 ++
isakmp.h | 3 +-
juniper.txt | 55 +++++++++++++++++++++++++++
vpnc.c | 121 ++++++++++++++++++++++++++++++++++++++----------------------
7 files changed, 183 insertions(+), 48 deletions(-)
create mode 100644 juniper.txt
diff --git a/ChangeLog b/ChangeLog
index 59ee346..5998d59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+* vpnc-0.5.4.tar.gz Sun May 20 21:19:37 MDT 2012
+
+ User visible changes:
+
+ * Add support for Juniper SRX Dynamic VPN
+ Based on patchset from Mikael Cam - Nateis
+ http://www.nateis.fr/vpnc/vpnc-0.5.3-to-0.5.4beta.patch
+ * Added explicit "IPSec IDType" option for IKE
+ * Tested with Cisco ASA and Juniper SRX210h (Junos 10.4R3.4)
+
* vpnc-0.5.3.tar.gz Wed Nov 19 21:29:22 CET 2008
User visible changes:
diff --git a/VERSION b/VERSION
index be14282..7d85683 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.5.3
+0.5.4
diff --git a/config.c b/config.c
index 7080630..07166c5 100644
--- a/config.c
+++ b/config.c
@@ -48,6 +48,7 @@ int opt_1des, opt_no_encryption, opt_auth_mode;
enum natt_mode_enum opt_natt_mode;
enum vendor_enum opt_vendor;
enum if_mode_enum opt_if_mode;
+enum isakmp_ipsec_id_enum opt_id_type;
uint16_t opt_udpencapport;
static void log_to_stderr(int priority __attribute__((unused)), const char *format, ...)
@@ -370,6 +371,11 @@ static const char *config_def_pid_file(void)
return "/var/run/vpnc.pid";
}
+static const char *config_def_id_type(void)
+{
+ return "0";
+}
+
static const char *config_def_vendor(void)
{
return "cisco";
@@ -414,6 +414,13 @@ static const struct config_names_s {
"your group name",
NULL
}, {
+ CONFIG_IPSEC_ID_TYPE, 1, 1,
+ "--id-type",
+ "IPSec ID Type",
+ "<ipv4/fqdn/user/key/#>",
+ "IKE Phase 1 Identification type",
+ config_def_id_type,
+ }, {
CONFIG_IPSEC_SECRET, 1, 0,
NULL,
"IPSec secret",
@@ -466,7 +473,7 @@ static const struct config_names_s {
CONFIG_VENDOR, 1, 1,
"--vendor",
"Vendor",
- "<cisco/netscreen>",
+ "<cisco/juniper/netscreen>",
"vendor of your IPSec gateway",
config_def_vendor
}, {
@@ -747,12 +760,32 @@ void do_config(int argc, char **argv)
if (!strcmp(config[CONFIG_VENDOR], "cisco")) {
opt_vendor = VENDOR_CISCO;
+ } else if (!strcmp(config[CONFIG_VENDOR], "juniper")) {
+ opt_vendor = VENDOR_JUNIPER;
} else if (!strcmp(config[CONFIG_VENDOR], "netscreen")) {
opt_vendor = VENDOR_NETSCREEN;
} else {
- printf("%s: unknown vendor %s\nknown vendors: cisco netscreen\n", argv[0], config[CONFIG_VENDOR]);
+ printf("%s: unknown vendor %s\nknown vendors: cisco juniper netscreen\n", argv[0], config[CONFIG_VENDOR]);
exit(1);
}
+
+ if (!strcmp(config[CONFIG_IPSEC_ID_TYPE], "ipv4")) {
+ opt_id_type = ISAKMP_IPSEC_ID_IPV4_ADDR;
+ } else if (!strcmp(config[CONFIG_IPSEC_ID_TYPE], "fqdn")) {
+ opt_id_type = ISAKMP_IPSEC_ID_FQDN;
+ } else if (!strcmp(config[CONFIG_IPSEC_ID_TYPE], "user")) {
+ opt_id_type = ISAKMP_IPSEC_ID_FQDN;
+ } else if (!strcmp(config[CONFIG_IPSEC_ID_TYPE], "key")) {
+ opt_id_type = ISAKMP_IPSEC_ID_FQDN;
+ } else {
+ s = NULL;
+ opt_id_type = strtol(config[CONFIG_IPSEC_ID_TYPE], &s, 0);
+ if (s == NULL || *s != '\0') {
+ printf("%s: unknown IPSec ID type %s\n", argv[0], config[CONFIG_IPSEC_ID_TYPE]);
+ exit(1);
+ }
+ }
+
}
if (opt_debug >= 99) {
diff --git a/config.h b/config.h
index 6fbd231..ee2a596 100644
--- a/config.h
+++ b/config.h
@@ -46,6 +46,7 @@ enum config_enum {
CONFIG_IPSEC_GATEWAY,
CONFIG_IPSEC_TARGET_NETWORK,
CONFIG_IPSEC_ID,
+ CONFIG_IPSEC_ID_TYPE,
CONFIG_IPSEC_SECRET,
CONFIG_IPSEC_SECRET_OBF,
CONFIG_XAUTH_USERNAME,
@@ -70,6 +71,7 @@ enum hex_dump_enum {
enum vendor_enum {
VENDOR_CISCO,
+ VENDOR_JUNIPER,
VENDOR_NETSCREEN
};
@@ -101,6 +103,7 @@ extern int opt_nd;
extern int opt_1des, opt_no_encryption, opt_auth_mode;
extern enum natt_mode_enum opt_natt_mode;
extern enum if_mode_enum opt_if_mode;
+extern enum isakmp_ipsec_id_enum opt_id_type;
extern uint16_t opt_udpencapport;
#define TIMESTAMP() ({ \
diff --git a/isakmp.h b/isakmp.h
index 45418e6..e009d74 100644
--- a/isakmp.h
+++ b/isakmp.h
@@ -396,7 +396,8 @@ extern const unsigned char VID_NATT_RFC[];
/* Support for draft-ietf-ipsec-isakmp-mode-cfg-05.txt (yuk). */
enum isakmp_modecfg_cfg_enum {
- ISAKMP_MODECFG_CFG_REQUEST = 1,
+ ISAKMP_MODECFG_CFG_RESERVED = 0,
+ ISAKMP_MODECFG_CFG_REQUEST,
ISAKMP_MODECFG_CFG_REPLY,
ISAKMP_MODECFG_CFG_SET,
ISAKMP_MODECFG_CFG_ACK
diff --git a/juniper.txt b/juniper.txt
new file mode 100644
index 0000000..f1ae461
--- /dev/null
+++ b/juniper.txt
@@ -0,0 +1,55 @@
+Using vpnc with Juniper / Junos / SRX
+-------------------------------------
+
+Breif instructions for using vpnc with the dynamic vpn feature of the
+SRX. Make sure your SRX config is set up with "shared-ike-id". Make
+sure the SRX "dynamic hostname" matches the vpnc "IPSec ID".
+
+Example VPNC Config
+-------------------
+ Vendor juniper
+ IPSec gateway 192.168.10.1
+ IPSec ID example.com
+ IPSec secret TheGroupSecret
+ Xauth username joe
+ Xauth password joespw
+ IKE Authmode psk
+ IKE DH Group dh2
+ Perfect Forward Secrecy dh2
+
+Example SRX Config
+------------------
+ # IKE Phase 1
+ set security ike policy DYN-VPN-IKE mode aggressive
+ set security ike policy DYN-VPN-IKE proposal-set standard
+ set security ike policy DYN-VPN-IKE pre-shared-key ascii-text "TheGroupSecret"
+ set security ike gateway DYN-VPN-GW ike-policy DYN-VPN-IKE
+ set security ike gateway DYN-VPN-GW dynamic hostname example.com
+ set security ike gateway DYN-VPN-GW dynamic connections-limit 10
+ set security ike gateway DYN-VPN-GW dynamic ike-user-type shared-ike-id
+ set security ike gateway DYN-VPN-GW external-interface ge-0/0/15.0
+ set security ike gateway DYN-VPN-GW xauth access-profile DYN-VPN-PROFILE
+ # IKE Phase 2
+ set security ipsec policy DYN-VPN-IPSEC-POLICY perfect-forward-secrecy keys group2
+ set security ipsec policy DYN-VPN-IPSEC-POLICY proposal-set standard
+ set security ipsec vpn DYN-VPN-IPSEC ike gateway DYN-VPN-GW
+ set security ipsec vpn DYN-VPN-IPSEC ike ipsec-policy DYN-VPN-IPSEC-POLICY
+ # VPN
+ # laptop[joe@example.com] <======> 192.168.10.1[example.com] <-----> 10.10.10.0/24[internal]
+ set access profile DYN-VPN-PROFILE address-assignment pool DYN-VPN-POOL
+ set access address-assignment pool DYN-VPN-POOL family inet network 10.10.10.0/24
+ set access address-assignment pool DYN-VPN-POOL family inet range dvpn-range low 10.10.10.24
+ set access address-assignment pool DYN-VPN-POOL family inet range dvpn-range high 10.10.10.96
+ set access address-assignment pool DYN-VPN-POOL family inet xauth-attributes primary-dns 8.8.8.8/32
+ set security dynamic-vpn access-profile DYN-VPN-PROFILE
+ set security dynamic-vpn clients all remote-protected-resources 192.168.10.1/24
+ set security dynamic-vpn clients all remote-exceptions 0.0.0.0/0
+ set security dynamic-vpn clients all ipsec-vpn DYN-VPN-IPSEC
+ set security policies from-zone UNTRUST to-zone TRUST policy DYN-VPN match source-address any
+ set security policies from-zone UNTRUST to-zone TRUST policy DYN-VPN match destination-address any
+ set security policies from-zone UNTRUST to-zone TRUST policy DYN-VPN match application any
+ set security policies from-zone UNTRUST to-zone TRUST policy DYN-VPN then permit tunnel ipsec-vpn DYN-VPN-IPSEC
+ set access firewall-authentication web-authentication default-profile DYN-VPN-PROFILE
+ # Local firewall user (joe)
+ set access profile DYN-VPN-PROFILE client joe firewall-user password "joespw"
+ set security dynamic-vpn clients all user joe
diff --git a/vpnc.c b/vpnc.c
index 91cf6d6..e43bfe3 100644
--- a/vpnc.c
+++ b/vpnc.c
@@ -1278,8 +1278,12 @@ static void do_phase1_am_packet1(struct sa_block *s, const char *key_id)
l = l->next->next;
l->next = new_isakmp_payload(ISAKMP_PAYLOAD_ID);
l = l->next;
- if (opt_vendor == VENDOR_CISCO)
+ if (opt_id_type != ISAKMP_IPSEC_ID_RESERVED)
+ l->u.id.type = opt_id_type;
+ else if (opt_vendor == VENDOR_CISCO)
l->u.id.type = ISAKMP_IPSEC_ID_KEY_ID;
+ else if (opt_vendor == VENDOR_JUNIPER)
+ l->u.id.type = ISAKMP_IPSEC_ID_FQDN;
else
l->u.id.type = ISAKMP_IPSEC_ID_USER_FQDN;
l->u.id.protocol = IPPROTO_UDP;
@@ -2161,6 +2165,55 @@ static int do_phase2_notice_check(struct sa_block *s, struct isakmp_packet **r_p
return reject;
}
+static int do_phase2_modeconfig_extra(struct sa_block *s, struct isakmp_packet **r, int sendonly)
+{
+ struct isakmp_attribute *a = (*r)->payload->next->u.modecfg.attributes;
+ int reject;
+
+ DEBUGTOP(2, printf("S5.5.1 do netscreen/juniper modecfg extra\n"));
+
+ do_config_to_env(s, a);
+
+ for (; a; a = a->next)
+ if(a->af == isakmp_attr_lots)
+ a->u.lots.length = 0;
+
+ (*r)->payload->next->u.modecfg.type = ISAKMP_MODECFG_CFG_ACK;
+ sendrecv_phase2(s, (*r)->payload->next, ISAKMP_EXCHANGE_MODECFG_TRANSACTION,
+ (*r)->message_id, sendonly, 0, 0, 0, 0);
+
+ reject = do_phase2_notice_check(s, r, NULL, 0);
+ return reject;
+}
+
+static int do_phase2_modeconfig_ack(struct sa_block *s, struct isakmp_packet **r, int sendonly)
+{
+ /* The final SET should have just one attribute. */
+ struct isakmp_attribute *a = (*r)->payload->next->u.modecfg.attributes;
+ uint16_t set_result = 1;
+ int reject = -1;
+
+ if (a == NULL
+ || a->type != ISAKMP_XAUTH_06_ATTRIB_STATUS
+ || a->af != isakmp_attr_16 || a->next != NULL) {
+ reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
+ phase2_fatal(s, "xauth SET message rejected: %s(%d)", reject);
+ } else {
+ set_result = a->u.attr_16;
+ }
+
+ /* ACK the SET. */
+ DEBUGTOP(2, printf("S5.7 send xauth ack\n"));
+ (*r)->payload->next->u.modecfg.type = ISAKMP_MODECFG_CFG_ACK;
+ sendrecv_phase2(s, (*r)->payload->next, ISAKMP_EXCHANGE_MODECFG_TRANSACTION,
+ (*r)->message_id, sendonly, 0, 0, 0, 0);
+
+ if (set_result == 0)
+ error(2, 0, "authentication unsuccessful");
+
+ return reject;
+}
+
static int do_phase2_xauth(struct sa_block *s)
{
struct isakmp_packet *r = NULL;
@@ -2346,56 +2399,33 @@ static int do_phase2_xauth(struct sa_block *s)
}
- if ((opt_vendor == VENDOR_NETSCREEN) &&
+ if ((opt_vendor == VENDOR_JUNIPER) &&
(r->payload->next->u.modecfg.type == ISAKMP_MODECFG_CFG_SET)) {
- struct isakmp_attribute *a = r->payload->next->u.modecfg.attributes;
-
- DEBUGTOP(2, printf("S5.5.1 do netscreen modecfg extra\n"));
-
- do_config_to_env(s, a);
-
- for (; a; a = a->next)
- if(a->af == isakmp_attr_lots)
- a->u.lots.length = 0;
-
- r->payload->next->u.modecfg.type = ISAKMP_MODECFG_CFG_ACK;
- sendrecv_phase2(s, r->payload->next,
- ISAKMP_EXCHANGE_MODECFG_TRANSACTION,
- r->message_id, 0, 0, 0, 0, 0);
-
+ do_phase2_modeconfig_ack(s, &r, 0);
reject = do_phase2_notice_check(s, &r, NULL, 0);
- if (reject == -1) {
- free_isakmp_packet(r);
- return 1;
+ if (reject != -1) {
+ DEBUGTOP(2, printf("S5.6 process xauth set (juniper)\n"));
+ reject = do_phase2_modeconfig_extra(s, &r, 1);
}
- }
-
- DEBUGTOP(2, printf("S5.6 process xauth set\n"));
- {
- /* The final SET should have just one attribute. */
- struct isakmp_attribute *a = r->payload->next->u.modecfg.attributes;
- uint16_t set_result = 1;
-
- if (a == NULL
- || a->type != ISAKMP_XAUTH_06_ATTRIB_STATUS
- || a->af != isakmp_attr_16 || a->next != NULL) {
- reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
- phase2_fatal(s, "xauth SET message rejected: %s(%d)", reject);
- } else {
- set_result = a->u.attr_16;
+ } else if ((opt_vendor == VENDOR_NETSCREEN) &&
+ (r->payload->next->u.modecfg.type == ISAKMP_MODECFG_CFG_SET)) {
+ reject = do_phase2_modeconfig_extra(s, &r, 0);
+ if (reject != -1) {
+ DEBUGTOP(2, printf("S5.6 process xauth set (netscreen)\n"));
+ do_phase2_modeconfig_ack(s, &r, 1);
}
-
- /* ACK the SET. */
- DEBUGTOP(2, printf("S5.7 send xauth ack\n"));
- r->payload->next->u.modecfg.type = ISAKMP_MODECFG_CFG_ACK;
- sendrecv_phase2(s, r->payload->next, ISAKMP_EXCHANGE_MODECFG_TRANSACTION,
- r->message_id, 1, 0, 0, 0, 0);
+ } else {
+ DEBUGTOP(2, printf("S5.6 process xauth set\n"));
+ do_phase2_modeconfig_ack(s, &r, 1);
+ }
+ if (r && r->payload)
r->payload->next = NULL; /* this part is already free()d by sendrecv_phase2 */
+ if (r)
free_isakmp_packet(r); /* this frees the received set packet (header+hash) */
- if (set_result == 0)
- error(2, 0, "authentication unsuccessful");
- }
+ if (reject == -1)
+ return 1;
+
DEBUGTOP(2, printf("S5.8 xauth done\n"));
return 0;
}
@@ -2773,6 +2803,9 @@ static void do_phase2_qm(struct sa_block *s)
case ISAKMP_PAYLOAD_NONCE:
nonce_r = rp;
break;
+ case ISAKMP_PAYLOAD_D:
+ nonce_r = rp;
+ break;
default:
reject = ISAKMP_N_INVALID_PAYLOAD_TYPE;
@robinsonaarond
Copy link

Hey jlaundry, I'm trying to get this patch to work against my Juniper dynamic VPN, but I'm getting this error:
hash comparison failed: (ISAKMP_N_AUTHENTICATION_FAILED)(24) check group password!

But I am sure the set security ike policy ike-dyn pre-shared-key ascii-text I have set is correct.

I know this patch is pretty old; do you still expect it to work? Have you run across this issue in your configuration?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment