mirror of
https://github.com/nishiki/manage-password.git
synced 2025-02-21 10:20:05 +00:00
316 lines
8 KiB
Python
Executable file
316 lines
8 KiB
Python
Executable file
#!/usr/bin/python
|
|
# author: nishiki
|
|
# mail: nishiki@yaegashi.fr
|
|
# date: 16/06/2013
|
|
# info: a simple script who manage your passwords
|
|
|
|
import csv
|
|
import re
|
|
import os
|
|
import sys
|
|
import gnupg
|
|
import getpass
|
|
import StringIO
|
|
import tempfile
|
|
import time
|
|
import datetime
|
|
|
|
FILE_GPG = '/home/adrien/.password-manager'
|
|
KEY = 'adrien.waksberg@believedigital.com'
|
|
FILE_PWD = '/tmp/.tmp_passwd'
|
|
TIMEOUT_PWD = 300
|
|
|
|
|
|
class ManagePasswd:
|
|
|
|
ID = 0
|
|
TYPE = 1
|
|
SERVER = 2
|
|
LOGIN = 3
|
|
PASSWD = 4
|
|
PORT = 5
|
|
COMMENT = 6
|
|
|
|
|
|
def __init__(self, key, file_gpg, file_pwd, timeout_pwd=300):
|
|
self.KEY = key
|
|
self.FILE_PWD = file_pwd
|
|
self.FILE_GPG = file_gpg
|
|
self.TIMEOUT_PWD = timeout_pwd
|
|
|
|
if os.path.isfile(self.FILE_GPG):
|
|
self.decrypt()
|
|
else:
|
|
self.data = ''
|
|
|
|
def __del__(self):
|
|
try:
|
|
self.file_tmp_name
|
|
except:
|
|
self.file_tmp_name = ''
|
|
|
|
if os.path.isfile(self.file_tmp_name):
|
|
os.remove(self.file_tmp_name)
|
|
|
|
# Decrypt a gpg file
|
|
# @rtrn: true if data is decrypted
|
|
def decrypt(self):
|
|
gpg = gnupg.GPG(verbose=False)
|
|
|
|
# Manage the passphrase
|
|
if os.path.isfile(self.FILE_PWD):
|
|
stat_file = os.stat(self.FILE_PWD)
|
|
if stat_file.st_mtime + self.TIMEOUT_PWD < time.time():
|
|
open(self.FILE_PWD, 'w').close()
|
|
else:
|
|
open(self.FILE_PWD, 'w').close()
|
|
|
|
file_pwd = open(self.FILE_PWD, 'r+')
|
|
os.chmod(self.FILE_PWD, 0600)
|
|
passwd = file_pwd.readline()
|
|
if not passwd:
|
|
passwd = getpass.getpass('Password GPG: ')
|
|
file_pwd.write(passwd)
|
|
|
|
file_pwd.close()
|
|
|
|
file_gpg = open(self.FILE_GPG, 'rb')
|
|
self.data = gpg.decrypt_file(file_gpg, passphrase=passwd)
|
|
file_gpg.close()
|
|
|
|
if not self.data.ok:
|
|
print 'Error: Your passphrase is probably wrong!'
|
|
os.remove(self.FILE_PWD)
|
|
return False
|
|
else:
|
|
os.utime(self.FILE_PWD, None)
|
|
return True
|
|
|
|
# Encrypt a file
|
|
def encrypt(self):
|
|
if os.path.isfile(self.file_tmp_name):
|
|
self.file_tmp.close()
|
|
os.system('gpg -r ' + self.KEY + ' --yes --output ' + self.FILE_GPG + ' --encrypt ' + self.file_tmp_name)
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
# Search in some csv data
|
|
# @args: search -> the string to search
|
|
# type -> the connection type (ssh, web, other)
|
|
# @rtrn: a list with the resultat of the search
|
|
def search(self, search, type=''):
|
|
result = list()
|
|
regex = re.compile('^.*' + search + '.*$')
|
|
regex_type = re.compile('^' + type + '$')
|
|
|
|
file_csv = StringIO.StringIO(self.data)
|
|
reader = csv.reader(file_csv, delimiter=';', quotechar='|')
|
|
for row in reader:
|
|
if regex.match(row[self.SERVER]) or regex.match(row[self.COMMENT]):
|
|
if type == '':
|
|
result.append(row)
|
|
else:
|
|
if regex_type.match(row[self.TYPE]):
|
|
result.append(row)
|
|
file_csv.close()
|
|
|
|
return result
|
|
|
|
# Search an id in some csv data
|
|
# @args: id -> the string to search
|
|
# @rtrn: the resultat of the search or false
|
|
def searchId(self, id):
|
|
result = list()
|
|
|
|
file_csv = StringIO.StringIO(self.data)
|
|
reader = csv.reader(file_csv, delimiter=';', quotechar='|')
|
|
for row in reader:
|
|
if row[self.ID] == id:
|
|
file_csv.close()
|
|
return row
|
|
|
|
file_csv.close()
|
|
return False
|
|
|
|
# Connect to ssh and display the password
|
|
# @args: search ->
|
|
def ssh(self, search):
|
|
result = self.search(search, 'ssh')
|
|
for r in result:
|
|
server = r[self.SERVER]
|
|
login = r[self.LOGIN]
|
|
port = r[self.PORT]
|
|
passwd = r[self.PASSWD]
|
|
|
|
if not port:
|
|
port = 22
|
|
|
|
if passwd:
|
|
os.system('sshpass -p ' + passwd + ' ssh ' + login + '@' + server + ' -p ' + str(port))
|
|
else:
|
|
os.system('ssh ' + login + '@' + server + ' -p ' + str(port))
|
|
|
|
if len(result) == 0:
|
|
print 'No result!'
|
|
|
|
|
|
# Display the connections informations for a server
|
|
def display(self, search, type=''):
|
|
result = self.search(search, type)
|
|
for r in result:
|
|
print '# --------------------'
|
|
print '# Id: ' + r[self.ID]
|
|
print '# Server: ' + r[self.SERVER]
|
|
print '# Type: ' + r[self.TYPE]
|
|
print '# Login: ' + r[self.LOGIN]
|
|
print '# Password: ' + r[self.PASSWD]
|
|
print '# Port: ' + r[self.PORT]
|
|
print '# Comment: ' + r[self.COMMENT]
|
|
|
|
if len(result) == 0:
|
|
print 'No result!'
|
|
|
|
|
|
# Display help
|
|
def help(self):
|
|
print '# HELP'
|
|
print '# --------------------'
|
|
print 'Add a new item: -a'
|
|
print 'Update an item: -u ID'
|
|
print 'Remove an item: -r ID'
|
|
print 'Show a item: -d search [type]'
|
|
print 'Connect ssh: -s search'
|
|
|
|
|
|
# Add a new item
|
|
def add(self):
|
|
print '# Add a new password'
|
|
print '# --------------------'
|
|
id = hex(int(time.time()))
|
|
server = raw_input('Enter the server name or ip: ')
|
|
type = raw_input('Enter the type of connection (ssh, web, other): ')
|
|
login = raw_input('Enter the login connection: ')
|
|
passwd = raw_input('Enter the the password: ')
|
|
port = raw_input('Enter the connection port (optinal): ')
|
|
comment = raw_input('Enter a comment (optinal): ')
|
|
|
|
self.generateTmpFile()
|
|
writer = csv.writer(self.file_tmp, delimiter=';', quotechar='|')
|
|
file_csv = StringIO.StringIO(self.data)
|
|
reader = csv.reader(file_csv, delimiter=';', quotechar='|')
|
|
for row in reader:
|
|
writer.writerow(row)
|
|
file_csv.close()
|
|
writer.writerow([id, type, server, login, passwd, port, comment])
|
|
print 'Item has been added!'
|
|
|
|
# Remove an item
|
|
# @args: id -> the unique identifiant
|
|
def remove(self, id):
|
|
self.generateTmpFile()
|
|
writer = csv.writer(self.file_tmp, delimiter=';', quotechar='|')
|
|
file_csv = StringIO.StringIO(self.data)
|
|
reader = csv.reader(file_csv, delimiter=';', quotechar='|')
|
|
for row in reader:
|
|
if row[self.ID] != id:
|
|
writer.writerow(row)
|
|
else:
|
|
print 'The item has been removed!'
|
|
file_csv.close()
|
|
|
|
# Update an item
|
|
# @args: id -> the item identifiant
|
|
def update(self, id):
|
|
result = self.searchId(id)
|
|
|
|
print '# Add a new password'
|
|
print '# --------------------'
|
|
id = result[self.ID]
|
|
server = raw_input('Enter the server name or ip [' + result[self.SERVER] + ']: ')
|
|
type = raw_input('Enter the type of connection [' + result[self.TYPE] + ']: ')
|
|
login = raw_input('Enter the login connection [' + result[self.LOGIN] + ']: ')
|
|
passwd = raw_input('Enter the the password: ')
|
|
port = raw_input('Enter the connection port [' + result[self.PORT] + ']: ')
|
|
comment = raw_input('Enter a comment [' + result[self.COMMENT]+ ']: ')
|
|
|
|
if not server:
|
|
server = result[self.SERVER]
|
|
if not login:
|
|
login = result[self.LOGIN]
|
|
if not type:
|
|
type = result[self.TYPE]
|
|
if not passwd:
|
|
passwd = result[self.PASSWD]
|
|
if not port:
|
|
port = result[self.PORT]
|
|
if not comment:
|
|
comment = result[self.COMMENT]
|
|
|
|
self.generateTmpFile()
|
|
writer = csv.writer(self.file_tmp, delimiter=';', quotechar='|')
|
|
file_csv = StringIO.StringIO(self.data)
|
|
reader = csv.reader(file_csv, delimiter=';', quotechar='|')
|
|
for row in reader:
|
|
if row[self.ID] != id:
|
|
writer.writerow(row)
|
|
writer.writerow([id, type, server, login, passwd, port, comment])
|
|
file_csv.close()
|
|
print 'Item has been updated!'
|
|
|
|
# Generate a temporary file
|
|
def generateTmpFile(self):
|
|
try:
|
|
self.file_tmp_name
|
|
except:
|
|
self.file_tmp_name = ''
|
|
|
|
if not os.path.isfile(self.file_tmp_name):
|
|
(file_tmp_fd, self.file_tmp_name) = tempfile.mkstemp()
|
|
self.file_tmp = os.fdopen(file_tmp_fd, 'r+')
|
|
return True
|
|
else:
|
|
try:
|
|
self.file_tmp = open(file_tmp_name, 'r+')
|
|
return True
|
|
except:
|
|
return False
|
|
|
|
|
|
################
|
|
# BEGIN SCRIPT #
|
|
################
|
|
|
|
num_argv = len(sys.argv)
|
|
|
|
manage = ManagePasswd(KEY, FILE_GPG, FILE_PWD, TIMEOUT_PWD)
|
|
|
|
# Display the item's informations
|
|
if num_argv >= 3 and sys.argv[1] == '-d':
|
|
if num_argv == 4:
|
|
manage.display(sys.argv[2], sys.argv[3])
|
|
else:
|
|
manage.display(sys.argv[2])
|
|
|
|
# Remove an item
|
|
elif num_argv == 3 and sys.argv[1] == '-r':
|
|
manage.remove(sys.argv[2])
|
|
manage.encrypt()
|
|
|
|
# Update an item
|
|
elif num_argv == 3 and sys.argv[1] == '-u':
|
|
manage.update(sys.argv[2])
|
|
manage.encrypt()
|
|
|
|
# Connect to ssh
|
|
elif num_argv == 3 and sys.argv[1] == '-s':
|
|
manage.ssh(sys.argv[2])
|
|
|
|
# Add a new item
|
|
elif num_argv == 2 and sys.argv[1] == '-a':
|
|
manage.add()
|
|
manage.encrypt()
|
|
|
|
# Display help
|
|
else:
|
|
manage.help()
|