diff --git a/myproxy/oauth/source/.gitignore b/myproxy/oauth/source/.gitignore deleted file mode 100644 index eaea68ac98..0000000000 --- a/myproxy/oauth/source/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -MANIFEST -dist diff --git a/myproxy/oauth/source/LICENSE b/myproxy/oauth/source/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/myproxy/oauth/source/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/myproxy/oauth/source/MANIFEST.in b/myproxy/oauth/source/MANIFEST.in deleted file mode 100644 index 491c2e8c07..0000000000 --- a/myproxy/oauth/source/MANIFEST.in +++ /dev/null @@ -1,12 +0,0 @@ -include conf/* -include sysconfig/myproxy-oauth -include init/myproxy-oauth -recursive-include myproxy *.py -recursive-include myproxyoauth *.py -include myproxyoauth/static/* -include myproxyoauth/templates/* -recursive-include oauth2 * -include *.py -include myproxy-oauth-setup -include README.md -include MANIFEST.in diff --git a/myproxy/oauth/source/README.md b/myproxy/oauth/source/README.md deleted file mode 100644 index 23de33688c..0000000000 --- a/myproxy/oauth/source/README.md +++ /dev/null @@ -1,47 +0,0 @@ -myproxy-oauth -============= - -MyProxy Delegation Service in Python ------------------------------------- - -The MyProxy Delegation Service is a Python implementation of MyProxy OAuth -protocol, https://docs.google.com/document/pub?id=10SC7oSURc-EgxMQjcCS50gz0u2HzDJAFiG5hEHiSdxA. -The service can be deployed to -Apache with mod\_wsgi or run as a standalone service using the python wsgiref -server. An example configuration file for Apache is in conf/. -The file should be copied to /etc/apache2/conf.d/ on Debian-based systems, or -to /etc/httpd/conf.d/ on Red Hat-based system. - -By default, the service uses SQLite3 database. A path to the database file is -hard-coded in myproxyoauth/database.py. The directory with the database file -must be readable and writable by the user the wsgi process runs as. - -To generate web pages, the service uses templates stored in -myproxyoauth/templates/. The templates, and other static files stored in -myproxyoauth/static/ like images or cascade style sheets can be easily edited -and displayed directly in a web browser. The templates are accessible at -https://hostname/oauth/templates/, and the static files at -https://hostname/oauth/static/. - -To use the service with Globus Online, Globus Online that acts here as an OAuth -client has to be registered with the service first. To trigger the registration -workflow, go to https://hostname/oauth/configure. A Globus Online user -specified in the registration form will become an admin of the service. - -Prerequisite packages on Debian-based systems: - -* python >= 2.5 -* python-crypto >= 2.0 and python-m2crypto or python-crypto >= 2.2 -* python-openssl -* python-openssl - -If you want to use this with apache2 instead of the standalone server, you'll -also need libapache2-mod-wsgi and the apache2 server with the ssl module -enabled and the default-ssl site enabled. - -Prerequisite packages on RedHat-based systems -* pyOpenSSL -* python-crypto - -If you want to use this with apache2 instead of the standalone service, you'll -also need httpd, mod\_wsgi, and mod\_ssl diff --git a/myproxy/oauth/source/conf/myproxy-oauth b/myproxy/oauth/source/conf/myproxy-oauth deleted file mode 100644 index 016a6450d1..0000000000 --- a/myproxy/oauth/source/conf/myproxy-oauth +++ /dev/null @@ -1,31 +0,0 @@ - - # Serve HTML templates with all static files (images, CSS, etc.) requested directly at http[s]:///oauth/templates/ - Alias /oauth/templates/ /usr/share/myproxy-oauth/myproxyoauth/templates/ - - Options Indexes - Order allow,deny - Allow from all - - - # Serve static files requested from MyProxy OAuth application - Alias /oauth/static/ /usr/share/myproxy-oauth/myproxyoauth/static/ - - Options Indexes - Order allow,deny - Allow from all - - - # Serve other files using mod_wsgi - WSGIDaemonProcess myproxyoauth user=myproxyoauth group=myproxyoauth threads=1 - WSGISocketPrefix /var/run/wsgi - - WSGIProcessGroup myproxyoauth - WSGIScriptAlias /oauth /usr/share/myproxy-oauth/wsgi.py - -# WSGIApplicationGroup %{GLOBAL} -# WSGIScriptReloading On - SSLRequireSSL - Order allow,deny - Allow from all - - diff --git a/myproxy/oauth/source/conf/myproxy-oauth-2.4 b/myproxy/oauth/source/conf/myproxy-oauth-2.4 deleted file mode 100644 index 082be115ae..0000000000 --- a/myproxy/oauth/source/conf/myproxy-oauth-2.4 +++ /dev/null @@ -1,34 +0,0 @@ - - # Serve HTML templates with all static files (images, CSS, etc.) requested directly at http[s]:///oauth/templates/ - Alias /oauth/templates/ /usr/share/myproxy-oauth/myproxyoauth/templates/ - - Options Indexes - Require all granted - - - # Serve static files requested from MyProxy OAuth application - Alias /oauth/static/ /usr/share/myproxy-oauth/myproxyoauth/static/ - - Options Indexes - Require all granted - - - # Serve other files using mod_wsgi - WSGIDaemonProcess myproxyoauth user=myproxyoauth group=myproxyoauth threads=1 - WSGISocketPrefix run/wsgi - - WSGIProcessGroup myproxyoauth - WSGIScriptAlias /oauth /usr/share/myproxy-oauth/wsgi.py - -# WSGIApplicationGroup %{GLOBAL} -# WSGIScriptReloading On - SSLRequireSSL - Require all granted - - -# WSGIApplicationGroup %{GLOBAL} -# WSGIScriptReloading On - SSLRequireSSL - Require all granted - - diff --git a/myproxy/oauth/source/conf/myproxy-oauth-2.4-deb b/myproxy/oauth/source/conf/myproxy-oauth-2.4-deb deleted file mode 100644 index 50c471741b..0000000000 --- a/myproxy/oauth/source/conf/myproxy-oauth-2.4-deb +++ /dev/null @@ -1,34 +0,0 @@ - - # Serve HTML templates with all static files (images, CSS, etc.) requested directly at http[s]:///oauth/templates/ - Alias /oauth/templates/ /usr/share/myproxy-oauth/myproxyoauth/templates/ - - Options Indexes - Require all granted - - - # Serve static files requested from MyProxy OAuth application - Alias /oauth/static/ /usr/share/myproxy-oauth/myproxyoauth/static/ - - Options Indexes - Require all granted - - - # Serve other files using mod_wsgi - WSGIDaemonProcess myproxyoauth user=myproxyoauth group=myproxyoauth threads=1 - WSGISocketPrefix /var/run/apache2/wsgi - - WSGIProcessGroup myproxyoauth - WSGIScriptAlias /oauth /usr/share/myproxy-oauth/wsgi.py - -# WSGIApplicationGroup %{GLOBAL} -# WSGIScriptReloading On - SSLRequireSSL - Require all granted - - -# WSGIApplicationGroup %{GLOBAL} -# WSGIScriptReloading On - SSLRequireSSL - Require all granted - - diff --git a/myproxy/oauth/source/conf/myproxy-oauth-epel5 b/myproxy/oauth/source/conf/myproxy-oauth-epel5 deleted file mode 100644 index 59b5fcc984..0000000000 --- a/myproxy/oauth/source/conf/myproxy-oauth-epel5 +++ /dev/null @@ -1,32 +0,0 @@ -LoadModule wsgi_module modules/mod_wsgi.so - - # Serve HTML templates with all static files (images, CSS, etc.) requested directly at http[s]:///oauth/templates/ - Alias /oauth/templates/ /usr/share/myproxy-oauth/myproxyoauth/templates/ - - Options Indexes - Order allow,deny - Allow from all - - - # Serve static files requested from MyProxy OAuth application - Alias /oauth/static/ /usr/share/myproxy-oauth/myproxyoauth/static/ - - Options Indexes - Order allow,deny - Allow from all - - - # Serve other files using mod_wsgi - WSGIDaemonProcess myproxyoauth user=myproxyoauth group=myproxyoauth threads=1 - WSGISocketPrefix /var/run/wsgi - - WSGIProcessGroup myproxyoauth - WSGIScriptAlias /oauth /usr/share/myproxy-oauth/wsgi.py - -# WSGIApplicationGroup %{GLOBAL} -# WSGIScriptReloading On - SSLRequireSSL - Order allow,deny - Allow from all - - diff --git a/myproxy/oauth/source/myproxy-oauth-setup b/myproxy/oauth/source/myproxy-oauth-setup deleted file mode 100644 index d81cd97542..0000000000 --- a/myproxy/oauth/source/myproxy-oauth-setup +++ /dev/null @@ -1,342 +0,0 @@ -#! /usr/bin/python2 -# -# Copyright 2010-2017 University of Chicago -# -# 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. -# - -import base64 -import getpass -import getopt -import httplib -import json -import os -import random -import socket -import urllib -from subprocess import Popen, PIPE -import sys - -def public_name(): - """ - Try to guess the public host name of this machine. If this is - on a machine which is able to access ec2 metadata, it will use - that; otherwise socket.getfqdn() - """ - url = 'http://169.254.169.254/latest/meta-data/public-hostname' - value = None - try: - socket.setdefaulttimeout(3.0) - value = urllib.urlopen(url).read() - except IOError: - pass - - if value is not None and "404 - Not Found" in value: - value = None - - if value is None: - value = socket.getfqdn() - return value - -""" -Register Globus as an OAuth client with this MyProxy OAuth Delegation -service. The registration consists of two steps: -1. Get an access token from Globus. -2. Trigger Globus client registration with this service. -""" -def configure(username=None, pwstdin=False, oauth_server=None, myproxy_server=None, nexus_server=None): - - # Delay this until after seteuid() so that the database file is owned by - # the specified user - from myproxyoauth.database import db_session, Admin, Client - if username is None: - default_user = getpass.getuser() - print "Globus Username [%s]: " % (default_user), - username = sys.stdin.readline().strip() - if username == '': - username = default_user - if pwstdin: - print "Globus Password: ", - password = sys.stdin.readline().strip() - else: - password = getpass.getpass("Globus Password: ") - - default_hostname = public_name() - - if oauth_server is None: - print "OAuth Server [%s]: " % (default_hostname), - oauth_server = sys.stdin.readline().strip() - if oauth_server == '': - oauth_server = default_hostname - - if myproxy_server is None: - print "MyProxy Server [%s]: " % (default_hostname), - myproxy_server = sys.stdin.readline().strip() - if myproxy_server == '': - myproxy_server = default_hostname - - if nexus_server is None: - nexus_server = "nexus.api.globusonline.org" - - admins = db_session.get_admin() - admin = None - if len(admins) > 0: - admin = admins[0] - - if admin is not None: - if admin.username != username: - message = 'You are not an admin of the MyProxy Delegation Service' - print >>sys.stderr, message - sys.exit(1) - - try: - access_token = get_access_token(username, password, nexus_server) - except Exception, e: - message='Could not get access token. %s' % str(e) - print >>sys.stderr, message - sys.exit(1) - - client_id = 'myproxy:oa4mp,2012:/client/' \ - + ''.join([random.choice('0123456789abcdef') for i in range(32)]) - try: - (home_url, gateway_name, oauth_consumer_id, public_key) = register_go( - nexus_server, access_token, client_id, oauth_server) - except Exception, e: - message = str(e) - print >>sys.stderr, message - sys.exit(1) - - print "Registered: gateway_name: %s, home_url: %s," \ - " oauth_consumer_id: %s" \ - % (gateway_name, home_url, oauth_consumer_id) - - if admin is None: - db_session.add_admin(Admin(username)) - - db_session.delete_clients( - [Client(oauth_consumer_key=oauth_consumer_id)]) - client = Client() - client.oauth_consumer_key=oauth_consumer_id - client.oauth_client_pubkey=public_key - client.name=gateway_name - client.home_url=home_url - client.myproxy_server=myproxy_server - db_session.add_client(client) - - db_session.commit() - selinux_permissions() - -def get_access_token(username, password, server): - """ - Get an access token from Globus Nexus. - Returns: an access token - """ - - basic_auth = base64.b64encode('%s:%s' % (username, password)) - headers = { 'Content-type': 'app/json; charset=UTF-8', - 'Hostname': server, - 'Accept': 'app/json; charset=UTF-8', - 'Authorization': 'Basic %s' % basic_auth } - c = httplib.HTTPSConnection(server, 443) - c.request('GET', '/goauth/token?grant_type=client_credentials', - headers=headers) - response = c.getresponse() - json_reader = None - if hasattr(json, 'loads'): - json_reader = json.loads - elif hasattr(json, 'JsonReader'): - json_reader_obj = json.JsonReader() - json_reader = json_reader_obj.read - - if response.status == 403: - try : - message = json_reader(response.read()).get('message') - except Exception, e: - message = str(e) - raise Exception('403 Error: %s' % message) - elif response.status > 299 or response.status < 200: - raise Exception('%d Error: %s' % (response.status, response.reason)) - data = json_reader(response.read()) - token = data.get('access_token') - if token is None: - raise Exception('No access token in response') - return token - - -def register_go(server, access_token, client_id, myproxy_server): - """ - Trigger the nexus_server to register with the oauth_server. - Returns: home_url, gateway_name, public_key, oauth_consumer_id - """ - - headers = { 'Content-type': 'app/json', - 'X-Globus-Goauthtoken': access_token} - body = '{"oauth_consumer_id": "%s", "oauth_server": "%s"}' \ - % (client_id, myproxy_server) - c = httplib.HTTPSConnection(server, 443) - c.request('POST', '/identity_providers/oauth_registration', - body=body, headers=headers) - response = c.getresponse() - json_reader = None - if hasattr(json, 'loads'): - json_reader = json.loads - elif hasattr(json, 'JsonReader'): - json_reader_obj = json.JsonReader() - json_reader = json_reader_obj.read - if response.status == 403: - try: - message = json_reader(response.read()).get('message') - except Exception, e: - message = str(e) - raise Exception('403 Error: %s' % message) - elif response.status > 299 or response.status < 200: - raise Exception('%d Error: %s' % (response.status, response.reason)) - data = json_reader(response.read()) - home_url = data.get('home_url') - gateway_name = data.get('gateway_name') - oauth_consumer_id = data.get('oauth_consumer_id') - public_key = data.get('public_key') - return (home_url, gateway_name, oauth_consumer_id, public_key) - - -def usage(outstream=sys.stdout): - print >>outstream, """myproxy-oauth-setup [-h] -myproxy-oauth-setup {-s | --stdin} {-u USER | --user=USER} - {-o SERVER| --oauth-server=SERVER} - {-m SERVER| --myproxy-server=SERVER} - {-n SERVER| --nexus-api-server=SERVER}""" - -def selinux_permissions(): - save_uid = os.geteuid() - if os.getuid() == 0: - os.seteuid(0) - - semanage = which("semanage") - chcon = which("chcon") - restorecon = which("restorecon") - setsebool = which("setsebool") - args = None - - # Allow httpd to write to the myproxy-oauth sqlite3 database - if semanage is not None: - args = [semanage, 'fcontext', '-a', '-t', 'httpd_sys_rw_content_t', - '/var/lib/myproxy-oauth/myproxy-oauth.db'] - elif chcon is not None: - args = [chcon, '-t', 'httpd_sys_rw_content_t', - '/var/lib/myproxy-oauth/myproxy-oauth.db'] - - if args is not None: - context_proc = Popen(args, stdin=None, stdout=PIPE, stderr=PIPE) - (out, err) = context_proc.communicate() - if out is not None: - print out - if err is not None: - print >>sys.stderr, err - - args = None - - # Allow httpd to connect to myproxy service - if semanage is not None: - args = [semanage, 'boolean', '-m', '-1', 'httpd_can_network_connect'] - elif setsebool is not None: - args = [setsebool, '-P', 'httpd_can_network_connect', 'on'] - - if args is not None: - setbool_proc = Popen(args, stdin=None, stdout=PIPE, stderr=PIPE) - (out, err) = setbool_proc.communicate() - if out is not None: - print out - if err is not None: - print >>sys.stderr, err - - args = None - # Allow httpd to run wsgi - if semanage is not None: - args = [semanage, 'boolean', '-m', '-1', 'httpd_execmem'] - elif setsebool is not None: - args = [setsebool, '-P', 'httpd_execmem', 'on'] - if args is not None: - setbool_proc = Popen(args, stdin=None, stdout=PIPE, stderr=PIPE) - (out, err) = setbool_proc.communicate() - if out is not None: - print out - if err is not None: - print >>sys.stderr, err - - if semanage is not None and restorecon is not None: - args = [restorecon, '/var/lib/myproxy-oauth/myproxy-oauth.db'] - restorecon_proc = Popen(args, stdin=None, stdout=PIPE, stderr=PIPE) - (out, err) = restorecon_proc.communicate() - if out is not None: - print out - if err is not None: - print >>sys.stderr, err - - if os.geteuid() == 0 and save_uid != 0: - os.seteuid(save_uid) -def which(name): - exe_path = None - path_to_check = os.environ['PATH'].split(os.pathsep) - for sbin in ["/usr/sbin", "/sbin"]: - if sbin not in path_to_check: - path_to_check.append(sbin) - - for path in path_to_check: - exe_path = os.path.join(path, name) - if os.path.isfile(exe_path) and os.access(exe_path, os.X_OK): - return exe_path - return None - -if __name__ == '__main__': - try: - opts, args = getopt.getopt(sys.argv[1:], "hsu:o:m:n:i:", - ["help", "stdin", "user=", "oauth-server=", "myproxy-server=", - "nexus-api-server=", "id="]) - except getopt.GetoptError, e: - print >>sys.stderr, "Invalid option " + e.opt - usage(outstream=sys.stderr) - sys.exit(1) - - pwstdin = False - user = None - oauth_server = None - myproxy_server = None - nexus_server = None - userid = None - - for (o, val) in opts: - if o in ['-h', '--help']: - usage() - sys.exit(0) - elif o in ['-s', '--stdin']: - pwstdin = True - elif o in ['-u', '--user']: - user = val - elif o in ['-o', '--oauth-server']: - oauth_server = val - elif o in ['-m', '--myproxy-server']: - myproxy_server = val - elif o in ['-n', '--nexus-api-server']: - nexus_server = val - elif o in ['-i', '--id']: - userid = int(val) - else: - print >>sys.stderr, "Unknown option %s" %(o) - sys.exit(1) - - if userid is not None: - os.seteuid(userid) - - configure(username=user, pwstdin=pwstdin, oauth_server=oauth_server, - myproxy_server=myproxy_server, nexus_server=nexus_server) -# vim: syntax=python: nospell: diff --git a/myproxy/oauth/source/myproxy/__init__.py b/myproxy/oauth/source/myproxy/__init__.py deleted file mode 100644 index c46b617845..0000000000 --- a/myproxy/oauth/source/myproxy/__init__.py +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -# -# myproxy client -# -# Written by Tom Uram -# 2005/08/04 -# Modified by Lukasz Lacinski -# 2012/05/21 - -import os -import socket -from OpenSSL import crypto, SSL - -class GetException(Exception): pass -class RetrieveProxyException(Exception): pass - - -def deserialize_response(msg): - """ - Deserialize a MyProxy server response - Returns: integer response, errortext (if any) - """ - - lines = msg.split('\n') - - # get response value - responselines = filter( lambda x: x.startswith('RESPONSE'), lines) - responseline = responselines[0] - response = int(responseline.split('=')[1]) - - # get error text - errortext = "" - errorlines = filter( lambda x: x.startswith('ERROR'), lines) - for e in errorlines: - etext = e.split('=')[1] - errortext += etext - - return response, errortext - - -CMD_GET="""VERSION=MYPROXYv2 -COMMAND=0 -USERNAME=%s -PASSPHRASE=%s -LIFETIME=%d\0""" - -def myproxy_logon(certreq_pem, lifetime, username, passphrase, myproxy_server): - """ - Function to retrieve a proxy credential from a MyProxy server - - Exceptions: GetException, RetrieveProxyException - """ - hostname = myproxy_server - port = 7512 - try: - hostname, port = myproxy_server.split(':') - except: - pass - - context = SSL.Context(SSL.SSLv23_METHOD) - context.set_options(SSL.OP_NO_SSLv2) - context.set_options(SSL.OP_NO_SSLv3) - - # disable for compatibility with myproxy server (er, globus) - # globus doesn't handle this case, apparently, and instead - # chokes in proxy delegation code - context.set_options(0x00000800L) - - # connect to myproxy server - conn = SSL.Connection(context,socket.socket()) - conn.connect((hostname, int(port))) - - # send globus compatibility stuff - conn.write('0') - - # send get command - cmd_get = CMD_GET % (username, passphrase, lifetime) - conn.write(cmd_get) - - # process server response - dat = conn.recv(8192) - response, errortext = deserialize_response(dat) - if response: - raise GetException(errortext) - - # generate and send certificate request - # - The client will generate a public/private key pair and send a - # NULL-terminated PKCS#10 certificate request to the server. - req = crypto.load_certificate_request(crypto.FILETYPE_PEM, certreq_pem) - certreq_asn1 = crypto.dump_certificate_request(crypto.FILETYPE_ASN1, req) - conn.send(certreq_asn1) - - # process certificates - # - 1 byte, number of certs - dat = conn.recv(1) - numcerts = ord(dat[0]) - - # - n certs - dat = conn.recv(8192) - - # process server response - resp = conn.recv(8192) - response, errortext = deserialize_response(resp) - if response: - raise RetrieveProxyException(errortext) - - # deserialize certs from received cert data and convert them from ASN1 to PEM - pem_certs = "" - - while dat: - # find start of cert, get length - ind = dat.find('\x30\x82') - if ind < 0: - break - - len = 256 * ord(dat[ind+2]) + ord(dat[ind+3]) - - # extract der-format cert, and convert to pem - c = dat[ind:ind + len + 4] - x509 = crypto.load_certificate(crypto.FILETYPE_ASN1, c) - pem_certs += crypto.dump_certificate(crypto.FILETYPE_PEM, x509) - - # trim cert from data - dat = dat[ind + len + 4:] - - return pem_certs diff --git a/myproxy/oauth/source/myproxyoauth/__init__.py b/myproxy/oauth/source/myproxyoauth/__init__.py deleted file mode 100644 index 1c27cd28b8..0000000000 --- a/myproxy/oauth/source/myproxyoauth/__init__.py +++ /dev/null @@ -1,117 +0,0 @@ -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -from myproxyoauth.database import init_db - -init_db() - -import logging, sys -import os -import pkgutil -import myproxyoauth.templates -import myproxyoauth.static - -logging.basicConfig(stream=sys.stderr) - -__path__ = pkgutil.extend_path(__path__, __name__) - -class MyProxyOAuth(object): - logger = logging.getLogger() - - def __init__(self): - self.routes = dict() - self.teardown_request_func = None - self.logger = MyProxyOAuth.logger - - def __call__(self, environ, start_response): - path_info = environ.get("PATH_INFO") - method = environ.get("REQUEST_METHOD") - template_route = "GET:/templates/" - static_route = "GET:/static/" - - route = method + ":" + path_info - self.logger.debug("route is " + route) - if route in self.routes: - self.logger.debug("route is present") - exc = None - try: - try: - return self.routes[route](environ, start_response) - except Exception, e: - headers = [("Content-Type", "text/plain")] - response = "500 Internal Server Error" - return str(e) - finally: - if self.teardown_request_func is not None: - self.teardown_request_func(exception=e) - elif route.startswith(template_route) or route.startswith(static_route): - self.logger.debug("Routing static content") - dataname = None - modname = None - content_type = None - if route.startswith(template_route): - modname = 'myproxyoauth.templates' - dataname = route[len(template_route):] - content_type = "text/html" - else: - modname = 'myproxyoauth.static' - dataname = route[len(static_route):] - if dataname.endswith(".png"): - content_type = "image/png" - elif dataname.endswith(".css"): - content_type = "text/css" - else: - content_type = "application/octet-string" - - try: - if not("/" in dataname or - ".py" in dataname or - dataname == "." or - dataname == ".."): - data = pkgutil.get_data(modname, dataname) - status = "200 Ok" - headers = [("Content-Type", content_type)] - start_response(status, headers) - return data - except Exception, e: - headers = [("Content-Type", "text/plain")] - response = "500 Internal Server Error" - return str(e) - else: - try: - headers = [("Content-Type", "text/plain")] - response = "404 Not Found" - start_response(response, headers) - return [response] - finally: - if self.teardown_request_func is not None: - self.teardown_request_func() - - def route(self, path, methods=["GET"]): - def decorator(func): - for m in methods: - self.routes[m + ":" + path] = func - return decorator - - def teardown_request(self, func): - def decorator(): - self.teardown_request_func = func - return decorator - -application = MyProxyOAuth() - -import myproxyoauth.views -# vim: filetype=python: nospell: diff --git a/myproxy/oauth/source/myproxyoauth/database.py b/myproxy/oauth/source/myproxyoauth/database.py deleted file mode 100644 index ad31b1fbb0..0000000000 --- a/myproxy/oauth/source/myproxyoauth/database.py +++ /dev/null @@ -1,298 +0,0 @@ -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -try: - import sqlite3 -except: - from pysqlite2 import dbapi2 as sqlite3 - -class Admin(object): - def __init__(self, username=None): - self.username = username - -class Client(object): - def __init__(self, oauth_consumer_key=None, oauth_client_pubkey=None, name=None, home_url=None, myproxy_server=None, limited_proxy=0): - self.oauth_consumer_key = oauth_consumer_key - self.oauth_client_pubkey = oauth_client_pubkey - self.name = name - self.home_url = home_url - self.myproxy_server = myproxy_server - self.limited_proxy = limited_proxy - -class Transaction(object): - def __init__(self, temp_token=None, temp_token_valid=None, - oauth_callback=None, certreq=None, oauth_consumer_key=None, - oauth_verifier=None, access_token=None, access_token_valid=None, - certificate=None, username=None, certlifetime=None, timestamp=None): - self.temp_token = temp_token - self.temp_token_valid = temp_token_valid - self.oauth_callback = oauth_callback - self.certreq = certreq - self.oauth_consumer_key = oauth_consumer_key - self.oauth_verifier = oauth_verifier - self.access_token = access_token - self.access_token_valid = access_token_valid - self.certificate = certificate - self.username = username - self.certlifetime = certlifetime - self.timestamp = timestamp - -class Database(object): - def __init__(self, path='/var/lib/myproxy-oauth/myproxy-oauth.db'): - self.connection = sqlite3.connect(path) - self.cursor = self.connection.cursor() - - def init_db(self): - table_exists_query = """ - SELECT name - FROM sqlite_master WHERE type='table' AND name=?""" - self.cursor.execute(table_exists_query, ['admin']) - if len(self.cursor.fetchall()) == 0: - self.cursor.execute("CREATE TABLE admin(username TEXT PRIMARY KEY)") - - self.cursor.execute(table_exists_query, ['clients']) - if len(self.cursor.fetchall()) == 0: - self.cursor.execute(""" - CREATE TABLE clients ( - oauth_consumer_key TEXT PRIMARY KEY, - oauth_client_pubkey TEXT, - name TEXT, - home_url TEXT, - myproxy_server TEXT, - limited_proxy INTEGER DEFAULT 0 - );""") - self.cursor.execute(table_exists_query, ['transactions']) - if len(self.cursor.fetchall()) == 0: - self.cursor.execute(""" - CREATE TABLE transactions( - temp_token TEXT PRIMARY KEY, - temp_token_valid INTEGER, - oauth_callback TEXT, - certreq TEXT, - oauth_consumer_key TEXT, - oauth_verifier TEXT UNIQUE, - access_token TEXT UNIQUE, - access_token_valid INTEGER, - certificate TEXT, - username TEXT, - certlifetime INTEGER, - timestamp INTEGER - );""") - - def commit(self): - self.connection.commit() - - def add_admin(self, admin): - self.cursor.execute("INSERT INTO admin(username) VALUES(?)", - [admin.username]) - - def get_admin(self, admin=None): - query = "SELECT username FROM admin" - wheres = [] - args = [] - - if admin is not None: - if admin.username is not None: - wheres.append("username = ?") - args.append(admin.username) - - if len(wheres) > 0: - query = query + " WHERE " + " AND ".join(wheres) - - self.cursor.execute(query, args) - res = [] - for row in self.cursor: - res.append(Admin(*row)) - - return res - - def add_client(self, client): - self.cursor.execute(""" - INSERT INTO clients( - oauth_consumer_key, oauth_client_pubkey, name, - home_url, myproxy_server, limited_proxy) - VALUES(?,?,?,?,?,?)""", [ - client.oauth_consumer_key, client.oauth_client_pubkey, - client.name, client.home_url, client.myproxy_server, - client.limited_proxy]) - - def get_client(self, client=None): - query = """ - SELECT oauth_consumer_key, oauth_client_pubkey, name, - home_url, myproxy_server, limited_proxy - FROM clients - """ - wheres = [] - args = [] - - if client is not None: - if client.oauth_consumer_key is not None: - wheres.append("oauth_consumer_key = ?") - args.append(client.oauth_consumer_key) - if client.oauth_client_pubkey is not None: - wheres.append("oauth_client_pubkey = ?") - args.append(client.oauth_client_pubkey) - if client.name is not None: - wheres.append("name = ?") - args.append(client.name) - if client.home_url is not None: - wheres.append("home_url = ?") - args.append(client.home_url) - if client.myproxy_server is not None: - wheres.append("myproxy_server = ?") - args.append(client.myproxy_server) - if client.limited_proxy is not None: - wheres.append("limited_proxy = ?") - args.append(client.limited_proxy) - - if len(wheres) > 0: - query = query + "WHERE " + " AND ".join(wheres) - - self.cursor.execute(query, args) - res = [] - for row in self.cursor: - res.append(Client(*row)) - - return res - - def delete_clients(self, clients): - if len(clients) > 0: - self.cursor.executemany( - "DELETE FROM clients WHERE oauth_consumer_key = ?", - [(tuple([c.oauth_consumer_key])) for c in clients]) - - def add_transaction(self, transaction): - self.cursor.execute(""" - INSERT INTO transactions (temp_token, temp_token_valid, - oauth_callback, certreq, oauth_consumer_key, - oauth_verifier, access_token, access_token_valid, - certificate, username, certlifetime, timestamp) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", - [transaction.temp_token, - transaction.temp_token_valid, transaction.oauth_callback, - transaction.certreq, transaction.oauth_consumer_key, - transaction.oauth_verifier, transaction.access_token, - transaction.access_token_valid, transaction.certificate, - transaction.username, transaction.certlifetime, - transaction.timestamp]) - - def update_transaction(self, transaction): - query = "UPDATE transactions SET " - sets = [] - args = [] - if transaction.temp_token_valid is not None: - sets.append("temp_token_valid = ?") - args.append(transaction.temp_token_valid) - if transaction.oauth_callback is not None: - sets.append("oauth_callback = ?") - args.append(transaction.oauth_callback) - if transaction.certreq is not None: - sets.append("certreq = ?") - args.append(transaction.certreq) - if transaction.oauth_consumer_key is not None: - sets.append("oauth_consumer_key = ?") - args.append(transaction.oauth_consumer_key) - if transaction.oauth_verifier is not None: - sets.append("oauth_verifier = ?") - args.append(transaction.oauth_verifier) - if transaction.access_token is not None: - sets.append("access_token = ?") - args.append(transaction.access_token) - if transaction.access_token_valid is not None: - sets.append("access_token_valid = ?") - args.append(transaction.access_token_valid) - if transaction.certificate is not None: - sets.append("certificate = ?") - args.append(transaction.certificate) - if transaction.username is not None: - sets.append("username = ?") - args.append(transaction.username) - if transaction.certlifetime is not None: - sets.append("certlifetime = ?") - args.append(transaction.certlifetime) - if transaction.timestamp is not None: - sets.append("timestamp = ?") - args.append(transaction.timestamp) - query = query + ",".join(sets) + " WHERE temp_token=?" - args.append(transaction.temp_token) - self.cursor.execute(query, args) - - def delete_transactions(self, transactions): - if len(transactions) > 0: - self.cursor.executemany( - "DELETE FROM transactions WHERE temp_token = ?", - [(t.temp_token,) for t in transactions]) - - def get_transaction(self, transaction=None): - query = """ - SELECT - temp_token, temp_token_valid, - oauth_callback, certreq, oauth_consumer_key, - oauth_verifier, access_token, access_token_valid, - certificate, username, certlifetime, timestamp - FROM transactions""" - wheres = [] - args = [] - - if transaction is not None: - if transaction.temp_token is not None: - wheres.append("temp_token = ?") - args.append(transaction.temp_token) - if transaction.temp_token_valid is not None: - wheres.append("temp_token_valid = ?") - args.append(transaction.temp_token_valid) - if transaction.oauth_callback is not None: - wheres.append("oauth_callback = ?") - args.append(transaction.oauth_callback) - if transaction.certreq is not None: - wheres.append("certreq = ?") - args.append(transaction.certreq) - if transaction.oauth_consumer_key is not None: - wheres.append("oauth_consumer_key = ?") - args.append(transaction.oauth_consumer_key) - if transaction.oauth_verifier is not None: - wheres.append("oauth_verifier = ?") - args.append(transaction.oauth_verifier) - if transaction.access_token is not None: - wheres.append("access_token = ?") - args.append(transaction.access_token) - if transaction.access_token_valid is not None: - wheres.append("access_token_valid = ?") - args.append(transaction.access_token_valid) - if transaction.certificate is not None: - wheres.append("certificate = ?") - args.append(transaction.certificate) - if transaction.username is not None: - wheres.append("username = ?") - args.append(transaction.username) - if transaction.certlifetime is not None: - wheres.append("certlifetime = ?") - args.append(transaction.certlifetime) - if transaction.timestamp is not None: - wheres.append("timestamp = ?") - args.append(transaction.timestamp) - - if len(wheres) > 0: - query = query + " WHERE " + " AND ".join(wheres) - - self.cursor.execute(query, args) - res = [] - for row in self.cursor: - res.append(Transaction(*row)) - return res - -db_session = Database() -init_db = db_session.init_db diff --git a/myproxy/oauth/source/myproxyoauth/static/__init__.py b/myproxy/oauth/source/myproxyoauth/static/__init__.py deleted file mode 100644 index 459c2301c5..0000000000 --- a/myproxy/oauth/source/myproxyoauth/static/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -import pkgutil - -__path__ = pkgutil.extend_path(__path__, __name__) diff --git a/myproxy/oauth/source/myproxyoauth/static/oauth.css b/myproxy/oauth/source/myproxyoauth/static/oauth.css deleted file mode 100644 index ec89367272..0000000000 --- a/myproxy/oauth/source/myproxyoauth/static/oauth.css +++ /dev/null @@ -1,96 +0,0 @@ -* { - margin: 0; - padding: 0; -} -#header { - min-height: 64px; - background: url("headerbg.png") repeat scroll 0 0 transparent; -} -#logo { - margin-left: 6px; - width: 280px; - height: 64px; - display: inline; - float: left; - background: url("logo.png") no-repeat; -} -#title { - margin-right: 30px; - height: 64px; - display: inline; - float: right; - line-height: 64px; - font-family: MuseoSans,Arial,sans-serif; - font-style: normal; - font-weight: 300; - font-size: 1.5em; - color: #FFFFFF; -} -#main { - width: 960px; - min-height: 500px; - padding-bottom: 50px; - margin-left: auto; - margin-right: auto; -} -#sep { - width: 100%; - height: 32px; - display: block; - background-image: -webkit-linear-gradient(top, #F4F4F4 0%, white 75%); - background-image: linear-gradient(top, #F4F4F4 0%, white 75%); -} -#topic { - margin-top: 30px; - margin-bottom: 50px; - margin-left: auto; - margin-right: auto; - border-bottom: 1px solid #CCC; - width: 780px; - position: relative; -} -#message { - width: 500px; - position: relative; - margin-left: auto; - margin-right: auto; - margin-bottom: 40px; -} -body { - font-family: "Helvetica Neue",Arial,Helvetica,sans-serif; - font-size: 12px; - color: #333; -} -h1 { - display: inline; - font-family: MuseoSans,Arial,sans-serif; - font-weight: normal; -} -table { - margin: auto; -} -th { - padding: 5px; - font-weight: bold; - text-align: left; -} -td { - padding: 5px; -} -input[type="submit"] { - background: #5F8DC6; - color: white; - text-shadow: 1px 1px 1px #666; - gradient(top, #709FD8 0%, #649EE2 58%, #5F8DC6 100%); - background-image: linear-gradient(top, #709FD8 0%, #649EE2 58%, #5F8DC6 100%); - border: 1px solid #4C80C0; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; - font-family: Arial, Helvetica, Verdana, sans-serif; - font-size: 1.0em; - font-weight: normal; - margin: 0 5px 0 0; - padding: 4px 10px 5px; - vertical-align: middle; -} diff --git a/myproxy/oauth/source/myproxyoauth/templates/__init__.py b/myproxy/oauth/source/myproxyoauth/templates/__init__.py deleted file mode 100644 index 459c2301c5..0000000000 --- a/myproxy/oauth/source/myproxyoauth/templates/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -import pkgutil - -__path__ = pkgutil.extend_path(__path__, __name__) diff --git a/myproxy/oauth/source/myproxyoauth/templates/authorize.html b/myproxy/oauth/source/myproxyoauth/templates/authorize.html deleted file mode 100644 index 05708ffee4..0000000000 --- a/myproxy/oauth/source/myproxyoauth/templates/authorize.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - MyProxy Delegation Service - {{ stylesheets }} - - - -
-
-

MyProxy Client Authorization

-
- Welcome to the OAuth for MyProxy Client Authorization Page. - The Client below is requesting access to your account. If you approve, - please sign in with your username and password. -
- - - - -
- - -
Client Information
Name: {{ client_name }}
- URL: {{ client_url }}
-
- - - - - - - - - - - - -
Username
Password
- -
-
{{ retry_message }}
-
- - - diff --git a/myproxy/oauth/source/myproxyoauth/views.py b/myproxy/oauth/source/myproxyoauth/views.py deleted file mode 100644 index 1b08bea0c6..0000000000 --- a/myproxy/oauth/source/myproxyoauth/views.py +++ /dev/null @@ -1,390 +0,0 @@ -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -import socket -import cgi -import random -import base64 -import httplib -import json -import time -import oauth2 as oauth -import Crypto.PublicKey.RSA -import myproxy -import pkgutil -import os -import sys -from myproxyoauth import application -from myproxyoauth.database import db_session, Admin, Client, Transaction -from urllib import quote - -def bad_request(start_response): - status = "400 Bad Request" - headers = [ ("Content-Type", "text/plain") ] - start_response(status, headers, sys.exc_info()) - return "Bad request\n" - -def get_template(name): - template_data = None - if hasattr(pkgutil, "get_data"): - template_data = pkgutil.get_data("myproxyoauth.templates", name) - else: - template_path = os.path.join( - os.path.dirname(__file__), 'templates', name) - template_file = file(template_path, "r") - try: - template_data = template_file.read() - finally: - template_file.close() - return template_data - - -def render_template(name, **kwargs): - template = get_template(name) - for template_token in kwargs: - template = template.replace( - "{{ " + template_token + " }}", kwargs[template_token]) - return str(template) - -def url_reconstruct(environ): - url = environ['wsgi.url_scheme']+'://' - - if environ.get('HTTP_HOST'): - url += environ['HTTP_HOST'] - else: - url += environ['SERVER_NAME'] - - if environ['wsgi.url_scheme'] == 'https': - if environ['SERVER_PORT'] != '443': - url += ':' + environ['SERVER_PORT'] - else: - if environ['SERVER_PORT'] != '80': - url += ':' + environ['SERVER_PORT'] - - url += quote(environ.get('SCRIPT_NAME', '')) - url += quote(environ.get('PATH_INFO', '')) - if environ.get('QUERY_STRING'): - url += '?' + environ['QUERY_STRING'] - return url - -@application.route('/test') -def test(environ, start_response): - status = "403 Forbidden" - headers = [("Content-Type", "text/plain")] - start_response(status, headers) - return "bad" - -@application.teardown_request -def shutdown_session(exception=None): - db_session.remove() - -""" -Implementation of OAuth for MyProxy Protocol, -https://docs.google.com/document/pub?id=10SC7oSURc-EgxMQjcCS50gz0u2HzDJAFiG5hEHiSdxA -""" - -@application.route('/initiate', methods=['GET']) -def initiate(environ, start_response): - try: - request = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) - oauth_signature_method = request.getvalue('oauth_signature_method') - if oauth_signature_method is None: - oauth_signature_method='RSA-SHA1' - oauth_signature = str(request.getvalue('oauth_signature')) - oauth_timestamp = int(request.getvalue('oauth_timestamp')) - oauth_nonce = int(request.getvalue('oauth_nonce')) - oauth_version = str(request.getvalue('oauth_version')) - oauth_consumer_key = str(request.getvalue('oauth_consumer_key')) - oauth_callback = str(request.getvalue('oauth_callback')) - certlifetime = request.getvalue('certlifetime') - if certlifetime is not None: - certlifetime = int(certlifetime) - else: - certlifetime = 86400 - - clients = db_session.get_client(Client(oauth_consumer_key=oauth_consumer_key)) - client = None - if len(clients) > 0: - client = clients[0] - if client is None: - application.logger.error('Unregistered client requested a temporary token.') - status = "403 Not authorized" - headers = [ - ("Content-Type", "text/plain") ] - start_response(status, headers) - return "Uregistered client" - - if hasattr(Crypto.PublicKey.RSA, 'importKey'): - key = Crypto.PublicKey.RSA.importKey(client.oauth_client_pubkey) - else: - import M2Crypto.RSA - import M2Crypto.BIO - import struct - import sys - - bio = M2Crypto.BIO.MemoryBuffer(str(client.oauth_client_pubkey)) - - k = None - try: - k = M2Crypto.RSA.load_pub_key_bio(bio) - def unpack_from(fmt, data, offs): - unpack_len = struct.calcsize(fmt) - - return struct.unpack(fmt, data[offs:offs+unpack_len]) - - def decode(n): - len = reduce(lambda x,y: long(x*256+y), - unpack_from("4B", n, 0)) - return reduce(lambda x,y: long(x*256+y), - unpack_from(str(len)+"B", n, 4)) - keytuple = (decode(k.n), decode(k.e)) - except: - application.logger.error(str(sys.exc_info())) - raise - - key = Crypto.PublicKey.RSA.construct(keytuple) - - method = environ['REQUEST_METHOD'] - url = url_reconstruct(environ) - o_request = oauth.Request.from_request(method, url) - o_consumer = oauth.Consumer(client.oauth_consumer_key, key) - o_server = oauth.Server() - o_server.add_signature_method(oauth.SignatureMethod_RSA_SHA1()) - try: - o_server.verify_request(o_request, o_consumer, None) - except: - e = sys.exc_info() - application.logger.error(str(e[1])) - status = "403 Not authorized" - headers = [ - ("Content-Type", "text/plain") ] - start_response(status, headers, e) - return str(e[1]) - - certreq = str(request.getvalue('certreq')) - - oauth_temp_token = 'myproxy:oa4mp,2012:/tempCred/' \ - + ''.join([random.choice('0123456789abcdef') for i in range(32)]) \ - + '/' + str(int(time.time())) - transaction = Transaction() - transaction.temp_token = oauth_temp_token - transaction.temp_token_valid = 1 - transaction.oauth_callback = oauth_callback - transaction.certreq = certreq - transaction.oauth_consumer_key = oauth_consumer_key - transaction.certlifetime = certlifetime - transaction.timestamp = int(time.time()) - db_session.add_transaction(transaction) - db_session.commit() - - status = "200 Ok" - headers = [ - ("Content-Type", "app/x-www-form-urlencoded") ] - start_response(status, headers) - - return "oauth_token=%s&oauth_callback_confirmed=true" % oauth_temp_token - except: - return bad_request(start_response) - - -@application.route('/authorize', methods=['GET']) -def get_authorize(environ, start_response): - try: - request = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) - oauth_temp_token = str(request.getvalue('oauth_token')) - transactions = db_session.get_transaction( - Transaction(temp_token=oauth_temp_token, temp_token_valid=1)) - if len(transactions) == 0: - status = "403 Not authorized" - headers = [ ("Content-Type", "text/plain") ] - start_response(status, headers) - return 'Invalid temporary token' - - transaction = transactions[0] - - clients = db_session.get_client(Client(oauth_consumer_key=transaction.oauth_consumer_key)) - if len(clients) == 0: - status = "403 Not authorized" - headers = [ ("Content-Type", "text/plain") ] - start_response(status, headers) - return 'Unregistered client' - client = clients[0] - - transaction.temp_token_valid = 0 - db_session.update_transaction(transaction) - db_session.commit() - styles = ['static/oauth.css'] - css_path = os.path.join( - os.path.dirname(__file__), 'static', 'site.css') - if os.path.exists(css_path): - styles.append("static/site.css") - res = render_template('authorize.html', - client_name=client.name, - client_url=client.home_url, - temp_token=oauth_temp_token, - retry_message="", - stylesheets="\n".join( - [("" % x) for x in styles])) - status = "200 Ok" - headers = [ ("Content-Type", "text/html")] - start_response(status, headers) - return res - except: - return bad_request(start_response) - - -@application.route('/authorize', methods=['POST']) -def post_authorize(environ, start_response): - try: - request = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) - oauth_temp_token = str(request.getvalue('oauth_token')) - username = str(request.getvalue('username')) - passphrase = str(request.getvalue('passphrase')) - - transactions = db_session.get_transaction(Transaction(temp_token=oauth_temp_token)) - transaction = None - if len(transactions) > 0: - transaction = transactions[0] - - clients = db_session.get_client(Client(oauth_consumer_key=transaction.oauth_consumer_key)) - client = None - if len(clients) > 0: - client = clients[0] - cert = None - try: - certreq = "-----BEGIN CERTIFICATE REQUEST-----\n" + str(transaction.certreq) + "-----END CERTIFICATE REQUEST-----\n" - cert = myproxy.myproxy_logon(certreq, - transaction.certlifetime, - username, passphrase, client.myproxy_server) - except: - e = sys.exc_info() - application.logger.error(str(e[1])) - status = "200 Ok" - headers = [ ("Content-Type", "text/html") ] - styles = ['static/oauth.css'] - css_path = os.path.join( - os.path.dirname(__file__), 'static', 'site.css') - if os.path.exists(css_path): - styles.append("static/site.css") - res = render_template('authorize.html', - client_name=client.name, - client_url=client.home_url, - temp_token=oauth_temp_token, - retry_message=str(e[1]), - stylesheets="\n".join( - [("" % x) for x in styles])) - start_response(status, headers, e) - return res - - oauth_verifier = 'myproxy:oa4mp,2012:/verifier/' \ - + ''.join([random.choice('0123456789abcdef') for i in range(32)]) \ - + '/' + str(int(time.time())) - - transaction.oauth_verifier = oauth_verifier - transaction.certificate = cert - transaction.username = username - db_session.update_transaction(transaction) - db_session.commit() - - status = "301 Moved Permanently" - joiner = "?" - if "?" in transaction.oauth_callback: - joiner="&" - headers = [ - ("Location", str("%s%soauth_token=%s&oauth_verifier=%s" % \ - (transaction.oauth_callback, joiner, oauth_temp_token, oauth_verifier)))] - - start_response(status, headers) - return "" - except: - return bad_request(start_response) - -@application.route('/token', methods=['GET']) -def token(environ, start_response): - try: - args = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) - oauth_signature_method = args.getvalue('oauth_signature_method') - if oauth_signature_method is None: - oauth_signature_method='RSA-SHA1' - else: - oauth_signature_method=str(oauth_signature_method) - oauth_signature = str(args.getvalue('oauth_signature')) - oauth_timestamp = int(args.getvalue('oauth_timestamp')) - oauth_nonce = int(args.getvalue('oauth_nonce')) - oauth_version = str(args.getvalue('oauth_version')) - oauth_consumer_key = str(args.getvalue('oauth_consumer_key')) - oauth_temp_token = str(args.getvalue('oauth_token')) - oauth_verifier = str(args.getvalue('oauth_verifier')) - - oauth_access_token = 'myproxy:oa4mp,2012:/accessToken/' \ - + ''.join([random.choice('0123456789abcdef') for i in range(32)]) \ - + '/' + str(int(time.time())) - - transactions = db_session.get_transaction(Transaction(temp_token=oauth_temp_token)) - transaction = None - if len(transactions) > 0: - transaction = transactions[0] - transaction.access_token = oauth_access_token - db_session.update_transaction(transaction) - db_session.commit() - - status = "200 Ok" - headers = [('Content-Type', 'app/x-www-form-urlencoded')] - resp = start_response(status, headers) - return "oauth_token=%s" % str(oauth_access_token) - except: - return bad_request(start_response) - -@application.route('/getcert', methods=['GET']) -def getcert(environ, start_response): - try: - args = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) - oauth_signature_method = args.getvalue('oauth_signature_method') - if oauth_signature_method is None: - oauth_signature_method = 'RSA-SHA1' - else: - oauth_signature_method = str(oauth_signature_method) - oauth_signature = str(args.getvalue('oauth_signature')) - oauth_timestamp = int(args.getvalue('oauth_timestamp')) - oauth_nonce = int(args.getvalue('oauth_nonce')) - oauth_version = str(args.getvalue('oauth_version')) - oauth_consumer_key = str(args.getvalue('oauth_consumer_key')) - oauth_access_token = str(args.getvalue('oauth_token')) - - transactions = db_session.get_transaction( - Transaction(access_token=oauth_access_token)) - transaction = None - if len(transactions) > 0: - transaction = transactions[0] - if transaction is None: - status = "403 Forbidden" - headers = [("Content-Type", "text/plain")] - start_response(status, headers) - return "Invalid access token" - - # Clear database - old_transactions = [(t) for t in db_session.get_transaction() if t.timestamp < int(time.time())] - db_session.delete_transactions(old_transactions) - db_session.commit() - - status = "200 Ok" - headers = [ ("Content-Type", "app/x-www-form-urlencoded") ] - start_response(status, headers) - - return 'username=%s\n%s' % (str(transaction.username), str(transaction.certificate)) - except: - return bad_request(start_response) -# vim: syntax=python: nospell: diff --git a/myproxy/oauth/source/oauth2/README b/myproxy/oauth/source/oauth2/README deleted file mode 100644 index 6ac37b40be..0000000000 --- a/myproxy/oauth/source/oauth2/README +++ /dev/null @@ -1,4 +0,0 @@ -oauth2/__init__.py is downloaded from -https://github.com/simplegeo/python-oauth2/blob/master/oauth2/__init__.py -and fixed to be used by the MyProxy OAuth server. All modifications are -commented in __init__.py. \ No newline at end of file diff --git a/myproxy/oauth/source/oauth2/__init__.py b/myproxy/oauth/source/oauth2/__init__.py deleted file mode 100644 index 7f3f0e270f..0000000000 --- a/myproxy/oauth/source/oauth2/__init__.py +++ /dev/null @@ -1,757 +0,0 @@ -""" -The MIT License - -Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -""" - -import urllib -import time -import random -import urlparse -import hmac -import binascii - -try: - from urlparse import parse_qs, parse_qsl -except ImportError: - from cgi import parse_qs, parse_qsl - -try: - from Crypto.PublicKey import RSA - from Crypto.Util.number import long_to_bytes, bytes_to_long -except ImportError: - RSA=None - -try: - from hashlib import sha1 as sha -except ImportError: - import sha # Deprecated - - -VERSION = '1.0' # Hi Blaine! -HTTP_METHOD = 'GET' -SIGNATURE_METHOD = 'PLAINTEXT' - - -class Error(RuntimeError): - """Generic exception class.""" - - def __init__(self, message='OAuth error occurred.'): - self._message = message - - @property - def message(self): - """A hack to get around the deprecation errors in 2.6.""" - return self._message - - def __str__(self): - return self._message - - -class MissingSignature(Error): - pass - - -def build_authenticate_header(realm=''): - """Optional WWW-Authenticate header (401 error)""" - return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} - - -def build_xoauth_string(url, consumer, token=None): - """Build an XOAUTH string for use in SMTP/IMPA authentication.""" - request = Request.from_consumer_and_token(consumer, token, - "GET", url) - - signing_method = SignatureMethod_HMAC_SHA1() - request.sign_request(signing_method, consumer, token) - - params = [] - for k, v in sorted(request.iteritems()): - if v is not None: - params.append('%s="%s"' % (k, escape(v))) - - return "%s %s %s" % ("GET", url, ','.join(params)) - - -def escape(s): - """Escape a URL including any /.""" - return urllib.quote(s, safe='~') - - -def generate_timestamp(): - """Get seconds since epoch (UTC).""" - return int(time.time()) - - -def generate_nonce(length=8): - """Generate pseudorandom number.""" - return ''.join([str(random.randint(0, 9)) for i in range(length)]) - - -def generate_verifier(length=8): - """Generate pseudorandom number.""" - return ''.join([str(random.randint(0, 9)) for i in range(length)]) - - -class Consumer(object): - """A consumer of OAuth-protected services. - - The OAuth consumer is a "third-party" service that wants to access - protected resources from an OAuth service provider on behalf of an end - user. It's kind of the OAuth client. - - Usually a consumer must be registered with the service provider by the - developer of the consumer software. As part of that process, the service - provider gives the consumer a *key* and a *secret* with which the consumer - software can identify itself to the service. The consumer will include its - key in each request to identify itself, but will use its secret only when - signing requests, to prove that the request is from that particular - registered consumer. - - Once registered, the consumer can then use its consumer credentials to ask - the service provider for a request token, kicking off the OAuth - authorization process. - """ - - key = None - secret = None - - def __init__(self, key, secret): - self.key = key - self.secret = secret - - if self.key is None or self.secret is None: - raise ValueError("Key and secret must be set.") - - def __str__(self): - data = {'oauth_consumer_key': self.key, - 'oauth_consumer_secret': self.secret} - - return urllib.urlencode(data) - - -class Token(object): - """An OAuth credential used to request authorization or a protected - resource. - - Tokens in OAuth comprise a *key* and a *secret*. The key is included in - requests to identify the token being used, but the secret is used only in - the signature, to prove that the requester is who the server gave the - token to. - - When first negotiating the authorization, the consumer asks for a *request - token* that the live user authorizes with the service provider. The - consumer then exchanges the request token for an *access token* that can - be used to access protected resources. - """ - - key = None - secret = None - callback = None - callback_confirmed = None - verifier = None - - def __init__(self, key, secret): - self.key = key - self.secret = secret - - if self.key is None or self.secret is None: - raise ValueError("Key and secret must be set.") - - def set_callback(self, callback): - self.callback = callback - self.callback_confirmed = 'true' - - def set_verifier(self, verifier=None): - if verifier is not None: - self.verifier = verifier - else: - self.verifier = generate_verifier() - - def get_callback_url(self): - if self.callback and self.verifier: - # Append the oauth_verifier. - parts = urlparse.urlparse(self.callback) - scheme, netloc, path, params, query, fragment = parts[:6] - if query: - query = '%s&oauth_verifier=%s' % (query, self.verifier) - else: - query = 'oauth_verifier=%s' % self.verifier - return urlparse.urlunparse((scheme, netloc, path, params, - query, fragment)) - return self.callback - - def to_string(self): - """Returns this token as a plain string, suitable for storage. - - The resulting string includes the token's secret, so you should never - send or store this string where a third party can read it. - """ - - data = { - 'oauth_token': self.key, - 'oauth_token_secret': self.secret, - } - - if self.callback_confirmed is not None: - data['oauth_callback_confirmed'] = self.callback_confirmed - return urllib.urlencode(data) - - @staticmethod - def from_string(s): - """Deserializes a token from a string like one returned by - `to_string()`.""" - - if not len(s): - raise ValueError("Invalid parameter string.") - - params = parse_qs(s, keep_blank_values=False) - if not len(params): - raise ValueError("Invalid parameter string.") - - try: - key = params['oauth_token'][0] - except Exception: - raise ValueError("'oauth_token' not found in OAuth request.") - - try: - secret = params['oauth_token_secret'][0] - except Exception: - raise ValueError("'oauth_token_secret' not found in " - "OAuth request.") - - token = Token(key, secret) - try: - token.callback_confirmed = params['oauth_callback_confirmed'][0] - except KeyError: - pass # 1.0, no callback confirmed. - return token - - def __str__(self): - return self.to_string() - - -def setter(attr): - name = attr.__name__ - - def getter(self): - try: - return self.__dict__[name] - except KeyError: - raise AttributeError(name) - - def deleter(self): - del self.__dict__[name] - - return property(getter, attr, deleter) - - -class Request(dict): - - """The parameters and information for an HTTP request, suitable for - authorizing with OAuth credentials. - - When a consumer wants to access a service's protected resources, it does - so using a signed HTTP request identifying itself (the consumer) with its - key, and providing an access token authorized by the end user to access - those resources. - - """ - - version = VERSION - - def __init__(self, method=HTTP_METHOD, url=None, parameters=None): - self.method = method - self.url = url - if parameters is not None: - self.update(parameters) - - @setter - def url(self, value): - self.__dict__['url'] = value - if value is not None: - scheme, netloc, path, params, query, fragment = urlparse.urlparse(value) - - # Exclude default port numbers. - if scheme == 'http' and netloc[-3:] == ':80': - netloc = netloc[:-3] - elif scheme == 'https' and netloc[-4:] == ':443': - netloc = netloc[:-4] - if scheme not in ('http', 'https'): - raise ValueError("Unsupported URL %s (%s)." % (value, scheme)) - - # Normalized URL excludes params, query, and fragment. - self.normalized_url = urlparse.urlunparse((scheme, netloc, path, None, None, None)) - else: - self.normalized_url = None - self.__dict__['url'] = None - - @setter - def method(self, value): - self.__dict__['method'] = value.upper() - - def _get_timestamp_nonce(self): - return self['oauth_timestamp'], self['oauth_nonce'] - - def get_nonoauth_parameters(self): - """Get any non-OAuth parameters.""" - return dict([(k, v) for k, v in self.iteritems() - if not k.startswith('oauth_')]) - - def to_header(self, realm=''): - """Serialize as a header for an HTTPAuth request.""" - oauth_params = ((k, v) for k, v in self.items() - if k.startswith('oauth_')) - stringy_params = ((k, escape(str(v))) for k, v in oauth_params) - header_params = ('%s="%s"' % (k, v) for k, v in stringy_params) - params_header = ', '.join(header_params) - - auth_header = 'OAuth realm="%s"' % realm - if params_header: - auth_header = "%s, %s" % (auth_header, params_header) - - return {'Authorization': auth_header} - - def to_postdata(self): - """Serialize as post data for a POST request.""" - # tell urlencode to deal with sequence values and map them correctly - # to resulting querystring. for example self["k"] = ["v1", "v2"] will - # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D - return urllib.urlencode(self, True).replace('+', '%20') - - def to_url(self): - """Serialize as a URL for a GET request.""" - base_url = urlparse.urlparse(self.url) - try: - query = base_url.query - except AttributeError: - # must be python <2.5 - query = base_url[4] - query = parse_qs(query) - for k, v in self.items(): - query.setdefault(k, []).append(v) - - try: - scheme = base_url.scheme - netloc = base_url.netloc - path = base_url.path - params = base_url.params - fragment = base_url.fragment - except AttributeError: - # must be python <2.5 - scheme = base_url[0] - netloc = base_url[1] - path = base_url[2] - params = base_url[3] - fragment = base_url[5] - - url = (scheme, netloc, path, params, - urllib.urlencode(query, True), fragment) - return urlparse.urlunparse(url) - - def get_parameter(self, parameter): - ret = self.get(parameter) - if ret is None: - raise Error('Parameter not found: %s' % parameter) - - return ret - - def get_normalized_parameters(self): - """Return a string that contains the parameters that must be signed.""" - items = [] - for key, value in self.iteritems(): - if key == 'oauth_signature': - continue - # 1.0a/9.1.1 states that kvp must be sorted by key, then by value, - # so we unpack sequence values into multiple items for sorting. - if hasattr(value, '__iter__'): - items.extend((key, item) for item in value) - else: - items.append((key, value)) - - # Include any query string parameters from the provided URL - query = urlparse.urlparse(self.url)[4] - - url_items = self._split_url_string(query).items() -# What the heck are the two lines below for? They duplicate non-oauth parameters in signature base string. -# non_oauth_url_items = list([(k, v) for k, v in url_items if not k.startswith('oauth_')]) -# items.extend(non_oauth_url_items) - - encoded_str = urllib.urlencode(sorted(items)) - # Encode signature parameters per Oauth Core 1.0 protocol - # spec draft 7, section 3.6 - # (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6) - # Spaces must be encoded with "%20" instead of "+" - return encoded_str.replace('+', '%20').replace('%7E', '~') - - def sign_request(self, signature_method, consumer, token): - """Set the signature parameter to the result of sign.""" - - if 'oauth_consumer_key' not in self: - self['oauth_consumer_key'] = consumer.key - - if token and 'oauth_token' not in self: - self['oauth_token'] = token.key - - self['oauth_signature_method'] = signature_method.name - self['oauth_signature'] = signature_method.sign(self, consumer, token) - - @classmethod - def make_timestamp(cls): - """Get seconds since epoch (UTC).""" - return str(int(time.time())) - - @classmethod - def make_nonce(cls): - """Generate pseudorandom number.""" - return str(random.randint(0, 100000000)) - - @classmethod - def from_request(cls, http_method, http_url, headers=None, parameters=None, - query_string=None): - """Combines multiple parameter sources.""" - if parameters is None: - parameters = {} - - # Headers - if headers and 'Authorization' in headers: - auth_header = headers['Authorization'] - # Check that the authorization header is OAuth. - if auth_header[:6] == 'OAuth ': - auth_header = auth_header[6:] - try: - # Get the parameters from the header. - header_params = cls._split_header(auth_header) - parameters.update(header_params) - except: - raise Error('Unable to parse OAuth parameters from ' - 'Authorization header.') - - # GET or POST query string. - if query_string: - query_params = cls._split_url_string(query_string) - parameters.update(query_params) - - # URL parameters. - param_str = urlparse.urlparse(http_url)[4] # query - url_params = cls._split_url_string(param_str) - parameters.update(url_params) - - if parameters: - return cls(http_method, http_url, parameters) - - return None - - @classmethod - def from_consumer_and_token(cls, consumer, token=None, - http_method=HTTP_METHOD, http_url=None, parameters=None): - if not parameters: - parameters = {} - - defaults = { - 'oauth_consumer_key': consumer.key, - 'oauth_timestamp': cls.make_timestamp(), - 'oauth_nonce': cls.make_nonce(), - 'oauth_version': cls.version, - } - - defaults.update(parameters) - parameters = defaults - - if token: - parameters['oauth_token'] = token.key - if token.verifier: - parameters['oauth_verifier'] = token.verifier - - return Request(http_method, http_url, parameters) - - @classmethod - def from_token_and_callback(cls, token, callback=None, - http_method=HTTP_METHOD, http_url=None, parameters=None): - - if not parameters: - parameters = {} - - parameters['oauth_token'] = token.key - - if callback: - parameters['oauth_callback'] = callback - - return cls(http_method, http_url, parameters) - - @staticmethod - def _split_header(header): - """Turn Authorization: header into parameters.""" - params = {} - parts = header.split(',') - for param in parts: - # Ignore realm parameter. - if param.find('realm') > -1: - continue - # Remove whitespace. - param = param.strip() - # Split key-value. - param_parts = param.split('=', 1) - # Remove quotes and unescape the value. - params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"')) - return params - - @staticmethod - def _split_url_string(param_str): - """Turn URL string into parameters.""" - parameters = parse_qs(param_str, keep_blank_values=False) - for k, v in parameters.iteritems(): - parameters[k] = urllib.unquote(v[0]) - return parameters - - -class Server(object): - """A skeletal implementation of a service provider, providing protected - resources to requests from authorized consumers. - - This class implements the logic to check requests for authorization. You - can use it with your web server or web framework to protect certain - resources with OAuth. - """ - - timestamp_threshold = 300 # In seconds, five minutes. - version = VERSION - signature_methods = None - - def __init__(self, signature_methods=None): - self.signature_methods = signature_methods or {} - - def add_signature_method(self, signature_method): - self.signature_methods[signature_method.name] = signature_method - return self.signature_methods - - def verify_request(self, request, consumer, token): - """Verifies an api call and checks all the parameters.""" - - version = self._get_version(request) - self._check_signature(request, consumer, token) - parameters = request.get_nonoauth_parameters() - return parameters - - def build_authenticate_header(self, realm=''): - """Optional support for the authenticate header.""" - return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} - - def _get_version(self, request): - """Verify the correct version request for this server.""" - try: - version = request.get_parameter('oauth_version') - except: - version = VERSION - - if version and version != self.version: - raise Error('OAuth version %s not supported.' % str(version)) - - return version - - def _get_signature_method(self, request): - """Figure out the signature with some defaults.""" - try: - signature_method = request.get_parameter('oauth_signature_method') - except: - signature_method = SIGNATURE_METHOD - - try: - # Get the signature method object. - signature_method = self.signature_methods[signature_method] - except: - signature_method_names = ', '.join(self.signature_methods.keys()) - raise Error('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names)) - - return signature_method - - def _get_verifier(self, request): - return request.get_parameter('oauth_verifier') - - def _check_signature(self, request, consumer, token): - timestamp, nonce = request._get_timestamp_nonce() - self._check_timestamp(timestamp) - signature_method = self._get_signature_method(request) - - try: - signature = request.get_parameter('oauth_signature') - except: - raise MissingSignature('Missing oauth_signature.') - - # Validate the signature. - valid = signature_method.check(request, consumer, token, signature) - - if not valid: - key, base = signature_method.signing_base(request, consumer, token) - - raise Error('Invalid signature. Expected signature base ' - 'string: %s' % base) - -# Why does the server sign anything if only client knows a private key? -# built = signature_method.sign(request, consumer, token) - - def _check_timestamp(self, timestamp): - """Verify that timestamp is recentish.""" - timestamp = int(timestamp) - now = int(time.time()) - lapsed = now - timestamp - if lapsed > self.timestamp_threshold: - raise Error('Expired timestamp: given %d and now %s has a ' - 'greater difference than threshold %d' % (timestamp, now, - self.timestamp_threshold)) - - -class SignatureMethod(object): - """A way of signing requests. - - The OAuth protocol lets consumers and service providers pick a way to sign - requests. This interface shows the methods expected by the other `oauth` - modules for signing requests. Subclass it and implement its methods to - provide a new way to sign requests. - """ - - def signing_base(self, request, consumer, token): - """Calculates the string that needs to be signed. - - This method returns a 2-tuple containing the starting key for the - signing and the message to be signed. The latter may be used in error - messages to help clients debug their software. - - """ - raise NotImplementedError - - def sign(self, request, consumer, token): - """Returns the signature for the given request, based on the consumer - and token also provided. - - You should use your implementation of `signing_base()` to build the - message to sign. Otherwise it may be less useful for debugging. - - """ - raise NotImplementedError - - def check(self, request, consumer, token, signature): - """Returns whether the given signature is the correct signature for - the given consumer and token signing the given request.""" - built = self.sign(request, consumer, token) - return built == signature - - -class SignatureMethod_HMAC_SHA1(SignatureMethod): - name = 'HMAC-SHA1' - - def signing_base(self, request, consumer, token): - if request.normalized_url is None: - raise ValueError("Base URL for request is not set.") - - sig = ( - escape(request.method), - escape(request.normalized_url), - escape(request.get_normalized_parameters()), - ) - - key = '%s&' % escape(consumer.secret) - if token: - key += escape(token.secret) - raw = '&'.join(sig) - return key, raw - - def sign(self, request, consumer, token): - """Builds the base signature string.""" - key, raw = self.signing_base(request, consumer, token) - - # HMAC object. - hashed = hmac.new(key, raw, sha) - - # Calculate the digest base 64. - return binascii.b2a_base64(hashed.digest())[:-1] - - -class SignatureMethod_RSA_SHA1(SignatureMethod): - name = 'RSA-SHA1' - - def signing_base(self, request, consumer, token): - if request.normalized_url is None: - raise ValueError("Base URL for request is not set.") - - sig = ( - escape(request.method), - escape(request.normalized_url), - escape(request.get_normalized_parameters()), - ) - - key = consumer.secret - raw = '&'.join(sig) - return key, raw - - def sign(self, request, consumer, token): - """Builds the base signature string.""" - if RSA is None: raise NotImplementedError, self.name - key, raw = self.signing_base(request, consumer, token) - - digest = sha(raw).digest() - sig = key.sign(self._pkcs1imify(key, digest), '')[0] - sig_bytes = long_to_bytes(sig) - # Calculate the digest base 64. - return binascii.b2a_base64(sig_bytes)[:-1] - - def check(self, request, consumer, token, signature): - """Returns whether the given signature is the correct signature for - the given consumer and token signing the given request.""" - if RSA is None: raise NotImplementedError, self.name - key, raw = self.signing_base(request, consumer, token) - - digest = sha(raw).digest() - sig = bytes_to_long(binascii.a2b_base64(signature)) - data = self._pkcs1imify(key, digest) - - pubkey = key.publickey() - return pubkey.verify(data, (sig,)) - - @staticmethod - def _pkcs1imify(key, data): - """Adapted from paramiko - - turn a 20-byte SHA1 hash into a blob of data as large as the key's N, - using PKCS1's \"emsa-pkcs1-v1_5\" encoding. totally bizarre. - """ - SHA1_DIGESTINFO = '\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14' - size = len(long_to_bytes(key.n)) - filler = '\xff' * (size - len(SHA1_DIGESTINFO) - len(data) - 3) - return '\x00\x01' + filler + '\x00' + SHA1_DIGESTINFO + data - - - -class SignatureMethod_PLAINTEXT(SignatureMethod): - - name = 'PLAINTEXT' - - def signing_base(self, request, consumer, token): - """Concatenates the consumer key and secret with the token's - secret.""" - sig = '%s&' % escape(consumer.secret) - if token: - sig = sig + escape(token.secret) - return sig, sig - - def sign(self, request, consumer, token): - key, raw = self.signing_base(request, consumer, token) - return raw diff --git a/myproxy/oauth/source/setup.py b/myproxy/oauth/source/setup.py deleted file mode 100644 index 73028b7e01..0000000000 --- a/myproxy/oauth/source/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/python - -from distutils.core import setup - -setup(name = 'myproxy_oauth', - version = '1.2', - description = 'MyProxy OAuth Delegation Service', - author = 'Globus Toolkit', - author_email = 'support@globus.org', - packages = [ - 'myproxy', - 'myproxyoauth', - 'myproxyoauth.templates', - 'myproxyoauth.static', - 'oauth2'], - package_data = { - 'myproxyoauth': [ 'templates/*.html', 'static/*.png', 'static/*.css' ] - }, - scripts = [ 'wsgi.py', 'myproxy-oauth-setup' ], - data_files = [ - ('apache', [ - 'conf/myproxy-oauth', - 'conf/myproxy-oauth-2.4', - 'conf/myproxy-oauth-2.4-deb', - 'conf/myproxy-oauth-epel5' ])] -) diff --git a/myproxy/oauth/source/wsgi.py b/myproxy/oauth/source/wsgi.py deleted file mode 100644 index 257f45323e..0000000000 --- a/myproxy/oauth/source/wsgi.py +++ /dev/null @@ -1,153 +0,0 @@ -#! /usr/bin/python2 -# -# Copyright 2010-2011 University of Chicago -# -# 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. -# - -import os -import pwd -import sys -import socket -import logging -import getopt - -BASE_DIR = os.path.abspath(os.path.dirname(__file__)) - -sys.path.insert(0, BASE_DIR) - -root = "/oauth" - -import ssl -from wsgiref.simple_server import WSGIServer, WSGIRequestHandler - - -class SecureWSGIServer(WSGIServer): - def set_credentials( self, keypath=None, certpath=None): - self.keypath = keypath - self.certpath = certpath - - def get_request(self): - (sock, addr) = WSGIServer.get_request(self) - ssock = ssl.wrap_socket(sock, - keyfile=self.keypath, certfile=self.certpath, server_side=True) - return (ssock, addr) - - def close_request(self, request): - try: - request.shutdown(socket.SHUT_RDWR) - request.close() - except Exception, e: - print "Exception closing request" + str(e) - -class SecureWSGIRequestHandler( WSGIRequestHandler): - """An SSL-aware WSGIRequestHandler, which sets HTTPS environment variables. - """ - #xxx todo: set SSL_PROTOCOL, maybe others - def get_environ( self): - env = WSGIRequestHandler.get_environ( self) - if isinstance( self.request, ssl.SSLSocket): - env['HTTPS'] = 'on' - # JB: Add handling of wsgi.url_scheme - env['wsgi.url_scheme'] = 'https' - # JB: Add handling of script name - if env['SCRIPT_NAME'] == "" and env['PATH_INFO'].startswith(root): - env['SCRIPT_NAME'] = root - env['PATH_INFO'] = env['PATH_INFO'][len(root):] - return env - -if __name__ == "__main__": - opts, args = getopt.getopt(sys.argv[1:],"c:k:u:p:bf:l:h") - certfile = None - keyfile = None - user = None - port = 443 - pidfile = None - log_level = logging.WARN - background = False - for (opt, param) in opts: - if opt == '-c': - certfile = param - elif opt == '-k': - keyfile = param - elif opt == '-u': - user = param - elif opt == '-p': - port = int(param) - elif opt == '-b': - background = True - elif opt == '-f': - pidfile = param - elif opt == '-l': - log_level_str = param - log_level = getattr(logging, log_level_str) - elif opt == '-h': - print "Usage %s [-c CERT-FILE] [-k KEYFILE] [-u USER] [-p PORT] | [-h]\n" %(sys.argv[0]) - sys.exit(0) - if certfile is None: - certfile = os.environ.get("X509_USER_CERT") - if certfile is None: - certfile = "/etc/grid-security/hostcert.pem" - if keyfile is None: - keyfile = os.environ.get("X509_USER_KEY") - if keyfile is None: - keyfile = "/etc/grid-security/hostkey.pem" - - pid = 0 - if background: - pid = os.fork() - if pid < 0: - print >>sys.stderr, "Error forking background process" - sys.exit(1) - elif pid > 0: - print "Running in background (%d)" % (pid) - if pidfile is not None: - pid_fd = file(pidfile, "w") - try: - pid_fd.write("%d\n" % (pid)) - finally: - pid_fd.close() - sys.exit(0); - elif pid == 0: - os.setsid() - os.close(sys.stdin.fileno()) - sys.stdin = open(os.devnull, "r") - os.close(sys.stdout.fileno()) - sys.stdout = open(os.devnull, "a") - os.close(sys.stderr.fileno()) - sys.stderr = open(os.devnull, "a") - - server = SecureWSGIServer(("0.0.0.0", port), SecureWSGIRequestHandler) - if pidfile is not None: - f = file(pidfile, "w") - try: - print >>f, str(os.getpid()) - finally: - f.close() - if os.getuid() == 0 and user is not None: - os.seteuid(pwd.getpwnam(user)[2]) - # import after setuid due to side-effects of import (creating db) - from myproxyoauth import application - application.logger.setLevel(log_level) - server.set_app(application) - server.set_credentials(keypath=keyfile,certpath=certfile) - try: - server.serve_forever() - finally: - if pidfile is not None: - if os.getuid() != os.geteuid(): - os.setuid(os.getuid()) - os.path.remove(pidfile) -else: - from myproxyoauth import application -# vim:filetype=python:nospell: diff --git a/packaging/debian/myproxy-oauth/debian/changelog.in b/packaging/debian/myproxy-oauth/debian/changelog.in deleted file mode 100644 index e3e4ba0d80..0000000000 --- a/packaging/debian/myproxy-oauth/debian/changelog.in +++ /dev/null @@ -1,208 +0,0 @@ -myproxy-oauth (1.2-1+gct.@distro@) @distro@; urgency=medium - - * Explicitly py2 - - -- Globus Toolkit Fri, 10 May 2019 14:16:25 -0400 - -myproxy-oauth (1.1-1+gct.@distro@) @distro@; urgency=medium - - * Allow newer TLS versions - - -- Globus Toolkit Mon, 14 May 2018 14:16:25 -0400 - -myproxy-oauth (1.0-1+gct.@distro@) @distro@; urgency=medium - - * First Grid Community Toolkit release - - -- Mattias Ellert Tue, 03 Apr 2018 10:33:10 +0200 - -myproxy-oauth (0.27-1+gt6.@distro@) @distro@; urgency=low - - * Revert previous - - -- Globus Toolkit Mon, 18 Dec 2017 14:45:44 -0500 - -myproxy-oauth (0.26-1+gt6.@distro@) @distro@; urgency=low - - * Move apache config file deployment into setup script - - -- Globus Toolkit Mon, 13 Mar 2017 16:34:10 -0400 - -myproxy-oauth (0.25-1+gt6.@distro@) @distro@; urgency=low - - * Python exception handling workaround for 2.5-3.x - - -- Globus Toolkit Thu, 10 Nov 2016 15:52:39 -0500 - -myproxy-oauth (0.24-1+gt6.@distro@) @distro@; urgency=low - - * Verify all paths yield proper response or error response - - -- Globus Toolkit Wed, 09 Nov 2016 14:05:06 -0500 - -myproxy-oauth (0.23-1+gt6.@distro@) @distro@; urgency=low - - * Fix indent issue - - -- Globus Toolkit Fri, 04 Nov 2016 13:02:00 -0400 - -myproxy-oauth (0.22-1+gt6.@distro@) @distro@; urgency=low - - * Catch exceptions and return "400 Bad Request" - - -- Globus Toolkit Tue, 18 Oct 2016 14:41:29 -0400 - -myproxy-oauth (0.21-2+gt6.@distro@) @distro@; urgency=low - - * Fix redirect when callback_uri contains a query - - -- Globus Toolkit Thu, 10 Mar 2016 11:17:33 -0500 - -myproxy-oauth (0.20-1+gt6.@distro@) @distro@; urgency=low - - * Use setsebool if it is installed and semanage is not available - - -- Globus Toolkit Thu, 29 Oct 2015 08:53:56 -0400 - -myproxy-oauth (0.19-2+gt6.@distro@) @distro@; urgency=low - - * Add lsb-release build dependency - - -- Globus Toolkit Mon, 27 Apr 2015 09:16:09 -0400 - -myproxy-oauth (0.19-1+gt6.@distro@) @distro@; urgency=low - - * Use TLSv1 - * Support for apache-2.4 versions on debian - - -- Globus Toolkit Thu, 23 Apr 2015 11:26:03 -0400 - -myproxy-oauth (0.18-3+gt6.@distro@) @distro@; urgency=low - - * Run selinux commands as root - * Run database commands as myproxyoauth - * Remove python-httplib2 dependency in unused code - * Add python build dependency - * build and install when building with -A - - -- Globus Toolkit Tue, 11 Nov 2014 17:07:07 -0500 - -myproxy-oauth (0.15-3+gt6.@distro@) @distro@; urgency=low - - * Change section from unknown to net - - -- Globus Toolkit Wed, 03 Sep 2014 21:35:18 -0400 - -myproxy-oauth (0.15-2+gt6.@distro@) @distro@; urgency=low - - * Handle Ubuntu 14.04 apache2 configuation layout - - -- Globus Toolkit Fri, 01 Aug 2014 13:27:42 -0400 - -myproxy-oauth (0.15-1+gt6.@distro@) @distro@; urgency=low - - * EC2-Aware public hostname - - -- Globus Toolkit Thu, 31 Jul 2014 13:48:06 -0400 - -myproxy-oauth (0.14-1+gt6.@distro@) @distro@; urgency=low - - * Distro-tag package version - - -- Globus Toolkit Mon, 02 Jun 2014 14:35:22 -0400 - -myproxy-oauth (0.14-1) unstable; urgency=low - - * Move to globus repo - - -- Globus Toolkit Mon, 20 Jan 2014 09:53:11 -0500 - -myproxy-oauth (0.13-2) unstable; urgency=low - - * Fix regression on python path setting - - -- Globus Toolkit Fri, 25 Oct 2013 13:17:59 -0400 - -myproxy-oauth (0.13-1) unstable; urgency=low - - * Fix regression on python path setting - - -- Globus Toolkit Wed, 04 Sep 2013 15:51:46 -0400 - -myproxy-oauth (0.12-1) unstable; urgency=low - - * Fall back to pysqlite2 when sqlite3 is not available - - -- Globus Toolkit Wed, 04 Sep 2013 14:05:27 -0400 - -myproxy-oauth (0.11-1) unstable; urgency=low - - * Removed dependency on sqlalchemy - - -- Globus Toolkit Wed, 04 Sep 2013 12:29:59 -0400 - -myproxy-oauth (0.10-1) unstable; urgency=low - - * Removed dependency on jinja2 - - -- Globus Toolkit Fri, 23 Aug 2013 12:31:29 -0400 - -myproxy-oauth (0.9-1) unstable; urgency=low - - * Fix missing import of subprocess when SElinux is used - - -- Globus Toolkit Thu, 06 Jun 2013 09:32:22 -0400 - -myproxy-oauth (0.8-1) unstable; urgency=low - - * enable mod_wsgi for epel5 distros - - -- Globus Toolkit Fri, 31 May 2013 14:00:50 -0400 - -myproxy-oauth (0.7-1) unstable; urgency=low - - * SELinux label db file - - -- Globus Toolkit Tue, 07 May 2013 11:17:04 -0400 - -myproxy-oauth (0.6-1) unstable; urgency=low - - * offline setup - - -- Globus Toolkit Tue, 07 May 2013 16:22:21 -0400 - -myproxy-oauth (0.5-1) unstable; urgency=low - - * import application - - -- Globus Toolkit Tue, 09 Apr 2013 14:31:28 -0400 - -myproxy-oauth (0.4-1) unstable; urgency=low - - * Fix MANIFEST.in - - -- Globus Toolkit Tue, 09 Apr 2013 12:39:52 -0400 - -myproxy-oauth (0.3-1) unstable; urgency=low - - * Init script - - -- Globus Toolkit Tue, 09 Apr 2013 11:11:31 -0400 - -myproxy-oauth (0.2-1) unstable; urgency=low - - * Updates to work on rhel 5, 6 - - -- Globus Toolkit Mon, 08 Apr 2013 10:44:52 -0400 - -myproxy-oauth (0.1-1) unstable; urgency=low - - * Updates to work on deb6, ubuntu 10.04 - - -- Globus Toolkit Fri, 05 Apr 2013 12:39:59 -0400 - -myproxy-oauth (0.0-1) unstable; urgency=low - - * Initial packaging - - -- Globus Toolkit Thu, 28 Mar 2013 05:36:05 -0400 diff --git a/packaging/debian/myproxy-oauth/debian/compat b/packaging/debian/myproxy-oauth/debian/compat deleted file mode 100644 index ec635144f6..0000000000 --- a/packaging/debian/myproxy-oauth/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/packaging/debian/myproxy-oauth/debian/control b/packaging/debian/myproxy-oauth/debian/control deleted file mode 100644 index 22bab52f35..0000000000 --- a/packaging/debian/myproxy-oauth/debian/control +++ /dev/null @@ -1,19 +0,0 @@ -Source: myproxy-oauth -Section: net -Priority: optional -Maintainer: Mattias Ellert -Build-Depends: debhelper (>= 9), python, lsb-release -Standards-Version: 4.1.3 - -Package: myproxy-oauth -Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.5), python-crypto (>=2.2) | python-m2crypto, python-crypto (>= 2.0), python-openssl, libapache2-mod-wsgi, apache2 -Description: myproxy-oauth - The Grid Community Toolkit (GCT) is an open source software toolkit used for - building grid systems and applications. It is a fork of the Globus Toolkit - originally created by the Globus Alliance. It is supported by the Grid - Community Forum (GridCF) that provides community-based support for core - software packages in grid computing. - . - The myproxy-oauth package contains: - MyProxy OAuth Delegation Service diff --git a/packaging/debian/myproxy-oauth/debian/copyright b/packaging/debian/myproxy-oauth/debian/copyright deleted file mode 100644 index a54a79e22c..0000000000 --- a/packaging/debian/myproxy-oauth/debian/copyright +++ /dev/null @@ -1,20 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: myproxy_oauth -Upstream-Contact: https://github.com/gridcf/gct/ - -Files: * -Copyright: - 2012-2019 University of Chicago - 2018-2019 Grid Community Forum -License: Apache-2.0 - 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. diff --git a/packaging/debian/myproxy-oauth/debian/myproxy-oauth-setup.in b/packaging/debian/myproxy-oauth/debian/myproxy-oauth-setup.in deleted file mode 100644 index 319816a3e7..0000000000 --- a/packaging/debian/myproxy-oauth/debian/myproxy-oauth-setup.in +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/sh -if [ "$(id -u)" = 0 ]; then - idarg="-i $(id -u myproxyoauth)" -fi -export PYTHONPATH="@PYTHONPATH@" -exec /usr/bin/python /usr/share/myproxy-oauth/myproxy-oauth-setup "$@" ${idarg} diff --git a/packaging/debian/myproxy-oauth/debian/myproxy-oauth.postinst b/packaging/debian/myproxy-oauth/debian/myproxy-oauth.postinst deleted file mode 100644 index 5c13080c37..0000000000 --- a/packaging/debian/myproxy-oauth/debian/myproxy-oauth.postinst +++ /dev/null @@ -1,22 +0,0 @@ -#! /bin/sh - -case "$1" in - configure) - getent group myproxyoauth > /dev/null || groupadd -r myproxyoauth - - getent passwd myproxyoauth > /dev/null || \ - useradd -r -g myproxyoauth -d /usr/share/myproxy-oauth \ - -s /bin/nologin \ - -c "User to run the MyProxy OAuth service" myproxyoauth - install -d /var/lib/myproxy-oauth -o myproxyoauth \ - -g myproxyoauth -m 0700 - ;; - abort-upgrade) - ;; - abort-remove) - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/packaging/debian/myproxy-oauth/debian/rules b/packaging/debian/myproxy-oauth/debian/rules deleted file mode 100755 index 50e5b7ea95..0000000000 --- a/packaging/debian/myproxy-oauth/debian/rules +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -# export DH_VERBOSE=1 - -INSTALLDIR = $(CURDIR)/debian/tmp -libdir = /usr/share -sbindir = /usr/sbin -name = myproxy-oauth - -os_vendor:=$(shell lsb_release -is) -os_version:=$(shell lsb_release -rs) - -ifeq (Ubuntu,$(os_vendor)) - ifeq (0, $(shell [ `echo $(os_version) | tr -d .` -lt 1404 ] && echo 0)) - apacheconfdir=/etc/apache2/conf.d - else - apacheconfdir=/etc/apache2/conf-available - apacheconf_suffix=-2.4-deb - endif -else - ifeq (Debian,$(os_vendor)) - ifeq (0, $(shell [ `echo $(os_version) | cut -d . -f1` -lt 8 ] && echo 0)) - apacheconfdir=/etc/apache2/conf.d - else - apacheconfdir=/etc/apache2/conf-available - apacheconf_suffix=-2.4-deb - endif - else - apacheconfdir=/etc/apache2/conf.d - endif -endif - -%: - dh $@ - -clean: - dh clean - python setup.py clean -a - rm -f debian/myproxy-oauth.install - rm -f build-stamp - -build: build-stamp - : - -build-stamp: - python setup.py build - touch $@ - -install-stamp: build-stamp - python setup.py install --install-layout=deb \ - --root=$(INSTALLDIR) --no-compile \ - --install-lib /usr/share/$(name) \ - --install-scripts /usr/share/$(name) \ - --install-data /usr/share/doc/$(name) - mkdir -p $(INSTALLDIR)$(apacheconfdir) - mkdir -p $(INSTALLDIR)$(sbindir) - sed -e s'!@PYTHONPATH@!/usr/share/$(name)!' \ - < $(CURDIR)/debian/myproxy-oauth-setup.in \ - > $(INSTALLDIR)/$(sbindir)/myproxy-oauth-setup - chmod 0755 $(INSTALLDIR)/$(sbindir)/myproxy-oauth-setup - cp $(INSTALLDIR)/usr/share/doc/$(name)/apache/$(name)$(apacheconf_suffix) \ - $(INSTALLDIR)$(apacheconfdir)/$(name).conf - find debian/tmp -type f | while read filename; do \ - echo "$$filename" |sed -e s"|debian/tmp/||"; \ - done > debian/myproxy-oauth.install - dh_install - -install: install-stamp - : - -binary-indep: install - dh $@ - -binary: install - dh $@ - -.PHONY: clean build install binary binary-indep diff --git a/packaging/debian/myproxy-oauth/debian/source/format b/packaging/debian/myproxy-oauth/debian/source/format deleted file mode 100644 index 163aaf8d82..0000000000 --- a/packaging/debian/myproxy-oauth/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/packaging/fedora/ORDERING b/packaging/fedora/ORDERING index 7c74c714d0..6754ff8f6b 100644 --- a/packaging/fedora/ORDERING +++ b/packaging/fedora/ORDERING @@ -46,7 +46,6 @@ globus-xio-gridftp-driver globus-gridmap-verify-myproxy-callout globus-proxy-utils myproxy -myproxy-oauth globus-xioperf globus-gatekeeper globus-gram-client-tools diff --git a/packaging/fedora/myproxy-oauth.spec b/packaging/fedora/myproxy-oauth.spec deleted file mode 100644 index ccb34cebe1..0000000000 --- a/packaging/fedora/myproxy-oauth.spec +++ /dev/null @@ -1,206 +0,0 @@ -%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}} - -Name: myproxy-oauth -%global _name %(echo %{name} | tr - _) -Version: 1.2 -Release: 1%{?dist} -Summary: MyProxy OAuth Delegation Service - -Group: System Environment/Libraries -License: %{?suse_version:Apache-2.0}%{!?suse_version:ASL 2.0} -URL: https://github.com/gridcf/gct/ -Source: %{_name}-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -BuildRequires: python2 -BuildArch: noarch - -%if %{?fedora}%{!?fedora:0} >= 26 -Requires: python2-pyOpenSSL -%else -Requires: pyOpenSSL -%endif - -%if 0%{?suse_version} == 0 -Requires: mod_ssl -%if %{?fedora}%{!?fedora:0} >= 28 -Requires: python2-mod_wsgi -%else -Requires: mod_wsgi -%endif -Requires(pre): shadow-utils -%else -# Available from http://download.opensuse.org/repositories/Apache/SLE_11_SP3/Apache.repo -Requires: apache2 >= 2.4 -# Available from http://download.opensuse.org/repositories/Apache:/Modules/Apache_SLE_12_SP1/Apache:Modules.repo -Requires: apache2-mod_wsgi -Requires(pre): shadow -%endif - -%if 0%{?rhel} == 6 -Requires: python-crypto -Requires: m2crypto -%else -%if 0%{?suse_version} > 0 -Requires: python-crypto -Requires: python-m2crypto -%else -Requires: python2-crypto -Requires: m2crypto -%endif -%endif - -%description -The Grid Community Toolkit (GCT) is an open source software toolkit used for -building grid systems and applications. It is a fork of the Globus Toolkit -originally created by the Globus Alliance. It is supported by the Grid -Community Forum (GridCF) that provides community-based support for core -software packages in grid computing. - -The %{name} package contains: -MyProxy OAuth Delegation Service - -%prep -%setup -q -n %{_name}-%{version} - -%build -: - -%install -%{__python2} setup.py install \ - --install-lib /usr/share/%{name} \ - --install-scripts /usr/share/%{name} \ - --install-data %{_pkgdocdir} \ - --root $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT/%{_pkgdocdir} -cp README.md $RPM_BUILD_ROOT%{_pkgdocdir}/README.txt -mkdir -p $RPM_BUILD_ROOT/%{_sbindir} -pythonpath="/usr/share/%{name}" -cat > $RPM_BUILD_ROOT%{_sbindir}/myproxy-oauth-setup <= 18 || 0%{?rhel} >= 7 -mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d -cp $RPM_BUILD_ROOT%{_pkgdocdir}/apache/myproxy-oauth-2.4 \ - $RPM_BUILD_ROOT/etc/httpd/conf.d/wsgi-myproxy-oauth.conf -%else -%if 0%{?suse_version} > 0 -mkdir -p $RPM_BUILD_ROOT/etc/apache2/conf.d -cp $RPM_BUILD_ROOT%{_pkgdocdir}/apache/myproxy-oauth-2.4 \ - $RPM_BUILD_ROOT/etc/apache2/conf.d/wsgi-myproxy-oauth.conf -%else -mkdir -p $RPM_BUILD_ROOT/etc/httpd/conf.d -cp $RPM_BUILD_ROOT%{_pkgdocdir}/apache/myproxy-oauth \ - $RPM_BUILD_ROOT/etc/httpd/conf.d/wsgi-myproxy-oauth.conf -%endif -%endif - -mkdir -p "$RPM_BUILD_ROOT/var/lib/myproxy-oauth" - -%pre -getent group myproxyoauth >/dev/null || groupadd -r myproxyoauth -getent passwd myproxyoauth >/dev/null || \ - useradd -r -g myproxyoauth -d /usr/share/myproxy-oauth -s /sbin/nologin \ - -c "MyProxy Oauth Daemon" myproxyoauth - -%if 0%{?suse_version} != 0 -mkdir -p /srv/www/run -%endif - -exit 0 - -%files -%defattr(-,root,root,-) -%if %{?suse_version}%{!?suse_version:0} -%dir %{_sysconfdir}/apache2 -%dir %{_sysconfdir}/apache2/conf.d -%endif -%dir %{_pkgdocdir} -%doc %{_pkgdocdir}/README.txt -%dir %{_pkgdocdir}/apache -%doc %{_pkgdocdir}/apache/* -%config(noreplace) /etc/*/conf.d/wsgi-myproxy-oauth.conf -%dir %attr(0700,myproxyoauth,myproxyoauth) /var/lib/myproxy-oauth -/usr/share/%{name} - -%{_sbindir}/myproxy-oauth-setup - -%changelog -* Fri May 10 2019 Globus Toolkit - 1.2-1 -- Explicitly py2 - -* Mon May 14 2018 Globus Toolkit - 1.1-1 -- Allow newer TLS versions - -* Tue Apr 03 2018 Mattias Ellert - 1.0-1 -- First Grid Community Toolkit release - -* Mon Dec 18 2017 Globus Toolkit - 0.27-1 -- Revert - -* Mon Mar 13 2017 Globus Toolkit - 0.26-1 -- Move apache config file deployment into setup script - -* Thu Nov 10 2016 Globus Toolkit - 0.25-1 -- Python exception handling workaround for 2.5-3.x - -* Wed Nov 09 2016 Globus Toolkit - 0.24-1 -- Verify all paths yield proper response or error response - -* Fri Nov 04 2016 Globus Toolkit - 0.23-1 -- Fix indent issue - -* Tue Oct 18 2016 Globus Toolkit - 0.22-1 -- Catch exceptions and return "400 Bad Request" - -* Wed Aug 31 2016 Globus Toolkit - 0.21-4 -- Updates for SLES 12 - -* Thu Mar 10 2016 Globus Toolkit - 0.21-1 -- Fix redirect when callback_uri contains a query - -* Thu Oct 29 2015 Globus Toolkit - 0.20-1 -- Use setsebool if it is installed and semanage is not available - -* Tue Nov 11 2014 Globus Toolkit - 0.18-1 -- Run selinux commands as root, run database commands as myproxyoauth - -* Wed Nov 05 2014 Globus Toolkit - 0.16-1 -- Remove httplib2 dependent code which is not used - -* Mon Aug 04 2014 Globus Toolkit - 0.15-2 -- Fix error in scriptlet to create wsgi socket dir on SLES 11 - -* Thu Jul 31 2014 Globus Toolkit - 0.15-1 -- Update to 0.15 for EC2-public hostname awareness -- Create wsgi socket dir on SLES 11 - -* Tue Jul 29 2014 Globus Toolkit - 0.14-3 -- EL7 requires Apache 2.4 configuration file - -* Fri Jul 25 2014 Globus Toolkit - 0.14-2 -- EL7 doesn't require python-sqlite2 - -* Mon Jan 20 2014 Globus Toolkit - 0.14-1 -- move to globus repo - -* Wed Sep 04 2013 Globus Toolkit - 0.13-1 -- Fix regression on python path setting - -* Wed Sep 04 2013 Globus Toolkit - 0.12-1 -- Fall back to pysqlite2 when sqlite3 is not available - -* Wed Sep 04 2013 Globus Toolkit - 0.11-1 -- Remove dependency on sql alchemy - -* Fri Aug 23 2013 Globus Toolkit - 0.10-1 -- Remove dependency on jinja2 - -* Wed Mar 27 2013 Globus Toolkit - 0.0-1 -- Initial packaging diff --git a/travis-ci/make_source_tarballs.sh b/travis-ci/make_source_tarballs.sh index 90672f8703..ba6bcb1ec8 100755 --- a/travis-ci/make_source_tarballs.sh +++ b/travis-ci/make_source_tarballs.sh @@ -45,9 +45,6 @@ package_version=$(grep '^PACKAGE_VERSION =' Makefile | cut -d ' ' -f 3) time make dist && mv "${package_name}-${package_version}.tar.gz" package-output/ echo '================================================================================' -pushd "$root/myproxy/oauth/source" -time python setup.py sdist -mv dist/*.tar.gz "$root/package-output/" err=0 pushd "$root/package-output/" @@ -70,5 +67,4 @@ if [[ $err -ne 0 ]]; then exit $err fi -popd diff --git a/travis-ci/run_task_inside_docker.sh b/travis-ci/run_task_inside_docker.sh index 5f0f049432..a11b02fc44 100755 --- a/travis-ci/run_task_inside_docker.sh +++ b/travis-ci/run_task_inside_docker.sh @@ -89,8 +89,6 @@ elif [[ $TASK == *rpms ]]; then packages+=('perl(DBI)') # for globus-scheduler-event-generator: packages+=(redhat-lsb-core) - # for myproxy-oauth - packages+=(m2crypto mod_ssl mod_wsgi pyOpenSSL python-crypto) # for gsi-openssh packages+=(pam libedit libedit-devel) fi