This file is indexed.

/usr/share/pyshared/gluon/contrib/login_methods/x509_auth.py is in python-gluon 1.99.7-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Written by Michele Comitini <mcm@glisco.it>
License: GPL v3

Adds support for x509 authentication.

"""

from gluon.globals import current
from gluon.storage import Storage
from gluon.http import HTTP,redirect

#requires M2Crypto
from M2Crypto import X509



class X509Auth(object):
    """
    Login using x509 cert from client.

    from gluon.contrib.login_methods.x509_auth import X509Account
    auth.settings.actions_disabled=['register','change_password',
                                    'request_reset_password','profile']
    auth.settings.login_form = X509Account()

    """



    def __init__(self):
        self.request = current.request
        self.ssl_client_raw_cert = self.request.env.ssl_client_raw_cert

        # rebuild the certificate passed by the env
        # this is double work, but it is the only way
        # since we cannot access the web server ssl engine directly

        if self.ssl_client_raw_cert:

            x509=X509.load_cert_string(self.ssl_client_raw_cert, X509.FORMAT_PEM)
            # extract it from the cert
            self.serial = self.request.env.ssl_client_serial or ('%x' % x509.get_serial_number()).upper()


            subject = x509.get_subject()

            # Reordering the subject map to a usable Storage map
            # this allows us a cleaner syntax:
            # cn = self.subject.cn
            self.subject = Storage(filter(None,
                                          map(lambda x:
                                                  (x,map(lambda y: 
                                                         y.get_data().as_text(),
                                                         subject.get_entries_by_nid(subject.nid[x]))),
                                              subject.nid.keys())))



    def login_form(self, **args):
        raise HTTP(403,'Login not allowed. No valid x509 crentials')

        

    def login_url(self, next="/"):
        raise HTTP(403,'Login not allowed. No valid x509 crentials')




    def logout_url(self, next="/"):
        return next

    def get_user(self):
        '''Returns the user info contained in the certificate.
        '''

        # We did not get the client cert?
        if not self.ssl_client_raw_cert:
            return None

        # Try to reconstruct some useful info for web2py auth machinery

        p = profile = dict()

        username = p['username'] = reduce(lambda a,b: '%s | %s' % (a,b), self.subject.CN or self.subject.commonName)
        p['first_name'] = reduce(lambda a,b: '%s | %s' % (a,b),self.subject.givenName or username)
        p['last_name'] = reduce(lambda a,b: '%s | %s' % (a,b),self.subject.surname)
        p['email'] = reduce(lambda a,b: '%s | %s' % (a,b),self.subject.Email or self.subject.emailAddress)

        # IMPORTANT WE USE THE CERT SERIAL AS UNIQUE KEY FOR THE USER
        p['registration_id'] = self.serial

        # If the auth table has a field certificate it will be used to
        # save a PEM encoded copy of the user certificate.

        p['certificate'] = self.ssl_client_raw_cert

        return profile