~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/mail/ngx_mail_parse.c

Version: ~ [ nginx-0.6.26 ] ~ [ nginx-0.5.35 ] ~ [ nginx-0.5.20 ] ~ [ nginx-0.5.19 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.