%PDF- %PDF-
| Direktori : /usr/share/hplip/base/ |
| 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