示例#1
0
    def update_user_state(self, user, state):
        if user not in self.fhs.keys():
            raise totpcgi.UserStateError("%s's state FH has gone away!" % user)

        import json

        fh = self.fhs[user]

        logger.debug('fh.name=%s' % fh.name)

        js = {
            'fail_timestamps'     : state.fail_timestamps,
            'success_timestamps'  : state.success_timestamps,
            'used_scratch_tokens' : state.used_scratch_tokens
        }

        logger.debug('saving state=%s' % js)

        logger.debug('Saving new state for user %s' % user)
        json.dump(js, fh, indent=4)
        fh.truncate()

        logger.debug('Unlocking state file for user %s' % user)
        flock(fh, LOCK_UN)
        fh.close()

        del self.fhs[user]

        logger.debug('fhs=%s' % self.fhs)
示例#2
0
    def update_user_state(self, user, state):
        logger.debug('Writing new state for user %s', user)

        if user not in self.locks.keys():
            raise totpcgi.UserStateError("%s's MySQL lock has gone away!" %
                                         user)

        userid = self.locks[user]

        cur = self.conn.cursor()

        cur.execute('DELETE FROM timestamps WHERE userid=%s', (userid, ))
        cur.execute('DELETE FROM used_scratch_tokens WHERE userid=%s',
                    (userid, ))

        for timestamp in state.fail_timestamps:
            cur.execute(
                '''
                INSERT INTO timestamps (userid, success, timestamp)
                     VALUES (%s, %s, %s)''', (userid, False, timestamp))

        for timestamp in state.success_timestamps:
            cur.execute(
                '''
                INSERT INTO timestamps (userid, success, timestamp)
                     VALUES (%s, %s, %s)''', (userid, True, timestamp))

        for token in state.used_scratch_tokens:
            cur.execute(
                '''
                INSERT INTO used_scratch_tokens (userid, token)
                     VALUES (%s, %s)''', (userid, token))

        if state.counter >= 0 and self.has_counters:
            cur.execute('DELETE FROM counters WHERE userid=%s', (userid, ))
            cur.execute(
                '''
                INSERT INTO counters (userid, counter)
                     VALUES (%s, %s)''', (userid, state.counter))

        logger.debug('Releasing lock for userid=%s', userid)
        cur.execute('SELECT RELEASE_LOCK(%s)', (userid, ))

        self.conn.commit()

        del self.locks[user]
示例#3
0
    def get_user_state(self, user):
        state = totpcgi.GAUserState()

        import json

        # load the state file and keep it locked while we do verification
        state_file = os.path.join(self.state_dir, user) + '.json'
        logger.debug('Loading user state from: %s' % state_file)
        
        # For totpcgiprov and totpcgi to be able to write to the same state
        # file, we have to create it world-writable. Since we have restricted
        # permissions on the parent directory (totpcgi:totpcgiprov), plus
        # selinux labels in place, this should keep this safe from tampering.
        os.umask(0000)

        # we exclusive-lock the file to prevent race conditions resulting
        # in potential token reuse.
        if os.access(state_file, os.W_OK):
            logger.debug('%s exists, opening r+' % state_file)
            fh = open(state_file, 'r+')
            logger.debug('Locking state file for user %s' % user)
            lockf(fh, LOCK_EX)
            try:
                js = json.load(fh)

                logger.debug('loaded state=%s' % js)

                state.fail_timestamps = js['fail_timestamps']
                state.success_timestamps = js['success_timestamps']
                state.used_scratch_tokens = js['used_scratch_tokens']

                if 'counter' in js:
                    state.counter = js['counter']

            except Exception, ex:
                # We fail out of caution, though if someone wanted to 
                # screw things up, they could have done so without making
                # the file un-parseable by json -- all they need to do is to
                # erase the file.
                logger.debug('Parsing json failed with: %s' % ex)
                logger.debug('Unlocking state file for user %s' % user)
                lockf(fh, LOCK_UN)
                raise totpcgi.UserStateError(
                    'Error parsing the state file for: %s' % user)

            fh.seek(0)
示例#4
0
    def get_user_state(self, user):
        state = totpcgi.GAUserState()

        import json

        # load the state file and keep it locked while we do verification
        state_file = os.path.join(self.state_dir, user) + '.json'
        logger.debug('Loading user state from: %s' % state_file)
        
        # Don't let anyone but ourselves see the contents of the state file
        os.umask(0077)

        # we exclusive-lock the file to prevent race conditions resulting
        # in potential token reuse.
        if os.access(state_file, os.R_OK):
            logger.debug('%s exists, opening r+' % state_file)
            fh = open(state_file, 'r+')
            logger.debug('Locking state file for user %s' % user)
            flock(fh, LOCK_EX)
            try:
                js = json.load(fh)

                logger.debug('loaded state=%s' % js)

                state.fail_timestamps     = js['fail_timestamps']
                state.success_timestamps  = js['success_timestamps']
                state.used_scratch_tokens = js['used_scratch_tokens']

            except Exception, ex:
                # We fail out of caution, though if someone wanted to 
                # screw things up, they could have done so without making
                # the file un-parseable by json -- all they need to do is to
                # erase the file.
                logger.debug('Parsing json failed with: %s' % ex)
                logger.debug('Unlocking state file for user %s' % user)
                flock(fh, LOCK_UN)
                raise totpcgi.UserStateError(
                        'Error parsing the state file for: %s' % user)

            fh.seek(0)
示例#5
0
    def update_user_state(self, user, state):
        logger.debug('Writing new state for user %s' % user)

        if user not in self.locks.keys():
            raise totpcgi.UserStateError("%s's pg lock has gone away!" % user)

        userid = self.locks[user]

        cur = self.conn.cursor()

        cur.execute('DELETE FROM timestamps WHERE userid=%s', (userid, ))
        cur.execute('DELETE FROM used_scratch_tokens WHERE userid=%s',
                    (userid, ))

        for timestamp in state.fail_timestamps:
            cur.execute(
                '''
                INSERT INTO timestamps (userid, success, timestamp)
                     VALUES (%s, %s, %s)''', (userid, False, timestamp))

        for timestamp in state.success_timestamps:
            cur.execute(
                '''
                INSERT INTO timestamps (userid, success, timestamp)
                     VALUES (%s, %s, %s)''', (userid, True, timestamp))

        for token in state.used_scratch_tokens:
            cur.execute(
                '''
                INSERT INTO used_scratch_tokens (userid, token)
                     VALUES (%s, %s)''', (userid, token))

        logger.debug('Unlocking advisory lock for userid=%s' % userid)
        cur.execute('SELECT pg_advisory_unlock(%s)', (userid, ))

        self.conn.commit()

        del self.locks[user]
示例#6
0
                # screw things up, they could have done so without making
                # the file un-parseable by json -- all they need to do is to
                # erase the file.
                logger.debug('Parsing json failed with: %s' % ex)
                logger.debug('Unlocking state file for user %s' % user)
                flock(fh, LOCK_UN)
                raise totpcgi.UserStateError(
                        'Error parsing the state file for: %s' % user)

            fh.seek(0)
        else:
            logger.debug('%s does not exist, opening w' % state_file)
            try:
                fh = open(state_file, 'w')
            except IOError:
                raise totpcgi.UserStateError(
                        'Cannot write user state for %s, exiting.' % user)
            logger.debug('Locking state file for user %s' % user)
            flock(fh, LOCK_EX)


        # The following condition should never happen, in theory,
        # because we have an exclusive lock on that file. If it does, 
        # things have broken somewhere (probably locking is broken).
        if user not in self.fhs.keys():
            self.fhs[user] = fh

        return state

    def update_user_state(self, user, state):
        if user not in self.fhs.keys():
            raise totpcgi.UserStateError("%s's state FH has gone away!" % user)