File: ikev1_vendorid.c

package info (click to toggle)
libreswan 5.2-2.4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 81,656 kB
  • sloc: ansic: 129,988; sh: 32,018; xml: 20,646; python: 10,303; makefile: 3,022; javascript: 1,506; sed: 574; yacc: 511; perl: 264; awk: 52
file content (207 lines) | stat: -rw-r--r-- 5,790 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/* Libreswan ISAKMP VendorID Handling
 * Copyright (C) 2002-2003 Mathieu Lafon - Arkoon Network Security
 * Copyright (C) 2004 Xelerance Corporation
 * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com>
 * Copyright (C) 2013 Wolfgang Nothdurft <wolfgang@linogate.de>
 * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
 * Copyright (C) 2019 Andrew Cagney <cagney@gnu.org>
 *
 * See also https://github.com/royhills/ike-scan/blob/master/ike-vendor-ids
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <https://www.gnu.org/licenses/gpl2.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 */

#include "vendorid.h"

#include "defs.h"
#include "log.h"
#include "ikev1_vendorid.h"
#include "demux.h"
#include "connections.h"

/*
 * Handle IKEv1 Known VendorID's.  This function parses what the remote peer
 * sends us, and enables/disables features based on it.  As we go along,
 * we set vid_useful to TRUE if we did something based on this VendorID.  This
 * suppresses the 'Ignored VendorID ...' log message.
 *
 * @param md message_digest
 * @param vidstr VendorID String
 * @param len Length of vidstr
 * @param vid VendorID Struct (see vendor.h)
 * @param st State Structure (Hopefully initialized)
 * @return void
 */

void handle_v1_vendorid(struct msg_digest *md,
			shunk_t vid,
			struct logger *logger)
{
	enum known_vendorid id = vendorid_by_shunk(vid);

	bool vid_useful = true; /* tentatively TRUE */

	switch (id) {
	/*
	 * Use most recent supported NAT-Traversal method and ignore
	 * the other ones (implementations will send all supported
	 * methods but only one will be used)
	 *
	 * Note: most recent == higher id in vendor.h
	 */

	case VID_LIBRESWANSELF:
	case VID_LIBRESWAN:
	case VID_LIBRESWAN_OLD:
	case VID_OPPORTUNISTIC:
		/* not really useful, but it changes the msg from "ignored" to "received" */
		break;

	case VID_NATT_IETF_00:
	case VID_NATT_IETF_01:
		vid_useful = false; /* no longer supported */
		break;

	case VID_NATT_IETF_02:
	case VID_NATT_IETF_02_N:
	case VID_NATT_IETF_03:
	case VID_NATT_IETF_04:
	case VID_NATT_IETF_05:
	case VID_NATT_IETF_06:
	case VID_NATT_IETF_07:
	case VID_NATT_IETF_08:
	case VID_NATT_DRAFT_IETF_IPSEC_NAT_T_IKE:
	case VID_NATT_RFC:
		if (md->v1_quirks.qnat_traversal_vid < id) {
			enum_buf idb;
			dbg(" quirks.qnat_traversal_vid set to=%d [%s]", id,
			    str_vendorid(id, &idb));
			md->v1_quirks.qnat_traversal_vid = id;
		} else {
			enum_buf idb;
			dbg("ignoring older NAT-T Vendor ID payload [%s]",
			    str_vendorid(id, &idb));
			vid_useful = false;
		}
		break;

	case VID_MISC_DPD:
	case VID_DPD1_NG:
		/* Remote side would like to do DPD with us on this connection */
		md->dpd = true;
		break;

	case VID_MISC_IKEv2:
		md->ikev2 = true;
		break;

	case VID_SSH_SENTINEL_1_4_1:
		llog(RC_LOG, logger,
			    "SSH Sentinel 1.4.1 found, setting XAUTH_ACK quirk");
		md->v1_quirks.xauth_ack_msgid = true;
		break;

	case VID_CISCO_UNITY:
		md->v1_quirks.modecfg_pull_mode = true;
		break;

	case VID_MISC_XAUTH:
		md->v1_quirks.xauth_vid = true;
		break;

	case VID_IKE_FRAGMENTATION:
		md->fragvid = true;
		break;

	default:
		vid_useful = false;
		break;
	}

	llog_vendorid(logger, id, vid, vid_useful);
}

/**
 * Add an IKEv1 (!)  vendor id payload to the msg
 *
 * @param np
 * @param outs PB stream
 * @param vid Int of VendorID to be sent (see vendor.h for the list)
 * @return bool True if successful
 */

bool out_v1VID(struct pbs_out *outs, unsigned int id)
{
	shunk_t blob = shunk_from_vendorid(id);
	enum_buf eb;
	const char *descr = str_vendorid(id, &eb);
	dbg("%s(): sending [%s]", __func__, descr);
	return ikev1_out_generic_raw(&isakmp_vendor_id_desc, outs,
				     blob.ptr, blob.len, "V_ID");
}

/*
 * out_vid_set: output all Vendor ID payloads for IKEv1.
 *
 * Next Payload has historically been tricky.  We dodge this
 * by a couple of ways
 *
 * We always emit DPD VID.  So the our caller knows that the
 * preceding NP must be ISAKMP_NEXT_VID.  This also means that
 * each VID payload before DPD VID must have NP ISAKMP_NEXT_VID.
 *
 * It happens that VID payloads that are emitted here are the last payloads
 * of the message so the DPD VID payload's NP must be ISAKMP_NEXT_NONE.
 *
 * If any changes make this NP calculation more tricky, we should
 * exploit the NP backpatching logic in out_struct.
 */

bool out_v1VID_set(struct pbs_out *outs, const struct connection *c)
{
	/* cusomizeable Vendor ID */
	if (c->config->send_vendorid) {
		if (!ikev1_out_generic_raw(&isakmp_vendor_id_desc, outs,
					pluto_vendorid, strlen(pluto_vendorid), "Pluto Vendor ID")) {
			return false;
		}
	}

#define MAYBE_VID(q, vid) {  \
	if (q) {  \
		if (!out_v1VID(outs, vid)) {  \
			return false;  \
		}  \
	}  \
}

	MAYBE_VID(c->config->send_vid_cisco_unity, VID_CISCO_UNITY);
	MAYBE_VID(c->config->send_vid_fake_strongswan, VID_STRONGSWAN);
	MAYBE_VID(c->config->ike_frag.allow, VID_IKE_FRAGMENTATION);
	MAYBE_VID(c->local->host.config->xauth.client || c->local->host.config->xauth.server, VID_MISC_XAUTH);

#undef MAYBE_VID

	/*
	 * DPD: last, unconditional, VID.
	 * Note: because this is unconditional AND last
	 * we know that all previous np must be ISAKMP_NEXT_VID.
	 * There might be a successor payload generated by caller;
	 * we count on backpatching to fix our np.
	 */

	if (!out_v1VID(outs, VID_MISC_DPD)) {
		return false;
	}

	return true;
}