如何在 Rust 中预授权 authopen?

问题描述 投票:0回答:1

我正在尝试用 Rust 创建一个 os 图像 flasher。为了获得 SD 卡的权限,我正在尝试使用 authopen,如之前的答案中所述。

这是我为了重现该问题而创建的一个 Rust 小示例:

use std::{
    io::{Write, IoSliceMut},
    process::{Command, Stdio},
};      

use security_framework::authorization::{Authorization, AuthorizationItemSetBuilder, Flags};
use nix::sys::socket::{socketpair, SockFlag, SockType, AddressFamily, recvmsg, MsgFlags, UnixAddr, RecvMsg};
use nix::unistd::{close, pipe};
use nix::cmsg_space;


const DISK: &str = "/dev/rdisk2";

fn main() {
    open_auth(DISK);
}

fn open_auth(path: &str) {
    let rights = AuthorizationItemSetBuilder::new()
        .add_right(format!("sys.openfile.readwrite.{}", path))
        .unwrap()
        .build();

    let auth = Authorization::new(
        Some(rights),
        None,
        Flags::INTERACTION_ALLOWED | Flags::EXTEND_RIGHTS | Flags::PREAUTHORIZE,
    )
    .unwrap();

    let form = auth.make_external_form().unwrap();
    let form_bytes: Vec<u8> = form.bytes.into_iter().map(|x| x as u8).collect();

    let (srx, stx) = socketpair(
        AddressFamily::Unix,
        SockType::Stream,
        None,
        SockFlag::empty(),
    )
    .unwrap();
    let (prx, ptx) = pipe().unwrap();

    let mut cmd = Command::new("/usr/libexec/authopen")
        .args(["-stdoutpipe", "-extauth", "-o", "02", path])
        .stdin(Stdio::piped())
        .stdout(stx)
        .spawn()
        .unwrap();

    let mut stdin = cmd.stdin.take().unwrap();
    stdin.write_all(&form_bytes).unwrap();
    drop(stdin);

    let mut buf = [0u8; 4];
    let mut io_vec = [IoSliceMut::new(&mut buf)];
    let mut cmsg = cmsg_space!(RawFd);
    println!("Size: {}", cmsg.capacity());
    let msg: RecvMsg<'_, '_, UnixAddr> = recvmsg(
        srx.as_raw_fd(),
        &mut io_vec,
        Some(&mut cmsg),
        MsgFlags::empty(),
    )
    .unwrap();
    println!("RMSG: {:?}", msg);
    println!("Something: {:?}", msg.cmsgs().unwrap().collect::<Vec<_>>());

    println!("CMSG: {:?}", cmsg);
    println!("IOVEC: {:?}", io_vec);

    let output = cmd.wait().unwrap();
    println!("Raw output: {output:#?}");
}

这是我尝试运行它时得到的输出:

Finished dev profile [unoptimized + debuginfo] target(s) in 1.78s
     Running target/debug/temp
Size: 16
RMSG: RecvMsg { bytes: 2, cmsghdr: None, address: Some(UnixAddr { sun: sockaddr_un { sun_len: 0, sun_family: 0 } }), flags: MsgFlags(0x0), iobufs: PhantomData<&()>, mhdr: msghdr { msg_name: 0x7ff7b7f34166, msg_namelen: 0, msg_iov: 0x7ff7b7f34b68, msg_iovlen: 1, msg_control: 0x60000231c050, msg_controllen: 0, msg_flags: 0 } }
Something: []
CMSG: []
IOVEC: [[0, 16, 0, 0]]
Raw output: ExitStatus(
    unix_wait_status(
        256,
    ),
)

正如你所看到的,我得到的回应似乎不正确。我希望收到

ScmRights
控制消息,但我只收到 2 个字节的响应。

我之前没有做过任何Macos开发,所以也许我只是做了一些愚蠢的事情,所以任何帮助将不胜感激。

macos rust authopen
1个回答
0
投票

要在 Rust 中预授权 authopen,您需要使用 security_framework 箱为特定磁盘路径创建授权权限集,并使用适当的标志(包括 PREAUTHORIZE)初始化 Authorization 对象。将此授权转换为外部形式,然后使用正确的参数生成 authopen 进程。将授权表单字节写入 authopen 的 stdin,然后接收并处理响应,在 ScmRights 控制消息中查找文件描述符。确保您的应用程序具有完整磁盘访问权限,并考虑以提升的权限运行它。如果问题仍然存在,请验证正确的磁盘路径,检查 authopen 二进制文件是否存在于“/usr/libexec/authopen”中,并确保您的 Rust 代码具有执行 authopen 所需的权限。请记住,要在整个过程中适当处理错误,并使用最新版本的 security_framework crate 以与最新的 macOS 版本兼容。希望这有帮助,祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.