Module: check_mk
Branch: master
Commit: df61d05214b6d200bbbf9ef4c3bb759aadef3c68
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=df61d05214b6d2…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Wed Jul 20 09:57:29 2016 +0200
Several fixex and minor improvements to current password store implementation;
---
bin/.f12 | 2 +-
bin/{pwquery.sh => pwquery} | 2 +-
checks/check_http | 7 ++---
lib/passwordstore.py | 2 +-
web/htdocs/valuespec.py | 49 +++++++++++++++++++++++----------
web/htdocs/wato.py | 3 ++
web/plugins/userdb/user_attributes.py | 21 +++++++++-----
7 files changed, 56 insertions(+), 30 deletions(-)
diff --git a/bin/.f12 b/bin/.f12
index f9f022e..5b9bf09 100644
--- a/bin/.f12
+++ b/bin/.f12
@@ -4,7 +4,7 @@ SITE=${SITE:-$(omd sites --bare | head -n 1)}
OMD_ROOT=/omd/sites/${SITE}
make
-sudo install -m 755 mkeventd mkeventd_open514 mkevent mkbackup $OMD_ROOT/bin/
+sudo install -m 755 mkeventd mkeventd_open514 mkevent mkbackup pwquery $OMD_ROOT/bin/
sudo chown root.omd $OMD_ROOT/bin/mkeventd_open514
sudo chmod 4750 $OMD_ROOT/bin/mkeventd_open514
echo "Installed to $OMD_ROOT/bin"
diff --git a/bin/pwquery.sh b/bin/pwquery
similarity index 94%
rename from bin/pwquery.sh
rename to bin/pwquery
index 86d5f36..10b6124 100755
--- a/bin/pwquery.sh
+++ b/bin/pwquery
@@ -9,7 +9,7 @@ shift
export PYTHONPATH=$OMD_ROOT/lib/python:$OMD_ROOT/local/lib/python
$OMD_ROOT/bin/python $OMD_ROOT/lib/python/cmk/passwordstore.py\
- --get $1 --user $2\
+ --get $1\
--keydir $OMD_ROOT/var/check_mk/private_keys\
--file $OMD_ROOT/var/check_mk/passwords.json
diff --git a/checks/check_http b/checks/check_http
index 0f8a4f8..7ac64b6 100644
--- a/checks/check_http
+++ b/checks/check_http
@@ -96,16 +96,13 @@ def check_http_arguments(params):
if "auth" in settings:
user, password = settings["auth"]
if password.startswith("store:"):
- group, password = password[6:].split(":", 1)
- args += ' -a %s:%s --password-store %s' %\
- (quote_shell_string(user), quote_shell_string(password),
- quote_shell_string(group))
+ args += ' -a %s --password-store' % (quote_shell_string(user + ":" + password[6:]))
else:
if password.startswith("imm:"):
password = password[4:]
# else: assume that a password that starts with neither store nor imm is from an old
# configuration and has no prefix
- args += ' -a %s:%s' % (quote_shell_string(user), quote_shell_string(password))
+ args += ' -a %s' % quote_shell_string(user + ":" + password)
if "proxy_auth" in settings:
auth = settings["proxy_auth"]
diff --git a/lib/passwordstore.py b/lib/passwordstore.py
index a1b27c8..e09e6e4 100644
--- a/lib/passwordstore.py
+++ b/lib/passwordstore.py
@@ -564,7 +564,7 @@ def do_action(store, args):
logging.info("key \"%s\" set with owner \"%s\"", args.set[0], args.user)
elif args.get is not None:
try:
- print(store.get(args.get, args.user))
+ sys.stdout.write(store.get(args.get, args.user))
except NotAuthorizedException:
logging.warn("User \"%s\" isn't authorized to retrive \"%s\"",
args.user, args.get)
diff --git a/web/htdocs/valuespec.py b/web/htdocs/valuespec.py
index cb912e7..fce02f1 100644
--- a/web/htdocs/valuespec.py
+++ b/web/htdocs/valuespec.py
@@ -3373,6 +3373,8 @@ class PasswordSpec(TextAscii):
html.icon_button("#", _(u"Show/Hide password"), "showhide",
onclick="vs_toggle_hidden(this);")
+
+
class PasswordFromStore(Alternative):
def __init__(self, **kwargs):
kwargs["elements"] = [
@@ -3391,6 +3393,7 @@ class PasswordFromStore(Alternative):
)
Alternative.__init__(self, **kwargs)
+
def __stored_passwords(self):
from cmk.passwordstore import CryptoBackend, PasswordStore, NonePasswordProvider
backend = CryptoBackend(defaults.var_dir + "/private_keys", NonePasswordProvider())
@@ -3400,48 +3403,64 @@ class PasswordFromStore(Alternative):
with PasswordStore(defaults.var_dir + "/passwords.json", backend) as store:
return store.list(with_details=True)
+
def matching_alternative(self, value):
if value.startswith("store:") and len(self._elements) > 1:
- return self._elements[1], value.split(':', 2)[2]
+ return self._elements[1], value.split(':', 1)[1]
elif value.startswith("imm:"):
return self._elements[0], value.split(':', 1)[1]
else:
return self._elements[0], value
+
def value_to_text(self, value):
return value.split(':', 1)[1]
+
def validate_datatype(self, value, varprefix):
- return Alternative.validate_datatype(self, value.split(':', 2)[2], varprefix)
+ mvs, value = self.matching_alternative(value)
+ return Alternative.validate_datatype(self, value, varprefix)
+
- def __find_contactgroup(self, value, varprefix):
+ def __get_password_by_key(self, value, varprefix):
for pw in self.__passwords:
if pw['key'] == value:
- import config, userdb
- for group in userdb.contactgroups_of_user(config.user_id):
- if "group:" + group in pw['shared']:
- return group
- raise MKUserError(varprefix,
- _("You don't belong to a contact group with access to "
- "password key %s") % value)
- raise MKUserError(varprefix, _("Unknown password key %s") % value)
+ return pw
+ raise MKUserError(varprefix, _("Unknown password key: %s") % value)
+
+
+ def __may_use_password(self, key, varprefix):
+ import config, userdb
+ pw = self.__get_password_by_key(key, varprefix)
+
+ if pw["owner"] == "user:" + config.user_id:
+ return # the users password
+
+ for group in userdb.contactgroups_of_user(config.user_id):
+ if "group:" + group in pw['shared']:
+ return group # is shared with a users group
+
+ raise MKUserError(varprefix, _("You don't have permission to use the password with "
+ "the key \"%s\", shared by user %s.") % (key, pw["owner"][5:]))
+
def validate_value(self, value, varprefix):
- prefix, group, val = value.split(':', 2)
+ prefix, val = value.split(':', 1)
if prefix == "store":
# couldn't check user permission before, but now I can
- self.__find_contactgroup(val, varprefix)
+ self.__may_use_password(val, varprefix)
else:
return Alternative.validate_value(self, val, varprefix)
+
def from_html_vars(self, varprefix):
nr = int(html.var(varprefix + "_use"))
if nr == 0:
return "imm:" + Alternative.from_html_vars(self, varprefix)
else:
key = Alternative.from_html_vars(self, varprefix)
- group = self.__find_contactgroup(key, varprefix)
- return ":".join(["store", group, key])
+ return ":".join(["store", key])
+
class FileUpload(ValueSpec):
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 047eca3..f44ae87 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -10917,6 +10917,9 @@ def mode_edit_user(phase):
select_language(user)
custom_user_attributes('personal')
+ forms.header(_("Password Store"), isopen = False)
+ custom_user_attributes("password_store")
+
# Later we could add custom macros here, which then could be used
# for notifications. On the other hand, if we implement some check_mk
# --notify, we could directly access the data in the account with the need
diff --git a/web/plugins/userdb/user_attributes.py b/web/plugins/userdb/user_attributes.py
index 805613a..a1a1694 100644
--- a/web/plugins/userdb/user_attributes.py
+++ b/web/plugins/userdb/user_attributes.py
@@ -87,22 +87,29 @@ declare_user_attribute(
"passwords",
ListOf(
Dictionary(
- title = _("Password Store"),
elements = [
("key", TextAscii(title=_("Key"))),
("secret", PasswordSpec(title=_("Password"), allow_empty=True, hidden=True)),
- ('contactgroups', ListChoice(
- title = _('Share with Contact groups'),
- help = _('Specify the contact groups that may access the password.'),
+ ("contactgroups", ListChoice(
+ title = _("Share with contact groups"),
+ help = _("By default you are the only user that can configure checks to use "
+ "your configured passwords. It is possible to share a password with "
+ "a group of users to make them able to use a password in checks."),
default_value = [],
choices = list_contactgroups,
))
],
optional_keys=[]
),
- title = _("Password"),
- add_label = _("Add Password")
+ title = _("Password Store"),
+ add_label = _("Add Password"),
+ help = _("The password store is used to store multiple passwords per user which can then "
+ "be used by Check_MK during checking. The passwords are stored in encrypted form, "
+ "so that they can not be read by other users in clear text. They can be decrypted "
+ "by Check_MK during monitoring to hand over them to checks for authentification "
+ "with the monitoringed systems."),
),
- domain = "passwords"
+ domain = "multisite",
+ topic = "password_store",
)
Module: check_mk
Branch: master
Commit: 8dccfef293d94b7d8576d67034c585cb531aa79b
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=8dccfef293d94b…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Tue Jul 19 16:01:37 2016 +0200
Fixed typo
---
web/htdocs/key_mgmt.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/web/htdocs/key_mgmt.py b/web/htdocs/key_mgmt.py
index 4474549..e35023d 100644
--- a/web/htdocs/key_mgmt.py
+++ b/web/htdocs/key_mgmt.py
@@ -448,9 +448,9 @@ class PageDownloadKey(object):
def page(self):
html.write("<p>%s</p>" %
- _("To be able to download the passphrase, you need to unlock the key by entering the "
+ _("To be able to download the key, you need to unlock the key by entering the "
"passphrase. This is only done to verify that you are allowed to download the key. "
- "The key will be downloaded encrypted form."))
+ "The key will be downloaded in encrypted form."))
html.begin_form("key", method="POST")
html.prevent_password_auto_completion()
self._vs_key().render_input("key", {})
Module: check_mk
Branch: master
Commit: 77530e677e33b12b165df7982615484467335ce9
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=77530e677e33b1…
Author: Sven Rueß <sr(a)mathias-kettner.de>
Date: Tue Jul 19 14:14:37 2016 +0200
2241 check_mk_agent.openwrt: Added section for local scripts and plugins
Added missing sections for local script and plugins.
The agent supports the same information, except the following sections:
<ul>
<li>VirtualBox Guests</li>
<li>MK's Remote Plugin Executor</li>
<li>MK's runas Executor</li>
</ul>
Addional the Agent is missing following features:
<ul>
<li>Agent based encryption</li>
</ul>
---
.werks/2241 | 21 +++++++++
ChangeLog | 1 +
agents/check_mk_agent.openwrt | 98 +++++++++++++++++++++++++++++++++++------
3 files changed, 107 insertions(+), 13 deletions(-)
diff --git a/.werks/2241 b/.werks/2241
new file mode 100644
index 0000000..8e66644
--- /dev/null
+++ b/.werks/2241
@@ -0,0 +1,21 @@
+Title: check_mk_agent.openwrt: Added section for local scripts and plugins
+Level: 1
+Component: checks
+Compatible: compat
+Version: 1.4.0i1
+Date: 1468929868
+Class: feature
+
+Added missing sections for local script and plugins.
+
+The agent supports the same information, except the following sections:
+<ul>
+ <li>VirtualBox Guests</li>
+ <li>MK's Remote Plugin Executor</li>
+ <li>MK's runas Executor</li>
+</ul>
+
+Addional the Agent is missing following features:
+<ul>
+ <li>Agent based encryption</li>
+</ul>
diff --git a/ChangeLog b/ChangeLog
index cea99fd..d948592 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -117,6 +117,7 @@
* 3558 check_mail: now able to process mail body with Content-Transfer-Encoding base64...
* 3695 f5_bigip_cluster_v11: Now WATO configurable...
NOTE: Please refer to the migration notes!
+ * 2241 check_mk_agent.openwrt: Added section for local scripts and plugins...
* 3073 FIX: windows agent: relative paths to mrpe scripts are now treated as relative to the agent installation directory...
* 3061 FIX: mk_jolokia: Fixed debugging of the agent plugin
* 3074 FIX: windows agent: fixed incorrect values for 32-bit performance counters
diff --git a/agents/check_mk_agent.openwrt b/agents/check_mk_agent.openwrt
index 8c9acd9..7de8a06 100755
--- a/agents/check_mk_agent.openwrt
+++ b/agents/check_mk_agent.openwrt
@@ -1,5 +1,5 @@
#!/bin/ash
-# Check_MK Agent for Linux
+# Check_MK Agent for OpenWRT
# +------------------------------------------------------------------+
# | ____ _ _ __ __ _ __ |
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
@@ -119,8 +119,10 @@ run_cached () {
local NOW=$(date +%s)
local section=
local mrpe=0
+ local append_age=0
if [ "$1" = -s ] ; then local section="echo '<<<$2:cached($NOW,$3)>>>' ; " ; shift ; fi
if [ "$1" = -m ] ; then local mrpe=1 ; shift ; fi
+ if [ "$1" = -a ] ; then local append_age=1 ; shift ; fi
local NAME=$1
local MAXAGE=$2
shift 2
@@ -145,14 +147,23 @@ run_cached () {
# Check if cache file exists and is recent enough
if [ -s "$CACHEFILE" ] ; then
local MTIME=$(stat -c %Y "$CACHEFILE")
- if [ $((NOW - MTIME)) -le $MAXAGE ] ; then local USE_CACHEFILE=1 ; fi
+ local AGE=$((NOW - MTIME))
+ if [ $AGE -le $MAXAGE ] ; then local USE_CACHEFILE=1 ; fi
# Output the file in any case, even if it is
# outdated. The new file will not yet be available
- cat "$CACHEFILE"
+ if [ $append_age -eq 1 ] ; then
+ # insert the cached-string before the pipe (first -e)
+ # or, if no pipe found (-e t) append it (third -e),
+ # but only once and on the second line (2!b) (first line is section header,
+ # all further lines are long output)
+ cat "$CACHEFILE" | sed -e "2s/|/ (Cached: ${AGE}\/${MAXAGE}s)|/" -e t -e "2s/$/ (Cached: ${AGE}\/${MAXAGE}s)/"
+ else
+ cat "$CACHEFILE"
+ fi
fi
# Cache file outdated and new job not yet running? Start it
- if [ -z "$USE_CACHEFILE" -a ! -e "$CACHEFILE.new" ] ; then
+ if [ -z "$USE_CACHEFILE" ] && [ ! -e "$CACHEFILE.new" ] ; then
# When the command fails, the output is throws away ignored
if [ $mrpe -eq 1 ] ; then
echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; run_mrpe $NAME $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup bash >/dev/null 2>&1 &
@@ -172,6 +183,11 @@ run_real_time_checks()
. $MK_CONFDIR/real_time_checks.cfg
+ if [ "$PASSPHRASE" != "" ] ; then
+ # new mechanism to set the passphrase has priority
+ RTC_SECRET=$PASSPHRASE
+ fi
+
while true; do
# terminate when pidfile is gone or other Real-Time Check process started or configured timeout
if [ ! -e $PIDFILE ] || [ $(<$PIDFILE) -ne $$ ] || [ $RTC_TIMEOUT -eq 0 ]; then
@@ -179,13 +195,22 @@ run_real_time_checks()
fi
for SECTION in $RTC_SECTIONS; do
+ if [ "$ENCRYPTED_RT" != "no" ] ; then
+ PROTOCOL=00
+ else
+ PROTOCOL=99
+ fi
# Be aware of maximum packet size. Maybe we need to check the size of the section
# output and do some kind of nicer error handling.
# 2 bytes: protocol version, 10 bytes: timestamp, rest: encrypted data
# dd is used to concatenate the output of all commands to a single write/block => udp packet
- { echo -n 00 ;
+ { echo -n $PROTOCOL ;
date +%s | tr -d '\n' ;
- export RTC_SECRET=$RTC_SECRET ; section_$SECTION | openssl enc -aes-256-cbc -pass env:RTC_SECRET -nosalt ;
+ if [ "$ENCRYPTED_RT" != "no" ] ; then
+ export RTC_SECRET=$RTC_SECRET ; section_$SECTION | openssl enc -aes-256-cbc -pass env:RTC_SECRET -nosalt ;
+ else
+ section_$SECTION ;
+ fi
} | dd bs=9999 iflag=fullblock 2>/dev/null >/dev/udp/$REMOTE/$RTC_PORT
done
@@ -195,8 +220,8 @@ run_real_time_checks()
}
echo '<<<check_mk>>>'
-echo Version: 1.2.8b7
-echo AgentOS: linux
+echo Version: 1.4.0i1
+echo AgentOS: openwrt
echo Hostname: $HOSTNAME
echo AgentDirectory: $MK_CONFDIR
echo DataDirectory: $MK_VARDIR
@@ -295,7 +320,6 @@ section_cpu
echo '<<<uptime>>>'
cat /proc/uptime
-
# New variant: Information about speed and state in one section
if type ip > /dev/null
then
@@ -334,7 +358,6 @@ if type ovs-appctl > /dev/null ; then
done
fi
-
# Number of TCP connections in the various states
echo '<<<tcp_conn_stats>>>'
cat /proc/net/tcp /proc/net/tcp6 2>/dev/null | awk ' /:/ { c[$4]++; } END { for (x in c) { print x, c[x]; } }'
@@ -368,7 +391,9 @@ cat /proc/vmstat /proc/stat
# Hardware sensors via IPMI (need ipmitool)
if type ipmitool > /dev/null
then
- run_cached -s ipmi 300 "waitmax 300 ipmitool sensor list | grep -v 'command failed' | sed -e 's/ *| */|/g' -e 's/ /_/g' -e 's/_*"'$'"//' -e 's/|/ /g' | egrep -v '^[^ ]+ na ' | grep -v ' discrete '"
+ run_cached -s "ipmi:sep(124)" 300 "waitmax 300 ipmitool sensor list | grep -v 'command failed' | egrep -v '^[^ ]+ na ' | grep -v ' discrete '"
+ # readable discrete sensor states
+ run_cached -s "ipmi_discrete:sep(124)" 300 "waitmax 300 ipmitool sdr elist compact"
fi
# IPMI data via ipmi-sensors (of freeipmi). Please make sure, that if you
@@ -628,7 +653,6 @@ if type zpool >/dev/null; then
zpool status -x
fi
-
# Veritas Cluster Server
# Software is always installed in /opt/VRTSvcs.
# Secure mode must be off to allow root to execute commands
@@ -642,7 +666,6 @@ then
hares -display -sys $vcshost -attribute State -localclus
fi
-
# Fileinfo-Check: put patterns for files into /etc/check_mk/fileinfo.cfg
if [ -r "$MK_CONFDIR/fileinfo.cfg" ] ; then
echo '<<<fileinfo:sep(124)>>>'
@@ -710,6 +733,20 @@ if type trd >/dev/null; then
trd -s
fi
+# HTTP Accelerator Statistics
+if type varnishstat >/dev/null; then
+ echo "<<<varnish>>>"
+ varnishstat -1
+fi
+
+# Proxmox Cluster
+if type pvecm > /dev/null 2>&1 ; then
+ echo "<<<pvecm_status:sep(58)>>>"
+ pvecm status
+ echo "<<<pvecm_nodes>>>"
+ pvecm nodes
+fi
+
# Start new liveupdate process in background on each agent execution. Starting
# a new live update process will terminate the old one automatically after
# max. 1 sec.
@@ -723,6 +760,41 @@ if [ -e $MK_CONFDIR/real_time_checks.cfg ]; then
fi
fi
+is_valid_plugin () {
+ [[ -f "$1" && -x "$1" ]] && true || false
+}
+
+# Local checks
+echo '<<<local>>>'
+if cd $LOCALDIR ; then
+ for skript in $(ls) ; do
+ if is_valid_plugin "$skript" ; then
+ ./$skript
+ fi
+ done
+ # Call some plugins only every X'th second
+ for skript in [1-9]*/* ; do
+ if is_valid_plugin "$skript" ; then
+ run_cached local_${skript//\//\\} ${skript%/*} "$skript"
+ fi
+ done
+fi
+
+# Plugins
+if cd $PLUGINSDIR ; then
+ for skript in $(ls) ; do
+ if is_valid_plugin "$skript" ; then
+ ./$skript
+ fi
+ done
+ # Call some plugins only every Xth second
+ for skript in [1-9]*/* ; do
+ if is_valid_plugin "$skript" ; then
+ run_cached plugins_${skript//\//\\} ${skript%/*} "$skript"
+ fi
+ done
+fi
+
# Agent output snippets created by cronjobs, etc.
if [ -d "$SPOOLDIR" ]
then
Module: check_mk
Branch: master
Commit: 87bb5cba91804e486d6b55754296e5c76fe0e7d9
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=87bb5cba91804e…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Tue Jul 19 11:58:51 2016 +0200
Updated bug entries #2499
---
.bugs/2499 | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/.bugs/2499 b/.bugs/2499
new file mode 100644
index 0000000..1ffc8e1
--- /dev/null
+++ b/.bugs/2499
@@ -0,0 +1,19 @@
+Title: Error in check plugins breaks automation for package info
+Component: core
+State: open
+Date: 2016-07-19 11:56:45
+Targetversion: future
+Class: nastiness
+
+I did:
+
+1. Installed an MKP via WATO
+2. Dissolved the files
+3. Manually began to delete one after the other
+
+As soon as I've deleted some foo.include - the automation for the package
+information would stop working sind load_checks() in check_mk.py unconditionally
+exists (sys.exit(5)) when a check plugin cannot be loaded.
+
+Better output just a warning and suppress this warning when in
+automation mode.