提交 40d05a7a 编写于 作者: N nicolargo

Change username for server and web server authentication (issue #693)

上级 5497ae12
......@@ -11,6 +11,7 @@ Enhancements and new features:
* New folders' monitoring plugins (issue #721)
* Use wildcard (regexp) to the hide configuration option for network, diskio and fs sections (issue #799 )
* Command line arguments are now take into account in the WebUI (#789 from @notFloran)
* Change username for server and web server authentication (issue #693)
* Add an option to disable top menu (issue #766)
* Add IOps in the DiskIO plugin (issue #763)
* Add hide configuration key for FS Plugin (issue #736)
......
......@@ -114,7 +114,7 @@ class GlancesClient(object):
# Other errors
msg = "Connection to server failed"
if err.errcode == 401:
msg += " (Bad password)"
msg += " (Bad username/password)"
else:
msg += " ({0} {1})".format(err.errcode, err.errmsg)
self.log_and_exit(msg)
......
......@@ -24,6 +24,7 @@ import os
import sys
import tempfile
from glances.compat import input
from glances.config import Config
from glances.globals import appname, LINUX, WINDOWS, psutil_version, version
from glances.logger import logger
......@@ -174,6 +175,8 @@ Start the client browser (browser mode):\n\
help='define the client/server TCP port [default: {0}]'.format(self.server_port))
parser.add_argument('-B', '--bind', default='0.0.0.0', dest='bind_address',
help='bind server to the given IPv4/IPv6 address or hostname')
parser.add_argument('--username', action='store_true', default=False, dest='username_prompt',
help='define a client/server username')
parser.add_argument('--password', action='store_true', default=False, dest='password_prompt',
help='define a client/server password')
parser.add_argument('--snmp-community', default='public', dest='snmp_community',
......@@ -252,21 +255,37 @@ Start the client browser (browser mode):\n\
args.process_short_name = True
# Server or client login/password
args.username = self.username
if args.username_prompt:
# Every username needs a password
args.password_prompt = True
# Prompt username
if args.server:
args.username = self.__get_username(description='Define the Glances server username: ')
elif args.webserver:
args.username = self.__get_username(description='Define the Glances webserver username: ')
elif args.client:
args.username = self.__get_username(description='Enter the Glances server username: ')
else:
# Default user name is 'glances'
args.username = self.username
if args.password_prompt:
# Interactive or file password
if args.server:
args.password = self.__get_password(
description='Define the password for the Glances server',
confirm=True)
description='Define the Glances server password ({} username): '.format(args.username),
confirm=True,
username=args.username)
elif args.webserver:
args.password = self.__get_password(
description='Define the password for the Glances web server\nUser name: glances',
confirm=True)
description='Define the Glances webserver password ({} username): '.format(args.username),
confirm=True,
username=args.username)
elif args.client:
args.password = self.__get_password(
description='Enter the Glances server password',
clear=True)
description='Enter the Glances server password({} username): '.format(args.username),
clear=True,
username=args.username)
else:
# Default is no password
args.password = self.password
......@@ -324,14 +343,19 @@ Start the client browser (browser mode):\n\
return args
def __get_password(self, description='', confirm=False, clear=False):
def __get_username(self, description=''):
"""Read a username from the command line.
"""
return input(description)
def __get_password(self, description='', confirm=False, clear=False, username='glances'):
"""Read a password from the command line.
- if confirm = True, with confirmation
- if clear = True, plain (clear password)
"""
from glances.password import GlancesPassword
password = GlancesPassword()
password = GlancesPassword(username=username)
return password.get_password(description, confirm, clear)
def is_standalone(self):
......
......@@ -35,9 +35,10 @@ class GlancesPassword(object):
"""This class contains all the methods relating to password."""
def __init__(self):
def __init__(self, username='glances'):
self.username = username
self.password_path = self.get_password_path()
self.password_filename = 'glances.pwd'
self.password_filename = self.username + '.pwd'
self.password_filepath = os.path.join(self.password_path, self.password_filename)
def get_password_path(self):
......@@ -102,13 +103,9 @@ class GlancesPassword(object):
logger.info("Read password from file {0}".format(self.password_filepath))
password = self.load_password()
else:
# Else enter the password from the command line
if description != '':
print(description)
# password_sha256 is the plain SHA-256 password
# password_hashed is the salt + SHA-256 password
password_sha256 = self.sha256_hash(getpass.getpass('Password: '))
password_sha256 = self.sha256_hash(getpass.getpass(description))
password_hashed = self.hash_password(password_sha256)
if confirm:
# password_confirm is the clear password (only used to compare)
......@@ -144,7 +141,7 @@ class GlancesPassword(object):
return
# Create/overwrite the password file
with open(self.password_filepath, 'w') as file_pwd:
with open(self.password_filepath, 'wb') as file_pwd:
file_pwd.write(hashed_password)
def load_password(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册