Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/imap-login/client-authenticate.c @ 2768:d344be0bb70f HEAD
Added IMAP and POP3 proxying support.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 18 Oct 2004 22:21:40 +0300 |
parents | 26a091f3add6 |
children | e624a9ad6a30 |
comparison
equal
deleted
inserted
replaced
2767:54dfccbe7f11 | 2768:d344be0bb70f |
---|---|
11 #include "str-sanitize.h" | 11 #include "str-sanitize.h" |
12 #include "imap-parser.h" | 12 #include "imap-parser.h" |
13 #include "auth-client.h" | 13 #include "auth-client.h" |
14 #include "client.h" | 14 #include "client.h" |
15 #include "client-authenticate.h" | 15 #include "client-authenticate.h" |
16 #include "imap-proxy.h" | |
17 | |
18 #include <stdlib.h> | |
16 | 19 |
17 const char *client_authenticate_get_capabilities(int secured) | 20 const char *client_authenticate_get_capabilities(int secured) |
18 { | 21 { |
19 const struct auth_mech_desc *mech; | 22 const struct auth_mech_desc *mech; |
20 unsigned int i, count; | 23 unsigned int i, count; |
74 | 77 |
75 /* clear sensitive data */ | 78 /* clear sensitive data */ |
76 safe_memset(line, 0, strlen(line)); | 79 safe_memset(line, 0, strlen(line)); |
77 } | 80 } |
78 | 81 |
79 static int client_handle_success_args(struct imap_client *client, | 82 static int client_handle_args(struct imap_client *client, |
80 const char *const *args, int nologin) | 83 const char *const *args, int nologin) |
81 { | 84 { |
82 const char *reason = NULL, *referral = NULL; | 85 const char *reason = NULL, *host = NULL, *destuser = NULL, *pass = NULL; |
83 string_t *reply; | 86 string_t *reply; |
87 unsigned int port = 143; | |
88 int proxy = FALSE; | |
84 | 89 |
85 for (; *args != NULL; args++) { | 90 for (; *args != NULL; args++) { |
86 if (strcmp(*args, "nologin") == 0) | 91 if (strcmp(*args, "nologin") == 0) |
87 nologin = TRUE; | 92 nologin = TRUE; |
93 else if (strcmp(*args, "proxy") == 0) | |
94 proxy = TRUE; | |
88 else if (strncmp(*args, "reason=", 7) == 0) | 95 else if (strncmp(*args, "reason=", 7) == 0) |
89 reason = *args + 7; | 96 reason = *args + 7; |
90 else if (strncmp(*args, "referral=", 9) == 0) | 97 else if (strncmp(*args, "host=", 5) == 0) |
91 referral = *args + 9; | 98 host = *args + 5; |
92 } | 99 else if (strncmp(*args, "port=", 5) == 0) |
93 | 100 port = atoi(*args + 5); |
94 if (!nologin && referral == NULL) | 101 else if (strncmp(*args, "destuser=", 9) == 0) |
102 destuser = *args + 9; | |
103 else if (strncmp(*args, "pass=", 5) == 0) | |
104 pass = *args + 5; | |
105 } | |
106 | |
107 if (destuser == NULL) | |
108 destuser = client->common.virtual_user; | |
109 | |
110 if (proxy) { | |
111 /* we want to proxy the connection to another server. | |
112 | |
113 proxy host=.. [port=..] [destuser=..] pass=.. */ | |
114 if (imap_proxy_new(client, host, port, destuser, pass) < 0) | |
115 client_destroy_internal_failure(client); | |
116 else { | |
117 client_destroy(client, t_strconcat( | |
118 "Proxy: ", client->common.virtual_user, NULL)); | |
119 } | |
120 return TRUE; | |
121 } else if (host != NULL) { | |
122 /* IMAP referral | |
123 | |
124 [nologin] referral host=.. [port=..] [destuser=..] | |
125 [reason=..] | |
126 | |
127 NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login. | |
128 OK [...] Logged in, but you should use this server instead. | |
129 .. [REFERRAL ..] (Reason from auth server) | |
130 */ | |
131 reply = t_str_new(128); | |
132 str_append(reply, nologin ? "NO " : "OK "); | |
133 str_printfa(reply, "[REFERRAL imap://%s;AUTH=%s@%s", | |
134 destuser, client->common.auth_mech_name, host); | |
135 if (port != 143) | |
136 str_printfa(reply, ":%u", port); | |
137 str_append(reply, "/] "); | |
138 if (reason != NULL) | |
139 str_append(reply, reason); | |
140 else if (nologin) | |
141 str_append(reply, "Try this server instead."); | |
142 else { | |
143 str_append(reply, "Logged in, but you should use " | |
144 "this server instead."); | |
145 } | |
146 client_send_tagline(client, str_c(reply)); | |
147 } else if (nologin) { | |
148 /* Authentication went ok, but for some reason user isn't | |
149 allowed to log in. Shouldn't probably happen. */ | |
150 reply = t_str_new(128); | |
151 if (reason != NULL) | |
152 str_printfa(reply, "NO %s", reason); | |
153 else | |
154 str_append(reply, "NO Login not allowed."); | |
155 client_send_tagline(client, str_c(reply)); | |
156 } else { | |
157 /* normal login/failure */ | |
95 return FALSE; | 158 return FALSE; |
96 | 159 } |
97 reply = t_str_new(128); | 160 |
98 str_append(reply, nologin ? "NO " : "OK "); | |
99 if (referral != NULL) | |
100 str_printfa(reply, "[REFERRAL %s] ", referral); | |
101 | |
102 if (reason != NULL) | |
103 str_append(reply, reason); | |
104 else if (!nologin) | |
105 str_append(reply, "Logged in."); | |
106 else if (referral != NULL) | |
107 str_append(reply, "Try this server instead."); | |
108 else | |
109 str_append(reply, "Login disabled."); | |
110 | |
111 client_send_tagline(client, str_c(reply)); | |
112 if (!nologin) { | 161 if (!nologin) { |
113 client_destroy(client, t_strconcat( | 162 client_destroy(client, t_strconcat( |
114 "Login: ", client->common.virtual_user, NULL)); | 163 "Login: ", client->common.virtual_user, NULL)); |
115 } else { | 164 } else { |
116 /* get back to normal client input. */ | 165 /* get back to normal client input. */ |
131 ssize_t ret; | 180 ssize_t ret; |
132 | 181 |
133 switch (reply) { | 182 switch (reply) { |
134 case SASL_SERVER_REPLY_SUCCESS: | 183 case SASL_SERVER_REPLY_SUCCESS: |
135 if (args != NULL) { | 184 if (args != NULL) { |
136 if (client_handle_success_args(client, args, FALSE)) | 185 if (client_handle_args(client, args, FALSE)) |
137 break; | 186 break; |
138 } | 187 } |
139 | 188 |
140 client_send_tagline(client, "OK Logged in."); | 189 client_send_tagline(client, "OK Logged in."); |
141 client_destroy(client, t_strconcat( | 190 client_destroy(client, t_strconcat( |
142 "Login: ", client->common.virtual_user, NULL)); | 191 "Login: ", client->common.virtual_user, NULL)); |
143 break; | 192 break; |
144 case SASL_SERVER_REPLY_AUTH_FAILED: | 193 case SASL_SERVER_REPLY_AUTH_FAILED: |
145 if (args != NULL) { | 194 if (args != NULL) { |
146 if (client_handle_success_args(client, args, TRUE)) | 195 if (client_handle_args(client, args, TRUE)) |
147 break; | 196 break; |
148 } | 197 } |
149 | 198 |
150 if (data == NULL) | 199 if (data == NULL) |
151 client_send_tagline(client, "Authentication failed"); | 200 client_send_tagline(client, "Authentication failed"); |
159 io_remove(client->io); | 208 io_remove(client->io); |
160 client->io = io_add(client->common.fd, IO_READ, | 209 client->io = io_add(client->common.fd, IO_READ, |
161 client_input, client); | 210 client_input, client); |
162 break; | 211 break; |
163 case SASL_SERVER_REPLY_MASTER_FAILED: | 212 case SASL_SERVER_REPLY_MASTER_FAILED: |
164 client_send_line(client, "* BYE Internal login failure. " | 213 client_destroy_internal_failure(client); |
165 "Refer to server log for more information."); | |
166 client_destroy(client, t_strconcat("Internal login failure: ", | |
167 client->common.virtual_user, | |
168 NULL)); | |
169 break; | 214 break; |
170 case SASL_SERVER_REPLY_CONTINUE: | 215 case SASL_SERVER_REPLY_CONTINUE: |
171 data_len = strlen(data); | 216 data_len = strlen(data); |
172 iov[0].iov_base = "+ "; | 217 iov[0].iov_base = "+ "; |
173 iov[0].iov_len = 2; | 218 iov[0].iov_len = 2; |