Пример #1
0
class YubiServeHandler:
    def __init__(self, sql_connection, params, vclass):
        self.sql = SQL(sql_connection)
        self.params = params
        self.vclass = vclass

    def sign_message(self, answer, api_key):
        data = ['%s=%s' % (k, v) for (k, v) in answer.iteritems()]
        data.sort()
        data = '&'.join(data)

        otp_hmac = hmac.new(api_key, str(data), hashlib.sha1)
        otp_hmac = base64.b64encode(otp_hmac.digest())

        return otp_hmac

    def build_answer(self, stat, answer, api_key=''):
        answer['status'] = stat
        answer['h'] = self.sign_message(answer, api_key)

        data = '\r\n'.join(['%s=%s' % (k, v) for (k, v) in answer.iteritems()])
        data += '\r\n'

        return data

    def do_validate(self):
        answer = {'t': time.strftime("%Y-%m-%dT%H:%M:%S"), 'otp': ''}

        # API id and OTP are required
        if 'id' not in self.params or 'otp' not in self.params:
            return self.build_answer(status.MISSING_PARAMETER, answer)

        # ensure API id is valid
        if not self.sql.select('get_api_secret', [self.params['id']]):
            return self.build_answer(status.NO_SUCH_CLIENT, answer)

        api_key = base64.b64decode(self.sql.result[0])

        # do token validation
        vclass = self.vclass(self.sql)
        stat = vclass.set_params(self.params, answer)
        if stat == status.OK:
            stat = vclass.validate()
        return self.build_answer(stat, answer, api_key)
Пример #2
0
class Backend(object):

    __drivers = ['SQLITE', 'LDAP']

    def __init__(self, driver, uri=None, connection=None):  # FIXME ugly hack
        """Initializing function

        driver (string) - either 'SQLITE' or 'LDAP'
        uri (string) - OPTIONAL The location of the SQLITE databse file or the
            LDAP uri
        connection (object) - OPTIONAL SQL Connection
        """
        self.driver = driver
        if driver not in self.__drivers:
            self.driver = 'SQLITE'

        if self.driver == 'SQLITE' and not connection:
            sql_connection = connect_to_db(uri)
            self.sql = SQL(sql_connection)
        elif self.driver == 'SQLITE' and connection:
            self.sql = connection
        elif self.driver == 'LDAP':
            self.ldap = LDAPConnection()

    def get_key(self, userid):
        """Function that fetches the aeskey, internalname, counter and timestamp
        from the data storage.

        Params:
            userid (string)  - the userid (keyid) extracted from the OTP

        Returns:
            key (tuple) - (aeskey, internalname, counter, time) if the supplied
                userid matches an entry in the Data Storage
        """
        if self.driver == 'SQLITE':
            if not self.sql.select('yubico_get_key', [userid]):
                return status.BAD_OTP
            aeskey, internalname, counter, time = self.sql.result
        elif self.driver == 'LDAP':
            dn, entry = self.ldap.search('yubico_get_key', [userid])[0]
            aeskey = entry['aeskey'][0]
            internalname = entry['internalname'][0]
            counter = int(entry['counter'][0])
            time = int(entry['time'][0])

        return (aeskey, internalname, counter, time)

    def update_counter(self, count, timestamp, userid):
        """Function that updates the counter in the data.

        Params:
            count (int) - the new count to updated
            timestamp (int) - the timestamp from the otp
            userid (string) - the userid for the key for which the counter has
                to be updated.
        """
        if self.driver == 'SQLITE':
            self.sql.update('yubico_update_counter',
                            [count, timestamp, userid])
        elif self.driver == 'LDAP':
            dn, entry = self.ldap.search('yubico_get_key', [userid])[0]
            self.ldap.update_d(dn, {'counter': str(count),
                                    'time': str(timestamp)})

    def get_user_keys(self, username):
        """LDAP only function that retrieves the keys of a user.

        Params:
            username (string) - the uid of the user in ldap
        """
        if self.driver == 'LDAP':
            dn, entry = self.ldap.search('get_keys', username)[0]
            return entry['gluuOTPMetadata']

    def update_key(self, username, key):
        """LDAP only function that updates the particular key of the user.

        Params:
            username (string) - the user whose key is to be updated
            key (string) - the key dict as string with updated values
        """
        dn, entry = self.ldap.search('get_keys', username)
        # NOTE This way of updating restricts to one OTP key per person
        self.ldap.update(dn, 'gluuOTPMetadata', key)