oncp.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. /*
  2. * OpenConnect (SSL + DTLS) VPN client
  3. *
  4. * Copyright © 2008-2015 Intel Corporation.
  5. *
  6. * Author: David Woodhouse <dwmw2@infradead.org>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * version 2.1, as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. */
  17. /*
  18. * Grateful thanks to Tiebing Zhang, who did much of the hard work
  19. * of analysing and decoding the protocol.
  20. */
  21. #include <config.h>
  22. #include "openconnect-internal.h"
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <sys/types.h>
  26. #include <time.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include <errno.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <stdarg.h>
  33. static void buf_append_tlv(struct oc_text_buf *buf, uint16_t val, uint32_t len, void *data)
  34. {
  35. unsigned char b[6];
  36. store_be16(b, val);
  37. store_be32(b + 2, len);
  38. buf_append_bytes(buf, b, 6);
  39. if (len)
  40. buf_append_bytes(buf, data, len);
  41. }
  42. static void buf_append_tlv_be32(struct oc_text_buf *buf, uint16_t val, uint32_t data)
  43. {
  44. unsigned char d[4];
  45. store_be32(d, data);
  46. buf_append_tlv(buf, val, 4, d);
  47. }
  48. static const char authpkt_head[] = { 0x00, 0x04, 0x00, 0x00, 0x00 };
  49. static const char authpkt_tail[] = { 0xbb, 0x01, 0x00, 0x00, 0x00, 0x00 };
  50. #define GRP_ATTR(g, a) (((g) << 16) | (a))
  51. static int process_attr(struct openconnect_info *vpninfo,
  52. struct oc_vpn_option **new_opts, struct oc_ip_info *new_ip_info,
  53. int group, int attr, unsigned char *data, int attrlen)
  54. {
  55. char buf[80];
  56. int i;
  57. switch(GRP_ATTR(group, attr)) {
  58. case GRP_ATTR(6, 2):
  59. if (attrlen != 4) {
  60. badlen:
  61. vpn_progress(vpninfo, PRG_ERR,
  62. _("Unexpected length %d for TLV %d/%d\n"),
  63. attrlen, group, attr);
  64. return -EINVAL;
  65. }
  66. new_ip_info->mtu = load_be32(data);
  67. vpn_progress(vpninfo, PRG_DEBUG,
  68. _("Received MTU %d from server\n"),
  69. new_ip_info->mtu);
  70. break;
  71. case GRP_ATTR(2, 1):
  72. if (attrlen != 4)
  73. goto badlen;
  74. snprintf(buf, sizeof(buf), "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
  75. vpn_progress(vpninfo, PRG_DEBUG, _("Received DNS server %s\n"), buf);
  76. for (i = 0; i < 3; i++) {
  77. if (!new_ip_info->dns[i]) {
  78. new_ip_info->dns[i] = add_option_dup(new_opts, "DNS", buf, -1);
  79. break;
  80. }
  81. }
  82. break;
  83. case GRP_ATTR(2, 2):
  84. vpn_progress(vpninfo, PRG_DEBUG, _("Received DNS search domain %.*s\n"),
  85. attrlen, (char *)data);
  86. new_ip_info->domain = add_option_dup(new_opts, "search", (char *)data, attrlen);
  87. if (new_ip_info->domain) {
  88. char *p = (char *)new_ip_info->domain;
  89. while ((p = strchr(p, ',')))
  90. *p = ' ';
  91. }
  92. break;
  93. case GRP_ATTR(1, 1):
  94. if (attrlen != 4)
  95. goto badlen;
  96. snprintf(buf, sizeof(buf), "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
  97. vpn_progress(vpninfo, PRG_DEBUG, _("Received internal IP address %s\n"), buf);
  98. new_ip_info->addr = add_option_dup(new_opts, "ipaddr", buf, -1);
  99. break;
  100. case GRP_ATTR(1, 2):
  101. if (attrlen != 4)
  102. goto badlen;
  103. snprintf(buf, sizeof(buf), "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
  104. vpn_progress(vpninfo, PRG_DEBUG, _("Received netmask %s\n"), buf);
  105. new_ip_info->netmask = add_option_dup(new_opts, "netmask", buf, -1);
  106. break;
  107. case GRP_ATTR(1, 3):
  108. if (attrlen != 4)
  109. goto badlen;
  110. snprintf(buf, sizeof(buf), "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
  111. vpn_progress(vpninfo, PRG_DEBUG, _("Received internal gateway address %s\n"), buf);
  112. /* Hm, what are we supposed to do with this? It's a tunnel;
  113. having a gateway is meaningless. */
  114. add_option_dup(new_opts, "ipaddr", buf, -1);
  115. break;
  116. case GRP_ATTR(3, 3): {
  117. struct oc_split_include *inc;
  118. if (attrlen != 8)
  119. goto badlen;
  120. snprintf(buf, sizeof(buf), "%d.%d.%d.%d/%d.%d.%d.%d",
  121. data[0], data[1], data[2], data[3],
  122. data[4], data[5], data[6], data[7]);
  123. vpn_progress(vpninfo, PRG_DEBUG, _("Received split include route %s\n"), buf);
  124. inc = malloc(sizeof(*inc));
  125. if (inc) {
  126. inc->route = add_option_dup(new_opts, "split-include", buf, -1);
  127. if (inc->route) {
  128. inc->next = new_ip_info->split_includes;
  129. new_ip_info->split_includes = inc;
  130. } else
  131. free(inc);
  132. }
  133. break;
  134. }
  135. case GRP_ATTR(3, 4): {
  136. struct oc_split_include *exc;
  137. if (attrlen != 8)
  138. goto badlen;
  139. snprintf(buf, sizeof(buf), "%d.%d.%d.%d/%d.%d.%d.%d",
  140. data[0], data[1], data[2], data[3],
  141. data[4], data[5], data[6], data[7]);
  142. vpn_progress(vpninfo, PRG_DEBUG, _("Received split exclude route %s\n"), buf);
  143. exc = malloc(sizeof(*exc));
  144. if (exc) {
  145. exc->route = add_option_dup(new_opts, "split-exclude", buf, -1);
  146. if (exc->route) {
  147. exc->next = new_ip_info->split_excludes;
  148. new_ip_info->split_excludes = exc;
  149. } else
  150. free(exc);
  151. }
  152. break;
  153. }
  154. case GRP_ATTR(4, 1):
  155. if (attrlen != 4)
  156. goto badlen;
  157. snprintf(buf, sizeof(buf), "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
  158. vpn_progress(vpninfo, PRG_DEBUG, _("Received WINS server %s\n"), buf);
  159. for (i = 0; i < 3; i++) {
  160. if (!new_ip_info->nbns[i]) {
  161. new_ip_info->nbns[i] = add_option_dup(new_opts, "WINS", buf, -1);
  162. break;
  163. }
  164. }
  165. break;
  166. case GRP_ATTR(8, 1): {
  167. const char *enctype;
  168. if (attrlen != 1)
  169. goto badlen;
  170. if (data[0] == ENC_AES_128_CBC) {
  171. enctype = "AES-128";
  172. vpninfo->enc_key_len = 16;
  173. } else if (data[0] == ENC_AES_256_CBC) {
  174. enctype = "AES-256";
  175. vpninfo->enc_key_len = 32;
  176. } else
  177. enctype = "unknown";
  178. vpn_progress(vpninfo, PRG_DEBUG, _("ESP encryption: 0x%02x (%s)\n"),
  179. data[0], enctype);
  180. vpninfo->esp_enc = data[0];
  181. break;
  182. }
  183. case GRP_ATTR(8, 2): {
  184. const char *mactype;
  185. if (attrlen != 1)
  186. goto badlen;
  187. if (data[0] == HMAC_MD5) {
  188. mactype = "MD5";
  189. vpninfo->hmac_key_len = 16;
  190. } else if (data[0] == HMAC_SHA1) {
  191. mactype = "SHA1";
  192. vpninfo->hmac_key_len = 20;
  193. } else
  194. mactype = "unknown";
  195. vpn_progress(vpninfo, PRG_DEBUG, _("ESP HMAC: 0x%02x (%s)\n"),
  196. data[0], mactype);
  197. vpninfo->esp_hmac = data[0];
  198. break;
  199. }
  200. case GRP_ATTR(8, 3):
  201. if (attrlen != 1)
  202. goto badlen;
  203. vpninfo->esp_compr = data[0];
  204. vpninfo->dtls_compr = data[0] ? COMPR_LZO : 0;
  205. vpn_progress(vpninfo, PRG_DEBUG, _("ESP compression: %d\n"), data[0]);
  206. break;
  207. case GRP_ATTR(8, 4):
  208. if (attrlen != 2)
  209. goto badlen;
  210. i = load_be16(data);
  211. udp_sockaddr(vpninfo, i);
  212. vpn_progress(vpninfo, PRG_DEBUG, _("ESP port: %d\n"), i);
  213. break;
  214. case GRP_ATTR(8, 5):
  215. if (attrlen != 4)
  216. goto badlen;
  217. vpninfo->esp_lifetime_bytes = load_be32(data);
  218. vpn_progress(vpninfo, PRG_DEBUG, _("ESP key lifetime: %u bytes\n"),
  219. vpninfo->esp_lifetime_bytes);
  220. break;
  221. case GRP_ATTR(8, 6):
  222. if (attrlen != 4)
  223. goto badlen;
  224. vpninfo->esp_lifetime_seconds = load_be32(data);
  225. vpn_progress(vpninfo, PRG_DEBUG, _("ESP key lifetime: %u seconds\n"),
  226. vpninfo->esp_lifetime_seconds);
  227. break;
  228. case GRP_ATTR(8, 9):
  229. if (attrlen != 4)
  230. goto badlen;
  231. vpninfo->esp_ssl_fallback = load_be32(data);
  232. vpn_progress(vpninfo, PRG_DEBUG, _("ESP to SSL fallback: %u seconds\n"),
  233. vpninfo->esp_ssl_fallback);
  234. break;
  235. case GRP_ATTR(8, 10):
  236. if (attrlen != 4)
  237. goto badlen;
  238. vpninfo->esp_replay_protect = load_be32(data);
  239. vpn_progress(vpninfo, PRG_DEBUG, _("ESP replay protection: %d\n"),
  240. load_be32(data));
  241. break;
  242. case GRP_ATTR(7, 1):
  243. if (attrlen != 4)
  244. goto badlen;
  245. memcpy(&vpninfo->esp_out.spi, data, 4);
  246. vpn_progress(vpninfo, PRG_DEBUG, _("ESP SPI (outbound): %x\n"),
  247. load_be32(data));
  248. break;
  249. case GRP_ATTR(7, 2):
  250. if (attrlen != 0x40)
  251. goto badlen;
  252. /* data contains enc_key and hmac_key concatenated */
  253. memcpy(vpninfo->esp_out.enc_key, data, 0x40);
  254. vpn_progress(vpninfo, PRG_DEBUG, _("%d bytes of ESP secrets\n"),
  255. attrlen);
  256. break;
  257. default:
  258. buf[0] = 0;
  259. for (i=0; i < 16 && i < attrlen; i++)
  260. sprintf(buf + strlen(buf), " %02x", data[i]);
  261. if (attrlen > 16)
  262. sprintf(buf + strlen(buf), "...");
  263. vpn_progress(vpninfo, PRG_DEBUG,
  264. _("Unknown TLV group %d attr %d len %d:%s\n"),
  265. group, attr, attrlen, buf);
  266. }
  267. return 0;
  268. }
  269. static void put_len16(struct oc_text_buf *buf, int where)
  270. {
  271. int len = buf->pos - where;
  272. store_be16(buf->data + where - 2, len);
  273. }
  274. static void put_len32(struct oc_text_buf *buf, int where)
  275. {
  276. int len = buf->pos - where;
  277. store_be32(buf->data + where - 4, len);
  278. }
  279. /* We don't know what these are so just hope they never change */
  280. static const unsigned char kmp_head[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  281. static const unsigned char kmp_tail[] = { 0x01, 0x00, 0x00, 0x00, 0x00,
  282. 0x00, 0x00, 0x00, 0x00, 0x00 };
  283. static const unsigned char kmp_tail_out[] = { 0x01, 0x00, 0x00, 0x00, 0x01,
  284. 0x00, 0x00, 0x00, 0x00, 0x00 };
  285. static const unsigned char data_hdr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  286. 0x01, 0x2c, 0x01, 0x00, 0x00, 0x00,
  287. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
  288. #ifdef HAVE_ESP
  289. static const unsigned char esp_kmp_hdr[] = {
  290. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2e,
  291. 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* KMP header */
  292. 0x00, 0x56, /* KMP length */
  293. 0x00, 0x07, 0x00, 0x00, 0x00, 0x50, /* TLV group 7 */
  294. 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, /* Attr 1 (SPI) */
  295. };
  296. /* Followed by 4 bytes of SPI */
  297. static const unsigned char esp_kmp_part2[] = {
  298. 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, /* Attr 2 (secrets) */
  299. };
  300. /* And now 0x40 bytes of random secret for encryption and HMAC key */
  301. #endif
  302. static const struct pkt esp_enable_pkt = {
  303. .next = NULL,
  304. { .oncp = { .rec = { 0x21, 0x00 },
  305. .kmp = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f,
  306. 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  307. 0x00, 0x00, 0x00, 0x0d } }
  308. },
  309. .data = {
  310. 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, /* Group 6, len 7 */
  311. 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, /* Attr 1, len 1 */
  312. 0x01
  313. },
  314. .len = 13
  315. };
  316. static int queue_esp_control(struct openconnect_info *vpninfo, int enable)
  317. {
  318. struct pkt *new = alloc_pkt(vpninfo, esp_enable_pkt.len);
  319. if (!new)
  320. return -ENOMEM;
  321. new->oncp = esp_enable_pkt.oncp;
  322. new->len = esp_enable_pkt.len;
  323. memcpy(new->data, esp_enable_pkt.data, esp_enable_pkt.len);
  324. new->data[12] = enable;
  325. queue_packet(&vpninfo->tcp_control_queue, new);
  326. return 0;
  327. }
  328. static int check_kmp_header(struct openconnect_info *vpninfo, unsigned char *bytes, int pktlen)
  329. {
  330. if (pktlen < 20 || memcmp(bytes, kmp_head, sizeof(kmp_head)) ||
  331. memcmp(bytes + 8, kmp_tail, sizeof(kmp_tail))) {
  332. vpn_progress(vpninfo, PRG_ERR,
  333. _("Failed to parse KMP header\n"));
  334. return -EINVAL;
  335. }
  336. return load_be16(bytes + 6);
  337. }
  338. static int parse_conf_pkt(struct openconnect_info *vpninfo, unsigned char *bytes, int pktlen, int kmp)
  339. {
  340. int kmplen, kmpend, grouplen, groupend, group, attr, attrlen;
  341. int ofs = 0;
  342. int split_enc_hmac_keys = 0;
  343. struct oc_vpn_option *new_opts = NULL;
  344. struct oc_ip_info new_ip_info = {};
  345. kmplen = load_be16(bytes + ofs + 18);
  346. kmpend = ofs + kmplen;
  347. if (kmpend > pktlen) {
  348. eparse:
  349. vpn_progress(vpninfo, PRG_ERR,
  350. _("Failed to parse KMP message\n"));
  351. dump_buf_hex(vpninfo, PRG_ERR, '<', bytes, pktlen);
  352. einval:
  353. free_optlist(new_opts);
  354. free_split_routes(&new_ip_info);
  355. return -EINVAL;
  356. }
  357. vpn_progress(vpninfo, PRG_DEBUG,
  358. _("Got KMP message %d of size %d\n"),
  359. kmp, kmplen);
  360. ofs += 0x14;
  361. while (ofs < kmpend) {
  362. if (ofs + 6 > kmpend)
  363. goto eparse;
  364. group = load_be16(bytes + ofs);
  365. grouplen = load_be32(bytes + ofs + 2);
  366. ofs += 6;
  367. groupend = ofs + grouplen;
  368. if (groupend > pktlen)
  369. goto eparse;
  370. if (kmp == 302 && group != 7 && group != 8) {
  371. vpn_progress(vpninfo, PRG_ERR,
  372. _("Received non-ESP TLVs (group %d) in ESP negotiation KMP\n"),
  373. group);
  374. goto einval;
  375. }
  376. while (ofs < groupend) {
  377. if (ofs + 6 > groupend)
  378. goto eparse;
  379. attr = load_be16(bytes + ofs);
  380. attrlen = load_be32(bytes + ofs + 2);
  381. ofs += 6;
  382. if (attrlen + ofs > groupend)
  383. goto eparse;
  384. if (process_attr(vpninfo, &new_opts, &new_ip_info,
  385. group, attr, bytes + ofs, attrlen))
  386. goto eparse;
  387. if (GRP_ATTR(group, attr)==GRP_ATTR(7, 2))
  388. split_enc_hmac_keys = 1;
  389. ofs += attrlen;
  390. }
  391. }
  392. /* The encryption and HMAC keys are sent concatenated together in a block of 0x40 bytes;
  393. we can't split them apart until we know how long the encryption key is. */
  394. if (split_enc_hmac_keys)
  395. memcpy(vpninfo->esp_out.hmac_key, vpninfo->esp_out.enc_key + vpninfo->enc_key_len, vpninfo->hmac_key_len);
  396. int ret = install_vpn_opts(vpninfo, new_opts, &new_ip_info);
  397. if (ret) {
  398. free_optlist(new_opts);
  399. free_split_routes(&new_ip_info);
  400. return ret;
  401. }
  402. return 0;
  403. }
  404. int oncp_connect(struct openconnect_info *vpninfo)
  405. {
  406. int ret, len, kmp, kmplen, group, check_len;
  407. struct oc_text_buf *reqbuf;
  408. unsigned char bytes[65536];
  409. if (!vpninfo->cookies) {
  410. /* XX: This will happen if authentication was separate/external */
  411. ret = internal_split_cookies(vpninfo, 0, "DSID");
  412. if (ret)
  413. return ret;
  414. }
  415. ret = openconnect_open_https(vpninfo);
  416. if (ret)
  417. return ret;
  418. reqbuf = buf_alloc();
  419. buf_append(reqbuf, "POST /dana/js?prot=1&svc=4 HTTP/1.1\r\n");
  420. /* The TLS socket actually remains open for use by the oNCP
  421. tunnel, but the "Connection: close" header is nevertheless
  422. required here. It appears to signal to the server to stop
  423. treating this as an HTTP connection and to start treating
  424. it as an oNCP connection.
  425. */
  426. buf_append(reqbuf, "Connection: close\r\n");
  427. oncp_common_headers(vpninfo, reqbuf);
  428. buf_append(reqbuf, "Content-Length: 256\r\n");
  429. buf_append(reqbuf, "\r\n");
  430. if (buf_error(reqbuf)) {
  431. vpn_progress(vpninfo, PRG_ERR,
  432. _("Error creating oNCP negotiation request\n"));
  433. ret = buf_error(reqbuf);
  434. goto out;
  435. }
  436. if (vpninfo->dump_http_traffic)
  437. dump_buf(vpninfo, '>', reqbuf->data);
  438. ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
  439. if (ret < 0)
  440. goto out;
  441. ret = process_http_response(vpninfo, 1, NULL, reqbuf);
  442. if (ret < 0)
  443. goto out;
  444. if (ret != 200) {
  445. vpn_progress(vpninfo, PRG_ERR,
  446. _("Unexpected %d result from server\n"),
  447. ret);
  448. ret = ((ret >= 400 && ret <= 499) || ret == 302) ? -EPERM : -EINVAL;
  449. goto out;
  450. }
  451. /* This is probably some kind of vestigial authentication packet, although
  452. * it's mostly obsolete now that the authentication is really done over
  453. * HTTP. We only send the hostname. */
  454. buf_truncate(reqbuf);
  455. buf_append_le16(reqbuf, sizeof(authpkt_head) + 2 +
  456. strlen(vpninfo->localname) + sizeof(authpkt_tail));
  457. buf_append_bytes(reqbuf, authpkt_head, sizeof(authpkt_head));
  458. buf_append_le16(reqbuf, strlen(vpninfo->localname));
  459. buf_append(reqbuf, "%s", vpninfo->localname);
  460. buf_append_bytes(reqbuf, authpkt_tail, sizeof(authpkt_tail));
  461. if (buf_error(reqbuf)) {
  462. vpn_progress(vpninfo, PRG_ERR,
  463. _("Error creating oNCP negotiation request\n"));
  464. ret = buf_error(reqbuf);
  465. goto out;
  466. }
  467. dump_buf_hex(vpninfo, PRG_DEBUG, '>', (void *)reqbuf->data, reqbuf->pos);
  468. ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
  469. if (ret != reqbuf->pos) {
  470. if (ret >= 0) {
  471. vpn_progress(vpninfo, PRG_ERR,
  472. _("Short write in oNCP negotiation\n"));
  473. ret = -EIO;
  474. }
  475. goto out;
  476. }
  477. /* Now we expect a three-byte response with what's presumably an
  478. error code */
  479. ret = vpninfo->ssl_read(vpninfo, (void *)bytes, 3);
  480. check_len = load_le16(bytes);
  481. if (ret < 0)
  482. goto out;
  483. vpn_progress(vpninfo, PRG_TRACE,
  484. _("Read %d bytes of SSL record\n"), ret);
  485. dump_buf_hex(vpninfo, PRG_TRACE, '<', (void *)bytes, ret);
  486. if (ret != 3 || check_len < 1) {
  487. vpn_progress(vpninfo, PRG_ERR,
  488. _("Unexpected response of size %d after hostname packet\n"),
  489. ret);
  490. ret = -EINVAL;
  491. goto out;
  492. }
  493. if (bytes[2]) {
  494. vpn_progress(vpninfo, PRG_ERR,
  495. _("Server response to hostname packet is error 0x%02x\n"),
  496. bytes[2]);
  497. if (bytes[2] == 0x08)
  498. vpn_progress(vpninfo, PRG_ERR,
  499. _("This seems to indicate that the server has disabled support for\n"
  500. "Juniper's older oNCP protocol, and only allows connections using\n"
  501. "the newer Junos Pulse protocol. This version of OpenConnect has\n"
  502. "EXPERIMENTAL support for Pulse using --prot=pulse\n"));
  503. ret = -EINVAL;
  504. goto out;
  505. }
  506. /* And then a KMP message 301 with the IP configuration.
  507. * Sometimes this arrives as a separate SSL record (with its own
  508. * 2-byte length prefix), and sometimes concatenated with the
  509. * previous 3-byte response).
  510. */
  511. if (check_len == 1) {
  512. len = vpninfo->ssl_read(vpninfo, (void *)bytes, sizeof(bytes));
  513. check_len = load_le16(bytes);
  514. } else {
  515. len = vpninfo->ssl_read(vpninfo, (void *)(bytes+2), sizeof(bytes)-2) + 2;
  516. check_len--;
  517. }
  518. if (len < 0) {
  519. ret = len;
  520. goto out;
  521. }
  522. vpn_progress(vpninfo, PRG_TRACE,
  523. _("Read %d bytes of SSL record\n"), len);
  524. if (len < 0x16 || check_len + 2 != len) {
  525. vpn_progress(vpninfo, PRG_ERR,
  526. _("Invalid packet waiting for KMP 301\n"));
  527. dump_buf_hex(vpninfo, PRG_ERR, '<', bytes, len);
  528. ret = -EINVAL;
  529. goto out;
  530. }
  531. ret = check_kmp_header(vpninfo, bytes + 2, len);
  532. if (ret < 0)
  533. goto out;
  534. /* We expect KMP message 301 here */
  535. if (ret != 301) {
  536. vpn_progress(vpninfo, PRG_ERR,
  537. _("Expected KMP message 301 from server but got %d\n"),
  538. ret);
  539. ret = -EINVAL;
  540. goto out;
  541. }
  542. kmplen = load_be16(bytes + 20);
  543. if (kmplen + 2 >= sizeof(bytes)) {
  544. vpn_progress(vpninfo, PRG_ERR,
  545. _("KMP message 301 from server too large (%d bytes)\n"),
  546. kmplen);
  547. ret = -EINVAL;
  548. goto out;
  549. }
  550. vpn_progress(vpninfo, PRG_TRACE,
  551. _("Got KMP message 301 of length %d\n"), kmplen);
  552. while (kmplen + 22 > len) {
  553. char l[2];
  554. int thislen;
  555. if (vpninfo->ssl_read(vpninfo, (void *)l, 2) != 2) {
  556. vpn_progress(vpninfo, PRG_ERR,
  557. _("Failed to read continuation record length\n"));
  558. ret = -EINVAL;
  559. goto out;
  560. }
  561. if (load_le16(l) + len > kmplen + 22) {
  562. vpn_progress(vpninfo, PRG_ERR,
  563. _("Record of additional %d bytes too large; would make %d\n"),
  564. load_le16(l), len + load_le16(l));
  565. ret = -EINVAL;
  566. goto out;
  567. }
  568. thislen = vpninfo->ssl_read(vpninfo, (void *)(bytes + len), load_le16(l));
  569. if (thislen != load_le16(l)) {
  570. vpn_progress(vpninfo, PRG_ERR,
  571. _("Failed to read continuation record of length %d\n"),
  572. load_le16(l));
  573. ret = -EINVAL;
  574. goto out;
  575. }
  576. vpn_progress(vpninfo, PRG_TRACE,
  577. _("Read additional %d bytes of KMP 301 message\n"),
  578. thislen);
  579. len += thislen;
  580. }
  581. ret = parse_conf_pkt(vpninfo, bytes + 2, len - 2, ret);
  582. if (ret)
  583. goto out;
  584. buf_truncate(reqbuf);
  585. buf_append_le16(reqbuf, 0); /* Length. We'll fix it later. */
  586. buf_append_bytes(reqbuf, kmp_head, sizeof(kmp_head));
  587. buf_append_be16(reqbuf, 303); /* KMP message 303 */
  588. buf_append_bytes(reqbuf, kmp_tail_out, sizeof(kmp_tail_out));
  589. buf_append_be16(reqbuf, 0); /* KMP message length */
  590. kmp = reqbuf->pos;
  591. buf_append_tlv(reqbuf, 6, 0, NULL); /* TLV group 6 */
  592. group = reqbuf->pos;
  593. buf_append_tlv_be32(reqbuf, 2, vpninfo->ip_info.mtu);
  594. if (buf_error(reqbuf)) {
  595. vpn_progress(vpninfo, PRG_ERR,
  596. _("Error creating oNCP negotiation request\n"));
  597. ret = buf_error(reqbuf);
  598. goto out;
  599. }
  600. put_len32(reqbuf, group);
  601. put_len16(reqbuf, kmp);
  602. #ifdef HAVE_ESP
  603. if (!openconnect_setup_esp_keys(vpninfo, 1)) {
  604. struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in];
  605. /* Since we'll want to do this in the oncp_mainloop too, where it's easier
  606. * *not* to have an oc_text_buf and build it up manually, and since it's
  607. * all fixed size and fairly simple anyway, just hard-code the packet */
  608. buf_append_bytes(reqbuf, esp_kmp_hdr, sizeof(esp_kmp_hdr));
  609. buf_append_bytes(reqbuf, &esp->spi, sizeof(esp->spi));
  610. buf_append_bytes(reqbuf, esp_kmp_part2, sizeof(esp_kmp_part2));
  611. buf_append_bytes(reqbuf, &esp->enc_key, vpninfo->enc_key_len);
  612. buf_append_bytes(reqbuf, &esp->hmac_key, 0x40 - vpninfo->enc_key_len);
  613. if (buf_error(reqbuf)) {
  614. vpn_progress(vpninfo, PRG_ERR,
  615. _("Error negotiating ESP keys\n"));
  616. ret = buf_error(reqbuf);
  617. goto out;
  618. }
  619. }
  620. #endif
  621. /* Length at the start of the packet is little-endian */
  622. store_le16(reqbuf->data, reqbuf->pos - 2);
  623. vpn_progress(vpninfo, PRG_DEBUG, _("oNCP negotiation request outgoing:\n"));
  624. dump_buf_hex(vpninfo, PRG_DEBUG, '>', (void *)reqbuf->data, reqbuf->pos);
  625. ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
  626. if (ret != reqbuf->pos) {
  627. if (ret >= 0) {
  628. vpn_progress(vpninfo, PRG_ERR,
  629. _("Short write in oNCP negotiation\n"));
  630. ret = -EIO;
  631. }
  632. goto out;
  633. }
  634. ret = 0;
  635. out:
  636. if (ret)
  637. openconnect_close_https(vpninfo, 0);
  638. else {
  639. monitor_fd_new(vpninfo, ssl);
  640. monitor_read_fd(vpninfo, ssl);
  641. monitor_except_fd(vpninfo, ssl);
  642. }
  643. buf_free(reqbuf);
  644. vpninfo->partial_rec_size = 0;
  645. free_pkt(vpninfo, vpninfo->cstp_pkt);
  646. vpninfo->cstp_pkt = NULL;
  647. return ret;
  648. }
  649. static int oncp_receive_espkeys(struct openconnect_info *vpninfo, int len)
  650. {
  651. #ifdef HAVE_ESP
  652. int ret;
  653. ret = parse_conf_pkt(vpninfo, vpninfo->cstp_pkt->oncp.kmp, len + 20, 301);
  654. if (!ret)
  655. ret = openconnect_setup_esp_keys(vpninfo, 1);
  656. if (!ret) {
  657. struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in];
  658. unsigned char *p = vpninfo->cstp_pkt->oncp.kmp;
  659. memcpy(p, esp_kmp_hdr, sizeof(esp_kmp_hdr));
  660. p += sizeof(esp_kmp_hdr);
  661. memcpy(p, &esp->spi, sizeof(esp->spi));
  662. p += sizeof(esp->spi);
  663. memcpy(p, esp_kmp_part2, sizeof(esp_kmp_part2));
  664. p += sizeof(esp_kmp_part2);
  665. memcpy(p, esp->enc_key, vpninfo->enc_key_len);
  666. memcpy(p+vpninfo->enc_key_len, esp->hmac_key, 0x40 - vpninfo->enc_key_len);
  667. p += 0x40;
  668. vpninfo->cstp_pkt->len = p - vpninfo->cstp_pkt->data;
  669. store_le16(vpninfo->cstp_pkt->oncp.rec,
  670. (p - vpninfo->cstp_pkt->oncp.kmp));
  671. queue_packet(&vpninfo->tcp_control_queue, vpninfo->cstp_pkt);
  672. vpninfo->cstp_pkt = NULL;
  673. print_esp_keys(vpninfo, _("new incoming"), esp);
  674. print_esp_keys(vpninfo, _("new outgoing"), &vpninfo->esp_out);
  675. }
  676. return ret;
  677. #else
  678. vpn_progress(vpninfo, PRG_DEBUG,
  679. _("Ignoring ESP keys since ESP support not available in this build\n"));
  680. return 0;
  681. #endif
  682. }
  683. static int oncp_record_read(struct openconnect_info *vpninfo, void *buf, int len)
  684. {
  685. int ret;
  686. if (!vpninfo->partial_rec_size) {
  687. unsigned char lenbuf[2];
  688. ret = ssl_nonblock_read(vpninfo, 0, lenbuf, 2);
  689. if (ret <= 0)
  690. return ret;
  691. if (ret == 1) {
  692. /* Surely at least *this* never happens? The two length bytes
  693. * of the oNCP record being split across multiple SSL records */
  694. vpn_progress(vpninfo, PRG_ERR,
  695. _("Read only 1 byte of oNCP length field\n"));
  696. return -EIO;
  697. }
  698. vpninfo->partial_rec_size = load_le16(lenbuf);
  699. if (!vpninfo->partial_rec_size) {
  700. ret = ssl_nonblock_read(vpninfo, 0, lenbuf, 1);
  701. if (ret == 1) {
  702. if (lenbuf[0] == 1) {
  703. vpn_progress(vpninfo, PRG_ERR,
  704. _("Server terminated connection (session expired)\n"));
  705. vpninfo->quit_reason = "VPN session expired";
  706. } else if (lenbuf[0] == 8) {
  707. vpn_progress(vpninfo, PRG_ERR,
  708. _("Server terminated connection (idle timeout)\n"));
  709. vpninfo->quit_reason = "Idle timeout";
  710. } else {
  711. vpn_progress(vpninfo, PRG_ERR,
  712. _("Server terminated connection (reason: %d)\n"),
  713. lenbuf[0]);
  714. vpninfo->quit_reason = "Server terminated connection";
  715. }
  716. return -EPIPE;
  717. } else {
  718. vpn_progress(vpninfo, PRG_ERR,
  719. _("Server sent zero-length oNCP record\n"));
  720. vpninfo->quit_reason = "Zero-length oNCP record";
  721. return -EIO;
  722. }
  723. }
  724. }
  725. if (len > vpninfo->partial_rec_size)
  726. len = vpninfo->partial_rec_size;
  727. ret = ssl_nonblock_read(vpninfo, 0, buf, len);
  728. if (ret > 0)
  729. vpninfo->partial_rec_size -= ret;
  730. return ret;
  731. }
  732. int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
  733. {
  734. int ret;
  735. int work_done = 0;
  736. /* Periodic TNCC */
  737. if (trojan_check_deadline(vpninfo, timeout)) {
  738. oncp_send_tncc_command(vpninfo, 0);
  739. return 1;
  740. }
  741. if (vpninfo->ssl_fd == -1)
  742. goto do_reconnect;
  743. /* FIXME: The poll() handling here is fairly simplistic. Actually,
  744. if the SSL connection stalls it could return a WANT_WRITE error
  745. on _either_ of the SSL_read() or SSL_write() calls. In that case,
  746. we should probably remove POLLIN from the events we're looking for,
  747. and add POLLOUT. As it is, though, it'll just chew CPU time in that
  748. fairly unlikely situation, until the write backlog clears. */
  749. while (readable) {
  750. int len, kmp, kmplen, iplen;
  751. /* Some servers send us packets that are larger than
  752. negotiated MTU. We reserve some extra space to
  753. handle that */
  754. int receive_mtu = MAX(16384, vpninfo->ip_info.mtu);
  755. len = receive_mtu + vpninfo->pkt_trailer;
  756. if (!vpninfo->cstp_pkt) {
  757. vpninfo->cstp_pkt = alloc_pkt(vpninfo, len);
  758. if (!vpninfo->cstp_pkt) {
  759. vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
  760. break;
  761. }
  762. vpninfo->cstp_pkt->len = 0;
  763. }
  764. /*
  765. * This protocol is horrid. There are encapsulations within
  766. * encapsulations within encapsulations. Some of them entirely
  767. * gratuitous.
  768. *
  769. * First there's the SSL records which are a natural part of
  770. * using TLS as a transport. They appear to make no use of the
  771. * packetisation which these provide.
  772. *
  773. * Then within the TLS data stream there are "records" preceded
  774. * by a 16-bit little-endian length. It's not clear what these
  775. * records represent; they appear to be entirely gratuitous and
  776. * just need to be discarded. A record boundary sometimes falls
  777. * right in the middle of a data packet; there's no apparent
  778. * logic to it.
  779. *
  780. * Then there are the KMP packets themselves, each of which has
  781. * a length field of its own. There can be multiple KMP packets
  782. * in each of the above-mention "records", and as noted there
  783. * even be *partial* KMP packets in each record.
  784. *
  785. * Finally, a KMP data packet may actually contain multiple IP
  786. * packets, which need to be split apart by using the length
  787. * field in the IP header. This is Legacy IP only, never IPv6
  788. * for the Network Connect protocol.
  789. */
  790. /* Until we pass it up the stack, we use cstp_pkt->len to show
  791. * the amount of data received *including* the KMP header. */
  792. len = oncp_record_read(vpninfo,
  793. vpninfo->cstp_pkt->oncp.kmp + vpninfo->cstp_pkt->len,
  794. receive_mtu + 20 - vpninfo->cstp_pkt->len);
  795. if (!len)
  796. break;
  797. else if (len < 0) {
  798. if (vpninfo->quit_reason)
  799. return len;
  800. goto do_reconnect;
  801. }
  802. vpninfo->cstp_pkt->len += len;
  803. vpninfo->ssl_times.last_rx = time(NULL);
  804. if (vpninfo->cstp_pkt->len < 20)
  805. continue;
  806. next_kmp:
  807. /* Now we have a KMP header. It might already have been there */
  808. kmp = load_be16(vpninfo->cstp_pkt->oncp.kmp + 6);
  809. kmplen = load_be16(vpninfo->cstp_pkt->oncp.kmp + 18);
  810. if (len == vpninfo->cstp_pkt->len)
  811. vpn_progress(vpninfo, PRG_DEBUG, _("Incoming KMP message %d of size %d (got %d)\n"),
  812. kmp, kmplen, vpninfo->cstp_pkt->len - 20);
  813. else
  814. vpn_progress(vpninfo, PRG_DEBUG, _("Continuing to process KMP message %d now size %d (got %d)\n"),
  815. kmp, kmplen, vpninfo->cstp_pkt->len - 20);
  816. switch (kmp) {
  817. case 300:
  818. next_ip:
  819. /* Need at least 6 bytes of payload to check the IP packet length */
  820. if (vpninfo->cstp_pkt->len < 26)
  821. continue;
  822. switch(vpninfo->cstp_pkt->data[0] >> 4) {
  823. case 4:
  824. iplen = load_be16(vpninfo->cstp_pkt->data + 2);
  825. break;
  826. case 6:
  827. iplen = load_be16(vpninfo->cstp_pkt->data + 4) + 40;
  828. break;
  829. default:
  830. badiplen:
  831. vpn_progress(vpninfo, PRG_ERR,
  832. _("Unrecognised data packet\n"));
  833. goto unknown_pkt;
  834. }
  835. if (!iplen || iplen > receive_mtu || iplen > kmplen)
  836. goto badiplen;
  837. if (iplen > vpninfo->cstp_pkt->len - 20)
  838. continue;
  839. work_done = 1;
  840. vpn_progress(vpninfo, PRG_TRACE,
  841. _("Received uncompressed data packet of %d bytes\n"),
  842. iplen);
  843. /* If there's nothing after the IP packet, and it's the last (or
  844. * only) packet in this KMP300 so we don't need to keep the KMP
  845. * header either, then just queue it. */
  846. if (iplen == kmplen && iplen == vpninfo->cstp_pkt->len - 20) {
  847. vpninfo->cstp_pkt->len = iplen;
  848. queue_packet(&vpninfo->incoming_queue, vpninfo->cstp_pkt);
  849. vpninfo->cstp_pkt = NULL;
  850. continue;
  851. }
  852. /* OK, we have a whole packet, and we have stuff after it */
  853. queue_new_packet(vpninfo, &vpninfo->incoming_queue,
  854. vpninfo->cstp_pkt->data, iplen);
  855. kmplen -= iplen;
  856. if (kmplen) {
  857. /* Still data packets to come in this KMP300 */
  858. store_be16(vpninfo->cstp_pkt->oncp.kmp + 18, kmplen);
  859. vpninfo->cstp_pkt->len -= iplen;
  860. if (vpninfo->cstp_pkt->len > 20)
  861. memmove(vpninfo->cstp_pkt->data,
  862. vpninfo->cstp_pkt->data + iplen,
  863. vpninfo->cstp_pkt->len - 20);
  864. goto next_ip;
  865. }
  866. /* We have depleted the KMP300, and there are more bytes from
  867. * the next KMP message in the buffer. Move it up and process it */
  868. memmove(vpninfo->cstp_pkt->oncp.kmp,
  869. vpninfo->cstp_pkt->data + iplen,
  870. vpninfo->cstp_pkt->len - iplen - 20);
  871. vpninfo->cstp_pkt->len -= (iplen + 20);
  872. goto next_kmp;
  873. case 302:
  874. /* Should never happen; if it does we'll have to cope */
  875. if (kmplen > receive_mtu)
  876. goto unknown_pkt;
  877. /* Probably never happens. We need it in its own record.
  878. * If I fix oncp_receive_espkeys() not to reuse cstp_pkt
  879. * we can stop doing this. */
  880. if (vpninfo->cstp_pkt->len != kmplen + 20)
  881. goto unknown_pkt;
  882. ret = oncp_receive_espkeys(vpninfo, kmplen);
  883. if (ret) {
  884. vpn_progress(vpninfo, PRG_ERR, _("Failed to set up ESP: %s\n"),
  885. strerror(-ret));
  886. oncp_esp_close(vpninfo);
  887. }
  888. work_done = 1;
  889. break;
  890. default:
  891. unknown_pkt:
  892. vpn_progress(vpninfo, PRG_ERR,
  893. _("Unknown KMP message %d of size %d:\n"), kmp, kmplen);
  894. dump_buf_hex(vpninfo, PRG_ERR, '<', vpninfo->cstp_pkt->oncp.kmp,
  895. vpninfo->cstp_pkt->len);
  896. if (kmplen + 20 != vpninfo->cstp_pkt->len)
  897. vpn_progress(vpninfo, PRG_DEBUG,
  898. _(".... + %d more bytes unreceived\n"),
  899. kmplen + 20 - vpninfo->cstp_pkt->len);
  900. vpninfo->quit_reason = "Unknown packet received";
  901. return 1;
  902. }
  903. }
  904. /* If SSL_write() fails we are expected to try again. With exactly
  905. the same data, at exactly the same location. So we keep the
  906. packet we had before.... */
  907. if (vpninfo->current_ssl_pkt) {
  908. handle_outgoing:
  909. vpninfo->ssl_times.last_tx = time(NULL);
  910. unmonitor_write_fd(vpninfo, ssl);
  911. vpn_progress(vpninfo, PRG_TRACE, _("Packet outgoing:\n"));
  912. dump_buf_hex(vpninfo, PRG_TRACE, '>',
  913. vpninfo->current_ssl_pkt->oncp.rec,
  914. vpninfo->current_ssl_pkt->len + 22);
  915. ret = ssl_nonblock_write(vpninfo, 0,
  916. vpninfo->current_ssl_pkt->oncp.rec,
  917. vpninfo->current_ssl_pkt->len + 22);
  918. if (ret < 0) {
  919. do_reconnect:
  920. /* XXX: Do we have to do this or can we leave it open?
  921. * Perhaps we could even reconnect asynchronously while
  922. * the ESP is still running? */
  923. #ifdef HAVE_ESP
  924. esp_shutdown(vpninfo);
  925. #endif
  926. ret = ssl_reconnect(vpninfo);
  927. if (ret) {
  928. vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
  929. vpninfo->quit_reason = "oNCP reconnect failed";
  930. return ret;
  931. }
  932. vpninfo->dtls_need_reconnect = 1;
  933. return 1;
  934. } else if (!ret) {
  935. #if 0 /* Not for Juniper yet */
  936. /* -EAGAIN: ssl_nonblock_write() will have added the SSL
  937. fd to ->select_wfds if appropriate, so we can just
  938. return and wait. Unless it's been stalled for so long
  939. that DPD kicks in and we kill the connection. */
  940. switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) {
  941. case KA_DPD_DEAD:
  942. goto peer_dead;
  943. case KA_REKEY:
  944. goto do_rekey;
  945. case KA_NONE:
  946. return work_done;
  947. default:
  948. /* This should never happen */
  949. break;
  950. }
  951. #else
  952. return work_done;
  953. #endif
  954. }
  955. if (ret != vpninfo->current_ssl_pkt->len + 22) {
  956. vpn_progress(vpninfo, PRG_ERR,
  957. _("SSL wrote too few bytes! Asked for %d, sent %d\n"),
  958. vpninfo->current_ssl_pkt->len + 22, ret);
  959. vpninfo->quit_reason = "Internal error";
  960. return 1;
  961. }
  962. /* Don't free the 'special' packets */
  963. if (vpninfo->current_ssl_pkt == vpninfo->deflate_pkt) {
  964. free_pkt(vpninfo, vpninfo->pending_deflated_pkt);
  965. vpninfo->pending_deflated_pkt = NULL;
  966. } else if (vpninfo->current_ssl_pkt == &esp_enable_pkt) {
  967. /* Only set the ESP state to connected and actually start
  968. sending packets on it once the enable message has been
  969. *sent* over the TCP channel. */
  970. vpn_progress(vpninfo, PRG_TRACE,
  971. _("Sent ESP enable control packet\n"));
  972. vpninfo->dtls_state = DTLS_ESTABLISHED;
  973. work_done = 1;
  974. } else {
  975. free_pkt(vpninfo, vpninfo->current_ssl_pkt);
  976. }
  977. vpninfo->current_ssl_pkt = NULL;
  978. }
  979. #if 0 /* Not understood for Juniper yet */
  980. if (vpninfo->owe_ssl_dpd_response) {
  981. vpninfo->owe_ssl_dpd_response = 0;
  982. vpninfo->current_ssl_pkt = (struct pkt *)&dpd_resp_pkt;
  983. goto handle_outgoing;
  984. }
  985. switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
  986. case KA_REKEY:
  987. do_rekey:
  988. /* Not that this will ever happen; we don't even process
  989. the setting when we're asked for it. */
  990. vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
  991. if (vpninfo->ssl_times.rekey_method == REKEY_TUNNEL)
  992. goto do_reconnect;
  993. else if (vpninfo->ssl_times.rekey_method == REKEY_SSL) {
  994. ret = cstp_handshake(vpninfo, 0);
  995. if (ret) {
  996. /* if we failed rehandshake try establishing a new-tunnel instead of failing */
  997. vpn_progress(vpninfo, PRG_ERR, _("Rehandshake failed; attempting new-tunnel\n"));
  998. goto do_reconnect;
  999. }
  1000. goto do_dtls_reconnect;
  1001. }
  1002. break;
  1003. case KA_DPD_DEAD:
  1004. peer_dead:
  1005. vpn_progress(vpninfo, PRG_ERR,
  1006. _("CSTP Dead Peer Detection detected dead peer!\n"));
  1007. do_reconnect:
  1008. ret = cstp_reconnect(vpninfo);
  1009. if (ret) {
  1010. vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
  1011. vpninfo->quit_reason = "CSTP reconnect failed";
  1012. return ret;
  1013. }
  1014. do_dtls_reconnect:
  1015. /* succeeded, let's rekey DTLS, if it is not rekeying
  1016. * itself. */
  1017. if (vpninfo->dtls_state > DTLS_SLEEPING &&
  1018. vpninfo->dtls_times.rekey_method == REKEY_NONE) {
  1019. vpninfo->dtls_need_reconnect = 1;
  1020. }
  1021. return 1;
  1022. case KA_DPD:
  1023. vpn_progress(vpninfo, PRG_DEBUG, _("Send CSTP DPD\n"));
  1024. vpninfo->current_ssl_pkt = (struct pkt *)&dpd_pkt;
  1025. goto handle_outgoing;
  1026. case KA_KEEPALIVE:
  1027. /* No need to send an explicit keepalive
  1028. if we have real data to send */
  1029. if (vpninfo->dtls_state != DTLS_ESTABLISHED && vpninfo->outgoing_queue)
  1030. break;
  1031. vpn_progress(vpninfo, PRG_DEBUG, _("Send CSTP Keepalive\n"));
  1032. vpninfo->current_ssl_pkt = (struct pkt *)&keepalive_pkt;
  1033. goto handle_outgoing;
  1034. case KA_NONE:
  1035. ;
  1036. }
  1037. #endif
  1038. /* Queue the ESP enable message. We will start sending packets
  1039. * via ESP once the enable message has been *sent* over the
  1040. * TCP channel. Assign it directly to current_ssl_pkt so that
  1041. * we can use it in-place and match against it above. */
  1042. if (vpninfo->dtls_state == DTLS_CONNECTED) {
  1043. vpninfo->current_ssl_pkt = (struct pkt *)&esp_enable_pkt;
  1044. goto handle_outgoing;
  1045. }
  1046. vpninfo->current_ssl_pkt = dequeue_packet(&vpninfo->tcp_control_queue);
  1047. if (vpninfo->current_ssl_pkt)
  1048. goto handle_outgoing;
  1049. /* Service outgoing packet queue, if no DTLS */
  1050. while (vpninfo->dtls_state != DTLS_ESTABLISHED &&
  1051. (vpninfo->current_ssl_pkt = dequeue_packet(&vpninfo->outgoing_queue))) {
  1052. struct pkt *this = vpninfo->current_ssl_pkt;
  1053. /* Little-endian overall record length */
  1054. store_le16(this->oncp.rec, (this->len + 20));
  1055. memcpy(this->oncp.kmp, data_hdr, 18);
  1056. /* Big-endian length in KMP message header */
  1057. store_be16(this->oncp.kmp + 18, this->len);
  1058. vpn_progress(vpninfo, PRG_TRACE,
  1059. _("Sending uncompressed data packet of %d bytes\n"),
  1060. this->len);
  1061. goto handle_outgoing;
  1062. }
  1063. /* Work is not done if we just got rid of packets off the queue */
  1064. return work_done;
  1065. }
  1066. int oncp_bye(struct openconnect_info *vpninfo, const char *reason)
  1067. {
  1068. char *orig_path;
  1069. char *res_buf=NULL;
  1070. int ret;
  1071. /* We need to close and reopen the HTTPS connection (to kill
  1072. * the oncp tunnel) and submit a new HTTPS request to logout.
  1073. */
  1074. openconnect_close_https(vpninfo, 0);
  1075. orig_path = vpninfo->urlpath;
  1076. vpninfo->urlpath = strdup("dana-na/auth/logout.cgi"); /* redirect segfaults without strdup */
  1077. ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, HTTP_NO_FLAGS);
  1078. free(vpninfo->urlpath);
  1079. vpninfo->urlpath = orig_path;
  1080. if (ret < 0)
  1081. vpn_progress(vpninfo, PRG_ERR, _("Logout failed.\n"));
  1082. else
  1083. vpn_progress(vpninfo, PRG_INFO, _("Logout successful.\n"));
  1084. free(res_buf);
  1085. return ret;
  1086. }
  1087. #ifdef HAVE_ESP
  1088. void oncp_esp_close(struct openconnect_info *vpninfo)
  1089. {
  1090. /* Tell server to stop sending on ESP channel */
  1091. if (vpninfo->dtls_state >= DTLS_CONNECTED)
  1092. queue_esp_control(vpninfo, 0);
  1093. esp_close(vpninfo);
  1094. }
  1095. int oncp_esp_send_probes(struct openconnect_info *vpninfo)
  1096. {
  1097. struct pkt *pkt;
  1098. int pktlen, seq;
  1099. if (vpninfo->dtls_fd == -1) {
  1100. int fd = udp_connect(vpninfo);
  1101. if (fd < 0)
  1102. return fd;
  1103. /* We are not connected until we get an ESP packet back */
  1104. vpninfo->dtls_state = DTLS_SLEEPING;
  1105. vpninfo->dtls_fd = fd;
  1106. monitor_fd_new(vpninfo, dtls);
  1107. monitor_read_fd(vpninfo, dtls);
  1108. monitor_except_fd(vpninfo, dtls);
  1109. }
  1110. pkt = alloc_pkt(vpninfo, 1 + vpninfo->pkt_trailer);
  1111. if (!pkt)
  1112. return -ENOMEM;
  1113. for (seq=1; seq <= (vpninfo->dtls_state==DTLS_ESTABLISHED ? 1 : 2); seq++) {
  1114. pkt->len = 1;
  1115. pkt->data[0] = 0;
  1116. pktlen = construct_esp_packet(vpninfo, pkt,
  1117. vpninfo->dtls_addr->sa_family == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IPIP);
  1118. if (pktlen < 0 ||
  1119. send(vpninfo->dtls_fd, (void *)&pkt->esp, pktlen, 0) < 0)
  1120. vpn_progress(vpninfo, PRG_DEBUG, _("Failed to send ESP probe\n"));
  1121. }
  1122. free_pkt(vpninfo, pkt);
  1123. vpninfo->dtls_times.last_tx = time(&vpninfo->new_dtls_started);
  1124. return 0;
  1125. };
  1126. int oncp_esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt)
  1127. {
  1128. return (pkt->len == 1 && pkt->data[0] == 0);
  1129. }
  1130. #endif /* HAVE_ESP */