This file is indexed.

/usr/lib/python3/dist-packages/radicale/auth/IMAP.py is in python3-radicale 1.1.1+20160115-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012 Daniel Aleksandersen
# Copyright © 2013 Nikita Koshikov
# Copyright © 2013 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Radicale.  If not, see <http://www.gnu.org/licenses/>.

"""
IMAP authentication.

Secure authentication based on the ``imaplib`` module.

Validating users against a modern IMAP4rev1 server that awaits STARTTLS on
port 143. Legacy SSL (often on legacy port 993) is deprecated and thus
unsupported. STARTTLS is enforced except if host is ``localhost`` as
passwords are sent in PLAIN.

Python 3.2 or newer is required for TLS.

"""

import imaplib

from .. import config, log

IMAP_SERVER = config.get("auth", "imap_hostname")
IMAP_SERVER_PORT = config.getint("auth", "imap_port")
IMAP_USE_SSL = config.getboolean("auth", "imap_ssl")

IMAP_WARNED_UNENCRYPTED = False

def is_authenticated(user, password):
    """Check if ``user``/``password`` couple is valid."""
    global IMAP_WARNED_UNENCRYPTED

    if not user or not password:
        return False

    log.LOGGER.debug(
        "Connecting to IMAP server %s:%s." % (IMAP_SERVER, IMAP_SERVER_PORT,))

    connection_is_secure = False
    if IMAP_USE_SSL:
        connection = imaplib.IMAP4_SSL(host=IMAP_SERVER, port=IMAP_SERVER_PORT)
        connection_is_secure = True
    else:
        connection = imaplib.IMAP4(host=IMAP_SERVER, port=IMAP_SERVER_PORT)

    server_is_local = (IMAP_SERVER == "localhost")

    if not connection_is_secure:
        try:
            connection.starttls()
            log.LOGGER.debug("IMAP server connection changed to TLS.")
            connection_is_secure = True
        except AttributeError:
            if not server_is_local:
                log.LOGGER.error(
                    "Python 3.2 or newer is required for IMAP + TLS.")
        except (imaplib.IMAP4.error, imaplib.IMAP4.abort) as exception:
            log.LOGGER.warning(
                "IMAP server at %s failed to accept TLS connection "
                "because of: %s" % (IMAP_SERVER, exception))

    if server_is_local and not connection_is_secure and not IMAP_WARNED_UNENCRYPTED:
        IMAP_WARNED_UNENCRYPTED = True
        log.LOGGER.warning(
            "IMAP server is local. "
            "Will allow transmitting unencrypted credentials.")

    if connection_is_secure or server_is_local:
        try:
            connection.login(user, password)
            connection.logout()
            log.LOGGER.debug(
                "Authenticated IMAP user %s "
                "via %s." % (user, IMAP_SERVER))
            return True
        except (imaplib.IMAP4.error, imaplib.IMAP4.abort) as exception:
            log.LOGGER.error(
                "IMAP server could not authenticate user %s "
                "because of: %s" % (user, exception))
    else:
        log.LOGGER.critical(
            "IMAP server did not support TLS and is not ``localhost``. "
            "Refusing to transmit passwords under these conditions. "
            "Authentication attempt aborted.")
    return False  # authentication failed