Mercurial > hg > nginx
comparison src/imap/ngx_imap_handler.c @ 809:da9c1521319d
AUTH PLAIN LOGIN CRAM-MD5
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 24 Oct 2006 18:38:31 +0000 |
parents | 887d8dec72dc |
children | e3aa8f305d21 |
comparison
equal
deleted
inserted
replaced
808:eef6d9cc45da | 809:da9c1521319d |
---|---|
30 ngx_string("-ERR internal server error" CRLF), | 30 ngx_string("-ERR internal server error" CRLF), |
31 ngx_string("* BAD internal server error" CRLF), | 31 ngx_string("* BAD internal server error" CRLF), |
32 }; | 32 }; |
33 | 33 |
34 static u_char pop3_ok[] = "+OK" CRLF; | 34 static u_char pop3_ok[] = "+OK" CRLF; |
35 static u_char pop3_next[] = "+ " CRLF; | |
36 static u_char pop3_username[] = "+ VXNlcm5hbWU6" CRLF; | |
37 static u_char pop3_password[] = "+ UGFzc3dvcmQ6" CRLF; | |
35 static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF; | 38 static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF; |
36 | 39 |
37 static u_char imap_star[] = "* "; | 40 static u_char imap_star[] = "* "; |
38 static u_char imap_ok[] = "OK completed" CRLF; | 41 static u_char imap_ok[] = "OK completed" CRLF; |
39 static u_char imap_next[] = "+ OK" CRLF; | 42 static u_char imap_next[] = "+ OK" CRLF; |
545 s->login_attempt++; | 548 s->login_attempt++; |
546 | 549 |
547 ngx_imap_auth_http_init(s); | 550 ngx_imap_auth_http_init(s); |
548 | 551 |
549 return; | 552 return; |
550 | 553 } |
551 } else { | 554 |
552 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | 555 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
553 } | |
554 | |
555 break; | 556 break; |
556 | 557 |
557 case NGX_IMAP_CAPABILITY: | 558 case NGX_IMAP_CAPABILITY: |
558 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | 559 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
559 | 560 |
664 | 665 |
665 | 666 |
666 void | 667 void |
667 ngx_pop3_auth_state(ngx_event_t *rev) | 668 ngx_pop3_auth_state(ngx_event_t *rev) |
668 { | 669 { |
669 u_char *text; | 670 u_char *text, *p, *last; |
670 ssize_t size; | 671 ssize_t size; |
671 ngx_int_t rc; | 672 ngx_int_t rc; |
672 ngx_str_t *arg; | 673 ngx_str_t *arg, salt, plain; |
673 ngx_connection_t *c; | 674 ngx_connection_t *c; |
674 ngx_imap_session_t *s; | 675 ngx_imap_session_t *s; |
675 ngx_imap_core_srv_conf_t *cscf; | 676 ngx_imap_core_srv_conf_t *cscf; |
676 #if (NGX_IMAP_SSL) | 677 #if (NGX_IMAP_SSL) |
677 ngx_imap_ssl_conf_t *sslcf; | 678 ngx_imap_ssl_conf_t *sslcf; |
728 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | 729 ngx_memcpy(s->login.data, arg[0].data, s->login.len); |
729 | 730 |
730 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | 731 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
731 "pop3 login: \"%V\"", &s->login); | 732 "pop3 login: \"%V\"", &s->login); |
732 | 733 |
733 } else { | 734 break; |
734 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | 735 } |
735 } | 736 |
736 | 737 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
737 break; | 738 break; |
738 | 739 |
739 case NGX_POP3_CAPA: | 740 case NGX_POP3_CAPA: |
740 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | 741 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
741 | 742 |
797 } | 798 } |
798 | 799 |
799 ngx_imap_auth_http_init(s); | 800 ngx_imap_auth_http_init(s); |
800 | 801 |
801 return; | 802 return; |
802 | 803 } |
803 } else { | 804 |
805 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
806 break; | |
807 | |
808 case NGX_POP3_AUTH: | |
809 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
810 | |
811 if (s->args.nelts == 0) { | |
812 size = cscf->pop3_auth_capability.len; | |
813 text = cscf->pop3_auth_capability.data; | |
814 break; | |
815 } | |
816 | |
817 if (s->args.nelts != 1) { | |
804 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | 818 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
805 } | 819 break; |
806 | 820 } |
821 | |
822 arg = s->args.elts; | |
823 | |
824 s->args.nelts = 0; | |
825 s->buffer->pos = s->buffer->start; | |
826 s->buffer->last = s->buffer->start; | |
827 s->arg_start = s->buffer->start; | |
828 | |
829 if (arg[0].len == 5) { | |
830 | |
831 if (ngx_strncasecmp(arg[0].data, "LOGIN", 5) == 0) { | |
832 s->imap_state = ngx_pop3_auth_login_username; | |
833 | |
834 size = sizeof(pop3_username) - 1; | |
835 text = pop3_username; | |
836 | |
837 break; | |
838 | |
839 } else if (ngx_strncasecmp(arg[0].data, "PLAIN", 5) == 0) { | |
840 s->imap_state = ngx_pop3_auth_plain; | |
841 | |
842 size = sizeof(pop3_next) - 1; | |
843 text = pop3_next; | |
844 | |
845 break; | |
846 } | |
847 | |
848 } else if (arg[0].len == 8 | |
849 && ngx_strncasecmp(arg[0].data, "CRAM-MD5", 8) == 0) | |
850 { | |
851 s->imap_state = ngx_pop3_auth_cram_md5; | |
852 | |
853 text = ngx_palloc(c->pool, | |
854 sizeof("+ " CRLF) - 1 | |
855 + ngx_base64_encoded_length(s->salt.len)); | |
856 if (text == NULL) { | |
857 ngx_imap_session_internal_server_error(s); | |
858 return; | |
859 } | |
860 | |
861 text[0] = '+'; text[1]= ' '; | |
862 salt.data = &text[2]; | |
863 s->salt.len -= 2; | |
864 | |
865 ngx_encode_base64(&salt, &s->salt); | |
866 | |
867 s->salt.len += 2; | |
868 size = 2 + salt.len; | |
869 text[size++] = CR; text[size++] = LF; | |
870 | |
871 break; | |
872 } | |
873 | |
874 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
807 break; | 875 break; |
808 | 876 |
809 case NGX_POP3_QUIT: | 877 case NGX_POP3_QUIT: |
810 s->quit = 1; | 878 s->quit = 1; |
811 break; | 879 break; |
867 } | 935 } |
868 | 936 |
869 ngx_imap_auth_http_init(s); | 937 ngx_imap_auth_http_init(s); |
870 | 938 |
871 return; | 939 return; |
872 | 940 } |
873 } else { | 941 |
874 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | 942 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
875 } | |
876 | |
877 break; | 943 break; |
878 | 944 |
879 case NGX_POP3_CAPA: | 945 case NGX_POP3_CAPA: |
880 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | 946 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
881 size = cscf->pop3_capability.len; | 947 size = cscf->pop3_capability.len; |
898 break; | 964 break; |
899 | 965 |
900 /* suppress warinings */ | 966 /* suppress warinings */ |
901 case ngx_pop3_passwd: | 967 case ngx_pop3_passwd: |
902 break; | 968 break; |
969 | |
970 case ngx_pop3_auth_login_username: | |
971 arg = s->args.elts; | |
972 s->imap_state = ngx_pop3_auth_login_password; | |
973 | |
974 s->args.nelts = 0; | |
975 s->buffer->pos = s->buffer->start; | |
976 s->buffer->last = s->buffer->start; | |
977 s->arg_start = s->buffer->start; | |
978 | |
979 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
980 "pop3 auth login username: \"%V\"", &arg[0]); | |
981 | |
982 s->login.data = ngx_palloc(c->pool, | |
983 ngx_base64_decoded_length(arg[0].len)); | |
984 if (s->login.data == NULL){ | |
985 ngx_imap_session_internal_server_error(s); | |
986 return; | |
987 } | |
988 | |
989 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
990 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
991 "client sent invalid base64 encoding " | |
992 "in AUTH LOGIN command"); | |
993 ngx_imap_session_internal_server_error(s); | |
994 return; | |
995 } | |
996 | |
997 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
998 "pop3 auth login username: \"%V\"", &s->login); | |
999 | |
1000 size = sizeof(pop3_password) - 1; | |
1001 text = pop3_password; | |
1002 | |
1003 break; | |
1004 | |
1005 case ngx_pop3_auth_login_password: | |
1006 arg = s->args.elts; | |
1007 | |
1008 #if (NGX_DEBUG_IMAP_PASSWD) | |
1009 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
1010 "pop3 auth login password: \"%V\"", &arg[0]); | |
1011 #endif | |
1012 | |
1013 s->passwd.data = ngx_palloc(c->pool, | |
1014 ngx_base64_decoded_length(arg[0].len)); | |
1015 if (s->passwd.data == NULL){ | |
1016 ngx_imap_session_internal_server_error(s); | |
1017 return; | |
1018 } | |
1019 | |
1020 if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) { | |
1021 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1022 "client sent invalid base64 encoding " | |
1023 "in AUTH LOGIN command"); | |
1024 ngx_imap_session_internal_server_error(s); | |
1025 return; | |
1026 } | |
1027 | |
1028 #if (NGX_DEBUG_IMAP_PASSWD) | |
1029 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
1030 "pop3 auth login password: \"%V\"", &s->passwd); | |
1031 #endif | |
1032 | |
1033 s->args.nelts = 0; | |
1034 s->buffer->pos = s->buffer->start; | |
1035 s->buffer->last = s->buffer->start; | |
1036 | |
1037 if (rev->timer_set) { | |
1038 ngx_del_timer(rev); | |
1039 } | |
1040 | |
1041 ngx_imap_auth_http_init(s); | |
1042 | |
1043 return; | |
1044 | |
1045 case ngx_pop3_auth_plain: | |
1046 arg = s->args.elts; | |
1047 | |
1048 #if (NGX_DEBUG_IMAP_PASSWD) | |
1049 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
1050 "pop3 auth plain: \"%V\"", &arg[0]); | |
1051 #endif | |
1052 | |
1053 plain.data = ngx_palloc(c->pool, | |
1054 ngx_base64_decoded_length(arg[0].len)); | |
1055 if (plain.data == NULL){ | |
1056 ngx_imap_session_internal_server_error(s); | |
1057 return; | |
1058 } | |
1059 | |
1060 if (ngx_decode_base64(&plain, &arg[0]) != NGX_OK) { | |
1061 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1062 "client sent invalid base64 encoding " | |
1063 "in AUTH PLAIN command"); | |
1064 ngx_imap_session_internal_server_error(s); | |
1065 return; | |
1066 } | |
1067 | |
1068 p = plain.data; | |
1069 last = p + plain.len; | |
1070 | |
1071 while (p < last && *p++) { /* void */ } | |
1072 | |
1073 s->login.data = p; | |
1074 | |
1075 while (p < last && *p) { p++; } | |
1076 | |
1077 s->login.len = p++ - s->login.data; | |
1078 s->passwd.data = p; | |
1079 | |
1080 while (p < last && *p) { p++; } | |
1081 | |
1082 s->passwd.len = p - s->passwd.data; | |
1083 | |
1084 #if (NGX_DEBUG_IMAP_PASSWD) | |
1085 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
1086 "pop3 auth plain: \"%V\" \"%V\"", | |
1087 &s->login, &s->passwd); | |
1088 #endif | |
1089 | |
1090 s->args.nelts = 0; | |
1091 s->buffer->pos = s->buffer->start; | |
1092 s->buffer->last = s->buffer->start; | |
1093 | |
1094 if (rev->timer_set) { | |
1095 ngx_del_timer(rev); | |
1096 } | |
1097 | |
1098 ngx_imap_auth_http_init(s); | |
1099 | |
1100 return; | |
1101 | |
1102 case ngx_pop3_auth_cram_md5: | |
1103 arg = s->args.elts; | |
1104 | |
1105 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
1106 "pop3 auth cram-md5: \"%V\"", &arg[0]); | |
1107 | |
1108 s->login.data = ngx_palloc(c->pool, | |
1109 ngx_base64_decoded_length(arg[0].len)); | |
1110 if (s->login.data == NULL){ | |
1111 ngx_imap_session_internal_server_error(s); | |
1112 return; | |
1113 } | |
1114 | |
1115 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
1116 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1117 "client sent invalid base64 encoding " | |
1118 "in AUTH LOGIN command"); | |
1119 ngx_imap_session_internal_server_error(s); | |
1120 return; | |
1121 } | |
1122 | |
1123 p = s->login.data; | |
1124 last = p + s->login.len; | |
1125 | |
1126 while (p < last) { | |
1127 if (*p++ == ' ') { | |
1128 s->login.len = p - s->login.data - 1; | |
1129 s->passwd.len = last - p; | |
1130 s->passwd.data = p; | |
1131 break; | |
1132 } | |
1133 } | |
1134 | |
1135 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
1136 "pop3 auth cram-md5: \"%V\" \"%V\"", | |
1137 &s->login, &s->passwd); | |
1138 | |
1139 s->auth_method = NGX_IMAP_AUTH_CRAM_MD5; | |
1140 | |
1141 s->args.nelts = 0; | |
1142 s->buffer->pos = s->buffer->start; | |
1143 s->buffer->last = s->buffer->start; | |
1144 | |
1145 if (rev->timer_set) { | |
1146 ngx_del_timer(rev); | |
1147 } | |
1148 | |
1149 ngx_imap_auth_http_init(s); | |
1150 | |
1151 return; | |
903 } | 1152 } |
904 } | 1153 } |
905 | 1154 |
906 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { | 1155 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { |
907 text = pop3_invalid_command; | 1156 text = pop3_invalid_command; |