array.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  1. /*
  2. * OpenConnect (SSL + DTLS) VPN client
  3. *
  4. * Copyright © 2020 David Woodhouse
  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. #include <config.h>
  18. #include "openconnect-internal.h"
  19. #include "json.h"
  20. #include <unistd.h>
  21. #include <fcntl.h>
  22. #include <sys/types.h>
  23. #ifdef _WIN32
  24. #include "win32-ipicmp.h"
  25. #else
  26. /* The BSDs require the first two headers before netinet/ip.h
  27. * (Linux and macOS already #include them within netinet/ip.h)
  28. */
  29. #include <netinet/in_systm.h>
  30. #include <netinet/in.h>
  31. #include <netinet/ip.h>
  32. #include <netinet/ip_icmp.h>
  33. #include <netinet/ip6.h>
  34. #include <netinet/icmp6.h>
  35. #endif
  36. #include <time.h>
  37. #include <string.h>
  38. #include <ctype.h>
  39. #include <errno.h>
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include <stdarg.h>
  43. static struct oc_auth_form *plain_auth_form(void)
  44. {
  45. struct oc_auth_form *form;
  46. struct oc_form_opt *opt, *opt2, *opt3;
  47. form = calloc(1, sizeof(*form));
  48. if (!form) {
  49. nomem:
  50. free_auth_form(form);
  51. return NULL;
  52. }
  53. form->auth_id = strdup("form");
  54. opt = form->opts = calloc(1, sizeof(*opt));
  55. if (!opt)
  56. goto nomem;
  57. opt->label = strdup("authgroup:");
  58. opt->name = strdup("method");
  59. opt->type = OC_FORM_OPT_TEXT;
  60. opt2 = opt->next = calloc(1, sizeof(*opt2));
  61. if (!opt2)
  62. goto nomem;
  63. opt2->label = strdup("username:");
  64. opt2->name = strdup("uname");
  65. opt2->type = OC_FORM_OPT_TEXT;
  66. opt3 = opt2->next = calloc(1, sizeof(*opt3));
  67. if (!opt3)
  68. goto nomem;
  69. opt3->label = strdup("password:");
  70. opt3->name = strdup("pwd");
  71. opt3->type = OC_FORM_OPT_PASSWORD;
  72. return form;
  73. }
  74. int array_obtain_cookie(struct openconnect_info *vpninfo)
  75. {
  76. struct oc_auth_form *form = plain_auth_form();
  77. if (!form)
  78. return -ENOMEM;
  79. struct oc_text_buf *req_buf = buf_alloc();
  80. int ret;
  81. if ((ret = buf_error(req_buf)))
  82. goto out;
  83. do {
  84. ret = process_auth_form(vpninfo, form);
  85. } while (ret == OC_FORM_RESULT_NEWGROUP);
  86. if (ret)
  87. goto out;
  88. append_form_opts(vpninfo, form, req_buf);
  89. if ((ret = buf_error(req_buf)))
  90. goto out;
  91. free(vpninfo->urlpath);
  92. vpninfo->urlpath = strdup("prx/000/http/localhost/login");
  93. if (!vpninfo->urlpath) {
  94. ret = -ENOMEM;
  95. goto out;
  96. }
  97. char *resp_buf = NULL;
  98. ret = do_https_request(vpninfo, "POST",
  99. "application/x-www-form-urlencoded",
  100. req_buf, &resp_buf, NULL, HTTP_REDIRECT_TO_GET);
  101. free(resp_buf);
  102. if (ret <= 0)
  103. goto out;
  104. struct oc_vpn_option *cookie;
  105. for (cookie = vpninfo->cookies; cookie; cookie = cookie->next) {
  106. if (!strncmp(cookie->option, "ANsession", 9)) {
  107. free(vpninfo->cookie);
  108. if (asprintf(&vpninfo->cookie, "%s=%s", cookie->option, cookie->value) <= 0)
  109. return -ENOMEM;
  110. ret = 0;
  111. goto out;
  112. }
  113. }
  114. vpn_progress(vpninfo, PRG_INFO, _("No ANsession cookie found\n"));
  115. ret = -EPERM;
  116. out:
  117. if (form) free_auth_form(form);
  118. if (req_buf) buf_free(req_buf);
  119. printf("obtain return %d\n", ret);
  120. return ret;
  121. }
  122. /* XXX: Lifted from oncp.c. Share it. */
  123. static int parse_cookie(struct openconnect_info *vpninfo)
  124. {
  125. char *p = vpninfo->cookie;
  126. /* We currently expect the "cookie" to contain multiple cookies:
  127. * DSSignInUrl=/; DSID=xxx; DSFirstAccess=xxx; DSLastAccess=xxx
  128. * Process those into vpninfo->cookies unless we already had them
  129. * (in which case they may be newer). */
  130. while (p && *p) {
  131. char *semicolon = strchr(p, ';');
  132. char *equals;
  133. if (semicolon)
  134. *semicolon = 0;
  135. equals = strchr(p, '=');
  136. if (!equals) {
  137. vpn_progress(vpninfo, PRG_ERR, _("Invalid cookie '%s'\n"), p);
  138. return -EINVAL;
  139. }
  140. *equals = 0;
  141. http_add_cookie(vpninfo, p, equals+1, 0);
  142. *equals = '=';
  143. p = semicolon;
  144. if (p) {
  145. *p = ';';
  146. p++;
  147. while (*p && isspace((int)(unsigned char)*p))
  148. p++;
  149. }
  150. }
  151. return 0;
  152. }
  153. /* No idea what these structures are yet... */
  154. static const unsigned char conf50[] = { 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  155. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  156. static const unsigned char conf54[] = { 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  157. 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
  158. 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x0f,
  159. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  160. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  161. 0x52, 0x54, 0x00, 0xde, 0xa2, 0xa6, 0x00, 0x00 };
  162. static const unsigned char ipff[] = { 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
  163. 0x00, 0xff, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
  164. 0x00, 0x00, 0x00, 0x00 };
  165. static const struct pkt dpd_pkt = {
  166. .next = NULL,
  167. .data = { 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
  168. 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  169. 0x00, 0x00, 0x00, 0x00 },
  170. .len = 20,
  171. };
  172. static const struct pkt nodtls_pkt = {
  173. .next = NULL,
  174. .data = { 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
  175. 0x00, 0xff, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
  176. 0x00, 0x00, 0x00, 0x00 },
  177. .len = 20,
  178. };
  179. static int parse_one_inc_exc(struct openconnect_info *vpninfo, struct oc_vpn_option **opts,
  180. struct oc_ip_info *ip_info, int incl, int ipv6, json_value *val)
  181. {
  182. if (val->type != json_object) {
  183. vpn_progress(vpninfo, PRG_ERR, "Include not object\n");
  184. return -EINVAL;
  185. }
  186. /* We have no idea how they expose IPv6 yet. Hopefully not
  187. as wrong-endian integers like Legacy IP! */
  188. if (ipv6)
  189. return 0;
  190. uint32_t route_ip = 0, route_mask = 0;
  191. int route_ip_found = 0, route_mask_found = 0;
  192. for (int i = 0; i < val->u.object.length; i++) {
  193. json_char *child_name = val->u.object.values[i].name;
  194. json_value *child_val = val->u.object.values[i].value;
  195. if (child_val->type != json_integer)
  196. continue;
  197. if (!strcmp(child_name, "ip")) {
  198. store_le32(&route_ip, child_val->u.integer);
  199. route_ip_found = 1;
  200. } else if (!strcmp(child_name, "mask")) {
  201. store_le32(&route_mask, child_val->u.integer);
  202. route_mask_found = 1;
  203. }
  204. }
  205. if (route_ip_found && route_mask_found) {
  206. char buf[64];
  207. if (!inet_ntop(AF_INET, &route_ip, buf, sizeof(buf)/2))
  208. return -errno;
  209. char *p = buf + strlen(buf);
  210. *(p++) = '/';
  211. if (!inet_ntop(AF_INET, &route_mask, p, sizeof(buf) - (p - buf)))
  212. return -errno;
  213. vpn_progress(vpninfo, PRG_INFO, "Found split route %s\n", buf);
  214. struct oc_split_include *inc = malloc(sizeof (*inc));
  215. if (!inc)
  216. return -ENOMEM;
  217. struct oc_split_include **list;
  218. if (incl)
  219. list = &ip_info->split_includes;
  220. else
  221. list = &ip_info->split_excludes;
  222. inc->route = add_option_dup(opts, "split-include", buf, -1);
  223. inc->next = *list;
  224. *list = inc;
  225. }
  226. return 0;
  227. }
  228. static int parse_network_inc_exc(struct openconnect_info *vpninfo, struct oc_vpn_option **opts,
  229. struct oc_ip_info *ip_info, int incl, json_value *val)
  230. {
  231. int ret = 0;
  232. if (val->type != json_object) {
  233. vpn_progress(vpninfo, PRG_ERR, "Includes not object\n");
  234. return -EINVAL;
  235. }
  236. for (int i = 0; i < val->u.object.length; i++) {
  237. json_char *child_name = val->u.object.values[i].name;
  238. json_value *child_val = val->u.object.values[i].value;
  239. int is_ipv6;
  240. if (child_val->type != json_array)
  241. continue;
  242. if (!strcmp(child_name, "ipv6"))
  243. is_ipv6 = 1;
  244. else if (!strcmp(child_name, "ipv4"))
  245. is_ipv6 = 0;
  246. else
  247. continue;
  248. for (int j = 0; j < child_val->u.array.length; j++) {
  249. ret = parse_one_inc_exc(vpninfo, opts, ip_info, incl, is_ipv6,
  250. child_val->u.array.values[j]);
  251. if (ret)
  252. goto out;
  253. }
  254. }
  255. out:
  256. return ret;
  257. }
  258. static int parse_proxy_script(struct openconnect_info *vpninfo, struct oc_vpn_option **opts,
  259. struct oc_ip_info *ip_info, json_value *val)
  260. {
  261. return 0;
  262. }
  263. static int parse_dns_servers(struct openconnect_info *vpninfo, struct oc_vpn_option **opts,
  264. struct oc_ip_info *ip_info, json_value *val)
  265. {
  266. int servers_found = 0;
  267. if (val->type != json_array)
  268. return -EINVAL;
  269. /*
  270. * The 'dns_servers' object is an array, containing object[s] with
  271. * children named 'ipv4' and, presumably, 'ipv6'. Each of those is
  272. * *itself* an array. It isn't clear why we need an array of arrays.
  273. * Nor why IPv6 and Legacy IP need to be separate at all.
  274. *
  275. * "dns_servers": [{
  276. * "ipv4": [67373064, 134744072]
  277. * }],
  278. */
  279. for (int i = 0; i < val->u.array.length; i++) {
  280. json_value *elem1 = val->u.array.values[i];
  281. if (elem1->type != json_object)
  282. continue;
  283. for (int j = 0; j < elem1->u.object.length; j++) {
  284. json_char *child_name = elem1->u.object.values[j].name;
  285. json_value *child_val = elem1->u.object.values[j].value;
  286. if (child_val->type != json_array)
  287. continue;
  288. int legacyip;
  289. if (!strcmp(child_name, "ipv4"))
  290. legacyip = 1;
  291. else if (!strcmp(child_name, "ipv6"))
  292. legacyip = 0;
  293. else
  294. continue;
  295. for (int k = 0; k < child_val->u.array.length; k++) {
  296. json_value *elem2 = child_val->u.array.values[k];
  297. char buf[32];
  298. const char *server = buf;
  299. if (legacyip && elem2->type == json_integer) {
  300. uint32_t addr;
  301. store_le32(&addr, elem2->u.integer);
  302. if (!inet_ntop(AF_INET, &addr, buf, sizeof(buf)))
  303. return -errno;
  304. } else if (!legacyip && elem2->type == json_string) {
  305. server = elem2->u.string.ptr;
  306. } else continue;
  307. vpn_progress(vpninfo, PRG_INFO, _("Found DNS server %s\n"), server);
  308. if (servers_found < 3 &&
  309. (ip_info->dns[servers_found] =
  310. add_option_dup(opts, "DNS", server, -1)))
  311. servers_found++;
  312. }
  313. }
  314. }
  315. return 0;
  316. }
  317. static int parse_search_domains(struct openconnect_info *vpninfo, struct oc_vpn_option **opts,
  318. struct oc_ip_info *ip_info, json_value *val)
  319. {
  320. if (val->type != json_array)
  321. return -EINVAL;
  322. struct oc_text_buf *domains = buf_alloc();
  323. for (int i = 0; i < val->u.array.length; i++) {
  324. json_value *elem = val->u.array.values[i];
  325. if (elem->type != json_string)
  326. continue;
  327. vpn_progress(vpninfo, PRG_INFO, _("Got search domain '%s'\n"),
  328. elem->u.string.ptr);
  329. buf_append(domains, "%s ", elem->u.string.ptr);
  330. }
  331. if (buf_error(domains))
  332. return buf_free(domains);
  333. if (domains->pos) {
  334. domains->data[domains->pos - 1] = '\0';
  335. ip_info->domain = add_option_steal(opts, "search", &domains->data);
  336. }
  337. buf_free(domains);
  338. return 0;
  339. }
  340. static int parse_interface_info(struct openconnect_info *vpninfo,
  341. json_value *val)
  342. {
  343. struct oc_vpn_option *new_opts = NULL;
  344. struct oc_ip_info new_ip_info = {};
  345. int i, ret = 0;
  346. if (val->type != json_object)
  347. return -EINVAL;
  348. for (i = 0; i < val->u.object.length; i++) {
  349. json_char *child_name = val->u.object.values[i].name;
  350. json_value *child_val = val->u.object.values[i].value;
  351. if (child_val->type == json_integer) {
  352. json_int_t ival = child_val->u.integer;
  353. /* The Array server gives us Legacy IP addresses as
  354. * decimal integers, in wrong-endian form. So an IP
  355. * address of e.g. 1.2.3.4 is presented as 0x04030201
  356. * or "client_ipv4: 67305985" in the JSON response.
  357. * Obviously, integers represented as decimal strings
  358. * don't have an endianness on the wire per se; this
  359. * is only "wrong" endian. So... since the address in
  360. * struct in_addr is supposed to be stored in network
  361. * (big) endian form, we need to store the
  362. * wrong-endian integer as *little* endian in order
  363. * end up with the correct result. */
  364. if (!strcmp(child_name, "client_ipv4")) {
  365. uint32_t ip;
  366. store_le32(&ip, ival);
  367. new_ip_info.addr = add_option_ipaddr(&new_opts,
  368. "client_ipv4",
  369. AF_INET, &ip);
  370. printf("Found Legacy IP address %s\n", new_ip_info.addr);
  371. } else if (!strcmp(child_name, "client_ipv4_mask")) {
  372. uint32_t mask;
  373. store_le32(&mask, ival);
  374. new_ip_info.netmask = add_option_ipaddr(&new_opts,
  375. "client_ipv4_mask",
  376. AF_INET, &mask);
  377. printf("Found Legacy IP netmask %s\n", new_ip_info.netmask);
  378. }
  379. else goto unknown;
  380. } else if (child_val->type == json_object) {
  381. if (!strcmp(child_name, "include_network_resource")) {
  382. ret = parse_network_inc_exc(vpninfo, &new_opts, &new_ip_info,
  383. 1, child_val);
  384. } else if (!strcmp(child_name, "exclude_network_resource")) {
  385. ret = parse_network_inc_exc(vpninfo, &new_opts, &new_ip_info,
  386. 0, child_val);
  387. } else if (!strcmp(child_name, "proxy_script")) {
  388. ret = parse_proxy_script(vpninfo, &new_opts, &new_ip_info,
  389. child_val);
  390. }
  391. else goto unknown;
  392. } else if (child_val->type == json_array) {
  393. if (!strcmp(child_name, "dns_servers")) {
  394. ret = parse_dns_servers(vpninfo, &new_opts, &new_ip_info,
  395. child_val);
  396. } else if (!strcmp(child_name, "search_domains")) {
  397. ret = parse_search_domains(vpninfo, &new_opts, &new_ip_info,
  398. child_val);
  399. }
  400. else goto unknown;
  401. } else {
  402. unknown:
  403. vpn_progress(vpninfo, PRG_DEBUG,
  404. _("Unknown Array config element '%s'\n"),
  405. child_name);
  406. }
  407. if (ret)
  408. goto out;
  409. }
  410. if (!ret)
  411. ret = install_vpn_opts(vpninfo, new_opts, &new_ip_info);
  412. out:
  413. if (ret) {
  414. free_optlist(new_opts);
  415. free_split_routes(&new_ip_info);
  416. }
  417. return ret;
  418. }
  419. static int parse_speed_tunnel(struct openconnect_info *vpninfo,
  420. json_value *val)
  421. {
  422. int speed_tunnel = 0, speed_tunnel_enc = 0, dpd = 0;
  423. int i;
  424. for (i = 0; i < val->u.object.length; i++) {
  425. json_char *child_name = val->u.object.values[i].name;
  426. json_value *child_val = val->u.object.values[i].value;
  427. if (child_val->type == json_integer) {
  428. json_int_t ival = child_val->u.integer;
  429. if (!strcmp(child_name, "allow_speed_tunnel"))
  430. speed_tunnel = ival;
  431. else if (!strcmp(child_name, "speed_tunnel_encryption"))
  432. speed_tunnel_enc = ival;
  433. else if (!strcmp(child_name, "keepalive_interval"))
  434. dpd = ival;
  435. }
  436. }
  437. vpn_progress(vpninfo, PRG_INFO,
  438. _("Initial config: Speed tunnel %d, enc %d, DPD %d\n"),
  439. speed_tunnel, speed_tunnel_enc, dpd);
  440. if (!speed_tunnel)
  441. vpninfo->dtls_state = DTLS_DISABLED;
  442. /* We don't support DPD yet...*/
  443. if (dpd) {
  444. if (!vpninfo->ssl_times.dpd)
  445. vpninfo->ssl_times.dpd = dpd;
  446. if (!vpninfo->dtls_times.dpd)
  447. vpninfo->dtls_times.dpd = dpd;
  448. }
  449. return 0;
  450. }
  451. static int do_json_request(struct openconnect_info *vpninfo, void *req, int reqlen,
  452. int (*rq_parser)(struct openconnect_info *vpninfo,
  453. json_value *val))
  454. {
  455. unsigned char bytes[16384];
  456. int ret;
  457. if (vpninfo->dump_http_traffic)
  458. dump_buf_hex(vpninfo, PRG_DEBUG, '>', req, reqlen);
  459. ret = vpninfo->ssl_write(vpninfo, req, reqlen);
  460. if (ret != reqlen) {
  461. if (ret >= 0) {
  462. vpn_progress(vpninfo, PRG_ERR,
  463. _("Short write in Array JSON negotiation\n"));
  464. return -EIO;
  465. }
  466. return ret;
  467. }
  468. ret = vpninfo->ssl_read(vpninfo, (void *)bytes, sizeof(bytes));
  469. if (ret < 0) {
  470. vpn_progress(vpninfo, PRG_ERR,
  471. _("Failed to read Array JSON response\n"));
  472. return ret;
  473. }
  474. if (vpninfo->dump_http_traffic)
  475. dump_buf_hex(vpninfo, PRG_DEBUG, '<', bytes, ret);
  476. if (ret <= 16 || bytes[16] != '{') {
  477. vpn_progress(vpninfo, PRG_ERR,
  478. _("Unexpected response to Array JSON request\n"));
  479. return -EINVAL;
  480. }
  481. dump_buf(vpninfo, '<', (char *)bytes + 16);
  482. json_settings settings = { 0 };
  483. char json_err[json_error_max];
  484. json_value *val = json_parse_ex(&settings, (json_char *)bytes + 16, ret - 16, json_err);
  485. if (!val) {
  486. eparse:
  487. vpn_progress(vpninfo, PRG_ERR,
  488. _("Failed to parse Array JSON response\n"));
  489. return -EINVAL;
  490. }
  491. if (vpninfo->verbose >= PRG_DEBUG)
  492. dump_json(vpninfo, PRG_DEBUG, val);
  493. if (val->type != json_object) {
  494. json_value_free(val);
  495. goto eparse;
  496. }
  497. ret = rq_parser(vpninfo, val);
  498. json_value_free(val);
  499. return ret;
  500. }
  501. int array_connect(struct openconnect_info *vpninfo)
  502. {
  503. int ret;
  504. struct oc_text_buf *reqbuf;
  505. unsigned char bytes[65536];
  506. if (!vpninfo->cookies) {
  507. ret = parse_cookie(vpninfo);
  508. if (ret)
  509. return ret;
  510. }
  511. /* We abuse ppp_tls_connect_req for the random client-id */
  512. if (!vpninfo->ppp_tls_connect_req) {
  513. unsigned char bin[16];
  514. ret = openconnect_random(bin, sizeof(bin));
  515. if (ret)
  516. return ret;
  517. struct oc_text_buf *buf = buf_alloc();
  518. buf_append(buf, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
  519. bin[0], bin[1], bin[2], bin[3], bin[4], bin[5], bin[6], bin[7],
  520. bin[8], bin[9], bin[10], bin[11], bin[12], bin[13], bin[14], bin[15]);
  521. if (buf_error(buf))
  522. return buf_free(buf);
  523. vpninfo->ppp_tls_connect_req = buf;
  524. /* Now build the request we actually send over DTLS, which
  525. * must have "13" following the client-id. Without that at
  526. * the end, we can send over DTLS but the worker process
  527. * seems to crash as soon as it needs to send us anything
  528. * more than a keepalive response. */
  529. buf = buf_alloc();
  530. buf_append(buf, "%s13", vpninfo->ppp_tls_connect_req->data);
  531. if (buf_error(buf))
  532. return buf_free(buf);
  533. vpninfo->ppp_dtls_connect_req = buf;
  534. }
  535. ret = openconnect_open_https(vpninfo);
  536. if (ret)
  537. return ret;
  538. reqbuf = buf_alloc();
  539. buf_append(reqbuf, "GET /vpntunnel HTTP/1.1\r\n");
  540. http_common_headers(vpninfo, reqbuf);
  541. buf_append(reqbuf, "appid: SSPVPN\r\n");
  542. buf_append(reqbuf, "clientid: %s\r\n", vpninfo->ppp_tls_connect_req->data);
  543. buf_append(reqbuf, "cpuid: %s\r\n", vpninfo->ppp_tls_connect_req->data);
  544. buf_append(reqbuf, "hostname: %s\r\n", vpninfo->localname);
  545. buf_append(reqbuf, "payload-ip-version: 6\r\n");
  546. buf_append(reqbuf, "x-devtype: 6\r\n");
  547. buf_append(reqbuf, "\r\n");
  548. if (buf_error(reqbuf)) {
  549. vpn_progress(vpninfo, PRG_ERR,
  550. _("Error creating array negotiation request\n"));
  551. ret = buf_error(reqbuf);
  552. goto out;
  553. }
  554. if (vpninfo->dump_http_traffic)
  555. dump_buf(vpninfo, '>', reqbuf->data);
  556. ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
  557. if (ret < 0)
  558. goto out;
  559. ret = process_http_response(vpninfo, 1, NULL, reqbuf);
  560. if (ret < 0)
  561. goto out;
  562. if (ret != 201 && ret != 200) {
  563. vpn_progress(vpninfo, PRG_ERR,
  564. _("Unexpected %d result from server\n"),
  565. ret);
  566. /* We get a redirect to /prx/000/http/localhost/cookietest when
  567. * the cookie has expired. */
  568. if (ret == 302 || vpninfo->redirect_url)
  569. ret = -EPERM;
  570. else
  571. ret = -EINVAL;
  572. goto out;
  573. }
  574. ret = do_json_request(vpninfo, (void *)conf50, sizeof(conf50),
  575. parse_speed_tunnel);
  576. if (ret)
  577. goto out;
  578. ret = do_json_request(vpninfo, (void *)conf54, sizeof(conf54),
  579. parse_interface_info);
  580. if (ret)
  581. goto out;
  582. if (vpninfo->dtls_state != DTLS_DISABLED) {
  583. struct oc_text_buf *dtlsbuf = buf_alloc();
  584. buf_append_bytes(dtlsbuf, (void *)ipff, 16);
  585. buf_append(dtlsbuf, "%s", vpninfo->ppp_tls_connect_req->data);
  586. if (buf_error(dtlsbuf)) {
  587. vpn_progress(vpninfo, PRG_ERR,
  588. _("Error building Array DTLS negotiation packet\n"));
  589. vpninfo->dtls_state = DTLS_DISABLED;
  590. ret = buf_free(dtlsbuf);
  591. goto out;
  592. }
  593. store_be16(dtlsbuf->data + 12, 4);
  594. store_be16(dtlsbuf->data + 2, dtlsbuf->pos);
  595. if (vpninfo->dump_http_traffic)
  596. dump_buf_hex(vpninfo, PRG_DEBUG, '>', (void *)dtlsbuf->data,
  597. dtlsbuf->pos);
  598. ret = vpninfo->ssl_write(vpninfo, (void *)dtlsbuf->data, dtlsbuf->pos);
  599. if (ret != dtlsbuf->pos) {
  600. buf_free(dtlsbuf);
  601. if (ret >= 0) {
  602. vpn_progress(vpninfo, PRG_ERR,
  603. _("Short write in array negotiation\n"));
  604. ret = -EIO;
  605. }
  606. goto out;
  607. }
  608. buf_free(dtlsbuf);
  609. ret = vpninfo->ssl_read(vpninfo, (void *)bytes, sizeof(bytes));
  610. if (ret < 0) {
  611. vpn_progress(vpninfo, PRG_ERR,
  612. _("Failed to read UDP negotiation response\n"));
  613. ret = -EIO;
  614. goto out;
  615. }
  616. /* Parse it, learn what we need from it */
  617. if (vpninfo->dump_http_traffic)
  618. dump_buf_hex(vpninfo, PRG_DEBUG, '<', bytes, ret);
  619. if (ret == 0x25 && !memcmp(bytes + 0x14, "DTLS SPEED TUNNEL", 0x11)) {
  620. int udp_port = load_be16(bytes + 0x12);
  621. vpn_progress(vpninfo, PRG_INFO, _("DTLS enabled on port %d\n"),
  622. udp_port);
  623. udp_sockaddr(vpninfo, udp_port);
  624. if (vpninfo->dtls_state == DTLS_NOSECRET)
  625. vpninfo->dtls_state = DTLS_SECRET;
  626. } else {
  627. /* The 'encrypted' UDP tunnel without DTLS looks like it's using
  628. * the same key repeatedly without IV or replay protection. I'm
  629. * not touching it with a bargepole, or the unencrypted one. */
  630. vpn_progress(vpninfo, PRG_INFO,
  631. _("Refusing non-DTLS UDP tunnel\n"));
  632. vpninfo->dtls_state = DTLS_DISABLED;
  633. }
  634. }
  635. #if 0
  636. /* Send third request 'ipff' */
  637. dump_buf_hex(vpninfo, PRG_DEBUG, '>', (void *)ipff, sizeof(ipff));
  638. ret = vpninfo->ssl_write(vpninfo, (void *)ipff, sizeof(ipff));
  639. if (ret != sizeof(ipff)) {
  640. shortwrite:
  641. if (ret >= 0) {
  642. vpn_progress(vpninfo, PRG_ERR,
  643. _("Short write in array negotiation\n"));
  644. ret = -EIO;
  645. }
  646. goto out;
  647. }
  648. ret = vpninfo->ssl_read(vpninfo, (void *)bytes, sizeof(bytes));
  649. if (ret < 0) {
  650. vpn_progress(vpninfo, PRG_ERR,
  651. _("Failed to read ipff response\n"));
  652. goto out;
  653. }
  654. /* Parse it, learn what we need from it */
  655. dump_buf_hex(vpninfo, PRG_DEBUG, '<', bytes, ret);
  656. #endif
  657. vpninfo->tcp_blocked_for_udp = 0;
  658. ret = 0; /* success */
  659. out:
  660. if (ret)
  661. openconnect_close_https(vpninfo, 0);
  662. else {
  663. monitor_fd_new(vpninfo, ssl);
  664. monitor_read_fd(vpninfo, ssl);
  665. monitor_except_fd(vpninfo, ssl);
  666. vpninfo->ssl_times.last_rx = vpninfo->ssl_times.last_tx = time(NULL);
  667. }
  668. buf_free(reqbuf);
  669. free_pkt(vpninfo, vpninfo->cstp_pkt);
  670. vpninfo->cstp_pkt = NULL;
  671. vpninfo->ip_info.mtu = 1400;
  672. return ret;
  673. }
  674. int array_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
  675. {
  676. int ret;
  677. int work_done = 0;
  678. if (vpninfo->ssl_fd == -1)
  679. goto do_reconnect;
  680. /* FIXME: The poll() handling here is fairly simplistic. Actually,
  681. if the SSL connection stalls it could return a WANT_WRITE error
  682. on _either_ of the SSL_read() or SSL_write() calls. In that case,
  683. we should probably remove POLLIN from the events we're looking for,
  684. and add POLLOUT. As it is, though, it'll just chew CPU time in that
  685. fairly unlikely situation, until the write backlog clears. */
  686. while (readable) {
  687. /* Some servers send us packets that are larger than
  688. negotiated MTU. We reserve some extra space to
  689. handle that */
  690. int receive_mtu = MAX(16384, vpninfo->deflate_pkt_size ? : vpninfo->ip_info.mtu);
  691. int len;
  692. if (!vpninfo->cstp_pkt) {
  693. vpninfo->partial_rec_size = 0;
  694. vpninfo->cstp_pkt = alloc_pkt(vpninfo, receive_mtu);
  695. if (!vpninfo->cstp_pkt) {
  696. vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
  697. break;
  698. }
  699. }
  700. len = ssl_nonblock_read(vpninfo, 0,
  701. vpninfo->cstp_pkt->data + vpninfo->partial_rec_size,
  702. receive_mtu - vpninfo->partial_rec_size);
  703. if (!len)
  704. break;
  705. if (len < 0)
  706. goto do_reconnect;
  707. if (vpninfo->partial_rec_size) {
  708. vpn_progress(vpninfo, PRG_DEBUG,
  709. _("Received %d more bytes after partial %d\n"),
  710. len, vpninfo->partial_rec_size);
  711. len += vpninfo->partial_rec_size;
  712. vpninfo->partial_rec_size = 0;
  713. }
  714. vpninfo->ssl_times.last_rx = time(NULL);
  715. work_done = 1;
  716. unsigned char *buf = vpninfo->cstp_pkt->data;
  717. int iplen;
  718. next_ip:
  719. if (len < sizeof(struct ip)) {
  720. vpn_progress(vpninfo, PRG_DEBUG,
  721. _("Received partial packet, %d bytes\n"), len);
  722. vpninfo->partial_rec_size = len;
  723. continue;
  724. }
  725. switch(buf[0] >> 4) {
  726. case 4:
  727. iplen = load_be16(buf + 2);
  728. break;
  729. case 6:
  730. iplen = load_be16(buf + 4) + 40;
  731. break;
  732. default:
  733. badiplen:
  734. vpn_progress(vpninfo, PRG_ERR,
  735. _("Unrecognised data packet, len %d\n"), len);
  736. dump_buf_hex(vpninfo, PRG_DEBUG, '<', buf, len);
  737. continue;
  738. }
  739. if (iplen > receive_mtu)
  740. goto badiplen;
  741. /* Argh. It even splits IP packets across TLS records. */
  742. if (iplen > len) {
  743. vpn_progress(vpninfo, PRG_DEBUG,
  744. _("Received partial packet, %d of %d bytes\n"),
  745. len, iplen);
  746. vpninfo->partial_rec_size = len;
  747. continue;
  748. }
  749. /* Dump control packets but don't queue them */
  750. if (buf[0] == 0x45 && buf[9] == 0xff) {
  751. uint16_t ctrl_type = load_be16(buf + 12);
  752. vpn_progress(vpninfo, PRG_DEBUG,
  753. _("Receive control packet of type %x:\n"),
  754. ctrl_type);
  755. dump_buf_hex(vpninfo, PRG_DEBUG, '<', buf, len);
  756. if (iplen == len)
  757. continue;
  758. } else {
  759. vpn_progress(vpninfo, PRG_TRACE,
  760. _("Received data packet of %d bytes\n"),
  761. iplen);
  762. if (iplen == len) {
  763. /* This buffer (now) contains just a single IP packet */
  764. vpninfo->cstp_pkt->len = iplen;
  765. queue_packet(&vpninfo->incoming_queue, vpninfo->cstp_pkt);
  766. vpninfo->cstp_pkt = NULL;
  767. continue;
  768. } else {
  769. /* Awfully inefficient for now. We *copy* the packet into
  770. * a new buffer and then memmove the subsequent one(s)
  771. * down in the original buffer. */
  772. queue_new_packet(vpninfo, &vpninfo->incoming_queue,
  773. buf, iplen);
  774. }
  775. }
  776. /* Move the next packet(s) up to the head of the existing buffer */
  777. len -= iplen;
  778. memmove(buf, buf + iplen, len);
  779. vpn_progress(vpninfo, PRG_TRACE,
  780. _("Moved down %d bytes after previous packet\n"), len);
  781. goto next_ip;
  782. }
  783. /* If SSL_write() fails we are expected to try again. With exactly
  784. the same data, at exactly the same location. So we keep the
  785. packet we had before.... */
  786. if (vpninfo->current_ssl_pkt) {
  787. handle_outgoing:
  788. vpninfo->ssl_times.last_tx = time(NULL);
  789. unmonitor_write_fd(vpninfo, ssl);
  790. ret = ssl_nonblock_write(vpninfo, 0,
  791. vpninfo->current_ssl_pkt->data,
  792. vpninfo->current_ssl_pkt->len);
  793. if (ret < 0)
  794. goto do_reconnect;
  795. else if (!ret) {
  796. /* -EAGAIN: ssl_nonblock_write() will have added the SSL
  797. fd to ->select_wfds if appropriate, so we can just
  798. return and wait. Unless it's been stalled for so long
  799. that DPD kicks in and we kill the connection. */
  800. switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) {
  801. case KA_DPD_DEAD:
  802. goto peer_dead;
  803. case KA_REKEY:
  804. goto do_rekey;
  805. case KA_NONE:
  806. return work_done;
  807. default:
  808. /* This should never happen */
  809. break;
  810. }
  811. }
  812. if (ret != vpninfo->current_ssl_pkt->len) {
  813. vpn_progress(vpninfo, PRG_ERR,
  814. _("SSL wrote too few bytes! Asked for %d, sent %d\n"),
  815. vpninfo->current_ssl_pkt->len + 8, ret);
  816. vpninfo->quit_reason = "Internal error";
  817. return 1;
  818. }
  819. /* Don't free the 'special' packets */
  820. if (vpninfo->current_ssl_pkt != &dpd_pkt &&
  821. vpninfo->current_ssl_pkt != &nodtls_pkt)
  822. free_pkt(vpninfo, vpninfo->current_ssl_pkt);
  823. vpninfo->current_ssl_pkt = NULL;
  824. }
  825. switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
  826. case KA_REKEY:
  827. do_rekey:
  828. /* Not that this will ever happen; we don't even process
  829. the setting when we're asked for it. */
  830. vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
  831. if (vpninfo->ssl_times.rekey_method == REKEY_TUNNEL)
  832. goto do_reconnect;
  833. else if (vpninfo->ssl_times.rekey_method == REKEY_SSL) {
  834. ret = cstp_handshake(vpninfo, 0);
  835. if (ret) {
  836. /* if we failed rehandshake try establishing a new-tunnel instead of failing */
  837. vpn_progress(vpninfo, PRG_ERR, _("Rehandshake failed; attempting new-tunnel\n"));
  838. goto do_reconnect;
  839. }
  840. goto do_dtls_reconnect;
  841. }
  842. break;
  843. case KA_DPD_DEAD:
  844. peer_dead:
  845. vpn_progress(vpninfo, PRG_ERR,
  846. _("TCP Dead Peer Detection detected dead peer!\n"));
  847. do_reconnect:
  848. ret = ssl_reconnect(vpninfo);
  849. if (ret) {
  850. vpn_progress(vpninfo, PRG_ERR, _("TCP reconnect failed\n"));
  851. vpninfo->quit_reason = "TCP reconnect failed";
  852. return ret;
  853. }
  854. do_dtls_reconnect:
  855. /* succeeded, let's rekey DTLS, if it is not rekeying
  856. * itself. */
  857. if (vpninfo->dtls_state > DTLS_SLEEPING &&
  858. vpninfo->dtls_times.rekey_method == REKEY_NONE) {
  859. vpninfo->dtls_need_reconnect = 1;
  860. }
  861. return 1;
  862. case KA_DPD:
  863. vpn_progress(vpninfo, PRG_DEBUG, _("Send TCP DPD\n"));
  864. /* last_dpd will just have been set */
  865. vpninfo->dtls_times.last_tx = vpninfo->dtls_times.last_dpd;
  866. work_done = 1;
  867. vpninfo->current_ssl_pkt = (struct pkt *)&dpd_pkt;
  868. goto handle_outgoing;
  869. break;
  870. case KA_KEEPALIVE:
  871. /* No need to send an explicit keepalive
  872. if we have real data to send */
  873. if (vpninfo->dtls_state != DTLS_ESTABLISHED &&
  874. vpninfo->outgoing_queue.head)
  875. break;
  876. vpn_progress(vpninfo, PRG_DEBUG, _("Send TCP Keepalive\n"));
  877. //vpninfo->current_ssl_pkt = (struct pkt *)&keepalive_pkt;
  878. //goto handle_outgoing;
  879. break;
  880. case KA_NONE:
  881. ;
  882. }
  883. if (vpninfo->dtls_state != DTLS_ESTABLISHED &&
  884. vpninfo->tcp_blocked_for_udp) {
  885. vpninfo->current_ssl_pkt = (struct pkt *)&nodtls_pkt;
  886. vpninfo->tcp_blocked_for_udp = 0;
  887. vpn_progress(vpninfo, PRG_TRACE,
  888. _("Sending DTLS off packet\n"));
  889. goto handle_outgoing;
  890. }
  891. /* Service outgoing packet queue, if no DTLS */
  892. while (vpninfo->dtls_state != DTLS_ESTABLISHED &&
  893. (vpninfo->current_ssl_pkt = dequeue_packet(&vpninfo->outgoing_queue))) {
  894. struct pkt *this = vpninfo->current_ssl_pkt;
  895. vpn_progress(vpninfo, PRG_TRACE,
  896. _("Sending uncompressed data packet of %d bytes\n"),
  897. this->len);
  898. vpninfo->current_ssl_pkt = this;
  899. goto handle_outgoing;
  900. }
  901. /* Work is not done if we just got rid of packets off the queue */
  902. return work_done;
  903. }
  904. int array_dtls_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
  905. {
  906. int work_done = 0;
  907. time_t now = time(NULL);
  908. int first_connected = 0;
  909. if (vpninfo->dtls_need_reconnect) {
  910. vpninfo->dtls_need_reconnect = 0;
  911. dtls_reconnect(vpninfo, timeout);
  912. return 1;
  913. }
  914. if (vpninfo->dtls_state == DTLS_CONNECTING) {
  915. dtls_try_handshake(vpninfo, timeout);
  916. if (vpninfo->dtls_state == DTLS_CONNECTED) {
  917. first_connected = 1;
  918. goto newly_connected;
  919. }
  920. vpninfo->delay_tunnel_reason = "DTLS establishing";
  921. return 0;
  922. }
  923. if (vpninfo->dtls_state == DTLS_SLEEPING) {
  924. int when = vpninfo->new_dtls_started + vpninfo->dtls_attempt_period - time(NULL);
  925. if (when <= 0) {
  926. vpn_progress(vpninfo, PRG_DEBUG, _("Attempt new DTLS connection\n"));
  927. if (dtls_reconnect(vpninfo, timeout) < 0)
  928. *timeout = 1000;
  929. } else if ((when * 1000) < *timeout) {
  930. *timeout = when * 1000;
  931. }
  932. return 0;
  933. }
  934. /* Nothing to do here for Cisco DTLS as it is preauthenticated */
  935. if (vpninfo->dtls_state == DTLS_CONNECTED) {
  936. /* First, see if there's a response for us. */
  937. while(readable) {
  938. int receive_mtu = MAX(16384, vpninfo->ip_info.mtu);
  939. int len;
  940. /* cstp_pkt is used by PPP over either transport, and TCP
  941. * may be in active use while we attempt to connect DTLS.
  942. * So use vpninfo->dtls_pkt for this. */
  943. if (!vpninfo->dtls_pkt)
  944. vpninfo->dtls_pkt = alloc_pkt(vpninfo, receive_mtu);
  945. if (!vpninfo->dtls_pkt) {
  946. vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
  947. dtls_close(vpninfo);
  948. vpninfo->dtls_state = DTLS_DISABLED;
  949. return 1;
  950. }
  951. struct pkt *this = vpninfo->dtls_pkt;
  952. len = ssl_nonblock_read(vpninfo, 1, this->data, receive_mtu);
  953. if (!len)
  954. break;
  955. if (len < 0) {
  956. vpn_progress(vpninfo, PRG_ERR,
  957. _("Failed to receive authentication response from DTLS\n"));
  958. dtls_close(vpninfo);
  959. return 1;
  960. }
  961. this->len = len;
  962. if (vpninfo->dump_http_traffic)
  963. dump_buf_hex(vpninfo, PRG_DEBUG, '<', this->data, len);
  964. if (len >= 6 && !memcmp(this->data, "200 OK", 6)) {
  965. vpn_progress(vpninfo, PRG_TRACE,
  966. _("DTLS session established\n"));
  967. vpninfo->dtls_state = DTLS_ESTABLISHED;
  968. vpninfo->tcp_blocked_for_udp = 1;
  969. goto established;
  970. }
  971. /* The '200 OK' packet might get dropped; we *assume* the server
  972. * won't resend it even if we send the clientip again, so let's
  973. * take IP traffic as 'success' too. */
  974. if (len >= sizeof(struct ip) && (this->data[0] >> 4) == 4 &&
  975. load_be16(this->data + 2) == len) {
  976. /* Looks like a Legacy IP packet; the '200 OK' was
  977. * probably dropped. */
  978. vpn_progress(vpninfo, PRG_TRACE,
  979. _("Received Legacy IP over DTLS; assuming established\n"));
  980. vpninfo->dtls_state = DTLS_ESTABLISHED;
  981. vpninfo->tcp_blocked_for_udp = 1;
  982. goto got_pkt;
  983. }
  984. if (len >= sizeof(struct ip6_hdr) && (this->data[0] >> 4) == 6 &&
  985. len == load_be16(this->data + 4) + sizeof(struct ip6_hdr)) {
  986. vpn_progress(vpninfo, PRG_TRACE,
  987. _("Received IPv6 over DTLS; assuming established\n"));
  988. vpninfo->dtls_state = DTLS_ESTABLISHED;
  989. vpninfo->tcp_blocked_for_udp = 1;
  990. goto got_pkt;
  991. }
  992. vpn_progress(vpninfo, PRG_TRACE,
  993. _("Received unknown DTLS packet\n"));
  994. }
  995. /* Resend the connect request every second */
  996. if (ka_check_deadline(timeout, now, vpninfo->dtls_times.last_tx + 1)) {
  997. newly_connected:
  998. if (buf_error(vpninfo->ppp_dtls_connect_req)) {
  999. vpn_progress(vpninfo, PRG_ERR,
  1000. _("Error creating connect request for DTLS session\n"));
  1001. dtls_close(vpninfo);
  1002. vpninfo->dtls_state = DTLS_DISABLED;
  1003. return 1;
  1004. }
  1005. if (vpninfo->dump_http_traffic)
  1006. dump_buf_hex(vpninfo, PRG_DEBUG, '>',
  1007. (void *)vpninfo->ppp_dtls_connect_req->data,
  1008. vpninfo->ppp_dtls_connect_req->pos);
  1009. int ret = ssl_nonblock_write(vpninfo, 1,
  1010. vpninfo->ppp_dtls_connect_req->data,
  1011. vpninfo->ppp_dtls_connect_req->pos);
  1012. if (ret < 0) {
  1013. vpn_progress(vpninfo, PRG_ERR,
  1014. _("Failed to write connect request to DTLS session\n"));
  1015. dtls_close(vpninfo);
  1016. vpninfo->dtls_state = DTLS_DISABLED;
  1017. return 1;
  1018. }
  1019. /* On the second and subsequent attempt, send a keepalive packet
  1020. * too. The server will *ignore* the clientid packet on a resend
  1021. * so we have to send this too to elicit a response. Sadly, if
  1022. * this ends up being the *first* packet it receives, it cuts
  1023. * us off. */
  1024. if (!first_connected) {
  1025. if (vpninfo->dump_http_traffic)
  1026. dump_buf_hex(vpninfo, PRG_DEBUG, '>',
  1027. (void *)dpd_pkt.data, dpd_pkt.len);
  1028. ssl_nonblock_write(vpninfo, 1, (void *)dpd_pkt.data, dpd_pkt.len);
  1029. }
  1030. vpninfo->dtls_times.last_tx = now;
  1031. }
  1032. return 0;
  1033. }
  1034. if (vpninfo->dtls_state != DTLS_ESTABLISHED)
  1035. return 0;
  1036. established:
  1037. while (readable) {
  1038. int len = MAX(16384, vpninfo->ip_info.mtu);
  1039. unsigned char *buf;
  1040. if (!vpninfo->dtls_pkt) {
  1041. vpninfo->dtls_pkt = alloc_pkt(vpninfo, len);
  1042. if (!vpninfo->dtls_pkt) {
  1043. vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
  1044. break;
  1045. }
  1046. }
  1047. buf = vpninfo->dtls_pkt->data;
  1048. len = ssl_nonblock_read(vpninfo, 1, buf, len);
  1049. if (len <= 0)
  1050. break;
  1051. vpninfo->dtls_pkt->len = len;
  1052. if (0) {
  1053. got_pkt:
  1054. len = vpninfo->dtls_pkt->len;
  1055. buf = vpninfo->dtls_pkt->data;
  1056. }
  1057. vpn_progress(vpninfo, PRG_TRACE,
  1058. _("Received DTLS packet 0x%02x of %d bytes\n"),
  1059. buf[0], len);
  1060. vpninfo->dtls_times.last_rx = time(NULL);
  1061. if (len >= sizeof(struct ip) && buf[0] == 0x45 &&
  1062. load_be16(buf + 2) == len && buf[9] == 0xff) {
  1063. uint16_t ctrl_type = load_be16(buf + 12);
  1064. vpn_progress(vpninfo, PRG_DEBUG,
  1065. _("Receive control packet of type %x:\n"),
  1066. ctrl_type);
  1067. dump_buf_hex(vpninfo, PRG_DEBUG, '<', buf, len);
  1068. continue;
  1069. }
  1070. queue_packet(&vpninfo->incoming_queue, vpninfo->dtls_pkt);
  1071. vpninfo->dtls_pkt = NULL;
  1072. work_done = 1;
  1073. }
  1074. switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
  1075. case KA_REKEY: {
  1076. int ret;
  1077. vpn_progress(vpninfo, PRG_INFO, _("DTLS rekey due\n"));
  1078. if (vpninfo->dtls_times.rekey_method == REKEY_SSL) {
  1079. time(&vpninfo->new_dtls_started);
  1080. vpninfo->dtls_state = DTLS_CONNECTING;
  1081. ret = dtls_try_handshake(vpninfo, timeout);
  1082. if (ret) {
  1083. vpn_progress(vpninfo, PRG_ERR, _("DTLS Rehandshake failed; reconnecting.\n"));
  1084. return dtls_reconnect(vpninfo, timeout);
  1085. }
  1086. }
  1087. return 1;
  1088. }
  1089. case KA_DPD_DEAD:
  1090. vpn_progress(vpninfo, PRG_ERR, _("DTLS Dead Peer Detection detected dead peer!\n"));
  1091. /* Fall back to SSL, and start a new DTLS connection */
  1092. dtls_reconnect(vpninfo, timeout);
  1093. return 1;
  1094. case KA_DPD:
  1095. vpn_progress(vpninfo, PRG_DEBUG, _("Send DTLS DPD\n"));
  1096. if (ssl_nonblock_write(vpninfo, 1, (void *)dpd_pkt.data, dpd_pkt.len) != dpd_pkt.len)
  1097. vpn_progress(vpninfo, PRG_ERR,
  1098. _("Failed to send DPD request. Expect disconnect\n"));
  1099. /* last_dpd will just have been set */
  1100. vpninfo->dtls_times.last_tx = vpninfo->dtls_times.last_dpd;
  1101. work_done = 1;
  1102. break;
  1103. case KA_KEEPALIVE: /* We don't do keepalive; only DPD */
  1104. case KA_NONE:
  1105. ;
  1106. }
  1107. /* Service outgoing packet queue */
  1108. unmonitor_write_fd(vpninfo, dtls);
  1109. while (vpninfo->outgoing_queue.head) {
  1110. struct pkt *this = dequeue_packet(&vpninfo->outgoing_queue);
  1111. struct pkt *send_pkt = this;
  1112. int ret;
  1113. /* If TOS optname is set, we want to copy the TOS/TCLASS header
  1114. to the outer UDP packet */
  1115. if (vpninfo->dtls_tos_optname)
  1116. udp_tos_update(vpninfo, this);
  1117. ret = ssl_nonblock_write(vpninfo, 1, send_pkt->data, send_pkt->len);
  1118. if (ret <= 0) {
  1119. /* Zero is -EAGAIN; just requeue. dtls_nonblock_write()
  1120. * will have added the socket to the poll wfd list. */
  1121. requeue_packet(&vpninfo->outgoing_queue, this);
  1122. if (ret < 0) {
  1123. /* If it's a real error, kill the DTLS connection so
  1124. the requeued packet will be sent over SSL */
  1125. dtls_reconnect(vpninfo, timeout);
  1126. work_done = 1;
  1127. }
  1128. return work_done;
  1129. }
  1130. time(&vpninfo->dtls_times.last_tx);
  1131. vpn_progress(vpninfo, PRG_TRACE,
  1132. _("Sent DTLS packet of %d bytes; DTLS send returned %d\n"),
  1133. this->len, ret);
  1134. free_pkt(vpninfo, this);
  1135. }
  1136. return work_done;
  1137. }
  1138. int array_bye(struct openconnect_info *vpninfo, const char *reason)
  1139. {
  1140. char *orig_path;
  1141. char *res_buf=NULL;
  1142. int ret;
  1143. /* We need to close and reopen the HTTPS connection (to kill
  1144. * the array tunnel) and submit a new HTTPS request to logout.
  1145. */
  1146. openconnect_close_https(vpninfo, 0);
  1147. orig_path = vpninfo->urlpath;
  1148. vpninfo->urlpath = strdup("prx/000/http/localhost/logout"); /* redirect segfaults without strdup */
  1149. ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, HTTP_NO_FLAGS);
  1150. free(vpninfo->urlpath);
  1151. vpninfo->urlpath = orig_path;
  1152. if (ret < 0)
  1153. vpn_progress(vpninfo, PRG_ERR, _("Logout failed.\n"));
  1154. else
  1155. vpn_progress(vpninfo, PRG_INFO, _("Logout successful.\n"));
  1156. free(res_buf);
  1157. return ret;
  1158. }