提交 0808fce8 编写于 作者: R Roberto Sassu

Add upload_digest_lists

上级 7029547b
......@@ -52,6 +52,10 @@ Lists extension:
Manages digest lists and converts digest lists of arbitrary formats to the
format supported by the kernel;
- upload_digest_lists:
Runs parsers of digest lists to upload those that are in a format not
recognized by the kernel;
- verify_digest_lists:
Verifies the integrity of digest lists;
......@@ -91,14 +95,21 @@ the $libdir/digestlist directory.
(4) parse digest list (fmt N) |
+----------+ +----------+ |
| Parser 1 | ... | Parser N | <--------------------------------|
+----------+ +----------+
+-----------------------------------+
| Compact list API (generator) | (5) convert to compact list
+-----------------------------------+
+-----------------------------------+
| Base library (I/O) |
+-----------------------------------+
+----------+ +----------+ |
+-----------------------------------+ |
| Compact list API (generator) | (5) convert to compact list |
+-----------------------------------+ and sign |
+-----------------------------------+ +-------------+ |
| Base library (I/O) | <---- | Signing Key | |
+-----------------------------------+ +-------------+ |
| |
| |
| |
upload_digest_lists: | |
| (6) upload digest list +------------+
+-------------+ | Parser |
| Kernel | <--------------------------------- | exec |
+-------------+ +------------+
......
......@@ -55,6 +55,7 @@ rm -rf $RPM_BUILD_ROOT
%{_bindir}/setup_ima_digest_lists
%{_bindir}/setup_ima_digest_lists_demo
%{_bindir}/manage_digest_lists
%{_bindir}/upload_digest_lists
%{_bindir}/verify_digest_lists
%{_bindir}/write_rpm_pgp_sig
%{_libdir}/libdigestlist-base.so
......@@ -84,6 +85,7 @@ rm -rf $RPM_BUILD_ROOT
%{_datarootdir}/digest-list-tools/setup_ima_digest_lists.txt
%{_datarootdir}/digest-list-tools/setup_ima_digest_lists_demo.txt
%{_datarootdir}/digest-list-tools/manage_digest_lists.txt
%{_datarootdir}/digest-list-tools/upload_digest_lists.txt
%{_datarootdir}/digest-list-tools/verify_digest_lists.txt
%{_datarootdir}/digest-list-tools/write_rpm_pgp_sig.txt
%{_mandir}/man1/gen_digest_lists.1.gz
......@@ -91,6 +93,7 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/setup_ima_digest_lists_demo.1.gz
%{_mandir}/man1/verify_digest_lists.1.gz
%{_mandir}/man1/manage_digest_lists.1.gz
%{_mandir}/man1/upload_digest_lists.1.gz
%{_mandir}/man1/write_rpm_pgp_sig.1.gz
%{_mandir}/man1/%{name}.1.gz
......
......@@ -2,6 +2,7 @@ dist_pkgdata_DATA = gen_digest_lists.txt \
setup_ima_digest_lists.txt \
setup_ima_digest_lists_demo.txt \
manage_digest_lists.txt \
upload_digest_lists.txt \
verify_digest_lists.txt \
write_rpm_pgp_sig.txt
......@@ -9,5 +10,6 @@ man1_MANS = gen_digest_lists.1 \
setup_ima_digest_lists.1 \
setup_ima_digest_lists_demo.1 \
manage_digest_lists.1 \
upload_digest_lists.1 \
verify_digest_lists.1 \
write_rpm_pgp_sig.1
.\" Text automatically generated by txt2man
.TH untitled "14 July 2020" "" ""
.SH NAME
\fBupload_digest_lists \fP- run digest list parsers
\fB
.RE
\fB
.SH SYNOPSIS
.nf
.fam C
\fBupload_digest_lists\fP add|del <digest \fIlist\fP path>
.fam T
.fi
.fam T
.fi
.SH DESCRIPTION
\fBupload_digest_lists\fP runs parsers of digest lists to upload those that are
in a format not recognized by the kernel.
.RE
.PP
.SH EXAMPLES
Run parsers of digest lists in /etc/ima/digest_lists.
.PP
# \fBupload_digest_lists\fP add /etc/ima/digest_lists
.RE
.PP
.SH AUTHOR
Written by Roberto Sassu, <roberto.sassu at huawei.com>.
.RE
.PP
.SH COPYING
Copyright (C) 2020 Huawei Technologies Duesseldorf GmbH. Free use of
this software is granted under the terms of the GNU Public License 2.0
(GPLv2).
NAME
upload_digest_lists - run digest list parsers
SYNOPSIS
upload_digest_lists add|del <digest list path>
DESCRIPTION
upload_digest_lists runs parsers of digest lists to upload those that are
in a format not recognized by the kernel.
EXAMPLES
Run parsers of digest lists in /etc/ima/digest_lists.
# upload_digest_lists add /etc/ima/digest_lists
AUTHOR
Written by Roberto Sassu, <roberto.sassu at huawei.com>.
COPYING
Copyright (C) 2020 Huawei Technologies Duesseldorf GmbH. Free use of
this software is granted under the terms of the GNU Public License 2.0
(GPLv2).
bin_PROGRAMS=manage_digest_lists gen_digest_lists verify_digest_lists \
write_rpm_pgp_sig
write_rpm_pgp_sig upload_digest_lists
manage_digest_lists_CFLAGS=-I$(top_srcdir)/include
manage_digest_lists_LDFLAGS=$(top_srcdir)/lib/libdigestlist-base.la
......@@ -16,3 +16,8 @@ verify_digest_lists_SOURCES=verify_digest_lists.c
write_rpm_pgp_sig_CFLAGS=-I$(top_srcdir)/include
write_rpm_pgp_sig_LDFLAGS=$(top_srcdir)/lib/libdigestlist-base.la
write_rpm_pgp_sig_SOURCES=write_rpm_pgp_sig.c
upload_digest_lists_CFLAGS=-I$(top_srcdir)/include
upload_digest_lists_LDFLAGS=-all-static
upload_digest_lists_SOURCES=upload_digest_lists.c
/*
* Copyright (C) 2020 Huawei Technologies Duesseldorf GmbH
*
* Author: Roberto Sassu <roberto.sassu@huawei.com>
*
* 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, version 2 of the
* License.
*
* File: upload_digest_lists.c
* Run parsers of digest list formats not recognizable by the kernel.
*/
#include <stdio.h>
#include <errno.h>
#include <fts.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/limits.h>
#include <sys/mount.h>
#include <sys/vfs.h>
#include <sys/stat.h>
#include <linux/magic.h>
#include "list.h"
#define MOUNT_FLAGS MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME
#define SYSFS_PATH "/sys"
#define SECURITYFS_PATH SYSFS_PATH "/kernel/security"
#define DIGEST_LIST_DATA SECURITYFS_PATH "/ima/digest_list_data"
struct format_entry {
struct list_head list;
char *format;
};
LIST_HEAD(formats);
int add_format_parser(char *path)
{
char *format = NULL, *name;
char *type_start, *format_start, *format_end;
struct format_entry *cur, *new;
int ret = 0;
name = strrchr(path, '/');
if (!name)
return -EINVAL;
name++;
type_start = strchr(name, '-');
if (!type_start)
return 0;
format_start = strchr(type_start + 1, '-');
if (!format_start)
return 0;
format_end = strchr(format_start + 1, '-');
if (!format_end)
return 0;
format = strndup(format_start + 1, format_end - format_start - 1);
if (!format)
return -ENOMEM;
list_for_each_entry(cur, &formats, list)
if (!strcmp(format, cur->format))
goto out;
if (!strcmp(format, "compact"))
goto out;
new = malloc(sizeof(*new));
if (!new) {
ret = -ENOMEM;
goto out;
}
new->format = format;
list_add(&new->list, &formats);
out:
if (ret < 0)
free(format);
return ret;
}
static int init_digest_list_upload(int *mount_sysfs, int *mount_securityfs)
{
struct stat st;
int ret;
if (!stat(SECURITYFS_PATH, &st))
goto mount_securityfs;
ret = mount(SYSFS_PATH, SYSFS_PATH, "sysfs", MOUNT_FLAGS, NULL);
if (ret < 0) {
printf("Cannot mount %s (%s)\n", SYSFS_PATH,
strerror(errno));
return ret;
}
*mount_sysfs = 1;
mount_securityfs:
if (!stat(DIGEST_LIST_DATA, &st))
return 0;
ret = mount(SECURITYFS_PATH, SECURITYFS_PATH, "securityfs", MOUNT_FLAGS,
NULL);
if (ret < 0) {
printf("Cannot mount %s (%s)\n", SECURITYFS_PATH,
strerror(errno));
return ret;
}
*mount_securityfs = 1;
return 0;
}
static void end_digest_list_upload(int umount_sysfs, int umount_securityfs)
{
if (umount_securityfs)
umount(SECURITYFS_PATH);
if (umount_sysfs)
umount(SYSFS_PATH);
}
int main(int argc, char *argv[])
{
int mount_sysfs = 0, mount_securityfs = 0;
char *paths[2] = { NULL, NULL };
struct format_entry *cur, *tmp;
char parser_path[PATH_MAX];
FTS *fts = NULL;
FTSENT *ftsent;
int fts_flags = (FTS_PHYSICAL | FTS_COMFOLLOW | FTS_NOCHDIR | FTS_XDEV);
int ret;
if (argc != 3) {
printf("Usage: %s add|del <digest list path>\n", argv[0]);
return -EINVAL;
}
paths[0] = argv[2];
fts = fts_open(paths, fts_flags, NULL);
if (!fts)
return -EACCES;
while ((ftsent = fts_read(fts)) != NULL) {
switch (ftsent->fts_info) {
case FTS_F:
ret = add_format_parser(ftsent->fts_path);
if (ret < 0)
printf("Cannot upload %s\n", ftsent->fts_path);
break;
default:
break;
}
}
fts_close(fts);
fts = NULL;
ret = init_digest_list_upload(&mount_sysfs, &mount_securityfs);
if (ret < 0)
return -EACCES;
list_for_each_entry_safe(cur, tmp, &formats, list) {
if (fork() == 0) {
snprintf(parser_path, sizeof(parser_path),
"/usr/libexec/%s_parser", cur->format);
return execlp(parser_path, parser_path, argv[1],
argv[2], NULL);
}
wait(NULL);
list_del(&cur->list);
free(cur->format);
free(cur);
}
end_digest_list_upload(mount_sysfs, mount_securityfs);
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册