[lxc-devel] [PATCH 1/1] lxc_create: prepend pretty header to config file
Stéphane Graber
stgraber at ubuntu.com
Fri Jul 12 13:50:51 UTC 2013
On Thu, Jul 11, 2013 at 11:51:25PM -0500, Serge Hallyn wrote:
> 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(-)
Does the LXC license allow linking to OpenSSL?
Specifically we need the following bit in the license:
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
Details: https://people.gnome.org/~markmc/openssl-and-the-gpl.html
>
> 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
>
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130712/d5041b4b/attachment.pgp>
More information about the lxc-devel
mailing list