fuzxy.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. /*
  2. * fuzzing proxy - network-level fuzzing injection proxy
  3. *
  4. * Copyright (C) 2016 Andy Green <andy@warmcat.com>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation:
  9. * version 2.1 of the License.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301 USA
  20. *
  21. *
  22. * fuzxy is designed to go on the client path
  23. *
  24. * [ client <-> fuzxy ] <-> server
  25. *
  26. * you can arrange that with, eg,
  27. *
  28. * http_proxy=localhost:8880
  29. *
  30. * env var before starting the client.
  31. *
  32. * Even though he is on the client side, he is able to see and change traffic
  33. * in both directions, and so fuzz both the client and the server.
  34. */
  35. #if defined(_WIN32) && defined(EXTERNAL_POLL)
  36. #define WINVER 0x0600
  37. #define _WIN32_WINNT 0x0600
  38. #define poll(fdArray, fds, timeout) WSAPoll((LPWSAPOLLFD)(fdArray), (ULONG)(fds), (INT)(timeout))
  39. #endif
  40. #include "lws_config.h"
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <getopt.h>
  44. #include <signal.h>
  45. #include <string.h>
  46. #include <sys/stat.h>
  47. #include <fcntl.h>
  48. #include <assert.h>
  49. #include <errno.h>
  50. #include "../lib/libwebsockets.h"
  51. #ifdef _WIN32
  52. #include <io.h>
  53. #include "gettimeofday.h"
  54. #else
  55. #include <syslog.h>
  56. #include <sys/time.h>
  57. #include <unistd.h>
  58. #include <sys/socket.h>
  59. #endif
  60. #if defined(__NetBSD__)
  61. #include <netinet/in.h>
  62. #endif
  63. #if defined(__sun)
  64. #include <strings.h> /* bzero */
  65. #endif
  66. #define MAX_FUZZ_BUF (1024 * 1024)
  67. enum types {
  68. FZY_S_DEAD = 0,
  69. FZY_S_LISTENING = 1,
  70. FZY_S_ACCEPTED = 2,
  71. FZY_S_PROXIED = 3,
  72. FZY_S_ONWARD = 4,
  73. };
  74. enum proxy_parser_states {
  75. FZY_PP_CONNECT = 0,
  76. FZY_PP_ADDRESS = 1,
  77. FZY_PP_PORT = 2,
  78. FZY_PP_CRLFS = 3,
  79. };
  80. enum fuzzer_parser_states {
  81. FZY_FP_SEARCH = 0,
  82. FZY_FP_SEARCH2 = 1,
  83. FZY_FP_INJECT_PREPARE = 2,
  84. FZY_FP_INJECT = 3,
  85. FZY_FP_PENDING = 4,
  86. };
  87. struct ring {
  88. char buf[4096];
  89. int head;
  90. int tail;
  91. };
  92. struct state {
  93. enum types type;
  94. enum proxy_parser_states pp;
  95. int ppc;
  96. struct ring in;
  97. char address[256];
  98. int port;
  99. enum fuzzer_parser_states fp;
  100. int fuzc;
  101. int pending;
  102. int twin; /* must be fixed up when arrays lose guys */
  103. unsigned int outbound:1; /* from local -> remote */
  104. unsigned int is_pending:1;
  105. unsigned char buf[MAX_FUZZ_BUF];
  106. unsigned int inject_len;
  107. };
  108. struct test {
  109. const char *s[3];
  110. int len[2];
  111. unsigned int swallow:1;
  112. };
  113. int force_exit = 0;
  114. int which = 5;
  115. static const struct test tests[] = {
  116. { { NULL, "\x0d\x0a\x0d\x0a",
  117. "{ 0xd9, 0x87, 0xd2, 0x88, 0xd2, (248){ 0x89, 0xd2 }, 0x0d, 0x0a },"
  118. }, { 0, 4 }, 1 },
  119. { { NULL, "\x0d\x0a\x0d\x0a",
  120. "{ 0xd9, 0x87, 0xd2, 0x88, 0xd2, (1373){ 0x89, 0xd2 }, 0x0d, 0x0a },"
  121. }, { 0, 4 }, 1 },
  122. { { NULL, "\x0d\x0a\x0d\x0a",
  123. "{ 0xd9, 0x87, 0xd2, 0x88, 0xd2, (16967){ 0x89, 0xd2 }, (87){ 0xe2, 0x82, 0xac }, 0x0d, 0x0a },"
  124. }, { 0, 4 }, 1 },
  125. { { NULL, "\x0d\x0a\x0d\x0a",
  126. "0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
  127. "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  128. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
  129. "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
  130. "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
  131. "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
  132. "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
  133. "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
  134. "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  135. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
  136. "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
  137. "0xef, 0xbb, 0xbf, 0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, "
  138. "0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, "
  139. "0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, "
  140. "0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, "
  141. "0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x0d, 0x0a, "
  142. }, { 0, 4 }, 1 },
  143. { { NULL, "\x0d\x0a\x0d\x0a",
  144. "(20){0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
  145. "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  146. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
  147. "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
  148. "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
  149. "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
  150. "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
  151. "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
  152. "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  153. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
  154. "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
  155. "0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
  156. "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  157. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
  158. "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
  159. "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
  160. "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
  161. "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
  162. "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
  163. "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  164. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
  165. "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
  166. "0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, "
  167. "0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, "
  168. "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, "
  169. "0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, "
  170. "0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, "
  171. "0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, "
  172. "0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, "
  173. "0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, "
  174. "0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, "
  175. "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, "
  176. "0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, "
  177. "0x0a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, "
  178. "0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, "
  179. "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, "
  180. "0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, "
  181. "0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, "
  182. "0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, "
  183. "0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, "
  184. "0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, "
  185. "0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, "
  186. "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, "
  187. "0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, "
  188. "0x0a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, "
  189. "0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, "
  190. "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, "
  191. "0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, "
  192. "0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, "
  193. "0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, "
  194. "0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, "
  195. "0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, "
  196. "0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, "
  197. "0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, "
  198. "0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, "
  199. "0x0a, 0xc0, 0x80, 0xef, 0xb7, 0x90, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, "
  200. "0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, "
  201. "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, "
  202. "0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, "
  203. "0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, "
  204. "0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, "
  205. "0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, "
  206. "0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, "
  207. "0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, "
  208. "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, "
  209. "0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, "
  210. "0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, "
  211. "0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, "
  212. "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, "
  213. "0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, "
  214. "0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, "
  215. "0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, "
  216. "0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, "
  217. "0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, 0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, "
  218. "0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, "
  219. "0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, "
  220. "0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, "
  221. "0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, 0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, "
  222. "0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, "
  223. "0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, "
  224. "0x61, 0x64, 0x0d, 0x0a, }"
  225. }, { 0, 4 }, 1 },
  226. { { NULL, "\x0d\x0a\x0d\x0a",
  227. "0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, "
  228. "0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  229. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x77, 0x65, "
  230. "0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, "
  231. "0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, "
  232. "0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x4b, 0x65, 0x79, 0x3a, "
  233. "0x20, 0x64, 0x47, 0x68, 0x6c, 0x49, 0x48, 0x4e, 0x68, 0x62, 0x58, 0x42, 0x73, 0x5a, 0x53, 0x42, "
  234. "0x75, 0x62, 0x32, 0x35, 0x6a, 0x5a, 0x51, 0x3d, 0x3d, 0x0d, 0x0a, 0x4f, 0x72, 0x69, 0x67, 0x69, "
  235. "0x6e, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, "
  236. "0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, "
  237. "0x65, 0x74, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x33, 0x0d, 0x0a, "
  238. "0xef, 0xbb, 0xbf, 0xc2, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x48, 0x54, "
  239. "0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x32, "
  240. "0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, "
  241. "0x3a, 0x20, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, "
  242. "0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x0d, 0x0a, (2048){ 0x0d, 0x0a}"
  243. }, { 0, 4 }, 1 },
  244. };
  245. static const int ring_size(struct ring *r)
  246. {
  247. return sizeof(r->buf);
  248. }
  249. static const int ring_used(struct ring *r)
  250. {
  251. return (r->head - r->tail) & (ring_size(r) - 1);
  252. }
  253. static const int ring_free(struct ring *r)
  254. {
  255. return (ring_size(r) - 1) - ring_used(r);
  256. }
  257. static const int ring_get_one(struct ring *r)
  258. {
  259. int n = r->buf[r->tail] & 255;
  260. if (r->tail == r->head)
  261. return -1;
  262. r->tail++;
  263. if (r->tail == ring_size(r))
  264. r->tail = 0;
  265. return n;
  266. }
  267. static int hex(char c)
  268. {
  269. if (c >= '0' && c <= '9')
  270. return c -'0';
  271. if (c >= 'a' && c <= 'f')
  272. return c - 'a' + 10;
  273. if (c >='A' && c <= 'F')
  274. return c - 'A' + 10;
  275. return -1;
  276. }
  277. static int
  278. fuzxy_tok(const char **src, unsigned char **buf, int *len)
  279. {
  280. unsigned char *start;
  281. unsigned int count, rlen;
  282. while (**src) {
  283. if (**src == ' ' || **src == ',' || **src == '\n') {
  284. (*src)++;
  285. continue;
  286. }
  287. if ((*src)[0] == '}') {
  288. (*src)++;
  289. return 0;
  290. }
  291. if ((*src)[0] == '0' && (*src)[1] == 'x') {
  292. if (!len) {
  293. lwsl_err("out of space\n");
  294. return -1;
  295. }
  296. ((*buf)++)[0] = (hex((*src)[2]) << 4) | hex((*src)[3]);
  297. *src += 4;
  298. (*len)--;
  299. }
  300. if (*src[0] == '(') {
  301. start = *buf;
  302. (*src)++;
  303. count = atoi(*src) - 1;
  304. lwsl_err("count %d\n", count);
  305. while (**src && **src != ')')
  306. (*src)++;
  307. if (!(*src)[0]) {
  308. lwsl_err("unexpected end in (\n");
  309. return -1;
  310. }
  311. (*src)++;
  312. while (**src == ' ')
  313. (*src)++;
  314. if (**src != '{') {
  315. lwsl_err("missing {\n");
  316. return -1;
  317. }
  318. (*src)++;
  319. if (fuzxy_tok(src, buf, len))
  320. return -1;
  321. rlen = *buf - start;
  322. while (count--) {
  323. if (*len < rlen) {
  324. lwsl_err("out of space\n");
  325. return -1;
  326. }
  327. memcpy(*buf, start, rlen);
  328. *buf += rlen;
  329. *len -= rlen;
  330. }
  331. }
  332. }
  333. return 0;
  334. }
  335. static int
  336. fuzxy_create_pattern(const char *src, unsigned char *buf, int len)
  337. {
  338. unsigned char *old = buf;
  339. int n;
  340. while (*src && (*src == '{' || *src == ' '))
  341. src++;
  342. if (!*src)
  343. return -1;
  344. n = fuzxy_tok(&src, &buf, &len);
  345. if (n)
  346. return -1;
  347. return buf - old;
  348. }
  349. void sighandler(int sig)
  350. {
  351. force_exit = 1;
  352. }
  353. static struct option options[] = {
  354. { "help", no_argument, NULL, 'h' },
  355. { "debug", required_argument, NULL, 'd' },
  356. { "port", required_argument, NULL, 'p' },
  357. { "ssl", no_argument, NULL, 's' },
  358. { "allow-non-ssl", no_argument, NULL, 'a' },
  359. { "interface", required_argument, NULL, 'i' },
  360. { "closetest", no_argument, NULL, 'c' },
  361. { "libev", no_argument, NULL, 'e' },
  362. #ifndef LWS_NO_DAEMONIZE
  363. { "daemonize", no_argument, NULL, 'D' },
  364. #endif
  365. { "resource_path", required_argument, NULL, 'r' },
  366. { NULL, 0, 0, 0 }
  367. };
  368. static struct pollfd pfd[128];
  369. static struct state state[128];
  370. static int pfds = 0;
  371. static void close_and_remove_fd(int index)
  372. {
  373. int n;
  374. lwsl_notice("%s: closing index %d\n", __func__, index);
  375. close(pfd[index].fd);
  376. pfd[index].fd = -1;
  377. n = state[index].twin;
  378. if (n) {
  379. assert(state[n].twin == index);
  380. }
  381. state[index].type = FZY_S_DEAD;
  382. if (index == pfds - 1) {
  383. if (state[index].twin)
  384. state[state[index].twin].twin = 0;
  385. state[index].twin = 0;
  386. goto bail;
  387. }
  388. /* swap the end guy into the deleted guy and trim back one */
  389. if (state[pfds - 1].twin) {
  390. state[state[pfds - 1].twin].twin = index;
  391. if (n && n == pfds - 1)
  392. n = index;
  393. }
  394. /* swap the last guy into dead guy's place and trim by one */
  395. pfd[index] = pfd[pfds - 1];
  396. state[index] = state[pfds - 1];
  397. if (n) {
  398. pfds--;
  399. state[n].twin = 0;
  400. close_and_remove_fd(n);
  401. return;
  402. }
  403. bail:
  404. pfds--;
  405. }
  406. static void construct_state(int n, enum types s, int flags)
  407. {
  408. memset(&state[n], 0, sizeof state[n]);
  409. state[n].type = s;
  410. pfd[n].events = flags | POLLHUP;
  411. }
  412. static int
  413. fuzxy_listen(const char *interface_name, int port, int *sockfd)
  414. {
  415. struct sockaddr_in serv_addr4;
  416. socklen_t len = sizeof(struct sockaddr);
  417. struct sockaddr_in sin;
  418. int n, opt = 1;
  419. *sockfd = socket(AF_INET, SOCK_STREAM, 0);
  420. if (*sockfd == -1) {
  421. lwsl_err("ERROR opening socket\n");
  422. goto bail1;
  423. }
  424. if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,
  425. (const void *)&opt, sizeof(opt)) < 0) {
  426. lwsl_err("unable to set listen socket options\n");
  427. goto bail2;
  428. }
  429. bzero((char *) &serv_addr4, sizeof(serv_addr4));
  430. serv_addr4.sin_addr.s_addr = INADDR_ANY;
  431. serv_addr4.sin_family = AF_INET;
  432. if (interface_name[0] &&
  433. lws_interface_to_sa(0, interface_name, (struct sockaddr_in *)
  434. (struct sockaddr *)&serv_addr4,
  435. sizeof(serv_addr4)) < 0) {
  436. lwsl_err("Unable to find interface %s\n", interface_name);
  437. goto bail2;
  438. }
  439. serv_addr4.sin_port = htons(port);
  440. n = bind(*sockfd, (struct sockaddr *)&serv_addr4,
  441. sizeof(serv_addr4));
  442. if (n < 0) {
  443. lwsl_err("ERROR on binding to port %d (%d %d)\n",
  444. port, n, errno);
  445. goto bail2;
  446. }
  447. if (getsockname(*sockfd, (struct sockaddr *)&sin, &len) == -1)
  448. lwsl_warn("getsockname: %s\n", strerror(errno));
  449. else
  450. port = ntohs(sin.sin_port);
  451. listen(*sockfd, SOMAXCONN);
  452. return 0;
  453. bail2:
  454. close(*sockfd);
  455. bail1:
  456. return -1;
  457. }
  458. static int fuzz(int n, char *out, int len)
  459. {
  460. struct state *s = &state[n];
  461. const struct test *t = &tests[which];
  462. int m = 0;
  463. int c;
  464. while (m < len) {
  465. switch (s->fp) {
  466. case FZY_FP_SEARCH:
  467. if (t->s[0] == NULL) {
  468. s->fuzc = 0;
  469. s->is_pending = 0;
  470. s->fp = FZY_FP_SEARCH2;
  471. goto search2;
  472. }
  473. c = ring_get_one(&state[s->twin].in);
  474. if (c < 0)
  475. return m;
  476. if (c == tests[which].s[0][s->fuzc++]) {
  477. if (s->fuzc == t->len[0]) {
  478. s->fuzc = 0;
  479. s->fp = FZY_FP_SEARCH2;
  480. }
  481. } else
  482. s->fuzc = 0;
  483. out[m++] = c;
  484. break;
  485. case FZY_FP_SEARCH2:
  486. search2:
  487. if (tests[which].s[1] == NULL) {
  488. s->fuzc = 0;
  489. s->is_pending = 0;
  490. s->fp = FZY_FP_INJECT_PREPARE;
  491. goto inject;
  492. }
  493. c = ring_get_one(&state[s->twin].in);
  494. if (c < 0)
  495. return m;
  496. if (c == tests[which].s[1][s->fuzc++]) {
  497. if (s->fuzc == tests[which].len[1]) {
  498. lwsl_notice("+++++++fuzzer hit...\n");
  499. s->fuzc = 0;
  500. s->fp = FZY_FP_INJECT_PREPARE;
  501. s->is_pending = !t->swallow;
  502. s->pending = c;
  503. goto inject;
  504. }
  505. } else
  506. s->fuzc = 0;
  507. if (!t->swallow)
  508. out[m++] = c;
  509. break;
  510. case FZY_FP_INJECT_PREPARE:
  511. inject:
  512. s->inject_len = fuzxy_create_pattern(t->s[2],
  513. s->buf, sizeof(s->buf));
  514. if (s->inject_len == (unsigned int) -1)
  515. return -1;
  516. s->fp = FZY_FP_INJECT;
  517. /* fallthru */
  518. case FZY_FP_INJECT:
  519. out[m++] = s->buf[s->fuzc++];
  520. if (s->fuzc == s->inject_len)
  521. s->fp = FZY_FP_PENDING;
  522. break;
  523. case FZY_FP_PENDING:
  524. if (s->is_pending)
  525. out[m++] = s->pending;
  526. s->fp = FZY_FP_SEARCH;
  527. s->fuzc = 0;
  528. break;
  529. }
  530. }
  531. return m;
  532. }
  533. static int
  534. handle_accept(int n)
  535. {
  536. struct addrinfo ai, *res, *result;
  537. struct sockaddr_in serv_addr4;
  538. struct state *s = &state[n];
  539. void *p = NULL;
  540. int m, sockfd;
  541. while (1) {
  542. m = ring_get_one(&s->in);
  543. if (m < 0)
  544. return 0;
  545. switch (s->pp) {
  546. case FZY_PP_CONNECT:
  547. if (m != "CONNECT "[s->ppc++]) {
  548. lwsl_notice("failed CONNECT match\n");
  549. return 1;
  550. }
  551. if (s->ppc == 8) {
  552. s->pp = FZY_PP_ADDRESS;
  553. s->ppc = 0;
  554. }
  555. break;
  556. case FZY_PP_ADDRESS:
  557. if (m == ':') {
  558. s->address[s->ppc++] = '\0';
  559. s->pp = FZY_PP_PORT;
  560. s->ppc = 0;
  561. break;
  562. }
  563. if (m == ' ') {
  564. s->address[s->ppc++] = '\0';
  565. s->pp = FZY_PP_CRLFS;
  566. s->ppc = 0;
  567. break;
  568. }
  569. s->address[s->ppc++] = m;
  570. if (s->ppc == sizeof(s->address)) {
  571. lwsl_notice("Failed on address length\n");
  572. return 1;
  573. }
  574. break;
  575. case FZY_PP_PORT:
  576. if (m == ' ') {
  577. s->pp = FZY_PP_CRLFS;
  578. s->ppc = 0;
  579. break;
  580. }
  581. if (m >= '0' && m <= '9') {
  582. s->port *= 10;
  583. s->port += m - '0';
  584. break;
  585. }
  586. return 1;
  587. case FZY_PP_CRLFS:
  588. if (m != "\x0d\x0a\x0d\x0a"[s->ppc++])
  589. s->ppc = 0;
  590. if (s->ppc != 4)
  591. break;
  592. s->type = FZY_S_PROXIED;
  593. memset (&ai, 0, sizeof ai);
  594. ai.ai_family = PF_UNSPEC;
  595. ai.ai_socktype = SOCK_STREAM;
  596. ai.ai_flags = AI_CANONNAME;
  597. if (getaddrinfo(s->address, NULL, &ai, &result)) {
  598. lwsl_notice("failed to lookup %s\n",
  599. s->address);
  600. return 1;
  601. }
  602. res = result;
  603. while (!p && res) {
  604. switch (res->ai_family) {
  605. case AF_INET:
  606. p = &((struct sockaddr_in *)res->
  607. ai_addr)->sin_addr;
  608. break;
  609. }
  610. res = res->ai_next;
  611. }
  612. if (!p) {
  613. lwsl_notice("Failed to get address result %s\n",
  614. s->address);
  615. freeaddrinfo(result);
  616. return 1;
  617. }
  618. serv_addr4.sin_family = AF_INET;
  619. serv_addr4.sin_addr = *((struct in_addr *)p);
  620. serv_addr4.sin_port = htons(s->port);
  621. bzero(&serv_addr4.sin_zero, 8);
  622. freeaddrinfo(result);
  623. lwsl_err("Conn %d req '%s' port %d\n", n,
  624. s->address, s->port);
  625. /* we need to open the associated onward connection */
  626. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  627. if (sockfd < 0) {
  628. lwsl_err("Could not get socket\n");
  629. return -1;
  630. }
  631. if (connect(sockfd, (struct sockaddr *)&serv_addr4,
  632. sizeof(struct sockaddr)) == -1 ||
  633. errno == EISCONN) {
  634. close(sockfd);
  635. lwsl_err("proxied onward connection failed\n");
  636. return 1;
  637. }
  638. s->twin = pfds;
  639. construct_state(pfds, FZY_S_ONWARD,
  640. POLLOUT | POLLIN | POLLERR);
  641. state[pfds].twin = n;
  642. lwsl_notice("binding conns %d and %d\n", n, pfds);
  643. state[pfds].outbound = s->outbound;
  644. state[pfds].ppc = 0;
  645. pfd[pfds++].fd = sockfd;
  646. lwsl_notice("onward connection in progress\n");
  647. if (ring_used(&s->in))
  648. pfd[s->twin].events |= POLLOUT;
  649. if (write(pfd[n].fd,
  650. "HTTP/1.0 200 \x0d\x0a\x0d\x0a", 17) < 17)
  651. return 1;
  652. }
  653. }
  654. return 0;
  655. }
  656. static void sigpipe_handler(int x)
  657. {
  658. }
  659. int
  660. main(int argc, char **argv)
  661. {
  662. char interface_name[128] = "", interface_name_local[128] = "lo";
  663. int port_local = 8880, accept_fd;
  664. struct sockaddr_in cli_addr;
  665. int debug_level = 7;
  666. socklen_t clilen;
  667. struct state *s;
  668. char out[4096];
  669. int opts = 0;
  670. int n = 0, m;
  671. #ifndef _WIN32
  672. /* LOG_PERROR is not POSIX standard, and may not be portable */
  673. #ifdef __sun
  674. int syslog_options = LOG_PID;
  675. #else
  676. int syslog_options = LOG_PID | LOG_PERROR;
  677. #endif
  678. #endif
  679. #ifndef LWS_NO_DAEMONIZE
  680. int daemonize = 0;
  681. #endif
  682. signal(SIGPIPE, sigpipe_handler);
  683. while (n >= 0) {
  684. n = getopt_long(argc, argv, "eci:hsap:d:Dr:", options, NULL);
  685. if (n < 0)
  686. continue;
  687. switch (n) {
  688. case 'e':
  689. opts |= LWS_SERVER_OPTION_LIBEV;
  690. break;
  691. #ifndef LWS_NO_DAEMONIZE
  692. case 'D':
  693. daemonize = 1;
  694. #if !defined(_WIN32) && !defined(__sun)
  695. syslog_options &= ~LOG_PERROR;
  696. #endif
  697. break;
  698. #endif
  699. case 'd':
  700. debug_level = atoi(optarg);
  701. break;
  702. case 'p':
  703. port_local = atoi(optarg);
  704. break;
  705. case 'i':
  706. strncpy(interface_name, optarg, sizeof interface_name);
  707. interface_name[(sizeof interface_name) - 1] = '\0';
  708. break;
  709. case 'h':
  710. fprintf(stderr, "Usage: libwebsockets-test-fuzxy "
  711. "[--port=<p>] [--ssl] "
  712. "[-d <log bitfield>] "
  713. "[--resource_path <path>]\n");
  714. exit(1);
  715. }
  716. }
  717. #if !defined(LWS_NO_DAEMONIZE) && !defined(WIN32)
  718. /*
  719. * normally lock path would be /var/lock/lwsts or similar, to
  720. * simplify getting started without having to take care about
  721. * permissions or running as root, set to /tmp/.lwsts-lock
  722. */
  723. if (daemonize && lws_daemonize("/tmp/.lwsts-lock")) {
  724. fprintf(stderr, "Failed to daemonize\n");
  725. return 1;
  726. }
  727. #endif
  728. signal(SIGINT, sighandler);
  729. #ifndef _WIN32
  730. /* we will only try to log things according to our debug_level */
  731. setlogmask(LOG_UPTO (LOG_DEBUG));
  732. openlog("fuzxy", syslog_options, LOG_DAEMON);
  733. #endif
  734. /* tell the library what debug level to emit and to send it to syslog */
  735. lws_set_log_level(debug_level, lwsl_emit_syslog);
  736. lwsl_notice("libwebsockets fuzzing proxy - license LGPL2.1+SLE\n");
  737. lwsl_notice("(C) Copyright 2016 Andy Green <andy@warmcat.com>\n");
  738. /* listen on local side */
  739. if (fuzxy_listen(interface_name, port_local, &pfd[pfds].fd)) {
  740. lwsl_err("Failed to listen on local side\n");
  741. goto bail1;
  742. }
  743. construct_state(pfds, FZY_S_LISTENING, POLLIN | POLLERR);
  744. pfds++;
  745. lwsl_notice("Local side listening on %s:%u\n",
  746. interface_name_local, port_local);
  747. while (!force_exit) {
  748. m = poll(pfd, pfds, 50);
  749. if (m < 0)
  750. continue;
  751. for (n = 0; n < pfds; n++) {
  752. s = &state[n];
  753. if (s->type == FZY_S_LISTENING &&
  754. (pfd[n].revents & POLLIN)) {
  755. /* first do the accept entry */
  756. clilen = sizeof(cli_addr);
  757. accept_fd = accept(pfd[0].fd,
  758. (struct sockaddr *)&cli_addr, &clilen);
  759. if (accept_fd < 0) {
  760. if (errno == EAGAIN ||
  761. errno == EWOULDBLOCK)
  762. continue;
  763. lwsl_warn("ERROR on accept: %s\n",
  764. strerror(errno));
  765. continue;
  766. }
  767. construct_state(pfds, FZY_S_ACCEPTED,
  768. POLLIN | POLLERR);
  769. state[pfds].outbound = n == 0;
  770. state[pfds].pp = FZY_PP_CONNECT;
  771. state[pfds].ppc = 0;
  772. pfd[pfds++].fd = accept_fd;
  773. lwsl_notice("new connect accepted\n");
  774. continue;
  775. }
  776. if (pfd[n].revents & POLLIN) {
  777. assert(ring_free(&s->in));
  778. m = (ring_size(&s->in) - 1) -
  779. s->in.head;
  780. if (s->in.head == ring_size(&s->in) - 1 &&
  781. s->in.tail)
  782. m = 1;
  783. m = read(pfd[n].fd, s->in.buf + s->in.head, m);
  784. // lwsl_notice("read %d\n", m);
  785. if (m <= 0) {
  786. lwsl_err("Error on read\n");
  787. goto drop;
  788. }
  789. s->in.head += m;
  790. if (s->in.head == ring_size(&s->in))
  791. s->in.head = 0;
  792. switch (s->type) {
  793. case FZY_S_ACCEPTED: /* parse proxy CONNECT */
  794. if (handle_accept(n))
  795. goto drop;
  796. break;
  797. case FZY_S_PROXIED:
  798. case FZY_S_ONWARD:
  799. if (ring_used(&s->in))
  800. pfd[s->twin].events |= POLLOUT;
  801. break;
  802. default:
  803. assert(0);
  804. break;
  805. }
  806. if (s->in.head == s->in.tail) {
  807. s->in.head = s->in.tail = 0;
  808. pfd[n].events |= POLLIN;
  809. }
  810. if (!ring_free(&s->in))
  811. pfd[n].events &= ~POLLIN;
  812. }
  813. if (pfd[n].revents & POLLOUT) {
  814. switch (s->type) {
  815. case FZY_S_PROXIED:
  816. case FZY_S_ONWARD:
  817. /*
  818. * draw down enough of the partner's
  819. * in ring to either exhaust it
  820. * or fill an output buffer
  821. */
  822. m = fuzz(n, out, sizeof(out));
  823. if (m < 0) {
  824. lwsl_err("Error on fuzz\n");
  825. goto drop;
  826. }
  827. lwsl_notice("got block %d\n", m);
  828. if (m) {
  829. m = write(pfd[n].fd, out, m);
  830. if (m <= 0) {
  831. lwsl_err("Error on write\n");
  832. goto drop;
  833. } else
  834. pfd[s->twin].events &= ~POLLIN;
  835. } else {
  836. pfd[n].events &= ~POLLOUT;
  837. if (ring_free(&state[s->twin].in))
  838. pfd[s->twin].events |= POLLIN;
  839. }
  840. break;
  841. default:
  842. break;
  843. }
  844. }
  845. continue;
  846. drop:
  847. close_and_remove_fd(n);
  848. n--; /* redo this slot */
  849. }
  850. }
  851. bail1:
  852. lwsl_notice("%s exited cleanly\n", argv[0]);
  853. #ifndef _WIN32
  854. closelog();
  855. #endif
  856. return 0;
  857. }