PageRenderTime 82ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/proxy/ajp_msg.c

https://bitbucket.org/jonasteuwen/apache2nginx
C | 607 lines | 319 code | 104 blank | 184 comment | 47 complexity | ebcae0d1a9cc96e87c0476c2eb7b729b MD5 | raw file
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. 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 "ajp.h"
  17. static char *hex_table = "0123456789ABCDEF";
  18. /**
  19. * Dump up to the first 1024 bytes on an AJP Message
  20. *
  21. * @param pool pool to allocate from
  22. * @param msg AJP Message to dump
  23. * @param err error string to display
  24. * @return dump message
  25. */
  26. char * ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err)
  27. {
  28. apr_size_t i, j;
  29. char line[80];
  30. char *current;
  31. char *rv, *p;
  32. apr_size_t bl = 8192;
  33. apr_byte_t x;
  34. apr_size_t len = msg->len;
  35. /* Display only first 1024 bytes */
  36. if (len > 1024)
  37. len = 1024;
  38. rv = apr_palloc(pool, bl);
  39. apr_snprintf(rv, bl,
  40. "ajp_msg_dump(): %s pos=%" APR_SIZE_T_FMT
  41. " len=%" APR_SIZE_T_FMT " max=%" APR_SIZE_T_FMT "\n",
  42. err, msg->pos, msg->len, msg->max_size);
  43. bl -= strlen(rv);
  44. p = rv + strlen(rv);
  45. for (i = 0; i < len; i += 16) {
  46. current = line;
  47. for (j = 0; j < 16; j++) {
  48. x = msg->buf[i + j];
  49. *current++ = hex_table[x >> 4];
  50. *current++ = hex_table[x & 0x0f];
  51. *current++ = ' ';
  52. }
  53. *current++ = ' ';
  54. *current++ = '-';
  55. *current++ = ' ';
  56. for (j = 0; j < 16; j++) {
  57. x = msg->buf[i + j];
  58. if (x > 0x20 && x < 0x7F) {
  59. *current++ = x;
  60. }
  61. else {
  62. *current++ = '.';
  63. }
  64. }
  65. *current++ = '\0';
  66. apr_snprintf(p, bl,
  67. "ajp_msg_dump(): %.4lx %s\n",
  68. (unsigned long)i, line);
  69. bl -= strlen(rv);
  70. p = rv + strlen(rv);
  71. }
  72. return rv;
  73. }
  74. /**
  75. * Check a new AJP Message by looking at signature and return its size
  76. *
  77. * @param msg AJP Message to check
  78. * @param len Pointer to returned len
  79. * @return APR_SUCCESS or error
  80. */
  81. apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len)
  82. {
  83. apr_byte_t *head = msg->buf;
  84. apr_size_t msglen;
  85. if (!((head[0] == 0x41 && head[1] == 0x42) ||
  86. (head[0] == 0x12 && head[1] == 0x34))) {
  87. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  88. "ajp_check_msg_header() got bad signature %x%x",
  89. head[0], head[1]);
  90. return AJP_EBAD_SIGNATURE;
  91. }
  92. msglen = ((head[2] & 0xff) << 8);
  93. msglen += (head[3] & 0xFF);
  94. if (msglen > msg->max_size) {
  95. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  96. "ajp_check_msg_header() incoming message is "
  97. "too big %" APR_SIZE_T_FMT ", max is %" APR_SIZE_T_FMT,
  98. msglen, msg->max_size);
  99. return AJP_ETOBIG;
  100. }
  101. msg->len = msglen + AJP_HEADER_LEN;
  102. msg->pos = AJP_HEADER_LEN;
  103. *len = msglen;
  104. return APR_SUCCESS;
  105. }
  106. /**
  107. * Reset an AJP Message
  108. *
  109. * @param msg AJP Message to reset
  110. * @return APR_SUCCESS or error
  111. */
  112. apr_status_t ajp_msg_reset(ajp_msg_t *msg)
  113. {
  114. msg->len = AJP_HEADER_LEN;
  115. msg->pos = AJP_HEADER_LEN;
  116. return APR_SUCCESS;
  117. }
  118. /**
  119. * Reuse an AJP Message
  120. *
  121. * @param msg AJP Message to reuse
  122. * @return APR_SUCCESS or error
  123. */
  124. apr_status_t ajp_msg_reuse(ajp_msg_t *msg)
  125. {
  126. apr_byte_t *buf;
  127. apr_size_t max_size;
  128. buf = msg->buf;
  129. max_size = msg->max_size;
  130. memset(msg, 0, sizeof(ajp_msg_t));
  131. msg->buf = buf;
  132. msg->max_size = max_size;
  133. msg->header_len = AJP_HEADER_LEN;
  134. ajp_msg_reset(msg);
  135. return APR_SUCCESS;
  136. }
  137. /**
  138. * Mark the end of an AJP Message
  139. *
  140. * @param msg AJP Message to end
  141. * @return APR_SUCCESS or error
  142. */
  143. apr_status_t ajp_msg_end(ajp_msg_t *msg)
  144. {
  145. apr_size_t len = msg->len - AJP_HEADER_LEN;
  146. if (msg->server_side) {
  147. msg->buf[0] = 0x41;
  148. msg->buf[1] = 0x42;
  149. }
  150. else {
  151. msg->buf[0] = 0x12;
  152. msg->buf[1] = 0x34;
  153. }
  154. msg->buf[2] = (apr_byte_t)((len >> 8) & 0xFF);
  155. msg->buf[3] = (apr_byte_t)(len & 0xFF);
  156. return APR_SUCCESS;
  157. }
  158. static APR_INLINE int ajp_log_overflow(ajp_msg_t *msg, const char *context)
  159. {
  160. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  161. "%s(): BufferOverflowException %" APR_SIZE_T_FMT
  162. " %" APR_SIZE_T_FMT,
  163. context, msg->pos, msg->len);
  164. return AJP_EOVERFLOW;
  165. }
  166. /**
  167. * Add an unsigned 32bits value to AJP Message
  168. *
  169. * @param msg AJP Message to get value from
  170. * @param value value to add to AJP Message
  171. * @return APR_SUCCESS or error
  172. */
  173. apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value)
  174. {
  175. apr_size_t len = msg->len;
  176. if ((len + 4) > msg->max_size) {
  177. return ajp_log_overflow(msg, "ajp_msg_append_uint32");
  178. }
  179. msg->buf[len] = (apr_byte_t)((value >> 24) & 0xFF);
  180. msg->buf[len + 1] = (apr_byte_t)((value >> 16) & 0xFF);
  181. msg->buf[len + 2] = (apr_byte_t)((value >> 8) & 0xFF);
  182. msg->buf[len + 3] = (apr_byte_t)(value & 0xFF);
  183. msg->len += 4;
  184. return APR_SUCCESS;
  185. }
  186. /**
  187. * Add an unsigned 16bits value to AJP Message
  188. *
  189. * @param msg AJP Message to get value from
  190. * @param value value to add to AJP Message
  191. * @return APR_SUCCESS or error
  192. */
  193. apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value)
  194. {
  195. apr_size_t len = msg->len;
  196. if ((len + 2) > msg->max_size) {
  197. return ajp_log_overflow(msg, "ajp_msg_append_uint16");
  198. }
  199. msg->buf[len] = (apr_byte_t)((value >> 8) & 0xFF);
  200. msg->buf[len + 1] = (apr_byte_t)(value & 0xFF);
  201. msg->len += 2;
  202. return APR_SUCCESS;
  203. }
  204. /**
  205. * Add an unsigned 8bits value to AJP Message
  206. *
  207. * @param msg AJP Message to get value from
  208. * @param value value to add to AJP Message
  209. * @return APR_SUCCESS or error
  210. */
  211. apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value)
  212. {
  213. apr_size_t len = msg->len;
  214. if ((len + 1) > msg->max_size) {
  215. return ajp_log_overflow(msg, "ajp_msg_append_uint8");
  216. }
  217. msg->buf[len] = value;
  218. msg->len += 1;
  219. return APR_SUCCESS;
  220. }
  221. /**
  222. * Add a String in AJP message, and transform the String in ASCII
  223. * if convert is set and we're on an EBCDIC machine
  224. *
  225. * @param msg AJP Message to get value from
  226. * @param value Pointer to String
  227. * @param convert When set told to convert String to ASCII
  228. * @return APR_SUCCESS or error
  229. */
  230. apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value,
  231. int convert)
  232. {
  233. size_t len;
  234. if (value == NULL) {
  235. return(ajp_msg_append_uint16(msg, 0xFFFF));
  236. }
  237. len = strlen(value);
  238. if ((msg->len + len + 2) > msg->max_size) {
  239. return ajp_log_overflow(msg, "ajp_msg_append_cvt_string");
  240. }
  241. /* ignore error - we checked once */
  242. ajp_msg_append_uint16(msg, (apr_uint16_t)len);
  243. /* We checked for space !! */
  244. memcpy(msg->buf + msg->len, value, len + 1); /* including \0 */
  245. if (convert) /* convert from EBCDIC if needed */
  246. ajp_xlate_to_ascii((char *)msg->buf + msg->len, len + 1);
  247. msg->len += len + 1;
  248. return APR_SUCCESS;
  249. }
  250. /**
  251. * Add a Byte array to AJP Message
  252. *
  253. * @param msg AJP Message to get value from
  254. * @param value Pointer to Byte array
  255. * @param valuelen Byte array len
  256. * @return APR_SUCCESS or error
  257. */
  258. apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value,
  259. apr_size_t valuelen)
  260. {
  261. if (! valuelen) {
  262. return APR_SUCCESS; /* Shouldn't we indicate an error ? */
  263. }
  264. if ((msg->len + valuelen) > msg->max_size) {
  265. return ajp_log_overflow(msg, "ajp_msg_append_bytes");
  266. }
  267. /* We checked for space !! */
  268. memcpy(msg->buf + msg->len, value, valuelen);
  269. msg->len += valuelen;
  270. return APR_SUCCESS;
  271. }
  272. /**
  273. * Get a 32bits unsigned value from AJP Message
  274. *
  275. * @param msg AJP Message to get value from
  276. * @param rvalue Pointer where value will be returned
  277. * @return APR_SUCCESS or error
  278. */
  279. apr_status_t ajp_msg_get_uint32(ajp_msg_t *msg, apr_uint32_t *rvalue)
  280. {
  281. apr_uint32_t value;
  282. if ((msg->pos + 3) > msg->len) {
  283. return ajp_log_overflow(msg, "ajp_msg_get_uint32");
  284. }
  285. value = ((msg->buf[(msg->pos++)] & 0xFF) << 24);
  286. value |= ((msg->buf[(msg->pos++)] & 0xFF) << 16);
  287. value |= ((msg->buf[(msg->pos++)] & 0xFF) << 8);
  288. value |= ((msg->buf[(msg->pos++)] & 0xFF));
  289. *rvalue = value;
  290. return APR_SUCCESS;
  291. }
  292. /**
  293. * Get a 16bits unsigned value from AJP Message
  294. *
  295. * @param msg AJP Message to get value from
  296. * @param rvalue Pointer where value will be returned
  297. * @return APR_SUCCESS or error
  298. */
  299. apr_status_t ajp_msg_get_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue)
  300. {
  301. apr_uint16_t value;
  302. if ((msg->pos + 1) > msg->len) {
  303. return ajp_log_overflow(msg, "ajp_msg_get_uint16");
  304. }
  305. value = ((msg->buf[(msg->pos++)] & 0xFF) << 8);
  306. value += ((msg->buf[(msg->pos++)] & 0xFF));
  307. *rvalue = value;
  308. return APR_SUCCESS;
  309. }
  310. /**
  311. * Peek a 16bits unsigned value from AJP Message, position in message
  312. * is not updated
  313. *
  314. * @param msg AJP Message to get value from
  315. * @param rvalue Pointer where value will be returned
  316. * @return APR_SUCCESS or error
  317. */
  318. apr_status_t ajp_msg_peek_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue)
  319. {
  320. apr_uint16_t value;
  321. if ((msg->pos + 1) > msg->len) {
  322. return ajp_log_overflow(msg, "ajp_msg_peek_uint16");
  323. }
  324. value = ((msg->buf[(msg->pos)] & 0xFF) << 8);
  325. value += ((msg->buf[(msg->pos + 1)] & 0xFF));
  326. *rvalue = value;
  327. return APR_SUCCESS;
  328. }
  329. /**
  330. * Peek a 8bits unsigned value from AJP Message, position in message
  331. * is not updated
  332. *
  333. * @param msg AJP Message to get value from
  334. * @param rvalue Pointer where value will be returned
  335. * @return APR_SUCCESS or error
  336. */
  337. apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue)
  338. {
  339. if (msg->pos > msg->len) {
  340. return ajp_log_overflow(msg, "ajp_msg_peek_uint8");
  341. }
  342. *rvalue = msg->buf[msg->pos];
  343. return APR_SUCCESS;
  344. }
  345. /**
  346. * Get a 8bits unsigned value from AJP Message
  347. *
  348. * @param msg AJP Message to get value from
  349. * @param rvalue Pointer where value will be returned
  350. * @return APR_SUCCESS or error
  351. */
  352. apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue)
  353. {
  354. if (msg->pos > msg->len) {
  355. return ajp_log_overflow(msg, "ajp_msg_get_uint8");
  356. }
  357. *rvalue = msg->buf[msg->pos++];
  358. return APR_SUCCESS;
  359. }
  360. /**
  361. * Get a String value from AJP Message
  362. *
  363. * @param msg AJP Message to get value from
  364. * @param rvalue Pointer where value will be returned
  365. * @return APR_SUCCESS or error
  366. */
  367. apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue)
  368. {
  369. apr_uint16_t size;
  370. apr_size_t start;
  371. apr_status_t status;
  372. status = ajp_msg_get_uint16(msg, &size);
  373. start = msg->pos;
  374. if ((status != APR_SUCCESS) || (size + start > msg->max_size)) {
  375. return ajp_log_overflow(msg, "ajp_msg_get_string");
  376. }
  377. msg->pos += (apr_size_t)size;
  378. msg->pos++; /* a String in AJP is NULL terminated */
  379. *rvalue = (const char *)(msg->buf + start);
  380. return APR_SUCCESS;
  381. }
  382. /**
  383. * Get a Byte array from AJP Message
  384. *
  385. * @param msg AJP Message to get value from
  386. * @param rvalue Pointer where value will be returned
  387. * @param rvalueLen Pointer where Byte array len will be returned
  388. * @return APR_SUCCESS or error
  389. */
  390. apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue,
  391. apr_size_t *rvalue_len)
  392. {
  393. apr_uint16_t size;
  394. apr_size_t start;
  395. apr_status_t status;
  396. status = ajp_msg_get_uint16(msg, &size);
  397. /* save the current position */
  398. start = msg->pos;
  399. if ((status != APR_SUCCESS) || (size + start > msg->max_size)) {
  400. return ajp_log_overflow(msg, "ajp_msg_get_bytes");
  401. }
  402. msg->pos += (apr_size_t)size; /* only bytes, no trailer */
  403. *rvalue = msg->buf + start;
  404. *rvalue_len = size;
  405. return APR_SUCCESS;
  406. }
  407. /**
  408. * Create an AJP Message from pool
  409. *
  410. * @param pool memory pool to allocate AJP message from
  411. * @param size size of the buffer to create
  412. * @param rmsg Pointer to newly created AJP message
  413. * @return APR_SUCCESS or error
  414. */
  415. apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg)
  416. {
  417. ajp_msg_t *msg = (ajp_msg_t *)apr_pcalloc(pool, sizeof(ajp_msg_t));
  418. if (!msg) {
  419. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  420. "ajp_msg_create(): can't allocate AJP message memory");
  421. return APR_ENOPOOL;
  422. }
  423. msg->server_side = 0;
  424. msg->buf = (apr_byte_t *)apr_palloc(pool, size);
  425. /* XXX: This should never happen
  426. * In case if the OS cannont allocate 8K of data
  427. * we are in serious trouble
  428. * No need to check the alloc return value, cause the
  429. * core dump is probably the best solution anyhow.
  430. */
  431. if (msg->buf == NULL) {
  432. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  433. "ajp_msg_create(): can't allocate AJP message memory");
  434. return APR_ENOPOOL;
  435. }
  436. msg->len = 0;
  437. msg->header_len = AJP_HEADER_LEN;
  438. msg->max_size = size;
  439. *rmsg = msg;
  440. return APR_SUCCESS;
  441. }
  442. /**
  443. * Recopy an AJP Message to another
  444. *
  445. * @param smsg source AJP message
  446. * @param dmsg destination AJP message
  447. * @return APR_SUCCESS or error
  448. */
  449. apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg)
  450. {
  451. if (dmsg == NULL) {
  452. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  453. "ajp_msg_copy(): destination msg is null");
  454. return AJP_EINVAL;
  455. }
  456. if (smsg->len > smsg->max_size) {
  457. ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  458. "ajp_msg_copy(): destination buffer too "
  459. "small %" APR_SIZE_T_FMT ", max size is %" APR_SIZE_T_FMT,
  460. smsg->len, smsg->max_size);
  461. return AJP_ETOSMALL;
  462. }
  463. memcpy(dmsg->buf, smsg->buf, smsg->len);
  464. dmsg->len = smsg->len;
  465. dmsg->pos = smsg->pos;
  466. return APR_SUCCESS;
  467. }
  468. /**
  469. * Serialize in an AJP Message a PING command
  470. *
  471. * +-----------------------+
  472. * | PING CMD (1 byte) |
  473. * +-----------------------+
  474. *
  475. * @param smsg AJP message to put serialized message
  476. * @return APR_SUCCESS or error
  477. */
  478. apr_status_t ajp_msg_serialize_ping(ajp_msg_t *msg)
  479. {
  480. apr_status_t rc;
  481. ajp_msg_reset(msg);
  482. if ((rc = ajp_msg_append_uint8(msg, CMD_AJP13_PING)) != APR_SUCCESS)
  483. return rc;
  484. return APR_SUCCESS;
  485. }
  486. /**
  487. * Serialize in an AJP Message a CPING command
  488. *
  489. * +-----------------------+
  490. * | CPING CMD (1 byte) |
  491. * +-----------------------+
  492. *
  493. * @param smsg AJP message to put serialized message
  494. * @return APR_SUCCESS or error
  495. */
  496. apr_status_t ajp_msg_serialize_cping(ajp_msg_t *msg)
  497. {
  498. apr_status_t rc;
  499. ajp_msg_reset(msg);
  500. if ((rc = ajp_msg_append_uint8(msg, CMD_AJP13_CPING)) != APR_SUCCESS)
  501. return rc;
  502. return APR_SUCCESS;
  503. }