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;