Skip to content

Commit

Permalink
feat: 处理非官方 URL 警告
Browse files Browse the repository at this point in the history
  • Loading branch information
Mufanc committed Dec 10, 2023
1 parent 9feac3e commit 17f1ad2
Show file tree
Hide file tree
Showing 15 changed files with 655 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.idea
/*.deb
/*.tar.zst
/PKGBUILD
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.PHONY : all clean
.OHESHELL :

all:
./build.sh

clean:
rm -rf PKGBUILD src pkg *.deb *.tar.zst
46 changes: 28 additions & 18 deletions PKGBUILD.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,41 @@ arch=('x86_64')
url='https://github.com/Mufanc/QWrapper'
license=('custom')
depends=(
# 默认依赖
'gtk3' 'libnotify' 'nss' 'libxss' 'libxtst' 'xdg-utils' 'at-spi2-core' 'util-linux-libs' 'libsecret'
# 移除问题库后补的依赖
'libvips' 'libunwind' 'libssh2'
)
makedepends=()
# 默认依赖
'gtk3' 'libnotify' 'nss' 'libxss' 'libxtst' 'xdg-utils' 'at-spi2-core' 'util-linux-libs' 'libsecret'
# 移除问题库后补的依赖
'libvips' 'libunwind' 'libssh2'
)
makedepends=('rust')
optdepends=('libappindicator-gtk3')
conflicts=('linuxqq')
source=('$SOURCE' 'launcher.sh')
sha256sums=()

build() {
cd "$PKGROOT/daemon"
cargo build --release

cd "$PKGROOT/inject"
cargo build --release
}

package() {
# 解包
tar -x --xz -f data.tar.xz --directory="$pkgdir"
# 解包
tar -x --xz -f data.tar.xz --directory="$pkgdir"

# 替换入口
mv "$pkgdir/opt/QQ/qq" "$pkgdir/opt/QQ/main"
cp "$srcdir/launcher.sh" "$pkgdir/opt/QQ/qq"
# 替换入口
mv "$pkgdir/opt/QQ/qq" "$pkgdir/opt/QQ/main"
cp "$srcdir/launcher.sh" "$pkgdir/opt/QQ/launcher.sh"
cp "$PKGROOT/daemon/target/release/daemon" "$pkgdir/opt/QQ/qq"
cp "$PKGROOT/inject/target/release/libinject.so" "$pkgdir/opt/QQ/libinject.so"

# 处理 crash
res="$pkgdir/opt/QQ/resources/app"
rm "$res"/libssh*
rm "$res"/libunwind*
rm "$res"/sharp-lib/*
# 处理 crash
res="$pkgdir/opt/QQ/resources/app"
rm "$res"/libssh*
rm "$res"/libunwind*
rm "$res"/sharp-lib/*
# 替换 desktop 名称
sed -i -E "s#(Name=.*)#Name=QQ (wrap)#" "$pkgdir/usr/share/applications/qq.desktop"
# 替换 desktop 名称
sed -i -E "s#(Name=.*)#Name=QQ (wrap)#" "$pkgdir/usr/share/applications/qq.desktop"
}
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export SOURCE=$(curl -s https://im.qq.com/rainbow/linuxQQDownload/ | grep -Eo '"deb":"[^"]+"' | grep -Eo 'https://.*_amd64\.deb')
export PKGVER=$(echo $SOURCE | awk -F "linuxqq_|-" '{print $2}')
export PKGVER=$(echo "$SOURCE" | awk -F "linuxqq_|-" '{print $2}')
export PKGROOT=$(realpath "$(dirname "$0")")
envsubst "$(env | grep -Po '^[A-Z_]+(?==)' | sed 's/^/$/g')" < PKGBUILD.proto > PKGBUILD
updpkgsums
makepkg -f
1 change: 1 addition & 0 deletions daemon/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
62 changes: 62 additions & 0 deletions daemon/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions daemon/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "daemon"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0.75"
nix = { version = "0.27.1", features = ["socket", "process"] }
2 changes: 2 additions & 0 deletions daemon/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
128 changes: 128 additions & 0 deletions daemon/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#![feature(peer_credentials_unix_socket)]

use std::fs;
use std::fs::Metadata;
use std::io::Read;
use std::os::fd::{AsRawFd, OwnedFd};
use std::os::unix::fs::MetadataExt;
use std::os::unix::net::UnixListener;
use std::process::{Command, exit};
use std::thread::sleep;
use std::time::Duration;

use anyhow::{bail, Result};
use nix::{libc, unistd};
use nix::errno::Errno;
use nix::sys::prctl;
use nix::sys::signal::Signal;
use nix::sys::socket;
use nix::sys::socket::{AddressFamily, MsgFlags, SockFlag, SockType, UnixAddr};

const BIND_ADDRESS: &str = "qwrapper-daemon";


fn bind_server(fd: &OwnedFd) -> Result<()> {
let addr = &UnixAddr::new_abstract(BIND_ADDRESS.as_bytes())?;

if let Err(err) = socket::bind(fd.as_raw_fd(), addr) {
if err != Errno::EADDRINUSE {
bail!(err);
}

eprintln!("address already in use, stop old daemon and retry...");

let client = socket::socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)?;
let client_raw = client.as_raw_fd();

socket::connect(client_raw, addr)?;
socket::send(client_raw, "@exit".as_bytes(), MsgFlags::empty())?;

drop(client); // close fd

sleep(Duration::from_secs(1));

return bind_server(fd);
}

socket::listen(&fd, 16)?;

Ok(())
}


fn verify_ns(proc: Option<libc::pid_t>) -> bool {
if proc.is_none() {
return false
}

fn get_ns(id: libc::pid_t) -> Option<Metadata> {
fs::metadata(format!("/proc/{id}/ns/pid")).ok()
}

let remote = get_ns(proc.unwrap());
let local = get_ns(unistd::getpid().as_raw());

match (remote, local) {
(Some(remote), Some(local)) => {
remote.dev() == local.dev() && remote.ino() == local.ino()
}
_ => false
}
}


fn super_command(cmd: &str) {
match cmd {
"@exit" => exit(0),
"@example" => println!("example"),
_ => ()
}
}


fn main() -> Result<()> {
let fd = socket::socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)?;

bind_server(&fd)?;

let listener = UnixListener::from(fd);
println!("daemon is listening on @{BIND_ADDRESS}");

prctl::set_pdeathsig(Signal::SIGKILL)?;

let mut command = Command::new("/opt/QQ/launcher.sh");
let mut child = command.spawn()?;

for stream in listener.incoming() {
match stream {
Ok(mut client) => {
let remote_pid = client.peer_cred()
.ok()
.and_then(|c| c.pid);

let mut data = String::new();
match client.read_to_string(&mut data) {
Ok(_) => {
#[allow(clippy::collapsible_else_if)]
if data.starts_with('@') && verify_ns(remote_pid) {
super_command(&data);
} else {
if let Err(err) = Command::new("xdg-open").arg(data).status() {
eprintln!("{err}");
}
}
}
Err(err) => eprintln!("error while receiving url: {err}")
}
}
Err(err) => {
eprintln!("error while accepting connection: {err}");
break
}
}
}

child.kill()?;

Ok(())
}
1 change: 1 addition & 0 deletions inject/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
Loading

0 comments on commit 17f1ad2

Please sign in to comment.