def _checkForAuthorizedKey(self, user_dict, credentials): """Check the key data in credentials against the keys found in LP.""" if credentials.algName == 'ssh-dss': wantKeyType = 'DSA' elif credentials.algName == 'ssh-rsa': wantKeyType = 'RSA' else: # unknown key type return False if len(user_dict['keys']) == 0: raise UserDisplayedUnauthorizedLogin( "Launchpad user %r doesn't have a registered SSH key" % credentials.username) for keytype, keytext in user_dict['keys']: if keytype != wantKeyType: continue try: if keytext.decode('base64') == credentials.blob: return True except binascii.Error: continue raise UnauthorizedLogin( "Your SSH key does not match any key registered for Launchpad " "user %s" % credentials.username)
def requestAvatarId(self, token): # validate credential signature token_info = None try: token_info = self.validate_and_parse_keystone_token(token) log.info( 'Successful login with Keystone token, extracted data: %s' % token_info) log.debug('Token: %s' % token) except Exception: log.debug('Exception while validating Keystone token', exc_info=True) log.warning('Authentication failed with Keystone token') return defer.fail(UnauthorizedLogin('Invalid credentials')) # extract avatar info from the token auth = getUtility(IAuthentication) oms_user = User(token_info['username']) # extract group information from the token oms_user.groups.extend(token_info['groups']) log.debug('Adding user groups: %s' % ', '.join(token_info['groups'])) for g in oms_user.groups: auth.registerPrincipal(Group(g)) auth.registerPrincipal(oms_user) return defer.succeed(token_info['username'])
def cbCheckPamUser(self, responses, username, ip): """ """ for (response, zero) in responses: if self.checkUserPass(username, response, ip): return defer.succeed(username) return defer.fail(UnauthorizedLogin())
def _srp_auth(self, username, password): try: auth = yield self._bonafide_auth(username, password) except SRPAuthError: raise UnauthorizedLogin( "User typed wrong password/username combination.") returnValue(auth)
def _checkedPassword(self, matched, username, realm): if matched: username = username.split('@', 1)[0] ## this is the avatar ID return "%s@%s" % (username, realm) else: raise UnauthorizedLogin("Unauthorized login")
def checkSpwd(self, spwd, username, password): """ Obtain the encrypted password for C{username} from the Unix shadow password database using L{spwd.getspnam}, and see if it it matches it matches C{password}. @param spwd: Module which provides functions which access to the Unix shadow password database. @type pwd: C{module} @param username: The user to look up in the Unix password database. @type username: L{unicode}/L{str} or L{bytes} @param password: The password to compare. @type username: L{unicode}/L{str} or L{bytes} """ try: if not isinstance(username, StringType): username = username.decode('utf-8') if getattr(spwd.struct_spwd, "sp_pwdp", None): # Python 3 cryptedPass = spwd.getspnam(username).sp_pwdp else: # Python 2 cryptedPass = spwd.getspnam(username).sp_pwd except KeyError: return defer.fail(UnauthorizedLogin()) else: if verifyCryptedPassword(cryptedPass, password): return defer.succeed(username)
def requestAvatarId(self, credentials): username, password = credentials.username, credentials.password try: import pwd except ImportError: pwd = None if pwd is not None: checked = self.checkPwd(pwd, username, password) if checked is not None: return checked try: import spwd except ImportError: spwd = None if spwd is not None: checked = self.checkSpwd(spwd, username, password) if checked is not None: return checked # TODO: check_pam? # TODO: check_shadow? return defer.fail(UnauthorizedLogin())
def requestAvatarId(self, credentials): """See `ICredentialsChecker`.""" if credentials.username == self.username: matched = yield credentials.checkPassword(self.password) if matched: returnValue(credentials.username) raise UnauthorizedLogin(credentials.username)
def requestAvatarId(self, credentials): """ Get the avatar id. Parameters ---------- credentials: (mandatory) something which implements one of the interfaces in self.credentialInterfaces. Returns ------- out: a Deferred which will fire a string which identifies an avatar, an empty tuple to specify an authenticated anonymous user (provided as checkers.ANONYMOUS) or fire a Failure(UnauthorizedLogin). Alternatively, return the result itself. """ try: session_ids = [] for repo in self.cw_repositories: session_ids.append( repo.connect(credentials.username, password=credentials.password)) except: logging.exception("Failed to get connection for user {0}".format( credentials.username)) return defer.fail(UnauthorizedLogin("Invalid user/password")) else: return defer.succeed((credentials.username, session_ids))
def auth_publickey(self, packet): """ Public key authentication. Payload:: byte has signature string algorithm name string key blob [string signature] (if has signature is True) Create a SSHPublicKey credential and verify it using our portal. """ hasSig = ord(packet[0:1]) algName, blob, rest = getNS(packet[1:], 2) try: pubKey = keys.Key.fromString(blob) except keys.BadKeyError: error = "Unsupported key type {} or bad key".format( algName.decode("ascii")) self._log.error(error) return defer.fail(UnauthorizedLogin(error)) signature = hasSig and getNS(rest)[0] or None if hasSig: b = (NS(self.transport.sessionID) + bytes( (MSG_USERAUTH_REQUEST, )) + NS(self.user) + NS(self.nextService) + NS(b"publickey") + bytes( (hasSig, )) + NS(pubKey.sshType()) + NS(blob)) c = credentials.SSHPrivateKey(self.user, algName, blob, b, signature) return self.portal.login(c, None, interfaces.IConchUser) else: c = credentials.SSHPrivateKey(self.user, algName, blob, None, None) return self.portal.login(c, None, interfaces.IConchUser).addErrback( self._ebCheckKey, packet[1:])
def authenticateUserPASS(self, user, password): """ Perform authentication for a username/password login. Override the default lookup scheme to allow virtual domains. @type user: L{bytes} @param user: The name of the user attempting to log in. @type password: L{bytes} @param password: The password to authenticate with. @rtype: L{Deferred} which successfully results in 3-L{tuple} of (L{IMailbox <pop3.IMailbox>}, L{IMailbox <pop3.IMailbox>} provider, no-argument callable) @return: A deferred which fires when authentication is complete. If successful, it returns an L{IMailbox <pop3.IMailbox>} interface, a mailbox and a logout function. If authentication fails, the deferred fails with an L{UnauthorizedLogin <twisted.cred.error.UnauthorizedLogin>} error. """ user, domain = self.lookupDomain(user) try: portal = self.service.lookupPortal(domain) except KeyError: return defer.fail(UnauthorizedLogin()) else: return portal.login(UsernamePassword(user, password), None, pop3.IMailbox)
def validate_and_parse_keystone_token(self, cms_token): """Validate Keystone CMS token. Partially taken from Keystone's common/cms.py module.""" signing_cert_file_name = get_config().get('keystone', 'signing_cert_file_name') ca_file_name = get_config().get('keystone', 'ca_file_name') openssl_cmd = get_config().get('keystone', 'openssl_cmd') process = subprocess.Popen([ openssl_cmd, "cms", "-verify", "-certfile", signing_cert_file_name, "-CAfile", ca_file_name, "-inform", "PEM", "-nosmimecap", "-nodetach", "-nocerts", "-noattr" ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, err = process.communicate(self.token_to_cms(cms_token)) retcode = process.poll() if retcode: log.info('Token validation has failed, return code: %s' % retcode) raise UnauthorizedLogin() token_info = json.loads(output) #print json.dumps(token_info, sort_keys=True, # indent=4, separators=(',', ': ')) res = { 'username': str(token_info['access']['user']['username']), 'groups': [str(token_info['access']['token']['tenant']['name'])] } return res
def requestAvatarId(self, credentials): l = ldap.initialize(self.lserver) l.set_option(ldap.OPT_REFERRALS, 0) l.protocol_version = 3 filter = "(&(objectClass=posixAccount)(uid="+credentials.username+"))" groupFilter = '(&(cn='+self.group+')(memberUid=' +credentials.username+'))' # return defer.succeed(credentials.username) #1. get user cn results = l.search_s(self.base_dn, self.scope, filter) for dn,entry in results: dn = str(dn) #2. check auth l.simple_bind_s(dn, credentials.password) #3. check group results = l.search_s(self.base_dn, self.scope, groupFilter) if len(results) > 0: return defer.succeed(credentials.username) # Something went wrong. Simply fail authentication return defer.fail(UnauthorizedLogin("unable to verify password"))
def _ebRequestAvatarId(self, f): if not f.check(UnauthorizedLogin): _log.error( "Unauthorized login due to internal error: {error}", error=f.value ) return failure.Failure(UnauthorizedLogin("unable to get avatar id")) return f
def authenticateUserAPOP(self, user, digest): """ Perform APOP authentication. Override the default lookup scheme to allow virtual domains. @type user: L{bytes} @param user: The name of the user attempting to log in. @type digest: L{bytes} @param digest: The challenge response. @rtype: L{Deferred} which successfully results in 3-L{tuple} of (L{IMailbox <pop3.IMailbox>}, L{IMailbox <pop3.IMailbox>} provider, no-argument callable) @return: A deferred which fires when authentication is complete. If successful, it returns an L{IMailbox <pop3.IMailbox>} interface, a mailbox and a logout function. If authentication fails, the deferred fails with an L{UnauthorizedLogin <twisted.cred.error.UnauthorizedLogin>} error. """ user, domain = self.lookupDomain(user) try: portal = self.service.lookupPortal(domain) except KeyError: return defer.fail(UnauthorizedLogin()) else: return portal.login(pop3.APOPCredentials(self.magic, user, digest), None, pop3.IMailbox)
def _cbRequestAvatarId(self, validKey, credentials): if not validKey: return failure.Failure(UnauthorizedLogin()) if not credentials.signature: return failure.Failure(error.ValidPublicKey()) else: try: pubKey = keys.getPublicKeyObject(data=credentials.blob) if keys.verifySignature(pubKey, credentials.signature, credentials.sigData): return credentials.username except: # any error should be treated as a failed login f = failure.Failure() log.err() return f return failure.Failure(UnauthorizedLogin())
def checkPwd(self, pwd, username, password): """ Obtain the encrypted password for C{username} from the Unix password database using L{pwd.getpwnam}, and see if it it matches it matches C{password}. @param pwd: Module which provides functions which access to the Unix password database. @type pwd: C{module} @param username: The user to look up in the Unix password database. @type username: L{unicode}/L{str} or L{bytes} @param password: The password to compare. @type username: L{unicode}/L{str} or L{bytes} """ try: if not isinstance(username, StringType): username = username.decode('utf-8') cryptedPass = pwd.getpwnam(username).pw_passwd except KeyError: return defer.fail(UnauthorizedLogin()) else: if cryptedPass in ('*', 'x'): # Allow checkSpwd to take over return None elif verifyCryptedPassword(cryptedPass, password): return defer.succeed(username)
def clean_username(self, username): if '@' not in username: return username extracted_username = self.extract_username(username) if self.username_with_domain(extracted_username) == username: return extracted_username raise UnauthorizedLogin('User typed a wrong domain.')
def requestAvatarId(self, credentials): credentials = IPrincipalCredentials(credentials) if credentials.authnPrincipal is None: raise UnauthorizedLogin( "No such user: {user}".format( user=credentials.credentials.username ) ) # See if record is enabledForLogin if not credentials.authnPrincipal.record.isLoginEnabled(): raise UnauthorizedLogin( "User not allowed to log in: {user}".format( user=credentials.credentials.username ) ) # Handle Kerberos as a separate behavior try: from twistedcaldav.authkerb import NegotiateCredentials except ImportError: NegotiateCredentials = None if NegotiateCredentials and isinstance(credentials.credentials, NegotiateCredentials): # If we get here with Kerberos, then authentication has already succeeded returnValue( ( credentials.authnPrincipal, credentials.authzPrincipal, ) ) else: if (yield credentials.authnPrincipal.record.verifyCredentials(credentials.credentials)): returnValue( ( credentials.authnPrincipal, credentials.authzPrincipal, ) ) else: raise UnauthorizedLogin( "Incorrect credentials for user: {user}".format( user=credentials.credentials.username ) )
def requestAvatarId(self, credentials): matched = self.passwords.get(credentials.username.decode('ascii'), None) if matched and matched == crypt.crypt( credentials.password.decode('ascii'), matched[:2]): return succeed(credentials.username) else: return fail(UnauthorizedLogin("Invalid username or password"))
def requestAvatarId(self, credentials): try: sessionid = self.repo.connect(credentials.username, password=credentials.password) except Exception, exc: logging.exception('failed to get connection for user %s', credentials.username) return defer.fail(UnauthorizedLogin("invalid password"))
def requestAvatarId(self, credentials): if self.service is None: raise NotImplementedError( "this checker has not defined its service name") username, password = credentials.username, credentials.password d = self.checkSoledadToken(username, password, self.service) d.addErrback(lambda f: defer.fail(UnauthorizedLogin())) return d
def sendDisconnect(self, reason, desc): log.debug('sending transport disconnect [%s]' % reason) transport.SSHClientTransport.sendDisconnect(self, reason, desc) # Tell the factory we had an unauthorized login exception if reason == 14: log.debug('login failure, telling the factory about it') self.factory.resetConnection(UnauthorizedLogin())
def checkSpwd(self, spwd, username, password): try: cryptedPass = spwd.getspnam(username)[1] except KeyError: return defer.fail(UnauthorizedLogin()) else: if verifyCryptedPassword(cryptedPass, password): return defer.succeed(username)
def sendDisconnect(self, reason, desc): log.debug('sending transport disconnect [%s]' % reason) transport.SSHClientTransport.sendDisconnect(self, reason, desc) # Tell the factory we had an unauthorized login exception if reason == transport.DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE: self.factory.resetConnection( UnauthorizedLogin('Authentication Failure'))
def requestAvatarId(self, credentials): if not credentials.username: if self.allow_anonymous: return defer.succeed(credentials.username) return defer.fail(UnauthorizedLogin()) return deferToThread(self.checkPassword, credentials)
def requestAvatarId(self, creds): if creds.blob == keys.Key.fromString(keydata.publicRSA_openssh).blob(): if creds.signature is not None: obj = keys.Key.fromString(creds.blob) if obj.verify(creds.signature, creds.sigData): return creds.username else: raise ValidPublicKey() raise UnauthorizedLogin()
def _err(reason, _deferred): if _deferred.called: return ##maybe has timeout log.msg('Warning! LDAP connection problem %s' % reason) reason.trap( ldaperrors.LDAPInvalidCredentials, # this happens with slapd 2.1.30 when binding # with DN but no password ldaperrors.LDAPUnwillingToPerform) _deferred.errback(UnauthorizedLogin('LDAP connection problem'))
def requestAvatarId(self, credentials): twunnel.logger.log( 3, "trace: SSHPrivateKeyCredentialsChecker.requestAvatarId") if len(self.configuration["REMOTE_PROXY_SERVER"]["ACCOUNTS"]) == 0: return defer.succeed(-1) if not credentials.signature: return defer.fail(ValidPublicKey()) i = 0 while i < len(self.configuration["REMOTE_PROXY_SERVER"]["ACCOUNTS"]): if self.configuration["REMOTE_PROXY_SERVER"]["ACCOUNTS"][i][ "NAME"] == credentials.username: j = 0 while j < len(self.configuration["REMOTE_PROXY_SERVER"] ["ACCOUNTS"][i]["KEYS"]): if self.configuration["REMOTE_PROXY_SERVER"]["ACCOUNTS"][ i]["KEYS"][j]["PUBLIC"]["FILE"] != "": key = keys.Key.fromFile( self.configuration["REMOTE_PROXY_SERVER"] ["ACCOUNTS"][i]["KEYS"][j]["PUBLIC"]["FILE"], passphrase=str( self.configuration["REMOTE_PROXY_SERVER"] ["ACCOUNTS"][i]["KEYS"][j]["PUBLIC"] ["PASSPHRASE"])) if key.blob() == credentials.blob: if key.verify(credentials.signature, credentials.sigData): return defer.succeed(i) j = j + 1 twunnel.logger.log(1, "ERROR_ACCOUNT_KEYS_PUBLIC") return defer.fail( UnauthorizedLogin("ERROR_ACCOUNT_KEYS_PUBLIC")) i = i + 1 twunnel.logger.log(1, "ERROR_ACCOUNT_NAME") return defer.fail(UnauthorizedLogin("ERROR_ACCOUNT_NAME"))
def requestAvatarId(self, credentials): if hasattr(credentials, 'password'): if self.checkUserPass(credentials.username, credentials.password): return defer.succeed(credentials.username) else: return defer.fail(UnauthorizedLogin()) elif hasattr(credentials, 'pamConversion'): return self.checkPamUser(credentials.username, credentials.pamConversion) return defer.fail(UnhandledCredentials())