예제 #1
0
파일: user.py 프로젝트: HarrySky/kolombo
async def list_users() -> None:
    from kolombo.models import User

    active_users = [user.email for user in await User.all_active()]
    info(f"Active users: {len(active_users)}")
    if len(active_users) > 0:
        print_list(active_users)
예제 #2
0
파일: domain.py 프로젝트: HarrySky/kolombo
async def list_domains() -> None:
    from kolombo.models import Domain

    all_domains = await Domain.all_active()
    active_pairs = [f"(MX) {domain.mx} -> {domain.actual}" for domain in all_domains]
    info(f"Active domains: {len(active_pairs)}")
    if len(active_pairs) > 0:
        print_list(active_pairs)
예제 #3
0
파일: dkim.py 프로젝트: HarrySky/kolombo
def get_txt_record(
    domain: str = Argument(  # noqa: B008
        ...,
        help="Domain to get DKIM TXT record for (if it was generated)"),
) -> None:
    if not path.exists(f"/etc/kolombo/dkim_keys/{domain}.txt"):
        error(f"There is no DKIM TXT record generated for {domain}!")
        exit(1)

    dkim_txt = read_dkim_txt_record(domain)
    info(
        f"[b]TXT[/] record for [b u]mail._domainkey.{domain}[/] is: {dkim_txt}"
    )
예제 #4
0
async def auth(
        x_secret_key: str = Header(...),  # noqa: B008
        domain: str = Header(..., alias="X-Domain"),  # noqa: B008
        protocol: str = Header(..., alias="Auth-Protocol"),  # noqa: B008
        auth_method: str = Header(...),  # noqa: B008
        email: str = Header(..., alias="Auth-User"),  # noqa: B008
        password: str = Header(..., alias="Auth-Pass"),  # noqa: B008
        login_attempt: int = Header(...,
                                    alias="Auth-Login-Attempt"),  # noqa: B008
        client_ip: str = Header(...),  # noqa: B008
) -> Response:
    """Endpoint used for auth of SMTP/IMAP users."""
    now = datetime.now().isoformat()
    if x_secret_key != conf.NGINX_SECRET_KEY:
        # This MUST NOT happen if everything is set up properly
        error(f"({now}) Not nginx trying to use API")
        return AuthError("Go Away", retry=False)

    # Check for possible usage errors to close connection early
    if protocol not in _protocol_to_port_mapping:
        error(f"({now}) Unsupported protocol: {protocol}")
        return AuthError("Unsupported protocol", retry=False)
    elif auth_method != "plain":
        error(f"({now}) Unsupported auth method: {auth_method}")
        return AuthError("Unsupported auth method", retry=False)

    # Remove newline from credentials
    email = email.rstrip("%0A")
    password = password.rstrip("%0A")
    if not await check_credentials(email, password, domain):
        warning(f"({now}) Failed {protocol} auth as {email} from {client_ip}")
        retry = login_attempt < conf.MAX_ATTEMPTS
        return AuthError("Invalid login or password", retry=retry)

    info(f"({now}) Successful {protocol} auth as {email} from {client_ip}")
    server_host = "kolombo-receiver"
    if protocol == "smtp":
        server_host = f"kolombo-{domain}-sender"

    server_ip = get_ip_for_host(server_host)
    server_port = _protocol_to_port_mapping[protocol]
    debug(
        f"({now}) Forwarding nginx to {server_ip}:{server_port} ({server_host})"
    )
    return AuthSuccess(server_ip, server_port)
예제 #5
0
파일: dkim.py 프로젝트: HarrySky/kolombo
def generate_keys(
        domain: str = Argument(
            ..., help="Domain to generate DKIM keys for"),  # noqa: B008
) -> None:
    client = from_env()
    build_kolombo_image(client, "dkim-gen")

    step(f"Generating DKIM keys for domain: {domain}")
    client.containers.run(
        "kolombo-dkim-gen",
        domain,
        stderr=True,
        auto_remove=True,
        volumes=["/etc/kolombo/dkim_keys:/etc/opendkim/keys"],
    )

    dkim_txt = read_dkim_txt_record(domain)
    info(
        f"[b]TXT[/] record for [b u]mail._domainkey.{domain}[/] is: {dkim_txt}"
    )
예제 #6
0
def init() -> None:
    from kolombo import __version__ as version

    username = getpwuid(getuid()).pw_name
    started(f"Setting up Kolombo for current user [b]{username}[/]")

    step("Creating /etc/kolombo folder ([u]need root privileges[/])")

    info("Creating /etc/kolombo folder (as root)")
    run(["mkdir", "-p", "-m", "750", "/etc/kolombo"], as_root=True)
    info(f"Changing /etc/kolombo owner to {username} (as root)")
    run(["chown", f"{getuid()}:{getgid()}", "/etc/kolombo"], as_root=True)

    step("Writing configuration to /etc/kolombo/kolombo.conf")
    debug_mode = confirm("Enable debug mode?",
                         default=False,
                         show_default=True)
    if debug_mode:
        enable_debug()

    nginx_secret_key: str = prompt(
        "Enter secret key for communication between NginX and auth API",
        default="changeme",
        show_default=True,
        hide_input=True,
        confirmation_prompt=True,
    )
    max_auth_attempts: int = prompt(
        "Enter maximum auth attempts per one session",
        default="3",
        show_default=True,
        type=INT,
    )
    passwords_salt: str = prompt(
        "Enter secret key to be used as salt for passwords hashing",
        default="changeme",
        show_default=True,
        hide_input=True,
        confirmation_prompt=True,
    )
    configuration = (
        f"### Generated by kolombo v{version}\n\n"
        "# Whether debug mode is enabled (0 - disabled, 1 - enabled)\n"
        f"DEBUG={int(debug_mode)}\n"
        "# Secret key that is used to determine that nginx is using API\n"
        f"NGINX_SECRET_KEY={nginx_secret_key}\n"
        "# Maximum auth attempts per one session\n"
        f"MAX_ATTEMPTS={max_auth_attempts}\n"
        "# Salt used for passwords hashing\n"
        f"SALT={passwords_salt}\n")
    with open("/etc/kolombo/kolombo.conf", "w") as config_file:
        config_file.write(configuration)

    step("Populating /etc/kolombo with default folders and files")
    debug("Creating /etc/kolombo folders for volumes")
    folders = ("maildirs", "mail-enabled", "virtual", "dkim_keys")
    for folder in folders:
        Path(f"/etc/kolombo/{folder}").mkdir(mode=0o770, exist_ok=True)

    for file in ("addresses", "domains", "mailbox", "ssl_map"):
        debug(f"Writing default file to /etc/kolombo/virtual/{file}")
        with open(f"/etc/kolombo/virtual/{file}", "w") as virtual_file:
            virtual_file.write(f"# {_virtual_configs[file]}\n")

    step(
        "Installing auto-completion ([u]restart current shell session to use[/])"
    )
    run([sys.argv[0], "--install-completion"])

    finished("Kolombo is set up!")