proxy.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451
  1. /*
  2. * Network proxy abstraction in PuTTY
  3. *
  4. * A proxy layer, if necessary, wedges itself between the network
  5. * code and the higher level backend.
  6. */
  7. #include <assert.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #define DEFINE_PLUG_METHOD_MACROS
  11. #include "putty.h"
  12. #include "network.h"
  13. #include "proxy.h"
  14. #define do_proxy_dns(cfg) \
  15. (cfg->proxy_dns == FORCE_ON || \
  16. (cfg->proxy_dns == AUTO && \
  17. cfg->proxy_type != PROXY_SOCKS4 && \
  18. cfg->proxy_type != PROXY_SOCKS5))
  19. /*
  20. * Call this when proxy negotiation is complete, so that this
  21. * socket can begin working normally.
  22. */
  23. void proxy_activate (Proxy_Socket p)
  24. {
  25. void *data;
  26. int len;
  27. long output_before, output_after;
  28. p->state = PROXY_STATE_ACTIVE;
  29. /* we want to ignore new receive events until we have sent
  30. * all of our buffered receive data.
  31. */
  32. sk_set_frozen(p->sub_socket, 1);
  33. /* how many bytes of output have we buffered? */
  34. output_before = bufchain_size(&p->pending_oob_output_data) +
  35. bufchain_size(&p->pending_output_data);
  36. /* and keep track of how many bytes do not get sent. */
  37. output_after = 0;
  38. /* send buffered OOB writes */
  39. while (bufchain_size(&p->pending_oob_output_data) > 0) {
  40. bufchain_prefix(&p->pending_oob_output_data, &data, &len);
  41. output_after += sk_write_oob(p->sub_socket, data, len);
  42. bufchain_consume(&p->pending_oob_output_data, len);
  43. }
  44. /* send buffered normal writes */
  45. while (bufchain_size(&p->pending_output_data) > 0) {
  46. bufchain_prefix(&p->pending_output_data, &data, &len);
  47. output_after += sk_write(p->sub_socket, data, len);
  48. bufchain_consume(&p->pending_output_data, len);
  49. }
  50. /* if we managed to send any data, let the higher levels know. */
  51. if (output_after < output_before)
  52. plug_sent(p->plug, output_after);
  53. /* if we were asked to flush the output during
  54. * the proxy negotiation process, do so now.
  55. */
  56. if (p->pending_flush) sk_flush(p->sub_socket);
  57. /* if the backend wanted the socket unfrozen, try to unfreeze.
  58. * our set_frozen handler will flush buffered receive data before
  59. * unfreezing the actual underlying socket.
  60. */
  61. if (!p->freeze)
  62. sk_set_frozen((Socket)p, 0);
  63. }
  64. /* basic proxy socket functions */
  65. static Plug sk_proxy_plug (Socket s, Plug p)
  66. {
  67. Proxy_Socket ps = (Proxy_Socket) s;
  68. Plug ret = ps->plug;
  69. if (p)
  70. ps->plug = p;
  71. return ret;
  72. }
  73. static void sk_proxy_close (Socket s)
  74. {
  75. Proxy_Socket ps = (Proxy_Socket) s;
  76. sk_close(ps->sub_socket);
  77. sk_addr_free(ps->remote_addr);
  78. sfree(ps);
  79. }
  80. static int sk_proxy_write (Socket s, const char *data, int len)
  81. {
  82. Proxy_Socket ps = (Proxy_Socket) s;
  83. if (ps->state != PROXY_STATE_ACTIVE) {
  84. bufchain_add(&ps->pending_output_data, data, len);
  85. return bufchain_size(&ps->pending_output_data);
  86. }
  87. return sk_write(ps->sub_socket, data, len);
  88. }
  89. static int sk_proxy_write_oob (Socket s, const char *data, int len)
  90. {
  91. Proxy_Socket ps = (Proxy_Socket) s;
  92. if (ps->state != PROXY_STATE_ACTIVE) {
  93. bufchain_clear(&ps->pending_output_data);
  94. bufchain_clear(&ps->pending_oob_output_data);
  95. bufchain_add(&ps->pending_oob_output_data, data, len);
  96. return len;
  97. }
  98. return sk_write_oob(ps->sub_socket, data, len);
  99. }
  100. static void sk_proxy_flush (Socket s)
  101. {
  102. Proxy_Socket ps = (Proxy_Socket) s;
  103. if (ps->state != PROXY_STATE_ACTIVE) {
  104. ps->pending_flush = 1;
  105. return;
  106. }
  107. sk_flush(ps->sub_socket);
  108. }
  109. static void sk_proxy_set_private_ptr (Socket s, void *ptr)
  110. {
  111. Proxy_Socket ps = (Proxy_Socket) s;
  112. sk_set_private_ptr(ps->sub_socket, ptr);
  113. }
  114. static void * sk_proxy_get_private_ptr (Socket s)
  115. {
  116. Proxy_Socket ps = (Proxy_Socket) s;
  117. return sk_get_private_ptr(ps->sub_socket);
  118. }
  119. static void sk_proxy_set_frozen (Socket s, int is_frozen)
  120. {
  121. Proxy_Socket ps = (Proxy_Socket) s;
  122. if (ps->state != PROXY_STATE_ACTIVE) {
  123. ps->freeze = is_frozen;
  124. return;
  125. }
  126. /* handle any remaining buffered recv data first */
  127. if (bufchain_size(&ps->pending_input_data) > 0) {
  128. ps->freeze = is_frozen;
  129. /* loop while we still have buffered data, and while we are
  130. * unfrozen. the plug_receive call in the loop could result
  131. * in a call back into this function refreezing the socket,
  132. * so we have to check each time.
  133. */
  134. while (!ps->freeze && bufchain_size(&ps->pending_input_data) > 0) {
  135. void *data;
  136. char databuf[512];
  137. int len;
  138. bufchain_prefix(&ps->pending_input_data, &data, &len);
  139. if (len > lenof(databuf))
  140. len = lenof(databuf);
  141. memcpy(databuf, data, len);
  142. bufchain_consume(&ps->pending_input_data, len);
  143. plug_receive(ps->plug, 0, databuf, len);
  144. }
  145. /* if we're still frozen, we'll have to wait for another
  146. * call from the backend to finish unbuffering the data.
  147. */
  148. if (ps->freeze) return;
  149. }
  150. sk_set_frozen(ps->sub_socket, is_frozen);
  151. }
  152. static const char * sk_proxy_socket_error (Socket s)
  153. {
  154. Proxy_Socket ps = (Proxy_Socket) s;
  155. if (ps->error != NULL || ps->sub_socket == NULL) {
  156. return ps->error;
  157. }
  158. return sk_socket_error(ps->sub_socket);
  159. }
  160. /* basic proxy plug functions */
  161. static int plug_proxy_closing (Plug p, const char *error_msg,
  162. int error_code, int calling_back)
  163. {
  164. Proxy_Plug pp = (Proxy_Plug) p;
  165. Proxy_Socket ps = pp->proxy_socket;
  166. if (ps->state != PROXY_STATE_ACTIVE) {
  167. ps->closing_error_msg = error_msg;
  168. ps->closing_error_code = error_code;
  169. ps->closing_calling_back = calling_back;
  170. return ps->negotiate(ps, PROXY_CHANGE_CLOSING);
  171. }
  172. return plug_closing(ps->plug, error_msg,
  173. error_code, calling_back);
  174. }
  175. static int plug_proxy_receive (Plug p, int urgent, char *data, int len)
  176. {
  177. Proxy_Plug pp = (Proxy_Plug) p;
  178. Proxy_Socket ps = pp->proxy_socket;
  179. if (ps->state != PROXY_STATE_ACTIVE) {
  180. /* we will lose the urgentness of this data, but since most,
  181. * if not all, of this data will be consumed by the negotiation
  182. * process, hopefully it won't affect the protocol above us
  183. */
  184. bufchain_add(&ps->pending_input_data, data, len);
  185. ps->receive_urgent = urgent;
  186. ps->receive_data = data;
  187. ps->receive_len = len;
  188. return ps->negotiate(ps, PROXY_CHANGE_RECEIVE);
  189. }
  190. return plug_receive(ps->plug, urgent, data, len);
  191. }
  192. static void plug_proxy_sent (Plug p, int bufsize)
  193. {
  194. Proxy_Plug pp = (Proxy_Plug) p;
  195. Proxy_Socket ps = pp->proxy_socket;
  196. if (ps->state != PROXY_STATE_ACTIVE) {
  197. ps->sent_bufsize = bufsize;
  198. ps->negotiate(ps, PROXY_CHANGE_SENT);
  199. return;
  200. }
  201. plug_sent(ps->plug, bufsize);
  202. }
  203. static int plug_proxy_accepting (Plug p, OSSocket sock)
  204. {
  205. Proxy_Plug pp = (Proxy_Plug) p;
  206. Proxy_Socket ps = pp->proxy_socket;
  207. if (ps->state != PROXY_STATE_ACTIVE) {
  208. ps->accepting_sock = sock;
  209. return ps->negotiate(ps, PROXY_CHANGE_ACCEPTING);
  210. }
  211. return plug_accepting(ps->plug, sock);
  212. }
  213. /*
  214. * This function can accept a NULL pointer as `addr', in which case
  215. * it will only check the host name.
  216. */
  217. static int proxy_for_destination (SockAddr addr, char *hostname, int port,
  218. const Config *cfg)
  219. {
  220. int s = 0, e = 0;
  221. char hostip[64];
  222. int hostip_len, hostname_len;
  223. const char *exclude_list;
  224. /*
  225. * Check the host name and IP against the hard-coded
  226. * representations of `localhost'.
  227. */
  228. if (!cfg->even_proxy_localhost &&
  229. (sk_hostname_is_local(hostname) ||
  230. (addr && sk_address_is_local(addr))))
  231. return 0; /* do not proxy */
  232. /* we want a string representation of the IP address for comparisons */
  233. if (addr) {
  234. sk_getaddr(addr, hostip, 64);
  235. hostip_len = strlen(hostip);
  236. } else
  237. hostip_len = 0; /* placate gcc; shouldn't be required */
  238. hostname_len = strlen(hostname);
  239. exclude_list = cfg->proxy_exclude_list;
  240. /* now parse the exclude list, and see if either our IP
  241. * or hostname matches anything in it.
  242. */
  243. while (exclude_list[s]) {
  244. while (exclude_list[s] &&
  245. (isspace((unsigned char)exclude_list[s]) ||
  246. exclude_list[s] == ',')) s++;
  247. if (!exclude_list[s]) break;
  248. e = s;
  249. while (exclude_list[e] &&
  250. (isalnum((unsigned char)exclude_list[e]) ||
  251. exclude_list[e] == '-' ||
  252. exclude_list[e] == '.' ||
  253. exclude_list[e] == '*')) e++;
  254. if (exclude_list[s] == '*') {
  255. /* wildcard at beginning of entry */
  256. if ((addr && strnicmp(hostip + hostip_len - (e - s - 1),
  257. exclude_list + s + 1, e - s - 1) == 0) ||
  258. strnicmp(hostname + hostname_len - (e - s - 1),
  259. exclude_list + s + 1, e - s - 1) == 0)
  260. return 0; /* IP/hostname range excluded. do not use proxy. */
  261. } else if (exclude_list[e-1] == '*') {
  262. /* wildcard at end of entry */
  263. if ((addr && strnicmp(hostip, exclude_list + s, e - s - 1) == 0) ||
  264. strnicmp(hostname, exclude_list + s, e - s - 1) == 0)
  265. return 0; /* IP/hostname range excluded. do not use proxy. */
  266. } else {
  267. /* no wildcard at either end, so let's try an absolute
  268. * match (ie. a specific IP)
  269. */
  270. if (addr && strnicmp(hostip, exclude_list + s, e - s) == 0)
  271. return 0; /* IP/hostname excluded. do not use proxy. */
  272. if (strnicmp(hostname, exclude_list + s, e - s) == 0)
  273. return 0; /* IP/hostname excluded. do not use proxy. */
  274. }
  275. s = e;
  276. /* Make sure we really have reached the next comma or end-of-string */
  277. while (exclude_list[s] &&
  278. !isspace((unsigned char)exclude_list[s]) &&
  279. exclude_list[s] != ',') s++;
  280. }
  281. /* no matches in the exclude list, so use the proxy */
  282. return 1;
  283. }
  284. SockAddr name_lookup(char *host, int port, char **canonicalname,
  285. const Config *cfg)
  286. {
  287. if (cfg->proxy_type != PROXY_NONE &&
  288. do_proxy_dns(cfg) &&
  289. proxy_for_destination(NULL, host, port, cfg)) {
  290. *canonicalname = dupstr(host);
  291. return sk_nonamelookup(host);
  292. }
  293. return sk_namelookup(host, canonicalname);
  294. }
  295. Socket new_connection(SockAddr addr, char *hostname,
  296. int port, int privport,
  297. int oobinline, int nodelay, int keepalive,
  298. Plug plug, const Config *cfg)
  299. {
  300. static const struct socket_function_table socket_fn_table = {
  301. sk_proxy_plug,
  302. sk_proxy_close,
  303. sk_proxy_write,
  304. sk_proxy_write_oob,
  305. sk_proxy_flush,
  306. sk_proxy_set_private_ptr,
  307. sk_proxy_get_private_ptr,
  308. sk_proxy_set_frozen,
  309. sk_proxy_socket_error
  310. };
  311. static const struct plug_function_table plug_fn_table = {
  312. plug_proxy_closing,
  313. plug_proxy_receive,
  314. plug_proxy_sent,
  315. plug_proxy_accepting
  316. };
  317. if (cfg->proxy_type != PROXY_NONE &&
  318. proxy_for_destination(addr, hostname, port, cfg))
  319. {
  320. Proxy_Socket ret;
  321. Proxy_Plug pplug;
  322. SockAddr proxy_addr;
  323. char *proxy_canonical_name;
  324. Socket sret;
  325. if ((sret = platform_new_connection(addr, hostname, port, privport,
  326. oobinline, nodelay, keepalive,
  327. plug, cfg)) !=
  328. NULL)
  329. return sret;
  330. ret = snew(struct Socket_proxy_tag);
  331. ret->fn = &socket_fn_table;
  332. ret->cfg = *cfg; /* STRUCTURE COPY */
  333. ret->plug = plug;
  334. ret->remote_addr = addr; /* will need to be freed on close */
  335. ret->remote_port = port;
  336. ret->error = NULL;
  337. ret->pending_flush = 0;
  338. ret->freeze = 0;
  339. bufchain_init(&ret->pending_input_data);
  340. bufchain_init(&ret->pending_output_data);
  341. bufchain_init(&ret->pending_oob_output_data);
  342. ret->sub_socket = NULL;
  343. ret->state = PROXY_STATE_NEW;
  344. ret->negotiate = NULL;
  345. if (cfg->proxy_type == PROXY_HTTP) {
  346. ret->negotiate = proxy_http_negotiate;
  347. } else if (cfg->proxy_type == PROXY_SOCKS4) {
  348. ret->negotiate = proxy_socks4_negotiate;
  349. } else if (cfg->proxy_type == PROXY_SOCKS5) {
  350. ret->negotiate = proxy_socks5_negotiate;
  351. } else if (cfg->proxy_type == PROXY_TELNET) {
  352. ret->negotiate = proxy_telnet_negotiate;
  353. } else {
  354. ret->error = "Proxy error: Unknown proxy method";
  355. return (Socket) ret;
  356. }
  357. /* create the proxy plug to map calls from the actual
  358. * socket into our proxy socket layer */
  359. pplug = snew(struct Plug_proxy_tag);
  360. pplug->fn = &plug_fn_table;
  361. pplug->proxy_socket = ret;
  362. /* look-up proxy */
  363. proxy_addr = sk_namelookup(cfg->proxy_host,
  364. &proxy_canonical_name);
  365. if (sk_addr_error(proxy_addr) != NULL) {
  366. ret->error = "Proxy error: Unable to resolve proxy host name";
  367. return (Socket)ret;
  368. }
  369. sfree(proxy_canonical_name);
  370. /* create the actual socket we will be using,
  371. * connected to our proxy server and port.
  372. */
  373. ret->sub_socket = sk_new(proxy_addr, cfg->proxy_port,
  374. privport, oobinline,
  375. nodelay, keepalive, (Plug) pplug);
  376. if (sk_socket_error(ret->sub_socket) != NULL)
  377. return (Socket) ret;
  378. /* start the proxy negotiation process... */
  379. sk_set_frozen(ret->sub_socket, 0);
  380. ret->negotiate(ret, PROXY_CHANGE_NEW);
  381. return (Socket) ret;
  382. }
  383. /* no proxy, so just return the direct socket */
  384. return sk_new(addr, port, privport, oobinline, nodelay, keepalive, plug);
  385. }
  386. Socket new_listener(char *srcaddr, int port, Plug plug, int local_host_only,
  387. const Config *cfg)
  388. {
  389. /* TODO: SOCKS (and potentially others) support inbound
  390. * TODO: connections via the proxy. support them.
  391. */
  392. return sk_newlistener(srcaddr, port, plug, local_host_only);
  393. }
  394. /* ----------------------------------------------------------------------
  395. * HTTP CONNECT proxy type.
  396. */
  397. static int get_line_end (char * data, int len)
  398. {
  399. int off = 0;
  400. while (off < len)
  401. {
  402. if (data[off] == '\n') {
  403. /* we have a newline */
  404. off++;
  405. /* is that the only thing on this line? */
  406. if (off <= 2) return off;
  407. /* if not, then there is the possibility that this header
  408. * continues onto the next line, if it starts with a space
  409. * or a tab.
  410. */
  411. if (off + 1 < len &&
  412. data[off+1] != ' ' &&
  413. data[off+1] != '\t') return off;
  414. /* the line does continue, so we have to keep going
  415. * until we see an the header's "real" end of line.
  416. */
  417. off++;
  418. }
  419. off++;
  420. }
  421. return -1;
  422. }
  423. int proxy_http_negotiate (Proxy_Socket p, int change)
  424. {
  425. if (p->state == PROXY_STATE_NEW) {
  426. /* we are just beginning the proxy negotiate process,
  427. * so we'll send off the initial bits of the request.
  428. * for this proxy method, it's just a simple HTTP
  429. * request
  430. */
  431. char *buf, dest[512];
  432. sk_getaddr(p->remote_addr, dest, lenof(dest));
  433. buf = dupprintf("CONNECT %s:%i HTTP/1.1\r\nHost: %s:%i\r\n",
  434. dest, p->remote_port, dest, p->remote_port);
  435. sk_write(p->sub_socket, buf, strlen(buf));
  436. sfree(buf);
  437. if (p->cfg.proxy_username[0] || p->cfg.proxy_password[0]) {
  438. char buf[sizeof(p->cfg.proxy_username)+sizeof(p->cfg.proxy_password)];
  439. char buf2[sizeof(buf)*4/3 + 100];
  440. int i, j, len;
  441. sprintf(buf, "%s:%s", p->cfg.proxy_username, p->cfg.proxy_password);
  442. len = strlen(buf);
  443. sprintf(buf2, "Proxy-Authorization: Basic ");
  444. for (i = 0, j = strlen(buf2); i < len; i += 3, j += 4)
  445. base64_encode_atom((unsigned char *)(buf+i),
  446. (len-i > 3 ? 3 : len-i), buf2+j);
  447. strcpy(buf2+j, "\r\n");
  448. sk_write(p->sub_socket, buf2, strlen(buf2));
  449. }
  450. sk_write(p->sub_socket, "\r\n", 2);
  451. p->state = 1;
  452. return 0;
  453. }
  454. if (change == PROXY_CHANGE_CLOSING) {
  455. /* if our proxy negotiation process involves closing and opening
  456. * new sockets, then we would want to intercept this closing
  457. * callback when we were expecting it. if we aren't anticipating
  458. * a socket close, then some error must have occurred. we'll
  459. * just pass those errors up to the backend.
  460. */
  461. return plug_closing(p->plug, p->closing_error_msg,
  462. p->closing_error_code,
  463. p->closing_calling_back);
  464. }
  465. if (change == PROXY_CHANGE_SENT) {
  466. /* some (or all) of what we wrote to the proxy was sent.
  467. * we don't do anything new, however, until we receive the
  468. * proxy's response. we might want to set a timer so we can
  469. * timeout the proxy negotiation after a while...
  470. */
  471. return 0;
  472. }
  473. if (change == PROXY_CHANGE_ACCEPTING) {
  474. /* we should _never_ see this, as we are using our socket to
  475. * connect to a proxy, not accepting inbound connections.
  476. * what should we do? close the socket with an appropriate
  477. * error message?
  478. */
  479. return plug_accepting(p->plug, p->accepting_sock);
  480. }
  481. if (change == PROXY_CHANGE_RECEIVE) {
  482. /* we have received data from the underlying socket, which
  483. * we'll need to parse, process, and respond to appropriately.
  484. */
  485. char *data, *datap;
  486. int len;
  487. int eol;
  488. if (p->state == 1) {
  489. int min_ver, maj_ver, status;
  490. /* get the status line */
  491. len = bufchain_size(&p->pending_input_data);
  492. assert(len > 0); /* or we wouldn't be here */
  493. data = snewn(len+1, char);
  494. bufchain_fetch(&p->pending_input_data, data, len);
  495. /*
  496. * We must NUL-terminate this data, because Windows
  497. * sscanf appears to require a NUL at the end of the
  498. * string because it strlens it _first_. Sigh.
  499. */
  500. data[len] = '\0';
  501. eol = get_line_end(data, len);
  502. if (eol < 0) {
  503. sfree(data);
  504. return 1;
  505. }
  506. status = -1;
  507. /* We can't rely on whether the %n incremented the sscanf return */
  508. if (sscanf((char *)data, "HTTP/%i.%i %n",
  509. &maj_ver, &min_ver, &status) < 2 || status == -1) {
  510. plug_closing(p->plug, "Proxy error: HTTP response was absent",
  511. PROXY_ERROR_GENERAL, 0);
  512. sfree(data);
  513. return 1;
  514. }
  515. /* remove the status line from the input buffer. */
  516. bufchain_consume(&p->pending_input_data, eol);
  517. if (data[status] != '2') {
  518. /* error */
  519. char *buf;
  520. data[eol] = '\0';
  521. while (eol > status &&
  522. (data[eol-1] == '\r' || data[eol-1] == '\n'))
  523. data[--eol] = '\0';
  524. buf = dupprintf("Proxy error: %s", data+status);
  525. plug_closing(p->plug, buf, PROXY_ERROR_GENERAL, 0);
  526. sfree(buf);
  527. sfree(data);
  528. return 1;
  529. }
  530. sfree(data);
  531. p->state = 2;
  532. }
  533. if (p->state == 2) {
  534. /* get headers. we're done when we get a
  535. * header of length 2, (ie. just "\r\n")
  536. */
  537. len = bufchain_size(&p->pending_input_data);
  538. assert(len > 0); /* or we wouldn't be here */
  539. data = snewn(len, char);
  540. datap = data;
  541. bufchain_fetch(&p->pending_input_data, data, len);
  542. eol = get_line_end(datap, len);
  543. if (eol < 0) {
  544. sfree(data);
  545. return 1;
  546. }
  547. while (eol > 2)
  548. {
  549. bufchain_consume(&p->pending_input_data, eol);
  550. datap += eol;
  551. len -= eol;
  552. eol = get_line_end(datap, len);
  553. }
  554. if (eol == 2) {
  555. /* we're done */
  556. bufchain_consume(&p->pending_input_data, 2);
  557. proxy_activate(p);
  558. /* proxy activate will have dealt with
  559. * whatever is left of the buffer */
  560. sfree(data);
  561. return 1;
  562. }
  563. sfree(data);
  564. return 1;
  565. }
  566. }
  567. plug_closing(p->plug, "Proxy error: unexpected proxy error",
  568. PROXY_ERROR_UNEXPECTED, 0);
  569. return 1;
  570. }
  571. /* ----------------------------------------------------------------------
  572. * SOCKS proxy type.
  573. */
  574. /* SOCKS version 4 */
  575. int proxy_socks4_negotiate (Proxy_Socket p, int change)
  576. {
  577. if (p->state == PROXY_CHANGE_NEW) {
  578. /* request format:
  579. * version number (1 byte) = 4
  580. * command code (1 byte)
  581. * 1 = CONNECT
  582. * 2 = BIND
  583. * dest. port (2 bytes) [network order]
  584. * dest. address (4 bytes)
  585. * user ID (variable length, null terminated string)
  586. */
  587. int length, type, namelen;
  588. char *command, addr[4], hostname[512];
  589. type = sk_addrtype(p->remote_addr);
  590. if (type == ADDRTYPE_IPV6) {
  591. plug_closing(p->plug, "Proxy error: SOCKS version 4 does"
  592. " not support IPv6", PROXY_ERROR_GENERAL, 0);
  593. return 1;
  594. } else if (type == ADDRTYPE_IPV4) {
  595. namelen = 0;
  596. sk_addrcopy(p->remote_addr, addr);
  597. } else { /* type == ADDRTYPE_NAME */
  598. assert(type == ADDRTYPE_NAME);
  599. sk_getaddr(p->remote_addr, hostname, lenof(hostname));
  600. namelen = strlen(hostname) + 1; /* include the NUL */
  601. addr[0] = addr[1] = addr[2] = 0;
  602. addr[3] = 1;
  603. }
  604. length = strlen(p->cfg.proxy_username) + namelen + 9;
  605. command = snewn(length, char);
  606. strcpy(command + 8, p->cfg.proxy_username);
  607. command[0] = 4; /* version 4 */
  608. command[1] = 1; /* CONNECT command */
  609. /* port */
  610. command[2] = (char) (p->remote_port >> 8) & 0xff;
  611. command[3] = (char) p->remote_port & 0xff;
  612. /* address */
  613. memcpy(command + 4, addr, 4);
  614. /* hostname */
  615. memcpy(command + 8 + strlen(p->cfg.proxy_username) + 1,
  616. hostname, namelen);
  617. sk_write(p->sub_socket, command, length);
  618. sfree(command);
  619. p->state = 1;
  620. return 0;
  621. }
  622. if (change == PROXY_CHANGE_CLOSING) {
  623. /* if our proxy negotiation process involves closing and opening
  624. * new sockets, then we would want to intercept this closing
  625. * callback when we were expecting it. if we aren't anticipating
  626. * a socket close, then some error must have occurred. we'll
  627. * just pass those errors up to the backend.
  628. */
  629. return plug_closing(p->plug, p->closing_error_msg,
  630. p->closing_error_code,
  631. p->closing_calling_back);
  632. }
  633. if (change == PROXY_CHANGE_SENT) {
  634. /* some (or all) of what we wrote to the proxy was sent.
  635. * we don't do anything new, however, until we receive the
  636. * proxy's response. we might want to set a timer so we can
  637. * timeout the proxy negotiation after a while...
  638. */
  639. return 0;
  640. }
  641. if (change == PROXY_CHANGE_ACCEPTING) {
  642. /* we should _never_ see this, as we are using our socket to
  643. * connect to a proxy, not accepting inbound connections.
  644. * what should we do? close the socket with an appropriate
  645. * error message?
  646. */
  647. return plug_accepting(p->plug, p->accepting_sock);
  648. }
  649. if (change == PROXY_CHANGE_RECEIVE) {
  650. /* we have received data from the underlying socket, which
  651. * we'll need to parse, process, and respond to appropriately.
  652. */
  653. if (p->state == 1) {
  654. /* response format:
  655. * version number (1 byte) = 4
  656. * reply code (1 byte)
  657. * 90 = request granted
  658. * 91 = request rejected or failed
  659. * 92 = request rejected due to lack of IDENTD on client
  660. * 93 = request rejected due to difference in user ID
  661. * (what we sent vs. what IDENTD said)
  662. * dest. port (2 bytes)
  663. * dest. address (4 bytes)
  664. */
  665. char data[8];
  666. if (bufchain_size(&p->pending_input_data) < 8)
  667. return 1; /* not got anything yet */
  668. /* get the response */
  669. bufchain_fetch(&p->pending_input_data, data, 8);
  670. if (data[0] != 0) {
  671. plug_closing(p->plug, "Proxy error: SOCKS proxy responded with "
  672. "unexpected reply code version",
  673. PROXY_ERROR_GENERAL, 0);
  674. return 1;
  675. }
  676. if (data[1] != 90) {
  677. switch (data[1]) {
  678. case 92:
  679. plug_closing(p->plug, "Proxy error: SOCKS server wanted IDENTD on client",
  680. PROXY_ERROR_GENERAL, 0);
  681. break;
  682. case 93:
  683. plug_closing(p->plug, "Proxy error: Username and IDENTD on client don't agree",
  684. PROXY_ERROR_GENERAL, 0);
  685. break;
  686. case 91:
  687. default:
  688. plug_closing(p->plug, "Proxy error: Error while communicating with proxy",
  689. PROXY_ERROR_GENERAL, 0);
  690. break;
  691. }
  692. return 1;
  693. }
  694. bufchain_consume(&p->pending_input_data, 8);
  695. /* we're done */
  696. proxy_activate(p);
  697. /* proxy activate will have dealt with
  698. * whatever is left of the buffer */
  699. return 1;
  700. }
  701. }
  702. plug_closing(p->plug, "Proxy error: unexpected proxy error",
  703. PROXY_ERROR_UNEXPECTED, 0);
  704. return 1;
  705. }
  706. /* SOCKS version 5 */
  707. int proxy_socks5_negotiate (Proxy_Socket p, int change)
  708. {
  709. if (p->state == PROXY_CHANGE_NEW) {
  710. /* initial command:
  711. * version number (1 byte) = 5
  712. * number of available authentication methods (1 byte)
  713. * available authentication methods (1 byte * previous value)
  714. * authentication methods:
  715. * 0x00 = no authentication
  716. * 0x01 = GSSAPI
  717. * 0x02 = username/password
  718. * 0x03 = CHAP
  719. */
  720. char command[5];
  721. int len;
  722. command[0] = 5; /* version 5 */
  723. if (p->cfg.proxy_username[0] || p->cfg.proxy_password[0]) {
  724. command[2] = 0x00; /* no authentication */
  725. len = 3;
  726. proxy_socks5_offerencryptedauth (command, &len);
  727. command[len++] = 0x02; /* username/password */
  728. command[1] = len - 2; /* Number of methods supported */
  729. } else {
  730. command[1] = 1; /* one methods supported: */
  731. command[2] = 0x00; /* no authentication */
  732. len = 3;
  733. }
  734. sk_write(p->sub_socket, command, len);
  735. p->state = 1;
  736. return 0;
  737. }
  738. if (change == PROXY_CHANGE_CLOSING) {
  739. /* if our proxy negotiation process involves closing and opening
  740. * new sockets, then we would want to intercept this closing
  741. * callback when we were expecting it. if we aren't anticipating
  742. * a socket close, then some error must have occurred. we'll
  743. * just pass those errors up to the backend.
  744. */
  745. return plug_closing(p->plug, p->closing_error_msg,
  746. p->closing_error_code,
  747. p->closing_calling_back);
  748. }
  749. if (change == PROXY_CHANGE_SENT) {
  750. /* some (or all) of what we wrote to the proxy was sent.
  751. * we don't do anything new, however, until we receive the
  752. * proxy's response. we might want to set a timer so we can
  753. * timeout the proxy negotiation after a while...
  754. */
  755. return 0;
  756. }
  757. if (change == PROXY_CHANGE_ACCEPTING) {
  758. /* we should _never_ see this, as we are using our socket to
  759. * connect to a proxy, not accepting inbound connections.
  760. * what should we do? close the socket with an appropriate
  761. * error message?
  762. */
  763. return plug_accepting(p->plug, p->accepting_sock);
  764. }
  765. if (change == PROXY_CHANGE_RECEIVE) {
  766. /* we have received data from the underlying socket, which
  767. * we'll need to parse, process, and respond to appropriately.
  768. */
  769. if (p->state == 1) {
  770. /* initial response:
  771. * version number (1 byte) = 5
  772. * authentication method (1 byte)
  773. * authentication methods:
  774. * 0x00 = no authentication
  775. * 0x01 = GSSAPI
  776. * 0x02 = username/password
  777. * 0x03 = CHAP
  778. * 0xff = no acceptable methods
  779. */
  780. char data[2];
  781. if (bufchain_size(&p->pending_input_data) < 2)
  782. return 1; /* not got anything yet */
  783. /* get the response */
  784. bufchain_fetch(&p->pending_input_data, data, 2);
  785. if (data[0] != 5) {
  786. plug_closing(p->plug, "Proxy error: SOCKS proxy returned unexpected version",
  787. PROXY_ERROR_GENERAL, 0);
  788. return 1;
  789. }
  790. if (data[1] == 0x00) p->state = 2; /* no authentication needed */
  791. else if (data[1] == 0x01) p->state = 4; /* GSSAPI authentication */
  792. else if (data[1] == 0x02) p->state = 5; /* username/password authentication */
  793. else if (data[1] == 0x03) p->state = 6; /* CHAP authentication */
  794. else {
  795. plug_closing(p->plug, "Proxy error: SOCKS proxy did not accept our authentication",
  796. PROXY_ERROR_GENERAL, 0);
  797. return 1;
  798. }
  799. bufchain_consume(&p->pending_input_data, 2);
  800. }
  801. if (p->state == 7) {
  802. /* password authentication reply format:
  803. * version number (1 bytes) = 1
  804. * reply code (1 byte)
  805. * 0 = succeeded
  806. * >0 = failed
  807. */
  808. char data[2];
  809. if (bufchain_size(&p->pending_input_data) < 2)
  810. return 1; /* not got anything yet */
  811. /* get the response */
  812. bufchain_fetch(&p->pending_input_data, data, 2);
  813. if (data[0] != 1) {
  814. plug_closing(p->plug, "Proxy error: SOCKS password "
  815. "subnegotiation contained wrong version number",
  816. PROXY_ERROR_GENERAL, 0);
  817. return 1;
  818. }
  819. if (data[1] != 0) {
  820. plug_closing(p->plug, "Proxy error: SOCKS proxy refused"
  821. " password authentication",
  822. PROXY_ERROR_GENERAL, 0);
  823. return 1;
  824. }
  825. bufchain_consume(&p->pending_input_data, 2);
  826. p->state = 2; /* now proceed as authenticated */
  827. }
  828. if (p->state == 8) {
  829. int ret;
  830. ret = proxy_socks5_handlechap(p);
  831. if (ret) return ret;
  832. }
  833. if (p->state == 2) {
  834. /* request format:
  835. * version number (1 byte) = 5
  836. * command code (1 byte)
  837. * 1 = CONNECT
  838. * 2 = BIND
  839. * 3 = UDP ASSOCIATE
  840. * reserved (1 byte) = 0x00
  841. * address type (1 byte)
  842. * 1 = IPv4
  843. * 3 = domainname (first byte has length, no terminating null)
  844. * 4 = IPv6
  845. * dest. address (variable)
  846. * dest. port (2 bytes) [network order]
  847. */
  848. char command[512];
  849. int len;
  850. int type;
  851. type = sk_addrtype(p->remote_addr);
  852. if (type == ADDRTYPE_IPV4) {
  853. len = 10; /* 4 hdr + 4 addr + 2 trailer */
  854. command[3] = 1; /* IPv4 */
  855. sk_addrcopy(p->remote_addr, command+4);
  856. } else if (type == ADDRTYPE_IPV6) {
  857. len = 22; /* 4 hdr + 16 addr + 2 trailer */
  858. command[3] = 4; /* IPv6 */
  859. sk_addrcopy(p->remote_addr, command+4);
  860. } else {
  861. assert(type == ADDRTYPE_NAME);
  862. command[3] = 3;
  863. sk_getaddr(p->remote_addr, command+5, 256);
  864. command[4] = strlen(command+5);
  865. len = 7 + command[4]; /* 4 hdr, 1 len, N addr, 2 trailer */
  866. }
  867. command[0] = 5; /* version 5 */
  868. command[1] = 1; /* CONNECT command */
  869. command[2] = 0x00;
  870. /* port */
  871. command[len-2] = (char) (p->remote_port >> 8) & 0xff;
  872. command[len-1] = (char) p->remote_port & 0xff;
  873. sk_write(p->sub_socket, command, len);
  874. p->state = 3;
  875. return 1;
  876. }
  877. if (p->state == 3) {
  878. /* reply format:
  879. * version number (1 bytes) = 5
  880. * reply code (1 byte)
  881. * 0 = succeeded
  882. * 1 = general SOCKS server failure
  883. * 2 = connection not allowed by ruleset
  884. * 3 = network unreachable
  885. * 4 = host unreachable
  886. * 5 = connection refused
  887. * 6 = TTL expired
  888. * 7 = command not supported
  889. * 8 = address type not supported
  890. * reserved (1 byte) = x00
  891. * address type (1 byte)
  892. * 1 = IPv4
  893. * 3 = domainname (first byte has length, no terminating null)
  894. * 4 = IPv6
  895. * server bound address (variable)
  896. * server bound port (2 bytes) [network order]
  897. */
  898. char data[5];
  899. int len;
  900. /* First 5 bytes of packet are enough to tell its length. */
  901. if (bufchain_size(&p->pending_input_data) < 5)
  902. return 1; /* not got anything yet */
  903. /* get the response */
  904. bufchain_fetch(&p->pending_input_data, data, 5);
  905. if (data[0] != 5) {
  906. plug_closing(p->plug, "Proxy error: SOCKS proxy returned wrong version number",
  907. PROXY_ERROR_GENERAL, 0);
  908. return 1;
  909. }
  910. if (data[1] != 0) {
  911. char buf[256];
  912. strcpy(buf, "Proxy error: ");
  913. switch (data[1]) {
  914. case 1: strcat(buf, "General SOCKS server failure"); break;
  915. case 2: strcat(buf, "Connection not allowed by ruleset"); break;
  916. case 3: strcat(buf, "Network unreachable"); break;
  917. case 4: strcat(buf, "Host unreachable"); break;
  918. case 5: strcat(buf, "Connection refused"); break;
  919. case 6: strcat(buf, "TTL expired"); break;
  920. case 7: strcat(buf, "Command not supported"); break;
  921. case 8: strcat(buf, "Address type not supported"); break;
  922. default: sprintf(buf+strlen(buf),
  923. "Unrecognised SOCKS error code %d",
  924. data[1]);
  925. break;
  926. }
  927. plug_closing(p->plug, buf, PROXY_ERROR_GENERAL, 0);
  928. return 1;
  929. }
  930. /*
  931. * Eat the rest of the reply packet.
  932. */
  933. len = 6; /* first 4 bytes, last 2 */
  934. switch (data[3]) {
  935. case 1: len += 4; break; /* IPv4 address */
  936. case 4: len += 16; break;/* IPv6 address */
  937. case 3: len += (unsigned char)data[4]; break; /* domain name */
  938. default:
  939. plug_closing(p->plug, "Proxy error: SOCKS proxy returned "
  940. "unrecognised address format",
  941. PROXY_ERROR_GENERAL, 0);
  942. return 1;
  943. }
  944. if (bufchain_size(&p->pending_input_data) < len)
  945. return 1; /* not got whole reply yet */
  946. bufchain_consume(&p->pending_input_data, len);
  947. /* we're done */
  948. proxy_activate(p);
  949. return 1;
  950. }
  951. if (p->state == 4) {
  952. /* TODO: Handle GSSAPI authentication */
  953. plug_closing(p->plug, "Proxy error: We don't support GSSAPI authentication",
  954. PROXY_ERROR_GENERAL, 0);
  955. return 1;
  956. }
  957. if (p->state == 5) {
  958. if (p->cfg.proxy_username[0] || p->cfg.proxy_password[0]) {
  959. char userpwbuf[514];
  960. int ulen, plen;
  961. ulen = strlen(p->cfg.proxy_username);
  962. if (ulen > 255) ulen = 255; if (ulen < 1) ulen = 1;
  963. plen = strlen(p->cfg.proxy_password);
  964. if (plen > 255) plen = 255; if (plen < 1) plen = 1;
  965. userpwbuf[0] = 1; /* version number of subnegotiation */
  966. userpwbuf[1] = ulen;
  967. memcpy(userpwbuf+2, p->cfg.proxy_username, ulen);
  968. userpwbuf[ulen+2] = plen;
  969. memcpy(userpwbuf+ulen+3, p->cfg.proxy_password, plen);
  970. sk_write(p->sub_socket, userpwbuf, ulen + plen + 3);
  971. p->state = 7;
  972. } else
  973. plug_closing(p->plug, "Proxy error: Server chose "
  974. "username/password authentication but we "
  975. "didn't offer it!",
  976. PROXY_ERROR_GENERAL, 0);
  977. return 1;
  978. }
  979. if (p->state == 6) {
  980. int ret;
  981. ret = proxy_socks5_selectchap(p);
  982. if (ret) return ret;
  983. }
  984. }
  985. plug_closing(p->plug, "Proxy error: Unexpected proxy error",
  986. PROXY_ERROR_UNEXPECTED, 0);
  987. return 1;
  988. }
  989. /* ----------------------------------------------------------------------
  990. * `Telnet' proxy type.
  991. *
  992. * (This is for ad-hoc proxies where you connect to the proxy's
  993. * telnet port and send a command such as `connect host port'. The
  994. * command is configurable, since this proxy type is typically not
  995. * standardised or at all well-defined.)
  996. */
  997. char *format_telnet_command(SockAddr addr, int port, const Config *cfg)
  998. {
  999. char *ret = NULL;
  1000. int retlen = 0, retsize = 0;
  1001. int so = 0, eo = 0;
  1002. #define ENSURE(n) do { \
  1003. if (retsize < retlen + n) { \
  1004. retsize = retlen + n + 512; \
  1005. ret = sresize(ret, retsize, char); \
  1006. } \
  1007. } while (0)
  1008. /* we need to escape \\, \%, \r, \n, \t, \x??, \0???,
  1009. * %%, %host, %port, %user, and %pass
  1010. */
  1011. while (cfg->proxy_telnet_command[eo] != 0) {
  1012. /* scan forward until we hit end-of-line,
  1013. * or an escape character (\ or %) */
  1014. while (cfg->proxy_telnet_command[eo] != 0 &&
  1015. cfg->proxy_telnet_command[eo] != '%' &&
  1016. cfg->proxy_telnet_command[eo] != '\\') eo++;
  1017. /* if we hit eol, break out of our escaping loop */
  1018. if (cfg->proxy_telnet_command[eo] == 0) break;
  1019. /* if there was any unescaped text before the escape
  1020. * character, send that now */
  1021. if (eo != so) {
  1022. ENSURE(eo - so);
  1023. memcpy(ret + retlen, cfg->proxy_telnet_command + so, eo - so);
  1024. retlen += eo - so;
  1025. }
  1026. so = eo++;
  1027. /* if the escape character was the last character of
  1028. * the line, we'll just stop and send it. */
  1029. if (cfg->proxy_telnet_command[eo] == 0) break;
  1030. if (cfg->proxy_telnet_command[so] == '\\') {
  1031. /* we recognize \\, \%, \r, \n, \t, \x??.
  1032. * anything else, we just send unescaped (including the \).
  1033. */
  1034. switch (cfg->proxy_telnet_command[eo]) {
  1035. case '\\':
  1036. ENSURE(1);
  1037. ret[retlen++] = '\\';
  1038. eo++;
  1039. break;
  1040. case '%':
  1041. ENSURE(1);
  1042. ret[retlen++] = '%';
  1043. eo++;
  1044. break;
  1045. case 'r':
  1046. ENSURE(1);
  1047. ret[retlen++] = '\r';
  1048. eo++;
  1049. break;
  1050. case 'n':
  1051. ENSURE(1);
  1052. ret[retlen++] = '\n';
  1053. eo++;
  1054. break;
  1055. case 't':
  1056. ENSURE(1);
  1057. ret[retlen++] = '\t';
  1058. eo++;
  1059. break;
  1060. case 'x':
  1061. case 'X':
  1062. {
  1063. /* escaped hexadecimal value (ie. \xff) */
  1064. unsigned char v = 0;
  1065. int i = 0;
  1066. for (;;) {
  1067. eo++;
  1068. if (cfg->proxy_telnet_command[eo] >= '0' &&
  1069. cfg->proxy_telnet_command[eo] <= '9')
  1070. v += cfg->proxy_telnet_command[eo] - '0';
  1071. else if (cfg->proxy_telnet_command[eo] >= 'a' &&
  1072. cfg->proxy_telnet_command[eo] <= 'f')
  1073. v += cfg->proxy_telnet_command[eo] - 'a' + 10;
  1074. else if (cfg->proxy_telnet_command[eo] >= 'A' &&
  1075. cfg->proxy_telnet_command[eo] <= 'F')
  1076. v += cfg->proxy_telnet_command[eo] - 'A' + 10;
  1077. else {
  1078. /* non hex character, so we abort and just
  1079. * send the whole thing unescaped (including \x)
  1080. */
  1081. ENSURE(1);
  1082. ret[retlen++] = '\\';
  1083. eo = so + 1;
  1084. break;
  1085. }
  1086. /* we only extract two hex characters */
  1087. if (i == 1) {
  1088. ENSURE(1);
  1089. ret[retlen++] = v;
  1090. eo++;
  1091. break;
  1092. }
  1093. i++;
  1094. v <<= 4;
  1095. }
  1096. }
  1097. break;
  1098. default:
  1099. ENSURE(2);
  1100. memcpy(ret+retlen, cfg->proxy_telnet_command + so, 2);
  1101. retlen += 2;
  1102. eo++;
  1103. break;
  1104. }
  1105. } else {
  1106. /* % escape. we recognize %%, %host, %port, %user, %pass.
  1107. * anything else, we just send unescaped (including the %).
  1108. */
  1109. if (cfg->proxy_telnet_command[eo] == '%') {
  1110. ENSURE(1);
  1111. ret[retlen++] = '%';
  1112. eo++;
  1113. }
  1114. else if (strnicmp(cfg->proxy_telnet_command + eo,
  1115. "host", 4) == 0) {
  1116. char dest[512];
  1117. int destlen;
  1118. sk_getaddr(addr, dest, lenof(dest));
  1119. destlen = strlen(dest);
  1120. ENSURE(destlen);
  1121. memcpy(ret+retlen, dest, destlen);
  1122. retlen += destlen;
  1123. eo += 4;
  1124. }
  1125. else if (strnicmp(cfg->proxy_telnet_command + eo,
  1126. "port", 4) == 0) {
  1127. char portstr[8], portlen;
  1128. portlen = sprintf(portstr, "%i", port);
  1129. ENSURE(portlen);
  1130. memcpy(ret + retlen, portstr, portlen);
  1131. retlen += portlen;
  1132. eo += 4;
  1133. }
  1134. else if (strnicmp(cfg->proxy_telnet_command + eo,
  1135. "user", 4) == 0) {
  1136. int userlen = strlen(cfg->proxy_username);
  1137. ENSURE(userlen);
  1138. memcpy(ret+retlen, cfg->proxy_username, userlen);
  1139. retlen += userlen;
  1140. eo += 4;
  1141. }
  1142. else if (strnicmp(cfg->proxy_telnet_command + eo,
  1143. "pass", 4) == 0) {
  1144. int passlen = strlen(cfg->proxy_password);
  1145. ENSURE(passlen);
  1146. memcpy(ret+retlen, cfg->proxy_password, passlen);
  1147. retlen += passlen;
  1148. eo += 4;
  1149. }
  1150. else {
  1151. /* we don't escape this, so send the % now, and
  1152. * don't advance eo, so that we'll consider the
  1153. * text immediately following the % as unescaped.
  1154. */
  1155. ENSURE(1);
  1156. ret[retlen++] = '%';
  1157. }
  1158. }
  1159. /* resume scanning for additional escapes after this one. */
  1160. so = eo;
  1161. }
  1162. /* if there is any unescaped text at the end of the line, send it */
  1163. if (eo != so) {
  1164. ENSURE(eo - so);
  1165. memcpy(ret + retlen, cfg->proxy_telnet_command + so, eo - so);
  1166. retlen += eo - so;
  1167. }
  1168. ENSURE(1);
  1169. ret[retlen] = '\0';
  1170. return ret;
  1171. #undef ENSURE
  1172. }
  1173. int proxy_telnet_negotiate (Proxy_Socket p, int change)
  1174. {
  1175. if (p->state == PROXY_CHANGE_NEW) {
  1176. char *formatted_cmd;
  1177. formatted_cmd = format_telnet_command(p->remote_addr, p->remote_port,
  1178. &p->cfg);
  1179. sk_write(p->sub_socket, formatted_cmd, strlen(formatted_cmd));
  1180. sfree(formatted_cmd);
  1181. p->state = 1;
  1182. return 0;
  1183. }
  1184. if (change == PROXY_CHANGE_CLOSING) {
  1185. /* if our proxy negotiation process involves closing and opening
  1186. * new sockets, then we would want to intercept this closing
  1187. * callback when we were expecting it. if we aren't anticipating
  1188. * a socket close, then some error must have occurred. we'll
  1189. * just pass those errors up to the backend.
  1190. */
  1191. return plug_closing(p->plug, p->closing_error_msg,
  1192. p->closing_error_code,
  1193. p->closing_calling_back);
  1194. }
  1195. if (change == PROXY_CHANGE_SENT) {
  1196. /* some (or all) of what we wrote to the proxy was sent.
  1197. * we don't do anything new, however, until we receive the
  1198. * proxy's response. we might want to set a timer so we can
  1199. * timeout the proxy negotiation after a while...
  1200. */
  1201. return 0;
  1202. }
  1203. if (change == PROXY_CHANGE_ACCEPTING) {
  1204. /* we should _never_ see this, as we are using our socket to
  1205. * connect to a proxy, not accepting inbound connections.
  1206. * what should we do? close the socket with an appropriate
  1207. * error message?
  1208. */
  1209. return plug_accepting(p->plug, p->accepting_sock);
  1210. }
  1211. if (change == PROXY_CHANGE_RECEIVE) {
  1212. /* we have received data from the underlying socket, which
  1213. * we'll need to parse, process, and respond to appropriately.
  1214. */
  1215. /* we're done */
  1216. proxy_activate(p);
  1217. /* proxy activate will have dealt with
  1218. * whatever is left of the buffer */
  1219. return 1;
  1220. }
  1221. plug_closing(p->plug, "Proxy error: Unexpected proxy error",
  1222. PROXY_ERROR_UNEXPECTED, 0);
  1223. return 1;
  1224. }