mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
removed IDS feature, it was never enabled by default in our builds
This commit is contained in:
parent
489cc25c2f
commit
5e962ff78e
15 changed files with 1 additions and 990 deletions
2
Makefile
2
Makefile
|
|
@ -27,7 +27,7 @@ endif
|
|||
COMPLETIONDIRS = src/zsh_completion src/bash_completion
|
||||
|
||||
APPS = src/firecfg/firecfg src/firejail/firejail src/firemon/firemon src/profstats/profstats src/jailcheck/jailcheck src/etc-cleanup/etc-cleanup
|
||||
SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee src/fids/fids
|
||||
SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee
|
||||
SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter src/fzenity/fzenity
|
||||
SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp
|
||||
SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace src/fnettrace-dns/fnettrace-dns src/fnettrace-sni/fnettrace-sni
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ HAVE_CHROOT=@HAVE_CHROOT@
|
|||
HAVE_DBUSPROXY=@HAVE_DBUSPROXY@
|
||||
HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@
|
||||
HAVE_FORCE_NONEWPRIVS=@HAVE_FORCE_NONEWPRIVS@
|
||||
HAVE_IDS=@HAVE_IDS@
|
||||
HAVE_LANDLOCK=@HAVE_LANDLOCK@
|
||||
HAVE_NETWORK=@HAVE_NETWORK@
|
||||
HAVE_ONLY_SYSCFG_PROFILES=@HAVE_ONLY_SYSCFG_PROFILES@
|
||||
|
|
@ -56,7 +55,6 @@ MANFLAGS = \
|
|||
$(HAVE_DBUSPROXY) \
|
||||
$(HAVE_FILE_TRANSFER) \
|
||||
$(HAVE_FORCE_NONEWPRIVS) \
|
||||
$(HAVE_IDS) \
|
||||
$(HAVE_LANDLOCK) \
|
||||
$(HAVE_NETWORK) \
|
||||
$(HAVE_ONLY_SYSCFG_PROFILES) \
|
||||
|
|
|
|||
19
configure
vendored
19
configure
vendored
|
|
@ -671,7 +671,6 @@ PKG_CONFIG_LIBDIR
|
|||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
HAVE_APPARMOR
|
||||
HAVE_IDS
|
||||
HAVE_SANDBOX_CHECK
|
||||
DEPS_CFLAGS
|
||||
TAR
|
||||
|
|
@ -733,7 +732,6 @@ enable_option_checking
|
|||
enable_analyzer
|
||||
enable_sanitizer
|
||||
enable_sandbox_check
|
||||
enable_ids
|
||||
enable_apparmor
|
||||
enable_selinux
|
||||
enable_landlock
|
||||
|
|
@ -1393,7 +1391,6 @@ Optional Features:
|
|||
--disable-sandbox-check disable checking if firejail is running within a
|
||||
sandbox, only use this when developing firejail
|
||||
inside of a sandbox
|
||||
--enable-ids enable ids
|
||||
--enable-apparmor enable apparmor
|
||||
--enable-selinux SELinux labeling support
|
||||
--disable-landlock disable Landlock self-restriction support
|
||||
|
|
@ -3972,21 +3969,6 @@ then :
|
|||
|
||||
fi
|
||||
|
||||
HAVE_IDS=""
|
||||
|
||||
# Check whether --enable-ids was given.
|
||||
if test ${enable_ids+y}
|
||||
then :
|
||||
enableval=$enable_ids;
|
||||
fi
|
||||
|
||||
if test "x$enable_ids" = "xyes"
|
||||
then :
|
||||
|
||||
HAVE_IDS="-DHAVE_IDS"
|
||||
|
||||
fi
|
||||
|
||||
HAVE_APPARMOR=""
|
||||
|
||||
# Check whether --enable-apparmor was given.
|
||||
|
|
@ -5776,7 +5758,6 @@ Features:
|
|||
disable user profiles: $HAVE_ONLY_SYSCFG_PROFILES
|
||||
enable --output logging: $HAVE_OUTPUT
|
||||
file transfer support: $HAVE_FILE_TRANSFER
|
||||
IDS support: $HAVE_IDS
|
||||
Landlock support: $HAVE_LANDLOCK
|
||||
manpage support: $HAVE_MAN
|
||||
network: $HAVE_NETWORK
|
||||
|
|
|
|||
|
|
@ -79,14 +79,6 @@ AS_IF([test "x$enable_sandbox_check" != "xno"], [
|
|||
HAVE_SANDBOX_CHECK="-DHAVE_SANDBOX_CHECK"
|
||||
])
|
||||
|
||||
HAVE_IDS=""
|
||||
AC_SUBST([HAVE_IDS])
|
||||
AC_ARG_ENABLE([ids],
|
||||
[AS_HELP_STRING([--enable-ids], [enable ids])])
|
||||
AS_IF([test "x$enable_ids" = "xyes"], [
|
||||
HAVE_IDS="-DHAVE_IDS"
|
||||
])
|
||||
|
||||
HAVE_APPARMOR=""
|
||||
AC_SUBST([HAVE_APPARMOR])
|
||||
AC_ARG_ENABLE([apparmor],
|
||||
|
|
@ -308,7 +300,6 @@ Features:
|
|||
disable user profiles: $HAVE_ONLY_SYSCFG_PROFILES
|
||||
enable --output logging: $HAVE_OUTPUT
|
||||
file transfer support: $HAVE_FILE_TRANSFER
|
||||
IDS support: $HAVE_IDS
|
||||
Landlock support: $HAVE_LANDLOCK
|
||||
manpage support: $HAVE_MAN
|
||||
network: $HAVE_NETWORK
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
.SUFFIXES:
|
||||
ROOT = ../..
|
||||
-include $(ROOT)/config.mk
|
||||
|
||||
MOD = fids
|
||||
MOD_DIR = $(ROOT)/src/$(MOD)
|
||||
PROG = $(MOD_DIR)/$(MOD)
|
||||
TARGET = $(PROG)
|
||||
|
||||
include $(ROOT)/src/prog.mk
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2025 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* A simple unkeyed BLAKE2b Implementation based on the official reference
|
||||
* from https://github.com/BLAKE2/BLAKE2.
|
||||
*
|
||||
* The original code was released under CC0 1.0 Universal license (Creative Commons),
|
||||
* a public domain license.
|
||||
*/
|
||||
|
||||
#include "fids.h"
|
||||
|
||||
// little-endian vs big-endian is irrelevant since the checksum is calculated and checked on the same computer.
|
||||
static inline uint64_t load64( const void *src ) {
|
||||
uint64_t w;
|
||||
memcpy( &w, src, sizeof( w ) );
|
||||
return w;
|
||||
}
|
||||
|
||||
// mixing function
|
||||
#define ROTR64(x, y) (((x) >> (y)) ^ ((x) << (64 - (y))))
|
||||
#define G(a, b, c, d, x, y) { \
|
||||
v[a] = v[a] + v[b] + x; \
|
||||
v[d] = ROTR64(v[d] ^ v[a], 32); \
|
||||
v[c] = v[c] + v[d]; \
|
||||
v[b] = ROTR64(v[b] ^ v[c], 24); \
|
||||
v[a] = v[a] + v[b] + y; \
|
||||
v[d] = ROTR64(v[d] ^ v[a], 16); \
|
||||
v[c] = v[c] + v[d]; \
|
||||
v[b] = ROTR64(v[b] ^ v[c], 63); }
|
||||
|
||||
// init vector
|
||||
static const uint64_t iv[8] = {
|
||||
0x6A09E667F3BCC908, 0xBB67AE8584CAA73B,
|
||||
0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
|
||||
0x510E527FADE682D1, 0x9B05688C2B3E6C1F,
|
||||
0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179
|
||||
};
|
||||
|
||||
|
||||
const uint8_t sigma[12][16] = {
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||
};
|
||||
|
||||
// blake2b context
|
||||
typedef struct {
|
||||
uint8_t b[128]; // input buffer
|
||||
uint64_t h[8]; // chained state
|
||||
uint64_t t[2]; // total number of bytes
|
||||
size_t c; // pointer for b[]
|
||||
size_t outlen; // digest size
|
||||
} CTX;
|
||||
|
||||
// compress function
|
||||
static void compress(CTX *ctx, int last) {
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
m[i] = load64(&ctx->b[8 * i]);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
v[i] = ctx->h[i];
|
||||
v[i + 8] = iv[i];
|
||||
}
|
||||
|
||||
v[12] ^= ctx->t[0];
|
||||
v[13] ^= ctx->t[1];
|
||||
if (last)
|
||||
v[14] = ~v[14];
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
G( 0, 4, 8, 12, m[sigma[i][ 0]], m[sigma[i][ 1]]);
|
||||
G( 1, 5, 9, 13, m[sigma[i][ 2]], m[sigma[i][ 3]]);
|
||||
G( 2, 6, 10, 14, m[sigma[i][ 4]], m[sigma[i][ 5]]);
|
||||
G( 3, 7, 11, 15, m[sigma[i][ 6]], m[sigma[i][ 7]]);
|
||||
G( 0, 5, 10, 15, m[sigma[i][ 8]], m[sigma[i][ 9]]);
|
||||
G( 1, 6, 11, 12, m[sigma[i][10]], m[sigma[i][11]]);
|
||||
G( 2, 7, 8, 13, m[sigma[i][12]], m[sigma[i][13]]);
|
||||
G( 3, 4, 9, 14, m[sigma[i][14]], m[sigma[i][15]]);
|
||||
}
|
||||
|
||||
for( i = 0; i < 8; ++i )
|
||||
ctx->h[i] ^= v[i] ^ v[i + 8];
|
||||
}
|
||||
|
||||
static int init(CTX *ctx, size_t outlen) { // (keylen=0: no key)
|
||||
size_t i;
|
||||
|
||||
if (outlen == 0 || outlen > 64)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ctx->h[i] = iv[i];
|
||||
ctx->h[0] ^= 0x01010000 ^ outlen;
|
||||
|
||||
ctx->t[0] = 0;
|
||||
ctx->t[1] = 0;
|
||||
ctx->c = 0;
|
||||
ctx->outlen = outlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update(CTX *ctx, const void *in, size_t inlen) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < inlen; i++) {
|
||||
if (ctx->c == 128) {
|
||||
ctx->t[0] += ctx->c;
|
||||
if (ctx->t[0] < ctx->c)
|
||||
ctx->t[1]++;
|
||||
compress(ctx, 0);
|
||||
ctx->c = 0;
|
||||
}
|
||||
ctx->b[ctx->c++] = ((const uint8_t *) in)[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void final(CTX *ctx, void *out) {
|
||||
size_t i;
|
||||
|
||||
ctx->t[0] += ctx->c;
|
||||
if (ctx->t[0] < ctx->c)
|
||||
ctx->t[1]++;
|
||||
|
||||
while (ctx->c < 128)
|
||||
ctx->b[ctx->c++] = 0;
|
||||
compress(ctx, 1);
|
||||
|
||||
for (i = 0; i < ctx->outlen; i++) {
|
||||
((uint8_t *) out)[i] =
|
||||
(ctx->h[i >> 3] >> (8 * (i & 7))) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
// public function
|
||||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen) {
|
||||
CTX ctx;
|
||||
|
||||
if (init(&ctx, outlen))
|
||||
return -1;
|
||||
update(&ctx, in, inlen);
|
||||
final(&ctx, out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/bin
|
||||
/sbin
|
||||
/usr/bin
|
||||
/usr/sbin
|
||||
/usr/games
|
||||
/opt
|
||||
/usr/share/ca-certificates
|
||||
|
||||
|
||||
/home/netblue/.bashrc
|
||||
/home/netblue/.config/firejail
|
||||
/home/netblue/.config/autostart
|
||||
/home/netblue/Desktop/*.desktop
|
||||
/home/netblue/.ssh
|
||||
/home/netblue/.gnupg
|
||||
157
src/fids/db.c
157
src/fids/db.c
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2025 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include"fids.h"
|
||||
|
||||
typedef struct db_t {
|
||||
struct db_t *next;
|
||||
char *fname;
|
||||
char *checksum;
|
||||
char *mode;
|
||||
int checked;
|
||||
} DB;
|
||||
|
||||
#define MAXBUF 4096
|
||||
static DB *database[HASH_MAX] = {NULL};
|
||||
|
||||
// djb2 hash function by Dan Bernstein
|
||||
static unsigned hash(const char *str) {
|
||||
unsigned long hash = 5381;
|
||||
int c;
|
||||
|
||||
while ((c = *str++) != '\0')
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
|
||||
return hash & (HASH_MAX - 1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// for testing the hash table
|
||||
static void db_print(void) {
|
||||
int i;
|
||||
for (i = 0; i < HASH_MAX; i++) {
|
||||
int cnt = 0;
|
||||
DB *ptr = database[i];
|
||||
while (ptr) {
|
||||
cnt++;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
printf("%d ", cnt);
|
||||
fflush(0);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void db_add(const char *fname, const char *checksum, const char *mode) {
|
||||
DB *ptr = malloc(sizeof(DB));
|
||||
if (!ptr)
|
||||
errExit("malloc");
|
||||
ptr->fname = strdup(fname);
|
||||
ptr->checksum = strdup(checksum);
|
||||
ptr->mode = strdup(mode);
|
||||
ptr->checked = 0;
|
||||
if (!ptr->fname || !ptr->checksum || !ptr->mode)
|
||||
errExit("strdup");
|
||||
|
||||
unsigned h = hash(fname);
|
||||
ptr->next = database[h];
|
||||
database[h] = ptr;
|
||||
}
|
||||
|
||||
void db_check(const char *fname, const char *checksum, const char *mode) {
|
||||
assert(fname);
|
||||
assert(checksum);
|
||||
assert(mode);
|
||||
|
||||
unsigned h =hash(fname);
|
||||
DB *ptr = database[h];
|
||||
while (ptr) {
|
||||
if (strcmp(fname, ptr->fname) == 0) {
|
||||
ptr->checked = 1;
|
||||
break;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
if (ptr ) {
|
||||
if (strcmp(checksum, ptr->checksum)) {
|
||||
f_modified++;
|
||||
fprintf(stderr, "\nWarning: modified %s\n", fname);
|
||||
}
|
||||
if (strcmp(mode, ptr->mode)) {
|
||||
f_permissions++;
|
||||
fprintf(stderr, "\nWarning: permissions %s: old %s, new %s\n",
|
||||
fname, ptr->mode, mode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
f_new++;
|
||||
fprintf(stderr, "\nWarning: new file %s\n", fname);
|
||||
}
|
||||
}
|
||||
|
||||
void db_missing(void) {
|
||||
int i;
|
||||
for (i = 0; i < HASH_MAX; i++) {
|
||||
DB *ptr = database[i];
|
||||
while (ptr) {
|
||||
if (!ptr->checked) {
|
||||
f_removed++;
|
||||
fprintf(stderr, "Warning: removed %s\n", ptr->fname);
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return 0 if ok, 1 if error
|
||||
int db_init(void) {
|
||||
char buf[MAXBUF];
|
||||
while(fgets(buf, MAXBUF, stdin)) {
|
||||
// split - tab separated
|
||||
|
||||
char *mode = buf;
|
||||
char *ptr = strchr(buf, '\t');
|
||||
if (!ptr)
|
||||
goto errexit;
|
||||
*ptr = '\0';
|
||||
|
||||
char *checksum = ptr + 1;
|
||||
ptr = strchr(checksum, '\t');
|
||||
if (!ptr)
|
||||
goto errexit;
|
||||
*ptr = '\0';
|
||||
|
||||
char *fname = ptr + 1;
|
||||
ptr = strchr(fname, '\n');
|
||||
if (!ptr)
|
||||
goto errexit;
|
||||
*ptr = '\0';
|
||||
|
||||
db_add(fname, checksum, mode);
|
||||
}
|
||||
// db_print();
|
||||
|
||||
return 0;
|
||||
|
||||
errexit:
|
||||
fprintf(stderr, "Error fids: database corrupted\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2025 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include"fids.h"
|
||||
|
||||
typedef struct db_exclude_t {
|
||||
struct db_exclude_t *next;
|
||||
char *fname;
|
||||
int len;
|
||||
} DB_EXCLUDE;
|
||||
static DB_EXCLUDE *database = NULL;
|
||||
|
||||
void db_exclude_add(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
DB_EXCLUDE *ptr = malloc(sizeof(DB_EXCLUDE));
|
||||
if (!ptr)
|
||||
errExit("malloc");
|
||||
|
||||
ptr->fname = strdup(fname);
|
||||
if (!ptr->fname)
|
||||
errExit("strdup");
|
||||
ptr->len = strlen(fname);
|
||||
ptr->next = database;
|
||||
database = ptr;
|
||||
}
|
||||
|
||||
int db_exclude_check(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
DB_EXCLUDE *ptr = database;
|
||||
while (ptr != NULL) {
|
||||
if (strncmp(fname, ptr->fname, ptr->len) == 0)
|
||||
return 1;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2025 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef FIDS_H
|
||||
#define FIDS_H
|
||||
|
||||
#include "../include/common.h"
|
||||
|
||||
// main.c
|
||||
#define MAX_DIR_LEVEL 20 // max directory tree depth
|
||||
#define MAX_INCLUDE_LEVEL 10 // max include level for config files
|
||||
extern int f_scanned;
|
||||
extern int f_modified;
|
||||
extern int f_new;
|
||||
extern int f_removed;
|
||||
extern int f_permissions;
|
||||
|
||||
// db.c
|
||||
#define HASH_MAX 2048 // power of 2
|
||||
int db_init(void);
|
||||
void db_check(const char *fname, const char *checksum, const char *mode);
|
||||
void db_missing(void);
|
||||
|
||||
// db_exclude.c
|
||||
void db_exclude_add(const char *fname);
|
||||
int db_exclude_check(const char *fname);
|
||||
|
||||
|
||||
// blake2b.c
|
||||
//#define KEY_SIZE 128 // key size in bytes
|
||||
#define KEY_SIZE 256
|
||||
//#define KEY_SIZE 512
|
||||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen);
|
||||
|
||||
#endif
|
||||
379
src/fids/main.c
379
src/fids/main.c
|
|
@ -1,379 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2025 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "fids.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <dirent.h>
|
||||
#include <glob.h>
|
||||
|
||||
#define MAXBUF 4096
|
||||
|
||||
static int dir_level = 1;
|
||||
static int include_level = 0;
|
||||
int arg_init = 0;
|
||||
int arg_check = 0;
|
||||
char *arg_homedir = NULL;
|
||||
char *arg_dbfile = NULL;
|
||||
|
||||
int f_scanned = 0;
|
||||
int f_modified = 0;
|
||||
int f_new = 0;
|
||||
int f_removed = 0;
|
||||
int f_permissions = 0;
|
||||
|
||||
|
||||
|
||||
static inline int is_dir(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
struct stat s;
|
||||
if (stat(fname, &s) == 0) {
|
||||
if (S_ISDIR(s.st_mode))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_link(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
char c;
|
||||
ssize_t rv = readlink(fname, &c, 1);
|
||||
return (rv != -1);
|
||||
}
|
||||
|
||||
// mode is an array of 10 chars or more
|
||||
static inline void file_mode(const char *fname, char *mode) {
|
||||
assert(fname);
|
||||
assert(mode);
|
||||
|
||||
struct stat s;
|
||||
if (stat(fname, &s)) {
|
||||
*mode = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(mode, (s.st_mode & S_IRUSR) ? "r" : "-");
|
||||
sprintf(mode + 1, (s.st_mode & S_IWUSR) ? "w" : "-");
|
||||
sprintf(mode + 2, (s.st_mode & S_IXUSR) ? "x" : "-");
|
||||
sprintf(mode + 3, (s.st_mode & S_IRGRP) ? "r" : "-");
|
||||
sprintf(mode + 4, (s.st_mode & S_IWGRP) ? "w" : "-");
|
||||
sprintf(mode + 5, (s.st_mode & S_IXGRP) ? "x" : "-");
|
||||
sprintf(mode + 6, (s.st_mode & S_IROTH) ? "r" : "-");
|
||||
sprintf(mode + 7, (s.st_mode & S_IWOTH) ? "w" : "-");
|
||||
sprintf(mode + 8, (s.st_mode & S_IXOTH) ? "x" : "-");
|
||||
}
|
||||
|
||||
|
||||
static void file_checksum(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
int fd = open(fname, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
off_t size = lseek(fd, 0, SEEK_END);
|
||||
if (size < 0) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
char *content = "empty";
|
||||
int mmapped = 0;
|
||||
if (size == 0) {
|
||||
// empty files don't mmap - use "empty" string as the file content
|
||||
size = 6; // strlen("empty") + 1
|
||||
}
|
||||
else {
|
||||
content = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
mmapped = 1;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
unsigned char checksum[KEY_SIZE / 8];
|
||||
blake2b(checksum, sizeof(checksum), content, size);
|
||||
if (mmapped)
|
||||
munmap(content, size);
|
||||
|
||||
// calculate blake2 checksum
|
||||
char str_checksum[(KEY_SIZE / 8) * 2 + 1];
|
||||
int long unsigned i;
|
||||
char *ptr = str_checksum;
|
||||
for (i = 0; i < sizeof(checksum); i++, ptr += 2)
|
||||
sprintf(ptr, "%02x", (unsigned char ) checksum[i]);
|
||||
|
||||
// build permissions string
|
||||
char mode[10];
|
||||
file_mode(fname, mode);
|
||||
|
||||
if (arg_init)
|
||||
printf("%s\t%s\t%s\n", mode, str_checksum, fname);
|
||||
else if (arg_check)
|
||||
db_check(fname, str_checksum, mode);
|
||||
else
|
||||
assert(0);
|
||||
|
||||
f_scanned++;
|
||||
if (f_scanned % 500 == 0)
|
||||
fprintf(stderr, "%d ", f_scanned);
|
||||
fflush(0);
|
||||
}
|
||||
|
||||
void list_directory(const char *fname) {
|
||||
assert(fname);
|
||||
if (dir_level > MAX_DIR_LEVEL) {
|
||||
fprintf(stderr, "Warning fids: maximum depth level exceeded for %s\n", fname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (db_exclude_check(fname))
|
||||
return;
|
||||
|
||||
if (is_link(fname))
|
||||
return;
|
||||
|
||||
if (!is_dir(fname)) {
|
||||
file_checksum(fname);
|
||||
return;
|
||||
}
|
||||
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
if (!(dir = opendir(fname)))
|
||||
return;
|
||||
|
||||
dir_level++;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
char *path;
|
||||
if (asprintf(&path, "%s/%s", fname, entry->d_name) == -1)
|
||||
errExit("asprintf");
|
||||
list_directory(path);
|
||||
free(path);
|
||||
}
|
||||
closedir(dir);
|
||||
dir_level--;
|
||||
}
|
||||
|
||||
void globbing(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
// filter top directory
|
||||
if (strcmp(fname, "/") == 0)
|
||||
return;
|
||||
|
||||
glob_t globbuf;
|
||||
int globerr = glob(fname, GLOB_NOCHECK | GLOB_NOSORT | GLOB_PERIOD, NULL, &globbuf);
|
||||
if (globerr) {
|
||||
fprintf(stderr, "Error fids: failed to glob pattern %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
long unsigned i;
|
||||
for (i = 0; i < globbuf.gl_pathc; i++) {
|
||||
char *path = globbuf.gl_pathv[i];
|
||||
assert(path);
|
||||
|
||||
list_directory(path);
|
||||
}
|
||||
|
||||
globfree(&globbuf);
|
||||
}
|
||||
|
||||
static void process_config(const char *fname) {
|
||||
assert(fname);
|
||||
|
||||
if (++include_level >= MAX_INCLUDE_LEVEL) {
|
||||
fprintf(stderr, "Error ids: maximum include level for config files exceeded\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Opening config file %s\n", fname);
|
||||
int fd = open(fname, O_RDONLY|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
if (include_level == 1) {
|
||||
fprintf(stderr, "Error ids: cannot open config file %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure the file is owned by root
|
||||
struct stat s;
|
||||
if (fstat(fd, &s)) {
|
||||
fprintf(stderr, "Error ids: cannot stat config file %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
if (s.st_uid || s.st_gid) {
|
||||
fprintf(stderr, "Error ids: config file not owned by root\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Loading config file %s\n", fname);
|
||||
FILE *fp = fdopen(fd, "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Error fids: cannot open config file %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char buf[MAXBUF];
|
||||
int line = 0;
|
||||
while (fgets(buf, MAXBUF, fp)) {
|
||||
line++;
|
||||
|
||||
// trim \n
|
||||
char *ptr = strchr(buf, '\n');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
|
||||
// comments
|
||||
ptr = strchr(buf, '#');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
|
||||
// empty space
|
||||
ptr = buf;
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
char *start = ptr;
|
||||
|
||||
// empty line
|
||||
if (*start == '\0')
|
||||
continue;
|
||||
|
||||
// trailing spaces
|
||||
ptr = start + strlen(start);
|
||||
ptr--;
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
*ptr-- = '\0';
|
||||
|
||||
// replace ${HOME}
|
||||
if (strncmp(start, "include", 7) == 0) {
|
||||
ptr = start + 7;
|
||||
if ((*ptr != ' ' && *ptr != '\t') || *ptr == '\0') {
|
||||
fprintf(stderr, "Error fids: invalid line %d in %s\n", line, fname);
|
||||
exit(1);
|
||||
}
|
||||
while (*ptr == ' ' || *ptr == '\t')
|
||||
ptr++;
|
||||
|
||||
if (*ptr == '/')
|
||||
process_config(ptr);
|
||||
else {
|
||||
// assume the file is in /etc/firejail
|
||||
char *tmp;
|
||||
if (asprintf(&tmp, "/etc/firejail/%s", ptr) == -1)
|
||||
errExit("asprintf");
|
||||
process_config(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
else if (*start == '!') {
|
||||
// exclude file or dir
|
||||
start++;
|
||||
if (strncmp(start, "${HOME}", 7))
|
||||
db_exclude_add(start);
|
||||
else {
|
||||
char *fname;
|
||||
if (asprintf(&fname, "%s%s", arg_homedir, start + 7) == -1)
|
||||
errExit("asprintf");
|
||||
db_exclude_add(fname);
|
||||
free(fname);
|
||||
}
|
||||
}
|
||||
else if (strncmp(start, "${HOME}", 7))
|
||||
globbing(start);
|
||||
else {
|
||||
char *fname;
|
||||
if (asprintf(&fname, "%s%s", arg_homedir, start + 7) == -1)
|
||||
errExit("asprintf");
|
||||
globbing(fname);
|
||||
free(fname);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
include_level--;
|
||||
}
|
||||
|
||||
static const char *const usage_str =
|
||||
"Usage: fids [--help|-h|-?] --init|--check homedir\n";
|
||||
|
||||
void usage(void) {
|
||||
puts(usage_str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "-h") == 0 ||
|
||||
strcmp(argv[i], "-?") == 0 ||
|
||||
strcmp(argv[i], "--help") == 0) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[i], "--init") == 0)
|
||||
arg_init = 1;
|
||||
else if (strcmp(argv[i], "--check") == 0)
|
||||
arg_check = 1;
|
||||
else if (strncmp(argv[i], "--", 2) == 0) {
|
||||
fprintf(stderr, "Error fids: invalid argument %s\n", argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Error fids: invalid number of arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
arg_homedir = argv[2];
|
||||
|
||||
int op = arg_check + arg_init;
|
||||
if (op == 0 || op == 2) {
|
||||
fprintf(stderr, "Error fids: use either --init or --check\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (arg_init) {
|
||||
process_config(SYSCONFDIR"/ids.config");
|
||||
fprintf(stderr, "\n%d files scanned\n", f_scanned);
|
||||
fprintf(stderr, "IDS database initialized\n");
|
||||
}
|
||||
else if (arg_check) {
|
||||
if (db_init()) {
|
||||
fprintf(stderr, "Error: IDS database not initialized, please run \"firejail --ids-init\"\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
process_config(SYSCONFDIR"/ids.config");
|
||||
fprintf(stderr, "\n%d files scanned: modified %d, permissions %d, new %d, removed %d\n",
|
||||
f_scanned, f_modified, f_permissions, f_new, f_removed);
|
||||
db_missing();
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -388,13 +388,6 @@ static const char *const compiletime_support =
|
|||
"disabled"
|
||||
#endif
|
||||
|
||||
"\n\t- IDS support is "
|
||||
#ifdef HAVE_IDS
|
||||
"enabled"
|
||||
#else
|
||||
"disabled"
|
||||
#endif
|
||||
|
||||
"\n\t- Landlock support is "
|
||||
#ifdef HAVE_LANDLOCK
|
||||
"enabled"
|
||||
|
|
|
|||
|
|
@ -915,8 +915,6 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc,
|
|||
|
||||
#define PATH_FLDD (RUN_FIREJAIL_LIB_DIR "/fldd")
|
||||
|
||||
#define PATH_FIDS (LIBDIR "/firejail/fids")
|
||||
|
||||
// bitmapped filters for sbox_run
|
||||
#define SBOX_ROOT (1 << 0) // run the sandbox as root
|
||||
#define SBOX_USER (1 << 1) // run the sandbox as a regular user
|
||||
|
|
@ -962,9 +960,6 @@ void dhcp_start(void);
|
|||
// selinux.c
|
||||
void selinux_relabel_path(const char *path, const char *inside_path);
|
||||
|
||||
// ids.c
|
||||
void run_ids(int argc, char **argv);
|
||||
|
||||
// oom.c
|
||||
void oom_set(const char *oom_string);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2025 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "firejail.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
static void ids_init(void) {
|
||||
// store checksums as root in /var/lib/firejail/${USERNAME}.ids
|
||||
char *fname;
|
||||
if (asprintf(&fname, VARDIR"/%s.ids", cfg.username) == -1)
|
||||
errExit("asprintf");
|
||||
|
||||
int rv = unlink(fname);
|
||||
(void) rv;
|
||||
int fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: cannot create %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// redirect output
|
||||
close(STDOUT_FILENO);
|
||||
if (dup(fd) != STDOUT_FILENO)
|
||||
errExit("dup");
|
||||
close(fd);
|
||||
free(fname);
|
||||
|
||||
sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FIDS, "--init", cfg.homedir);
|
||||
}
|
||||
|
||||
static void ids_check(void) {
|
||||
// store checksums as root in /var/lib/firejail/${USERNAME}.ids
|
||||
char *fname;
|
||||
if (asprintf(&fname, VARDIR"/%s.ids", cfg.username) == -1)
|
||||
errExit("asprintf");
|
||||
|
||||
int fd = open(fname, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: cannot open %s\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// redirect input
|
||||
close(STDIN_FILENO);
|
||||
if (dup(fd) != STDIN_FILENO)
|
||||
errExit("dup");
|
||||
close(fd);
|
||||
free(fname);
|
||||
|
||||
sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP| SBOX_ALLOW_STDIN, 3, PATH_FIDS, "--check", cfg.homedir);
|
||||
}
|
||||
|
||||
void run_ids(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Error: only one IDS command expected\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
EUID_ROOT();
|
||||
struct stat s;
|
||||
if (stat(VARDIR, &s)) // /var/lib/firejail
|
||||
create_empty_dir_as_root(VARDIR, 0700);
|
||||
|
||||
if (strcmp(argv[1], "--ids-init") == 0)
|
||||
ids_init();
|
||||
else if (strcmp(argv[1], "--ids-check") == 0)
|
||||
ids_check();
|
||||
else
|
||||
fprintf(stderr, "Error: unrecognized IDS command\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
@ -1143,19 +1143,6 @@ int main(int argc, char **argv, char **envp) {
|
|||
if (check_arg(argc, argv, "--build", 0)) // supports both --build and --build=filename
|
||||
run_builder(argc, argv); // this function will not return
|
||||
|
||||
// intrusion detection system
|
||||
#ifdef HAVE_IDS
|
||||
if (check_arg(argc, argv, "--ids-", 0)) // supports both --ids-init and --ids-check
|
||||
run_ids(argc, argv); // this function will not return
|
||||
#else
|
||||
if (check_arg(argc, argv, "--ids-", 0)) { // supports both --ids-init and --ids-check
|
||||
fprintf(stderr, "Error: IDS features disabled in your Firejail build.\n"
|
||||
"\tTo enable it, configure your build system using --enable-ids.\n"
|
||||
"\tExample: ./configure --prefix=/usr --enable-ids\n\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
EUID_ROOT();
|
||||
#ifndef HAVE_SUID
|
||||
if (geteuid() != 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue