示例#1
0
 def conversation(self, auth, query_list, data):
     try:
         return list(self._conversation(auth, query_list, data))
     except:
         AUTH.error('Unexpected error during PAM conversation: %s' %
                    (traceback.format_exc(), ))
         raise
示例#2
0
    def authenticate(self, username, password, **answers):
        answers.update({
            PAM_TEXT_INFO: '',
            PAM_ERROR_MSG: '',
            PAM_PROMPT_ECHO_ON: username,
            PAM_PROMPT_ECHO_OFF: password,
        })
        missing = []
        self.start(username, (answers, [], missing))

        try:
            self.pam.authenticate()
            self.pam.acct_mgmt()
        except PAMError as pam_err:
            AUTH.error("PAM: authentication error: %s" % (pam_err, ))
            if pam_err.args[
                    1] == PAM_NEW_AUTHTOK_REQD:  # error: ('Authentication token is no longer valid; new one required', 12)
                raise PasswordExpired(self.error_message(pam_err.args))
            if pam_err.args[
                    1] == PAM_ACCT_EXPIRED:  # error: ('User account has expired', 13)
                raise AccountExpired(self.error_message(pam_err.args))
            if missing:
                message = self._('Please insert your one time password (OTP).')
                raise AuthenticationInformationMissing(message, missing)
            raise AuthenticationFailed(self.error_message(pam_err.args))
示例#3
0
    def change_password(self, username, old_password,
                        new_password):  # type: (str, str, str) -> None
        answers = {
            PAM_TEXT_INFO: '',
            PAM_ERROR_MSG: '',
            PAM_PROMPT_ECHO_ON: username,
            PAM_PROMPT_ECHO_OFF: [old_password, new_password, new_password],
            # pam_kerberos asks for the old password first and then twice for the new password.
            # 'Current Kerberos password: '******'New password: '******'Retype new password: '******'LC_ALL=en_US.UTF-8')
        self.pam.putenv('LC_MESSAGES=en_US.UTF-8')
        self.pam.putenv('LANG=en_US.UTF-8')

        try:
            self.pam.chauthtok()
        except PAMError as pam_err:
            AUTH.warn('Changing password failed (%s). Prompts: %r' %
                      (pam_err, prompts))
            message = self._parse_error_message_from(pam_err.args, prompts)
            raise PasswordChangeFailed(
                '%s %s' % (self._('Changing password failed.'), message))
示例#4
0
 def conversation(self, auth, query_list,
                  data):  # type: (Any, Any, Any) -> List
     try:
         return list(self._conversation(auth, query_list, data))
     except BaseException:
         AUTH.error('Unexpected error during PAM conversation: %s' %
                    (traceback.format_exc(), ))
         raise
	def __authentication_result(self, thread, result, request):
		if isinstance(result, BaseException) and not isinstance(result, (AuthenticationFailed, AuthenticationInformationMissing, PasswordExpired, PasswordChangeFailed, AccountExpired)):
			msg = ''.join(thread.trace + traceback.format_exception_only(*thread.exc_info[:2]))
			AUTH.error(msg)
		if isinstance(result, tuple):
			username, password = result
			result = {'username': username, 'password': password, 'auth_type': request.body.get('auth_type')}
		auth_result = AuthenticationResult(result)
		self.signal_emit('authenticated', auth_result, request)
示例#6
0
    def _conversation(
        self, auth, query_list, data
    ):  # type: (Any, List[Tuple[Any, Any]], Any) -> Iterator[Tuple[str, int]]
        answers, prompts, missing = data
        prompts.extend(query_list)
        for query, qt in query_list:
            prompt = qt
            if qt == PAM_PROMPT_ECHO_OFF and query.strip(
                    ':\t ') in self.custom_prompts:
                prompt = query

            response = ''
            try:
                response = answers[prompt]
                if isinstance(response, list):
                    response = response.pop(0)
            except KeyError as exc:
                AUTH.error('Missing answer for prompt: %r' % (str(exc), ))
                missing.append(query)
            except IndexError:
                AUTH.error('Unexpected prompt: %r' % (query, ))

            if qt in (PAM_TEXT_INFO, PAM_ERROR_MSG):
                AUTH.info('PAM says: %r' % (query, ))
            # AUTH.error('# PAM(%d) %s: answer=%r' % (qt, repr(query).strip("':\" "), response))
            yield (response, 0)
	def __canonicalize_username(self, username):
		try:
			lo, po = get_machine_connection(write=False)
			result = None
			if lo:
				attr = 'mailPrimaryAddress' if '@' in username else 'uid'
				result = lo.search(filter_format('(&(%s=%s)(objectClass=person))', (attr, username)), attr=['uid'], unique=True)
			if result and result[0][1].get('uid'):
				username = result[0][1]['uid'][0]
				AUTH.info('Canonicalized username: %r' % (username,))
		except (ldap.LDAPError, udm_errors.ldapError) as exc:
			# /etc/machine.secret missing or LDAP server not reachable
			AUTH.warn('Canonicalization of username was not possible: %s' % (exc,))
			reset_cache()
		except:
			AUTH.error('Canonicalization of username failed: %s' % (traceback.format_exc(),))
		finally:  # ignore all exceptions, even in except blocks
			return username
	def __authenticate_thread(self, username, password, new_password, **custom_prompts):
		AUTH.info('Trying to authenticate user %r' % (username,))
		username = self.__canonicalize_username(username)
		try:
			self.pam.authenticate(username, password, **custom_prompts)
		except AuthenticationFailed as auth_failed:
			AUTH.error(str(auth_failed))
			raise
		except PasswordExpired as pass_expired:
			AUTH.info(str(pass_expired))
			if new_password is None:
				raise

			try:
				self.pam.change_password(username, password, new_password)
			except PasswordChangeFailed as change_failed:
				AUTH.error(str(change_failed))
				raise
			else:
				AUTH.info('Password change for %r was successful' % (username,))
				return (username, new_password)
		else:
			AUTH.info('Authentication for %r was successful' % (username,))
			return (username, password)