The branch, master has been updated via 22af043 CVE-2013-4476: s4:libtls: check for safe permissions of tls private key file (key.pem) via e0248cd CVE-2013-4476: s4:libtls: Create tls private key file (key.pem) with mode 0600 via cf29fb2 CVE-2013-4476: selftest/Samba4: use umask 0077 within mk_keyblobs() via 83a3ae1 CVE-2013-4476: samba-tool provision: create ${private_dir}/tls with mode 0700 via 63d98ed CVE-2013-4476: lib-util: split out file_save_mode() from file_save() via 8eae8d2 CVE-2013-4476: lib-util: add file_check_permissions() from 374b2cf xattr: fix listing EAs on *BSD for non-root users
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 22af043d2f20760f27150d7d469c7c7b944c6b55 Author: Björn Baumbach <b...@sernet.de> Date: Tue Oct 29 17:53:59 2013 +0100 CVE-2013-4476: s4:libtls: check for safe permissions of tls private key file (key.pem) If the tls key is not owned by root or has not mode 0600 samba will not start up. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10234 Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Björn Baumbach <b...@sernet.de> Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Karolin Seeger <ksee...@samba.org> Autobuild-Date(master): Mon Nov 11 13:07:16 CET 2013 on sn-devel-104 commit e0248cde8dcd82f348218665f5edd6b30cd3ef1f Author: Björn Baumbach <b...@sernet.de> Date: Tue Oct 29 17:52:39 2013 +0100 CVE-2013-4476: s4:libtls: Create tls private key file (key.pem) with mode 0600 Bug: https://bugzilla.samba.org/show_bug.cgi?id=10234 Signed-off-by: Björn Baumbach <b...@sernet.de> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit cf29fb2cf4727466ccbd6f0ca8d5d4cb75666d99 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Oct 30 14:48:36 2013 +0100 CVE-2013-4476: selftest/Samba4: use umask 0077 within mk_keyblobs() We should generate private keys with 0600. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10234 Pair-Programmed-With: Björn Baumbach <b...@sernet.de> Signed-off-by: Stefan Metzmacher <me...@samba.org> Signed-off-by: Björn Baumbach <b...@sernet.de> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 83a3ae18ddb945defc3a2f1d5ca2fb743fa43724 Author: Björn Baumbach <b...@sernet.de> Date: Tue Oct 29 17:49:55 2013 +0100 CVE-2013-4476: samba-tool provision: create ${private_dir}/tls with mode 0700 Bug: https://bugzilla.samba.org/show_bug.cgi?id=10234 Signed-off-by: Björn Baumbach <b...@sernet.de> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 63d98ed90466295d0e946f79868d3d7aad6e7589 Author: Björn Baumbach <b...@sernet.de> Date: Tue Oct 29 17:48:11 2013 +0100 CVE-2013-4476: lib-util: split out file_save_mode() from file_save() file_save_mode() writes files with specified mode. Bug: https://bugzilla.samba.org/show_bug.cgi?id=10234 Signed-off-by: Björn Baumbach <b...@sernet.de> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 8eae8d28bce2c3f6a323d3dc48ed10c2e6bb1ba5 Author: Björn Baumbach <b...@sernet.de> Date: Tue Oct 29 17:43:17 2013 +0100 CVE-2013-4476: lib-util: add file_check_permissions() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10234 Signed-off-by: Björn Baumbach <b...@sernet.de> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/util/samba_util.h | 11 +++++++++ lib/util/util.c | 44 ++++++++++++++++++++++++++++++++++++ lib/util/util_file.c | 16 +++++++++---- python/samba/provision/__init__.py | 2 +- selftest/target/Samba4.pm | 6 ++++- source4/lib/tls/tls.c | 17 ++++++++++++++ source4/lib/tls/tls_tstream.c | 16 +++++++++++++ source4/lib/tls/tlscert.c | 2 +- 8 files changed, 106 insertions(+), 8 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index 89aa9aa..243ed3e 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -580,6 +580,8 @@ a line **/ _PUBLIC_ void file_lines_slashcont(char **lines); +_PUBLIC_ bool file_save_mode(const char *fname, const void *packet, + size_t length, mode_t mode); /** save a lump of data into a file. Mostly used for debugging */ @@ -623,6 +625,15 @@ _PUBLIC_ time_t file_modtime(const char *fname); _PUBLIC_ bool directory_exist(const char *dname); /** + Check file permissions. +**/ +struct stat; +_PUBLIC_ bool file_check_permissions(const char *fname, + uid_t uid, + mode_t file_perms, + struct stat *pst); + +/** * Try to create the specified directory if it didn't exist. * * @retval true if the directory already existed and has the right permissions diff --git a/lib/util/util.c b/lib/util/util.c index f0ed7f6..3e9047c 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -122,6 +122,50 @@ _PUBLIC_ time_t file_modtime(const char *fname) } /** + Check file permissions. +**/ + +_PUBLIC_ bool file_check_permissions(const char *fname, + uid_t uid, + mode_t file_perms, + struct stat *pst) +{ + int ret; + struct stat st; + + if (pst == NULL) { + pst = &st; + } + + ZERO_STRUCTP(pst); + + ret = stat(fname, pst); + if (ret != 0) { + DEBUG(0, ("stat failed on file '%s': %s\n", + fname, strerror(errno))); + return false; + } + + if (pst->st_uid != uid && !uwrap_enabled()) { + DEBUG(0, ("invalid ownership of file '%s': " + "owned by uid %u, should be %u\n", + fname, (unsigned int)pst->st_uid, + (unsigned int)uid)); + return false; + } + + if ((pst->st_mode & 0777) != file_perms) { + DEBUG(0, ("invalid permissions on file " + "'%s': has 0%o should be 0%o\n", fname, + (unsigned int)(pst->st_mode & 0777), + (unsigned int)file_perms)); + return false; + } + + return true; +} + +/** Check if a directory exists. **/ diff --git a/lib/util/util_file.c b/lib/util/util_file.c index e031fc5..815cc2b 100644 --- a/lib/util/util_file.c +++ b/lib/util/util_file.c @@ -368,13 +368,11 @@ _PUBLIC_ void file_lines_slashcont(char **lines) } } -/** - save a lump of data into a file. Mostly used for debugging -*/ -_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length) +_PUBLIC_ bool file_save_mode(const char *fname, const void *packet, + size_t length, mode_t mode) { int fd; - fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644); + fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, mode); if (fd == -1) { return false; } @@ -386,6 +384,14 @@ _PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length) return true; } +/** + save a lump of data into a file. Mostly used for debugging +*/ +_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length) +{ + return file_save_mode(fname, packet, length, 0644); +} + _PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap) { char *p; diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py index d8f353f..4920735 100644 --- a/python/samba/provision/__init__.py +++ b/python/samba/provision/__init__.py @@ -2025,7 +2025,7 @@ def provision(logger, session_info, smbconf=None, if not os.path.exists(paths.private_dir): os.mkdir(paths.private_dir) if not os.path.exists(os.path.join(paths.private_dir, "tls")): - os.mkdir(os.path.join(paths.private_dir, "tls")) + os.makedirs(os.path.join(paths.private_dir, "tls"), 0700) if not os.path.exists(paths.state_dir): os.mkdir(paths.state_dir) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 646ac73..96d1657 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -258,7 +258,9 @@ sub mk_keyblobs($$) my $admincertfile = "$tlsdir/admincert.pem"; my $admincertupnfile = "$tlsdir/admincertupn.pem"; - mkdir($tlsdir, 0777); + mkdir($tlsdir, 0700); + my $oldumask = umask; + umask 0077; #This is specified here to avoid draining entropy on every run open(DHFILE, ">$dhfile"); @@ -449,6 +451,8 @@ Zd7J9s//rNFNa7waklFkDaY56+QWTFtdvxfE+KoHaqt6X8u6pqi7p3M4wDKQox+9Dx8yWFyq Wfz/8alZ5aMezCQzXJyIaJsCLeKABosSwHcpAFmxlQ== -----END CERTIFICATE----- EOF + + umask $oldumask; } sub provision_raw_prepare($$$$$$$$$$) diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c index db6d1eb..9a3e610 100644 --- a/source4/lib/tls/tls.c +++ b/source4/lib/tls/tls.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "lib/events/events.h" #include "lib/socket/socket.h" #include "lib/tls/tls.h" @@ -369,6 +370,7 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context * { struct tls_params *params; int ret; + struct stat st; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx); const char *certfile = lpcfg_tls_certfile(tmp_ctx, lp_ctx); @@ -399,6 +401,21 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context * talloc_free(hostname); } + if (file_exist(keyfile) && + !file_check_permissions(keyfile, geteuid(), 0600, &st)) + { + DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n" + "owner uid %u should be %u, mode 0%o should be 0%o\n" + "This is known as CVE-2013-4476.\n" + "Removing all tls .pem files will cause an " + "auto-regeneration with the correct permissions.\n", + keyfile, + (unsigned int)st.st_uid, geteuid(), + (unsigned int)(st.st_mode & 0777), 0600)); + talloc_free(tmp_ctx); + return NULL; + } + ret = gnutls_global_init(); if (ret < 0) goto init_failed; diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c index 6bb68fb..2cb75ed 100644 --- a/source4/lib/tls/tls_tstream.c +++ b/source4/lib/tls/tls_tstream.c @@ -19,6 +19,7 @@ #include "includes.h" #include "system/network.h" +#include "system/filesys.h" #include "../util/tevent_unix.h" #include "../lib/tsocket/tsocket.h" #include "../lib/tsocket/tsocket_internal.h" @@ -1083,6 +1084,7 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, struct tstream_tls_params *tlsp; #if ENABLE_GNUTLS int ret; + struct stat st; if (!enabled || key_file == NULL || *key_file == 0) { tlsp = talloc_zero(mem_ctx, struct tstream_tls_params); @@ -1110,6 +1112,20 @@ NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx, key_file, cert_file, ca_file); } + if (file_exist(key_file) && + !file_check_permissions(key_file, geteuid(), 0600, &st)) + { + DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n" + "owner uid %u should be %u, mode 0%o should be 0%o\n" + "This is known as CVE-2013-4476.\n" + "Removing all tls .pem files will cause an " + "auto-regeneration with the correct permissions.\n", + key_file, + (unsigned int)st.st_uid, geteuid(), + (unsigned int)(st.st_mode & 0777), 0600)); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred); if (ret != GNUTLS_E_SUCCESS) { DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c index 0c780ea..8a19e0a 100644 --- a/source4/lib/tls/tlscert.c +++ b/source4/lib/tls/tlscert.c @@ -152,7 +152,7 @@ void tls_cert_generate(TALLOC_CTX *mem_ctx, bufsize = sizeof(buf); TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize)); - if (!file_save(keyfile, buf, bufsize)) { + if (!file_save_mode(keyfile, buf, bufsize, 0600)) { DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile)); goto failed; } -- Samba Shared Repository