1
0
Fork 0
mirror of https://github.com/nishiki/manage-password.git synced 2024-10-27 02:33:19 +00:00
mpw/manage-password.py
2013-06-16 22:56:58 +02:00

313 lines
8 KiB
Python

#!/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/nishiki/.password-manager'
KEY = 'nishiki@yaegashi.fr'
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')
num = len(result)
if num > 0:
for i in range(num):
server = result[i][self.SERVER]
login = result[i][self.LOGIN]
port = result[i][self.PORT]
passwd = result[i][self.PASSWD]
if passwd:
os.system('sshpass -p ' + passwd + ' ssh ' + login + '@' + server + ' -p ' + str(port))
else:
os.system('ssh ' + login + '@' + server + ' -p ' + str(port))
else:
print 'No result!'
# Display the connections informations for a server
def display(self, search, type=''):
result = self.search(search, type)
num = len(result)
if num > 0:
for i in range(num):
print '# --------------------'
print '# Id: ' + result[i][self.ID]
print '# Server: ' + result[i][self.SERVER]
print '# Type: ' + result[i][self.TYPE]
print '# Login: ' + result[i][self.LOGIN]
print '# Password: ' + result[i][self.PASSWD]
print '# Port: ' + result[i][self.PORT]
print '# Comment: ' + result[i][self.COMMENT]
else:
print 'No result!'
# Display help
def help(self):
print '# HELP'
print '# --------------------'
print 'Add a new item: -a'
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()