[lxc-devel] [PATCH 1/1] lxc_create: prepend pretty header to config file
Serge Hallyn
serge.hallyn at ubuntu.com
Fri Jul 12 04:51:25 UTC 2013
Define a sha1sum_file() function in utils.c (which requires configure.ac
to check for -lcrypto and -lssl). Use that in lxcapi_create to write out
the sha1sum of the template being used.
Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
configure.ac | 2 +
src/lxc/Makefile.am | 2 +-
src/lxc/lxccontainer.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++--
src/lxc/utils.c | 36 ++++++++++++++++
src/lxc/utils.h | 2 +
5 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4567001..a7de8c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,6 +105,8 @@ if test "$enable_apparmor" = "check" ; then
fi
AM_CONDITIONAL([ENABLE_APPARMOR], [test "x$enable_apparmor" = "xyes"])
+AC_CHECK_LIB([crypto], [EVP_get_digestbyname], [], AC_MSG_ERROR([You must install the ssl and crypto libraries]))
+
AM_COND_IF([ENABLE_APPARMOR],
[AC_CHECK_HEADER([sys/apparmor.h],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 18469a1..fa090c4 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -116,7 +116,7 @@ liblxc_so_LDFLAGS = \
-shared \
-Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION)))
-liblxc_so_LDADD = $(CAP_LIBS) $(APPARMOR_LIBS) $(SECCOMP_LIBS)
+liblxc_so_LDADD = $(CAP_LIBS) $(APPARMOR_LIBS) $(SECCOMP_LIBS) -lssl -lcrypto
bin_SCRIPTS = \
lxc-ps \
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 4ff9d35..4b26051 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -862,6 +862,102 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
return true;
}
+bool prepend_lxc_header(char *path, const char *t, char *const argv[])
+{
+ size_t flen;
+ char *contents, *tpath;
+ int i, md_len;
+ FILE *f;
+ unsigned char md_value[EVP_MAX_MD_SIZE];
+ bool have_tpath = false;
+
+ if ((f = fopen(path, "r")) == NULL) {
+ SYSERROR("Opening old config");
+ return false;
+ }
+ if (fseek(f, 0, SEEK_END) < 0) {
+ SYSERROR("Seeking to end of old config file");
+ fclose(f);
+ return false;
+ }
+ if ((flen = ftell(f)) < 0) {
+ SYSERROR("telling size of old config");
+ fclose(f);
+ return false;
+ }
+ if (fseek(f, 0, SEEK_SET) < 0) {
+ SYSERROR("rewinding old config");
+ fclose(f);
+ return false;
+ }
+ if ((contents = malloc(flen + 1)) == NULL) {
+ SYSERROR("out of memory");
+ fclose(f);
+ return false;
+ }
+ if (fread(contents, 1, flen, f) != flen) {
+ SYSERROR("Reading old config");
+ free(contents);
+ fclose(f);
+ return false;
+ }
+ contents[flen] = '\0';
+ if (fclose(f) < 0) {
+ SYSERROR("closing old config");
+ free(contents);
+ return false;
+ }
+
+ if ((tpath = get_template_path(t)) < 0) {
+ ERROR("bad template: %s\n", t);
+ free(contents);
+ return false;
+ }
+
+ if (tpath) {
+ have_tpath = true;
+ md_len = sha1sum_file(tpath, md_value);
+ free(tpath);
+ if (md_len < 0) {
+ free(contents);
+ return false;
+ }
+ }
+
+ if ((f = fopen(path, "w")) == NULL) {
+ SYSERROR("reopening config for writing");
+ free(contents);
+ return false;
+ }
+ fprintf(f, "# Template used to create this container: %s\n", t);
+ if (argv) {
+ fprintf(f, "# Parameters passed to the template:");
+ while (*argv) {
+ fprintf(f, " %s", *argv);
+ argv++;
+ }
+ fprintf(f, "\n");
+ }
+ if (have_tpath) {
+ fprintf(f, "# Template script checksum (SHA-1): ");
+ for (i=0; i<md_len; i++)
+ fprintf(f, "%02x", md_value[i]);
+ fprintf(f, "\n");
+ }
+ if (fwrite(contents, 1, flen, f) != flen) {
+ SYSERROR("Writing original contents");
+ free(contents);
+ fclose(f);
+ return false;
+ }
+ free(contents);
+ if (fclose(f) < 0) {
+ SYSERROR("Closing config file after write");
+ return false;
+ }
+ return true;
+}
+
static bool lxcapi_destroy(struct lxc_container *c);
/*
* lxcapi_create:
@@ -959,6 +1055,11 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
if (c->lxc_conf)
lxc_conf_free(c->lxc_conf);
c->lxc_conf = NULL;
+
+ if (!prepend_lxc_header(c->configfile, tpath, argv)) {
+ ERROR("Error prepending header to configuration file");
+ goto out_unlock;
+ }
bret = load_config_locked(c, c->configfile);
out_unlock:
@@ -1612,13 +1713,13 @@ static int update_name_and_paths(const char *path, struct lxc_container *oldc,
}
flen = ftell(f);
if (flen < 0) {
- fclose(f);
SYSERROR("telling size of old config");
+ fclose(f);
return -1;
}
if (fseek(f, 0, SEEK_SET) < 0) {
- fclose(f);
SYSERROR("rewinding old config");
+ fclose(f);
return -1;
}
contents = malloc(flen+1);
@@ -1628,15 +1729,15 @@ static int update_name_and_paths(const char *path, struct lxc_container *oldc,
return -1;
}
if (fread(contents, 1, flen, f) != flen) {
+ SYSERROR("reading old config");
free(contents);
fclose(f);
- SYSERROR("reading old config");
return -1;
}
contents[flen] = '\0';
if (fclose(f) < 0) {
- free(contents);
SYSERROR("closing old config");
+ free(contents);
return -1;
}
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 136f943..b595d13 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -36,6 +36,7 @@
#include <libgen.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <openssl/evp.h>
#include "log.h"
@@ -392,3 +393,38 @@ int lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected
}
return ret;
}
+
+int sha1sum_file(char *fnam, unsigned char *md_value)
+{
+ EVP_MD_CTX *mdctx;
+ const EVP_MD *md;
+ char *line = NULL;
+ size_t len = 0, ret;
+ FILE *f;
+
+ unsigned int md_len;
+
+ OpenSSL_add_all_digests();
+ md = EVP_get_digestbyname("sha1");
+ if(!md) {
+ ERROR("Unknown message digest sha1\n");
+ return -1;
+ }
+
+ if ((f = fopen(fnam, "r")) < 0) {
+ SYSERROR("failed to open %s", fnam);
+ return -1;
+ }
+
+ mdctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(mdctx, md, NULL);
+
+ while ((ret = getline(&line, &len, f)) != -1)
+ EVP_DigestUpdate(mdctx, line, ret);
+ EVP_DigestFinal_ex(mdctx, md_value, &md_len);
+ EVP_MD_CTX_destroy(mdctx);
+ fclose(f);
+ if (line)
+ free(line);
+ return (int) md_len;
+}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 063f76c..ffcd4e5 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -26,6 +26,7 @@
#include <errno.h>
#include <sys/types.h>
#include "config.h"
+#include <openssl/evp.h>
/* returns 1 on success, 0 if there were any failures */
extern int lxc_rmdir_onedev(char *path);
@@ -176,5 +177,6 @@ extern int lxc_wait_for_pid_status(pid_t pid);
extern int lxc_write_nointr(int fd, const void* buf, size_t count);
extern int lxc_read_nointr(int fd, void* buf, size_t count);
extern int lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf);
+extern int sha1sum_file(char *fnam, unsigned char *md_value);
#endif
--
1.7.9.5
More information about the lxc-devel
mailing list