Linux Appimage (#85)

* updates to try to make appimage work
* Add notes on compatibility
* add wayland note
* minor change to better encode the screenshot commands
* add publish for linux artifact
main
Joel Smith 2021-03-30 16:55:03 -07:00 committed by GitHub
parent 0fdff8a62b
commit c241326690
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 125 additions and 15 deletions

View File

@ -27,7 +27,8 @@ jobs:
needs: [store-sha8] needs: [store-sha8]
strategy: strategy:
matrix: matrix:
os: [macos-latest] os: [macos-latest, ubuntu-16.04]
qt-version: ['5.15.2']
fail-fast: false fail-fast: false
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@ -39,6 +40,43 @@ jobs:
with: with:
submodules: true submodules: true
- name: Cache Qt
if: matrix.os == 'ubuntu-16.04' # We might want to do this for both mac and linux
id: cache-qt
uses: actions/cache@v1
with:
path: ../Qt
key: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
- name: Install Qt on Linux # we can also use this for macs
if: matrix.os == 'ubuntu-16.04'
uses: jurplel/install-qt-action@v2
with:
version: ${{ matrix.qt-version }}
cached: ${{ steps.cache-qt.outputs.cache-hit }}
- name: Build Pr (Linux)
if: matrix.os == 'ubuntu-16.04' && !contains(github.ref, 'tags/v') && !contains(github.ref, 'refs/heads/master') && !contains(github.ref, 'refs/heads/release-')
run: |
echo "Building!"
sudo apt install libxcb-keysyms1-dev desktop-file-utils libxcb-icccm4 libxcb-image0 libxcb-util1 \
libxcb-render-util0 libxcb-xinerama0 libxcb-composite0 libxcb-cursor0 libxcb-damage0 \
libxcb-dpms0 libxcb-dri2-0 libxcb-dri3-0 libxcb-ewmh2 libxcb-glx0 libxcb-present0 \
libxcb-randr0 libxcb-record0 libxcb-render0 libxcb-res0 libxcb-screensaver0 \
libxcb-shape0 libxcb-shm0 libxcb-sync1
qmake PREFIX=/usr -config release
make -j2
# create app image
make INSTALL_ROOT=appdir -j2 install ; find appdir/
wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
chmod a+x linuxdeployqt-continuous-x86_64.AppImage
export VERSION=${{ needs.store-sha8.outputs.sha8 }}
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage -verbose=2
mkdir -p dist
# file should be named ashirt-${{ needs.store-sha8.outputs.sha8 }}-x86_64.AppImage
mv ashirt*.AppImage dist/
- name: Build PR (mac) - name: Build PR (mac)
if: | if: |
matrix.os == 'macos-latest' && matrix.os == 'macos-latest' &&
@ -52,7 +90,7 @@ jobs:
qmake -config release qmake -config release
make make
macdeployqt ashirt.app -dmg macdeployqt ashirt.app -dmg
mkdir dist mkdir -p dist
cp ashirt.dmg dist/ashirt.dmg cp ashirt.dmg dist/ashirt.dmg
cp LICENSE dist/LICENSE cp LICENSE dist/LICENSE
cp README.md dist/README.md cp README.md dist/README.md
@ -77,7 +115,7 @@ jobs:
qmake -config release qmake -config release
make make
macdeployqt ashirt.app -dmg -always-overwrite -sign-for-notarization="John Kennedy" macdeployqt ashirt.app -dmg -always-overwrite -sign-for-notarization="John Kennedy"
mkdir dist mkdir -p dist
cp ashirt.dmg dist/ashirt.dmg cp ashirt.dmg dist/ashirt.dmg
cp LICENSE dist/LICENSE cp LICENSE dist/LICENSE
cp README.md dist/README.md cp README.md dist/README.md
@ -126,7 +164,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
platform: [darwin] platform: [darwin, linux]
steps: steps:
- name: Set Version - name: Set Version
run: echo "version=$(echo ${{ github.ref }} | cut -d'/' -f3 | cut -c2-)" >> $GITHUB_ENV run: echo "version=$(echo ${{ github.ref }} | cut -d'/' -f3 | cut -c2-)" >> $GITHUB_ENV

View File

@ -18,6 +18,39 @@ This application allows users to connect to a remote ASHIRT backend and create a
Official releases for Mac and Linux will be provided via the releases tab in GitHub along with source code for users to build themselves if desired. Official releases for Mac and Linux will be provided via the releases tab in GitHub along with source code for users to build themselves if desired.
### Installing for Linux
The official Linux release is delivered as an AppImage. Certain systems may require specialized information. For most distributions, "installation" is easy: simply set the execute flag on the AppImage, then run the application either in a terminal, or via the UI.
#### Support Matrix
| Distribution | Support Status | Notes |
| -------------------------- | ----------------- | ----------------------------------------------------------------- |
| Kali (xfce) | Supported¹ | Status is as of March, 2021 |
| Ubuntu 20.04 (Gnome) | Supported¹ | The operations menu does not update properly |
| Fedora 33 (Gnome) | Partial Support¹² | Key capture may not work properly |
| KDE Neon | Supported¹ | Status as of January 2021 |
| Linux Mint 20.1 (Cinnamon) | Supported¹ | |
| Linux Mint 20.1 (Mate) | Partial Support¹ | An alternate screenshotting tool is needed. e.g. gnome-screenshot |
¹ The application icon does not display properly
² Pure Gnome installations require a taskbar implementation, which is absent on newer versions of gnome. This can be solved by installing gnome extensions. See the list below of compatible Gnome Extensions
Note that, due to Wayland simply operating differently, global hotkeys are not supported on those platforms.
##### Valid Gnome Extensions
Various gnome extensions work. The below list is a subset. Before using one of these, check that the
gnome version they target is the same as the version you are using. Version mismatch could be buggy,
or just not work at all
| Extension Name | Notes |
| ---------------------------------------------------------------------------------------- | ----- |
| [Tray Icons](https://extensions.gnome.org/extension/1503/tray-icons/) | |
| [Tray Icons: Reloaded](https://extensions.gnome.org/extension/2890/tray-icons-reloaded/) | |
| [TopIcons Plus](https://extensions.gnome.org/extension/1031/topicons/) | |
## Non-tray OSes ## Non-tray OSes
Current Status: Non-functional Current Status: Non-functional
@ -52,12 +85,15 @@ Theoretically, any application that satisfies this requirement will work. For Ma
This tool will replace the above filename with `%file` as noted below: This tool will replace the above filename with `%file` as noted below:
| OS/DE/App | Capture Window | Capture Area | Notes | | OS/DE/App | Capture Window | Capture Area | Notes |
| ----------- | ---------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | ---------------- | --------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Linux/Gnome | gnome-screenshot -w -f %file | gnome-screenshot -a -f %file | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window | | Linux/Gnome | `gnome-screenshot -w -f %file` | `gnome-screenshot -a -f %file` | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
| MacOS X | screencapture -w %file | screencapture -s %file | | | Linux/Xfce4 | `xfce4-screenshooter -w -s %file` | `xfce4-screenshooter -r -s %file` | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
| Linux/KDE Plasma | `spectacle -a -bno %file` | `spectacle -r -bno %file` | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
| MacOS X | `screencapture -w %file` | `screencapture -s %file` | |
Note: this application expects a _single, basic command_. While piping output to another command _may_ work, it is not guaranteed. Likewise, providing multiple commands on the same "line" _may_ work, but is also not guaranteed. Officially, both of these techniques are unsupported. Note: this application expects a _single, basic command_. While piping output to another command _may_ work, it is not guaranteed. Likewise, providing multiple commands on the same "line" _may_ work, but is also not guaranteed. Officially, both of these techniques are unsupported.
Note 2: Mate-screenshot is unsupported, as it does not appear possible to specify where to write the file without opening up a GUI window
### Shortcuts ### Shortcuts

View File

@ -1,8 +1,7 @@
QT += core gui network sql QT += core gui network sql widgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11 CONFIG += c++11
TEMPLATE = app
# The following define makes your compiler emit warnings if you use # The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings # any Qt feature that has been marked deprecated (the exact warnings
@ -144,15 +143,36 @@ macx {
ICON = icons/ashirt.icns ICON = icons/ashirt.icns
QMAKE_TARGET_BUNDLE_PREFIX = com.theparanoids QMAKE_TARGET_BUNDLE_PREFIX = com.theparanoids
} }
unix {
isEmpty(PREFIX) {
PREFIX = /usr
}
isEmpty(BINDIR) {
BINDIR = $$PREFIX/bin
}
isEmpty(DATADIR) {
DATADIR = $$PREFIX/share
}
message("INSTROOT: |$$INSTROOT|")
message("PREFIX: |$$PREFIX|")
INSTALLS += target desktop icons
target.path = $$BINDIR
# Create appimage structure
desktop.path = $$DATADIR/applications
desktop.files += linux/ashirt.desktop
icons.path = $$DATADIR/icons/hicolor
icons.files += linux/icons/*
}
# Default rules for deployment. # Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin # else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
DISTFILES += \
bin/update_migration_resource.py
RESOURCES += \ RESOURCES += \
res_migrations.qrc \ res_migrations.qrc \
res_icons.qrc res_icons.qrc

BIN
icons/windowIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

8
linux/ashirt.desktop Normal file
View File

@ -0,0 +1,8 @@
[Desktop Entry]
Name=ashirt
Comment=Collect and add evidence to remote AShirt Instances
Terminal=false
Categories=Qt;Development;
Type=Application
Icon=ashirt
Exec=ashirt

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -3,5 +3,6 @@
<file>icons/shirt-dark.svg</file> <file>icons/shirt-dark.svg</file>
<file>icons/shirt-light.svg</file> <file>icons/shirt-light.svg</file>
<file>icons/shirt-red.svg</file> <file>icons/shirt-red.svg</file>
<file>icons/windowIcon.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -20,6 +20,8 @@ void handleCLI(std::vector<std::string> args);
#include "exceptions/fileerror.h" #include "exceptions/fileerror.h"
#include "traymanager.h" #include "traymanager.h"
QIcon getWindowIcon();
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
Q_INIT_RESOURCE(res_icons); Q_INIT_RESOURCE(res_icons);
Q_INIT_RESOURCE(res_migrations); Q_INIT_RESOURCE(res_migrations);
@ -67,6 +69,7 @@ int main(int argc, char* argv[]) {
QApplication app(argc, argv); QApplication app(argc, argv);
qRegisterMetaType<model::Tag>(); qRegisterMetaType<model::Tag>();
app.setWindowIcon(getWindowIcon());
if (!QSystemTrayIcon::isSystemTrayAvailable()) { if (!QSystemTrayIcon::isSystemTrayAvailable()) {
handleCLI(std::vector<std::string>(argv, argv + argc)); handleCLI(std::vector<std::string>(argv, argv + argc));
} }
@ -89,6 +92,10 @@ int main(int argc, char* argv[]) {
return rtn; return rtn;
} }
QIcon getWindowIcon() {
return QIcon(":icons/windowIcon.png");
}
#else #else
#include <QDebug> #include <QDebug>