Compare commits

..
Author SHA1 Message Date
rwinkhart b8611ab9fd Update README.md 2021-11-05 14:59:20 +00:00
RandyTheSilly 9a2986ab21 Final prep for first sshyp release 2021-11-05 10:56:17 -04:00
RandyTheSilly a81f892c4c Prep for first release of sshyp 2021-11-05 10:04:55 -04:00
RandyTheSilly aa9dd11793 Fixed bugs with config and syncing w/o files 2021-11-04 23:02:59 -04:00
RandyTheSilly c1da61bee5 Allow sshync to work w/sshyp 2021-11-04 20:23:09 -04:00
RandyTheSilly c34898b325 Ported rpass to sshyp 2021-11-01 20:31:11 -04:00
RandyTheSilly 621db67d34 Rebranding step 6 2021-11-01 19:02:12 -04:00
RandyTheSilly 3045a97f4c Rebranding step 5 2021-11-01 18:05:22 -04:00
RandyTheSilly 844c751957 Added link to changelog 2021-11-01 18:02:32 -04:00
RandyTheSilly be9d621c62 Rebranding step 4 2021-11-01 17:59:32 -04:00
rwinkhart 850aa60ba5 Delete changelog-sshyp 2021-11-01 21:52:45 +00:00
rwinkhart da4e229208 Delete rpass 2021-11-01 21:52:22 +00:00
8 changed files with 168 additions and 937 deletions
+10 -11
View File
@@ -1,23 +1,22 @@
# Maintainer: Randall Winkhart <idgr at tutanota dot com>
# The source package is no longer recieving updates past this version.
pkgname=rpass
pkgver=2021.11.01.mr5.1
pkgname=sshyp
pkgver=2021.11.05.fr1
pkgrel=1
pkgdesc='An rsync-based password manager and alternative to GNU pass'
pkgdesc='A self-hosted, synchronized password manager'
url='https://github.com/rwinkhart/sshyp'
arch=('x86_64' 'aarch64')
license=('GPL3')
depends=( python gnupg openssh rsync nano xclip wl-clipboard)
depends=( python gnupg openssh nano xclip wl-clipboard)
source_x86_64=('https://github.com/rwinkhart/sshyp/releases/download/v2021.11.01.mr5.1/rpass-2021.11.01.mr5.1.tar.xz')
source_aarch64=('https://github.com/rwinkhart/sshyp/releases/download/v2021.11.01.mr5.1/rpass-2021.11.01.mr5.1.tar.xz')
sha512sums_x86_64=('bf0c958721de1a13ca814d91bf74cbaaebe458198cba14b96b95fb1eeb72a1b901c8d3d00ea4c18ddff0d10d9ef6504a17a4caa345917412108df4787add61fd')
sha512sums_aarch64=('bf0c958721de1a13ca814d91bf74cbaaebe458198cba14b96b95fb1eeb72a1b901c8d3d00ea4c18ddff0d10d9ef6504a17a4caa345917412108df4787add61fd')
source_x86_64=('https://github.com/rwinkhart/sshyp/releases/download/v2021.11.05.fr1/sshyp-2021.11.05.fr1.tar.xz')
source_aarch64=('https://github.com/rwinkhart/sshyp/releases/download/v2021.11.05.fr1/sshyp-2021.11.05.fr1.tar.xz')
sha512sums_x86_64=('dcc2fe2e751120ffed86cad5f170bdf6ba4ef96df4c4cc784496289c7fda1ccef5ded030ce20f4ea6571a0def5bc185037b39f0958958a1aadb1ead63291b879')
sha512sums_aarch64=('dcc2fe2e751120ffed86cad5f170bdf6ba4ef96df4c4cc784496289c7fda1ccef5ded030ce20f4ea6571a0def5bc185037b39f0958958a1aadb1ead63291b879')
package() {
tar xf rpass-"$pkgver".tar.xz -C "${pkgdir}"
chown -R "$USER" ${pkgdir}/var/lib/rpass
tar xf sshyp-"$pkgver".tar.xz -C "${pkgdir}"
chown -R "$USER" ${pkgdir}/var/lib/sshyp
}
+31 -4
View File
@@ -1,13 +1,40 @@
# sshyp
A very simple self-hosted, synchronized password manager. Alternative to GNU pass.
"sshyp" stands for "sshync passwords", or "ssh sync passwords".
"sshync" is the custom syncing backend (based on sftp) used by "sshyp".
# WARNING
It is your responsibility to assess the security and stability of "sshyp" before using it and ensure it meets your needs.
I am not responsible for any data loss or breaches of your information resulting from the use of "sshyp".
"sshyp" is a new project that is constantly being updated, and though safety and security are priorities, they cannot be guaranteed.
# Mission Statement
sshyp aims to make it as simple as possible to manage passwords and notes via CLI across multiple devices in a self-hosted fashion.
sshyp aims to make it as simple as possible to manage passwords and notes via CLI across multiple devices in a secure, self-hosted fashion.
What sshyp can do:
- securely manage a collection of encrypted passwords and notes via CLI
- generate new, secure passwords to the user's choice in length and complexity
- securely sync said passwords and notes seamlessly between multiple POSIX compliant Unix devices
What sshyp will do:
- everything it already does, but also in a GUI for Linux/Android
- have a distinct retro theme
- receive many usability enhancements
What sshyp definitely won't do:
- 2FA/MFA (for security purposes, this should not be handled by your password manager)
- Windows support (I don't use Windows and I have no interest in developing for it)
# Installation
Arch Linux (x86_64, aarch64)
sshyp releases are available in the Arch User Repository as 'sshyp'.
Note: currently unavailable in the AUR (the older version, "rpass", will remain available until sshyp is stable)
sshyp releases will be available in the Arch User Repository as 'sshyp'.
Install with your preferred AUR helper or use:
@@ -26,8 +53,8 @@ Upon initial installation, be sure to run:
sshyp config
```
This command will allow you to configure the settings necessary for rpass to function.
As of right now, rpass is rapidly changing, and as such, it is a good idea to run "rpass config" after each update.
This command will allow you to configure the settings necessary for sshyp to function.
As of right now, sshyp is rapidly changing, and as such, it is a good idea to run "sshyp config" after each update.
All available options can be found with:
-834
View File
@@ -1,834 +0,0 @@
#!/usr/bin/python3
# internal modules
from os import system
from os import remove
from os import environ
from shutil import move
from shutil import rmtree
from sys import argv
from re import search
from re import escape
import random
import string
# custom modules
def clear():
print('\n' * 100)
def term(cmd):
_ = system(cmd)
def string_found(string1, string2):
if search(r"\b" + escape(string1) + r"\b", string2):
return True
return False
def replace_line(file_name, line_num, text):
xlines = open(file_name, 'r').readlines()
xlines[line_num] = text
open(file_name, 'w').writelines(xlines)
def edit_note():
lines = open('/dev/shm/' + shmfolder + '/' + shmentry).readlines()
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(lines[0:3])
open('/dev/shm/' + shmfolder + '/' + shmentry + '-n', 'w').writelines(lines[4:-2])
term('nano /dev/shm/' + shmfolder + '/' + shmentry + '-n')
edit_notes = open('/dev/shm/' + shmfolder + '/' + shmentry + '-n').read()
open('/dev/shm/' + shmfolder + '/' + shmentry, 'a').write('\n' + edit_notes + '\n\n')
def shmgen():
shmfoldergen = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits)
for _ in range(random.randint(10, 30)))
shmentrygen = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits)
for _ in range(random.randint(10, 30)))
term('mkdir -p /dev/shm/' + shmfoldergen)
return shmfoldergen, shmentrygen
def encrypt():
term('gpg -r ' + str(gpgid) + ' -e ' + "'" + '/dev/shm/' + shmfolder + '/' + shmentry + "'")
move('/dev/shm/' + shmfolder + '/' + shmentry + '.gpg', directory + entryname.replace('/', '', 1) + '.gpg')
rmtree('/dev/shm/' + shmfolder)
def encryptfolder():
term('gpg -r ' + str(gpgid) + ' -e ' + "'" + '/dev/shm/' + shmfolder + '/' + shmentry + "'")
move('/dev/shm/' + shmfolder + '/' + shmentry + '.gpg', directory + folder + '/' + folderentry + '.gpg')
rmtree('/dev/shm/' + shmfolder)
# argument - filter the argument to usable text
argument = str(argv).replace('[', '', 1).replace(']', '', 1).replace(',', '').replace("'", '') \
.replace(' ', '', 1).replace('/usr/bin/', '', 1).replace('rpass', '', 1)
# help
if argument == 'help' or argument == '--help' or argument == '-h':
print('\nrpass Copyright (C) 2021 Randall Winkhart')
print("This program comes with ABSOLUTELY NO WARRANTY; for details type `rpass show w'.\nThis is free software, "
"and you are welcome to redistribute it under certain conditions; type `rpass show c' for details.")
print('\nUSAGE: rpass [/<entry name>] [OPTION] [FLAG]\n')
print('Options: ')
print('help/--help/-h bring up this menu')
print('version/-v display rpass version info')
print('config configure rpass')
print('add add an entry')
print('gen generate a new password')
print('edit edit an existing entry')
print('copy copy details of an entry to your clipboard')
print('remove/-rm delete an existing entry')
print('sync/-s manually sync the entry directory via rsync\n')
print('Flags:')
print('add:')
print(' password/-p add a password entry')
print(' note/-n add a note entry')
print(' folder/-f add a new folder for entries')
print('edit:')
print(' rename/relocate/-r rename or relocate an entry')
print(' username/-u change the username of an entry')
print(' password/-p change the password of an entry')
print(' note/-n change the note attached to an entry')
print(' url/-l change the url attached to an entry')
print('copy:')
print(' username/-u copy the username of an entry to your clipboard')
print(' password/-p copy the password of an entry to your clipboard')
print(' url/-l copy the URL of an entry to your clipboard')
print(' note/-n copy the note of an entry to your clipboard')
print('gen:')
print(' update/-u generate a password for an existing entry\n')
print("Tip: You can quickly read an entry with 'rpass /<entry name>'!")
print("When specifying entry names, do not include the file extension! '.gpg' is assumed!\n")
# version info
if argument == 'version' or argument == '-v':
print('\n////////////////////////////////////////////////////////')
print('/ /')
print('/ rpass Copyright (C) 2021 Randall Winkhart /')
print('/ /')
print('/ Version 2021.11.01.mr5.1 /')
print('/ The Notetaker Update /')
print('/ /')
print('////////////////////////////////////////////////////////\n')
# licensing info
if argument == 'show w':
clear()
print('This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;')
print('without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.')
print('See the GNU General Public License for more details.')
print('\nhttps://opensource.org/licenses/GPL-3.0\n')
if argument == 'show c':
clear()
print('This program is free software: you can redistribute it and/or modify it under the terms of the GNU General')
print('Public License as published by the Free Software Foundation, either version 3 of the License,')
print('or (at your option) any later version.\n')
# config
if argument == 'config':
try:
print()
directorychoice = str(input('Would you like to use the default entry directory (~/.rpass-store/)? (Y/n) '))
if directorychoice == 'n' or directorychoice == 'N':
print('\nFormat: /this/path/ends/with/a/slash/\n')
directory = str(input('Please input a custom directory: '))
open("/var/lib/rpass/rpass-dir", 'w').write(directory + '\n')
else:
open("/var/lib/rpass/rpass-dir", 'w').write('/home/' + environ.get('USER') + '/.rpass-store/' + '\n')
print()
devicetype = str(input('Will this be a client, server, or offline device? (C/s/o) '))
if devicetype == 's' or devicetype == 'S':
open("/var/lib/rpass/rpass-ssh", 'w').write('\n\n\n\n' + devicetype)
print('\nMake sure the ssh service is running and properly configured.\n')
print('Configuration complete!\n')
else:
gpgid = ''
print()
gpgpresent = str(input(
'rpass requires the use of a unique gpg key. Do you already have one you are willing to use? (y/N) '))
if gpgpresent == 'y' or gpgpresent == 'Y':
print()
gpgid = str(input('Please input the ID of your gpg key: '))
open("/var/lib/rpass/rpass-gpg", 'w').write(gpgid + '\n')
else:
print()
gpggen = str(
input('Would you like to generate one now? Note that if you choose not to do this, you will have '
'to re-run "rpass config" to specify a gpg key when you acquire one (Y/n) '))
if gpggen == 'n' or gpggen == 'N':
exit()
else:
term('gpg --full-generate-key')
print()
gpgid = str(input('Please input the ID of your gpg key: '))
open("/var/lib/rpass/rpass-gpg", 'w').write(gpgid + '\n')
try:
open('/var/lib/rpass/lock', 'x').write('locked')
except FileExistsError:
pass
term('gpg -r ' + str(gpgid) + ' -e ' + '/var/lib/rpass/lock')
remove('/var/lib/rpass/lock')
if devicetype == 'o' or devicetype == 'O':
open("/var/lib/rpass/rpass-ssh", 'w').write('\n\n\n\n' + devicetype)
print('\nConfiguration complete!\n')
elif devicetype != 's' and devicetype != 'S':
devicetype = 'c'
print('\nMake sure the ssh service on the remote server is running and properly configured.\n')
sshgen = str(input('rsync support requires a unique ssh key. Would you like to have this '
'automatically generated? (Y/n) '))
if sshgen != 'n' and sshgen != 'N':
term('ssh-keygen -t ed25519 -f ~/.ssh/rpass')
print('\nExample input: 10.10.10.10:9999\n')
ip_port = str(input('What is the IP and ssh port of the remote server? '))
print()
ip, sep, port = ip_port.partition(':')
usernamessh = str(input('What is the username of the remote server? '))
print('\nDefault directory: ' + '/home/' + usernamessh + '/.rpass-store/\n')
directoryssh = str(input('Is the remote server using the default password directory? (Y/n) '))
if directoryssh == 'n' or directoryssh == 'N':
print('\nFormat: /this/path/ends/with/a/slash/\n')
directoryssh = str(input('What directory is the server using?: '))
else:
directoryssh = ('/home/' + usernamessh + '/.rpass-store/')
open("/var/lib/rpass/rpass-ssh", 'w').write(usernamessh + '\n' + ip + '\n' + port + '\n' + directoryssh +
'\n' + devicetype)
print('\nConfiguration complete!\n')
except KeyboardInterrupt:
print('\n\nConfiguration cancelled.\n')
exit()
# startup help
if argument == '':
clear()
print("Use 'help', '--help', or '-h' to see a list of commands.\n")
print('rpass is currently early software with very little polish\n')
# import userdata
try:
sshinfo = open("/var/lib/rpass/rpass-ssh").readlines()
usernamessh = sshinfo[0].replace('\n', '')
ip = sshinfo[1].replace('\n', '')
port = sshinfo[2].replace('\n', '')
directoryssh = sshinfo[3].replace('\n', '')
devicetype = sshinfo[4].replace('\n', '')
except (FileNotFoundError, IndexError):
usernamessh, ip, port, directoryssh, devicetype = (0, 0, 0, 0, 0)
directory = ''
try:
gpgid = open("/var/lib/rpass/rpass-gpg").read().strip()
directory = open("/var/lib/rpass/rpass-dir").read().strip()
term('mkdir -p ' + directory)
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print("Not all necessary configuration files are present. Please run 'rpass config'!")
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
exit()
# no argument
if argument == '':
try:
print()
term('cd ' + directory + '; ls -1 *')
print()
readentry = str(input('Entry to read: '))
clear()
term('gpg -d ' + directory + "'" + readentry.replace('/', '', 1) + "'" + '.gpg')
print()
except KeyboardInterrupt:
print('\n\nSelection cancelled.\n')
exit()
# read shortcut
if argument.startswith('/'):
if argument.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = argument.replace('/', '', 1).partition('/')
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
term('gpg -d ' + directory + "'" + argument.replace('/', '', 1) + '.gpg' + "'")
# add
if argument == 'add':
print('\nUSAGE: rpass add [FLAG]')
print('Flags:')
print('add:')
print(' password/-p add a password entry')
print(' note/-n add a note entry')
print(' folder/-f add a new folder for entries\n')
if argument == 'add note' or argument == 'add -n':
try:
clear()
entryname = str(input('Name of note: '))
except KeyboardInterrupt:
entryname, notes = (0, 0)
print('\n\nEntry add cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
term('nano /dev/shm/' + shmfolder + '/' + shmentry + '-n')
notes = open('/dev/shm/' + shmfolder + '/' + shmentry + '-n', 'r').read()
try:
if entryname.startswith('/'): # check if user input contains slashes
if entryname.replace('/', '', 1).__contains__('/'): # create folder and entry if there are two slashes
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines('\n\n\n\n' + notes + '\n\n')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else: # create entry if there is only one slash
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines('\n\n\n\n' + notes + '\n\n')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else: # create entry if there are no slashes
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines('\n\n\n\n' + notes + '\n\n')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The folder you requested to access does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'add password' or argument == 'add -p':
try:
clear()
entryname = str(input('Name of service: '))
username = str(input('Username: '))
password = str(input('Password: '))
url = str(input('URL: '))
except KeyboardInterrupt:
entryname, username, password, url, notes = (0, 0, 0, 0, 0)
print('\n\nEntry add cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
add_note = input('Add a note to this entry? (y/N) ')
if add_note == 'y' or add_note == 'Y':
term('nano /dev/shm/' + shmfolder + '/' + shmentry + '-n')
notes = open('/dev/shm/' + shmfolder + '/' + shmentry + '-n', 'r').read()
else:
notes = ''
try:
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + password + '\n' + url
+ '\n\n' + notes + '\n\n')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + password + '\n' + url
+ '\n\n' + notes + '\n\n')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + password + '\n' + url
+ '\n\n' + notes + '\n\n')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The folder you requested to access does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'add folder' or argument == 'add -f':
newfolder = str(input('Name of new folder: '))
term('mkdir ' + "'" + directory + newfolder + "'")
# edit
if argument == 'edit':
print('\nUSAGE: rpass edit [FLAG]')
print('Flags:')
print('edit:')
print(' rename/relocate/-r rename or relocate an entry')
print(' username/-u change the username of an entry')
print(' password/-p change the password of an entry')
print(' url/-l change the url attached to an entry')
print(' note/-n change the note attached to an entry\n')
if argument == 'edit rename' or argument == 'edit relocate' or argument == 'edit -r':
try:
clear()
term('cd ' + directory + '; ls -1 *')
print()
entryname = str(input('What file would you like to edit? '))
newname = str(input('New Name: '))
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
move(directory + folder + '/' + folderentry + '.gpg', directory + '/' + newname + '.gpg')
else:
move(directory + entryname.replace('/', '', 1) + '.gpg',
directory + newname.replace('/', '', 1) + '.gpg')
else:
move(directory + entryname + '.gpg', directory + newname + '.gpg')
except KeyboardInterrupt:
print('\n\nEdit cancelled.\n')
exit()
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
exit()
if argument == 'edit username' or argument == 'edit -u':
try:
clear()
term('cd ' + directory + '; ls -1 *')
print()
entryname = str(input('What file would you like to edit? '))
username = str(input('New Username: '))
except KeyboardInterrupt:
entryname, username = (0, 0)
print('\n\nEdit cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
folder + '/' + folderentry + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 0, username + '\n')
remove(directory + folder + '/' + folderentry + '.gpg')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
entryname.replace('/', '', 1) + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 0, username + '\n')
remove(directory + entryname.replace('/', '', 1) + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 0, username + '\n')
remove(directory + entryname + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'edit password' or argument == 'edit -p':
try:
clear()
term('cd ' + directory + '; ls -1 *')
print()
entryname = str(input('What file would you like to edit? '))
password = str(input('New Password: '))
except KeyboardInterrupt:
entryname, password = (0, 0)
print('\n\nEdit cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
folder + '/' + folderentry + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, password + '\n')
remove(directory + folder + '/' + folderentry + '.gpg')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
entryname.replace('/', '', 1) + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, password + '\n')
remove(directory + entryname.replace('/', '', 1) + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, password + '\n')
remove(directory + entryname + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'edit url' or argument == 'edit -l':
try:
clear()
term('cd ' + directory + '; ls -1 *')
print()
entryname = str(input('What file would you like to edit? '))
url = str(input('New URL: '))
except KeyboardInterrupt:
entryname, url = (0, 0)
print('\n\nEdit cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
folder + '/' + folderentry + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 2, url + '\n')
remove(directory + folder + '/' + folderentry + '.gpg')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
entryname.replace('/', '', 1) + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 2, url + '\n')
remove(directory + entryname.replace('/', '', 1) + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 2, url + '\n')
remove(directory + entryname + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'edit note' or argument == 'edit -n':
try:
clear()
term('cd ' + directory + '; ls -1 *')
print()
entryname = str(input('What file would you like to edit? '))
except KeyboardInterrupt:
entryname, notes = (0, 0)
print('\n\nEdit cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
folder + '/' + folderentry + '.gpg')
edit_note()
remove(directory + folder + '/' + folderentry + '.gpg')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
entryname.replace('/', '', 1) + '.gpg')
edit_note()
remove(directory + entryname.replace('/', '', 1) + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg')
edit_note()
remove(directory + entryname + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
# copy
if argument == 'copy':
print('\nUSAGE: rpass copy [FLAG]')
print('Flags:')
print('copy:')
print(' username/-u copy the username of an entry to your clipboard')
print(' password/-p copy the password of an entry to your clipboard')
print(' url/-l copy the URL of an entry to your clipboard')
print(' note/-n copy the note of an entry to your clipboard\n')
if argument == 'copy username' or argument == 'copy -u':
try:
print()
term('cd ' + directory + '; ls -1 *')
print()
readentry = str(input('Entry to copy: '))
except KeyboardInterrupt:
readentry = 0
print('\n\nCopy cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg')
copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines()
if environ.get('WAYLAND_DISPLAY') == 'wayland-0':
term('wl-copy ' + "'" + copyline[0].replace('\n', '') + "'")
else:
term('echo -n ' + "'" + copyline[0].replace('\n', '') + "'" + ' | xclip -sel c')
rmtree('/dev/shm/' + shmfolder)
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'copy password' or argument == 'copy -p':
try:
print()
term('cd ' + directory + '; ls -1 *')
print()
readentry = str(input('Entry to copy: '))
except KeyboardInterrupt:
readentry = 0
print('\n\nCopy cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg')
copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines()
if environ.get('WAYLAND_DISPLAY') == 'wayland-0':
term('wl-copy ' + "'" + copyline[1].replace('\n', '').replace("'", "'\\''") + "'")
else:
term('echo -n ' + "'" + copyline[1].replace('\n', '').replace("'", "'\\''") + "'" + ' | xclip -sel c')
rmtree('/dev/shm/' + shmfolder)
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'copy url' or argument == 'copy -l':
try:
print()
term('cd ' + directory + '; ls -1 *')
print()
readentry = str(input('Entry to copy: '))
except KeyboardInterrupt:
readentry = 0
print('\n\nCopy cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg')
copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines()
if environ.get('WAYLAND_DISPLAY') == 'wayland-0':
term('wl-copy ' + "'" + copyline[2].replace('\n', '') + "'")
else:
term('echo -n ' + "'" + copyline[2].replace('\n', '') + "'" + ' | xclip -sel c')
rmtree('/dev/shm/' + shmfolder)
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'copy note' or argument == 'copy -n':
try:
print()
term('cd ' + directory + '; ls -1 *')
print()
readentry = str(input('Entry to copy: '))
except KeyboardInterrupt:
readentry = 0
print('\n\nCopy cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + readentry + '.gpg')
copyline = open('/dev/shm/' + shmfolder + '/' + shmentry, 'r').readlines()
if environ.get('WAYLAND_DISPLAY') == 'wayland-0':
term('wl-copy ' + "'" + copyline[4].replace('\n', '') + "'")
else:
term('echo -n ' + "'" + copyline[4].replace('\n', '') + "'" + ' | xclip -sel c')
rmtree('/dev/shm/' + shmfolder)
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
# gen
if argument == 'gen':
try:
clear()
entryname = str(input('Name of service: '))
username = str(input('Username: '))
passlength = int(input('How many characters should be in the password? '))
passtype = str(input('Should the password be simple (for compatibility) or complex (for security)? (s/C) '))
if passtype != 's':
passtype = string.ascii_letters + string.digits + string.punctuation
if passtype == 's':
passtype = string.ascii_letters + string.digits
passgen = ''.join(random.SystemRandom().choice(passtype) for _ in range(passlength))
url = str(input('URL: '))
notes = str(input('Additional notes: '))
except KeyboardInterrupt:
entryname, username, passgen, url, notes = (0, 0, 0, 0, 0)
print('\n\nEntry generation cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + passgen + '\n' + url
+ '\n' + notes + '\n\n')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + passgen + '\n' + url
+ '\n' + notes + '\n\n')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
open('/dev/shm/' + shmfolder + '/' + shmentry, 'w').writelines(username + '\n' + passgen + '\n' + url
+ '\n' + notes + '\n\n')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The folder you requested to access does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
if argument == 'gen update' or argument == 'gen -u':
try:
clear()
term('cd ' + directory + '; ls -1 *')
print()
entryname = str(input('Which password would you like to re-generate? '))
passlength = int(input('How many characters should be in the password? '))
passtype = str(input('Should the password be simple (for compatibility) or complex (for security)? (s/C) '))
except KeyboardInterrupt:
entryname, passlength, passtype = (0, 0, 0)
print('\n\nEntry generation cancelled.\n')
exit()
shmfolder, shmentry = shmgen()
try:
if passtype != 's':
passtype = string.ascii_letters + string.digits + string.punctuation
if passtype == 's':
passtype = string.ascii_letters + string.digits
passgen = ''.join(random.SystemRandom().choice(passtype) for _ in range(passlength))
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
folder, sep, folderentry = entryname.replace('/', '', 1).partition('/')
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
folder + '/' + folderentry + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, passgen + '\n')
remove(directory + folder + '/' + folderentry.replace('/', '', 1) + '.gpg')
encryptfolder()
term('gpg -d ' + directory + folder + '/' + "'" + folderentry + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory +
entryname.replace('/', '', 1) + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, passgen + '\n')
remove(directory + entryname.replace('/', '', 1) + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname.replace('/', '', 1) + '.gpg' + "'")
else:
term('gpg -d --output /dev/shm/' + shmfolder + '/' + shmentry + ' ' + directory + entryname + '.gpg')
replace_line('/dev/shm/' + shmfolder + '/' + shmentry, 1, passgen + '\n')
remove(directory + entryname + '.gpg')
encrypt()
term('gpg -d ' + directory + "'" + entryname + '.gpg' + "'")
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
# remove
if argument == 'remove' or argument == '-rm':
clear()
term('cd ' + directory + '; ls -1 *')
print()
try:
entryname = str(input('What would you like to delete? '))
try:
term('gpg -d --output /dev/shm/rpass.lock /var/lib/rpass/lock.gpg')
unlocker = open('/dev/shm/rpass.lock', 'r').readlines()
remove('/dev/shm/rpass.lock')
except FileNotFoundError:
print('\nAccess denied.\n')
exit()
if entryname.startswith('/'):
if entryname.replace('/', '', 1).__contains__('/'):
if devicetype == 'c':
term('ssh -p ' + port + ' ' + usernamessh + '@' + ip + ' "' + ' rm -rf ' + "'" + directoryssh +
entryname.replace('/', '', 1) + '.gpg' + "'" + '"')
remove(directory + entryname.replace('/', '', 1) + '.gpg')
else:
if devicetype == 'c':
term('ssh -p ' + port + ' ' + usernamessh + '@' + ip + ' "' + ' rm -rf ' + "'" + directoryssh +
entryname.replace('/', '', 1) + "'" + '"')
rmtree(directory + entryname.replace('/', '', 1))
else:
if devicetype == 'c':
term('ssh -p ' + port + ' ' + usernamessh + '@' + ip + ' "' + ' rm -rf ' + "'" + directoryssh +
entryname + '.gpg' + "'" + '"')
remove(directory + entryname + '.gpg')
except KeyboardInterrupt:
print('\n\nDeletion cancelled.\n')
exit()
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print('The file you requested to delete does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
exit()
if argument.__contains__('-rm') or string_found('remove', argument) or string_found('add', argument) or \
string_found('edit', argument) or string_found('gen', argument) or string_found('copy', argument) or \
string_found('/', argument) or argument == 'sync' or argument == '-s' or argument == '' or argument == 'help' \
or argument == '--help' or argument == '-h' or argument == 'version' or argument == '-v' or argument == \
'config' or argument == 'show w' or argument == 'show c':
pass
else:
print('\n!!!!!!!!!!!!!!!')
print('Argument error!')
print('!!!!!!!!!!!!!!!')
print("\nUse 'help', '--help', or '-h' to see a list of commands.\n")
# permissions - applied pre-sync to ensure permissions are correct before upload
term('find ' + directory + ' -type d -exec chmod -R 700 {} +')
term('find ' + directory + ' -type f -exec chmod -R 600 {} +')
# rsync - ran at end of program to ensure all files are properly synced
if devicetype == 'c':
if argument.__contains__('-rm') or string_found('remove', argument) or string_found('add', argument) or \
string_found('edit', argument) or string_found('gen', argument) or argument == 'sync' or argument == '-s':
print('Syncing entries with other device(s)...\n')
term('rsync -v -H -r -l -t -p -e ' + '"ssh -i ~/.ssh/rpass -p ' + port + '" ' + directory + ' ' +
usernamessh + '@' + ip + ':' + directoryssh)
term('rsync -v -H -r -l -t -p --delete -e ' + '"ssh -i ~/.ssh/rpass -p ' + port + '" ' + usernamessh
+ '@' + ip + ':' + directoryssh + ' ' + directory)
+24 -16
View File
@@ -2,11 +2,13 @@
# Main Targets:
# TODO Make it so that when a new folder is created in sshyp, it is automatically created on the remote server
# TODO Replace references to rpass/sshyp directory with a changeable variable
# TODO Replace references to sshyp directory with a changeable variable
# TODO Clean everything up and move sshync to a separate package
# TODO Add dry run support
# TODO use partition command instead of split for separating paths
# TODO use classes!
# sshync 2021.11.01.unreleased3
# sshync 2021.11.05.unreleased5
# sshync was created to solve a problem with rpass/sshyp, and as such, sshync will be bundled with sshyp until it is
# polished enough for a standalone release
@@ -57,17 +59,17 @@ def get_file_paths_mod_remote(profile_dir):
identity = profile_data[5].replace('\n', '')
term("ssh -i " + "'" + identity + "'" + " -p " + port + " " + user + "@" + ip + " \"python -c \'import sshync; "
"sshync.get_file_paths_mod(" +
"\"'\"" + remote_dir + "/\"'\", " + "\"'\"/var/lib/rpass/sshyncdatabase_names\"'\", " +
"\"'\"/var/lib/rpass/sshyncdatabase_times\"'\")\'\"")
"\"'\"" + remote_dir + "/\"'\", " + "\"'\"/var/lib/sshyp/sshyncdatabase_names\"'\", " +
"\"'\"/var/lib/sshyp/sshyncdatabase_times\"'\")\'\"")
term(
'sftp -P ' + port + ' ' + user + '@' + ip + ':/var/lib/rpass/sshyncdatabase_names ' +
'/var/lib/rpass/sshyncdatabase_names')
'sftp -P ' + port + ' ' + user + '@' + ip + ':/var/lib/sshyp/sshyncdatabase_names ' +
'/var/lib/sshyp/sshyncdatabase_names')
term(
'sftp -P ' + port + ' ' + user + '@' + ip + ':/var/lib/rpass/sshyncdatabase_times ' +
'/var/lib/rpass/sshyncdatabase_times')
remote_mod_names = (open('/var/lib/rpass/sshyncdatabase_names').read()).replace('[', '').replace(']', '').replace(
'sftp -P ' + port + ' ' + user + '@' + ip + ':/var/lib/sshyp/sshyncdatabase_times ' +
'/var/lib/sshyp/sshyncdatabase_times')
remote_mod_names = (open('/var/lib/sshyp/sshyncdatabase_names').read()).replace('[', '').replace(']', '').replace(
' ', '').replace("'", '').split(',')
remote_mod_times = (open('/var/lib/rpass/sshyncdatabase_times').read()).replace('[', '').replace(']', '').replace(
remote_mod_times = (open('/var/lib/sshyp/sshyncdatabase_times').read()).replace('[', '').replace(']', '').replace(
' ', '').replace("'", '').split(',')
return remote_mod_names, remote_mod_times
@@ -107,7 +109,10 @@ def time_sort(old_names, new_names, old_times):
new_pos += 1
if title in old_names:
old_pos = old_names.index(title)
remote_mod_times_new.append(old_times[old_pos])
try:
remote_mod_times_new.append(old_times[old_pos])
except IndexError:
pass
return remote_mod_times_new
@@ -131,12 +136,15 @@ def run_profile(profile_dir):
remote_dir = profile_data[4].replace('\n', '')
identity = profile_data[5].replace('\n', '')
# get file modification times
local_mod_names, local_mod_times = get_file_paths_mod(local_dir + '/', '/var/lib/rpass/sshyncdatabase_names',
'/var/lib/rpass/sshyncdatabase_times')
local_mod_names, local_mod_times = get_file_paths_mod(local_dir + '/', '/var/lib/sshyp/sshyncdatabase_names',
'/var/lib/sshyp/sshyncdatabase_times')
remote_mod_times = []
remote_mod_names, remote_mod_times_temp = get_file_paths_mod_remote('/var/lib/rpass/rpass.sshync')
for time in remote_mod_times_temp: # remove quotes from remote_mod_times
remote_mod_times.append(float(time))
remote_mod_names, remote_mod_times_temp = get_file_paths_mod_remote('/var/lib/sshyp/sshyp.sshync')
try:
for time in remote_mod_times_temp: # remove quotes from remote_mod_times
remote_mod_times.append(float(time))
except ValueError:
pass
lmod_short = []
rmod_short = []
matching_names = []
+48 -67
View File
@@ -2,17 +2,18 @@
# external modules
import sshync
from os import system as term
from os import remove
from os import environ
from shutil import move
from shutil import rmtree
from shutil import copy
from sys import argv
from re import search
from re import escape
import random
import string
import sshync
# internal modules
@@ -66,19 +67,19 @@ def encryptfolder():
# argument - filter the argument to usable text
argument = str(argv).replace('[', '', 1).replace(']', '', 1).replace(',', '').replace("'", '') \
.replace(' ', '', 1).replace('/usr/bin/', '', 1).replace('rpass', '', 1).replace('./', '', 1).replace('.py', '', 1)
.replace(' ', '', 1).replace('/usr/bin/', '', 1).replace('sshyp', '', 1)
# help
if argument == 'help' or argument == '--help' or argument == '-h':
print('\nrpass Copyright (C) 2021 Randall Winkhart')
print("This program comes with ABSOLUTELY NO WARRANTY; for details type `rpass show w'.\nThis is free software, "
"and you are welcome to redistribute it under certain conditions; type `rpass show c' for details.")
print('\nUSAGE: rpass [/<entry name>] [OPTION] [FLAG]\n')
print('\nsshyp Copyright (C) 2021 Randall Winkhart')
print("This program comes with ABSOLUTELY NO WARRANTY; for details type `sshyp show w'.\nThis is free software, "
"and you are welcome to redistribute it under certain conditions; type `sshyp show c' for details.")
print('\nUSAGE: sshyp [/<entry name>] [OPTION] [FLAG]\n')
print('Options: ')
print('help/--help/-h bring up this menu')
print('version/-v display rpass version info')
print('config configure rpass')
print('version/-v display sshyp version info')
print('config configure sshyp')
print('add add an entry')
print('gen generate a new password')
print('edit edit an existing entry')
@@ -103,7 +104,7 @@ if argument == 'help' or argument == '--help' or argument == '-h':
print(' note/-n copy the note of an entry to your clipboard')
print('gen:')
print(' update/-u generate a password for an existing entry\n')
print("Tip: You can quickly read an entry with 'rpass /<entry name>'!")
print("Tip: You can quickly read an entry with 'sshyp /<entry name>'!")
print("When specifying entry names, do not include the file extension! '.gpg' is assumed!\n")
# version info
@@ -111,10 +112,10 @@ if argument == 'help' or argument == '--help' or argument == '-h':
if argument == 'version' or argument == '-v':
print('\n////////////////////////////////////////////////////////')
print('/ /')
print('/ rpass Copyright (C) 2021 Randall Winkhart /')
print('/ sshyp Copyright (C) 2021 Randall Winkhart /')
print('/ /')
print('/ Version 2021.10.18.mr5.1 /')
print('/ The Notetaker Update /')
print('/ Version 2021.11.05.fr1 /')
print('/ The sshync Update /')
print('/ /')
print('////////////////////////////////////////////////////////\n')
@@ -138,64 +139,57 @@ if argument == 'show c':
if argument == 'config':
try:
print()
devicetype = str(input('Will this be a client, server, or offline device? (C/s/o) '))
devicetype = str(input('Will this be a client or a server device? (C/s) '))
if devicetype == 's' or devicetype == 'S':
open("/var/lib/rpass/rpass-device", 'w').write(devicetype)
open("/var/lib/sshyp/sshyp-device", 'w').write(devicetype)
print('\nMake sure the ssh service is running and properly configured.\n')
copy('/usr/bin/sshync.py', '/home/' + environ.get('USER') + '/')
term('mkdir -p /home/' + environ.get('USER') + '/.password-pasture')
print('Configuration complete!\n')
else:
devicetype = 'c'
gpgid = ''
print()
gpgpresent = str(input(
'rpass requires the use of a unique gpg key. Do you already have one you are willing to use? (y/N) '))
'sshyp requires the use of a unique gpg key. Do you already have one you are willing to use? (y/N) '))
if gpgpresent == 'y' or gpgpresent == 'Y':
print()
gpgid = str(input('Please input the ID of your gpg key: '))
open("/var/lib/rpass/rpass-gpg", 'w').write(gpgid + '\n')
open("/var/lib/sshyp/sshyp-gpg", 'w').write(gpgid + '\n')
else:
print()
gpggen = str(
input('Would you like to generate one now? Note that if you choose not to do this, you will have '
'to re-run "rpass config" to specify a gpg key when you acquire one (Y/n) '))
'to re-run "sshyp config" to specify a gpg key when you acquire one (Y/n) '))
if gpggen == 'n' or gpggen == 'N':
exit()
else:
term('gpg --full-generate-key')
print()
gpgid = str(input('Please input the ID of your gpg key: '))
open("/var/lib/rpass/rpass-gpg", 'w').write(gpgid + '\n')
open("/var/lib/sshyp/sshyp-gpg", 'w').write(gpgid + '\n')
try:
open('/var/lib/rpass/lock', 'x').write('locked')
open('/var/lib/sshyp/lock', 'x').write('locked')
except FileExistsError:
pass
term('gpg -r ' + str(gpgid) + ' -e ' + '/var/lib/rpass/lock')
remove('/var/lib/rpass/lock')
if devicetype == 'o' or devicetype == 'O':
open("/var/lib/rpass/rpass-device", 'w').write(devicetype)
print('\nConfiguration complete!\n')
elif devicetype != 's' and devicetype != 'S':
devicetype = 'c'
term('gpg -r ' + str(gpgid) + ' -e ' + '/var/lib/sshyp/lock')
remove('/var/lib/sshyp/lock')
print('\nMake sure the ssh service on the remote server is running and properly configured.\n')
sshgen = str(input('rsync support requires a unique ssh key. Would you like to have this '
'automatically generated? (Y/n) '))
if sshgen != 'n' and sshgen != 'N':
term('ssh-keygen -t ed25519 -f ~/.ssh/rpass')
term('ssh-keygen -t ed25519 -f ~/.ssh/sshyp')
print('\nExample input: 10.10.10.10:9999\n')
ip_port = str(input('What is the IP and ssh port of the remote server? '))
print()
ip, sep, port = ip_port.partition(':')
usernamessh = str(input('What is the username of the remote server? '))
print('\nDefault directory: ' + '/home/' + usernamessh + '/.rpass-store/\n')
directoryssh = str(input('Is the remote server using the default password directory? (Y/n) '))
if directoryssh == 'n' or directoryssh == 'N':
print('\nFormat: /this/path/ends/with/a/slash/\n')
directoryssh = str(input('What directory is the server using?: '))
else:
directoryssh = ('/home/' + usernamessh + '/.rpass-store/')
open("/var/lib/rpass/rpass-device", 'w').write(devicetype)
sshync.make_profile('/var/lib/rpass/rpass.sshync', '/home/' + environ.get('USER') + '/.rpass-store/',
directoryssh, '/home/' + environ.get('USER') + '/.ssh/rpass', ip, port, usernamessh)
print('\nConfiguration complete!\n')
print('\nDefault directory: ' + '/home/' + usernamessh + '/.password-pasture/\n')
directoryssh = ('/home/' + usernamessh + '/.password-pasture/')
open("/var/lib/sshyp/sshyp-device", 'w').write(devicetype)
sshync.make_profile('/var/lib/sshyp/sshyp.sshync', '/home/' + environ.get('USER') + '/.password-pasture/',
directoryssh, '/home/' + environ.get('USER') + '/.ssh/sshyp', ip, port, usernamessh)
print('Configuration complete!\n')
except KeyboardInterrupt:
print('\n\nConfiguration cancelled.\n')
exit()
@@ -205,14 +199,15 @@ if argument == 'config':
if argument == '':
clear()
print("Use 'help', '--help', or '-h' to see a list of commands.\n")
print('rpass is currently early software with very little polish\n')
print('sshyp is currently early software with very little polish\n')
# import userdata
devicetype = 'c'
try:
devicetype = open('/var/lib/rpass/rpass-device').read().strip()
gpgid = open("/var/lib/rpass/rpass-gpg").read().strip()
sshinfo = sshync.get_profile('/var/lib/rpass/rpass.sshync')
devicetype = open('/var/lib/sshyp/sshyp-device').read().strip()
gpgid = open('/var/lib/sshyp/sshyp-gpg').read().strip()
sshinfo = sshync.get_profile('/var/lib/sshyp/sshyp.sshync')
usernamessh = sshinfo[0].replace('\n', '')
ip = sshinfo[1].replace('\n', '')
port = sshinfo[2].replace('\n', '')
@@ -220,9 +215,10 @@ try:
directoryssh = sshinfo[4].replace('\n', '')
term('mkdir -p ' + directory)
except FileNotFoundError:
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print("Not all necessary configuration files are present. Please run 'rpass config'!")
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
if devicetype != 's' and devicetype != 'S':
print('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
print("Not all necessary configuration files are present. Please run 'sshyp config'!")
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
devicetype, sshinfo, directory, directoryssh, ip, port, usernamessh = [0, 0, 0, 0, 0, 0, 0]
exit()
@@ -253,7 +249,7 @@ if argument.startswith('/'):
# add
if argument == 'add':
print('\nUSAGE: rpass add [FLAG]')
print('\nUSAGE: sshyp add [FLAG]')
print('Flags:')
print('add:')
print(' password/-p add a password entry')
@@ -292,7 +288,6 @@ if argument == 'add note' or argument == 'add -n':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('add')
if argument == 'add password' or argument == 'add -p':
try:
@@ -336,17 +331,15 @@ if argument == 'add password' or argument == 'add -p':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('add')
if argument == 'add folder' or argument == 'add -f':
newfolder = str(input('Name of new folder: '))
term('mkdir ' + "'" + directory + newfolder + "'")
open("/var/lib/rpass/mod_time", 'w').write('add')
# edit
if argument == 'edit':
print('\nUSAGE: rpass edit [FLAG]')
print('\nUSAGE: sshyp edit [FLAG]')
print('Flags:')
print('edit:')
print(' rename/relocate/-r rename or relocate an entry')
@@ -379,7 +372,6 @@ if argument == 'edit rename' or argument == 'edit relocate' or argument == 'edit
print('The file you requested to edit does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
exit()
open("/var/lib/rpass/mod_time", 'w').write('edit')
if argument == 'edit username' or argument == 'edit -u':
try:
@@ -422,7 +414,6 @@ if argument == 'edit username' or argument == 'edit -u':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('edit')
if argument == 'edit password' or argument == 'edit -p':
try:
@@ -465,7 +456,6 @@ if argument == 'edit password' or argument == 'edit -p':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('edit')
if argument == 'edit url' or argument == 'edit -l':
try:
@@ -508,7 +498,6 @@ if argument == 'edit url' or argument == 'edit -l':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('edit')
if argument == 'edit note' or argument == 'edit -n':
try:
@@ -550,12 +539,11 @@ if argument == 'edit note' or argument == 'edit -n':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('edit')
# copy
if argument == 'copy':
print('\nUSAGE: rpass copy [FLAG]')
print('\nUSAGE: sshyp copy [FLAG]')
print('Flags:')
print('copy:')
print(' username/-u copy the username of an entry to your clipboard')
@@ -588,7 +576,6 @@ if argument == 'copy username' or argument == 'copy -u':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('copy')
if argument == 'copy password' or argument == 'copy -p':
try:
@@ -615,7 +602,6 @@ if argument == 'copy password' or argument == 'copy -p':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('copy')
if argument == 'copy url' or argument == 'copy -l':
try:
@@ -642,7 +628,6 @@ if argument == 'copy url' or argument == 'copy -l':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('copy')
if argument == 'copy note' or argument == 'copy -n':
try:
@@ -669,7 +654,6 @@ if argument == 'copy note' or argument == 'copy -n':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('copy')
# gen
@@ -716,7 +700,6 @@ if argument == 'gen':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('gen')
if argument == 'gen update' or argument == 'gen -u':
try:
@@ -765,7 +748,6 @@ if argument == 'gen update' or argument == 'gen -u':
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
rmtree('/dev/shm/' + shmfolder)
exit()
open("/var/lib/rpass/mod_time", 'w').write('gen')
# remove
@@ -776,9 +758,9 @@ if argument == 'remove' or argument == '-rm':
try:
entryname = str(input('What would you like to delete? '))
try:
term('gpg -d --output /dev/shm/rpass.lock /var/lib/rpass/lock.gpg')
unlocker = open('/dev/shm/rpass.lock', 'r').readlines()
remove('/dev/shm/rpass.lock')
term('gpg -d --output /dev/shm/sshyp.lock /var/lib/sshyp/lock.gpg')
unlocker = open('/dev/shm/sshyp.lock', 'r').readlines()
remove('/dev/shm/sshyp.lock')
except FileNotFoundError:
print('\nAccess denied.\n')
exit()
@@ -806,7 +788,6 @@ if argument == 'remove' or argument == '-rm':
print('The file you requested to delete does not exist!')
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n')
exit()
open("/var/lib/rpass/mod_time", 'w').write('rm')
if argument.__contains__('-rm') or string_found('remove', argument) or string_found('add', argument) or \
string_found('edit', argument) or string_found('gen', argument) or string_found('copy', argument) or \
@@ -830,4 +811,4 @@ if devicetype == 'c':
if argument.__contains__('-rm') or string_found('remove', argument) or string_found('add', argument) or \
string_found('edit', argument) or string_found('gen', argument) or argument == 'sync' or argument == '-s':
print('Syncing entries with other device(s)...\n')
sshync.run_profile('/var/lib/rpass/rpass.sshync')
sshync.run_profile('/var/lib/sshyp/sshyp.sshync')
@@ -1,5 +1,52 @@
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp 2021.11.05.fr1
First public release of sshyp.
This release fixes major bugs from rpass and rebrands the project.
New features:
- an entirely new syncing back-end called sshync (custom Python wrapper around sftp)
^ in thoery, all syncing-related data loss should now be fixed, however, this new
system has just been created and is still under testing. Maybe wait for a few patches
before trusting this system.
Changes:
- branding has been updated to reflect new project name and goals
- custom directories, custom ssh keys, and offline only mode are removed (may be temporary)
^ the configuration wizard is being re-written in the next major update
Planned for next update (The Fluffy Update):
- modularized and optimized code
^ some older, bad code from "rpass" will be re-written.
- new visual features
^ this includes the new file list and thematic text art. sshyp will be
getting a retro computing theme.
- packages for more environments
^ "sshyp" will be officially packaged for Arch Linux, Alpine Linux, and Termux (Android).
Debian/Ubuntu and Fedora packaging will come later.
Planned for next update (The Sheep w/Shears Update):
- allow for copying entire notes (not just first line)
- allow for multi-client deletion... somehow
- ability to pass entries as arguments for more functions
- detatch sshync and make it a separate package
- manpage
Planned, no timeline:
- create separate gui frontend targetting mobile devices (Android + Linux phones)
^ the gui will also function on desktop linux
- package for more Linux distributions, such as Debian and Fedora)
- auto-completion on tab (currently unsure of best way to make this work)
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
rpass 2021.11.01.mr5.1
The Notetaker Update - Patch 1
@@ -1,4 +1,4 @@
sshyp 2021.11.01.fr1
sshyp 2021.11.05.fr1
First public release of sshyp.
@@ -14,6 +14,8 @@ New features:
Changes:
- branding has been updated to reflect new project name and goals
- custom directories, custom ssh keys, and offline only mode are removed (may be temporary)
^ the configuration wizard is being re-written in the next major update
Planned for next update (The Fluffy Update):
@@ -36,11 +38,12 @@ Planned for next update (The Sheep w/Shears Update):
Planned, no timeline:
- create separate gui frontend targetting mobile devices (first Android + Linux phones - official iOS client not likely)
- create separate gui frontend targetting mobile devices (Android + Linux phones)
^ the gui will also function on desktop linux
- make platform agnostic (add Windows support and package for more Linux distributions, such as Debian and Fedora)
- package for more Linux distributions, such as Debian and Fedora)
- auto-completion on tab (currently unsure of best way to make this work)
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
Future changelogs will include a link to the complete history of patches across rpass and sshyp.
The full history of changes to "sshyp" and "rpass" can be found on the following page:
https://raw.githubusercontent.com/rwinkhart/sshyp/main/extra/changelog-total
@@ -1,4 +1,4 @@
rpass is a FOSS password manager that takes advantage of rsync
sshyp is a FOSS password manager that takes advantage of rsync
Copyright (C) 2021 Randall Winkhart idgr@tutanota.com
This program is free software: you can redistribute it and/or modify