// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Code shared between several modules of the service implementation.

use {
    fidl_fuchsia_io::{
        MODE_PROTECTION_MASK, MODE_TYPE_DIRECTORY, MODE_TYPE_FILE, MODE_TYPE_MASK,
        MODE_TYPE_SERVICE, OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE, OPEN_FLAG_DESCRIBE,
        OPEN_FLAG_DIRECTORY, OPEN_FLAG_NODE_REFERENCE, OPEN_FLAG_NOT_DIRECTORY, OPEN_FLAG_POSIX,
        OPEN_FLAG_POSIX_EXECUTABLE, OPEN_FLAG_POSIX_WRITABLE, OPEN_RIGHT_READABLE,
        OPEN_RIGHT_WRITABLE,
    },
    fuchsia_zircon::Status,
    libc::{S_IRUSR, S_IWUSR},
};

/// POSIX emulation layer access attributes for all services created with service().
pub const POSIX_READ_WRITE_PROTECTION_ATTRIBUTES: u32 = S_IRUSR | S_IWUSR;

/// Validate that the requested flags for a new connection are valid.  It is a bit tricky as
/// depending on the presence of the `OPEN_FLAG_NODE_REFERENCE` flag we are effectively validating
/// two different cases: with `OPEN_FLAG_NODE_REFERENCE` the connection will be attached to the
/// service node itself, and without `OPEN_FLAG_NODE_REFERENCE` the connection will be forwarded to
/// the backing service.
///
/// `new_connection_validate_flags` will preserve `OPEN_FLAG_NODE_REFERENCE` to make it easier for
/// the caller to distinguish these two cases.
///
/// On success, returns the validated and cleaned flags.  On failure, it returns a [`Status`]
/// indicating the problem.
///
/// Changing this function can be dangerous!  Flags operations may have security implications.
pub fn new_connection_validate_flags(mut flags: u32, mode: u32) -> Result<u32, Status> {
    // There should be no MODE_TYPE_* flags set, except for, possibly, MODE_TYPE_SOCKET when the
    // target is a service.
    if (mode & !MODE_PROTECTION_MASK) & !MODE_TYPE_SERVICE != 0 {
        if mode & MODE_TYPE_MASK == MODE_TYPE_DIRECTORY {
            return Err(Status::NOT_DIR);
        } else if mode & MODE_TYPE_MASK == MODE_TYPE_FILE {
            return Err(Status::NOT_FILE);
        } else {
            return Err(Status::INVALID_ARGS);
        };
    }

    // A service is not a directory.
    flags &= !OPEN_FLAG_NOT_DIRECTORY;

    // For services the OPEN_FLAG_POSIX flags are ignored as they have meaning only for directories.
    flags &= !(OPEN_FLAG_POSIX | OPEN_FLAG_POSIX_WRITABLE | OPEN_FLAG_POSIX_EXECUTABLE);

    if flags & OPEN_FLAG_DIRECTORY != 0 {
        return Err(Status::NOT_DIR);
    }

    if flags & OPEN_FLAG_NODE_REFERENCE != 0 {
        flags &= !(OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE);
        if flags & !OPEN_FLAGS_ALLOWED_WITH_NODE_REFERENCE != 0 {
            return Err(Status::INVALID_ARGS);
        }
        flags &= OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_DESCRIBE;
        return Ok(flags);
    }

    // All the flags we have already checked above and removed.
    debug_assert!(
        flags
            & (OPEN_FLAG_DIRECTORY
                | OPEN_FLAG_NOT_DIRECTORY
                | OPEN_FLAG_POSIX
                | OPEN_FLAG_POSIX_WRITABLE
                | OPEN_FLAG_POSIX_EXECUTABLE
                | OPEN_FLAG_NODE_REFERENCE)
            == 0
    );

    // A service might only be connected to when both read and write permissions are present.
    if flags & OPEN_RIGHT_READABLE == 0 || flags & OPEN_RIGHT_WRITABLE == 0 {
        return Err(Status::ACCESS_DENIED);
    }
    let allowed_flags = OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE;

    // OPEN_FLAG_DESCRIBE is not allowed when connecting directly to the service itself.
    if flags & OPEN_FLAG_DESCRIBE != 0 {
        return Err(Status::INVALID_ARGS);
    }

    // Anything else is also not allowed.
    if flags & !allowed_flags != 0 {
        return Err(Status::INVALID_ARGS);
    }

    Ok(flags)
}

#[cfg(test)]
mod tests {
    use super::new_connection_validate_flags;

    use {
        fidl_fuchsia_io::{
            MODE_TYPE_DIRECTORY, MODE_TYPE_FILE, MODE_TYPE_SERVICE, MODE_TYPE_SOCKET,
            OPEN_FLAG_DESCRIBE, OPEN_FLAG_DIRECTORY, OPEN_FLAG_NODE_REFERENCE,
            OPEN_FLAG_NOT_DIRECTORY, OPEN_FLAG_POSIX, OPEN_FLAG_POSIX_EXECUTABLE,
            OPEN_FLAG_POSIX_WRITABLE, OPEN_RIGHT_READABLE, OPEN_RIGHT_WRITABLE,
        },
        fuchsia_zircon::Status,
    };

    /// Assertion for when `new_connection_validate_flags` should succeed => `ncvf_ok`.
    fn ncvf_ok(flags: u32, mode: u32, expected_new_flags: u32) {
        match new_connection_validate_flags(flags, mode) {
            Ok(new_flags) => assert_eq!(
                expected_new_flags, new_flags,
                "new_connection_validate_flags returned unexpected set of flags.\n\
                 Expected: {:X}\n\
                 Actual: {:X}",
                expected_new_flags, new_flags
            ),
            Err(status) => panic!("new_connection_validate_flags failed.  Status: {}", status),
        }
    }

    /// Assertion for when `new_connection_validate_flags` should fail => `ncvf_err`.
    fn ncvf_err(flags: u32, mode: u32, expected_status: Status) {
        match new_connection_validate_flags(flags, mode) {
            Ok(new_flags) => panic!(
                "new_connection_validate_flags should have failed.\n\
                 Got new flags: {:X}",
                new_flags
            ),
            Err(status) => assert_eq!(expected_status, status),
        }
    }

    /// Common combination for the service tests.
    const READ_WRITE: u32 = OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE;

    #[test]
    fn node_reference_basic() {
        // OPEN_FLAG_NODE_REFERENCE is preserved.
        ncvf_ok(OPEN_FLAG_NODE_REFERENCE, 0, OPEN_FLAG_NODE_REFERENCE);

        // Access flags are dropped.
        ncvf_ok(OPEN_FLAG_NODE_REFERENCE | OPEN_RIGHT_READABLE, 0, OPEN_FLAG_NODE_REFERENCE);
        ncvf_ok(OPEN_FLAG_NODE_REFERENCE | OPEN_RIGHT_WRITABLE, 0, OPEN_FLAG_NODE_REFERENCE);

        // OPEN_FLAG_DESCRIBE is preserved.
        ncvf_ok(
            OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_DESCRIBE,
            0,
            OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_DESCRIBE,
        );
        ncvf_ok(
            OPEN_FLAG_NODE_REFERENCE | READ_WRITE | OPEN_FLAG_DESCRIBE,
            0,
            OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_DESCRIBE,
        );

        ncvf_ok(OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_NOT_DIRECTORY, 0, OPEN_FLAG_NODE_REFERENCE);
        ncvf_err(OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_DIRECTORY, 0, Status::NOT_DIR);
    }

    #[test]
    fn service_basic() {
        // Access flags are required and preserved.
        ncvf_ok(READ_WRITE, 0, READ_WRITE);
        ncvf_err(OPEN_RIGHT_READABLE, 0, Status::ACCESS_DENIED);
        ncvf_err(OPEN_RIGHT_WRITABLE, 0, Status::ACCESS_DENIED);

        // OPEN_FLAG_DESCRIBE is not allowed.
        ncvf_err(READ_WRITE | OPEN_FLAG_DESCRIBE, 0, Status::INVALID_ARGS);

        ncvf_ok(READ_WRITE | OPEN_FLAG_NOT_DIRECTORY, 0, READ_WRITE);
        ncvf_err(READ_WRITE | OPEN_FLAG_DIRECTORY, 0, Status::NOT_DIR);
    }

    #[test]
    fn node_reference_posix() {
        // OPEN_FLAG_POSIX is ignored for services.
        ncvf_ok(
            OPEN_FLAG_NODE_REFERENCE
                | OPEN_FLAG_POSIX
                | OPEN_FLAG_POSIX_WRITABLE
                | OPEN_FLAG_POSIX_EXECUTABLE,
            0,
            OPEN_FLAG_NODE_REFERENCE,
        );
        ncvf_ok(
            OPEN_FLAG_NODE_REFERENCE
                | OPEN_FLAG_DESCRIBE
                | OPEN_FLAG_POSIX
                | OPEN_FLAG_POSIX_WRITABLE
                | OPEN_FLAG_POSIX_EXECUTABLE,
            0,
            OPEN_FLAG_NODE_REFERENCE | OPEN_FLAG_DESCRIBE,
        );
        ncvf_ok(
            OPEN_FLAG_NODE_REFERENCE
                | READ_WRITE
                | OPEN_FLAG_POSIX
                | OPEN_FLAG_POSIX_WRITABLE
                | OPEN_FLAG_POSIX_EXECUTABLE,
            0,
            OPEN_FLAG_NODE_REFERENCE,
        );
    }

    #[test]
    fn service_posix() {
        // OPEN_FLAG_POSIX is ignored for services.
        ncvf_ok(
            READ_WRITE | OPEN_FLAG_POSIX | OPEN_FLAG_POSIX_WRITABLE | OPEN_FLAG_POSIX_EXECUTABLE,
            0,
            READ_WRITE,
        );
        ncvf_err(
            READ_WRITE
                | OPEN_FLAG_DESCRIBE
                | OPEN_FLAG_POSIX
                | OPEN_FLAG_POSIX_WRITABLE
                | OPEN_FLAG_POSIX_EXECUTABLE,
            0,
            Status::INVALID_ARGS,
        );
    }

    #[test]
    fn file() {
        ncvf_err(OPEN_FLAG_NODE_REFERENCE, MODE_TYPE_FILE, Status::NOT_FILE);
        ncvf_err(READ_WRITE, MODE_TYPE_FILE, Status::NOT_FILE);
    }

    #[test]
    fn mode_directory() {
        ncvf_err(OPEN_FLAG_NODE_REFERENCE, MODE_TYPE_DIRECTORY, Status::NOT_DIR);
        ncvf_err(READ_WRITE, MODE_TYPE_DIRECTORY, Status::NOT_DIR);
    }

    #[test]
    fn mode_socket() {
        ncvf_err(OPEN_FLAG_NODE_REFERENCE, MODE_TYPE_SOCKET, Status::INVALID_ARGS);
        ncvf_err(READ_WRITE, MODE_TYPE_SOCKET, Status::INVALID_ARGS);
    }

    #[test]
    fn mode_service() {
        ncvf_ok(OPEN_FLAG_NODE_REFERENCE, MODE_TYPE_SERVICE, OPEN_FLAG_NODE_REFERENCE);
        ncvf_ok(READ_WRITE, MODE_TYPE_SERVICE, READ_WRITE);
    }
}
