struct auth_client_request *reauth_request;
string_t *auth_response;
struct timeval auth_first_started, auth_finished;
- const char *sasl_final_resp;
+ const char *sasl_final_delayed_resp;
+ enum sasl_server_reply delayed_final_reply;
+ const char *const *final_args;
const char *const *auth_passdb_args;
struct anvil_query *anvil_query;
struct anvil_request *anvil_request;
bool fd_proxying:1;
bool shutting_down:1;
bool resource_constraint:1;
+ bool final_response:1;
/* ... */
};
#include "login-common.h"
#include "array.h"
#include "md5.h"
+#include "sasl-server.h"
#include "str.h"
#include "base64.h"
#include "buffer.h"
#include "hex-binary.h"
#include "ioloop.h"
#include "istream.h"
+#include "strfuncs.h"
#include "write-full.h"
#include "strescape.h"
#include "str-sanitize.h"
client->auth_anonymous = TRUE;
} else if (str_begins(args[i], "event_", &key)) {
event_add_str(client->event_auth, key, value);
- } else if (login_binary->sasl_support_final_reply &&
- strcmp(key, "resp") == 0) {
- client->sasl_final_resp =
+ } else if (strcmp(key, "resp") == 0) {
+ client->sasl_final_delayed_resp =
p_strdup(client->pool, value);
}
}
for (i = 0; args[i] != NULL; i++) {
const char *key, *value;
t_split_key_value_eq(args[i], &key, &value);
- args_parse_user(client, key, value);
+ if (args_parse_user(client, key, value))
+ continue;
+ if (strcmp(key, "resp") == 0) {
+ client->sasl_final_delayed_resp =
+ p_strdup(client->preproxy_pool, value);
+ }
}
}
- client->authenticating = FALSE;
- call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
- NULL, args);
+ if (client->sasl_final_delayed_resp != NULL &&
+ !login_binary->sasl_support_final_reply) {
+ client->final_response = TRUE;
+ client->final_args = p_strarray_dup(client->preproxy_pool, args);
+ client->delayed_final_reply = SASL_SERVER_REPLY_AUTH_FAILED;
+ client->sasl_callback(client, SASL_SERVER_REPLY_CONTINUE,
+ client->sasl_final_delayed_resp, NULL);
+ } else {
+ client->authenticating = FALSE;
+ call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
+ NULL, args);
+ }
break;
}
}
sasl_server_auth_cancel(client, "Aborted", NULL,
SASL_SERVER_REPLY_AUTH_ABORTED);
}
+
+void sasl_server_auth_delayed_final(struct client *client)
+{
+ client->final_response = FALSE;
+ client->authenticating = FALSE;
+ client->auth_client_continue_pending = FALSE;
+ call_client_callback(client, client->delayed_final_reply, NULL, client->final_args);
+}