def _cbSha256PasswordMatch(self, matched, username): if matched: self.debug('user %s authenticated' % username) return username else: self.debug('user %s refused, password not matched' % username) return failure.Failure(errors.NotAuthenticatedError())
def bouncerResponse(result): # we either got a keycard as result, or None from the # bouncer; would be better if the bouncers returned failures # directly, but that's not how the current interface works. if not result: self.info("unauthorized login for interfaces %r", ifaces) return defer.fail( errors.NotAuthenticatedError("Unauthorized login")) keycard = result if not keycard.state == keycards.AUTHENTICATED: # challenge self.log('returning keycard for further authentication') return keycard # this is where we request the Avatar and can influence naming self.debug('authenticated login of %r into realm %r', keycard, self.realm) # FIXME: this is a hack if interfaces.IAdminMedium in ifaces: # we decide on a unique name for admin clients here keycard.avatarId = "admin-%06x" % self._adminCounter self._adminCounter += 1 self.log( 'calling %r.requestAvatar(keycard=%r, mind=%r, ifaces=%r)', self.realm, keycard, mind, ifaces) return self.realm.requestAvatar(keycard.avatarId, keycard, mind, *ifaces)
def requestAvatarId(self, credentials): if credentials.username in self.users: return defer.maybeDeferred( credentials.checkCryptPassword, self.users[credentials.username]).addCallback( self._cbCryptPasswordMatch, credentials.username) else: self.debug("user '%s' refused, not in storage backend" % credentials.username) return defer.fail(errors.NotAuthenticatedError())
def requestAvatarId(self, credentials): if credentials.username in self.users: salt, data = self.users[credentials.username] password = salt + data return defer.maybeDeferred( credentials.checkSha256Password, password).addCallback( self._cbSha256PasswordMatch, credentials.username) else: self.debug('user %s refused, not in database' % credentials.username) return defer.fail(errors.NotAuthenticatedError())
def requestAvatarId(self, credentials): avatarId = getattr(credentials, 'avatarId', None) if self._passwordless: self.debug('allowing passwordless login for user %s', credentials.username) return defer.succeed(avatarId or credentials.username) elif credentials.username in self.users: self.debug('authenticating user %s' % credentials.username) return defer.maybeDeferred( credentials.checkPassword, self.users[credentials.username]).addCallback( self._cbPasswordMatch, str(credentials.username), avatarId) else: return defer.fail(errors.NotAuthenticatedError())
def _authenticatedCallback(self, keycard, request): # !: since we are a callback, the incoming fd might have gone away # and closed self.debug('_authenticatedCallback: keycard %r' % keycard) if not keycard: raise errors.NotAuthenticatedError() # properly authenticated if request.method == 'GET': fd = request.transport.fileno() if self.bouncerName or self.plug: # the request was finished before the callback was executed if fd == -1: self.debug( 'Request interrupted before authentification ' 'was finished: asking bouncer %s to remove ' 'keycard id %s', self.bouncerName, keycard.id) self.doCleanupKeycard(self.bouncerName, keycard) return None if keycard.id in self._idToKeycard: self.warning("Duplicate keycard id: refusing") raise errors.NotAuthenticatedError() self._fdToKeycard[fd] = keycard self._idToKeycard[keycard.id] = keycard duration = keycard.duration or self._defaultDuration if duration: self.debug('new connection on %d will expire in %f seconds' % (fd, duration)) self._fdToDurationCall[fd] = reactor.callLater( duration, self._durationCallLater, fd) return None
def login(self, keycard, mind, *ifaces): """ Log in the keycard to the portal using the bouncer. @param keycard: the keycard used to login @type keycard: L{flumotion.common.keycards.Keycard} @param mind: a reference to the client-side requester @type mind: L{twisted.spread.pb.RemoteReference} @param ifaces: a list of interfaces for the perspective that the mind wishes to attach to @returns: a deferred, which will fire a tuple of (interface, avatarAspect, logout) or None. """ self.debug("_login(keycard=%r, mind=%r, ifaces=%r)" % (keycard, mind, ifaces)) if not self.bouncer: self.warning("no bouncer, refusing login") mind.broker.transport.loseConnection() return defer.fail( errors.NotAuthenticatedError( "No bouncer configured, no logins possible")) def onErrorCloseConnection(failure): try: host = mind.broker.transport.getHost() remote = '%s:%d' % (host.host, host.port) except: remote = '(unknown)' self.warning('failed login -- closing connection to %s', remote) self.debug('failure: %s', log.getFailureMessage(failure)) try: mind.broker.transport.loseConnection() except Exception, e: self.info('loseConnection failed: %s', log.getExceptionMessage(e)) # ignore it return failure
def _cbPasswordMatch(self, matched, username, avatarId): if matched: return avatarId or username else: return failure.Failure(errors.NotAuthenticatedError())