client-authenticate.c revision 2454dfa32c93c20a8522c6ed42fe057baaac9f9a
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "login-common.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "base64.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "buffer.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "hex-binary.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "ioloop.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "istream.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "ostream.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "safe-memset.h"
e98e8ba55a01427844b2d24becd791dde8b0178bTimo Sirainen#include "str.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "str-sanitize.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "auth-client.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "../pop3/pop3-capability.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "ssl-proxy.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "client.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "client-authenticate.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch#include "pop3-proxy.h"
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschstatic const char *capability_string = POP3_CAPABILITY_REPLY;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschbool cmd_capa(struct pop3_client *client, const char *args ATTR_UNUSED)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const struct auth_mech_desc *mech;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int i, count;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch string_t *str;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str = t_str_new(128);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, "+OK\r\n");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, capability_string);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen if (client_is_tls_enabled(&client->common) && !client->common.tls)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, "STLS\r\n");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (!client->common.set->disable_plaintext_auth ||
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client->common.secured)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, "USER\r\n");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, "SASL");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mech = sasl_server_get_advertised_mechs(&client->common, &count);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (i = 0; i < count; i++) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append_c(str, ' ');
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, mech[i].name);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(str, "\r\n.\r\n");
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen client_send_raw(&client->common, str_c(str));
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen return TRUE;
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen}
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainenvoid pop3_client_auth_result(struct client *client,
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen enum client_auth_result result,
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen const struct client_auth_reply *reply ATTR_UNUSED,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const char *text)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch switch (result) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_SUCCESS:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* nothing to be done for POP3 */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch break;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_TEMPFAIL:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_reply(client, POP3_CMD_REPLY_TEMPFAIL, text);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch break;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_AUTHFAILED:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_AUTHFAILED_REASON:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_AUTHZFAILED:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_PASS_EXPIRED:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_SSL_REQUIRED:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_LOGIN_DISABLED:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_MECH_INVALID:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_MECH_SSL_REQUIRED:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch case CLIENT_AUTH_RESULT_INVALID_BASE64:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_reply(client, POP3_CMD_REPLY_AUTH_ERROR, text);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch break;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch default:
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_reply(client, POP3_CMD_REPLY_ERROR, text);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch break;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschbool cmd_auth(struct pop3_client *pop3_client, const char *args)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct client *client = &pop3_client->common;
c1b9c4531186c6a7cd92d2c353273a834f8ee66fTimo Sirainen const struct auth_mech_desc *mech;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const char *mech_name, *p;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (*args == '\0') {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* Old-style SASL discovery, used by MS Outlook */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int i, count;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_raw(client, "+OK\r\n");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch mech = sasl_server_get_advertised_mechs(client, &count);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch for (i = 0; i < count; i++) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_raw(client, mech[i].name);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_raw(client, "\r\n");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_raw(client, ".\r\n");
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen return TRUE;
c1b9c4531186c6a7cd92d2c353273a834f8ee66fTimo Sirainen }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* <mechanism name> <initial response> */
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen p = strchr(args, ' ');
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen if (p == NULL) {
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen mech_name = args;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen args = NULL;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen } else {
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen mech_name = t_strdup_until(args, p);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen args = p+1;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen (void)client_auth_begin(client, mech_name, args);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen return TRUE;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen}
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainenbool cmd_user(struct pop3_client *pop3_client, const char *args)
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen{
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen if (!client_check_plaintext_auth(&pop3_client->common, FALSE)) {
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen if (pop3_client->common.virtual_user == NULL)
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen pop3_client->common.virtual_user = i_strdup(args);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen i_free(pop3_client->last_user);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen pop3_client->last_user = i_strdup(args);
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen
84a31ddebcf8c3aeaef7b9e54171a48ee1374c45Timo Sirainen client_send_raw(&pop3_client->common, "+OK\r\n");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschbool cmd_pass(struct pop3_client *pop3_client, const char *args)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct client *client = &pop3_client->common;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch string_t *plain_login, *base64;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (pop3_client->last_user == NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* client may ignore the USER reply and only display the error
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch message from PASS */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (!client_check_plaintext_auth(client, TRUE))
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_reply(client, POP3_CMD_REPLY_ERROR,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "No username given.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* authorization ID \0 authentication ID \0 pass */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch plain_login = t_str_new(128);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append_c(plain_login, '\0');
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(plain_login, pop3_client->last_user);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append_c(plain_login, '\0');
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch str_append(plain_login, args);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch i_free_and_null(pop3_client->last_user);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch base64 = buffer_create_dynamic(pool_datastack_create(),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch MAX_BASE64_ENCODED_SIZE(plain_login->used));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch base64_encode(plain_login->data, plain_login->used, base64);
d2dd9b7365c8efb4e205d521c9d66758dbf7300aTimo Sirainen
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch (void)client_auth_begin(client, "PLAIN", str_c(base64));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Boschbool cmd_apop(struct pop3_client *pop3_client, const char *args)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch{
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch struct client *client = &pop3_client->common;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch buffer_t *apop_data, *base64;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch const char *p;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch unsigned int server_pid, connect_uid;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (pop3_client->apop_challenge == NULL) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (client->set->auth_verbose)
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_log(client, "APOP failed: APOP not enabled");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_reply(client, POP3_CMD_REPLY_ERROR,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "APOP not enabled.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen /* <username> <md5 sum in hex> */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch p = strchr(args, ' ');
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (p == NULL || strlen(p+1) != 32) {
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen if (client->set->auth_verbose)
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen client_log(client, "APOP failed: Invalid parameters");
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen client_send_reply(client, POP3_CMD_REPLY_ERROR,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "Invalid parameters.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen /* APOP challenge \0 username \0 APOP response */
b32b2375b68fed551b4efd786d1640f7d42bcebcTimo Sirainen apop_data = buffer_create_dynamic(pool_datastack_create(), 128);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch buffer_append(apop_data, pop3_client->apop_challenge,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch strlen(pop3_client->apop_challenge)+1);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch buffer_append(apop_data, args, (size_t)(p-args));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch buffer_append_c(apop_data, '\0');
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (hex_to_binary(p+1, apop_data) < 0) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (client->set->auth_verbose) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_log(client, "APOP failed: "
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "Invalid characters in MD5 response");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_send_reply(client, POP3_CMD_REPLY_ERROR,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "Invalid characters in MD5 response.");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch base64 = buffer_create_dynamic(pool_datastack_create(),
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch MAX_BASE64_ENCODED_SIZE(apop_data->used));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch base64_encode(apop_data->data, apop_data->used, base64);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch auth_client_get_connect_id(auth_client, &server_pid, &connect_uid);
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch if (pop3_client->apop_server_pid != server_pid ||
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch pop3_client->apop_connect_uid != connect_uid) {
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch /* we reconnected to auth server and can't authenticate
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch with APOP in this session anymore. disconnecting the user
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch is probably the best solution now. */
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch client_destroy(client,
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch "Reconnected to auth server, can't do APOP");
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch }
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch (void)client_auth_begin(client, "APOP", str_c(base64));
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch return TRUE;
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch}
f9511e684858bf5f6ac77ab12254b85b737beae8Stephan Bosch