From 11bd572adf4a861e4c42123c2dadbacd3349af93 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 23 Dec 2014 18:25:17 +0100 Subject: support updating the challenge on boot --- bin/Makefile | 10 ++- bin/ykfde-cpio.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/ykfde.c | 3 +- 3 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 bin/ykfde-cpio.c (limited to 'bin') diff --git a/bin/Makefile b/bin/Makefile index daa77f2..4fcd6fb 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -5,13 +5,17 @@ RM := rm # flags CFLAGS += -std=c11 -O2 -fpic -pie -Wall -Werror -all: ykfde +all: ykfde ykfde-cpio ykfde: ykfde.c $(CC) $(CFLAGS) -lykpers-1 -lyubikey -liniparser -lcryptsetup $(LDFLAGS) -o ykfde ykfde.c -install: ykfde +ykfde-cpio: ykfde-cpio.c + $(CC) $(CFLAGS) -larchive $(LDFLAGS) -o ykfde-cpio ykfde-cpio.c + +install: ykfde ykfde-cpio $(INSTALL) -D -m0755 ykfde $(DESTDIR)/usr/bin/ykfde + $(INSTALL) -D -m0755 ykfde-cpio $(DESTDIR)/usr/bin/ykfde-cpio clean: - $(RM) -f ykfde + $(RM) -f ykfde ykfde-cpio diff --git a/bin/ykfde-cpio.c b/bin/ykfde-cpio.c new file mode 100644 index 0000000..71a39db --- /dev/null +++ b/bin/ykfde-cpio.c @@ -0,0 +1,220 @@ +/* + * (C) 2014 by Christian Hesse + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * compile with: + * $ gcc -o mkcpio mkcpio.c -larchive + */ + +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define CONFIGFILE "/etc/ykfde.conf" +#define CHALLENGEDIR "/etc/ykfde.d/" +#define CPIOFILE "/boot/ykfde-challenges.img" +#define CPIOTMPFILE CPIOFILE "-XXXXXX" + +int add_dir(struct archive *archive, const char * path) { + struct stat st; + struct archive_entry *entry; + int8_t rc; + + /* initialize struct stat for directories from root */ + if ((rc = stat("/", &st)) < 0) { + perror("stat() failed"); + goto out; + } + + if ((entry = archive_entry_new()) == NULL) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_entry_new() failed"); + goto out; + } + + archive_entry_set_pathname(entry, path); + archive_entry_set_filetype(entry, AE_IFDIR); + archive_entry_copy_stat(entry, &st); + if (archive_write_header(archive, entry) != ARCHIVE_OK) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_header() failed"); + goto out; + } + archive_entry_free(entry); + + rc = EXIT_SUCCESS; + +out: + return rc; +} + +int main(int argc, const char **argv) { + char cpiotmpfile[] = CPIOTMPFILE; + struct archive *archive; + struct archive_entry *entry; + struct stat st; + char buff[64]; + int len, fdfile, fdarchive; + DIR * dir; + struct dirent * ent; + char * filename, * path; + off_t pathlength = 0; + int8_t rc = EXIT_FAILURE; + + if ((rc = fdarchive = mkstemp(cpiotmpfile)) < 0) { + perror("mkstemp() failed"); + goto out10; + } + + if ((archive = archive_write_new()) == NULL) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_new() failed.\n"); + goto out10; + } + + if (archive_write_set_format_cpio_newc(archive) != ARCHIVE_OK) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_set_format_cpio_newc() failed.\n"); + goto out10; + } + + if (archive_write_open_fd(archive, fdarchive) != ARCHIVE_OK) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_open_fd() failed.\n"); + goto out10; + } + + if ((rc = add_dir(archive, ".")) < 0) { + fprintf(stderr, "add_dir() failed"); + goto out10; + } + + while (1) { + path = strdup(CHALLENGEDIR + 1); + if (strstr(path + pathlength, "/") == NULL) + break; + *strstr(path + pathlength, "/") = 0; + pathlength = strlen(path) + 1; + + if ((rc = add_dir(archive, path)) < 0) { + fprintf(stderr, "add_dir() failed"); + goto out10; + } + + free(path); + } + + if ((dir = opendir(CHALLENGEDIR)) != NULL) { + while ((ent = readdir(dir)) != NULL) { + filename = malloc(sizeof(CHALLENGEDIR) + strlen(ent->d_name) + 1); + sprintf(filename, CHALLENGEDIR "%s", ent->d_name); + + if ((rc = stat(filename, &st)) < 0) { + perror("stat() failed"); + goto out10; + } + + if (S_ISREG(st.st_mode)) { + if ((entry = archive_entry_new()) == NULL) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_entry_new() failed.\n"); + goto out10; + } + + /* these do not return exit code */ + archive_entry_set_pathname(entry, filename + 1); + archive_entry_set_size(entry, st.st_size); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_perm(entry, 0644); + + if (archive_write_header(archive, entry) != ARCHIVE_OK) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_header() failed"); + goto out10; + } + + if ((rc = fdfile = open(filename, O_RDONLY)) < 0) { + perror("open() failed"); + goto out10; + } + + if ((rc = len = read(fdfile, buff, sizeof(buff))) < 0) { + perror("read() failed"); + goto out10; + } + + while (len > 0) { + if (( rc = archive_write_data(archive, buff, len)) < 0) { + fprintf(stderr, "archive_write_data() failed"); + goto out10; + } + + if ((rc = len = read(fdfile, buff, sizeof(buff))) < 0) { + perror("read() failed"); + goto out10; + } + } + + if ((rc = close(fdfile)) < 0) { + perror("close() failed"); + goto out10; + } + + archive_entry_free(entry); + } + free(filename); + } + if ((rc = closedir(dir)) < 0) { + perror("closedir() failed"); + goto out10; + } + } else { + rc = EXIT_FAILURE; + perror("opendir() failed"); + goto out10; + } + + if (archive_write_close(archive) != ARCHIVE_OK) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_close() failed"); + goto out10; + } + + if (archive_write_free(archive) != ARCHIVE_OK) { + rc = EXIT_FAILURE; + fprintf(stderr, "archive_write_free() failed"); + goto out10; + } + + if (access(CPIOFILE, F_OK) == 0 && (rc = unlink(CPIOFILE)) < 0) { + perror("unkink() failed"); + goto out10; + } + + if ((rc = rename(cpiotmpfile, CPIOFILE)) < 0) { + perror("rename() failed"); + goto out10; + } + + rc = EXIT_SUCCESS; + +out10: + if (access(cpiotmpfile, F_OK) == 0) + unlink(cpiotmpfile); + + return rc; +} + +// vim: set syntax=c: diff --git a/bin/ykfde.c b/bin/ykfde.c index 43735d5..77bb86b 100644 --- a/bin/ykfde.c +++ b/bin/ykfde.c @@ -241,9 +241,8 @@ out60: close(challengefile); if (challengefiletmp) close(challengefiletmp); - if (access(challengefiletmpname, F_OK ) == 0 ) { + if (access(challengefiletmpname, F_OK) == 0 ) unlink(challengefiletmpname); - } out50: /* free crypt context */ -- cgit v1.2.3-54-g00ecf