| 272 | /* tok822_externalize - token tree to string, external form */ |
| 273 | |
| 274 | ACL_VSTRING *tok822_externalize(ACL_VSTRING *vp, TOK822 *tree, int flags) |
| 275 | { |
| 276 | ACL_VSTRING *tmp; |
| 277 | TOK822 *tp; |
| 278 | ssize_t start = 0; |
| 279 | TOK822 *addr = 0; |
| 280 | ssize_t addr_len = 0; |
| 281 | |
| 282 | /* |
| 283 | * Guard against a Sendmail buffer overflow (CERT advisory CA-2003-07). |
| 284 | * The problem was that Sendmail could store too much non-address text |
| 285 | * (comments, phrases, etc.) into a static 256-byte buffer. |
| 286 | * |
| 287 | * When the buffer fills up, fixed Sendmail versions remove comments etc. |
| 288 | * and reduce the information to just <$g>, which expands to <address>. |
| 289 | * No change is made when an address expression (text separated by |
| 290 | * commas) contains no address. This fix reportedly also protects |
| 291 | * Sendmail systems that are still vulnerable to this problem. |
| 292 | * |
| 293 | * Postfix takes the same approach, grudgingly. To avoid unnecessary damage, |
| 294 | * Postfix removes comments etc. only when the amount of non-address text |
| 295 | * in an address expression (text separated by commas) exceeds 250 bytes. |
| 296 | * |
| 297 | * With Sendmail, the address part of an address expression is the |
| 298 | * right-most <> instance in that expression. If an address expression |
| 299 | * contains no <>, then Postfix guarantees that it contains at most one |
| 300 | * non-comment string; that string is the address part of the address |
| 301 | * expression, so there is no ambiguity. |
| 302 | * |
| 303 | * Finally, we note that stress testing shows that other code in Sendmail |
| 304 | * 8.12.8 bluntly truncates ``text <address>'' to 256 bytes even when |
| 305 | * this means chopping the <address> somewhere in the middle. This is a |
| 306 | * loss of control that we're not entirely comfortable with. However, |
| 307 | * unbalanced quotes and dangling backslash do not seem to influence the |
| 308 | * way that Sendmail parses headers, so this is not an urgent problem. |
| 309 | */ |
| 310 | #define MAX_NONADDR_LENGTH 250 |
| 311 | |
| 312 | #define RESET_NONADDR_LENGTH { \ |
| 313 | start = (ssize_t) ACL_VSTRING_LEN(vp); \ |
| 314 | addr = 0; \ |
| 315 | addr_len = 0; \ |
| 316 | } |
| 317 | |
| 318 | #define ENFORCE_NONADDR_LENGTH do { \ |
| 319 | if (addr && (ssize_t) ACL_VSTRING_LEN(vp) - addr_len > start + MAX_NONADDR_LENGTH) \ |
| 320 | strip_address(vp, start, addr->head); \ |
| 321 | } while(0) |
| 322 | |
| 323 | if (flags & TOK822_STR_WIPE) |
| 324 | ACL_VSTRING_RESET(vp); |
| 325 | |
| 326 | if (flags & TOK822_STR_TRNC) |
| 327 | RESET_NONADDR_LENGTH; |
| 328 | |
| 329 | for (tp = tree; tp; tp = tp->next) { |
| 330 | switch (tp->type) { |
| 331 | case ',': |
no test coverage detected
searching dependent graphs…