# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2015-2022 Mikhail Morfikov
# Copyright (C) 2023-2024 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only

abi <abi/4.0>,

include <tunables/global>

@{exec_path} = @{bin}/qbittorrent
@{att} = ""
profile qbittorrent /{,usr/}bin/qbittorrent {
  include <abstractions/base-strict>
  include <abstractions/consoles>
  include <abstractions/dconf-write>
  include <abstractions/desktop>
  include <abstractions/disks-read>
  include <abstractions/fontconfig-cache-read>
  include <abstractions/graphics>
  include <abstractions/ibus-strict>
  include <abstractions/nameservice-strict>
  include <abstractions/private-files-strict>
  include <abstractions/qt5>
  include <abstractions/qt5-compose-cache-write>
  include <abstractions/qt5-settings-write>
  include <abstractions/ssl_certs>
  include <abstractions/user-download-strict>

  signal send set=(term, kill) peer=qbittorrent//python,

  # Qt/KDE session shutdown broadcasts TERM to the whole user session on exit
  signal (send) set=term,

  network inet dgram,
  network inet6 dgram,
  network inet stream,
  network inet6 stream,
  network netlink dgram,
  network netlink raw,

  @{exec_path} mr,

  @{open_path}           rpx -> child-open,
  @{python_path}         rcx -> python, # For "search engine"

  /{,usr/}lib{,exec,32,64}/*-linux-gnu*/{,libexec/}kf5/kioslave5 Px,
  /{,usr/}lib{,exec,32,64}/*-linux-gnu*/{,libexec/}kf6/kioworker Px,
  /{,usr/}lib{,exec,32,64}/kf5/kioslave5 Px,
  /{,usr/}lib{,exec,32,64}/kf6/kioworker Px,

  # Allowed apps to open
  @{bin}/ebook-viewer    rpx,
  @{bin}/geany           rpx,
  @{bin}/mpv             rpx,
  @{bin}/nautilus        rpx,
  @{bin}/qpdfview        rpx,
  @{bin}/smplayer        rpx,
  @{bin}/spacefm         rpx,
  @{bin}/viewnior       rpux,
  @{bin}/vlc             rpx,
  @{browsers_path}       rpx,

  /usr/share/GeoIP/GeoIP.dat r,
  /usr/share/gvfs/remote-volume-monitors/{,*} r,
  /usr/share/templates/ r,
  /usr/share/thumbnailers/{,*} r,

  /etc/fstab r,
  /etc/pulse/client.conf r,

  @{sys}/bus/usb/devices/ r,

  #aa:lint ignore=too-wide
  / r,
  /*/ r,

  owner @{HOME}/{,**} rw,
  @{MOUNTDIRS}/ r,
  @{MOUNTS}/ rw,
  @{MOUNTS}/** rw,
  @{run}/mount/utab r,
  owner @{run}/user/@{uid}/filehelper* rw,

  owner @{user_cache_dirs}/qBittorrent/{,**} rw,
  owner @{user_cache_dirs}/event-sound-cache.tdb.* r,

  owner @{user_config_dirs}/qBittorrent/ rw,
  owner @{user_config_dirs}/qBittorrent/** rwlk -> @{user_config_dirs}/qBittorrent/#@{int},
  owner @{user_config_dirs}/qBittorrentrc.lock rwk,

  owner @{user_share_dirs}/{,data/}qBittorrent/ rw,
  owner @{user_share_dirs}/{,data/}qBittorrent/** rwl -> @{user_share_dirs}/{,data/}qBittorrent/**/#@{int},
  owner @{user_share_dirs}/{,data/}qBittorrent/** rwl -> @{user_share_dirs}/{,data/}qBittorrent/#@{int},
  owner @{user_share_dirs}/data/ rw,
  owner @{user_share_dirs}/sounds/{,**} r,

  owner @{user_share_dirs}/user-places.xbel r,
  owner @{user_share_dirs}/user-places.xbel.bak rw,
  owner @{user_share_dirs}/user-places.xbel.@{rand6} rwl -> @{user_share_dirs}/user-places.xbel,
  owner @{user_share_dirs}/user-places.xbel.tbcache.@{rand6} rwl -> @{user_share_dirs}/user-places.xbel,

  /dev/shm/ r,
  owner /dev/shm/#@{int} rw,
  owner @{tmp}/.*/{,s} rw,
  owner @{tmp}/.qBittorrent/ rw,
  owner @{tmp}/.qBittorrent/* rwl -> /tmp/.qBittorrent/*,
  owner @{tmp}/*.torrent rw,
  owner @{tmp}/mozilla_*/*.torrent rw,
  owner @{tmp}/qtsingleapp-qBitto-* rw,
  owner @{tmp}/qtsingleapp-qBitto-*-lockfile rwk,
  owner @{tmp}/tmp* rw,

  owner @{PROC}/@{pids}/cmdline r,
  owner @{PROC}/@{pids}/comm r,
  owner @{PROC}/@{pids}/fd/ r,
  owner @{PROC}/@{pids}/mountinfo r,
  owner @{PROC}/@{pids}/mounts r,

  owner /dev/tty@{u8} rw,

  owner @{run}/user/@{uid}/#@{int} rw,
  owner @{run}/user/@{uid}/pulse/ rw,
  owner @{run}/user/@{uid}/qBittorrent@{rand6}.@{int}.kioworker.socket rwl -> @{run}/user/@{uid}/#@{int},

  owner @{user_config_dirs}/pulse/ rw,
  owner @{user_config_dirs}/pulse/cookie r,

  profile python {
    include <abstractions/base-strict>
    include <abstractions/nameservice-strict>
    include <abstractions/python>
    include <abstractions/ssl_certs>

    signal (receive) set=(term, kill) peer=qbittorrent,

    network inet dgram,
    network inet6 dgram,
    network inet stream,
    network inet6 stream,
    network netlink raw,

    @{python_path} r,

    owner @{user_share_dirs}/{,data/}qBittorrent/nova@{int}/{,**} rw,

    owner @{user_torrents_dirs}/** r,

    owner /dev/shm/sem.mp-@{word8} rwl -> /dev/shm/@{int},
    owner /dev/shm/* rw,

    owner @{tmp}/@{int} rw,
    owner @{tmp}/tmp* rw,

    deny /dev/dri/card@{int} rw,

    include if exists <local/qbittorrent_python>
  }

  include if exists <local/qbittorrent>
}

# vim:syntax=apparmor
