Source code for x2gobroker.authmechs.https_get_authmech
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
# Copyright (C) 2012-2019 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
# Copyright (C) 2012-2019 by Josh Lukens <jlukens@botch.com>
#
# X2Go Session Broker is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# X2Go Session Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
# Very simple authmech that requests a webpage over https with basic auth.
# If the page is fetched successfully (status 200) the user is authenticated.
#
# Used in conjunction with something like an apache server you can get easy
# access to the full handful of existing auth modules for things like radius,
# RSA, etc.
#
# Server name and path must be hard coded below for the time being. Also note
# that the httplib module used does not verify SSL certificates so be sure
# you are on a trusted network as there is a possibility of a man in the middle
# attack.
# modules
import http.client
import base64
[docs]class X2GoBrokerAuthMech(object):
"""\
X2Go Session Broker's **https_get** *authentication mechanism*:
This authentication mechanism can be attached to a web server
that provides some test URL protected by http(s) Basic
Authentication.
When the :func:`authenticate()` function gets called, it attempts
to retrieve the test URL via a http(s) GET request. The webserver
serving that URL then sends a response back, demanding
``Authorization``.
For the Basic Authorization request that gets sent back to the
webserver, the username and password provided by the X2Go client
application get used.
"""
[docs] def authenticate(self, username, password, config=None, **kwargs):
"""\
The **https_get** authentication mechanism's :func:`authenticate()`
method attempts authentication against a http(s) server.
It lets broker authentication succeed if the upstream webserver
grants authentication to a given test URL. Otherwise, broker
authencation fails.
The test URL is provided as set of config parameters passed in
via the ``config`` function parameter. If no config is given, the
default authentication will be performed against
``http://localhost/auth``.
The configuration object provided as ``config`` to this method
requires to understand this API (a class from module
:mod:`configparser` should do this for you)::
host = config.get_value('authmech_https_get','host')
path = config.get_value('authmech_https_get','path')
port = config.get_value('authmech_https_get','port')
:param username: The broker username sent by the client
:type username: ``str``
:param password: The broker password sent by the client
:type password: ``str``
:param config: A :mod:`configparser` compliant configuration object
:param type: ``<configparser-like-obj>``
:param kwargs: Any other parameter (for future features' compatibility, all ignored for now)
:type kwargs: ``dict``
:returns: Authentication success or failure.
:rtype: ``bool``
"""
## FIXME: these should really be specificed in master config file and have better error checking
if config:
host = config.get_value('authmech_https_get','host')
path = config.get_value('authmech_https_get','path')
port = config.get_value('authmech_https_get','port')
else:
host = "localhost"
path = "/auth"
port = "80"
# base64 encode the username and password
auth = base64.standard_b64encode('%s:%s' % (username, password)).replace('\n', '')
https = http.client.HTTPSConnection(host,port)
https.putrequest("GET", path)
https.putheader("Host", host)
https.putheader("User-Agent", "X2Go Session Broker")
https.putheader("Authorization", "Basic %s" % auth)
https.endheaders()
response = https.getresponse()
https.close()
if response.status == 200:
return True
return False