summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-04-02 12:34:29 -0400
committerDave Brolley <brolley@redhat.com>2009-04-02 12:34:29 -0400
commit2f54c4fe5a3aa21b4d5c38edabf83f3cdad0177d (patch)
tree5ff9417c68651e345b5c82f9662d2d8d39a870f3
parentf5ccb20cd2a00649213270637161f0d68ffc0163 (diff)
downloadsystemtap-steved-2f54c4fe5a3aa21b4d5c38edabf83f3cdad0177d.tar.gz
systemtap-steved-2f54c4fe5a3aa21b4d5c38edabf83f3cdad0177d.tar.xz
systemtap-steved-2f54c4fe5a3aa21b4d5c38edabf83f3cdad0177d.zip
2009-04-02 Dave Brolley <brolley@redhat.com>
* stap-serverd (initialization): Create client certificate database if it does not exist. * stap-server (call_stap): Don't pass --sign-module to stap. * session.h (unprivileged): New member of systemtap_session. * modsign.cxx (init_cert_db_path, check_cert_db_path): New functions. (sign_module): Call check_cert_db_path. * main.cxx (usage): Document --signing-cert and --unprivileged. (runner): Set default signing certificate path. Initialize s.unprivileged. (LONG_OPT_SIGN_MODULE): Renamed to LONG_OPT_SIGNING_CERT. (LONG_OPT_UNPRIVILEGED): #define it. (long_options): Add --signing-cert and --unprivileged. (runner): Allow multiple --signing-cert options. Use the last specified. Don't reset unless the new setting is valid. Handle LONG_OPT_UNPRIVILEGED.
-rw-r--r--main.cxx49
-rw-r--r--modsign.cxx42
-rw-r--r--session.h1
-rwxr-xr-xstap-server2
-rwxr-xr-xstap-serverd5
5 files changed, 76 insertions, 23 deletions
diff --git a/main.cxx b/main.cxx
index ceabbac5..cde85226 100644
--- a/main.cxx
+++ b/main.cxx
@@ -133,6 +133,8 @@ usage (systemtap_session& s, int exitcode)
#ifdef HAVE_LIBSQLITE3
<< " -q generate information on tapset coverage" << endl
#endif /* HAVE_LIBSQLITE3 */
+ << " --unprivileged" << endl
+ << " restrict usage to features available to unprivileged users" << endl
#if 0 /* PR6864: disable temporarily; should merge with -d somehow */
<< " --kelf make do with symbol table from vmlinux" << endl
<< " --kmap[=FILE]" << endl
@@ -140,6 +142,8 @@ usage (systemtap_session& s, int exitcode)
#endif
// Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use
// only, and don't belong in the eyesight of a plain user.
+ << " --signing-cert=DIRECTORY" << endl
+ << " specify an alternate certificate database for module signing" << endl
<< " --skip-badvars" << endl
<< " overlook context of bad $ variables" << endl
<< endl
@@ -422,7 +426,6 @@ runner (int argc, char * const argv [])
s.output_file = ""; // -o FILE
s.keep_tmpdir = false;
s.cmd = "";
- s.cert_db_path = "";
s.target_pid = 0;
s.merge=true;
s.perfmon=0;
@@ -435,6 +438,15 @@ runner (int argc, char * const argv [])
s.ignore_dwarf = false;
s.load_only = false;
s.skip_badvars = false;
+ s.unprivileged = false;
+
+ // Default location for our signing certificate.
+ // If we're root, use the database in SYSCONFDIR, otherwise
+ // use the one in our $HOME directory. */
+ if (getuid() == 0)
+ s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
+ else
+ s.cert_db_path = getenv("HOME") + string ("/.systemtap/ssl/server");
const char* s_p = getenv ("SYSTEMTAP_TAPSET");
if (s_p != NULL)
@@ -494,7 +506,8 @@ runner (int argc, char * const argv [])
#define LONG_OPT_IGNORE_DWARF 4
#define LONG_OPT_VERBOSE_PASS 5
#define LONG_OPT_SKIP_BADVARS 6
-#define LONG_OPT_SIGN_MODULE 7
+#define LONG_OPT_SIGNING_CERT 7
+#define LONG_OPT_UNPRIVILEGED 8
// NB: also see find_hash(), usage(), switch stmt below, stap.1 man page
static struct option long_options[] = {
{ "kelf", 0, &long_opt, LONG_OPT_KELF },
@@ -503,7 +516,8 @@ runner (int argc, char * const argv [])
{ "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF },
{ "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS },
{ "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS },
- { "sign-module", 2, &long_opt, LONG_OPT_SIGN_MODULE },
+ { "signing-cert", 2, &long_opt, LONG_OPT_SIGNING_CERT },
+ { "unprivileged", 0, &long_opt, LONG_OPT_UNPRIVILEGED },
{ NULL, 0, NULL, 0 }
};
int grc = getopt_long (argc, argv, "hVMvtp:I:e:o:R:r:m:kgPc:x:D:bs:uqwl:d:L:FS:",
@@ -771,42 +785,33 @@ runner (int argc, char * const argv [])
case LONG_OPT_SKIP_BADVARS:
s.skip_badvars = true;
break;
- case LONG_OPT_SIGN_MODULE:
- if (!s.cert_db_path.empty())
- {
- cerr << "You can't specify multiple --sign-module options." << endl;
- usage(s, 1);
- }
+ case LONG_OPT_SIGNING_CERT:
#if HAVE_NSS
if (optarg)
{
- s.cert_db_path = optarg;
- string::size_type len = s.cert_db_path.length();
+ string arg = optarg;
+ string::size_type len = arg.length();
- // Make sure the name is not empty (i.e. --sign-module= )
+ // Make sure the name is not empty (i.e. --signing-cert= )
if (len == 0)
{
- cerr << "Certificate database directory name can not be empty." << endl;
+ cerr << "Certificate database directory name for --signing-cert can not be empty." << endl;
usage (s, 1);
}
+ s.cert_db_path = arg;
+
// Chop off any trailing '/'.
if (len > 1 && s.cert_db_path.substr(len - 1, 1) == "/")
s.cert_db_path.erase(len - 1);
}
- else
- {
- /* If we're root, use the database in SYSCONFDIR, otherwise
- use the one in our $HOME directory. */
- if (getuid() == 0)
- s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
- else
- s.cert_db_path = getenv("HOME") + string ("/.systemtap/ssl/server");
- }
#else
cerr << "WARNING: Module signing is disabled. The required nss libraries are not available." << endl;
#endif
break;
+ case LONG_OPT_UNPRIVILEGED:
+ s.unprivileged = true;
+ break;
default:
cerr << "Internal error parsing command arguments." << endl;
usage(s, 1);
diff --git a/modsign.cxx b/modsign.cxx
index 2154cdbb..c9307484 100644
--- a/modsign.cxx
+++ b/modsign.cxx
@@ -33,10 +33,49 @@ extern "C" {
#include <cryptohi.h>
#include <stdio.h>
+#include <stdlib.h>
}
using namespace std;
+/* Function: int init_cert_db_path (const string &cert_db_path);
+ *
+ * Initialize a certificate database at the given path.
+ */
+static int
+init_cert_db_path (const string &cert_db_path) {
+ string cmd = "stap-gen-cert " + cert_db_path;
+ return system (cmd.c_str()) == 0;
+}
+
+/* Function: int check_cert_db_path (const string &cert_db_path);
+ *
+ * Check that the given certificate directory exists and is initialized.
+ * Create and/or initialize it otherwise.
+ */
+static int
+check_cert_db_path (const string &cert_db_path) {
+ static const char* keyFiles[] = {
+ "cert8.db", "key3.db", "pw", "secmod.db", "stap-server.cert", NULL
+ };
+
+ // Does the path exist?
+ PRFileInfo fileInfo;
+ PRStatus prStatus = PR_GetFileInfo (cert_db_path.c_str(), &fileInfo);
+ if (prStatus != PR_SUCCESS || fileInfo.type != PR_FILE_DIRECTORY)
+ return init_cert_db_path (cert_db_path);
+
+ // Does it contain the key files?
+ for (int i = 0; keyFiles[i]; ++i) {
+ string fname = cert_db_path + "/" + keyFiles[i];
+ prStatus = PR_GetFileInfo (fname.c_str (), &fileInfo);
+ if (prStatus != PR_SUCCESS || fileInfo.type != PR_FILE_FILE || fileInfo.size < 0)
+ return init_cert_db_path (cert_db_path);
+ }
+
+ return 1; // ok
+}
+
/* Function: char * password_callback()
*
* Purpose: This function is our custom password handler that is called by
@@ -212,6 +251,9 @@ sign_module (systemtap_session& s)
SECKEYPrivateKey *privKey;
SECStatus secStatus;
+ if (! check_cert_db_path (s.cert_db_path))
+ return;
+
password = get_password (s.cert_db_path + "/pw");
if (! password)
{
diff --git a/session.h b/session.h
index 069368f0..0b687090 100644
--- a/session.h
+++ b/session.h
@@ -113,6 +113,7 @@ struct systemtap_session
bool tapset_compile_coverage;
bool need_uprobes;
bool load_only; // flight recorder mode
+ bool unprivileged;
// NB: It is very important for all of the above (and below) fields
// to be cleared in the systemtap_session ctor (elaborate.cxx)
diff --git a/stap-server b/stap-server
index d26eaff9..76130bb1 100755
--- a/stap-server
+++ b/stap-server
@@ -330,7 +330,7 @@ function call_stap {
server_p_phase=$p_phase
fi
- eval ${stap_exec_prefix}stap "$cmdline" --sign-module -k -p $server_p_phase \
+ eval ${stap_exec_prefix}stap "$cmdline" -k -p $server_p_phase \
>> $tmpdir_server/stdout \
2>> $tmpdir_server/stderr
diff --git a/stap-serverd b/stap-serverd
index 9b1dfd43..04ef54c3 100755
--- a/stap-serverd
+++ b/stap-serverd
@@ -47,6 +47,11 @@ function initialization {
if test -f `which ${stap_exec_prefix}stap-add-server-cert` -a -x `which ${stap_exec_prefix}stap-add-server-cert`; then
${stap_exec_prefix}stap-authorize-server-cert $ssl_db/stap-server.cert
fi
+ elif ! test -f $stap_ssl_db/client/cert8.db; then
+ # If the client's database does not exist, then initialize it with our certificate.
+ if test -f `which ${stap_exec_prefix}stap-add-server-cert` -a -x `which ${stap_exec_prefix}stap-add-server-cert`; then
+ ${stap_exec_prefix}stap-authorize-server-cert $ssl_db/stap-server.cert
+ fi
fi
fi