Klaus Demo nginx / c578366
workaround for Eudora for Mac: it sends AUTH PLAIN [base64 encoded] Igor Sysoev 14 years ago
1 changed file(s) with 115 addition(s) and 65 deletion(s). Raw diff Collapse all Expand all
1111
1212 static void ngx_imap_init_session(ngx_connection_t *c);
1313 static void ngx_imap_init_protocol(ngx_event_t *rev);
14 static ngx_int_t ngx_imap_decode_auth_plain(ngx_imap_session_t *s,
15 ngx_str_t *encoded);
1416 static void ngx_imap_do_auth(ngx_imap_session_t *s);
1517 static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s);
1618 static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len);
659661 u_char *text, *p, *last;
660662 ssize_t size;
661663 ngx_int_t rc;
662 ngx_str_t *arg, salt, plain;
664 ngx_str_t *arg, salt;
663665 ngx_connection_t *c;
664666 ngx_imap_session_t *s;
665667 ngx_imap_core_srv_conf_t *cscf;
795797 break;
796798 }
797799
798 if (s->args.nelts != 1) {
799 rc = NGX_IMAP_PARSE_INVALID_COMMAND;
800 break;
801 }
802
803800 arg = s->args.elts;
804801
805802 if (arg[0].len == 5) {
806803
807804 if (ngx_strncasecmp(arg[0].data, "LOGIN", 5) == 0) {
805
806 if (s->args.nelts != 1) {
807 rc = NGX_IMAP_PARSE_INVALID_COMMAND;
808 break;
809 }
810
808811 s->imap_state = ngx_pop3_auth_login_username;
809812
810813 size = sizeof(pop3_username) - 1;
813816 break;
814817
815818 } else if (ngx_strncasecmp(arg[0].data, "PLAIN", 5) == 0) {
816 s->imap_state = ngx_pop3_auth_plain;
817
818 size = sizeof(pop3_next) - 1;
819 text = pop3_next;
820
819
820 if (s->args.nelts == 1) {
821 s->imap_state = ngx_pop3_auth_plain;
822
823 size = sizeof(pop3_next) - 1;
824 text = pop3_next;
825
826 break;
827 }
828
829 if (s->args.nelts == 2) {
830
831 /*
832 * workaround for Eudora for Mac: it sends
833 * AUTH PLAIN [base64 encoded]
834 */
835
836 rc = ngx_imap_decode_auth_plain(s, &arg[1]);
837
838 if (rc == NGX_OK) {
839 ngx_imap_do_auth(s);
840 return;
841 }
842
843 if (rc == NGX_ERROR) {
844 ngx_imap_session_internal_server_error(s);
845 return;
846 }
847
848 /* rc == NGX_IMAP_PARSE_INVALID_COMMAND */
849
850 break;
851 }
852
853 rc = NGX_IMAP_PARSE_INVALID_COMMAND;
821854 break;
822855 }
823856
9981031 case ngx_pop3_auth_plain:
9991032 arg = s->args.elts;
10001033
1001 #if (NGX_DEBUG_IMAP_PASSWD)
1002 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0,
1003 "pop3 auth plain: \"%V\"", &arg[0]);
1004 #endif
1005
1006 plain.data = ngx_palloc(c->pool,
1007 ngx_base64_decoded_length(arg[0].len));
1008 if (plain.data == NULL){
1034 rc = ngx_imap_decode_auth_plain(s, &arg[0]);
1035
1036 if (rc == NGX_OK) {
1037 ngx_imap_do_auth(s);
1038 return;
1039 }
1040
1041 if (rc == NGX_ERROR) {
10091042 ngx_imap_session_internal_server_error(s);
10101043 return;
10111044 }
10121045
1013 if (ngx_decode_base64(&plain, &arg[0]) != NGX_OK) {
1014 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1015 "client sent invalid base64 encoding "
1016 "in AUTH PLAIN command");
1017 rc = NGX_IMAP_PARSE_INVALID_COMMAND;
1018 break;
1019 }
1020
1021 p = plain.data;
1022 last = p + plain.len;
1023
1024 while (p < last && *p++) { /* void */ }
1025
1026 if (p == last) {
1027 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1028 "client sent invalid login "
1029 "in AUTH PLAIN command");
1030 rc = NGX_IMAP_PARSE_INVALID_COMMAND;
1031 break;
1032 }
1033
1034 s->login.data = p;
1035
1036 while (p < last && *p) { p++; }
1037
1038 if (p == last) {
1039 ngx_log_error(NGX_LOG_INFO, c->log, 0,
1040 "client sent invalid password "
1041 "in AUTH PLAIN command");
1042 rc = NGX_IMAP_PARSE_INVALID_COMMAND;
1043 break;
1044 }
1045
1046 s->login.len = p++ - s->login.data;
1047
1048 s->passwd.len = last - p;
1049 s->passwd.data = p;
1050
1051 #if (NGX_DEBUG_IMAP_PASSWD)
1052 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0,
1053 "pop3 auth plain: \"%V\" \"%V\"",
1054 &s->login, &s->passwd);
1055 #endif
1056
1057 ngx_imap_do_auth(s);
1058 return;
1046 /* rc == NGX_IMAP_PARSE_INVALID_COMMAND */
1047
1048 break;
10591049
10601050 case ngx_pop3_auth_cram_md5:
10611051 arg = s->args.elts;
11311121 }
11321122
11331123
1124 static ngx_int_t
1125 ngx_imap_decode_auth_plain(ngx_imap_session_t *s, ngx_str_t *encoded)
1126 {
1127 u_char *p, *last;
1128 ngx_str_t plain;
1129
1130 #if (NGX_DEBUG_IMAP_PASSWD)
1131 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
1132 "pop3 auth plain: \"%V\"", encoded);
1133 #endif
1134
1135 plain.data = ngx_palloc(s->connection->pool,
1136 ngx_base64_decoded_length(encoded->len));
1137 if (plain.data == NULL){
1138 return NGX_ERROR;
1139 }
1140
1141 if (ngx_decode_base64(&plain, encoded) != NGX_OK) {
1142 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
1143 "client sent invalid base64 encoding "
1144 "in AUTH PLAIN command");
1145 return NGX_IMAP_PARSE_INVALID_COMMAND;
1146 }
1147
1148 p = plain.data;
1149 last = p + plain.len;
1150
1151 while (p < last && *p++) { /* void */ }
1152
1153 if (p == last) {
1154 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
1155 "client sent invalid login in AUTH PLAIN command");
1156 return NGX_IMAP_PARSE_INVALID_COMMAND;
1157 }
1158
1159 s->login.data = p;
1160
1161 while (p < last && *p) { p++; }
1162
1163 if (p == last) {
1164 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
1165 "client sent invalid password in AUTH PLAIN command");
1166 return NGX_IMAP_PARSE_INVALID_COMMAND;
1167 }
1168
1169 s->login.len = p++ - s->login.data;
1170
1171 s->passwd.len = last - p;
1172 s->passwd.data = p;
1173
1174 #if (NGX_DEBUG_IMAP_PASSWD)
1175 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
1176 "pop3 auth plain: \"%V\" \"%V\"",
1177 &s->login, &s->passwd);
1178 #endif
1179
1180 return NGX_OK;
1181 }
1182
1183
11341184 static void
11351185 ngx_imap_do_auth(ngx_imap_session_t *s)
11361186 {