client-common-auth.c revision efe78d3ba24fc866af1c79b9223dc0809ba26cad
/* Copyright (c) 2002-2016 Dovecot authors, see the included COPYING file */
#include "hostpid.h"
#include "login-common.h"
#include "array.h"
#include "iostream.h"
#include "istream.h"
#include "ostream.h"
#include "str.h"
#include "safe-memset.h"
#include "time-util.h"
#include "login-proxy.h"
#include "auth-client.h"
#include "dsasl-client.h"
#include "master-service-ssl-settings.h"
#include "client-common.h"
#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
/* If we've been waiting auth server to respond for over this many milliseconds,
send a "waiting" message. */
struct client_auth_fail_code_id {
const char *id;
enum client_auth_fail_code code;
};
static const struct client_auth_fail_code_id client_auth_fail_codes[] = {
};
static enum client_auth_fail_code
client_auth_fail_code_lookup(const char *fail_code)
{
fail++;
}
return CLIENT_AUTH_FAIL_CODE_NONE;
}
{
return;
}
{
if (!client->notified_auth_ready) {
"delayed sending initial response (greeting)");
}
}
{
}
{
char *const *fields;
unsigned int i, count;
for (i = 0; i < count; i++) {
break;
}
if (i == count) {
}
if (i < array_count(alt_usernames)) {
return;
}
/* array is NULL-terminated, so if there are unused fields in
the middle set them as "" */
while (array_count(alt_usernames) < i) {
const char *empty_str = "";
}
}
const char *const *args,
struct client_auth_reply *reply_r)
{
if (p == NULL) {
value = "";
} else {
value = p + 1;
}
i_error("Auth service returned invalid "
"port number: %s", value);
}
i_error("BUG: Auth service returned invalid "
"proxy_timeout value: %s", value);
}
i_error("BUG: Auth service returned invalid "
"proxy_refresh value: %s", value);
}
/* code already assigned */
} else {
}
/* already handled in sasl-server.c */
if (success) {
}
}
if (array_count(&alt_usernames) > 0) {
const char **alt;
}
}
{
return;
}
{
/* input stream got closed in client_send_raw_data().
In most places we don't have to check for this explicitly,
but login_proxy_detach() attempts to get and use the
istream's fd, which is now -1. */
return;
}
/* remote username is different, log it */
}
}
{
}
{
/* remote username is different, log it */
}
}
{
if (send_line) {
}
/* call this last - it may destroy the client */
}
{
const char *line;
unsigned int duration;
/* we're just freeing the proxy */
return;
}
/* we came here from client_destroy() */
return;
}
/* failed for some reason, probably server disconnected */
return;
}
switch (i_stream_read(input)) {
case -2:
return;
case -1:
"proxy: Remote %s:%u disconnected: %s "
"(state=%u, duration=%us)%s",
" - BUG: line not read: %s", line)));
return;
}
break;
}
}
const struct client_auth_reply *reply)
{
struct login_proxy_settings proxy_set;
return -1;
}
return -1;
}
"proxy: Unsupported SASL mechanism %s",
reply->proxy_mech));
return -1;
}
/* have to use PLAIN authentication with master user logins */
}
/* connection_queue_add() decided that we were the oldest
connection and killed us. */
return -1;
}
return -1;
}
} else if (login_source_ips_count > 0) {
/* select the next source IP with round robin. */
}
if (proxy_set.connect_timeout_msecs == 0)
return -1;
}
/* disable input until authentication is finished */
return 0;
}
{
}
static bool
{
/* we want to proxy the connection to another server.
don't do this unless authentication succeeded. with
master user proxying we can get FAIL with proxy still set.
proxy host=.. [port=..] [destuser=..] pass=.. */
if (!success)
return FALSE;
else {
/* this for plugins being able th hook into auth reply
when proxying is used */
}
return TRUE;
}
const char *reason;
reason = "Try this server instead.";
else
reason = "Logged in, but you should use this server instead.";
} else {
return TRUE;
}
/* Either failed or user login is disabled */
reason = "Authorization failed";
break;
break;
break;
break;
break;
break;
reason = "Login disabled for this user";
break;
default:
else
}
} else {
return FALSE;
}
return TRUE;
}
{
}
{
}
{
}
{
const unsigned char *data;
return -1;
}
/* see if we have a full line */
for (i = 0; i < size; i++) {
if (data[i] == '\n')
break;
}
return -1;
}
/* drop trailing \r */
return i < size ? 1 : 0;
}
{
if (client_auth_read_line(client) <= 0)
return;
return;
}
}
{
}
{
}
static void
{
struct client_auth_reply reply;
switch (sasl_reply) {
break;
}
break;
break;
}
if (sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED) {
&reply, "Authentication aborted by client.");
} else {
data);
}
break;
/* authentication itself succeeded, we just hit some
internal failure. */
}
/* the fd may still be hanging somewhere in kernel or another
process. make sure the client gets disconnected. */
i_error("shutdown() failed: %m");
else
break;
return;
}
}
const char *init_resp)
{
"SSL required for authentication");
}
client->auth_attempts++;
return 1;
}
if (!client->authenticating)
return 1;
/* don't handle input until we get the initial auth reply */
return 0;
}
{
!ssl_required))
return TRUE;
"Plaintext authentication disabled");
}
if (pass_sent) {
"Plaintext authentication not allowed "
"If anyone was listening, the password was exposed.");
}
if (ssl_required) {
} else {
}
client->auth_attempts++;
return FALSE;
}
void clients_notify_auth_connected(void)
{
if (client->input_blocked) {
}
}
}