client-authenticate.c revision 2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenconst char *client_authenticate_get_capabilities(int tls)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen auth_mechs = auth_client_get_available_mechs(auth_client);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen for (i = 0; i < AUTH_MECH_COUNT; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen cached_capability = i_strdup_empty(str_c(str));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic struct auth_mech_desc *auth_mech_find(const char *name)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen for (i = 0; i < AUTH_MECH_COUNT; i++) {
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen strcasecmp(auth_mech_desc[i].name, name) == 0)
f46363f428d8f2784146d36692b21936a48a7006Timo Sirainenstatic void client_auth_abort(struct imap_client *client, const char *msg)
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen auth_client_request_abort(client->common.auth_request);
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen "NO Authentication failed.");
b437874782ad048daa155e0ac863c2326c3f5e43Timo Sirainen /* get back to normal client input */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen client->common.io = client->common.fd == -1 ? NULL :
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_add(client->common.fd, IO_READ, client_input, client);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenstatic void master_callback(struct client *_client, int success)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen struct imap_client *client = (struct imap_client *) _client;
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen reason = t_strconcat("Login: ", client->common.virtual_user,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen reason = t_strconcat("Internal login failure: ",
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen client_send_line(client, "* BYE Internal login failure.");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void client_send_auth_data(struct imap_client *client,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen buf = buffer_create_dynamic(data_stack_pool, size*2, (size_t)-1);
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen o_stream_send(client->output, buffer_get_data(buf, NULL),
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainenstatic void login_callback(struct auth_request *request,
8451c4b5afc1ff5366438b2766f75b592c33e1ecTimo Sirainen const void *ptr;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen switch (auth_callback(request, reply, data, &client->common,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* login failed */
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen /* continue */
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen ptr = buffer_get_data(client->plain_login, &size);
40a8e6948d662339c0c5e2c7abfb84ae7c1803fdTimo Sirainen auth_client_request_continue(request, ptr, size);
cd2ed64888b42b481cde6bb9548c8520516fa3e9Timo Sirainen /* success, we should be able to log in. if we fail, just
a3fe8c0c54d87822f4b4f8f0d10caac611861b2bTimo Sirainen disconnect the client. */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenint cmd_login(struct imap_client *client, struct imap_arg *args)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* two arguments: username and password */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (args[1].type != IMAP_ARG_ATOM && args[1].type != IMAP_ARG_STRING)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "* BAD [ALERT] Plaintext authentication is disabled, "
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "but your client sent password in plaintext anyway."
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "If anyone was listening, the password was exposed.");
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen "NO Plaintext authentication disabled.");
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen /* authorization ID \0 authentication ID \0 pass */
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainen buffer_append(client->plain_login, user, strlen(user));
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainen buffer_append(client->plain_login, pass, strlen(pass));
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainen auth_client_request_new(auth_client, AUTH_MECH_PLAIN,
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen /* don't read any input from client until login is finished */
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainenstatic void authenticate_callback(struct auth_request *request,
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen switch (auth_callback(request, reply, data, &client->common,
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen /* login failed */
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen /* continue */
c444eeaa2866152cf62652698aa11b125e8454bcTimo Sirainen client_send_auth_data(client, data, reply->data_size);
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen /* success, we should be able to log in. if we fail, just
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen disconnect the client. */
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen if (i_stream_next_line(client->input) == NULL)
578ef2538ccf42e2a48234c24a8b709397101d88Timo Sirainen /* @UNSAFE */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen client_auth_abort(client, "Authentication aborted");
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen buf = buffer_create_static_hard(data_stack_pool, linelen);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (base64_decode((const unsigned char *) line, linelen,
ca4526e3b5fbf5ea3dd477a2098522a44c9ac52cTimo Sirainen client_auth_abort(client, "Invalid base64 data");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } else if (client->common.auth_request == NULL) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen client_auth_abort(client, "Don't send unrequested data");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen auth_client_request_continue(client->common.auth_request,
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen /* clear sensitive data */
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen safe_memset(buffer_free_without_data(buf), 0, bufsize);
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainenint cmd_authenticate(struct imap_client *client, struct imap_arg *args)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we want only one argument: authentication mechanism name */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (args[0].type != IMAP_ARG_ATOM && args[0].type != IMAP_ARG_STRING)
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen "NO Unsupported authentication mechanism.");
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen if (!client->tls && mech->plaintext && disable_plaintext_auth) {
f5e1d3d6b34ec152aa1ff15c7bd3d3552e9227eaTimo Sirainen "NO Plaintext authentication disabled.");
deb06d37292d9112d74bdf80cfebb92ab5151679Timo Sirainen auth_client_request_new(auth_client, mech->mech,
3f603ef00e35fca21605afa0ad8d76e94fee2b96Timo Sirainen /* following input data will go to authentication */