1 /* Copyright (C) 2002-2004 Timo Sirainen */
6 #include "str-sanitize.h"
7 #include "auth-client.h"
9 #include "client-common.h"
12 static enum auth_request_flags
13 client_get_auth_flags(struct client *client)
15 enum auth_request_flags auth_flags = 0;
17 if (client->proxy != NULL &&
18 ssl_proxy_has_valid_client_cert(client->proxy))
19 auth_flags |= AUTH_REQUEST_FLAG_VALID_CLIENT_CERT;
21 auth_flags |= AUTH_REQUEST_FLAG_SECURED;
26 call_client_callback(struct client *client, enum sasl_server_reply reply,
27 const char *data, const char *const *args)
29 sasl_server_callback_t *sasl_callback;
31 i_assert(reply != SASL_SERVER_REPLY_CONTINUE);
33 sasl_callback = client->sasl_callback;
34 client->sasl_callback = NULL;
36 sasl_callback(client, reply, data, args);
37 /* NOTE: client may be destroyed now */
40 static void master_callback(struct client *client, bool success)
42 client->authenticating = FALSE;
43 call_client_callback(client, success ? SASL_SERVER_REPLY_SUCCESS :
44 SASL_SERVER_REPLY_MASTER_FAILED, NULL, NULL);
47 static void authenticate_callback(struct auth_request *request, int status,
48 const char *data_base64,
49 const char *const *args, void *context)
51 struct client *client = context;
55 if (!client->authenticating) {
61 i_assert(client->auth_request == request);
62 client->waiting_auth_reply = FALSE;
67 client->sasl_callback(client, SASL_SERVER_REPLY_CONTINUE,
71 client->auth_request = NULL;
74 for (i = 0; args[i] != NULL; i++) {
75 if (strncmp(args[i], "user=", 5) == 0) {
76 i_free(client->virtual_user);
77 client->virtual_user = i_strdup(args[i] + 5);
79 if (strcmp(args[i], "nologin") == 0 ||
80 strcmp(args[i], "proxy") == 0) {
81 /* user can't login */
87 client->authenticating = FALSE;
88 call_client_callback(client, SASL_SERVER_REPLY_SUCCESS,
91 master_request_login(client, master_callback,
92 auth_client_request_get_server_pid(request),
93 auth_client_request_get_id(request));
97 client->auth_request = NULL;
100 /* parse our username if it's there */
101 for (i = 0; args[i] != NULL; i++) {
102 if (strncmp(args[i], "user=", 5) == 0) {
103 i_free(client->virtual_user);
104 client->virtual_user =
105 i_strdup(args[i] + 5);
110 client->authenticating = FALSE;
111 call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
117 void sasl_server_auth_begin(struct client *client,
118 const char *service, const char *mech_name,
119 const char *initial_resp_base64,
120 sasl_server_callback_t *callback)
122 struct auth_request_info info;
123 const struct auth_mech_desc *mech;
126 client->authenticating = TRUE;
127 i_free(client->auth_mech_name);
128 client->auth_mech_name = str_ucase(i_strdup(mech_name));
129 client->sasl_callback = callback;
131 mech = auth_client_find_mech(auth_client, mech_name);
133 sasl_server_auth_failed(client,
134 "Unsupported authentication mechanism.");
138 if (!client->secured && disable_plaintext_auth &&
139 (mech->flags & MECH_SEC_PLAINTEXT) != 0) {
140 sasl_server_auth_failed(client,
141 "Plaintext authentication disabled.");
145 memset(&info, 0, sizeof(info));
146 info.mech = mech->name;
147 info.service = service;
148 info.cert_username = client->proxy == NULL ? NULL :
149 ssl_proxy_get_peer_name(client->proxy);
150 info.flags = client_get_auth_flags(client);
151 info.local_ip = client->local_ip;
152 info.remote_ip = client->ip;
153 info.initial_resp_base64 = initial_resp_base64;
155 client->auth_request =
156 auth_client_request_new(auth_client, NULL, &info,
157 authenticate_callback, client, &error);
158 if (client->auth_request == NULL) {
159 sasl_server_auth_failed(client,
160 t_strconcat("Authentication failed: ", error, NULL));
164 static void sasl_server_auth_cancel(struct client *client, const char *reason,
165 enum sasl_server_reply reply)
167 i_assert(client->authenticating);
169 if (verbose_auth && reason != NULL) {
170 const char *auth_name =
171 str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
172 client_syslog(client,
173 t_strdup_printf("Authenticate %s failed: %s",
177 client->authenticating = FALSE;
178 client->waiting_auth_reply = FALSE;
180 if (client->auth_request != NULL) {
181 auth_client_request_abort(client->auth_request);
182 client->auth_request = NULL;
185 call_client_callback(client, reply, reason, NULL);
188 void sasl_server_auth_failed(struct client *client, const char *reason)
190 sasl_server_auth_cancel(client, reason, SASL_SERVER_REPLY_AUTH_FAILED);
193 void sasl_server_auth_client_error(struct client *client, const char *reason)
195 sasl_server_auth_cancel(client, reason, SASL_SERVER_REPLY_CLIENT_ERROR);