Annotation of embedaddon/nginx/src/mail/ngx_mail_parse.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (C) Igor Sysoev
! 4: * Copyright (C) Nginx, Inc.
! 5: */
! 6:
! 7:
! 8: #include <ngx_config.h>
! 9: #include <ngx_core.h>
! 10: #include <ngx_event.h>
! 11: #include <ngx_mail.h>
! 12: #include <ngx_mail_pop3_module.h>
! 13: #include <ngx_mail_imap_module.h>
! 14: #include <ngx_mail_smtp_module.h>
! 15:
! 16:
! 17: ngx_int_t
! 18: ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
! 19: {
! 20: u_char ch, *p, *c, c0, c1, c2, c3;
! 21: ngx_str_t *arg;
! 22: enum {
! 23: sw_start = 0,
! 24: sw_spaces_before_argument,
! 25: sw_argument,
! 26: sw_almost_done
! 27: } state;
! 28:
! 29: state = s->state;
! 30:
! 31: for (p = s->buffer->pos; p < s->buffer->last; p++) {
! 32: ch = *p;
! 33:
! 34: switch (state) {
! 35:
! 36: /* POP3 command */
! 37: case sw_start:
! 38: if (ch == ' ' || ch == CR || ch == LF) {
! 39: c = s->buffer->start;
! 40:
! 41: if (p - c == 4) {
! 42:
! 43: c0 = ngx_toupper(c[0]);
! 44: c1 = ngx_toupper(c[1]);
! 45: c2 = ngx_toupper(c[2]);
! 46: c3 = ngx_toupper(c[3]);
! 47:
! 48: if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R')
! 49: {
! 50: s->command = NGX_POP3_USER;
! 51:
! 52: } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S')
! 53: {
! 54: s->command = NGX_POP3_PASS;
! 55:
! 56: } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P')
! 57: {
! 58: s->command = NGX_POP3_APOP;
! 59:
! 60: } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
! 61: {
! 62: s->command = NGX_POP3_QUIT;
! 63:
! 64: } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A')
! 65: {
! 66: s->command = NGX_POP3_CAPA;
! 67:
! 68: } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
! 69: {
! 70: s->command = NGX_POP3_AUTH;
! 71:
! 72: } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
! 73: {
! 74: s->command = NGX_POP3_NOOP;
! 75: #if (NGX_MAIL_SSL)
! 76: } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S')
! 77: {
! 78: s->command = NGX_POP3_STLS;
! 79: #endif
! 80: } else {
! 81: goto invalid;
! 82: }
! 83:
! 84: } else {
! 85: goto invalid;
! 86: }
! 87:
! 88: switch (ch) {
! 89: case ' ':
! 90: state = sw_spaces_before_argument;
! 91: break;
! 92: case CR:
! 93: state = sw_almost_done;
! 94: break;
! 95: case LF:
! 96: goto done;
! 97: }
! 98: break;
! 99: }
! 100:
! 101: if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
! 102: goto invalid;
! 103: }
! 104:
! 105: break;
! 106:
! 107: case sw_spaces_before_argument:
! 108: switch (ch) {
! 109: case ' ':
! 110: break;
! 111: case CR:
! 112: state = sw_almost_done;
! 113: s->arg_end = p;
! 114: break;
! 115: case LF:
! 116: s->arg_end = p;
! 117: goto done;
! 118: default:
! 119: if (s->args.nelts <= 2) {
! 120: state = sw_argument;
! 121: s->arg_start = p;
! 122: break;
! 123: }
! 124: goto invalid;
! 125: }
! 126: break;
! 127:
! 128: case sw_argument:
! 129: switch (ch) {
! 130:
! 131: case ' ':
! 132:
! 133: /*
! 134: * the space should be considered as part of the at username
! 135: * or password, but not of argument in other commands
! 136: */
! 137:
! 138: if (s->command == NGX_POP3_USER
! 139: || s->command == NGX_POP3_PASS)
! 140: {
! 141: break;
! 142: }
! 143:
! 144: /* fall through */
! 145:
! 146: case CR:
! 147: case LF:
! 148: arg = ngx_array_push(&s->args);
! 149: if (arg == NULL) {
! 150: return NGX_ERROR;
! 151: }
! 152: arg->len = p - s->arg_start;
! 153: arg->data = s->arg_start;
! 154: s->arg_start = NULL;
! 155:
! 156: switch (ch) {
! 157: case ' ':
! 158: state = sw_spaces_before_argument;
! 159: break;
! 160: case CR:
! 161: state = sw_almost_done;
! 162: break;
! 163: case LF:
! 164: goto done;
! 165: }
! 166: break;
! 167:
! 168: default:
! 169: break;
! 170: }
! 171: break;
! 172:
! 173: case sw_almost_done:
! 174: switch (ch) {
! 175: case LF:
! 176: goto done;
! 177: default:
! 178: goto invalid;
! 179: }
! 180: }
! 181: }
! 182:
! 183: s->buffer->pos = p;
! 184: s->state = state;
! 185:
! 186: return NGX_AGAIN;
! 187:
! 188: done:
! 189:
! 190: s->buffer->pos = p + 1;
! 191:
! 192: if (s->arg_start) {
! 193: arg = ngx_array_push(&s->args);
! 194: if (arg == NULL) {
! 195: return NGX_ERROR;
! 196: }
! 197: arg->len = s->arg_end - s->arg_start;
! 198: arg->data = s->arg_start;
! 199: s->arg_start = NULL;
! 200: }
! 201:
! 202: s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument;
! 203:
! 204: return NGX_OK;
! 205:
! 206: invalid:
! 207:
! 208: s->state = sw_start;
! 209: s->arg_start = NULL;
! 210:
! 211: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 212: }
! 213:
! 214:
! 215: ngx_int_t
! 216: ngx_mail_imap_parse_command(ngx_mail_session_t *s)
! 217: {
! 218: u_char ch, *p, *c;
! 219: ngx_str_t *arg;
! 220: enum {
! 221: sw_start = 0,
! 222: sw_spaces_before_command,
! 223: sw_command,
! 224: sw_spaces_before_argument,
! 225: sw_argument,
! 226: sw_backslash,
! 227: sw_literal,
! 228: sw_no_sync_literal_argument,
! 229: sw_start_literal_argument,
! 230: sw_literal_argument,
! 231: sw_end_literal_argument,
! 232: sw_almost_done
! 233: } state;
! 234:
! 235: state = s->state;
! 236:
! 237: for (p = s->buffer->pos; p < s->buffer->last; p++) {
! 238: ch = *p;
! 239:
! 240: switch (state) {
! 241:
! 242: /* IMAP tag */
! 243: case sw_start:
! 244: switch (ch) {
! 245: case ' ':
! 246: s->tag.len = p - s->buffer->start + 1;
! 247: s->tag.data = s->buffer->start;
! 248: state = sw_spaces_before_command;
! 249: break;
! 250: case CR:
! 251: s->state = sw_start;
! 252: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 253: case LF:
! 254: s->state = sw_start;
! 255: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 256: }
! 257: break;
! 258:
! 259: case sw_spaces_before_command:
! 260: switch (ch) {
! 261: case ' ':
! 262: break;
! 263: case CR:
! 264: s->state = sw_start;
! 265: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 266: case LF:
! 267: s->state = sw_start;
! 268: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 269: default:
! 270: s->cmd_start = p;
! 271: state = sw_command;
! 272: break;
! 273: }
! 274: break;
! 275:
! 276: case sw_command:
! 277: if (ch == ' ' || ch == CR || ch == LF) {
! 278:
! 279: c = s->cmd_start;
! 280:
! 281: switch (p - c) {
! 282:
! 283: case 4:
! 284: if ((c[0] == 'N' || c[0] == 'n')
! 285: && (c[1] == 'O'|| c[1] == 'o')
! 286: && (c[2] == 'O'|| c[2] == 'o')
! 287: && (c[3] == 'P'|| c[3] == 'p'))
! 288: {
! 289: s->command = NGX_IMAP_NOOP;
! 290:
! 291: } else {
! 292: goto invalid;
! 293: }
! 294: break;
! 295:
! 296: case 5:
! 297: if ((c[0] == 'L'|| c[0] == 'l')
! 298: && (c[1] == 'O'|| c[1] == 'o')
! 299: && (c[2] == 'G'|| c[2] == 'g')
! 300: && (c[3] == 'I'|| c[3] == 'i')
! 301: && (c[4] == 'N'|| c[4] == 'n'))
! 302: {
! 303: s->command = NGX_IMAP_LOGIN;
! 304:
! 305: } else {
! 306: goto invalid;
! 307: }
! 308: break;
! 309:
! 310: case 6:
! 311: if ((c[0] == 'L'|| c[0] == 'l')
! 312: && (c[1] == 'O'|| c[1] == 'o')
! 313: && (c[2] == 'G'|| c[2] == 'g')
! 314: && (c[3] == 'O'|| c[3] == 'o')
! 315: && (c[4] == 'U'|| c[4] == 'u')
! 316: && (c[5] == 'T'|| c[5] == 't'))
! 317: {
! 318: s->command = NGX_IMAP_LOGOUT;
! 319:
! 320: } else {
! 321: goto invalid;
! 322: }
! 323: break;
! 324:
! 325: #if (NGX_MAIL_SSL)
! 326: case 8:
! 327: if ((c[0] == 'S'|| c[0] == 's')
! 328: && (c[1] == 'T'|| c[1] == 't')
! 329: && (c[2] == 'A'|| c[2] == 'a')
! 330: && (c[3] == 'R'|| c[3] == 'r')
! 331: && (c[4] == 'T'|| c[4] == 't')
! 332: && (c[5] == 'T'|| c[5] == 't')
! 333: && (c[6] == 'L'|| c[6] == 'l')
! 334: && (c[7] == 'S'|| c[7] == 's'))
! 335: {
! 336: s->command = NGX_IMAP_STARTTLS;
! 337:
! 338: } else {
! 339: goto invalid;
! 340: }
! 341: break;
! 342: #endif
! 343:
! 344: case 10:
! 345: if ((c[0] == 'C'|| c[0] == 'c')
! 346: && (c[1] == 'A'|| c[1] == 'a')
! 347: && (c[2] == 'P'|| c[2] == 'p')
! 348: && (c[3] == 'A'|| c[3] == 'a')
! 349: && (c[4] == 'B'|| c[4] == 'b')
! 350: && (c[5] == 'I'|| c[5] == 'i')
! 351: && (c[6] == 'L'|| c[6] == 'l')
! 352: && (c[7] == 'I'|| c[7] == 'i')
! 353: && (c[8] == 'T'|| c[8] == 't')
! 354: && (c[9] == 'Y'|| c[9] == 'y'))
! 355: {
! 356: s->command = NGX_IMAP_CAPABILITY;
! 357:
! 358: } else {
! 359: goto invalid;
! 360: }
! 361: break;
! 362:
! 363: case 12:
! 364: if ((c[0] == 'A'|| c[0] == 'a')
! 365: && (c[1] == 'U'|| c[1] == 'u')
! 366: && (c[2] == 'T'|| c[2] == 't')
! 367: && (c[3] == 'H'|| c[3] == 'h')
! 368: && (c[4] == 'E'|| c[4] == 'e')
! 369: && (c[5] == 'N'|| c[5] == 'n')
! 370: && (c[6] == 'T'|| c[6] == 't')
! 371: && (c[7] == 'I'|| c[7] == 'i')
! 372: && (c[8] == 'C'|| c[8] == 'c')
! 373: && (c[9] == 'A'|| c[9] == 'a')
! 374: && (c[10] == 'T'|| c[10] == 't')
! 375: && (c[11] == 'E'|| c[11] == 'e'))
! 376: {
! 377: s->command = NGX_IMAP_AUTHENTICATE;
! 378:
! 379: } else {
! 380: goto invalid;
! 381: }
! 382: break;
! 383:
! 384: default:
! 385: goto invalid;
! 386: }
! 387:
! 388: switch (ch) {
! 389: case ' ':
! 390: state = sw_spaces_before_argument;
! 391: break;
! 392: case CR:
! 393: state = sw_almost_done;
! 394: break;
! 395: case LF:
! 396: goto done;
! 397: }
! 398: break;
! 399: }
! 400:
! 401: if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
! 402: goto invalid;
! 403: }
! 404:
! 405: break;
! 406:
! 407: case sw_spaces_before_argument:
! 408: switch (ch) {
! 409: case ' ':
! 410: break;
! 411: case CR:
! 412: state = sw_almost_done;
! 413: s->arg_end = p;
! 414: break;
! 415: case LF:
! 416: s->arg_end = p;
! 417: goto done;
! 418: case '"':
! 419: if (s->args.nelts <= 2) {
! 420: s->quoted = 1;
! 421: s->arg_start = p + 1;
! 422: state = sw_argument;
! 423: break;
! 424: }
! 425: goto invalid;
! 426: case '{':
! 427: if (s->args.nelts <= 2) {
! 428: state = sw_literal;
! 429: break;
! 430: }
! 431: goto invalid;
! 432: default:
! 433: if (s->args.nelts <= 2) {
! 434: s->arg_start = p;
! 435: state = sw_argument;
! 436: break;
! 437: }
! 438: goto invalid;
! 439: }
! 440: break;
! 441:
! 442: case sw_argument:
! 443: if (ch == ' ' && s->quoted) {
! 444: break;
! 445: }
! 446:
! 447: switch (ch) {
! 448: case '"':
! 449: if (!s->quoted) {
! 450: break;
! 451: }
! 452: s->quoted = 0;
! 453: /* fall through */
! 454: case ' ':
! 455: case CR:
! 456: case LF:
! 457: arg = ngx_array_push(&s->args);
! 458: if (arg == NULL) {
! 459: return NGX_ERROR;
! 460: }
! 461: arg->len = p - s->arg_start;
! 462: arg->data = s->arg_start;
! 463: s->arg_start = NULL;
! 464:
! 465: switch (ch) {
! 466: case '"':
! 467: case ' ':
! 468: state = sw_spaces_before_argument;
! 469: break;
! 470: case CR:
! 471: state = sw_almost_done;
! 472: break;
! 473: case LF:
! 474: goto done;
! 475: }
! 476: break;
! 477: case '\\':
! 478: if (s->quoted) {
! 479: s->backslash = 1;
! 480: state = sw_backslash;
! 481: }
! 482: break;
! 483: }
! 484: break;
! 485:
! 486: case sw_backslash:
! 487: switch (ch) {
! 488: case CR:
! 489: case LF:
! 490: goto invalid;
! 491: default:
! 492: state = sw_argument;
! 493: }
! 494: break;
! 495:
! 496: case sw_literal:
! 497: if (ch >= '0' && ch <= '9') {
! 498: s->literal_len = s->literal_len * 10 + (ch - '0');
! 499: break;
! 500: }
! 501: if (ch == '}') {
! 502: state = sw_start_literal_argument;
! 503: break;
! 504: }
! 505: if (ch == '+') {
! 506: state = sw_no_sync_literal_argument;
! 507: break;
! 508: }
! 509: goto invalid;
! 510:
! 511: case sw_no_sync_literal_argument:
! 512: if (ch == '}') {
! 513: s->no_sync_literal = 1;
! 514: state = sw_start_literal_argument;
! 515: break;
! 516: }
! 517: goto invalid;
! 518:
! 519: case sw_start_literal_argument:
! 520: switch (ch) {
! 521: case CR:
! 522: break;
! 523: case LF:
! 524: s->buffer->pos = p + 1;
! 525: s->arg_start = p + 1;
! 526: if (s->no_sync_literal == 0) {
! 527: s->state = sw_literal_argument;
! 528: return NGX_IMAP_NEXT;
! 529: }
! 530: state = sw_literal_argument;
! 531: s->no_sync_literal = 0;
! 532: break;
! 533: default:
! 534: goto invalid;
! 535: }
! 536: break;
! 537:
! 538: case sw_literal_argument:
! 539: if (s->literal_len && --s->literal_len) {
! 540: break;
! 541: }
! 542:
! 543: arg = ngx_array_push(&s->args);
! 544: if (arg == NULL) {
! 545: return NGX_ERROR;
! 546: }
! 547: arg->len = p + 1 - s->arg_start;
! 548: arg->data = s->arg_start;
! 549: s->arg_start = NULL;
! 550: state = sw_end_literal_argument;
! 551:
! 552: break;
! 553:
! 554: case sw_end_literal_argument:
! 555: switch (ch) {
! 556: case '{':
! 557: if (s->args.nelts <= 2) {
! 558: state = sw_literal;
! 559: break;
! 560: }
! 561: goto invalid;
! 562: case CR:
! 563: state = sw_almost_done;
! 564: break;
! 565: case LF:
! 566: goto done;
! 567: default:
! 568: state = sw_spaces_before_argument;
! 569: break;
! 570: }
! 571: break;
! 572:
! 573: case sw_almost_done:
! 574: switch (ch) {
! 575: case LF:
! 576: goto done;
! 577: default:
! 578: goto invalid;
! 579: }
! 580: }
! 581: }
! 582:
! 583: s->buffer->pos = p;
! 584: s->state = state;
! 585:
! 586: return NGX_AGAIN;
! 587:
! 588: done:
! 589:
! 590: s->buffer->pos = p + 1;
! 591:
! 592: if (s->arg_start) {
! 593: arg = ngx_array_push(&s->args);
! 594: if (arg == NULL) {
! 595: return NGX_ERROR;
! 596: }
! 597: arg->len = s->arg_end - s->arg_start;
! 598: arg->data = s->arg_start;
! 599:
! 600: s->arg_start = NULL;
! 601: s->cmd_start = NULL;
! 602: s->quoted = 0;
! 603: s->no_sync_literal = 0;
! 604: s->literal_len = 0;
! 605: }
! 606:
! 607: s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument;
! 608:
! 609: return NGX_OK;
! 610:
! 611: invalid:
! 612:
! 613: s->state = sw_start;
! 614: s->quoted = 0;
! 615: s->no_sync_literal = 0;
! 616: s->literal_len = 0;
! 617:
! 618: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 619: }
! 620:
! 621:
! 622: ngx_int_t
! 623: ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
! 624: {
! 625: u_char ch, *p, *c, c0, c1, c2, c3;
! 626: ngx_str_t *arg;
! 627: enum {
! 628: sw_start = 0,
! 629: sw_spaces_before_argument,
! 630: sw_argument,
! 631: sw_almost_done
! 632: } state;
! 633:
! 634: state = s->state;
! 635:
! 636: for (p = s->buffer->pos; p < s->buffer->last; p++) {
! 637: ch = *p;
! 638:
! 639: switch (state) {
! 640:
! 641: /* SMTP command */
! 642: case sw_start:
! 643: if (ch == ' ' || ch == CR || ch == LF) {
! 644: c = s->buffer->start;
! 645:
! 646: if (p - c == 4) {
! 647:
! 648: c0 = ngx_toupper(c[0]);
! 649: c1 = ngx_toupper(c[1]);
! 650: c2 = ngx_toupper(c[2]);
! 651: c3 = ngx_toupper(c[3]);
! 652:
! 653: if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O')
! 654: {
! 655: s->command = NGX_SMTP_HELO;
! 656:
! 657: } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O')
! 658: {
! 659: s->command = NGX_SMTP_EHLO;
! 660:
! 661: } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
! 662: {
! 663: s->command = NGX_SMTP_QUIT;
! 664:
! 665: } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
! 666: {
! 667: s->command = NGX_SMTP_AUTH;
! 668:
! 669: } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
! 670: {
! 671: s->command = NGX_SMTP_NOOP;
! 672:
! 673: } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L')
! 674: {
! 675: s->command = NGX_SMTP_MAIL;
! 676:
! 677: } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T')
! 678: {
! 679: s->command = NGX_SMTP_RSET;
! 680:
! 681: } else if (c0 == 'R' && c1 == 'C' && c2 == 'P' && c3 == 'T')
! 682: {
! 683: s->command = NGX_SMTP_RCPT;
! 684:
! 685: } else if (c0 == 'V' && c1 == 'R' && c2 == 'F' && c3 == 'Y')
! 686: {
! 687: s->command = NGX_SMTP_VRFY;
! 688:
! 689: } else if (c0 == 'E' && c1 == 'X' && c2 == 'P' && c3 == 'N')
! 690: {
! 691: s->command = NGX_SMTP_EXPN;
! 692:
! 693: } else if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'P')
! 694: {
! 695: s->command = NGX_SMTP_HELP;
! 696:
! 697: } else {
! 698: goto invalid;
! 699: }
! 700: #if (NGX_MAIL_SSL)
! 701: } else if (p - c == 8) {
! 702:
! 703: if ((c[0] == 'S'|| c[0] == 's')
! 704: && (c[1] == 'T'|| c[1] == 't')
! 705: && (c[2] == 'A'|| c[2] == 'a')
! 706: && (c[3] == 'R'|| c[3] == 'r')
! 707: && (c[4] == 'T'|| c[4] == 't')
! 708: && (c[5] == 'T'|| c[5] == 't')
! 709: && (c[6] == 'L'|| c[6] == 'l')
! 710: && (c[7] == 'S'|| c[7] == 's'))
! 711: {
! 712: s->command = NGX_SMTP_STARTTLS;
! 713:
! 714: } else {
! 715: goto invalid;
! 716: }
! 717: #endif
! 718: } else {
! 719: goto invalid;
! 720: }
! 721:
! 722: switch (ch) {
! 723: case ' ':
! 724: state = sw_spaces_before_argument;
! 725: break;
! 726: case CR:
! 727: state = sw_almost_done;
! 728: break;
! 729: case LF:
! 730: goto done;
! 731: }
! 732: break;
! 733: }
! 734:
! 735: if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
! 736: goto invalid;
! 737: }
! 738:
! 739: break;
! 740:
! 741: case sw_spaces_before_argument:
! 742: switch (ch) {
! 743: case ' ':
! 744: break;
! 745: case CR:
! 746: state = sw_almost_done;
! 747: s->arg_end = p;
! 748: break;
! 749: case LF:
! 750: s->arg_end = p;
! 751: goto done;
! 752: default:
! 753: if (s->args.nelts <= 10) {
! 754: state = sw_argument;
! 755: s->arg_start = p;
! 756: break;
! 757: }
! 758: goto invalid;
! 759: }
! 760: break;
! 761:
! 762: case sw_argument:
! 763: switch (ch) {
! 764: case ' ':
! 765: case CR:
! 766: case LF:
! 767: arg = ngx_array_push(&s->args);
! 768: if (arg == NULL) {
! 769: return NGX_ERROR;
! 770: }
! 771: arg->len = p - s->arg_start;
! 772: arg->data = s->arg_start;
! 773: s->arg_start = NULL;
! 774:
! 775: switch (ch) {
! 776: case ' ':
! 777: state = sw_spaces_before_argument;
! 778: break;
! 779: case CR:
! 780: state = sw_almost_done;
! 781: break;
! 782: case LF:
! 783: goto done;
! 784: }
! 785: break;
! 786:
! 787: default:
! 788: break;
! 789: }
! 790: break;
! 791:
! 792: case sw_almost_done:
! 793: switch (ch) {
! 794: case LF:
! 795: goto done;
! 796: default:
! 797: goto invalid;
! 798: }
! 799: }
! 800: }
! 801:
! 802: s->buffer->pos = p;
! 803: s->state = state;
! 804:
! 805: return NGX_AGAIN;
! 806:
! 807: done:
! 808:
! 809: s->buffer->pos = p + 1;
! 810:
! 811: if (s->arg_start) {
! 812: arg = ngx_array_push(&s->args);
! 813: if (arg == NULL) {
! 814: return NGX_ERROR;
! 815: }
! 816: arg->len = s->arg_end - s->arg_start;
! 817: arg->data = s->arg_start;
! 818: s->arg_start = NULL;
! 819: }
! 820:
! 821: s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument;
! 822:
! 823: return NGX_OK;
! 824:
! 825: invalid:
! 826:
! 827: s->state = sw_start;
! 828: s->arg_start = NULL;
! 829:
! 830: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 831: }
! 832:
! 833:
! 834: ngx_int_t
! 835: ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c)
! 836: {
! 837: ngx_str_t *arg;
! 838:
! 839: #if (NGX_MAIL_SSL)
! 840: if (ngx_mail_starttls_only(s, c)) {
! 841: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 842: }
! 843: #endif
! 844:
! 845: arg = s->args.elts;
! 846:
! 847: if (arg[0].len == 5) {
! 848:
! 849: if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
! 850:
! 851: if (s->args.nelts == 1) {
! 852: return NGX_MAIL_AUTH_LOGIN;
! 853: }
! 854:
! 855: if (s->args.nelts == 2) {
! 856: return NGX_MAIL_AUTH_LOGIN_USERNAME;
! 857: }
! 858:
! 859: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 860: }
! 861:
! 862: if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
! 863:
! 864: if (s->args.nelts == 1) {
! 865: return NGX_MAIL_AUTH_PLAIN;
! 866: }
! 867:
! 868: if (s->args.nelts == 2) {
! 869: return ngx_mail_auth_plain(s, c, 1);
! 870: }
! 871: }
! 872:
! 873: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 874: }
! 875:
! 876: if (arg[0].len == 8) {
! 877:
! 878: if (s->args.nelts != 1) {
! 879: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 880: }
! 881:
! 882: if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) {
! 883: return NGX_MAIL_AUTH_CRAM_MD5;
! 884: }
! 885: }
! 886:
! 887: return NGX_MAIL_PARSE_INVALID_COMMAND;
! 888: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>