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 64KB

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