From 0811191a66e7ef63700c788087d575fe9887d053 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 30 Aug 2010 11:46:47 +0200
Subject: [PATCH 6/7] sss_obfuscate tool

A tool to add obfuscated passwords into the SSSD config file
---
 Makefile.am                 |   10 ++++-
 contrib/sssd.spec.in        |    1 +
 src/man/sss_obfuscate.8.xml |  113 +++++++++++++++++++++++++++++++++++++++++++
 src/tools/sss_obfuscate     |   81 +++++++++++++++++++++++++++++++
 4 files changed, 204 insertions(+), 1 deletions(-)
 create mode 100644 src/man/sss_obfuscate.8.xml
 create mode 100644 src/tools/sss_obfuscate

diff --git a/Makefile.am b/Makefile.am
index 1820164..d6aef7f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -406,6 +406,14 @@ sssd_be_LDFLAGS = \
     -Wl,--version-script,$(srcdir)/src/providers/sssd_be.exports \
     -export-dynamic
 
+if BUILD_PYTHON_BINDINGS
+sss_obfuscate_pythondir = $(sbindir)
+sss_obfuscate_python_PYTHON = \
+	src/tools/sss_obfuscate
+endif
+
+
+
 dist_noinst_DATA += \
     src/examples/sssd.conf \
     src/examples/sssdproxytest \
@@ -964,7 +972,7 @@ dist_man_MANS = \
     src/man/sssd.8 src/man/sssd.conf.5 src/man/sssd-ldap.5 \
     src/man/sssd-krb5.5 src/man/sssd-ipa.5 src/man/sssd-simple.5 \
     src/man/sssd_krb5_locator_plugin.8 src/man/sss_groupshow.8 \
-    src/man/pam_sss.8
+    src/man/pam_sss.8 src/man/sss_obfuscate.8
 
 SUFFIXES = .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8
 .1.xml.1:
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 0477f68..a26cf9d 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -169,6 +169,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_sbindir}/sss_groupdel
 %{_sbindir}/sss_groupmod
 %{_sbindir}/sss_groupshow
+%{_sbindir}/sss_obfuscate
 %{_libexecdir}/%{servicename}/
 %{_libdir}/%{name}/
 %{_libdir}/ldb/memberof.so
diff --git a/src/man/sss_obfuscate.8.xml b/src/man/sss_obfuscate.8.xml
new file mode 100644
index 0000000..55bb1c3
--- /dev/null
+++ b/src/man/sss_obfuscate.8.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<reference>
+<title>SSSD Manual pages</title>
+<refentry>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/upstream.xml" />
+
+    <refmeta>
+        <refentrytitle>sss_obfuscate</refentrytitle>
+        <manvolnum>8</manvolnum>
+    </refmeta>
+
+    <refnamediv id='name'>
+        <refname>sss_obfuscate</refname>
+        <refpurpose>obfuscate a clear text password</refpurpose>
+    </refnamediv>
+
+    <refsynopsisdiv id='synopsis'>
+        <cmdsynopsis>
+            <command>sss_obfuscate</command>
+            <arg choice='opt'>
+                <replaceable>options</replaceable>
+            </arg>
+            <arg choice='plain'><replaceable>[PASSWORD]</replaceable></arg>
+        </cmdsynopsis>
+    </refsynopsisdiv>
+
+    <refsect1 id='description'>
+        <title>DESCRIPTION</title>
+        <para>
+            <command>sss_obfuscate</command> converts a given password into
+            human-unreadable format and places it into appropriate domain
+            section of the SSSD config file.
+        </para>
+        <para>
+            The cleartext password can be specified as an extra argument to the
+            program or read from standard input.
+            The obfuscated password is put into <quote>ldap_default_authtok</quote>
+            parameter of a given SSSD domain and the
+            <quote>ldap_default_authtok_type</quote> parameter is set to
+            <quote>obfuscated_password</quote>. Refer to
+            <citerefentry>
+                <refentrytitle>sssd-ldap</refentrytitle>
+                <manvolnum>5</manvolnum>
+            </citerefentry>
+            for more details on these parameters.
+        </para>
+        <para>
+            Please note that obfuscating the password provides <emphasis>no
+            real security benefit</emphasis> as it is still possible for an
+            attacker to reverse-engineer the password back. Using better
+            authentication mechanisms such as client side certificates or GSSAPI
+            is <emphasis>strongly</emphasis> advised.
+        </para>
+    </refsect1>
+
+    <refsect1 id='options'>
+        <title>OPTIONS</title>
+        <variablelist remap='IP'>
+            <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/param_help.xml" />
+            <varlistentry>
+                <term>
+                    <option>-s</option>,<option>--stdin</option>
+                </term>
+                <listitem>
+                    <para>
+                        The password to obfuscate will be read from standard
+                        input.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-d</option>,<option>--domain</option>
+                    <replaceable>DOMAIN</replaceable>
+                </term>
+                <listitem>
+                    <para>
+                        The SSSD domain to use the password in. The
+                        default name is <quote>default</quote>.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-f</option>,<option>--file</option>
+                    <replaceable>FILE</replaceable>
+                </term>
+                <listitem>
+                    <para>
+                        Read the config file specified by the positional
+                        parameter.
+                    </para>
+                    <para>
+                        Default: <filename>/etc/sssd/sssd.conf</filename>
+                    </para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsect1>
+
+    <refsect1 id='see_also'>
+        <title>SEE ALSO</title>
+        <para>
+            <citerefentry>
+                <refentrytitle>sssd-ldap</refentrytitle>
+                <manvolnum>5</manvolnum>
+            </citerefentry>
+        </para>
+    </refsect1>
+</refentry>
+</reference>
diff --git a/src/tools/sss_obfuscate b/src/tools/sss_obfuscate
new file mode 100644
index 0000000..220cd9b
--- /dev/null
+++ b/src/tools/sss_obfuscate
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+
+import sys
+from optparse import OptionParser
+
+import pysss
+import SSSDConfig
+
+def parse_options():
+    parser = OptionParser()
+    parser.add_option("-s", "--stdin", action="store_true",
+                      dest="stdin", default=False,
+                      help="Read input from stdin")
+    parser.add_option("-d", "--domain",
+                      dest="domain", default="default",
+                      help="The domain to use the password in (default: default)",
+                      metavar="DOMNAME")
+    parser.add_option("-f", "--file",
+                      dest="filename", default=None,
+                      help="Set input file to FILE (default: Use system default, usually /etc/sssd/sssd.conf)",
+                      metavar="FILE")
+    (options, args) = parser.parse_args()
+
+    # If no password given as positional paramater, read up from stdin
+    if len(args) == 0:
+        options.stdin = True
+
+    return options, args
+
+def main():
+    options, args = parse_options()
+    if not options:
+        print >>sys.stderr, "Cannot parse options"
+        return 1
+
+    if not options.stdin:
+        try:
+            password = args[0]
+        except IndexError:  # should never happen
+            print "Missing password parameter!"
+            return 1
+    else:
+        try:
+            password = sys.stdin.read()
+        except KeyboardInterrupt:
+            return 1
+
+    # Obfuscate the password
+    obfobj = pysss.password()
+    obfpwd = obfobj.encrypt(password, obfobj.AES_256)
+
+    # Save the obfuscated password into the domain
+    sssdconfig = SSSDConfig.SSSDConfig()
+    try:
+        sssdconfig.import_config(options.filename)
+    except IOError:
+        print "Cannot open config file %s" % options.filename
+        return 1
+
+    try:
+        domain = sssdconfig.get_domain(options.domain)
+    except SSSDConfig.NoDomainError:
+        print "No such domain %s" % options.domain
+        return 1
+
+    try:
+        domain.set_option('ldap_default_authtok_type', 'obfuscated_password')
+        domain.set_option('ldap_default_authtok', obfpwd)
+    except SSSDConfig.NoOptionError:
+        print "The domain %s does not seem to support the required options" % \
+              options.domain
+        return 1
+
+
+    sssdconfig.save_domain(domain)
+    sssdconfig.write()
+    return 0
+
+if __name__ == "__main__":
+    ret = main()
+    sys.exit(ret)
-- 
1.7.2.2

