%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /usr/share/hplip/base/
Upload File :
Create Path :
Current File : //usr/share/hplip/base/password.py

# -*- coding: utf-8 -*-
#
# (c) Copyright @ 2015 HP Development Company, L.P.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
# Author: Amarnath Chitumalla
#
import os
import getpass
import time
import string

from . import utils, tui
from .g import *
from .sixext import BytesIO, StringIO
from .sixext.moves import input
from . import pexpect

PASSWORD_RETRY_COUNT = 3



# This function promts for the username and password and returns
# (username,password)
def showPasswordPrompt(prompt):
    import getpass
    print ("")
    print ("")
    print (log.bold(prompt))
    username = input("Username: ")
    password = getpass.getpass("Password: ")

    return (username, password)


# TBD this function shoud be removed once distro class implemented
def get_distro_name():
    import distro
    return distro.linux_distribution(full_distribution_name=False)[0]

# upstream likes to rename stuff
def get_distro_std_name(os_name1):
    return get_distro_name()


class Password(object):

    def __init__(self, Mode=INTERACTIVE_MODE):
        self.__password = ""
        self.__password_prompt_str = ""
        self.__passwordValidated = False
        self.__mode = Mode
        self.__authType = utils.readAuthType()
        self.__expectList = []

        if not utils.to_bool(sys_conf.get('configure', 'qt5', '0')) and not not utils.to_bool(sys_conf.get('configure', 'qt4', '0')) and utils.to_bool(sys_conf.get('configure', 'qt3', '0')):
            self.__ui_toolkit = 'qt3'
        elif not utils.to_bool(sys_conf.get('configure', 'qt5', '0')) and not utils.to_bool(sys_conf.get('configure', 'qt3', '0')) and utils.to_bool(sys_conf.get('configure', 'qt4', '0')):
            self.__ui_toolkit = 'qt4'
        elif not utils.to_bool(sys_conf.get('configure', 'qt3', '0')) and not utils.to_bool(sys_conf.get('configure', 'qt4', '0')) and utils.to_bool(sys_conf.get('configure', 'qt5', '0')):
            self.__ui_toolkit = 'qt5'

        for s in utils.EXPECT_WORD_LIST:
            try:
                p = re.compile(s, re.I)
            except TypeError:
                self.__expectList.append(s)
            else:
                self.__expectList.append(p)

    ##################### Private functions ######################
    
    # check if caller is in wheel group - use 'su' if he isnt -
    # or if the caller is root (just for showing 'root' username)
    # in the prompt


    def __getPasswordDisplayString(self):
        if self.__authType == "su":
            return "Please enter the root/superuser password: "
        else:
            return "Please enter the sudoer (%s)'s password: " % os.getenv('USER')

    def __changeAuthType(self):
        if self.__authType == "sudo":
            self.__authType = "su"
        else:
            self.__authType = "sudo"
        user_conf.set('authentication', 'su_sudo', self.__authType)

    def __get_password(self, pswd_msg=''):
        if pswd_msg == '':
            if self.__authType == "su":
                pswd_msg = "Please enter the root/superuser password: "
            else:
                pswd_msg = "Please enter the sudoer (%s)'s password: " % os.getenv(
                    'USER')
        return getpass.getpass(log.bold(pswd_msg))

    def __get_password_ui(self, pswd_msg='', user="root"):
        if pswd_msg == '':
            pswd_msg = "Your HP Device requires to install HP proprietary plugin\nPlease enter root/superuser password to continue"

        if self.__ui_toolkit == "qt3":
            from ui.setupform import showPasswordUI
            username, password = showPasswordUI(pswd_msg, user, False)
        elif self.__ui_toolkit == "qt5":
            from ui5.setupdialog import showPasswordUI
            username, password = showPasswordUI(pswd_msg, user, False)
        else:  # self.__ui_toolkit == "qt4" --> default qt4
            from ui4.setupdialog import showPasswordUI
            username, password = showPasswordUI(pswd_msg, user, False)

        if username == "" and password == "":
            raise Exception("User Cancel")

        return password

    def __password_check(self, cmd, timeout=10):
        import io
        output = io.StringIO()
        ok, ret = False, ''

        try:
            child = pexpect.spawnu(cmd, timeout=timeout)
        except pexpect.ExceptionPexpect:
            return 1, ''

        try:
            try:
                start = time.time()

                while True:
                    update_spinner()

                    i = child.expect(self.__expectList)

                    cb = child.before
                    if cb:
                        start = time.time()
                        output.write(cb)

                    if i == 0:  # EOF
                        ok, ret = True, output.getvalue()
                        break

                    elif i == 1:  # TIMEOUT
                        if('true' in cmd and self.__password_prompt_str == ""):  # sudo true or su -c "true"
                            cb = cb.replace("[", r"\[")
                            cb = cb.replace("]", r"\]")

                            self.__password_prompt_str = cb
                            try:
                                p = re.compile(cb, re.I)
                            except TypeError:
                                self.__expectList.append(cb)
                            else:
                                self.__expectList.append(p)
                            log.debug(
                                "Adding missing password prompt string [%s]" % self.__password_prompt_str)
                        continue

                    else:  # password
                        if(self.__password_prompt_str == ""):
                            self.__password_prompt_str = utils.EXPECT_WORD_LIST[
                                i]
                            log.debug(
                                "Updating password prompt string [%s]" % self.__password_prompt_str)

                        child.sendline(self.__password)

            except (Exception, pexpect.ExceptionPexpect) as e:
                log.exception()

        finally:
            cleanup_spinner()

            try:
                child.close()
            except OSError:
                pass

        if ok:
            return child.exitstatus, ret
        else:

            return 1, ''

    def __validatePassword(self, pswd_msg):
        x = 1
        while True:
            if self.__mode == INTERACTIVE_MODE:
                self.__password = self.__get_password(pswd_msg)
            else:
                try:
                    if self.getAuthType() == 'su':
                        self.__password = self.__get_password_ui(
                            pswd_msg, "root")
                    else:
                        self.__password = self.__get_password_ui(
                            pswd_msg, os.getenv("USER"))
                except Exception as ex:
                    log.debug(ex)
                    break

            cmd = self.getAuthCmd() % "true"
            log.debug(cmd)

            status, output = self.__password_check(cmd)
            log.debug("status = %s  output=%s " % (status, output))

            if self.__mode == GUI_MODE:
                if self.__ui_toolkit == "qt4":
                    from ui4.setupdialog import FailureMessageUI
                elif self.__ui_toolkit == "qt5":
                    from ui5.setupdialog import FailureMessageUI
                elif self.__ui_toolkit == "qt3":
                    from ui.setupform import FailureMessageUI

            if status == 0:
                self.__passwordValidated = True
                break
            elif "not in the sudoers file" in output:
                # TBD.. IF user doesn't have sudo permissions, needs to change
                # to "su" type and query for password
                self.__changeAuthType()
                msg = "User doesn't have sudo permissions.\nChanging Authentication Type. Try again."
                if self.__mode == GUI_MODE:
                    FailureMessageUI(msg)
                else:
                    log.error(msg)
                raise Exception("User is not in the sudoers file.")

            else:
                self.__password = ""
                x += 1
                if self.__mode == GUI_MODE:
                    if x > PASSWORD_RETRY_COUNT:
                        FailureMessageUI("Password incorrect. ")
                        return
                    else:
                        FailureMessageUI("Password incorrect. %d attempt(s) left." % (
                            PASSWORD_RETRY_COUNT + 1 - x))
                else:
                    if x > PASSWORD_RETRY_COUNT:
                        log.error("Password incorrect. ")
                        return
                    else:
                        log.error("Password incorrect. %d attempt(s) left." % (
                            PASSWORD_RETRY_COUNT + 1 - x))

    def __get_password_utils(self):
        if self.__authType == "su":
            AuthType, AuthCmd = 'su', 'su -c "%s"'
        else:
            AuthType, AuthCmd = 'sudo', 'sudo %s'

        return AuthType, AuthCmd

    def __get_password_utils_ui(self):
        (os_name,_ver) = utils.get_distro_name()
        os_name = os_name.lower().replace(" ","")
        distro_name = get_distro_std_name(os_name)
        if self.__authType == "sudo":
            AuthType, AuthCmd = 'sudo', 'sudo %s'
        else:
            AuthType, AuthCmd = 'su', 'su -c "%s"'
        '''
        if utils.which('kdesu'):
            AuthType, AuthCmd = 'kdesu', 'kdesu -- %s'
        elif utils.which('kdesudo'):
            AuthType, AuthCmd = 'kdesudo', 'kdesudo -- %s'
        elif utils.which('gnomesu'):
            AuthType, AuthCmd = 'gnomesu', 'gnomesu -c "%s"'
        elif utils.which('gksu'):
            AuthType, AuthCmd = 'gksu' , 'gksu "%s"'
        '''

        return AuthType, AuthCmd

    ##################### Public functions ######################

    def clearPassword(self):
        log.debug("Clearing password...")
        self.__password = ""
        self.__passwordValidated = False
        if self.__authType == 'sudo':
            utils.run("sudo -K")

    def getAuthType(self):
        if self.__mode == INTERACTIVE_MODE:
            retValue = self.__authType
        else:
            retValue, AuthCmd = self.__get_password_utils_ui()

        return retValue

    def getAuthCmd(self):
        if self.__mode == INTERACTIVE_MODE:
            AuthType, AuthCmd = self.__get_password_utils()
        else:
            AuthType, AuthCmd = self.__get_password_utils_ui()

        return AuthCmd

    def getPassword(self, pswd_msg='', psswd_queried_cnt=0):
        if self.__passwordValidated:
            return self.__password

        if psswd_queried_cnt:
            return self.__password

        self.__validatePassword(pswd_msg)
        return self.__password

    def getPasswordPromptString(self):
        return self.__password_prompt_str

Zerion Mini Shell 1.0