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;