You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

http_connection.c 62KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "config.h"
  17. #include "http_connection.h"
  18. #include "http_private.h"
  19. #include "http_message.h"
  20. #include "utlist.h"
  21. #include "util.h"
  22. #include "printf.h"
  23. #include "logger.h"
  24. #include "ref.h"
  25. #include "ottery.h"
  26. #include "keypair_private.h"
  27. #include "cryptobox.h"
  28. #include "libutil/libev_helper.h"
  29. #include "libserver/ssl_util.h"
  30. #include "libserver/url.h"
  31. #include "contrib/mumhash/mum.h"
  32. #include "contrib/http-parser/http_parser.h"
  33. #include "unix-std.h"
  34. #include <openssl/err.h>
  35. #define ENCRYPTED_VERSION " HTTP/1.0"
  36. struct _rspamd_http_privbuf {
  37. rspamd_fstring_t *data;
  38. const gchar *zc_buf;
  39. gsize zc_remain;
  40. ref_entry_t ref;
  41. };
  42. enum rspamd_http_priv_flags {
  43. RSPAMD_HTTP_CONN_FLAG_ENCRYPTED = 1u << 0u,
  44. RSPAMD_HTTP_CONN_FLAG_NEW_HEADER = 1u << 1u,
  45. RSPAMD_HTTP_CONN_FLAG_RESETED = 1u << 2u,
  46. RSPAMD_HTTP_CONN_FLAG_TOO_LARGE = 1u << 3u,
  47. RSPAMD_HTTP_CONN_FLAG_ENCRYPTION_NEEDED = 1u << 4u,
  48. RSPAMD_HTTP_CONN_FLAG_PROXY = 1u << 5u,
  49. RSPAMD_HTTP_CONN_FLAG_PROXY_REQUEST = 1u << 6u,
  50. RSPAMD_HTTP_CONN_OWN_SOCKET = 1u << 7u,
  51. };
  52. #define IS_CONN_ENCRYPTED(c) ((c)->flags & RSPAMD_HTTP_CONN_FLAG_ENCRYPTED)
  53. #define IS_CONN_RESETED(c) ((c)->flags & RSPAMD_HTTP_CONN_FLAG_RESETED)
  54. struct rspamd_http_connection_private {
  55. struct rspamd_http_context *ctx;
  56. struct rspamd_ssl_connection *ssl;
  57. struct _rspamd_http_privbuf *buf;
  58. struct rspamd_keypair_cache *cache;
  59. struct rspamd_cryptobox_pubkey *peer_key;
  60. struct rspamd_cryptobox_keypair *local_key;
  61. struct rspamd_http_header *header;
  62. struct http_parser parser;
  63. struct http_parser_settings parser_cb;
  64. struct rspamd_io_ev ev;
  65. ev_tstamp timeout;
  66. struct rspamd_http_message *msg;
  67. struct iovec *out;
  68. guint outlen;
  69. enum rspamd_http_priv_flags flags;
  70. gsize wr_pos;
  71. gsize wr_total;
  72. };
  73. static const rspamd_ftok_t key_header = {
  74. .begin = "Key",
  75. .len = 3
  76. };
  77. static const rspamd_ftok_t date_header = {
  78. .begin = "Date",
  79. .len = 4
  80. };
  81. static const rspamd_ftok_t last_modified_header = {
  82. .begin = "Last-Modified",
  83. .len = 13
  84. };
  85. #define HTTP_ERROR http_error_quark ()
  86. GQuark
  87. http_error_quark (void)
  88. {
  89. return g_quark_from_static_string ("http-error-quark");
  90. }
  91. static void
  92. rspamd_http_privbuf_dtor (gpointer ud)
  93. {
  94. struct _rspamd_http_privbuf *p = (struct _rspamd_http_privbuf *)ud;
  95. if (p->data) {
  96. rspamd_fstring_free (p->data);
  97. }
  98. g_free (p);
  99. }
  100. static const gchar *
  101. rspamd_http_code_to_str (gint code)
  102. {
  103. if (code == 200) {
  104. return "OK";
  105. }
  106. else if (code == 404) {
  107. return "Not found";
  108. }
  109. else if (code == 403 || code == 401) {
  110. return "Not authorized";
  111. }
  112. else if (code >= 400 && code < 500) {
  113. return "Bad request";
  114. }
  115. else if (code >= 300 && code < 400) {
  116. return "See Other";
  117. }
  118. else if (code >= 500 && code < 600) {
  119. return "Internal server error";
  120. }
  121. return "Unknown error";
  122. }
  123. static void
  124. rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn,
  125. struct rspamd_http_connection_private *priv)
  126. {
  127. guchar *decoded_id;
  128. const gchar *eq_pos;
  129. gsize id_len;
  130. struct rspamd_cryptobox_pubkey *pk;
  131. if (priv->local_key == NULL) {
  132. /* In this case we cannot do anything, e.g. we cannot decrypt payload */
  133. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_ENCRYPTED;
  134. }
  135. else {
  136. /* Check sanity of what we have */
  137. eq_pos = memchr (data->begin, '=', data->len);
  138. if (eq_pos != NULL) {
  139. decoded_id = rspamd_decode_base32 (data->begin, eq_pos - data->begin,
  140. &id_len);
  141. if (decoded_id != NULL && id_len >= RSPAMD_KEYPAIR_SHORT_ID_LEN) {
  142. pk = rspamd_pubkey_from_base32 (eq_pos + 1,
  143. data->begin + data->len - eq_pos - 1,
  144. RSPAMD_KEYPAIR_KEX,
  145. RSPAMD_CRYPTOBOX_MODE_25519);
  146. if (pk != NULL) {
  147. if (memcmp (rspamd_keypair_get_id (priv->local_key),
  148. decoded_id,
  149. RSPAMD_KEYPAIR_SHORT_ID_LEN) == 0) {
  150. priv->msg->peer_key = pk;
  151. if (priv->cache && priv->msg->peer_key) {
  152. rspamd_keypair_cache_process (priv->cache,
  153. priv->local_key,
  154. priv->msg->peer_key);
  155. }
  156. }
  157. else {
  158. rspamd_pubkey_unref (pk);
  159. }
  160. }
  161. }
  162. priv->flags |= RSPAMD_HTTP_CONN_FLAG_ENCRYPTED;
  163. g_free (decoded_id);
  164. }
  165. }
  166. }
  167. static inline void
  168. rspamd_http_check_special_header (struct rspamd_http_connection *conn,
  169. struct rspamd_http_connection_private *priv)
  170. {
  171. if (rspamd_ftok_casecmp (&priv->header->name, &date_header) == 0) {
  172. priv->msg->date = rspamd_http_parse_date (priv->header->value.begin,
  173. priv->header->value.len);
  174. }
  175. else if (rspamd_ftok_casecmp (&priv->header->name, &key_header) == 0) {
  176. rspamd_http_parse_key (&priv->header->value, conn, priv);
  177. }
  178. else if (rspamd_ftok_casecmp (&priv->header->name, &last_modified_header) == 0) {
  179. priv->msg->last_modified = rspamd_http_parse_date (
  180. priv->header->value.begin,
  181. priv->header->value.len);
  182. }
  183. }
  184. static gint
  185. rspamd_http_on_url (http_parser * parser, const gchar *at, size_t length)
  186. {
  187. struct rspamd_http_connection *conn =
  188. (struct rspamd_http_connection *)parser->data;
  189. struct rspamd_http_connection_private *priv;
  190. priv = conn->priv;
  191. priv->msg->url = rspamd_fstring_append (priv->msg->url, at, length);
  192. return 0;
  193. }
  194. static gint
  195. rspamd_http_on_status (http_parser * parser, const gchar *at, size_t length)
  196. {
  197. struct rspamd_http_connection *conn =
  198. (struct rspamd_http_connection *)parser->data;
  199. struct rspamd_http_connection_private *priv;
  200. priv = conn->priv;
  201. if (parser->status_code != 200) {
  202. if (priv->msg->status == NULL) {
  203. priv->msg->status = rspamd_fstring_new ();
  204. }
  205. priv->msg->status = rspamd_fstring_append (priv->msg->status, at, length);
  206. }
  207. return 0;
  208. }
  209. static void
  210. rspamd_http_finish_header (struct rspamd_http_connection *conn,
  211. struct rspamd_http_connection_private *priv)
  212. {
  213. struct rspamd_http_header *hdr;
  214. khiter_t k;
  215. gint r;
  216. priv->header->combined = rspamd_fstring_append (priv->header->combined,
  217. "\r\n", 2);
  218. priv->header->value.len = priv->header->combined->len -
  219. priv->header->name.len - 4;
  220. priv->header->value.begin = priv->header->combined->str +
  221. priv->header->name.len + 2;
  222. priv->header->name.begin = priv->header->combined->str;
  223. k = kh_put (rspamd_http_headers_hash, priv->msg->headers, &priv->header->name,
  224. &r);
  225. if (r != 0) {
  226. kh_value (priv->msg->headers, k) = priv->header;
  227. hdr = NULL;
  228. }
  229. else {
  230. hdr = kh_value (priv->msg->headers, k);
  231. }
  232. DL_APPEND (hdr, priv->header);
  233. rspamd_http_check_special_header (conn, priv);
  234. }
  235. static void
  236. rspamd_http_init_header (struct rspamd_http_connection_private *priv)
  237. {
  238. priv->header = g_malloc0 (sizeof (struct rspamd_http_header));
  239. priv->header->combined = rspamd_fstring_new ();
  240. }
  241. static gint
  242. rspamd_http_on_header_field (http_parser * parser,
  243. const gchar *at,
  244. size_t length)
  245. {
  246. struct rspamd_http_connection *conn =
  247. (struct rspamd_http_connection *)parser->data;
  248. struct rspamd_http_connection_private *priv;
  249. priv = conn->priv;
  250. if (priv->header == NULL) {
  251. rspamd_http_init_header (priv);
  252. }
  253. else if (priv->flags & RSPAMD_HTTP_CONN_FLAG_NEW_HEADER) {
  254. rspamd_http_finish_header (conn, priv);
  255. rspamd_http_init_header (priv);
  256. }
  257. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
  258. priv->header->combined = rspamd_fstring_append (priv->header->combined,
  259. at, length);
  260. return 0;
  261. }
  262. static gint
  263. rspamd_http_on_header_value (http_parser * parser,
  264. const gchar *at,
  265. size_t length)
  266. {
  267. struct rspamd_http_connection *conn =
  268. (struct rspamd_http_connection *)parser->data;
  269. struct rspamd_http_connection_private *priv;
  270. priv = conn->priv;
  271. if (priv->header == NULL) {
  272. /* Should not happen */
  273. return -1;
  274. }
  275. if (!(priv->flags & RSPAMD_HTTP_CONN_FLAG_NEW_HEADER)) {
  276. priv->flags |= RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
  277. priv->header->combined = rspamd_fstring_append (priv->header->combined,
  278. ": ", 2);
  279. priv->header->name.len = priv->header->combined->len - 2;
  280. }
  281. priv->header->combined = rspamd_fstring_append (priv->header->combined,
  282. at, length);
  283. return 0;
  284. }
  285. static int
  286. rspamd_http_on_headers_complete (http_parser * parser)
  287. {
  288. struct rspamd_http_connection *conn =
  289. (struct rspamd_http_connection *)parser->data;
  290. struct rspamd_http_connection_private *priv;
  291. struct rspamd_http_message *msg;
  292. int ret;
  293. priv = conn->priv;
  294. msg = priv->msg;
  295. if (priv->header != NULL) {
  296. rspamd_http_finish_header (conn, priv);
  297. priv->header = NULL;
  298. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
  299. }
  300. if (msg->method == HTTP_HEAD) {
  301. /* We don't care about the rest */
  302. rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev);
  303. msg->code = parser->status_code;
  304. rspamd_http_connection_ref (conn);
  305. ret = conn->finish_handler (conn, msg);
  306. if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
  307. rspamd_http_context_push_keepalive (conn->priv->ctx, conn,
  308. msg, conn->priv->ctx->event_loop);
  309. rspamd_http_connection_reset (conn);
  310. }
  311. else {
  312. conn->finished = TRUE;
  313. }
  314. rspamd_http_connection_unref (conn);
  315. return ret;
  316. }
  317. /*
  318. * HTTP parser sets content length to (-1) when it doesn't know the real
  319. * length, for example, in case of chunked encoding.
  320. *
  321. * Hence, we skip body setup here
  322. */
  323. if (parser->content_length != ULLONG_MAX && parser->content_length != 0 &&
  324. msg->method != HTTP_HEAD) {
  325. if (conn->max_size > 0 &&
  326. parser->content_length > conn->max_size) {
  327. /* Too large message */
  328. priv->flags |= RSPAMD_HTTP_CONN_FLAG_TOO_LARGE;
  329. return -1;
  330. }
  331. if (!rspamd_http_message_set_body (msg, NULL, parser->content_length)) {
  332. return -1;
  333. }
  334. }
  335. if (parser->flags & F_SPAMC) {
  336. msg->flags |= RSPAMD_HTTP_FLAG_SPAMC;
  337. }
  338. msg->method = parser->method;
  339. msg->code = parser->status_code;
  340. return 0;
  341. }
  342. static void
  343. rspamd_http_switch_zc (struct _rspamd_http_privbuf *pbuf,
  344. struct rspamd_http_message *msg)
  345. {
  346. pbuf->zc_buf = msg->body_buf.begin + msg->body_buf.len;
  347. pbuf->zc_remain = msg->body_buf.allocated_len - msg->body_buf.len;
  348. }
  349. static int
  350. rspamd_http_on_body (http_parser * parser, const gchar *at, size_t length)
  351. {
  352. struct rspamd_http_connection *conn =
  353. (struct rspamd_http_connection *)parser->data;
  354. struct rspamd_http_connection_private *priv;
  355. struct rspamd_http_message *msg;
  356. struct _rspamd_http_privbuf *pbuf;
  357. const gchar *p;
  358. priv = conn->priv;
  359. msg = priv->msg;
  360. pbuf = priv->buf;
  361. p = at;
  362. if (!(msg->flags & RSPAMD_HTTP_FLAG_HAS_BODY)) {
  363. if (!rspamd_http_message_set_body (msg, NULL, parser->content_length)) {
  364. return -1;
  365. }
  366. }
  367. if (conn->finished) {
  368. return 0;
  369. }
  370. if (conn->max_size > 0 &&
  371. msg->body_buf.len + length > conn->max_size) {
  372. /* Body length overflow */
  373. priv->flags |= RSPAMD_HTTP_CONN_FLAG_TOO_LARGE;
  374. return -1;
  375. }
  376. if (!pbuf->zc_buf) {
  377. if (!rspamd_http_message_append_body (msg, at, length)) {
  378. return -1;
  379. }
  380. /* We might have some leftover in our private buffer */
  381. if (pbuf->data->len == length) {
  382. /* Switch to zero-copy mode */
  383. rspamd_http_switch_zc (pbuf, msg);
  384. }
  385. }
  386. else {
  387. if (msg->body_buf.begin + msg->body_buf.len != at) {
  388. /* Likely chunked encoding */
  389. memmove ((gchar *)msg->body_buf.begin + msg->body_buf.len, at, length);
  390. p = msg->body_buf.begin + msg->body_buf.len;
  391. }
  392. /* Adjust zero-copy buf */
  393. msg->body_buf.len += length;
  394. if (!(msg->flags & RSPAMD_HTTP_FLAG_SHMEM)) {
  395. msg->body_buf.c.normal->len += length;
  396. }
  397. pbuf->zc_buf = msg->body_buf.begin + msg->body_buf.len;
  398. pbuf->zc_remain = msg->body_buf.allocated_len - msg->body_buf.len;
  399. }
  400. if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) && !IS_CONN_ENCRYPTED (priv)) {
  401. /* Incremental update is impossible for encrypted requests so far */
  402. return (conn->body_handler (conn, msg, p, length));
  403. }
  404. return 0;
  405. }
  406. static int
  407. rspamd_http_on_body_decrypted (http_parser * parser, const gchar *at, size_t length)
  408. {
  409. struct rspamd_http_connection *conn =
  410. (struct rspamd_http_connection *)parser->data;
  411. struct rspamd_http_connection_private *priv;
  412. priv = conn->priv;
  413. if (priv->header != NULL) {
  414. rspamd_http_finish_header (conn, priv);
  415. priv->header = NULL;
  416. }
  417. if (conn->finished) {
  418. return 0;
  419. }
  420. if (priv->msg->body_buf.len == 0) {
  421. priv->msg->body_buf.begin = at;
  422. priv->msg->method = parser->method;
  423. priv->msg->code = parser->status_code;
  424. }
  425. priv->msg->body_buf.len += length;
  426. return 0;
  427. }
  428. static int
  429. rspamd_http_on_headers_complete_decrypted (http_parser *parser)
  430. {
  431. struct rspamd_http_connection *conn =
  432. (struct rspamd_http_connection *) parser->data;
  433. struct rspamd_http_connection_private *priv;
  434. struct rspamd_http_message *msg;
  435. int ret;
  436. priv = conn->priv;
  437. msg = priv->msg;
  438. if (priv->header != NULL) {
  439. rspamd_http_finish_header (conn, priv);
  440. priv->header = NULL;
  441. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
  442. }
  443. if (parser->flags & F_SPAMC) {
  444. priv->msg->flags |= RSPAMD_HTTP_FLAG_SPAMC;
  445. }
  446. if (msg->method == HTTP_HEAD) {
  447. /* We don't care about the rest */
  448. rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev);
  449. msg->code = parser->status_code;
  450. rspamd_http_connection_ref (conn);
  451. ret = conn->finish_handler (conn, msg);
  452. if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
  453. rspamd_http_context_push_keepalive (conn->priv->ctx, conn,
  454. msg, conn->priv->ctx->event_loop);
  455. rspamd_http_connection_reset (conn);
  456. }
  457. else {
  458. conn->finished = TRUE;
  459. }
  460. rspamd_http_connection_unref (conn);
  461. return ret;
  462. }
  463. priv->msg->method = parser->method;
  464. priv->msg->code = parser->status_code;
  465. return 0;
  466. }
  467. static int
  468. rspamd_http_decrypt_message (struct rspamd_http_connection *conn,
  469. struct rspamd_http_connection_private *priv,
  470. struct rspamd_cryptobox_pubkey *peer_key)
  471. {
  472. guchar *nonce, *m;
  473. const guchar *nm;
  474. gsize dec_len;
  475. struct rspamd_http_message *msg = priv->msg;
  476. struct rspamd_http_header *hdr, *hcur, *hcurtmp;
  477. struct http_parser decrypted_parser;
  478. struct http_parser_settings decrypted_cb;
  479. enum rspamd_cryptobox_mode mode;
  480. mode = rspamd_keypair_alg (priv->local_key);
  481. nonce = msg->body_buf.str;
  482. m = msg->body_buf.str + rspamd_cryptobox_nonce_bytes (mode) +
  483. rspamd_cryptobox_mac_bytes (mode);
  484. dec_len = msg->body_buf.len - rspamd_cryptobox_nonce_bytes (mode) -
  485. rspamd_cryptobox_mac_bytes (mode);
  486. if ((nm = rspamd_pubkey_get_nm (peer_key, priv->local_key)) == NULL) {
  487. nm = rspamd_pubkey_calculate_nm (peer_key, priv->local_key);
  488. }
  489. if (!rspamd_cryptobox_decrypt_nm_inplace (m, dec_len, nonce,
  490. nm, m - rspamd_cryptobox_mac_bytes (mode), mode)) {
  491. msg_err ("cannot verify encrypted message, first bytes of the input: %*xs",
  492. (gint)MIN(msg->body_buf.len, 64), msg->body_buf.begin);
  493. return -1;
  494. }
  495. /* Cleanup message */
  496. kh_foreach_value (msg->headers, hdr, {
  497. DL_FOREACH_SAFE (hdr, hcur, hcurtmp) {
  498. rspamd_fstring_free (hcur->combined);
  499. g_free (hcur);
  500. }
  501. });
  502. kh_destroy (rspamd_http_headers_hash, msg->headers);
  503. msg->headers = kh_init (rspamd_http_headers_hash);
  504. if (msg->url != NULL) {
  505. msg->url = rspamd_fstring_assign (msg->url, "", 0);
  506. }
  507. msg->body_buf.len = 0;
  508. memset (&decrypted_parser, 0, sizeof (decrypted_parser));
  509. http_parser_init (&decrypted_parser,
  510. conn->type == RSPAMD_HTTP_SERVER ? HTTP_REQUEST : HTTP_RESPONSE);
  511. memset (&decrypted_cb, 0, sizeof (decrypted_cb));
  512. decrypted_cb.on_url = rspamd_http_on_url;
  513. decrypted_cb.on_status = rspamd_http_on_status;
  514. decrypted_cb.on_header_field = rspamd_http_on_header_field;
  515. decrypted_cb.on_header_value = rspamd_http_on_header_value;
  516. decrypted_cb.on_headers_complete = rspamd_http_on_headers_complete_decrypted;
  517. decrypted_cb.on_body = rspamd_http_on_body_decrypted;
  518. decrypted_parser.data = conn;
  519. decrypted_parser.content_length = dec_len;
  520. if (http_parser_execute (&decrypted_parser, &decrypted_cb, m,
  521. dec_len) != (size_t)dec_len) {
  522. msg_err ("HTTP parser error: %s when parsing encrypted request",
  523. http_errno_description (decrypted_parser.http_errno));
  524. return -1;
  525. }
  526. return 0;
  527. }
  528. static int
  529. rspamd_http_on_message_complete (http_parser * parser)
  530. {
  531. struct rspamd_http_connection *conn =
  532. (struct rspamd_http_connection *)parser->data;
  533. struct rspamd_http_connection_private *priv;
  534. int ret = 0;
  535. enum rspamd_cryptobox_mode mode;
  536. if (conn->finished) {
  537. return 0;
  538. }
  539. priv = conn->priv;
  540. if ((conn->opts & RSPAMD_HTTP_REQUIRE_ENCRYPTION) && !IS_CONN_ENCRYPTED (priv)) {
  541. priv->flags |= RSPAMD_HTTP_CONN_FLAG_ENCRYPTION_NEEDED;
  542. msg_err ("unencrypted connection when encryption has been requested");
  543. return -1;
  544. }
  545. if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) == 0 && IS_CONN_ENCRYPTED (priv)) {
  546. mode = rspamd_keypair_alg (priv->local_key);
  547. if (priv->local_key == NULL || priv->msg->peer_key == NULL ||
  548. priv->msg->body_buf.len < rspamd_cryptobox_nonce_bytes (mode) +
  549. rspamd_cryptobox_mac_bytes (mode)) {
  550. msg_err ("cannot decrypt message");
  551. return -1;
  552. }
  553. /* We have keys, so we can decrypt message */
  554. ret = rspamd_http_decrypt_message (conn, priv, priv->msg->peer_key);
  555. if (ret != 0) {
  556. return ret;
  557. }
  558. if (conn->body_handler != NULL) {
  559. rspamd_http_connection_ref (conn);
  560. ret = conn->body_handler (conn,
  561. priv->msg,
  562. priv->msg->body_buf.begin,
  563. priv->msg->body_buf.len);
  564. rspamd_http_connection_unref (conn);
  565. }
  566. }
  567. else if ((conn->opts & RSPAMD_HTTP_BODY_PARTIAL) == 0 && conn->body_handler) {
  568. g_assert (conn->body_handler != NULL);
  569. rspamd_http_connection_ref (conn);
  570. ret = conn->body_handler (conn,
  571. priv->msg,
  572. priv->msg->body_buf.begin,
  573. priv->msg->body_buf.len);
  574. rspamd_http_connection_unref (conn);
  575. }
  576. if (ret == 0) {
  577. rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev);
  578. rspamd_http_connection_ref (conn);
  579. ret = conn->finish_handler (conn, priv->msg);
  580. if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
  581. rspamd_http_context_push_keepalive (conn->priv->ctx, conn,
  582. priv->msg, conn->priv->ctx->event_loop);
  583. rspamd_http_connection_reset (conn);
  584. }
  585. else {
  586. conn->finished = TRUE;
  587. }
  588. rspamd_http_connection_unref (conn);
  589. }
  590. return ret;
  591. }
  592. static void
  593. rspamd_http_simple_client_helper (struct rspamd_http_connection *conn)
  594. {
  595. struct rspamd_http_connection_private *priv;
  596. gpointer ssl;
  597. gint request_method;
  598. GString *prev_host = NULL;
  599. priv = conn->priv;
  600. ssl = priv->ssl;
  601. priv->ssl = NULL;
  602. /* Preserve data */
  603. if (priv->msg) {
  604. request_method = priv->msg->method;
  605. /* Preserve host for keepalive */
  606. prev_host = priv->msg->host;
  607. priv->msg->host = NULL;
  608. }
  609. rspamd_http_connection_reset (conn);
  610. priv->ssl = ssl;
  611. /* Plan read message */
  612. if (conn->opts & RSPAMD_HTTP_CLIENT_SHARED) {
  613. rspamd_http_connection_read_message_shared (conn, conn->ud,
  614. conn->priv->timeout);
  615. }
  616. else {
  617. rspamd_http_connection_read_message (conn, conn->ud,
  618. conn->priv->timeout);
  619. }
  620. if (priv->msg) {
  621. priv->msg->method = request_method;
  622. priv->msg->host = prev_host;
  623. }
  624. else {
  625. if (prev_host) {
  626. g_string_free (prev_host, TRUE);
  627. }
  628. }
  629. }
  630. static void
  631. rspamd_http_write_helper (struct rspamd_http_connection *conn)
  632. {
  633. struct rspamd_http_connection_private *priv;
  634. struct iovec *start;
  635. guint niov, i;
  636. gint flags = 0;
  637. gsize remain;
  638. gssize r;
  639. GError *err;
  640. struct iovec *cur_iov;
  641. struct msghdr msg;
  642. priv = conn->priv;
  643. if (priv->wr_pos == priv->wr_total) {
  644. goto call_finish_handler;
  645. }
  646. start = &priv->out[0];
  647. niov = priv->outlen;
  648. remain = priv->wr_pos;
  649. /* We know that niov is small enough for that */
  650. if (priv->ssl) {
  651. /* Might be recursive! */
  652. cur_iov = g_malloc (niov * sizeof (struct iovec));
  653. }
  654. else {
  655. cur_iov = alloca (niov * sizeof (struct iovec));
  656. }
  657. memcpy (cur_iov, priv->out, niov * sizeof (struct iovec));
  658. for (i = 0; i < priv->outlen && remain > 0; i++) {
  659. /* Find out the first iov required */
  660. start = &cur_iov[i];
  661. if (start->iov_len <= remain) {
  662. remain -= start->iov_len;
  663. start = &cur_iov[i + 1];
  664. niov--;
  665. }
  666. else {
  667. start->iov_base = (void *)((char *)start->iov_base + remain);
  668. start->iov_len -= remain;
  669. remain = 0;
  670. }
  671. }
  672. memset (&msg, 0, sizeof (msg));
  673. msg.msg_iov = start;
  674. msg.msg_iovlen = MIN (IOV_MAX, niov);
  675. g_assert (niov > 0);
  676. #ifdef MSG_NOSIGNAL
  677. flags = MSG_NOSIGNAL;
  678. #endif
  679. if (priv->ssl) {
  680. r = rspamd_ssl_writev (priv->ssl, msg.msg_iov, msg.msg_iovlen);
  681. g_free (cur_iov);
  682. }
  683. else {
  684. r = sendmsg (conn->fd, &msg, flags);
  685. }
  686. if (r == -1) {
  687. if (!priv->ssl) {
  688. err = g_error_new (HTTP_ERROR, errno, "IO write error: %s", strerror (errno));
  689. rspamd_http_connection_ref (conn);
  690. conn->error_handler (conn, err);
  691. rspamd_http_connection_unref (conn);
  692. g_error_free (err);
  693. }
  694. return;
  695. }
  696. else {
  697. priv->wr_pos += r;
  698. }
  699. if (priv->wr_pos >= priv->wr_total) {
  700. goto call_finish_handler;
  701. }
  702. else {
  703. /* Want to write more */
  704. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_RESETED;
  705. if (priv->ssl && r > 0) {
  706. /* We can write more data... */
  707. rspamd_http_write_helper (conn);
  708. return;
  709. }
  710. }
  711. return;
  712. call_finish_handler:
  713. rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev);
  714. if ((conn->opts & RSPAMD_HTTP_CLIENT_SIMPLE) == 0) {
  715. rspamd_http_connection_ref (conn);
  716. conn->finished = TRUE;
  717. conn->finish_handler (conn, priv->msg);
  718. rspamd_http_connection_unref (conn);
  719. }
  720. else {
  721. /* Plan read message */
  722. rspamd_http_simple_client_helper (conn);
  723. }
  724. }
  725. static gssize
  726. rspamd_http_try_read (gint fd,
  727. struct rspamd_http_connection *conn,
  728. struct rspamd_http_connection_private *priv,
  729. struct _rspamd_http_privbuf *pbuf,
  730. const gchar **buf_ptr)
  731. {
  732. gssize r;
  733. gchar *data;
  734. gsize len;
  735. struct rspamd_http_message *msg;
  736. msg = priv->msg;
  737. if (pbuf->zc_buf == NULL) {
  738. data = priv->buf->data->str;
  739. len = priv->buf->data->allocated;
  740. }
  741. else {
  742. data = (gchar *)pbuf->zc_buf;
  743. len = pbuf->zc_remain;
  744. if (len == 0) {
  745. rspamd_http_message_grow_body (priv->msg, priv->buf->data->allocated);
  746. rspamd_http_switch_zc (pbuf, msg);
  747. data = (gchar *)pbuf->zc_buf;
  748. len = pbuf->zc_remain;
  749. }
  750. }
  751. if (priv->ssl) {
  752. r = rspamd_ssl_read (priv->ssl, data, len);
  753. }
  754. else {
  755. r = read (fd, data, len);
  756. }
  757. if (r <= 0) {
  758. return r;
  759. }
  760. else {
  761. if (pbuf->zc_buf == NULL) {
  762. priv->buf->data->len = r;
  763. }
  764. else {
  765. pbuf->zc_remain -= r;
  766. pbuf->zc_buf += r;
  767. }
  768. }
  769. if (buf_ptr) {
  770. *buf_ptr = data;
  771. }
  772. return r;
  773. }
  774. static void
  775. rspamd_http_ssl_err_handler (gpointer ud, GError *err)
  776. {
  777. struct rspamd_http_connection *conn = (struct rspamd_http_connection *)ud;
  778. rspamd_http_connection_ref (conn);
  779. conn->error_handler (conn, err);
  780. rspamd_http_connection_unref (conn);
  781. }
  782. static void
  783. rspamd_http_event_handler (int fd, short what, gpointer ud)
  784. {
  785. struct rspamd_http_connection *conn = (struct rspamd_http_connection *)ud;
  786. struct rspamd_http_connection_private *priv;
  787. struct _rspamd_http_privbuf *pbuf;
  788. const gchar *d;
  789. gssize r;
  790. GError *err;
  791. priv = conn->priv;
  792. pbuf = priv->buf;
  793. REF_RETAIN (pbuf);
  794. rspamd_http_connection_ref (conn);
  795. if (what == EV_READ) {
  796. r = rspamd_http_try_read (fd, conn, priv, pbuf, &d);
  797. if (r > 0) {
  798. if (http_parser_execute (&priv->parser, &priv->parser_cb,
  799. d, r) != (size_t)r || priv->parser.http_errno != 0) {
  800. if (priv->flags & RSPAMD_HTTP_CONN_FLAG_TOO_LARGE) {
  801. err = g_error_new (HTTP_ERROR, 413,
  802. "Request entity too large: %zu",
  803. (size_t)priv->parser.content_length);
  804. }
  805. else if (priv->flags & RSPAMD_HTTP_CONN_FLAG_ENCRYPTION_NEEDED) {
  806. err = g_error_new (HTTP_ERROR, 400,
  807. "Encryption required");
  808. }
  809. else if (priv->parser.http_errno == HPE_CLOSED_CONNECTION) {
  810. msg_err ("got garbage after end of the message, ignore it");
  811. REF_RELEASE (pbuf);
  812. rspamd_http_connection_unref (conn);
  813. return;
  814. }
  815. else {
  816. err = g_error_new (HTTP_ERROR, 500 + priv->parser.http_errno,
  817. "HTTP parser error: %s",
  818. http_errno_description (priv->parser.http_errno));
  819. }
  820. if (!conn->finished) {
  821. conn->error_handler (conn, err);
  822. }
  823. else {
  824. msg_err ("got error after HTTP request is finished: %e", err);
  825. }
  826. g_error_free (err);
  827. REF_RELEASE (pbuf);
  828. rspamd_http_connection_unref (conn);
  829. return;
  830. }
  831. }
  832. else if (r == 0) {
  833. /* We can still call http parser */
  834. http_parser_execute (&priv->parser, &priv->parser_cb, d, r);
  835. if (!conn->finished) {
  836. err = g_error_new (HTTP_ERROR,
  837. errno,
  838. "IO read error: unexpected EOF");
  839. conn->error_handler (conn, err);
  840. g_error_free (err);
  841. }
  842. REF_RELEASE (pbuf);
  843. rspamd_http_connection_unref (conn);
  844. return;
  845. }
  846. else {
  847. if (!priv->ssl) {
  848. err = g_error_new (HTTP_ERROR,
  849. errno,
  850. "IO read error: %s",
  851. strerror (errno));
  852. conn->error_handler (conn, err);
  853. g_error_free (err);
  854. }
  855. REF_RELEASE (pbuf);
  856. rspamd_http_connection_unref (conn);
  857. return;
  858. }
  859. }
  860. else if (what == EV_TIMEOUT) {
  861. /* Let's try to read from the socket first */
  862. r = rspamd_http_try_read (fd, conn, priv, pbuf, &d);
  863. if (r > 0) {
  864. if (http_parser_execute (&priv->parser, &priv->parser_cb,
  865. d, r) != (size_t)r || priv->parser.http_errno != 0) {
  866. err = g_error_new (HTTP_ERROR, priv->parser.http_errno,
  867. "HTTP parser error: %s",
  868. http_errno_description (priv->parser.http_errno));
  869. if (!conn->finished) {
  870. conn->error_handler (conn, err);
  871. }
  872. else {
  873. msg_err ("got error after HTTP request is finished: %e", err);
  874. }
  875. g_error_free (err);
  876. REF_RELEASE (pbuf);
  877. rspamd_http_connection_unref (conn);
  878. return;
  879. }
  880. }
  881. else if (r == 0) {
  882. if (!conn->finished) {
  883. err = g_error_new (HTTP_ERROR, ETIMEDOUT,
  884. "IO timeout");
  885. conn->error_handler (conn, err);
  886. g_error_free (err);
  887. }
  888. REF_RELEASE (pbuf);
  889. rspamd_http_connection_unref (conn);
  890. return;
  891. }
  892. else {
  893. err = g_error_new (HTTP_ERROR, ETIMEDOUT,
  894. "IO timeout");
  895. conn->error_handler (conn, err);
  896. g_error_free (err);
  897. REF_RELEASE (pbuf);
  898. rspamd_http_connection_unref (conn);
  899. return;
  900. }
  901. }
  902. else if (what == EV_WRITE) {
  903. rspamd_http_write_helper (conn);
  904. }
  905. REF_RELEASE (pbuf);
  906. rspamd_http_connection_unref (conn);
  907. }
  908. static void
  909. rspamd_http_parser_reset (struct rspamd_http_connection *conn)
  910. {
  911. struct rspamd_http_connection_private *priv = conn->priv;
  912. http_parser_init (&priv->parser,
  913. conn->type == RSPAMD_HTTP_SERVER ? HTTP_REQUEST : HTTP_RESPONSE);
  914. priv->parser_cb.on_url = rspamd_http_on_url;
  915. priv->parser_cb.on_status = rspamd_http_on_status;
  916. priv->parser_cb.on_header_field = rspamd_http_on_header_field;
  917. priv->parser_cb.on_header_value = rspamd_http_on_header_value;
  918. priv->parser_cb.on_headers_complete = rspamd_http_on_headers_complete;
  919. priv->parser_cb.on_body = rspamd_http_on_body;
  920. priv->parser_cb.on_message_complete = rspamd_http_on_message_complete;
  921. }
  922. static struct rspamd_http_connection *
  923. rspamd_http_connection_new_common (struct rspamd_http_context *ctx,
  924. gint fd,
  925. rspamd_http_body_handler_t body_handler,
  926. rspamd_http_error_handler_t error_handler,
  927. rspamd_http_finish_handler_t finish_handler,
  928. unsigned opts,
  929. enum rspamd_http_connection_type type,
  930. enum rspamd_http_priv_flags priv_flags,
  931. struct upstream *proxy_upstream)
  932. {
  933. struct rspamd_http_connection *conn;
  934. struct rspamd_http_connection_private *priv;
  935. g_assert (error_handler != NULL && finish_handler != NULL);
  936. if (ctx == NULL) {
  937. ctx = rspamd_http_context_default ();
  938. }
  939. conn = g_malloc0 (sizeof (struct rspamd_http_connection));
  940. conn->opts = opts;
  941. conn->type = type;
  942. conn->body_handler = body_handler;
  943. conn->error_handler = error_handler;
  944. conn->finish_handler = finish_handler;
  945. conn->fd = fd;
  946. conn->ref = 1;
  947. conn->finished = FALSE;
  948. /* Init priv */
  949. priv = g_malloc0 (sizeof (struct rspamd_http_connection_private));
  950. conn->priv = priv;
  951. priv->ctx = ctx;
  952. priv->flags = priv_flags;
  953. if (type == RSPAMD_HTTP_SERVER) {
  954. priv->cache = ctx->server_kp_cache;
  955. }
  956. else {
  957. priv->cache = ctx->client_kp_cache;
  958. if (ctx->client_kp) {
  959. priv->local_key = rspamd_keypair_ref (ctx->client_kp);
  960. }
  961. }
  962. rspamd_http_parser_reset (conn);
  963. priv->parser.data = conn;
  964. return conn;
  965. }
  966. struct rspamd_http_connection *
  967. rspamd_http_connection_new_server (struct rspamd_http_context *ctx,
  968. gint fd,
  969. rspamd_http_body_handler_t body_handler,
  970. rspamd_http_error_handler_t error_handler,
  971. rspamd_http_finish_handler_t finish_handler,
  972. unsigned opts)
  973. {
  974. return rspamd_http_connection_new_common (ctx, fd, body_handler,
  975. error_handler, finish_handler, opts, RSPAMD_HTTP_SERVER, 0, NULL);
  976. }
  977. struct rspamd_http_connection *
  978. rspamd_http_connection_new_client_socket (struct rspamd_http_context *ctx,
  979. rspamd_http_body_handler_t body_handler,
  980. rspamd_http_error_handler_t error_handler,
  981. rspamd_http_finish_handler_t finish_handler,
  982. unsigned opts,
  983. gint fd)
  984. {
  985. return rspamd_http_connection_new_common (ctx, fd, body_handler,
  986. error_handler, finish_handler, opts, RSPAMD_HTTP_CLIENT, 0, NULL);
  987. }
  988. struct rspamd_http_connection *
  989. rspamd_http_connection_new_client (struct rspamd_http_context *ctx,
  990. rspamd_http_body_handler_t body_handler,
  991. rspamd_http_error_handler_t error_handler,
  992. rspamd_http_finish_handler_t finish_handler,
  993. unsigned opts,
  994. rspamd_inet_addr_t *addr)
  995. {
  996. gint fd;
  997. if (ctx == NULL) {
  998. ctx = rspamd_http_context_default ();
  999. }
  1000. if (ctx->http_proxies) {
  1001. struct upstream *up = rspamd_upstream_get (ctx->http_proxies,
  1002. RSPAMD_UPSTREAM_ROUND_ROBIN, NULL, 0);
  1003. if (up) {
  1004. rspamd_inet_addr_t *proxy_addr = rspamd_upstream_addr_next (up);
  1005. fd = rspamd_inet_address_connect (proxy_addr, SOCK_STREAM, TRUE);
  1006. if (fd == -1) {
  1007. msg_info ("cannot connect to http proxy %s: %s",
  1008. rspamd_inet_address_to_string_pretty (proxy_addr),
  1009. strerror (errno));
  1010. rspamd_upstream_fail (up, TRUE, strerror (errno));
  1011. return NULL;
  1012. }
  1013. return rspamd_http_connection_new_common (ctx, fd, body_handler,
  1014. error_handler, finish_handler, opts,
  1015. RSPAMD_HTTP_CLIENT,
  1016. RSPAMD_HTTP_CONN_OWN_SOCKET|RSPAMD_HTTP_CONN_FLAG_PROXY,
  1017. up);
  1018. }
  1019. }
  1020. /* Unproxied version */
  1021. fd = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE);
  1022. if (fd == -1) {
  1023. msg_info ("cannot connect make http connection to %s: %s",
  1024. rspamd_inet_address_to_string_pretty (addr),
  1025. strerror (errno));
  1026. return NULL;
  1027. }
  1028. return rspamd_http_connection_new_common (ctx, fd, body_handler,
  1029. error_handler, finish_handler, opts,
  1030. RSPAMD_HTTP_CLIENT,
  1031. RSPAMD_HTTP_CONN_OWN_SOCKET,
  1032. NULL);
  1033. }
  1034. struct rspamd_http_connection *
  1035. rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx,
  1036. rspamd_http_body_handler_t body_handler,
  1037. rspamd_http_error_handler_t error_handler,
  1038. rspamd_http_finish_handler_t finish_handler,
  1039. rspamd_inet_addr_t *addr,
  1040. const gchar *host)
  1041. {
  1042. struct rspamd_http_connection *conn;
  1043. if (ctx == NULL) {
  1044. ctx = rspamd_http_context_default ();
  1045. }
  1046. conn = rspamd_http_context_check_keepalive (ctx, addr, host);
  1047. if (conn) {
  1048. return conn;
  1049. }
  1050. conn = rspamd_http_connection_new_client (ctx,
  1051. body_handler, error_handler, finish_handler,
  1052. RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_KEEP_ALIVE,
  1053. addr);
  1054. if (conn) {
  1055. rspamd_http_context_prepare_keepalive (ctx, conn, addr, host);
  1056. }
  1057. return conn;
  1058. }
  1059. void
  1060. rspamd_http_connection_reset (struct rspamd_http_connection *conn)
  1061. {
  1062. struct rspamd_http_connection_private *priv;
  1063. struct rspamd_http_message *msg;
  1064. priv = conn->priv;
  1065. msg = priv->msg;
  1066. /* Clear request */
  1067. if (msg != NULL) {
  1068. if (msg->peer_key) {
  1069. priv->peer_key = msg->peer_key;
  1070. msg->peer_key = NULL;
  1071. }
  1072. rspamd_http_message_unref (msg);
  1073. priv->msg = NULL;
  1074. }
  1075. conn->finished = FALSE;
  1076. /* Clear priv */
  1077. rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev);
  1078. if (!(priv->flags & RSPAMD_HTTP_CONN_FLAG_RESETED)) {
  1079. rspamd_http_parser_reset (conn);
  1080. }
  1081. if (priv->buf != NULL) {
  1082. REF_RELEASE (priv->buf);
  1083. priv->buf = NULL;
  1084. }
  1085. if (priv->out != NULL) {
  1086. g_free (priv->out);
  1087. priv->out = NULL;
  1088. }
  1089. priv->flags |= RSPAMD_HTTP_CONN_FLAG_RESETED;
  1090. }
  1091. struct rspamd_http_message *
  1092. rspamd_http_connection_steal_msg (struct rspamd_http_connection *conn)
  1093. {
  1094. struct rspamd_http_connection_private *priv;
  1095. struct rspamd_http_message *msg;
  1096. priv = conn->priv;
  1097. msg = priv->msg;
  1098. /* Clear request */
  1099. if (msg != NULL) {
  1100. if (msg->peer_key) {
  1101. priv->peer_key = msg->peer_key;
  1102. msg->peer_key = NULL;
  1103. }
  1104. priv->msg = NULL;
  1105. }
  1106. return msg;
  1107. }
  1108. struct rspamd_http_message *
  1109. rspamd_http_connection_copy_msg (struct rspamd_http_message *msg, GError **err)
  1110. {
  1111. struct rspamd_http_message *new_msg;
  1112. struct rspamd_http_header *hdr, *nhdr, *nhdrs, *hcur;
  1113. const gchar *old_body;
  1114. gsize old_len;
  1115. struct stat st;
  1116. union _rspamd_storage_u *storage;
  1117. new_msg = rspamd_http_new_message (msg->type);
  1118. new_msg->flags = msg->flags;
  1119. if (msg->body_buf.len > 0) {
  1120. if (msg->flags & RSPAMD_HTTP_FLAG_SHMEM) {
  1121. /* Avoid copying by just maping a shared segment */
  1122. new_msg->flags |= RSPAMD_HTTP_FLAG_SHMEM_IMMUTABLE;
  1123. storage = &new_msg->body_buf.c;
  1124. storage->shared.shm_fd = dup (msg->body_buf.c.shared.shm_fd);
  1125. if (storage->shared.shm_fd == -1) {
  1126. rspamd_http_message_unref (new_msg);
  1127. g_set_error (err, http_error_quark (), errno,
  1128. "cannot dup shmem fd: %d: %s",
  1129. msg->body_buf.c.shared.shm_fd, strerror (errno));
  1130. return NULL;
  1131. }
  1132. if (fstat (storage->shared.shm_fd, &st) == -1) {
  1133. g_set_error (err, http_error_quark (), errno,
  1134. "cannot stat shmem fd: %d: %s",
  1135. storage->shared.shm_fd, strerror (errno));
  1136. rspamd_http_message_unref (new_msg);
  1137. return NULL;
  1138. }
  1139. /* We don't own segment, so do not try to touch it */
  1140. if (msg->body_buf.c.shared.name) {
  1141. storage->shared.name = msg->body_buf.c.shared.name;
  1142. REF_RETAIN (storage->shared.name);
  1143. }
  1144. new_msg->body_buf.str = mmap (NULL, st.st_size,
  1145. PROT_READ, MAP_SHARED,
  1146. storage->shared.shm_fd, 0);
  1147. if (new_msg->body_buf.str == MAP_FAILED) {
  1148. g_set_error (err, http_error_quark (), errno,
  1149. "cannot mmap shmem fd: %d: %s",
  1150. storage->shared.shm_fd, strerror (errno));
  1151. rspamd_http_message_unref (new_msg);
  1152. return NULL;
  1153. }
  1154. new_msg->body_buf.begin = new_msg->body_buf.str;
  1155. new_msg->body_buf.len = msg->body_buf.len;
  1156. new_msg->body_buf.begin = new_msg->body_buf.str +
  1157. (msg->body_buf.begin - msg->body_buf.str);
  1158. }
  1159. else {
  1160. old_body = rspamd_http_message_get_body (msg, &old_len);
  1161. if (!rspamd_http_message_set_body (new_msg, old_body, old_len)) {
  1162. g_set_error (err, http_error_quark (), errno,
  1163. "cannot set body for message, length: %zd",
  1164. old_len);
  1165. rspamd_http_message_unref (new_msg);
  1166. return NULL;
  1167. }
  1168. }
  1169. }
  1170. if (msg->url) {
  1171. if (new_msg->url) {
  1172. new_msg->url = rspamd_fstring_append (new_msg->url, msg->url->str,
  1173. msg->url->len);
  1174. }
  1175. else {
  1176. new_msg->url = rspamd_fstring_new_init (msg->url->str,
  1177. msg->url->len);
  1178. }
  1179. }
  1180. if (msg->host) {
  1181. new_msg->host = g_string_new_len (msg->host->str, msg->host->len);
  1182. }
  1183. new_msg->method = msg->method;
  1184. new_msg->port = msg->port;
  1185. new_msg->date = msg->date;
  1186. new_msg->last_modified = msg->last_modified;
  1187. kh_foreach_value (msg->headers, hdr, {
  1188. nhdrs = NULL;
  1189. DL_FOREACH (hdr, hcur) {
  1190. nhdr = g_malloc (sizeof (struct rspamd_http_header));
  1191. nhdr->combined = rspamd_fstring_new_init (hcur->combined->str,
  1192. hcur->combined->len);
  1193. nhdr->name.begin = nhdr->combined->str +
  1194. (hcur->name.begin - hcur->combined->str);
  1195. nhdr->name.len = hcur->name.len;
  1196. nhdr->value.begin = nhdr->combined->str +
  1197. (hcur->value.begin - hcur->combined->str);
  1198. nhdr->value.len = hcur->value.len;
  1199. DL_APPEND (nhdrs, nhdr);
  1200. }
  1201. gint r;
  1202. khiter_t k = kh_put (rspamd_http_headers_hash, new_msg->headers,
  1203. &nhdrs->name,&r);
  1204. if (r != 0) {
  1205. kh_value (new_msg->headers, k) = nhdrs;
  1206. }
  1207. else {
  1208. DL_CONCAT (kh_value (new_msg->headers, k), nhdrs);
  1209. }
  1210. });
  1211. return new_msg;
  1212. }
  1213. void
  1214. rspamd_http_connection_free (struct rspamd_http_connection *conn)
  1215. {
  1216. struct rspamd_http_connection_private *priv;
  1217. priv = conn->priv;
  1218. if (priv != NULL) {
  1219. rspamd_http_connection_reset (conn);
  1220. if (priv->ssl) {
  1221. rspamd_ssl_connection_free (priv->ssl);
  1222. priv->ssl = NULL;
  1223. }
  1224. if (priv->local_key) {
  1225. rspamd_keypair_unref (priv->local_key);
  1226. }
  1227. if (priv->peer_key) {
  1228. rspamd_pubkey_unref (priv->peer_key);
  1229. }
  1230. if (priv->flags & RSPAMD_HTTP_CONN_OWN_SOCKET) {
  1231. /* Fd is owned by a connection */
  1232. close (conn->fd);
  1233. }
  1234. g_free (priv);
  1235. }
  1236. g_free (conn);
  1237. }
  1238. static void
  1239. rspamd_http_connection_read_message_common (struct rspamd_http_connection *conn,
  1240. gpointer ud, ev_tstamp timeout,
  1241. gint flags)
  1242. {
  1243. struct rspamd_http_connection_private *priv = conn->priv;
  1244. struct rspamd_http_message *req;
  1245. conn->ud = ud;
  1246. req = rspamd_http_new_message (
  1247. conn->type == RSPAMD_HTTP_SERVER ? HTTP_REQUEST : HTTP_RESPONSE);
  1248. priv->msg = req;
  1249. req->flags = flags;
  1250. if (flags & RSPAMD_HTTP_FLAG_SHMEM) {
  1251. req->body_buf.c.shared.shm_fd = -1;
  1252. }
  1253. if (priv->peer_key) {
  1254. priv->msg->peer_key = priv->peer_key;
  1255. priv->peer_key = NULL;
  1256. priv->flags |= RSPAMD_HTTP_CONN_FLAG_ENCRYPTED;
  1257. }
  1258. priv->timeout = timeout;
  1259. priv->header = NULL;
  1260. priv->buf = g_malloc0 (sizeof (*priv->buf));
  1261. REF_INIT_RETAIN (priv->buf, rspamd_http_privbuf_dtor);
  1262. priv->buf->data = rspamd_fstring_sized_new (8192);
  1263. priv->flags |= RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
  1264. rspamd_ev_watcher_init (&priv->ev, conn->fd, EV_READ,
  1265. rspamd_http_event_handler, conn);
  1266. rspamd_ev_watcher_start (priv->ctx->event_loop, &priv->ev, priv->timeout);
  1267. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_RESETED;
  1268. }
  1269. void
  1270. rspamd_http_connection_read_message (struct rspamd_http_connection *conn,
  1271. gpointer ud, ev_tstamp timeout)
  1272. {
  1273. rspamd_http_connection_read_message_common (conn, ud, timeout, 0);
  1274. }
  1275. void
  1276. rspamd_http_connection_read_message_shared (struct rspamd_http_connection *conn,
  1277. gpointer ud, ev_tstamp timeout)
  1278. {
  1279. rspamd_http_connection_read_message_common (conn, ud, timeout,
  1280. RSPAMD_HTTP_FLAG_SHMEM);
  1281. }
  1282. static void
  1283. rspamd_http_connection_encrypt_message (
  1284. struct rspamd_http_connection *conn,
  1285. struct rspamd_http_message *msg,
  1286. struct rspamd_http_connection_private *priv,
  1287. guchar *pbody,
  1288. guint bodylen,
  1289. guchar *pmethod,
  1290. guint methodlen,
  1291. guint preludelen,
  1292. gint hdrcount,
  1293. guchar *np,
  1294. guchar *mp,
  1295. struct rspamd_cryptobox_pubkey *peer_key)
  1296. {
  1297. struct rspamd_cryptobox_segment *segments;
  1298. guchar *crlfp;
  1299. const guchar *nm;
  1300. gint i, cnt;
  1301. guint outlen;
  1302. struct rspamd_http_header *hdr, *hcur;
  1303. enum rspamd_cryptobox_mode mode;
  1304. mode = rspamd_keypair_alg (priv->local_key);
  1305. crlfp = mp + rspamd_cryptobox_mac_bytes (mode);
  1306. outlen = priv->out[0].iov_len + priv->out[1].iov_len;
  1307. /*
  1308. * Create segments from the following:
  1309. * Method, [URL], CRLF, nheaders, CRLF, body
  1310. */
  1311. segments = g_new (struct rspamd_cryptobox_segment, hdrcount + 5);
  1312. segments[0].data = pmethod;
  1313. segments[0].len = methodlen;
  1314. if (conn->type != RSPAMD_HTTP_SERVER) {
  1315. segments[1].data = msg->url->str;
  1316. segments[1].len = msg->url->len;
  1317. /* space + HTTP version + crlf */
  1318. segments[2].data = crlfp;
  1319. segments[2].len = preludelen - 2;
  1320. crlfp += segments[2].len;
  1321. i = 3;
  1322. }
  1323. else {
  1324. /* Here we send just CRLF */
  1325. segments[1].data = crlfp;
  1326. segments[1].len = 2;
  1327. crlfp += segments[1].len;
  1328. i = 2;
  1329. }
  1330. kh_foreach_value (msg->headers, hdr, {
  1331. DL_FOREACH (hdr, hcur) {
  1332. segments[i].data = hcur->combined->str;
  1333. segments[i++].len = hcur->combined->len;
  1334. }
  1335. });
  1336. /* crlfp should point now at the second crlf */
  1337. segments[i].data = crlfp;
  1338. segments[i++].len = 2;
  1339. if (pbody) {
  1340. segments[i].data = pbody;
  1341. segments[i++].len = bodylen;
  1342. }
  1343. cnt = i;
  1344. if ((nm = rspamd_pubkey_get_nm (peer_key, priv->local_key)) == NULL) {
  1345. nm = rspamd_pubkey_calculate_nm (peer_key, priv->local_key);
  1346. }
  1347. rspamd_cryptobox_encryptv_nm_inplace (segments, cnt, np, nm, mp, mode);
  1348. /*
  1349. * iov[0] = base HTTP request
  1350. * iov[1] = CRLF
  1351. * iov[2] = nonce
  1352. * iov[3] = mac
  1353. * iov[4..i] = encrypted HTTP request/reply
  1354. */
  1355. priv->out[2].iov_base = np;
  1356. priv->out[2].iov_len = rspamd_cryptobox_nonce_bytes (mode);
  1357. priv->out[3].iov_base = mp;
  1358. priv->out[3].iov_len = rspamd_cryptobox_mac_bytes (mode);
  1359. outlen += rspamd_cryptobox_nonce_bytes (mode) +
  1360. rspamd_cryptobox_mac_bytes (mode);
  1361. for (i = 0; i < cnt; i ++) {
  1362. priv->out[i + 4].iov_base = segments[i].data;
  1363. priv->out[i + 4].iov_len = segments[i].len;
  1364. outlen += segments[i].len;
  1365. }
  1366. priv->wr_total = outlen;
  1367. g_free (segments);
  1368. }
  1369. static void
  1370. rspamd_http_detach_shared (struct rspamd_http_message *msg)
  1371. {
  1372. rspamd_fstring_t *cpy_str;
  1373. cpy_str = rspamd_fstring_new_init (msg->body_buf.begin, msg->body_buf.len);
  1374. rspamd_http_message_set_body_from_fstring_steal (msg, cpy_str);
  1375. }
  1376. gint
  1377. rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
  1378. gchar *repbuf, gsize replen, gsize bodylen, gsize enclen, const gchar* host,
  1379. struct rspamd_http_connection* conn, struct rspamd_http_message* msg,
  1380. rspamd_fstring_t** buf,
  1381. struct rspamd_http_connection_private* priv,
  1382. struct rspamd_cryptobox_pubkey* peer_key)
  1383. {
  1384. gchar datebuf[64];
  1385. gint meth_len = 0;
  1386. const gchar *conn_type = "close";
  1387. if (conn->type == RSPAMD_HTTP_SERVER) {
  1388. /* Format reply */
  1389. if (msg->method < HTTP_SYMBOLS) {
  1390. rspamd_ftok_t status;
  1391. rspamd_http_date_format (datebuf, sizeof (datebuf), msg->date);
  1392. if (mime_type == NULL) {
  1393. mime_type =
  1394. encrypted ? "application/octet-stream" : "text/plain";
  1395. }
  1396. if (msg->status == NULL || msg->status->len == 0) {
  1397. if (msg->code == 200) {
  1398. RSPAMD_FTOK_ASSIGN (&status, "OK");
  1399. }
  1400. else if (msg->code == 404) {
  1401. RSPAMD_FTOK_ASSIGN (&status, "Not Found");
  1402. }
  1403. else if (msg->code == 403) {
  1404. RSPAMD_FTOK_ASSIGN (&status, "Forbidden");
  1405. }
  1406. else if (msg->code >= 500 && msg->code < 600) {
  1407. RSPAMD_FTOK_ASSIGN (&status, "Internal Server Error");
  1408. }
  1409. else {
  1410. RSPAMD_FTOK_ASSIGN (&status, "Undefined Error");
  1411. }
  1412. }
  1413. else {
  1414. status.begin = msg->status->str;
  1415. status.len = msg->status->len;
  1416. }
  1417. if (encrypted) {
  1418. /* Internal reply (encrypted) */
  1419. if (mime_type) {
  1420. meth_len =
  1421. rspamd_snprintf (repbuf, replen,
  1422. "HTTP/1.1 %d %T\r\n"
  1423. "Connection: close\r\n"
  1424. "Server: %s\r\n"
  1425. "Date: %s\r\n"
  1426. "Content-Length: %z\r\n"
  1427. "Content-Type: %s", /* NO \r\n at the end ! */
  1428. msg->code, &status, priv->ctx->config.server_hdr,
  1429. datebuf,
  1430. bodylen, mime_type);
  1431. }
  1432. else {
  1433. meth_len =
  1434. rspamd_snprintf (repbuf, replen,
  1435. "HTTP/1.1 %d %T\r\n"
  1436. "Connection: close\r\n"
  1437. "Server: %s\r\n"
  1438. "Date: %s\r\n"
  1439. "Content-Length: %z", /* NO \r\n at the end ! */
  1440. msg->code, &status, priv->ctx->config.server_hdr,
  1441. datebuf,
  1442. bodylen);
  1443. }
  1444. enclen += meth_len;
  1445. /* External reply */
  1446. rspamd_printf_fstring (buf,
  1447. "HTTP/1.1 200 OK\r\n"
  1448. "Connection: close\r\n"
  1449. "Server: %s\r\n"
  1450. "Date: %s\r\n"
  1451. "Content-Length: %z\r\n"
  1452. "Content-Type: application/octet-stream\r\n",
  1453. priv->ctx->config.server_hdr,
  1454. datebuf, enclen);
  1455. }
  1456. else {
  1457. if (mime_type) {
  1458. meth_len =
  1459. rspamd_printf_fstring (buf,
  1460. "HTTP/1.1 %d %T\r\n"
  1461. "Connection: close\r\n"
  1462. "Server: %s\r\n"
  1463. "Date: %s\r\n"
  1464. "Content-Length: %z\r\n"
  1465. "Content-Type: %s\r\n",
  1466. msg->code, &status, priv->ctx->config.server_hdr,
  1467. datebuf,
  1468. bodylen, mime_type);
  1469. }
  1470. else {
  1471. meth_len =
  1472. rspamd_printf_fstring (buf,
  1473. "HTTP/1.1 %d %T\r\n"
  1474. "Connection: close\r\n"
  1475. "Server: %s\r\n"
  1476. "Date: %s\r\n"
  1477. "Content-Length: %z\r\n",
  1478. msg->code, &status, priv->ctx->config.server_hdr,
  1479. datebuf,
  1480. bodylen);
  1481. }
  1482. }
  1483. }
  1484. else {
  1485. /* Legacy spamd reply */
  1486. if (msg->flags & RSPAMD_HTTP_FLAG_SPAMC) {
  1487. gsize real_bodylen;
  1488. goffset eoh_pos;
  1489. GString tmp;
  1490. /* Unfortunately, spamc protocol is deadly brain damaged */
  1491. tmp.str = (gchar *)msg->body_buf.begin;
  1492. tmp.len = msg->body_buf.len;
  1493. if (rspamd_string_find_eoh (&tmp, &eoh_pos) != -1 &&
  1494. bodylen > eoh_pos) {
  1495. real_bodylen = bodylen - eoh_pos;
  1496. }
  1497. else {
  1498. real_bodylen = bodylen;
  1499. }
  1500. rspamd_printf_fstring (buf, "SPAMD/1.1 0 EX_OK\r\n"
  1501. "Content-length: %z\r\n",
  1502. real_bodylen);
  1503. }
  1504. else {
  1505. rspamd_printf_fstring (buf, "RSPAMD/1.3 0 EX_OK\r\n");
  1506. }
  1507. }
  1508. }
  1509. else {
  1510. /* Client request */
  1511. if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
  1512. conn_type = "keep-alive";
  1513. }
  1514. /* Format request */
  1515. enclen += RSPAMD_FSTRING_LEN (msg->url) +
  1516. strlen (http_method_str (msg->method)) + 1;
  1517. if (host == NULL && msg->host == NULL) {
  1518. /* Fallback to HTTP/1.0 */
  1519. if (encrypted) {
  1520. rspamd_printf_fstring (buf,
  1521. "%s %s HTTP/1.0\r\n"
  1522. "Content-Length: %z\r\n"
  1523. "Content-Type: application/octet-stream\r\n"
  1524. "Connection: %s\r\n",
  1525. "POST",
  1526. "/post",
  1527. enclen,
  1528. conn_type);
  1529. }
  1530. else {
  1531. rspamd_printf_fstring (buf,
  1532. "%s %V HTTP/1.0\r\n"
  1533. "Content-Length: %z\r\n"
  1534. "Connection: %s\r\n",
  1535. http_method_str (msg->method),
  1536. msg->url,
  1537. bodylen,
  1538. conn_type);
  1539. if (bodylen > 0) {
  1540. if (mime_type == NULL) {
  1541. mime_type = "text/plain";
  1542. }
  1543. rspamd_printf_fstring (buf,
  1544. "Content-Type: %s\r\n",
  1545. mime_type);
  1546. }
  1547. }
  1548. }
  1549. else {
  1550. /* Normal HTTP/1.1 with Host */
  1551. if (host == NULL) {
  1552. host = msg->host->str;
  1553. }
  1554. if (encrypted) {
  1555. /* TODO: Add proxy support to HTTPCrypt */
  1556. rspamd_printf_fstring (buf,
  1557. "%s %s HTTP/1.1\r\n"
  1558. "Connection: %s\r\n"
  1559. "Host: %s\r\n"
  1560. "Content-Length: %z\r\n"
  1561. "Content-Type: application/octet-stream\r\n",
  1562. "POST",
  1563. "/post",
  1564. conn_type,
  1565. host,
  1566. enclen);
  1567. }
  1568. else {
  1569. if (conn->priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) {
  1570. rspamd_printf_fstring (buf,
  1571. "%s %s://%s:%d/%V HTTP/1.1\r\n"
  1572. "Connection: %s\r\n"
  1573. "Host: %s\r\n"
  1574. "Content-Length: %z\r\n",
  1575. http_method_str (msg->method),
  1576. (msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http",
  1577. host,
  1578. msg->port,
  1579. msg->url,
  1580. conn_type,
  1581. host,
  1582. bodylen);
  1583. }
  1584. else {
  1585. rspamd_printf_fstring (buf,
  1586. "%s %V HTTP/1.1\r\n"
  1587. "Connection: %s\r\n"
  1588. "Host: %s\r\n"
  1589. "Content-Length: %z\r\n",
  1590. http_method_str (msg->method),
  1591. msg->url,
  1592. conn_type,
  1593. host,
  1594. bodylen);
  1595. }
  1596. if (bodylen > 0) {
  1597. if (mime_type != NULL) {
  1598. rspamd_printf_fstring (buf,
  1599. "Content-Type: %s\r\n",
  1600. mime_type);
  1601. }
  1602. }
  1603. }
  1604. }
  1605. if (encrypted) {
  1606. GString *b32_key, *b32_id;
  1607. b32_key = rspamd_keypair_print (priv->local_key,
  1608. RSPAMD_KEYPAIR_PUBKEY | RSPAMD_KEYPAIR_BASE32);
  1609. b32_id = rspamd_pubkey_print (peer_key,
  1610. RSPAMD_KEYPAIR_ID_SHORT | RSPAMD_KEYPAIR_BASE32);
  1611. /* XXX: add some fuzz here */
  1612. rspamd_printf_fstring (&*buf, "Key: %v=%v\r\n", b32_id, b32_key);
  1613. g_string_free (b32_key, TRUE);
  1614. g_string_free (b32_id, TRUE);
  1615. }
  1616. }
  1617. return meth_len;
  1618. }
  1619. static gboolean
  1620. rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn,
  1621. struct rspamd_http_message *msg,
  1622. const gchar *host,
  1623. const gchar *mime_type,
  1624. gpointer ud,
  1625. ev_tstamp timeout,
  1626. gboolean allow_shared)
  1627. {
  1628. struct rspamd_http_connection_private *priv = conn->priv;
  1629. struct rspamd_http_header *hdr, *hcur;
  1630. gchar repbuf[512], *pbody;
  1631. gint i, hdrcount, meth_len = 0, preludelen = 0;
  1632. gsize bodylen, enclen = 0;
  1633. rspamd_fstring_t *buf;
  1634. gboolean encrypted = FALSE;
  1635. guchar nonce[rspamd_cryptobox_MAX_NONCEBYTES], mac[rspamd_cryptobox_MAX_MACBYTES];
  1636. guchar *np = NULL, *mp = NULL, *meth_pos = NULL;
  1637. struct rspamd_cryptobox_pubkey *peer_key = NULL;
  1638. enum rspamd_cryptobox_mode mode;
  1639. GError *err;
  1640. conn->ud = ud;
  1641. priv->msg = msg;
  1642. priv->timeout = timeout;
  1643. priv->header = NULL;
  1644. priv->buf = g_malloc0 (sizeof (*priv->buf));
  1645. REF_INIT_RETAIN (priv->buf, rspamd_http_privbuf_dtor);
  1646. priv->buf->data = rspamd_fstring_sized_new (512);
  1647. buf = priv->buf->data;
  1648. if (priv->peer_key && priv->local_key) {
  1649. priv->msg->peer_key = priv->peer_key;
  1650. priv->peer_key = NULL;
  1651. priv->flags |= RSPAMD_HTTP_CONN_FLAG_ENCRYPTED;
  1652. }
  1653. if (msg->peer_key != NULL) {
  1654. if (priv->local_key == NULL) {
  1655. /* Automatically generate a temporary keypair */
  1656. priv->local_key = rspamd_keypair_new (RSPAMD_KEYPAIR_KEX,
  1657. RSPAMD_CRYPTOBOX_MODE_25519);
  1658. }
  1659. encrypted = TRUE;
  1660. if (priv->cache) {
  1661. rspamd_keypair_cache_process (priv->cache,
  1662. priv->local_key, priv->msg->peer_key);
  1663. }
  1664. }
  1665. if (encrypted && (msg->flags &
  1666. (RSPAMD_HTTP_FLAG_SHMEM_IMMUTABLE|RSPAMD_HTTP_FLAG_SHMEM))) {
  1667. /* We cannot use immutable body to encrypt message in place */
  1668. allow_shared = FALSE;
  1669. rspamd_http_detach_shared (msg);
  1670. }
  1671. if (allow_shared) {
  1672. gchar tmpbuf[64];
  1673. if (!(msg->flags & RSPAMD_HTTP_FLAG_SHMEM) ||
  1674. msg->body_buf.c.shared.name == NULL) {
  1675. allow_shared = FALSE;
  1676. }
  1677. else {
  1678. /* Insert new headers */
  1679. rspamd_http_message_add_header (msg, "Shm",
  1680. msg->body_buf.c.shared.name->shm_name);
  1681. rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "%d",
  1682. (int)(msg->body_buf.begin - msg->body_buf.str));
  1683. rspamd_http_message_add_header (msg, "Shm-Offset",
  1684. tmpbuf);
  1685. rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "%z",
  1686. msg->body_buf.len);
  1687. rspamd_http_message_add_header (msg, "Shm-Length",
  1688. tmpbuf);
  1689. }
  1690. }
  1691. if (priv->ctx->config.user_agent && conn->type == RSPAMD_HTTP_CLIENT) {
  1692. rspamd_ftok_t srch;
  1693. khiter_t k;
  1694. gint r;
  1695. RSPAMD_FTOK_ASSIGN (&srch, "User-Agent");
  1696. k = kh_put (rspamd_http_headers_hash, msg->headers, &srch,&r);
  1697. if (r != 0) {
  1698. hdr = g_malloc0 (sizeof (struct rspamd_http_header));
  1699. guint vlen = strlen (priv->ctx->config.user_agent);
  1700. hdr->combined = rspamd_fstring_sized_new (srch.len + vlen + 4);
  1701. rspamd_printf_fstring (&hdr->combined, "%T: %*s\r\n", &srch, vlen,
  1702. priv->ctx->config.user_agent);
  1703. hdr->name.begin = hdr->combined->str;
  1704. hdr->name.len = srch.len;
  1705. hdr->value.begin = hdr->combined->str + srch.len + 2;
  1706. hdr->value.len = vlen;
  1707. hdr->prev = hdr; /* for utlists */
  1708. kh_value (msg->headers, k) = hdr;
  1709. /* as we searched using static buffer */
  1710. kh_key (msg->headers, k) = &hdr->name;
  1711. }
  1712. }
  1713. if (encrypted) {
  1714. mode = rspamd_keypair_alg (priv->local_key);
  1715. if (msg->body_buf.len == 0) {
  1716. pbody = NULL;
  1717. bodylen = 0;
  1718. msg->method = HTTP_GET;
  1719. }
  1720. else {
  1721. pbody = (gchar *)msg->body_buf.begin;
  1722. bodylen = msg->body_buf.len;
  1723. msg->method = HTTP_POST;
  1724. }
  1725. if (conn->type == RSPAMD_HTTP_SERVER) {
  1726. /*
  1727. * iov[0] = base reply
  1728. * iov[1] = CRLF
  1729. * iov[2] = nonce
  1730. * iov[3] = mac
  1731. * iov[4] = encrypted reply
  1732. * iov[6] = encrypted crlf
  1733. * iov[7..n] = encrypted headers
  1734. * iov[n + 1] = encrypted crlf
  1735. * [iov[n + 2] = encrypted body]
  1736. */
  1737. priv->outlen = 7;
  1738. enclen = rspamd_cryptobox_nonce_bytes (mode) +
  1739. rspamd_cryptobox_mac_bytes (mode) +
  1740. 4 + /* 2 * CRLF */
  1741. bodylen;
  1742. }
  1743. else {
  1744. /*
  1745. * iov[0] = base request
  1746. * iov[1] = CRLF
  1747. * iov[2] = nonce
  1748. * iov[3] = mac
  1749. * iov[4] = encrypted method + space
  1750. * iov[5] = encrypted url
  1751. * iov[7] = encrypted prelude
  1752. * iov[8..n] = encrypted headers
  1753. * iov[n + 1] = encrypted crlf
  1754. * [iov[n + 2] = encrypted body]
  1755. */
  1756. priv->outlen = 8;
  1757. if (bodylen > 0) {
  1758. if (mime_type != NULL) {
  1759. preludelen = rspamd_snprintf (repbuf, sizeof (repbuf), "%s\r\n"
  1760. "Content-Length: %z\r\n"
  1761. "Content-Type: %s\r\n"
  1762. "\r\n", ENCRYPTED_VERSION, bodylen,
  1763. mime_type);
  1764. }
  1765. else {
  1766. preludelen = rspamd_snprintf (repbuf, sizeof (repbuf), "%s\r\n"
  1767. "Content-Length: %z\r\n"
  1768. ""
  1769. "\r\n", ENCRYPTED_VERSION, bodylen);
  1770. }
  1771. }
  1772. else {
  1773. preludelen = rspamd_snprintf (repbuf, sizeof (repbuf),
  1774. "%s\r\n\r\n",
  1775. ENCRYPTED_VERSION);
  1776. }
  1777. enclen = rspamd_cryptobox_nonce_bytes (mode) +
  1778. rspamd_cryptobox_mac_bytes (mode) +
  1779. preludelen + /* version [content-length] + 2 * CRLF */
  1780. bodylen;
  1781. }
  1782. if (bodylen > 0) {
  1783. priv->outlen ++;
  1784. }
  1785. }
  1786. else {
  1787. if (msg->method < HTTP_SYMBOLS) {
  1788. if (msg->body_buf.len == 0 || allow_shared) {
  1789. pbody = NULL;
  1790. bodylen = 0;
  1791. priv->outlen = 2;
  1792. if (msg->method == HTTP_INVALID) {
  1793. msg->method = HTTP_GET;
  1794. }
  1795. }
  1796. else {
  1797. pbody = (gchar *)msg->body_buf.begin;
  1798. bodylen = msg->body_buf.len;
  1799. priv->outlen = 3;
  1800. if (msg->method == HTTP_INVALID) {
  1801. msg->method = HTTP_POST;
  1802. }
  1803. }
  1804. }
  1805. else if (msg->body_buf.len > 0) {
  1806. allow_shared = FALSE;
  1807. pbody = (gchar *)msg->body_buf.begin;
  1808. bodylen = msg->body_buf.len;
  1809. priv->outlen = 2;
  1810. }
  1811. else {
  1812. /* Invalid body for spamc method */
  1813. abort ();
  1814. }
  1815. }
  1816. peer_key = msg->peer_key;
  1817. priv->wr_total = bodylen + 2;
  1818. hdrcount = 0;
  1819. if (msg->method < HTTP_SYMBOLS) {
  1820. kh_foreach_value (msg->headers, hdr, {
  1821. DL_FOREACH (hdr, hcur) {
  1822. /* <name: value\r\n> */
  1823. priv->wr_total += hcur->combined->len;
  1824. enclen += hcur->combined->len;
  1825. priv->outlen ++;
  1826. hdrcount ++;
  1827. }
  1828. });
  1829. }
  1830. /* Allocate iov */
  1831. priv->out = g_malloc0 (sizeof (struct iovec) * priv->outlen);
  1832. priv->wr_pos = 0;
  1833. meth_len = rspamd_http_message_write_header (mime_type, encrypted,
  1834. repbuf, sizeof (repbuf), bodylen, enclen,
  1835. host, conn, msg,
  1836. &buf, priv, peer_key);
  1837. priv->wr_total += buf->len;
  1838. /* Setup external request body */
  1839. priv->out[0].iov_base = buf->str;
  1840. priv->out[0].iov_len = buf->len;
  1841. /* Buf will be used eventually for encryption */
  1842. if (encrypted) {
  1843. gint meth_offset, nonce_offset, mac_offset;
  1844. mode = rspamd_keypair_alg (priv->local_key);
  1845. ottery_rand_bytes (nonce, rspamd_cryptobox_nonce_bytes (mode));
  1846. memset (mac, 0, rspamd_cryptobox_mac_bytes (mode));
  1847. meth_offset = buf->len;
  1848. if (conn->type == RSPAMD_HTTP_SERVER) {
  1849. buf = rspamd_fstring_append (buf, repbuf, meth_len);
  1850. }
  1851. else {
  1852. meth_len = strlen (http_method_str (msg->method)) + 1; /* + space */
  1853. buf = rspamd_fstring_append (buf, http_method_str (msg->method),
  1854. meth_len - 1);
  1855. buf = rspamd_fstring_append (buf, " ", 1);
  1856. }
  1857. nonce_offset = buf->len;
  1858. buf = rspamd_fstring_append (buf, nonce,
  1859. rspamd_cryptobox_nonce_bytes (mode));
  1860. mac_offset = buf->len;
  1861. buf = rspamd_fstring_append (buf, mac,
  1862. rspamd_cryptobox_mac_bytes (mode));
  1863. /* Need to be encrypted */
  1864. if (conn->type == RSPAMD_HTTP_SERVER) {
  1865. buf = rspamd_fstring_append (buf, "\r\n\r\n", 4);
  1866. }
  1867. else {
  1868. buf = rspamd_fstring_append (buf, repbuf, preludelen);
  1869. }
  1870. meth_pos = buf->str + meth_offset;
  1871. np = buf->str + nonce_offset;
  1872. mp = buf->str + mac_offset;
  1873. }
  1874. /* During previous writes, buf might be reallocated and changed */
  1875. priv->buf->data = buf;
  1876. if (encrypted) {
  1877. /* Finish external HTTP request */
  1878. priv->out[1].iov_base = "\r\n";
  1879. priv->out[1].iov_len = 2;
  1880. /* Encrypt the real request */
  1881. rspamd_http_connection_encrypt_message (conn, msg, priv, pbody, bodylen,
  1882. meth_pos, meth_len, preludelen, hdrcount, np, mp, peer_key);
  1883. }
  1884. else {
  1885. i = 1;
  1886. if (msg->method < HTTP_SYMBOLS) {
  1887. kh_foreach_value (msg->headers, hdr, {
  1888. DL_FOREACH (hdr, hcur) {
  1889. priv->out[i].iov_base = hcur->combined->str;
  1890. priv->out[i++].iov_len = hcur->combined->len;
  1891. }
  1892. });
  1893. priv->out[i].iov_base = "\r\n";
  1894. priv->out[i++].iov_len = 2;
  1895. }
  1896. else {
  1897. /* No CRLF for compatibility reply */
  1898. priv->wr_total -= 2;
  1899. }
  1900. if (pbody != NULL) {
  1901. priv->out[i].iov_base = pbody;
  1902. priv->out[i++].iov_len = bodylen;
  1903. }
  1904. }
  1905. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_RESETED;
  1906. if (priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) {
  1907. /* We need to disable SSL flag! */
  1908. msg->flags &=~ RSPAMD_HTTP_FLAG_SSL;
  1909. }
  1910. rspamd_ev_watcher_stop (priv->ctx->event_loop, &priv->ev);
  1911. if (msg->flags & RSPAMD_HTTP_FLAG_SSL) {
  1912. gpointer ssl_ctx = (msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY) ?
  1913. priv->ctx->ssl_ctx_noverify : priv->ctx->ssl_ctx;
  1914. if (!ssl_ctx) {
  1915. err = g_error_new (HTTP_ERROR, errno, "ssl message requested "
  1916. "with no ssl ctx");
  1917. rspamd_http_connection_ref (conn);
  1918. conn->error_handler (conn, err);
  1919. rspamd_http_connection_unref (conn);
  1920. g_error_free (err);
  1921. return FALSE;
  1922. }
  1923. else {
  1924. if (priv->ssl) {
  1925. /* Cleanup the existing connection */
  1926. rspamd_ssl_connection_free (priv->ssl);
  1927. }
  1928. priv->ssl = rspamd_ssl_connection_new (ssl_ctx, priv->ctx->event_loop,
  1929. !(msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY),
  1930. conn->log_tag);
  1931. g_assert (priv->ssl != NULL);
  1932. if (!rspamd_ssl_connect_fd (priv->ssl, conn->fd, host, &priv->ev,
  1933. priv->timeout, rspamd_http_event_handler,
  1934. rspamd_http_ssl_err_handler, conn)) {
  1935. err = g_error_new (HTTP_ERROR, errno,
  1936. "ssl connection error: ssl error=%s, errno=%s",
  1937. ERR_error_string (ERR_get_error (), NULL),
  1938. strerror (errno));
  1939. rspamd_http_connection_ref (conn);
  1940. conn->error_handler (conn, err);
  1941. rspamd_http_connection_unref (conn);
  1942. g_error_free (err);
  1943. return FALSE;
  1944. }
  1945. }
  1946. }
  1947. else {
  1948. rspamd_ev_watcher_init (&priv->ev, conn->fd, EV_WRITE,
  1949. rspamd_http_event_handler, conn);
  1950. rspamd_ev_watcher_start (priv->ctx->event_loop, &priv->ev, priv->timeout);
  1951. }
  1952. return TRUE;
  1953. }
  1954. gboolean
  1955. rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
  1956. struct rspamd_http_message *msg,
  1957. const gchar *host,
  1958. const gchar *mime_type,
  1959. gpointer ud,
  1960. ev_tstamp timeout)
  1961. {
  1962. return rspamd_http_connection_write_message_common (conn, msg, host, mime_type,
  1963. ud, timeout, FALSE);
  1964. }
  1965. gboolean
  1966. rspamd_http_connection_write_message_shared (struct rspamd_http_connection *conn,
  1967. struct rspamd_http_message *msg,
  1968. const gchar *host,
  1969. const gchar *mime_type,
  1970. gpointer ud,
  1971. ev_tstamp timeout)
  1972. {
  1973. return rspamd_http_connection_write_message_common (conn, msg, host, mime_type,
  1974. ud, timeout, TRUE);
  1975. }
  1976. void
  1977. rspamd_http_connection_set_max_size (struct rspamd_http_connection *conn,
  1978. gsize sz)
  1979. {
  1980. conn->max_size = sz;
  1981. }
  1982. void
  1983. rspamd_http_connection_set_key (struct rspamd_http_connection *conn,
  1984. struct rspamd_cryptobox_keypair *key)
  1985. {
  1986. struct rspamd_http_connection_private *priv = conn->priv;
  1987. g_assert (key != NULL);
  1988. priv->local_key = rspamd_keypair_ref (key);
  1989. }
  1990. const struct rspamd_cryptobox_pubkey*
  1991. rspamd_http_connection_get_peer_key (struct rspamd_http_connection *conn)
  1992. {
  1993. struct rspamd_http_connection_private *priv = conn->priv;
  1994. if (priv->peer_key) {
  1995. return priv->peer_key;
  1996. }
  1997. else if (priv->msg) {
  1998. return priv->msg->peer_key;
  1999. }
  2000. return NULL;
  2001. }
  2002. gboolean
  2003. rspamd_http_connection_is_encrypted (struct rspamd_http_connection *conn)
  2004. {
  2005. struct rspamd_http_connection_private *priv = conn->priv;
  2006. if (priv->peer_key != NULL) {
  2007. return TRUE;
  2008. }
  2009. else if (priv->msg) {
  2010. return priv->msg->peer_key != NULL;
  2011. }
  2012. return FALSE;
  2013. }
  2014. GHashTable *
  2015. rspamd_http_message_parse_query (struct rspamd_http_message *msg)
  2016. {
  2017. GHashTable *res;
  2018. rspamd_fstring_t *key = NULL, *value = NULL;
  2019. rspamd_ftok_t *key_tok = NULL, *value_tok = NULL;
  2020. const gchar *p, *c, *end;
  2021. struct http_parser_url u;
  2022. enum {
  2023. parse_key,
  2024. parse_eqsign,
  2025. parse_value,
  2026. parse_ampersand
  2027. } state = parse_key;
  2028. res = g_hash_table_new_full (rspamd_ftok_icase_hash,
  2029. rspamd_ftok_icase_equal,
  2030. rspamd_fstring_mapped_ftok_free,
  2031. rspamd_fstring_mapped_ftok_free);
  2032. if (msg->url && msg->url->len > 0) {
  2033. http_parser_parse_url (msg->url->str, msg->url->len, TRUE, &u);
  2034. if (u.field_set & (1 << UF_QUERY)) {
  2035. p = msg->url->str + u.field_data[UF_QUERY].off;
  2036. c = p;
  2037. end = p + u.field_data[UF_QUERY].len;
  2038. while (p <= end) {
  2039. switch (state) {
  2040. case parse_key:
  2041. if ((p == end || *p == '&') && p > c) {
  2042. /* We have a single parameter without a value */
  2043. key = rspamd_fstring_new_init (c, p - c);
  2044. key_tok = rspamd_ftok_map (key);
  2045. key_tok->len = rspamd_url_decode (key->str, key->str,
  2046. key->len);
  2047. value = rspamd_fstring_new_init ("", 0);
  2048. value_tok = rspamd_ftok_map (value);
  2049. g_hash_table_replace (res, key_tok, value_tok);
  2050. state = parse_ampersand;
  2051. }
  2052. else if (*p == '=' && p > c) {
  2053. /* We have something like key=value */
  2054. key = rspamd_fstring_new_init (c, p - c);
  2055. key_tok = rspamd_ftok_map (key);
  2056. key_tok->len = rspamd_url_decode (key->str, key->str,
  2057. key->len);
  2058. state = parse_eqsign;
  2059. }
  2060. else {
  2061. p ++;
  2062. }
  2063. break;
  2064. case parse_eqsign:
  2065. if (*p != '=') {
  2066. c = p;
  2067. state = parse_value;
  2068. }
  2069. else {
  2070. p ++;
  2071. }
  2072. break;
  2073. case parse_value:
  2074. if ((p == end || *p == '&') && p >= c) {
  2075. g_assert (key != NULL);
  2076. if (p > c) {
  2077. value = rspamd_fstring_new_init (c, p - c);
  2078. value_tok = rspamd_ftok_map (value);
  2079. value_tok->len = rspamd_url_decode (value->str,
  2080. value->str,
  2081. value->len);
  2082. /* Detect quotes for value */
  2083. if (value_tok->begin[0] == '"') {
  2084. memmove (value->str, value->str + 1,
  2085. value_tok->len - 1);
  2086. value_tok->len --;
  2087. }
  2088. if (value_tok->begin[value_tok->len - 1] == '"') {
  2089. value_tok->len --;
  2090. }
  2091. }
  2092. else {
  2093. value = rspamd_fstring_new_init ("", 0);
  2094. value_tok = rspamd_ftok_map (value);
  2095. }
  2096. g_hash_table_replace (res, key_tok, value_tok);
  2097. key = value = NULL;
  2098. key_tok = value_tok = NULL;
  2099. state = parse_ampersand;
  2100. }
  2101. else {
  2102. p ++;
  2103. }
  2104. break;
  2105. case parse_ampersand:
  2106. if (p != end && *p != '&') {
  2107. c = p;
  2108. state = parse_key;
  2109. }
  2110. else {
  2111. p ++;
  2112. }
  2113. break;
  2114. }
  2115. }
  2116. }
  2117. if (state != parse_ampersand && key != NULL) {
  2118. rspamd_fstring_free (key);
  2119. }
  2120. }
  2121. return res;
  2122. }
  2123. struct rspamd_http_message *
  2124. rspamd_http_message_ref (struct rspamd_http_message *msg)
  2125. {
  2126. REF_RETAIN (msg);
  2127. return msg;
  2128. }
  2129. void
  2130. rspamd_http_message_unref (struct rspamd_http_message *msg)
  2131. {
  2132. REF_RELEASE (msg);
  2133. }
  2134. void
  2135. rspamd_http_connection_disable_encryption (struct rspamd_http_connection *conn)
  2136. {
  2137. struct rspamd_http_connection_private *priv;
  2138. priv = conn->priv;
  2139. if (priv) {
  2140. if (priv->local_key) {
  2141. rspamd_keypair_unref (priv->local_key);
  2142. }
  2143. if (priv->peer_key) {
  2144. rspamd_pubkey_unref (priv->peer_key);
  2145. }
  2146. priv->local_key = NULL;
  2147. priv->peer_key = NULL;
  2148. priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_ENCRYPTED;
  2149. }
  2150. }