summaryrefslogtreecommitdiffstats
path: root/apachekerbauth/var/www/cgi-bin
diff options
context:
space:
mode:
authorPrashanth Pai <ppai@redhat.com>2013-09-23 11:47:21 +0530
committerPrashanth Pai <ppai@redhat.com>2013-09-23 11:57:31 +0530
commitaf2cbe8a5bec2b7971de137416d6e62ac1b96498 (patch)
tree42de6bfc2b380f27512956a7c0392ede9e0889e1 /apachekerbauth/var/www/cgi-bin
parent728157e52fe3212d50edfc17fcd72e1aaf9a6e76 (diff)
Minor swiftkerbauth changes
* Replaced python-webob with swift.common.swob * Use swift memcached instead of python memcached * Added optional debugging headers to swift-auth script * Swiftkerbauth and Apachekerbauth are now a single RPM * Updates to httpd conf file to specify Kerberos principal * Added setupy.py, makerpm.sh, .gitignore and MANIFEST.in * RPM is now generated by bdist_rpm using setup.py and not from spec files TODO -> Documentation changes in doc/ * Steps to setup kerberos environment * Swiftkerbauth usage and examples -> Testing swiftkerbauth * Investigate borrowing tests from tempauth.py and its dependencies * Write a python client script to test swiftkerbauth Signed-off-by: Prashanth Pai <ppai@redhat.com>
Diffstat (limited to 'apachekerbauth/var/www/cgi-bin')
-rwxr-xr-xapachekerbauth/var/www/cgi-bin/swift-auth123
1 files changed, 123 insertions, 0 deletions
diff --git a/apachekerbauth/var/www/cgi-bin/swift-auth b/apachekerbauth/var/www/cgi-bin/swift-auth
new file mode 100755
index 0000000..6173408
--- /dev/null
+++ b/apachekerbauth/var/www/cgi-bin/swift-auth
@@ -0,0 +1,123 @@
+#!/usr/bin/python
+
+# Copyright (c) 2013 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Requires the following command to be run:
+# setsebool -P httpd_can_network_connect 1
+# setsebool -P httpd_can_network_memcache 1
+
+import cgi
+from swift.common.memcached import MemcacheRing
+import os
+import grp
+import random
+import re
+import subprocess
+from time import time, ctime
+
+# After how many seconds the cached information about an authentication
+# token is discarded.
+TOKEN_LIFE = 86400
+
+# This is used as a prefix for tokens and memcache keys. We use the default
+# value from the Swift tempauth filter. In the future, this should be turned
+# into a configuration parameter.
+RESELLER_PREFIX = 'AUTH_'
+
+MEMCACHE_SERVERS = ['127.0.0.1:11211']
+
+DEBUG_HEADERS = True
+
+def main():
+ remote_user = os.environ['REMOTE_USER']
+ matches = re.match('([^@]+)@.*', remote_user)
+ if not matches:
+ raise RuntimeError("Malformed REMOTE_USER \"%s\"" % remote_user)
+
+ username = matches.group(1)
+
+ mc = MemcacheRing(MEMCACHE_SERVERS)
+
+ # Check if we already got a token for this user.
+ memcache_user_key = '%s/user/%s' % (RESELLER_PREFIX, username)
+ token = None
+ candidate_token = mc.get(memcache_user_key)
+ if candidate_token:
+ memcache_token_key = '%s/token/%s' % (RESELLER_PREFIX, candidate_token)
+ cached_auth_data = mc.get(memcache_token_key)
+ if cached_auth_data:
+ expires, groups = cached_auth_data
+ if expires > time():
+ token = candidate_token
+
+ if not token:
+ # We don't use uuid.uuid4() here because importing the uuid module
+ # causes (harmless) SELinux denials in the audit log on RHEL 6. If this
+ # is a security concern, a custom SELinux policy module could be
+ # written to not log those denials.
+ r = random.SystemRandom()
+ token = '%stk%s' % \
+ (RESELLER_PREFIX,
+ ''.join(r.choice('abcdef0123456789') for x in range(32)))
+
+ # Retrieve the numerical group IDs. We cannot list the group names
+ # because group names from Active Directory may contain spaces, and
+ # we wouldn't be able to split the list of group names into its
+ # elements.
+ p = subprocess.Popen(['id', '-G', username], stdout=subprocess.PIPE)
+ if p.wait() != 0:
+ raise RuntimeError("Failure running id -G for %s" % remote_user)
+
+ (p_stdout, p_stderr) = p.communicate()
+
+ # Convert the group numbers into group names.
+ groups = []
+ for gid in p_stdout.strip().split(" "):
+ groups.append(grp.getgrgid(int(gid))[0])
+
+ # The first element of the list is considered a unique identifier
+ # for the user. We add the username to accomplish this.
+ if username in groups:
+ groups.remove(username)
+ groups = [username] + groups
+
+ groups = ','.join(groups)
+
+ expires = time() + TOKEN_LIFE
+ auth_data = (expires, groups)
+
+ memcache_token_key = "%s/token/%s" % (RESELLER_PREFIX, token)
+ mc.set(memcache_token_key, auth_data, timeout=TOKEN_LIFE)
+
+ # Record the token with the user info for future use.
+ memcache_user_key = '%s/user/%s' % (RESELLER_PREFIX, username)
+ mc.set(memcache_user_key, token, timeout=TOKEN_LIFE)
+
+ print "X-Auth-Token: %s" % token
+
+ # For debugging.
+ if DEBUG_HEADERS:
+ print "X-Debug-Remote-User: %s" % username
+ print "X-Debug-Groups: %s" % groups
+ print "X-Debug-Token-Life: %ss" % TOKEN_LIFE
+ print "X-Debug-Token-Expires: %s" % ctime(expires)
+
+ print ""
+
+try:
+ print("Content-Type: text/html")
+ main()
+except:
+ cgi.print_exception()