Compare commits

...
220 Commits
Author SHA1 Message Date
RandyTheSilly 0bcf5fc0d1 Update documentation for release v1.5.3 2024-01-08 22:16:48 -05:00
RandyTheSilly ec3ee297b8 Remove unnecessary empty variable declarations (these were only included to silence PyCharm warnings) 2024-01-08 22:00:05 -05:00
RandyTheSilly 5f5ede7349 Fix notes sometimes being appended incorrectly when editing incomplete entries 2024-01-08 21:32:01 -05:00
RandyTheSilly cc3fa30865 Add CHOWN.py port-job to package.sh 2024-01-08 20:15:33 -05:00
RandyTheSilly 3613d3dd0c Fix installed extension ownership on FreeBSD 2024-01-08 20:11:26 -05:00
RandyTheSilly 249269a3e3 Address flake8 suggestions 2024-01-08 19:39:44 -05:00
RandyTheSilly c441802058 Fix root-level entries being displayed incorrectly in the entry list 2024-01-08 10:51:59 -05:00
RandyTheSilly 5439c899f7 Update documentation for release v1.5.2 - again 2024-01-07 20:51:41 -05:00
RandyTheSilly 0990bae310 Fix notes starting with blank lines differing in entry readout VS entry preview 2024-01-07 20:20:27 -05:00
RandyTheSilly ae21489c75 Optimize multi-line note readout 2024-01-07 20:00:57 -05:00
RandyTheSilly 5717133168 Do not connect to server from "sshyp init" menu, as the user may not yet have copied their ssh pubkey to the server 2024-01-07 19:42:44 -05:00
RandyTheSilly 07c0dee0a4 Fix quick-unlock: newly generated quick-unlock pins have not been valid since v1.5.0 - this is now fixed - re-generate your quick-unlock pin if it was created after v1.5.0 2024-01-07 19:08:02 -05:00
RandyTheSilly c85640804a Make quick-unlock pin-length configuration helptext more clear 2024-01-07 18:00:11 -05:00
RandyTheSilly 8ec2b31c23 Recommend using ssh keyfile without a password 2024-01-07 17:48:14 -05:00
RandyTheSilly 50189dd526 Warn against removing active device IDs 2024-01-07 17:14:36 -05:00
RandyTheSilly f13404e76f Apply consistent code formatting, especially regarding additive and multiplicative operators 2024-01-07 17:05:18 -05:00
RandyTheSilly 5d00f83df0 Remove trailing spaces upon commit 2024-01-07 16:44:39 -05:00
RandyTheSilly 5ce28e1138 Replace misuses of ".extend()" 2024-01-07 16:33:45 -05:00
RandyTheSilly 2f7b548360 Keep the user in device ID add/remove menus until they select "BACK", optimize menu logic 2024-01-07 16:25:43 -05:00
RandyTheSilly 6789e3e3de Improve method of serving whitelist contents to clients 2024-01-04 14:08:02 -05:00
RandyTheSilly a345f4181c Fix multi-word device IDs being unable to verify via quick-unlock 2024-01-04 13:56:26 -05:00
RandyTheSilly 08c6f1aeef Attempt to remove old device ID registration/whitelist entry from server when changing client device ID - bumps minimum supported Python version to 3.8 2024-01-04 13:41:35 -05:00
RandyTheSilly 3bb2f194d4 Standardize language (vars): _proceed/_sure -> _sure 2024-01-04 03:31:48 -05:00
RandyTheSilly 52727e8eea Extend 18d03279b9 to server tweak menu 2024-01-04 03:23:06 -05:00
RandyTheSilly cd560d6f8f Fix incorrect order of parameters when calling copy_id_check() from dev_id_config(), fixed inconsistency between order of parameters that caused the readability issue leading to the typo 2024-01-04 03:06:02 -05:00
RandyTheSilly 18d03279b9 Standardize language: device name/id -> device id, syncing -> synchronization/synchronizing 2024-01-03 22:56:13 -05:00
RandyTheSilly d4f1831486 Add a warning before changing an existing device id 2024-01-03 22:14:39 -05:00
RandyTheSilly 0ecb842480 Add "BACK" button in optional SSH configuration 2024-01-03 14:58:29 -05:00
RandyTheSilly 45be25e6bd Rename all back/cancel buttons to "BACK" 2024-01-03 14:43:14 -05:00
RandyTheSilly acf46b6227 Move registered_remover() to be covered by RMSERVER port-job 2024-01-03 14:32:46 -05:00
RandyTheSilly 3418bf6170 Replace unnecessary use of pop() 2024-01-03 14:20:15 -05:00
RandyTheSilly dbf3b35237 Add option to remove registered devices in server tweak menu 2024-01-03 14:10:09 -05:00
RandyTheSilly c48edfc624 Add 2024 to copyright duration, split changelog archive for 2024 2024-01-02 14:14:10 -05:00
RandyTheSilly b2eb63cbe6 Update documentation for release v1.5.2 2023-12-11 14:37:01 -05:00
RandyTheSilly 43f8306932 Add processing warnings during gpg key generation 2023-12-11 13:56:56 -05:00
RandyTheSilly e044122d48 Allow displaying partial options in curses menus in smaller terminals 2023-12-11 13:09:21 -05:00
RandyTheSilly 0e45a21a58 Re-implement "additional configuration options" header after init menu 2023-12-11 12:54:01 -05:00
RandyTheSilly a119544fbf Re-implement empty directory notification in entry list 2023-12-11 12:40:10 -05:00
RandyTheSilly 23e51ae133 Improve text wrapping for entry list - list now uses full width of terminal and can be displayed in smaller terminals without crashing 2023-12-11 02:58:04 -05:00
RandyTheSilly 27cf610a1f Fix crash when terminal is not tall enough to display curses radio pretext 2023-12-10 21:49:40 -05:00
RandyTheSilly 2edb1b9b53 Remove "/example/" heading format from extension downloader (this format is reserved entry paths) 2023-12-10 20:10:08 -05:00
RandyTheSilly 675e05c14f Improve text wrapping for curses radio pretext 2023-12-10 19:03:14 -05:00
RandyTheSilly 937b1357f5 Improve entry reader and entry list readability in light terminals 2023-12-10 15:28:57 -05:00
RandyTheSilly c3f8178db4 Fix needless function recursion when calling the global menu from the init menu (fixes errors on Alpine Linux 3.19) 2023-12-09 01:30:19 -05:00
RandyTheSilly 75cf927343 Properly handle error for missing pinentry program/configuration 2023-12-08 20:55:45 -05:00
RandyTheSilly 5a34cfbc8b Bump version to 1.5.2
Former-commit-id: 4344a965a805f5c92a707ed7ad37048f8eda93b6
Former-commit-id: 42325bca647366a6593272694daff9f9af390f10
2023-12-08 19:03:30 -05:00
RandyTheSilly c0d5d3b79f Address 7e1961e0ec [formerly c1521a73d443c173cd2b23f18f71f99fc54b0eb6] [formerly ef5415a793eaf8088f857331872181b40ef4d78f] in port-job
Former-commit-id: fe1d754b62dca302700dd8ab05f01a31117a9d0f
Former-commit-id: 223d95ecba109bad3c0724793c29574600f5bffe
2023-11-27 16:15:25 -05:00
RandyTheSilly d45f4264df Improve license information readability
Former-commit-id: c6c1f1b32544cd43e338c92fed8f8a168690be13
Former-commit-id: 7545104ced2e65a78734184261e104a34b4ec63b
2023-11-22 14:40:58 -05:00
RandyTheSilly dbae72b926 More clearly present extension information in the install screen
Former-commit-id: d75086ed21f45966b6c2b0074aea6e288d1ce650
Former-commit-id: fcf66ffac17cfc97868b0dc6dd4f4c4077f90fd3
2023-10-26 20:30:49 -04:00
RandyTheSilly da4a4d272d Add support for multi-line extension usage information
Former-commit-id: f3dfe5815a3ffcf453b430f12b63235a88469b3f
Former-commit-id: 9c3fec49417dfca2c1494f3edacd123b25dbe27a
2023-10-26 19:11:52 -04:00
RandyTheSilly 7e1961e0ec Fix empty clipboard warnings being shown to the user on Wayland if the same entry field is copied multiple times within 30 seconds
Former-commit-id: ef5415a793eaf8088f857331872181b40ef4d78f
Former-commit-id: c1521a73d443c173cd2b23f18f71f99fc54b0eb6
2023-10-26 18:32:47 -04:00
RandyTheSilly f80fd2b6e2 Fix quotes being copied when clearing Termux clipboard
Former-commit-id: 028b6bdcf891aa017f1d21b6b083591322695b69
Former-commit-id: 9ef4a8e58fc44068efdfab43b6f33e4de76d8efe
2023-10-26 17:48:12 -04:00
RandyTheSilly 787a2bbfc4 Fix extension removal on Busybox environments (Alpine)
Former-commit-id: 47909194ae390b1ace732f19da7a5a72592824c8
Former-commit-id: 165ea2af5edfc99d1094a4aeb1a341ac815d3af8
2023-10-25 21:16:17 -04:00
RandyTheSilly e7f0618142 Fix Fedora and FreeBSD packaging excluding clipclear.py (official v1.5.1 packages are unaffected by this)
Former-commit-id: d8d0d5a4cd14e3aac159ebd9755c82c3f0e058e2
Former-commit-id: 7bc639d5628c27988f88cb691345eb8680c07266
2023-10-24 11:50:26 -04:00
RandyTheSilly 1f5a2c8f3c Update documentation for release v1.5.1
Former-commit-id: d9721cfcc36cc53f2719f0c57c3c5c58578e3eb1
Former-commit-id: 9e3bba69e4d4e8d074b3882b56f2221aa7edd6ad
2023-10-23 23:19:03 -04:00
RandyTheSilly 386044d081 Fix colons and backslashes in gpg key names being interpreted as their hexadecimal equivalents
Former-commit-id: 98a19896d872423ff771e4b7bb5014397b63e889
Former-commit-id: 940178d578742aa457b985df4d7b231324aba0d9
2023-10-23 22:32:56 -04:00
RandyTheSilly c651c41a41 Disable ConfigParser interpolation to allow for "%" to be stored in configuration files
Former-commit-id: 4ac84f3ceef3407bd9e8e2c2f2191f7ea2ee2a55
Former-commit-id: 2fb4bf9d2630520702e99fa0913a3db5e1a0d0bb
2023-10-23 21:08:01 -04:00
RandyTheSilly 7cb245edde Fix CLIPCLEAR port-job for generic Linux (Wayland/X11)
Former-commit-id: 3690a41cbfce5eff13388fa7c9fe9f39d6e36865
Former-commit-id: a9a991dc141d1eb7d7973f8ecb08188dda27953b
2023-10-23 20:37:41 -04:00
RandyTheSilly edf31f9a7c Add port-job for making clipclear.py platform-specific
Former-commit-id: 6aafd4dfcddefc31bf61d3018b63ef48c156d8a8
Former-commit-id: c016e6872d71bc4bb347d85cf964dd9e7b7fe149
2023-10-23 13:51:11 -04:00
RandyTheSilly 362b1aa025 Remove unused variable from RMEXTMAN.py
Former-commit-id: ea907d093c1ffdccffc9db55f573d08650cfb7e2
Former-commit-id: e2178912cec4b4327c576af625fe8d1e6e498665
2023-10-23 13:05:46 -04:00
RandyTheSilly 5633520d82 Fix clipboard clearing on non-Wayland platforms; drop dos2unix as a WSL dependency; suggest openssh-server on Debian and Fedora
Former-commit-id: 046786460edc669fa9b962314953164c1cce078e
Former-commit-id: d9f0eeb57d73a0255c9dc713533d08d30413bf90
2023-10-23 10:35:59 -04:00
RandyTheSilly a487bd561a Fix clipboard contents sometimes failing to clear
Former-commit-id: 8ecbbb6199864fda973e47605a10d737318f3993
Former-commit-id: eb625eded3f9518967ee9fa06201311e8571e394
2023-10-20 00:32:29 -04:00
RandyTheSilly cbc0538e82 Call printf with %b to avoid interpreting directives
Former-commit-id: f1e812634d538b8e8c412b0c3aa1c43aab1c4f1b
Former-commit-id: f95072b8742e752be18dc3fe9cba17c8e82eb41b
2023-10-19 20:52:35 -04:00
RandyTheSilly 5c589de4f2 Switch to v1.5.1 extension pointer
Former-commit-id: 3997d7c4f7a05a8992b93a9b8d73c3d44e4c6026
Former-commit-id: 2a56f062345d177023c9a6f1f5ed5415450a9155
2023-10-19 18:47:06 -04:00
RandyTheSilly 44392467e5 Require identity to be passed to whitelist_verify() (for extension support with custom SSH keys)
Former-commit-id: 9db42722585f1fb707d5144e828cefddfcbf5137
Former-commit-id: 1e79c49459b49eb422788eba315a6d9c6e09f9a1
2023-10-18 15:14:20 -04:00
RandyTheSilly 18aacf648b Add pop-up explaining optional configuration menu
Former-commit-id: ed0d42781420080646ec6051e9f9c56ba8eaba99
Former-commit-id: 48b7d5de29ee9ad88b0aec222954769473ddda8a
2023-10-17 00:52:54 -04:00
RandyTheSilly ac621a8a73 Add "TROUBLESHOOTING" section to man page
Former-commit-id: 352412410256035906c586975b9cc5460f6b19be
Former-commit-id: 2d1092037448f1d2aaf9c137b751efcbe984995e
2023-10-17 00:40:06 -04:00
RandyTheSilly 98f76ac1ab Exclude "known_hosts.old" in ssh key listing
Former-commit-id: fc088270e9865b35ae4b10f020fec916e5093a8a
Former-commit-id: 8988481a7d3f37636dfa534312890760cd24ca81
2023-10-16 23:51:20 -04:00
RandyTheSilly bdff85f024 Fix copy_id_check resulting in errors when called from another module
Former-commit-id: 31bb5415499ca5f06413eba61eaafd284d2d5da1
Former-commit-id: 9cd0e6852e09874a1a06c8cde22e539f1cb58345
2023-10-16 23:46:19 -04:00
RandyTheSilly 2bcabe8597 Update README.md to specify Python 3.12 support
Former-commit-id: cfc8548cfb03f839d3cec89be68f839e8863de89
Former-commit-id: 1c0495fb2421d5f1b035a468fa15175b2a031e43
2023-10-02 20:05:10 -04:00
RandyTheSilly 7259a8732c (MacOS) Port new clipboard behavior to MacOS
Former-commit-id: bd887c5ee6a75130b8c994034708ae7893764251
Former-commit-id: e1621ed1a986f731c8217d741fd84a42196cb4e9
2023-09-26 20:29:51 -04:00
RandyTheSilly 20cdc27b88 (Haiku) Port new clipboard behavior to Haiku
Former-commit-id: 3a40559cf39475a0291187a4853c1e5f335b96f0
Former-commit-id: 95bfec78129d9d22afb16a33775df8d3abb24fa1
2023-09-26 19:51:05 -04:00
RandyTheSilly 2f6bdb8d2e (Termux) Port new clipboard clear behavior to Termux
Former-commit-id: bdda7fae8c2305e1f64c468d45c205d12645f669
Former-commit-id: e6fea38cc85a03b8970f0cdf61390825cc048c20
2023-09-26 19:32:56 -04:00
RandyTheSilly eb4fae3e9e Fixed new clipboard clear behavior on FreeBSD
Former-commit-id: e276182b11c518bc7b880eaebb7d9c8fd528761b
Former-commit-id: fc1f067c5c0df86109795feca05527be5322d829
2023-09-26 19:03:07 -04:00
RandyTheSilly 30afbafcbf Fixed xclip throwing errors on FreeBSD
Former-commit-id: 65b466c0598f2194d452c0897ffa9eeb7ec3b281
Former-commit-id: 51ad92728be141113047bb25fb8841d141d545e6
2023-09-26 18:37:42 -04:00
RandyTheSilly e010180219 (X11) Port new clipboard clear behavior to X11
Former-commit-id: 11edd45f8ccaa6de548d6656ef50cd0c1bdff0b4
Former-commit-id: 1fb779b6d27937d83802f50fb6857f24ec7765ed
2023-09-25 13:53:59 -04:00
RandyTheSilly 1f4e7d5cae (WSL) Marked "dos2unix" as a dependency for the WSL package
Former-commit-id: e1adc5ac923a07d87ccb2ee3c687b9e935200617
Former-commit-id: a906b07e1cc19921d1ec94cec99644657b963ee1
2023-09-25 13:11:01 -04:00
RandyTheSilly 67983da22e (WSL) Port new clipboard clear behavior to WSL
Former-commit-id: e1d96418abae79f6af75d72eeb6279e661196bd5
Former-commit-id: 0b345de72d9dc13de2f0db7c26264e0deb685965
2023-09-25 12:54:21 -04:00
RandyTheSilly aa0bd017c9 Fixed CLIPBOARD.py port-job overriding the new clipboard clear behavior
Former-commit-id: 13f705945bf0bbe95b5699f2bd64b9c790324048
Former-commit-id: 54e8c6f8d54e592bdda885de296f56f1d5ecdd24
2023-09-24 22:04:00 -04:00
RandyTheSilly 5a4e952d4d (Wayland) Only clear clipboard contents if they have not been changed since altered by sshyp
Former-commit-id: 2b6be8d327419bccc51430f732fb03ff9bba0439
Former-commit-id: 09406c55e394e97c90d984067bff9b4677b0496a
2023-09-24 21:50:14 -04:00
RandyTheSilly db05e9b05e Fixed offline-mode sync warning displaying at inappropriate times
Former-commit-id: 37c0fe00ec30a903ec7ba40525f01a2963b24d72
Former-commit-id: e6cea4d212e6f9b231dc0d0743b667b9f2eb376c
2023-09-24 19:35:48 -04:00
RandyTheSilly 397ad7d409 Update Haiku package to use Python 3.11
Former-commit-id: cc3ae472b67be63d960b4993c355f9d5acf7d899
Former-commit-id: 8d758713964c081c6dbb56899f2b84e51d25eac0
2023-09-24 19:27:20 -04:00
RandyTheSilly 5af02866b4 Fixed clipboard contents leaking through process list on Wayland
Former-commit-id: bb1485fec2d891af9f49b4d8e81df72b0e6160d9
Former-commit-id: 2eff4ace8b82735a890bf1e669d92d7abbb59dfa
2023-09-24 18:56:42 -04:00
RandyTheSilly e8267f838a Read some fields from config file as boolean values
Former-commit-id: ba2f082fc4d043d55ba5d25875ac9b9600bbbd3a
Former-commit-id: 4e31560e91047d035eb87e312fd17f3e8ad1935f
2023-09-24 16:38:30 -04:00
RandyTheSilly e4fbcd6825 Added an error for when the configured text editor cannot be found on the system
Former-commit-id: f41356854b88cf6a53604ef37025667d17041da7
Former-commit-id: 627cb9298583b7fbb6358edead75c65e671619d0
2023-09-24 15:04:36 -04:00
RandyTheSilly 9ba4b8d724 Added a warning when the user manually attempts to sync in offline mode
Former-commit-id: f54591cc6997078a248c5d8dc3dcd533824c04e4
Former-commit-id: fb405077f39e22840e98bca6a854496bd583c49c
2023-09-24 14:35:01 -04:00
RandyTheSilly 0b73d4016f Always use the user-specified ssh keyfile in place of the previously hard-coded ~/.ssh/sshyp
Former-commit-id: 2ec48a889401a5da39c162f966b2e1eaa4c90aad
Former-commit-id: e0071948993af51c3de731eaf49c16d5fdab3632
2023-09-24 14:03:44 -04:00
RandyTheSilly 185baec03f Fixed re-encryption not being possible in offline mode
Former-commit-id: f608b138c1d850523c3c5cde0e65ec592a1e1a10
Former-commit-id: 0c5f542c6bf66e51c79969dd3ba60586d814d73a
2023-07-12 21:07:31 -04:00
RandyTheSilly f930ffe94a Fixed version info graphic having invisible elements in white-background terminals
Former-commit-id: 0b2eafdf0bcecc580110455373d2fc3e5390b60b
Former-commit-id: 9889ea48fff7c744776b4687b7ab91e17534e03d
2023-07-12 20:55:38 -04:00
RandyTheSilly a6fb33705e Update documentation for release v1.5.0
Former-commit-id: d7e5cd4c453f28ab69cce51c9720f9bc81932525
Former-commit-id: 42b30444972be06c8781ad193abcd638b64fd2de
2023-07-12 19:22:58 -04:00
RandyTheSilly 6483ffe6cf Fixed extensions directory not being preserved in Fedora package
Former-commit-id: d2d094187d9fa2d037b94bdc387a54c463f3a2d1
Former-commit-id: 38dc77b41bcaf8afd15f6d058c6ef0fedc93f6b6
2023-07-12 18:35:03 -04:00
RandyTheSilly 33bc0fc10f Fixed extensions directory not being preserved in FreeBSD package
Former-commit-id: 5aeda29d8b3bfb0549fccf6b7f90880038293288
Former-commit-id: 4d5471ad85f47ff9e18624671a0fb55bc4413a2f
2023-07-12 17:47:09 -04:00
RandyTheSilly 58698c1c55 Updated version info screen text art
Former-commit-id: 3e4d061d96877024ab8ebc1710a08a477ac4a9ca
Former-commit-id: 66e5d57695cec0a87b8ed44ed632e00b2364be4f
2023-07-11 15:06:37 -04:00
RandyTheSilly 37075230cc Added port-job for disabling extension management; applied to Haiku and Termux packages
Former-commit-id: eb66222b45b41fbd92712dacd23ed825ba377982
Former-commit-id: 0544589759a4e41c005aae8a6b00fcdff58f72d9
2023-07-11 12:34:59 -04:00
RandyTheSilly 7e9786fe60 Fixed possibility of attempting to sync from a server installation
Former-commit-id: 4ac82c68470f451635c698a244899140e97640b2
Former-commit-id: 8b1381521016f23d1c53c6f1e23d1851a0aa04f0
2023-07-10 15:46:07 -04:00
RandyTheSilly 2e51a1ff15 Ensure ~/.ssh directory exists in sshync configuration
Former-commit-id: 84f8021609d8e62c12e89fc539fcb954ec876118
Former-commit-id: 3bb543b0b155f6ef73dc277042246bf8f918597b
2023-07-10 14:41:44 -04:00
RandyTheSilly b1567d768b Removed use of awk/sed from packaging script
Former-commit-id: 7dceca5cbeea3726c84b83fd274d795683692415
Former-commit-id: a7565aa6ebf70e8d7eea07f5e3ecac3606c54947
2023-07-10 14:16:58 -04:00
RandyTheSilly e487c381e7 Auto-detect Installed-Size for Debian packages
Former-commit-id: bc0244a0818f976c31e342e2bd2ec1f09a2d00b8
Former-commit-id: 0a4361c046776c7a7d7a40fba054482fad9cdcd9
2023-07-10 14:09:14 -04:00
RandyTheSilly 8ce1f18ff9 Converted Termux package to client-only due to server-hosting bugs on Termux
Former-commit-id: e5315b2037e0e8355d6d3765e252c402a67ec18d
Former-commit-id: 90636fda875b795ff65b2ce4abee73d418616ed1
2023-07-10 12:21:58 -04:00
RandyTheSilly 3783230606 Rename Haiku package filename to match package name
Former-commit-id: 759cbd160e0ea0d7ef5c2934196d4f3468287634
Former-commit-id: d81c780f775655f5c8669a44af23b8cc0771e27a
2023-07-10 11:23:42 -04:00
RandyTheSilly a3551cc042 If $EDITOR is not set, default to "vi" instead of "nano"
Former-commit-id: e07df2bf109cc0de30a88a1bfe49ec15f8e739fb
Former-commit-id: 9dc13886c901240b8f8cfe99a1181817d92161a7
2023-07-09 13:17:50 -04:00
RandyTheSilly 5b9b6da341 Fixed CLIPTOOL.py adding an outdated, non-functional warning
Former-commit-id: 4072bb5ec0cd7b08eecb176f809aed9145385090
Former-commit-id: 1b42beaa6d097c1c953cb91dafdc821271791467
2023-07-09 13:00:39 -04:00
RandyTheSilly 9abb1c45bd Include stweak.py in FreeBSD and Fedora packages
Former-commit-id: a0af16d70dea2b0a2196fe2588d58574119d316f
Former-commit-id: 9bbdc72fe9e3a4d10819397af585980f55893fc6
2023-07-09 11:36:26 -04:00
RandyTheSilly ba1e2734be Re-implemented re-encryption termination warning
Former-commit-id: 328eb0038e909a9831edce0f1b978323c491f4f5
Former-commit-id: 337b2de2b370e6d410a14f5cffcea6d1b3b26034
2023-07-08 21:58:50 -04:00
RandyTheSilly d40d1daab5 Fixed Haiku using the wrong Python version, made building on Haiku easier
Former-commit-id: f5d19c55405790060136af4f2a012987ce88d5f2
Former-commit-id: 69aef95294b038c405d95ad3aa37c0a1991a9f8a
2023-07-08 20:25:59 -04:00
RandyTheSilly 5255d61f61 Fixed missing clipboard tool error message
Former-commit-id: 0f44766f316be7c27ba2a9a6cb94ac9bbb86c0ab
Former-commit-id: 4811948d213abb5f5170841022f5b026242ac80b
2023-07-08 19:58:14 -04:00
RandyTheSilly 9fc2aa69a3 No longer exit the tweak menu after (un-)installing an extension
Former-commit-id: 6589fef86d354b7dd3fd066e19b87b412c5e6eec
Former-commit-id: 6d9b5a407a566effa13943664d4d6ba00de40d54
2023-07-08 19:41:45 -04:00
RandyTheSilly 7f4ddd2775 Re-enforce proper syntax by always showing /<entry name>, rather the </entry name>
Former-commit-id: cd0cfb7df05a37999ae057e9d2908f8130107e9e
Former-commit-id: 64bcafbc58b241b74275e70675ae586e9180400f
2023-07-08 19:15:29 -04:00
RandyTheSilly 4a7234282b Replaced termination messages with mid-config confirmation dialogs
Former-commit-id: d6cf3398a45586fc2f21b209cc8a10ad7f67c5d9
Former-commit-id: 55b9c950ac3d9a2fa63341c0e7382c912abda216
2023-07-08 19:09:06 -04:00
RandyTheSilly 5fb5b5b108 Allow multiple lines of text before presenting radio options
Former-commit-id: 46751c0b67133a277612c46086b21f5c2477cf48
Former-commit-id: db8800da451d469e1d42dae19a4ca77bf657c947
2023-07-08 18:53:37 -04:00
RandyTheSilly 1344aa23f6 Fixed privilege escalation code attempting to run when interacting with user-only menus
Former-commit-id: bcc2a99ab5324a049982bfff83eb191cfd7c0346
Former-commit-id: ce58e4b07a2e5fc26ab34c8ecdc695953b5a2d58
2023-07-08 17:24:57 -04:00
RandyTheSilly 2ac8e8e434 Fixed privilege escalation input in extension manager
Former-commit-id: d75cdc8010eb8b5285c532284c9b14d553c7deaf
Former-commit-id: 57edd15ca67e4f2e94f5201cdb18401b5ac40f59
2023-07-08 17:18:05 -04:00
RandyTheSilly aa7768fd6e Fixed potential variable undefined errors
Former-commit-id: e5e902682c90b221f8bb58d4a5ca08f2c82bb703
Former-commit-id: c210e048d0ee28327e8302f37f9dc439db826055
2023-07-08 12:58:26 -04:00
RandyTheSilly 2835214d60 Handle missing section and option errors on startup
Former-commit-id: 0729eb0432f1974f1957bd0eb146d287a36c43da
Former-commit-id: 60d0a88bf87fb87580b36feedecbf0b4a82215fd
2023-07-07 17:13:52 -04:00
RandyTheSilly ee56a7a919 Fixed many instances where the curses menus could break the terminal session
Former-commit-id: df73403b4a8bc3ffb238486516d0f1e5a1f601c6
Former-commit-id: 649503907f391ff318fc0d3247b965ed3b2aacba
2023-07-07 15:06:57 -04:00
RandyTheSilly 4ad516e156 Fixed required options not being set when switching from server to client modes
Former-commit-id: 70c190d280802779a92fe2ad509c648134ea83aa
Former-commit-id: a2d939cd3b467186714625da7eae0027e738c5e0
2023-07-07 12:53:42 -04:00
RandyTheSilly 3347c425d9 Fixed attempting to install extensions resulting in an error
Former-commit-id: 821b770fdcea74c51b4077c2c956060340827b81
Former-commit-id: 5ca345ef9391b834d7b6d276ec2ff552a3bf942b
2023-07-07 10:26:13 -04:00
RandyTheSilly 488b94e638 Documentation draft for release v1.5.0
Former-commit-id: 0b48dd00fa914cb5c1d734687dae0827a7a00d7c
Former-commit-id: 2396087e33fed9982f12cfe3593c4ec43d4f0d89
2023-07-07 10:12:06 -04:00
RandyTheSilly 343bc40ddd Added "other" error code to man page
Former-commit-id: ad89fc282ced553cb2647625c0206cb3e796bbaf
Former-commit-id: 4a0a3ca2d282c61a970ed07b5170bbb0e85b37a1
2023-07-06 13:23:54 -04:00
RandyTheSilly 3cc5b5633c Added cancel option for installing/uninstalling extensions
Former-commit-id: d594a918dbc21b9379a83e7fd01f560ba4b275ea
Former-commit-id: bfe3f71d2ee6be832e7614e4f05147e576530d78
2023-07-06 13:02:02 -04:00
RandyTheSilly 43c10e74e2 Default to 'no' selection for optional menu items
Former-commit-id: 25735d67f0be5df5a47b94803a6d9b8f133def09
Former-commit-id: 0d9665a1fa1ce248a26622d007fd0c440cc9f86e
2023-07-06 12:24:15 -04:00
RandyTheSilly 95cc769c23 Fixed menu options not related to extension management throwing errors
Former-commit-id: a6d55fa0f2e072d823b13ac69f8ff27251b3f3c0
Former-commit-id: 847eeb222459802dc3b8ac778c6b89243048fa4f
2023-07-06 12:17:43 -04:00
RandyTheSilly 25d0ef5a21 Added extension removal functionality
Former-commit-id: ed236f56d17c89a942332c25fb5ae8a45d408750
Former-commit-id: 9f20e5ddeed271363ffd4b7f13d55891f0b67ed2
2023-07-06 12:10:54 -04:00
RandyTheSilly 1cb5386756 Fixed error when declining extension download
Former-commit-id: 02933773afc9f542ba523f0ffe0c80af33673300
Former-commit-id: 50b2953f7af0351bda5f4c89b114db181ced0359
2023-07-06 10:17:30 -04:00
RandyTheSilly a00beeea45 Added initial extension downloading/updating support
Former-commit-id: 7bea089f44a499d448a910e1d060b9b43facd306
Former-commit-id: 98ed803ca1f8733908922428fa4fc3fe2df54402
2023-07-06 10:05:01 -04:00
RandyTheSilly 8daf01e986 Better explain purpose of custom text editor option
Former-commit-id: fec282230b92ee3035666a648544c86369643c21
Former-commit-id: fb0f46bac590e3f948c3404b1ae3991feefbbc5d
2023-06-22 11:25:53 -04:00
RandyTheSilly 404f787b89 Reinstate advertised Debian support as of Debian 12
Former-commit-id: 0bc026407a02d655ced349ceb64117e5fcc54262
Former-commit-id: 40a2f4d7417ce1345f3e57d2151f515e2622b8d9
2023-06-22 11:18:00 -04:00
RandyTheSilly e7de5761bd Hide input when creating or editing a password
Former-commit-id: b7224d0533bdb5c82d31d6854fe03c04b3efa6c1
Former-commit-id: 6af841f88fc4ae05c9bfec463b947d82bb5968d6
2023-06-20 14:45:17 -04:00
RandyTheSilly 9d94ba1eb9 Removed unnecessary output when shearing a non-existent entry
Former-commit-id: 7c264de0ebf49889e309d43d1ad5a7483845308e
Former-commit-id: 84c4c04e1bd4b085b457ddbd8184c9c3b028dcd1
2023-06-20 14:35:59 -04:00
RandyTheSilly 0c78a32195 Spaced entry input prompts apart
Former-commit-id: bbe5c986067096b0f18ebfdc38ddfbfd4d75567b
Former-commit-id: e312eb7fb3ce6c90d7d19c2c0918d6ce8f407614
2023-06-20 14:20:01 -04:00
RandyTheSilly 2813387577 Print a blank line after sync completion
Former-commit-id: 1eaa21a210aff947eddc4c35a2c59542a33b4282
Former-commit-id: 0602f43ae43d0ac931bffac99d5538c8f90e13a1
2023-06-20 14:07:57 -04:00
RandyTheSilly 3f86508f9c Fixed line spacing before sync when shearing entries
Former-commit-id: ba6325c80012acec52506f5005899655bb4688a9
Former-commit-id: 528c39efdbfc368e5bdfed38cff25db034b4217d
2023-06-20 14:00:11 -04:00
RandyTheSilly 2834c6d67c Made line spacing before sync text more consistent
Former-commit-id: 2539fcb335c63424ca9e4d6e6f49af42ad4ff6bf
Former-commit-id: 5041cb5b85e4f16706f91af3d6d16c38e4855fe8
2023-06-20 13:51:05 -04:00
RandyTheSilly 29c5e60804 Fixed password field showing for blank files
Former-commit-id: 6d0f8763a7d7ccc4208092fff70fa4795b6d1722
Former-commit-id: 124b80ba9c0596e28ffa7e1a85760236dea345ca
2023-06-20 13:26:05 -04:00
RandyTheSilly ba5f118048 Do not append extra new lines in line_edit
Former-commit-id: b2aefd5723c643f625865ea76957b2dbe560b58f
Former-commit-id: 194dd58228db64c0d55089edfe60055ed9492860
2023-06-20 11:44:13 -04:00
RandyTheSilly 05e9bcc478 Removed redundant code from optimized_edit, renamed to line_edit
Former-commit-id: 6fc1642909392c5c1f2f7e4602fd499ceff9d6a4
Former-commit-id: 9dd02b390893cb6239717ab886534a24bc3ea618
2023-06-20 11:12:30 -04:00
RandyTheSilly 7972040d5d Updated re-encryption to no longer use optimized_edit, as it is now redundant
Former-commit-id: e7f60332c00e1ba6be5372035c88e1828738d319
Former-commit-id: 86d492d1e464db37fef35e5963a541d79a3e6d54
2023-06-20 10:42:05 -04:00
RandyTheSilly d417ff48ba Strip trailing whitespace before encrypting entries
Former-commit-id: 32429dfb574e465486d1397445fa8b34f5dd73fb
Former-commit-id: aca5cc58197564a74e99345ed08c3363dd5acea0
2023-06-20 09:55:40 -04:00
RandyTheSilly 7dedfcac17 Fixed username and password fields being swapped on some new entries
Former-commit-id: 7cadad4527f9e08aa9f3b45e9d4d4b683709c5fd
Former-commit-id: 0949d3b8c4f2e050597f3a2e41e2795d7a380ff4
2023-06-20 09:50:42 -04:00
RandyTheSilly 307bcc3faa Do not re-encrypt and sync if an edited note is unchanged
Former-commit-id: b8bcb481830ad5deb344d4d0c79976db7f06bb52
Former-commit-id: 6ebe9ee2f25dcfd90bea3784d337cb6cefbe903e
2023-06-20 09:44:35 -04:00
RandyTheSilly d031e3c7ab Use tempfile.NamedTemporaryFile() for editing notes, removing the need for shm_gen()
Former-commit-id: 2d2e733945ba2748a24ed93f861145cf26ac1f13
Former-commit-id: e3b5add08675438e1a08607d081a9a44f426425e
2023-06-18 14:10:25 -04:00
RandyTheSilly 4f8d088d0e Removed unused option for su-security
Former-commit-id: d25ab089e078069b95a75482bab21999376e04c1
Former-commit-id: e02925d1e8446b4196bd529b092119e6039cdaa0
2023-06-18 00:26:51 -04:00
RandyTheSilly b035e208d7 No longer use tmpfs for entry decryption unless a note is being edited
Former-commit-id: f2087663fa4416500810bfd49575267c15b2097b
Former-commit-id: 4b830d1c7c9485a1bf816a0d7d3500638ab70451
2023-06-18 00:07:54 -04:00
RandyTheSilly 93647c0489 Demoted quick-unlock from recommended and added a security advisory
Former-commit-id: b894e8b66fa30394fd8cb43cea818f8a82f62878
Former-commit-id: 1c78d9ac043cc0478c112936a3bb99798a88e9b8
2023-06-17 20:50:56 -04:00
RandyTheSilly 75b9f4f0a5 Removed shebangs from libraries
Former-commit-id: 2d6d4000b0358ba7974350e2f85ec93d1387096f
Former-commit-id: c06d215f3d3dac7a8bf53ca5932b6da4752dc20c
2023-06-15 21:06:01 -04:00
RandyTheSilly 463df727e9 Allow directly passing a quick-unlock pin to decrypt()
Former-commit-id: 26d16e1c832cfd07dcc48fb807a4389f21f416b8
Former-commit-id: a197c1f00ee16ade6ae6cc253d4940c9a38356ad
2023-06-15 20:59:37 -04:00
RandyTheSilly 184a7c680d Made decrypt() more friendly to extensions
Former-commit-id: a52d6557e53ab834e8f6c39c66f4aec6f9ac0622
Former-commit-id: a19ed491bdf5cf2bfe5502752615cc465e14dddc
2023-06-15 20:45:19 -04:00
RandyTheSilly 49abdc4222 Require _quick_unlock_enabled parameter for decrypt()
Former-commit-id: af37809cfeb7c36de355d6cc0e8bc159f7291033
Former-commit-id: 195364d30d36467a4966347b54d66136e36dcdeb
2023-06-15 20:05:32 -04:00
RandyTheSilly 72f322b896 Merged determine_decrypt() into decrypt()
Former-commit-id: dd9483453409affdcbc54635ff187e4bc00ec5d4
Former-commit-id: c97d3856801cecf744f0c5bcebdaf9d21998967f
2023-06-15 19:58:09 -04:00
RandyTheSilly 5d0abb0537 Fixed potential variable undefined errors
Former-commit-id: 65168e24ed228816d4089241d4086317488fd696
Former-commit-id: 5c46855d45488b2ec5fd8b53040237fc224b45d4
2023-06-15 17:02:44 -04:00
RandyTheSilly 183582efbb Added missing new line after quick-unlock help message
Former-commit-id: a973b2dcdb3d93ec4a27ae77b09adb125a25a610
Former-commit-id: a3f54bcc22400e3da16ccc3bd8446cd860f6308f
2023-06-15 13:34:06 -04:00
RandyTheSilly 8e72ae1660 Moved quick-unlock+whitelist management to new tweak menu
Former-commit-id: ffb947c22fed9979052aa408db96a403f8654d7f
Former-commit-id: 9d4b8d043245f39c2ac8084f59c9dcfc26185d17
2023-06-15 13:30:23 -04:00
RandyTheSilly f154cbe400 Disallow entering negative quick-unlock pin lengths
Former-commit-id: b95a4003c8abd3ceb1fabd8e0c2758409f05e617
Former-commit-id: b1e4e8b8b297bd62277d02c9919ab2db9cb63ab9
2023-06-15 09:43:29 -04:00
RandyTheSilly ebb12e731f Use getpass for whitelist setup passphrase input
Former-commit-id: cf2b51588b2f79183e2bd263b4c3fa76d99b2b4e
Former-commit-id: 03b555137cbf646bbb22893d414a43fb3cd4753a
2023-06-15 09:23:37 -04:00
RandyTheSilly 7fc84d5f9b Updated whitelist setup gpg key detection method
Former-commit-id: d80505f72614d7fd49e5e8eba6f8f9443b8b6538
Former-commit-id: 4e627cb8830a714a39f6c71a8c745c50b2107f86
2023-06-15 09:15:30 -04:00
RandyTheSilly e0f37af453 Fixed the 'sync' argument working in offline mode if the user has previously saved sshync configurations
Former-commit-id: 9fa803ba406ede532a8d50c0138dace89cce405e
Former-commit-id: b63538263fa365e5a0f9ade3b5a90d5b066fe06f
2023-06-13 14:57:43 -04:00
RandyTheSilly f90d502106 Added an entry re-encryption/optimization option to the tweak menu
Former-commit-id: f868668a456300bcd46fd75381485a4fa75bcbbb
Former-commit-id: 4b812719f0d7cd17c8cc0c7f62903dba809f8a92
2023-06-13 14:38:01 -04:00
RandyTheSilly c7a8854f3f Optimized RMSERVER.py port-job script
Former-commit-id: 8ac85dff97de4dabab373fa784d6cdf3d4ae3084
Former-commit-id: af32466a41e6f152507569df651eda1fa8502ef3
2023-06-12 14:35:05 -04:00
RandyTheSilly da03e1e5f9 Fixed and re-enabled TWEAK-DEVTYPE port-job
Former-commit-id: 15038a5b6446b1356d6e45fd17111412bcd2072f
Former-commit-id: 9b6a5624f009d9b158b3ee722c2cd220582e8374
2023-06-12 13:57:23 -04:00
RandyTheSilly 43061b4fa0 List client options first in device type tweak menu
Former-commit-id: 8aebe573a8ae73026f8a7b1dca386d92fd5fd14f
Former-commit-id: 44bcf5f242b0dee634c4fea7cdae07e1a9a83d70
2023-06-12 13:42:30 -04:00
RandyTheSilly fcfa2adbf1 Optimized UNAME.py port-job script
Former-commit-id: 3b4e2b105fab3bb555dd4c6be3f421e68b808633
Former-commit-id: bd560b680c70bfb7a19d66ee0ad8eee4d99f3465
2023-06-12 11:43:38 -04:00
RandyTheSilly 28d0ba5448 Added patchnotes for backport release v1.4.3
Former-commit-id: 0a359e235d918cbb8b976c6cbc5a4c3bf7b39314
Former-commit-id: fc5920a2fa6da4ee43ef350637026c2fc157e1e9
2023-06-08 20:30:57 -04:00
RandyTheSilly 6c2d51aea6 Fixed checking /lib/sshyp instead of /usr/lib/sshyp
Former-commit-id: fc0ea87c0c15077897a5cbee7fc38b22f8022c70
Former-commit-id: e2abdc03fc4b3fa8c62f4c08164d36e83647a645
2023-06-08 19:36:20 -04:00
RandyTheSilly 2322140af7 Directly specify device type for tweak menu
Former-commit-id: 4969b540d5380edaddc26e7cd9d99a61f1a3ddbc
Former-commit-id: 9c375230650f780180d0d96952397814bc2eacc2
2023-06-08 14:53:52 -04:00
RandyTheSilly 93bffe2587 Use separate tweak menus for clients and servers
Former-commit-id: 92a7ce68f150aa223bc5a78ba02dd7cb7c07317d
Former-commit-id: 838381c35f3fec2a8780772bef8fcac33e7baac1
2023-06-08 14:46:47 -04:00
RandyTheSilly 8474807cd4 Fixed syncing over IPv6
Former-commit-id: f4a7e2b2c2273ad4d64574aca1288bc82319a2b1
Former-commit-id: e056a1b558042f572584d8a0f431bfbc4504a822
2023-06-03 20:16:19 -04:00
RandyTheSilly 227924cd81 Removed unneeded string processing when syncing entries
Former-commit-id: 2e8a632d487013cfd68ff8e2898a12b302bebd4c
Former-commit-id: 2253b64577cff33cf564fbbc31f0d2b62a39fdff
2023-06-03 19:45:16 -04:00
RandyTheSilly 1040a6f2ed Fixed IPv6 configuration support
Former-commit-id: 729d0009cf43999009d19747d70d87b2ac68b597
Former-commit-id: b48b284c1a811d5c7cb69963388f3eac0c3a1a79
2023-06-03 01:34:51 -04:00
RandyTheSilly a1ea9d6831 General cleanup and port-job updates
Former-commit-id: 343ec2505e3ee3858089ee0a4b5175c6029ad23f
Former-commit-id: 7cd32bc931d57e39166c62174561b6c7fdacb9cf
2023-06-01 23:09:53 -04:00
RandyTheSilly f36a7f5672 Fixed text formatting in device ID configuration
Former-commit-id: 7a032919fc0b9f82d861c4ec01f08cb75e6a44ff
Former-commit-id: c9cef5ee5d88027239871695e58a55f1e5fa9ac0
2023-05-25 14:46:39 -04:00
RandyTheSilly fe54acd3b0 Fixed clipboard tool warning showing on platforms where it is irrelevant, such as Termux and WSL
Former-commit-id: d979f20a0d6d24bcbe59773d6cb0d0654c06443c
Former-commit-id: b3168f92e537ec49d8b28e9e2fe8389672ae7ad7
2023-05-25 14:33:08 -04:00
RandyTheSilly 669c62510a Fixed keyboard interrupts not closing tweak menu
Former-commit-id: 76d730a63118b1e4490b6c4f8a5ca7bc84617a6b
Former-commit-id: 234c9c7ac5f3083cf9b0f3fdc35a2bce5f684d07
2023-05-25 14:15:40 -04:00
RandyTheSilly 97bce0cec7 Repeat the tweak menu after each choice path is completed
Former-commit-id: 4b49d43f13fbb006c5315e9be677bcc33dd2ac20
Former-commit-id: ac447b63ec5cb5e85dc9133466a434be0786c30d
2023-05-25 13:59:22 -04:00
RandyTheSilly 709db8f6de Re-use _copy_subject instead of _copy_line[_index]
Former-commit-id: 541227f28a7a2bbe7c5e7fe98e3223e3fb3ba5ae
Former-commit-id: 064b30c58d6905a68fa6684bb3ab17fd543f99cf
2023-05-25 13:29:34 -04:00
RandyTheSilly 273b3c97a5 Throw an error when trying to copy a line that does exist, but is blank
Former-commit-id: 15449013e83cb2454771399594305cf82150bd9c
Former-commit-id: ffe3d6a89cb1cfd86bbfb2beadce5510f143ff92
2023-05-25 13:24:14 -04:00
RandyTheSilly 657bc0291f Fixed errors when clearing clipboard on Windows (WSL)
Former-commit-id: 92b8baf923cccd20cd22cf6322c30ba1a0729cec
Former-commit-id: 8ef2d4f2fe2e3e91b820b0e0577a7fc5bd9b90ca
2023-05-25 11:29:22 -04:00
RandyTheSilly 4ec66f6352 Improved detection of and errors relating to clipboard support in raw ttys
Former-commit-id: 7b13af57872ff2bd2bf8285608b5d9a206c84fe8
Former-commit-id: 4406cd49234ff58cf568a55d07757f373830fe91
2023-05-25 11:07:22 -04:00
Randall Winkhart d061ded756 Link to known bugs list in README.md
Former-commit-id: c9212b660b38ea59b7a83d6dbbc32a8e6fa126e1
Former-commit-id: 1d63a876586e351fa23548c495d31ec941c4d8f5
2023-05-25 10:07:37 -04:00
RandyTheSilly d868476d35 Fixed use of multiple versions of Powershell under WSL (now uses only system-provided executable)
Former-commit-id: b804ff1921655a73423b67332385f7dbf5a20319
Former-commit-id: 8dfced454233d135877582617c12ec0615ba73ca
2023-05-25 09:38:20 -04:00
RandyTheSilly e594a625d9 Fixed fallback to standard unlock by converting some lists to tuples
Former-commit-id: d1f6a3af6f3904109e331ade7aee0f8747b34c9d
Former-commit-id: f8e5df1ce733d892559dd4154e79fa45dee163c8
2023-05-25 08:42:36 -04:00
RandyTheSilly 5fabdf5a86 Removed unneeded import statement and file exists checks
Former-commit-id: b20e08c31225cc085ef4dfbc801954742a59d3ae
Former-commit-id: 28edd16022adea08295a917affb85e0a3d28fb1f
2023-05-23 15:53:14 -04:00
RandyTheSilly c6951d8890 Moved all entry/folder exists/type checks to dedicated functions
Former-commit-id: a7a45850f1a808ce7e4f41d6804676650d990f20
Former-commit-id: fcddfd19d416f99ab2427ff33ed00ad980596bce
2023-05-23 15:45:05 -04:00
RandyTheSilly 8e26916bd7 Improve Termux clipboard detection method
Former-commit-id: 44ca402d01feb5aad992a77e781bc00568018e25
Former-commit-id: 0b149749308c365c891077f6f85dd5ff66212319
2023-05-19 13:57:41 -04:00
RandyTheSilly d981baab6c Save all gpg keys by recipient name
Former-commit-id: 57dfcf1f45480ddefff8821ab1b065517d6eb5ae
Former-commit-id: 95bca3145403ae542666ea004941ec5182206b29
2023-05-15 20:03:32 -04:00
RandyTheSilly ddf5fc2bc8 Silenced output from gpg and ssh auto-generation
Former-commit-id: 1d53e68b98fea537c89939dfb0f0938821bde356
Former-commit-id: be752a442af3050c406709e48b98f8d8b87ef03b
2023-05-15 15:37:48 -04:00
RandyTheSilly 2265207987 Re-implemented ssh keyfile auto-generation
Former-commit-id: fee233f5bec9c7b4edf024c09d489efebfa6a46e
Former-commit-id: d4df456842afcddca9807d5a7ae89666f65d3e4b
2023-05-15 15:15:04 -04:00
RandyTheSilly 293f9b8145 Only strip from the right when printing or copying entry contents
Former-commit-id: 67ceab321d24015a626d934f6ab56d1eaf604eee
Former-commit-id: b144c9ad791e37e07d521114a3d7baba49b290d9
2023-05-15 14:08:14 -04:00
RandyTheSilly 46dc81f0eb Strip data being copied when reading, rather than when sending to clipboard
Former-commit-id: 8b3ced0685b76b116ff9d1b7909c0d571054ee26
Former-commit-id: 34abaa4089dcad7dcc3bc3d8209d10e90915139c
2023-05-15 13:59:25 -04:00
RandyTheSilly 4894bc48e0 Rename options to arguments, flags to options
Former-commit-id: eb32adc94e5d746f42211e1a35cb507a9cfa2b6d
Former-commit-id: 0fd9c2e89778c1a8c4947436dd0bb19f551ec696
2023-05-15 13:22:57 -04:00
RandyTheSilly 0ca12cf4ab Replaced subprocess lists with tuples
Former-commit-id: 13e76157cedcc46af3b40fed5aa9e89091816586
Former-commit-id: 2ed9a7ac2ff0d1407811e89399812366340a5d3f
2023-05-15 13:03:20 -04:00
RandyTheSilly 03f011ccd0 Hid some broken output from gpg key generation
Former-commit-id: 7b1bbb84299a2693a5dd1a3018ca7aabc637f3c4
Former-commit-id: d98f1ac9192ff9c4113c0ba314f2fba1354fbe4b
2023-05-15 11:11:13 -04:00
RandyTheSilly 399d89f829 Removed "https://" from auto-generated gpg keys to fix curses display
Former-commit-id: d14833156a779ba8069db00c930ff048cc1b4ffa
Former-commit-id: c9ba8bf7533932436fd7331e6254154d3e2a045a
2023-05-15 10:59:02 -04:00
RandyTheSilly b14f925e53 Do not delete existing device IDs until a new one is set
Former-commit-id: 1f60a32e293d97059648c5c107af7e2b723f2319
Former-commit-id: 4c22d92687ccd58ddcf0cf55b0758e641b978ca4
2023-05-15 10:54:34 -04:00
RandyTheSilly f4bb0fb783 Allow configuring custom SSH keyfiles
Former-commit-id: 9c94bea462f8454ee547301f4a1cadb81251831f
Former-commit-id: 0838e13e3ff87c1be882303272246d4abc172f31
2023-05-15 10:50:17 -04:00
RandyTheSilly 453aacadbc Re-implemented quick-unlock tutorial
Former-commit-id: 30d7e1498a18409892403e580aaa16bf05fde40d
Former-commit-id: 6675cb6185ddd58f57b6b9114a18d1ccb1e7f911
2023-05-15 08:51:59 -04:00
RandyTheSilly 99379ec1b1 Fixed inconsistent spacing between items in entry reader
Former-commit-id: 268667df04d1bd7f22733475dc7079c698bba46a
Former-commit-id: 160b24686e81f304cb8426aaf043c239c2ab967f
2023-05-13 22:39:48 -04:00
RandyTheSilly 6288c45ba0 Fixed lock file not being generated in gpg setup
Former-commit-id: b9183ff7665bcc323ddcd9a59301b617794c0f79
Former-commit-id: fe1bab1c080ef4a1a9cf29a81c0e58c4e1b9fc4f
2023-05-13 21:59:19 -04:00
RandyTheSilly 53bb3dcacf Fixed errors when trying to set a device name from offline mode
Former-commit-id: f5d58f8d99fbef87cb0c44314595a4d2b7597538
Former-commit-id: 210d6f3fbc2672f53bfd438d941e0404de362d57
2023-05-13 21:19:40 -04:00
RandyTheSilly 2747aff0bf Updated port-jobs to allow for packaging the new config setup, fixed offline mode error
Former-commit-id: 511d1d887fb34b8613f063fc7992418bb614a740
Former-commit-id: 03f6817527864c52012de1d02bb2c34e8fed8a18
2023-05-13 20:48:51 -04:00
RandyTheSilly aeb3df7aed Update man page for the new tweak and init menus
Former-commit-id: 60feb572bb5b0c1a0b5b4e1be4ed3bc9c0146989
Former-commit-id: a479ae171c791277cfc305c8b780c9d239407737
2023-05-13 19:24:45 -04:00
RandyTheSilly 1ef290b289 Set success_flag when running the new tweak menu
Former-commit-id: b799bdc3b81c7e38cfad2fab46042bf25de7c157
Former-commit-id: a3e9b01e5b3c4f5f8bfb70ee94b26ea6d82cb031
2023-05-13 19:18:00 -04:00
RandyTheSilly bdedc98494 Switched to .INI config format, merged config files, finished adding functionality to new config menus
Former-commit-id: b5e877be47a49e967ced792156deb4f61841fb5e
Former-commit-id: c60df212fe964f089e246d39b3dbeaf28c006174
2023-05-13 19:11:38 -04:00
RandyTheSilly 60d3a674c4 Added basic functionality for new tweak menu + clean-up and optimization of all config menus
Former-commit-id: 59ecc6e80136bd1482aee48cff1b2b1167679836
Former-commit-id: 26043f564acf54fb97bdb3036ce48d57ee786f97
2023-05-13 15:53:46 -04:00
RandyTheSilly ebf58b7770 Initial implementation of optional tweak menu (design-only, non-functional)
Former-commit-id: 389b77adc683227597f2082920ed153d09a6cb94
Former-commit-id: 6a374155f4661d17a1939dd1911618aec76e78cd
2023-05-12 22:16:11 -04:00
RandyTheSilly 7b3270d70f Modularized configuration options for use in a future options menu
Former-commit-id: 45002b7ea5579407d47b14301b67dc0904f1121b
Former-commit-id: 4859a01aec7f9d1a70e1d887c6e4ab9a1f955fb8
2023-05-12 20:20:41 -04:00
RandyTheSilly 5e35bd7b3d Moved settings-related functions (anything that uses curses) to their own library
Former-commit-id: 95a43d9258c716c49e44020ffaec50a4b03eaaa6
Former-commit-id: 734e5249c491f87fb688651954a0ce84cd6f874e
2023-05-12 18:43:22 -04:00
RandyTheSilly c3aa63b585 Fixed clipboard tool detection on Wayland, various fixes related to curses menu
Former-commit-id: b021ed0871fb2e099ea82701378ca0876e8f594f
Former-commit-id: 21707287d99f03268c1f05eda6ab875c22272c27
2023-05-12 18:08:42 -04:00
RandyTheSilly fcca6321aa Initial implementation of curses config wizard
Former-commit-id: 430110dabec18b8e19528379e783ca9ea4e069c5
Former-commit-id: 722b819e32c838914b171b84feec9ce3526dbf45
2023-05-12 15:50:49 -04:00
RandyTheSilly d799a9d149 Added man page example for "--show"
Former-commit-id: b541410572815e9e4dce1db50b918fc5d849ba54
Former-commit-id: faa0c7cf9b4bec1e56aec87b0818bf988f46d31e
2023-05-12 08:12:05 -04:00
RandyTheSilly 2adee8978c Change FreeBSD dependencies to specify python3, rather than python
Former-commit-id: 8019c1fbe564af3969474ae70e4db7ab044ca3cd
Former-commit-id: 60b88be63ee6a3b1c63920970867bf4ca031d855
2023-05-11 19:19:48 -04:00
RandyTheSilly 63292e291d Hide passwords in password-only entries, ensure entry reader spacing is consistent
Former-commit-id: 30613971d642819f7ed40f777c966237ff592c1f
Former-commit-id: f7654f02d6c6663109c481415b2c7d4f91613a88
2023-05-11 15:48:34 -04:00
RandyTheSilly 2525260b3d Only show passwords in entry reader if command ends in "--show" or "-s"
Former-commit-id: 001d6e838c7b363897f3cdddefc5a75d581a1deb
Former-commit-id: 4e291ece75777038e1ec9547be78d5acc1a58b12
2023-05-11 15:26:26 -04:00
RandyTheSilly 50c4aa9a96 Fixed FreeBSD package using Termux clipboard
Former-commit-id: b54de0022328504eeaee74e31a495c69f7a782c8
Former-commit-id: d18f505374d1d10665d418f77642aa68428d3b23
2023-05-11 13:02:11 -04:00
RandyTheSilly a89b201fc7 Added warning if relevant clipboard tool is not installed
Former-commit-id: 2d89d7954a6d1c0133f235862e78b1bcfdcef9ff
Former-commit-id: 988a751409f02e2b065c461d4c3f723472ee725a
2023-05-11 12:11:30 -04:00
RandyTheSilly 64e56fb871 Fetch version number from changelog-archive
Former-commit-id: 017777ce0ce4bc51e5f8cc08c581501c6d9dc3db
Former-commit-id: ec36ca51fcadf38b8dea519b0fff5f80ee54ac32
2023-05-10 14:10:27 -04:00
RandyTheSilly 8062dad78d Marked xclip and wl-clipboard as optional dependencies
Former-commit-id: 18c803b31864f7759a71a2b1c7ec0b2b1cff3471
Former-commit-id: 7e92994170865b4e5b60d4bf12838e618f546dfd
2023-05-09 15:53:03 -04:00
RandyTheSilly 9eedb3c977 No longer include changelogs in distribution packages
Former-commit-id: f019cfe5a5d5080f02473123cba8e91f23821db2
Former-commit-id: a73603b784e19218c87b6602f9f52a3aaebb3e90
2023-05-09 15:32:05 -04:00
RandyTheSilly fc1c64a64d Silence existence errors when performing a silent sync
Former-commit-id: 69737630d74706da434a4e5056488124f6d59ecc
Former-commit-id: 688ff118ff212ae012def21fc2dfadd44dfcce54
2023-05-09 14:54:01 -04:00
RandyTheSilly 50ffbf2ec8 Fixed the moving of folders containing entries (entries are no longer deleted in sync mode)
Former-commit-id: 2773f7e35dc9f3bfbfb3959aff493e0f04e2a115
Former-commit-id: 9ad375002bb3942284cf93d120e3e0b21c5d34d4
2023-05-09 14:45:07 -04:00
RandyTheSilly c42cfc548e Update README.md with new packaging information
Former-commit-id: 7a0a7d5d2eae137bfd39c0890a778548f92cdb1e
Former-commit-id: 0e883e91814383b686291b5a58351ffc0d3fae35
2023-04-30 01:08:04 -04:00
20 changed files with 1834 additions and 1044 deletions
+16 -27
View File
@@ -1,7 +1,7 @@
![sshyp](https://github.com/rwinkhart/sshyp-labs/blob/main/extra/artwork/sshyp-banner.png) ![sshyp](https://github.com/rwinkhart/sshyp-labs/blob/main/extra/artwork/sshyp-banner.png)
[![release](https://img.shields.io/github/v/release/rwinkhart/sshyp)](https://github.com/rwinkhart/sshyp/releases) [![release](https://img.shields.io/github/v/release/rwinkhart/sshyp)](https://github.com/rwinkhart/sshyp/releases)
![python](https://img.shields.io/badge/python-3.7--3.11-yellow) ![python](https://img.shields.io/badge/python-3.8--3.12-yellow)
[![downloads](https://img.shields.io/github/downloads/rwinkhart/sshyp/total)](https://github.com/rwinkhart/sshyp/releases) [![downloads](https://img.shields.io/github/downloads/rwinkhart/sshyp/total)](https://github.com/rwinkhart/sshyp/releases)
[![CodeQL](https://github.com/rwinkhart/sshyp/actions/workflows/codeql-analysis.yml/badge.svg?branch=main)](https://github.com/rwinkhart/sshyp/actions/workflows/codeql-analysis.yml) [![CodeQL](https://github.com/rwinkhart/sshyp/actions/workflows/codeql-analysis.yml/badge.svg?branch=main)](https://github.com/rwinkhart/sshyp/actions/workflows/codeql-analysis.yml)
@@ -14,13 +14,15 @@ sshyp is compatible with entries created by pass/password-store, as its original
sshyp makes use of a custom sftp wrapper, called sshync (ssh+sync), to reliably sync user entries with a local or remote server. sshyp makes use of a custom sftp wrapper, called sshync (ssh+sync), to reliably sync user entries with a local or remote server.
The name "sshyp" is a combination of its syncing library, "sshync", and "passwords". The name "sshyp" is a combination of its synchronization library, "sshync", and "passwords".
# WARNING # WARNING
It is your responsibility to assess the security and stability of "sshyp" before using it and ensure it meets your needs. 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". 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. "sshyp" is a new project that is constantly being updated, and though safety and security are priorities, they cannot be guaranteed.
Always check the [known bugs](https://github.com/rwinkhart/sshyp/wiki/Known-Bugs) list before updating or installing sshyp.
# Mission Statement # Mission Statement
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. 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.
@@ -38,11 +40,13 @@ What sshyp can do:
Please see the [installation guide](https://github.com/rwinkhart/sshyp/wiki/Installation) in the sshyp wiki for directions specific to your distribution/OS. Please see the [installation guide](https://github.com/rwinkhart/sshyp/wiki/Installation) in the sshyp wiki for directions specific to your distribution/OS.
Pre-built packages exist for Haiku, FreeBSD, Alpine Linux, Arch Linux, Debian/Ubuntu Linux, Fedora Linux, and Termux. These can be downloaded from the releases page. Pre-built packages exist for Haiku, FreeBSD, Alpine Linux, Debian/Ubuntu Linux, Fedora Linux, Termux, and WSL. These can be downloaded from the releases page.
Support for additional environments, such as MacOS and OpenBSD, is coming soon. Additionally, sshyp is distributed on the AUR.
Extensions are available in the [sshyp-labs](https://github.com/rwinkhart/sshyp-labs) repository. Extensions can be installed from the `sshyp tweak` menu on most supported platforms.
For Haiku and Termux, extensions must instead be installed through the [system package manager](https://github.com/rwinkhart/sshyp-labs/releases).
# Building # Building
A packaging script is included in the root directory of the repo in order to package sshyp for your distribution. To package sshyp from source, simply run: A packaging script is included in the root directory of the repo in order to package sshyp for your distribution. To package sshyp from source, simply run:
@@ -59,39 +63,24 @@ Haiku and Fedora packaging must be done on their own respective distributions.
The AUR version and the packages attached to the release tags were already packaged using this script. The AUR version and the packages attached to the release tags were already packaged using this script.
Currently, the script can create packages for Haiku, FreeBSD, Alpine Linux (APKBUILD), Arch Linux (PKGBUILD), Debian/Ubuntu Linux, Fedora Linux, Termux, and generic. Currently, the script can create packages for Haiku, FreeBSD, Alpine Linux (APKBUILD), Arch Linux (PKGBUILD), Debian/Ubuntu Linux, Fedora Linux, Termux, and WSL.
# Usage # Usage
Upon initial installation (on both the server and client devices), be sure to run: Upon initial installation (on both the server and client devices), run `sshyp init` to configure the settings necessary for sshyp to function.
``` In order to configure optional settings or change already configured settings, run `sshyp tweak`.
sshyp tweak
```
This command will allow you to configure the settings necessary for sshyp to function. To ensure configuration compatibility, it is a good idea to run 'sshyp tweak' after each major update.
Please note that decrypting and reading entries is disabled on server devices for security reasons. Only devices configured as clients can use the GPG key to decrypt entries. Please note that decrypting and reading entries is disabled on server devices for security reasons. Only devices configured as clients can use the GPG key to decrypt entries.
All available options can be found with: All available options can be found with `sshyp help`, or alternatively, in the man page.
```
sshyp help
```
Or alternatively, in the man page:
```
man sshyp
```
# Roadmap # Roadmap
Short-term Goals: Short-term Goals:
- MacOS support - implement a method for tracking how long it has been since a password has been changed (password aging)
- improved temporary directory security - find and fix more bugs
- a minimal GUI app - being made as an [extension](https://github.com/rwinkhart/sshyp-labs)
Long-term Goals: Long-term Goals:
- a fun surprise - migrate from gpg to a better-suited utility focused on symmetric cipher encryption
- seize the thrones, shear the humans - seize the thrones, shear the humans
+2 -1
View File
@@ -1,4 +1,5 @@
#!/bin/sh #!/bin/sh
git add -f extra lib/sshyp.py lib/sshync.py port-jobs share LICENSE README.md package.sh commit.sh .gitignore sed -i 's/[[:space:]]*$//' ./lib/* ./port-jobs/* ./package.sh
git add -f extra lib/sshyp.py lib/sshync.py lib/stweak.py lib/clipclear.py port-jobs share LICENSE README.md package.sh commit.sh .gitignore
git commit -m "$1" git commit -m "$1"
git push git push
+132
View File
@@ -1,3 +1,135 @@
sshyp v1.5.1
10/24/2023
the fortified flock update - patch one
this release fixes both long and short-standing bugs that managed to escape discovery in testing;
it also addresses some issues that first-time users may be put-off by upon encountering
user-facing features:
- the clipboard is now only cleared if the contents of the clipboard still match what was placed onto it by sshyp
^ this means that sshyp will no longer remove data from the clipboard that it did not place there
- a warning/explanation is now provided when the user attempts to sync in offline mode
- a readable error is now provided if the user attempts to edit a note and the specified text editor cannot be found
- the optional configuration menu is now explained when encountered during "sshyp init"
- the man page now includes common troubleshooting information
fixes/optimizations:
- custom, user-provided ssh keyfiles are now properly utilized in all cases
^ previously, using custom ssh keyfiles would break various features
- clipboard contents are no longer leaked via the process list on Wayland
- interpolation has been disabled for ConfigParser, allowing "%" to be stored in configuration files
- gpg keys with ":" or "\" in their names are now properly written to the configuration file
- copy_id_check() and whitelist_verify() are now safely callable from extensions
- the ssh key selection will no longer see "known_hosts.old" as a valid keyfile
- when possible, data from the configuration file is now read as boolean values
- the Haiku package has been updated to use Python 3.11
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp v1.5.0
07/12/2023
the fortified flock update
this release implements new curses-based TUI configuration menus and improves the security of sshyp
compatibility-breaking changes:
- a completely new configuration system calls for a new configuration file
^ before using sshyp v1.5.0 for the first time, 'sshyp init' will need to be ran to create the
new configuration file - the old configuration files can be safely deleted
^ 'sshyp tweak' has been repurposed as the configuration menu for changing individual options,
rather than re-doing setup entirely - after initialization, this is the one you want to use
- the new extension manager is replacing the old method of installing extensions as system packages
^ any older extensions you have installed should be uninstalled to prevent conflicts
^ extensions are now installed and removed through the 'sshyp tweak' menu's extension manager
^ this does not yet apply to Haiku and Termux, which will continue to install extensions using
the previous method
- all clients and servers must be updated to this release for the folder renaming bug fix to work
^ failure to update all devices will result in errors and/or potential data loss
- various packaging changes
^ x-clip and wl-clipboard are now marked as optional dependencies, so the correct tool will
need to be installed as needed - a warning has been added for this if neither package is installed
^ the changelog no longer ships with sshyp - it is still available on GitHub
user-facing features:
- the old configuration menu, 'sshyp tweak', has been split into two new curses-based TUI menus
^ 'sshyp init' is for first-time setup/initialization
^ 'sshyp tweak' can be used at any time to quickly adjust individual settings
^ whitelist management tools have been moved to the new 'sshyp tweak' menu
^ clients and servers now each have their own dedicated 'sshyp tweak' menu
^ the new config file is in .INI format, making it easier to edit the config without sshyp
- added a 'sshyp tweak' option for re-encrypting all entries with a new gpg key
- added a security advisory when enabling quick-unlock to ensure the user understands potential risks
- the user is now warned if the clipboard tool relevant to their platform is not installed
- passwords are now hidden by default in the entry reader
^ they can be displayed by appending '--show' or '-s' to the end of the command
- input is now hidden when adding/editing a password in an entry
- entries are no longer re-encrypted and synced if the note editor is quit without saving
fixes/optimizations:
- a tmpfs is no longer used for decrypting entries unless editing notes
^ data is now decrypted directly into sshyp and written to entries pre-encrypted
^ this makes reading entries much more secure
^ editing entries is similarly secure to before - greater improvements coming in a future update
- folder renaming has been re-enabled and now functions as intended
- some unnecessarily verbose outputs were silenced and/or made to appear more cleanly
- FreeBSD packaging fixes
^ no longer incorrectly includes and uses the logic for the Termux clipboard
^ now specifies 'python3' dependency instead of 'python'
- many lists provided to the subprocess module have been swapped with tuples
- more correct and clear language is used to describe options and arguments in the help menus
- properly display an error when attempting to copy blank fields from entries
- shebangs have been removed from libraries not meant to be run directly
other factors of note:
- with the release of Debian 12 Bookworm, sshyp is once again fully supported on vanilla Debian
^ previously, it was only working correctly in offline mode due to Debian 11's old OpenSSH package
- this is the biggest release of sshyp ever
^ it includes LOTS of minor changes and optimizations not included in the patch notes summary
^ as such, keep an eye out for new bugs!
- the next major release of sshyp may be even larger...
^ but it is also likely very far away
^ GnuPG is great, but it is inherently incompatible with sshyp's future security model
^ if all goes according to plan, GnuPG will be replaced in the next release
^ assuming this happens, this next release will be crowned v2.0.0
^ sshyp v1.5.X is expected to be the latest stable release for a longer amount of time than usual
^ sshyp v1.5.X may receive security/bug fix patches after the release of v2.0.0, as needed
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp v1.4.3
06/08/2023
the argumentative agronomist update - patch three
IMPORTANT: the next major release of sshyp, v1.5.0, will make breaking changes that will require
running through 'sshyp tweak' again - also starting with v1.5.0, a copy of the changelog will no
longer be packaged with sshyp (it will still be available on GitHub) and clipboard tools
(x-clip and wl-clipboard) will be set to optional dependencies ('sshyp tweak' will warn of this)
this is a highly unconventional release featuring backports to fix critical bugs found during the
development of the upcoming v1.5.0
fixes:
- folder renaming has been disabled to prevent a severe data loss bug from occuring
^ this has been properly fixed for v1.5.0, but the fix requires all clients and servers
to be updated - to avoid breaking compatibility with 1.4.X, folder renaming was simply disabled
for the time being
- backported fix for syncing over IPv6
- backported fix for multiple versions of Powershell being called under WSL
- backported fix for checking /lib/sshyp instead of /usr/lib/sshyp
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp v1.4.2 sshyp v1.4.2
04/30/2023 04/30/2023
+82
View File
@@ -0,0 +1,82 @@
sshyp v1.5.3
01/08/2024
the fortified flock update - patch three
this release is a quick hot-fix for some bugs that were noticed after the release of v1.5.2
fixes/optimizations:
- fixed a regression with the entry list causing entries not part of a subdirectory to appear
in-line with the entry list header
- fixed extension group ownership under FreeBSD
^ the "wheel" group is now used where previously the non-existent "root" group was used
- fixed notes sometimes being appended in the wrong position after editing an incomplete entry
- addressed flake8 suggestions (slight optimization)
- removed unnecessary empty variable declarations
^ these were previously included to silence PyCharm's PEP8 warnings
^ the project is now primarily developed in VSCodium with the flake8 linter
^ the only change to flake8 defaults in the line length limit (79->120)
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
sshyp v1.5.2
01/07/2024
the fortified flock update - patch two
this release focuses on fixing various bugs, crashes, and visual oddities;
additionally, the new-user setup experience has been vastly improved
compatibility-breaking changes:
- this release is fully compatible with sshyp v1.5.0-v1.5.1
- the minimum Python version has been raised from Python 3.7 to Python 3.8
^ this was needed for the new device id changing behavior
^ Python 3.7 no longer receives security updates, so this should have minimal impact
^ please create an issue on GitHub if any Python version (3.8 or newer) does not work as intended
user-facing features:
- registered device ids can now be removed from the server tweak menu
^ all device id menus now stay open until the user manually exits
- changing a client's device id now attempts to automatically remove the previous id from the server
- the extension downloader now supports showing multiple lines of usage information
^ sshyp-mfa is taking advantage of this to display the info from the old man page
- basic tweak/init menu text wrapping and terminal-resizing has been added
^ the tweak/init radio menus now warn if the terminal needs to be resized to see all content;
this resizing can be done in real time without restarting sshyp (layout dynamically adjusts)
^ this avoids crashes on large radio menus in small terminals (crashes are still possible, but
only on unreasonably small terminals - this will probably stay the way it is now)
- ssh connections are no longer made from the init menu
^ this is to give the user time to register their ssh pubkey with the server
- the user is now warned that gpg key generation may take time and that sshyp should not be terminated
- the user is now warned about risks associated with changing or removing active device ids
- back buttons have been added to menus that were missing a safe way to exit
fixes/optimizations:
- quick-unlock has been fixed - invalid pins have been generated since v1.5.0
^ if quick-unlock is not working for you, re-generate your pin after this update!
- extension removal now works on Busybox environments (Alpine Linux)
- instead of crashing with an unhelpful error, sshyp now warns if a valid pinentry program is not found (gpg)
^ affects some Alpine Linux 3.19 base installs (pinentry does not always get installed with gpg)
- a recursive curses.wrapper() function is no longer used (fixes menu crash on Alpine Linux 3.19)
^ the new method of transitioning menus is more efficient on all platforms
- the wl-paste empty clipboard warning is no longer shown when multiple copies are done within 30 seconds (Wayland)
- quotes are no longer copied to the Termux clipboard on clear
- the entry reader and entry list should now be more visible in light terminals
^ in testing, I noticed some solarized dark themes bind color 8 to the same color as the terminal background,
leading to some invisible text - this will not be fixed (unless custom accent colors are added), as
I believe this is poor theme design and the fault of the particular solarized dark themes I tested
- entry list text wrapping has been vastly improved
^ better utilization of full terminal width
^ less prone to splitting entry names in half (should be impossible now)
^ no longer crashes on small terminals
- multi-word device ids can now verify via quick-unlock
- various language standardization changes
^ all back buttons in menus are now named "BACK"
^ all mentions of device ids are now referred to as "ids", rather than "names"
^ various non-user-facing variable renamings have also been made
- various menu helptext have been made more clear
^ this includes quick-unlock configuration, ssh configuration, device id configuration, and more
+52 -35
View File
@@ -1,14 +1,17 @@
.TH sshyp 1 "30 April 2023" "v1.4.2" "sshyp man page" .TH sshyp 1 "08 January 2024" "v1.5.3" "sshyp man page"
.SH NAME .SH NAME
\fBsshyp\fR - Simple, self-hosted, synchronized password management for UNIX(-like) systems. Alternative to (and compatible with) pass/password-store. \fBsshyp\fR - Simple, self-hosted, synchronized password management for UNIX(-like) systems. Alternative to (and compatible with) pass/password-store.
.SH SYNOPSIS .SH SYNOPSIS
Client Usage: sshyp [</entry name> [option] [flag]] [option] Client Usage: sshyp [/<entry name> [argument] [option]] | [argument]
Server Usage: sshyp <option> [flag] [device id] Server Usage: sshyp <argument>
.SH DESCRIPTION .SH DESCRIPTION
sshyp is a lightweight password and note management program written in Python. sshyp is used via CLI and is self-hosted with a client-server model. sshyp expects that you have access to a personal server with a properly configured ssh server, ideally accepting remote connections. sshyp is a lightweight password and note management program written in Python. sshyp is used via CLI and is self-hosted with a client-server model. sshyp expects that you have access to a personal server with a properly configured ssh server, ideally accepting remote connections.
.SH EXAMPLES (CLIENT) .SH EXAMPLES (CLIENT)
Setting up sshyp for the first time or altering its configuration (also recommended after major updates): Setting up sshyp for the first time:
sshyp init
Altering the existing sshyp configuration:
sshyp tweak sshyp tweak
Viewing the entry database: Viewing the entry database:
@@ -17,6 +20,12 @@ Viewing the entry database:
Reading an existing entry saved as '~/.local/share/sshyp/development/github.gpg': Reading an existing entry saved as '~/.local/share/sshyp/development/github.gpg':
sshyp /development/github sshyp /development/github
Removing an existing folder saved as '~/.local/share/sshyp/social':
sshyp /social shear
Reading the same entry without hiding the password:
sshyp /development/github --show
Copying the password of an existing entry saved as '~/.local/share/sshyp/financial/bank.gpg': Copying the password of an existing entry saved as '~/.local/share/sshyp/financial/bank.gpg':
sshyp /financial/bank copy -p sshyp /financial/bank copy -p
@@ -29,34 +38,20 @@ Making a new entry saved as '~/.local/share/sshyp/school/university.gpg' using t
Creating a note-only entry saved as '~/.local/share/sshyp/notes/test note.gpg': Creating a note-only entry saved as '~/.local/share/sshyp/notes/test note.gpg':
sshyp /notes/test\ note add -n sshyp /notes/test\ note add -n
Manually syncing entries with the server: Manually synchronizing entries with the server:
sshyp sync sshyp sync
.SH ARGUMENTS (CLIENT)
Removing an existing folder saved as '~/.local/share/sshyp/social':
sshyp /social/ shear
.SH EXAMPLES (SERVER)
Setting up the quick-unlock whitelist:
sshyp whitelist setup
Checking the quick-unlock whitelist status of all registered client devices:
sshyp whitelist list
Adding a device with the id 'laptop-im|lAoa;&;r&o:ez((g/Dz;EVb.nO_' to the quick-unlock whitelist:
sshyp whitelist add 'laptop-im|lAoa;&;r&o:ez((g/Dz;EVb.nO_'
Removing a device with the id 'laptop-im|lAoa;&;r&o:ez((g/Dz;EVb.nO_' from the quick-unlock whitelist:
sshyp whitelist del 'laptop-im|lAoa;&;r&o:ez((g/Dz;EVb.nO_'
.SH OPTIONS (CLIENT)
help/-h bring up the help menu help/-h bring up the help menu
version/-v display sshyp version info version/-v display sshyp version info
tweak configure sshyp init set up sshyp
tweak change configuration options/manage extensions and updates
add add an entry add add an entry
gen generate a new password gen generate a new password
edit edit an existing entry edit edit an existing entry
copy copy details of an entry to your clipboard copy copy details of an entry to your clipboard
shear delete an existing entry shear delete an existing entry
sync manually sync the entry directory via sshync sync manually sync the entry directory via sshync
.SH FLAGS (CLIENT) .SH OPTIONS (CLIENT)
add: add:
password/-p add a password entry password/-p add a password entry
note/-n add a note entry note/-n add a note entry
@@ -77,17 +72,11 @@ copy:
gen: gen:
update/-u generate a password for an existing entry update/-u generate a password for an existing entry
.SH OPTIONS (SERVER) .SH ARGUMENTS (SERVER)
help/-h bring up this menu help/-h bring up this menu
version/-v display sshyp version info version/-v display sshyp version info
tweak configure sshyp init set up sshyp
whitelist manage the quick-unlock whitelist tweak change configuration options/manage extensions and updates
.SH FLAGS (SERVER)
whitelist:
setup set up the quick-unlock whitelist
list/-l view all registered device ids and their quick-unlock whitelist status
add whitelist a device id for quick-unlock
del remove a device id from the quick-unlock whitelist
.SH SETUP .SH SETUP
sshyp operates on a client-server model, and thus requires you to have access to your own server (whether it be a physical home server or a cloud rental) with remote access via SSH. sshyp operates on a client-server model, and thus requires you to have access to your own server (whether it be a physical home server or a cloud rental) with remote access via SSH.
@@ -97,19 +86,45 @@ Server setup:
Configure an OpenSSH server (if sshyp was installed from the Debian package, openssh-server and openssh-sftp-server must be installed manually - if sshyp was installed from the Fedora package, openssh-server must be installed manually) Configure an OpenSSH server (if sshyp was installed from the Debian package, openssh-server and openssh-sftp-server must be installed manually - if sshyp was installed from the Fedora package, openssh-server must be installed manually)
Allow remote access to the SSH server w/public key authentication (disabling password-only authentication recommended) Allow remote access to the SSH server w/public key authentication (disabling password-only authentication recommended)
Install sshyp Install sshyp
Run "sshyp tweak" and set the device type as server Run "sshyp init" and set the device type as server
Optionally, run "sshyp whitelist setup" and configure quick-unlock Optionally, configure a quick-unlock pin from the tweak menu
Done! Done!
Client setup: Client setup:
Install sshyp Install sshyp
Run "sshyp tweak" and follow the prompts Run "sshyp init" and follow the prompts
Copy the generated public SSH key (located at ~/.ssh/sshyp.pub) to the server using preferred method (manually adding to authorized_keys, ssh-copy-id, etc.) Copy the generated public SSH key (located at ~/.ssh/sshyp.pub) to the server using preferred method (manually adding to authorized_keys, ssh-copy-id, etc.)
If you already have entries on the server, sync them using "sshyp sync" If you already have entries on the server, sync them using "sshyp sync"
Optionally, shell completions (both Bash and ZSH) can be enabled with your shell's respective method Optionally, shell completions (both Bash and ZSH) can be enabled with your shell's respective method
Done! Done!
Please note that the server setup intentionally does not allow the reading of entries (it does not allow adding a gpg decryption key). For security purposes, only clients can read entries. Please note that the server setup intentionally does not allow the reading of entries (it does not allow adding a gpg decryption key). For security purposes, only clients can read entries.
.SH TROUBLESHOOTING
.B Clipboard not clearing:
The intended way for sshyp to interact with the system clipboard is for it to clear it 30 seconds after copying a field. Unfortunately, this does not work by default on all systems due to the prevalence of clipboard managers.
Clipboard managers save a history of what has been copied to the clipboard, which is already a big enough issue on its own for people who copy sensitive information to their clipboard. Some clipboard managers simply will not allow the clipboard to be empty and will replace its contents with the last copied item if you attempt to clear it. One such naughty clipboard manager is KDE Klipper, which comes packaged into KDE Plasma and is typically enabled by default on most distributions. Due to this behavior, KDE Klipper breaks sshyp's clipboard clearing functionality and should not be left enabled.
It is likely other popular clipboard managers exhibit this behavior as well (Klipper is just the one I first noticed it with). Clipboard managers should not be enabled by default in any environment or distribution due to their potential security implications.
.B Shell completions not working:
ZSH:
Make sure your ~/.zshrc contains the following:
autoload -Uz compinit && compinit
Restart your shell
Bash:
Install your distribution's 'bash-completion' package and restart your shell
OR
Source the completion script manually by adding the following to your ~/.bashrc (then restart your shell):
Linux:
source /usr/share/bash-completion/completions/sshyp
FreeBSD:
source /usr/local/share/bash-completion/completions/sshyp
Haiku:
source /system/data/bash-completion/completions/sshyp
.SH EXIT CODES .SH EXIT CODES
0 - no error 0 - no error
@@ -122,5 +137,7 @@ Please note that the server setup intentionally does not allow the reading of en
4 - decryption/encryption error 4 - decryption/encryption error
5 - server connection error 5 - server connection error
6 - other error
.SH AUTHOR .SH AUTHOR
Randall Winkhart (https://github.com/rwinkhart) Randall Winkhart (https://github.com/rwinkhart)
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
from hashlib import sha512
from subprocess import DEVNULL, PIPE, run
from sys import argv
from time import sleep
# set period of time to wait before attempting to clear clipboard
sleep(30)
# enable the storing of clipboard contents hash for later comparison
hash_paste = sha512()
# PORT START CLIPCLEAR
if argv[2] == 'wsl':
hash_paste.update(run(('powershell.exe', '-c', 'Get-Clipboard'), stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('powershell.exe', '-c', 'Set-Clipboard'))
elif argv[2] == 'wayland':
hash_paste.update(run('wl-paste', stdout=PIPE, stderr=DEVNULL).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('wl-copy', '-c'))
elif argv[2] == 'haiku':
hash_paste.update(run(('clipboard', '-p'), stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('clipboard', '-r'))
elif argv[2] == 'mac':
hash_paste.update(run('pbpaste', stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run('pbcopy', input=b'')
elif argv[2] == 'termux':
hash_paste.update(run('termux-clipboard-get', stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(("termux-clipboard-set", ''))
elif argv[2] == 'x11':
hash_paste.update(run(('xclip', '-o', '-sel', 'c'), stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('xclip', '-i', '/dev/null', '-sel', 'c'))
# PORT END CLIPCLEAR
Executable → Regular
+43 -39
View File
@@ -1,20 +1,19 @@
#!/usr/bin/env python3
from os import listdir, remove, walk from os import listdir, remove, walk
from os.path import expanduser, isdir, getmtime, join from os.path import expanduser, isdir, isfile, getmtime, join
from subprocess import CalledProcessError, PIPE, run from subprocess import CalledProcessError, PIPE, run
from sys import exit as s_exit from sys import exit as s_exit
home = expanduser("~") home = expanduser('~')
# PORT START SSHYNC-REMOTE # PORT START SSHYNC-REMOTE
# REMOTE # REMOTE
# prints all necessary remote data to stdout # prints all necessary remote data to stdout
def remote_list_gen(_client_device_name, _remote_dir): def remote_list_gen(_client_device_id, _remote_dir):
# deletions # deletions
for _file in listdir(f"{home}/.config/sshyp/deleted"): for _file in listdir(f"{home}/.config/sshyp/deleted"):
_file_path, _sep, _device = _file.partition('\x1f') _file_path, _sep, _device = _file.partition('\x1f')
_file_path = _file_path.replace('\x1e', '/') _file_path = _file_path.replace('\x1e', '/')
if _device == _client_device_name: if _device == _client_device_id:
print(_file_path) print(_file_path)
try: try:
remove(f"{home}/.config/sshyp/deleted/{_file}") remove(f"{home}/.config/sshyp/deleted/{_file}")
@@ -32,8 +31,8 @@ def remote_list_gen(_client_device_name, _remote_dir):
# HYBRID # HYBRID
# deletes a file or folder and/or marks it for deletion upon syncing # deletes a file or folder and/or marks it for deletion upon synchronizing
def delete(_file_path, _target_database): def delete(_file_path, _target_database, _silent):
from shutil import rmtree from shutil import rmtree
_directory = f"{home}/.local/share/sshyp/" _directory = f"{home}/.local/share/sshyp/"
try: try:
@@ -42,10 +41,11 @@ def delete(_file_path, _target_database):
else: else:
remove(f"{_directory}{_file_path}.gpg") remove(f"{_directory}{_file_path}.gpg")
except FileNotFoundError: except FileNotFoundError:
if not _silent:
print(f"location does not exist {_target_database}") print(f"location does not exist {_target_database}")
if _target_database == 'remotely': if _target_database == 'remotely':
for _device_name in listdir(f"{home}/.config/sshyp/devices"): for _device_id in listdir(f"{home}/.config/sshyp/devices"):
open(f"{home}/.config/sshyp/deleted/" + _file_path.replace('/', '\x1e') + '\x1f' + _device_name, 'w') open(f"{home}/.config/sshyp/deleted/" + _file_path.replace('/', '\x1e') + '\x1f' + _device_id, 'w')
# retrieves and returns titles and mod times from the local device # retrieves and returns titles and mod times from the local device
@@ -67,9 +67,9 @@ def get_local_data(_directory, _device):
# captures and returns all necessary data from the remote server # captures and returns all necessary data from the remote server
def remote_list_fetch(_user_data): def remote_list_fetch(_user_data):
try: try:
_remote_data = run(['ssh', '-i', _user_data[5], '-p', _user_data[2], f"{_user_data[0]}@{_user_data[1]}", _remote_data = run(('ssh', '-i', _user_data[5], '-p', _user_data[2], f"{_user_data[0]}@{_user_data[1]}",
f'cd /lib/sshyp; python3 -c \'from sshync import remote_list_gen; remote_list_gen' f'cd /usr/lib/sshyp; python3 -c \'from sshync import remote_list_gen; remote_list_gen'
f'("{_user_data[6]}", "{_user_data[4]}")\''], stdout=PIPE, text=True, check=True f'("{_user_data[6]}", "{_user_data[4]}")\''), stdout=PIPE, text=True, check=True
).stdout.split('\x1d') ).stdout.split('\x1d')
except CalledProcessError: except CalledProcessError:
print('\n\u001b[38;5;9merror: failed to connect to the remote server\u001b[0m\n') print('\n\u001b[38;5;9merror: failed to connect to the remote server\u001b[0m\n')
@@ -84,11 +84,15 @@ def remote_list_fetch(_user_data):
# checks for and acts upon files and folders marked for deletion # checks for and acts upon files and folders marked for deletion
def deletion_sync(_deletion_database, _silent): def deletion_sync(_deletion_database, _silent):
_synced = False
for _file in _deletion_database: for _file in _deletion_database:
if _file != '': if _file != '':
if not _silent: if not _silent:
_synced = True
print(f"\u001b[38;5;208m{_file}\u001b[0m has been sheared, removing...") print(f"\u001b[38;5;208m{_file}\u001b[0m has been sheared, removing...")
delete(_file, 'locally') delete(_file, 'locally', _silent)
if _synced:
print()
# creates matches of remote folders on the local client # creates matches of remote folders on the local client
@@ -117,25 +121,21 @@ def sort_titles_mods(_list_1, _list_2):
return _title_list_2_sorted, _mod_list_2_sorted return _title_list_2_sorted, _mod_list_2_sorted
# creates a sshync job profile
def make_profile(_profile_dir, _local_dir, _remote_dir, _identity, _ip, _port, _user):
open(_profile_dir, 'w').write(f"{_user}\n{_ip}\n{_port}\n{_local_dir}\n{_remote_dir}\n{_identity}\n")
# returns a list of data read from a sshync job profile # returns a list of data read from a sshync job profile
def get_profile(_profile_dir): def get_profile(_profile_dir):
try: from configparser import ConfigParser
_profile_data = open(_profile_dir).readlines() _profile_data = ConfigParser(interpolation=None)
except (FileNotFoundError, IndexError): if isfile(_profile_dir):
_profile_data.read(_profile_dir)
else:
print('\n\u001b[38;5;9merror: the profile does not exist or is corrupted\u001b[0m\n') print('\n\u001b[38;5;9merror: the profile does not exist or is corrupted\u001b[0m\n')
_profile_data = None
s_exit(2) s_exit(2)
_user = _profile_data[0].rstrip() _user = _profile_data.get('SSHYNC', 'user')
_ip = _profile_data[1].rstrip() _ip = _profile_data.get('SSHYNC', 'ip')
_port = _profile_data[2].rstrip() _port = _profile_data.get('SSHYNC', 'port')
_local_dir = _profile_data[3].rstrip() _local_dir = _profile_data.get('SSHYNC', 'local_dir')
_remote_dir = _profile_data[4].rstrip() _remote_dir = _profile_data.get('SSHYNC', 'remote_dir')
_identity = _profile_data[5].rstrip() _identity = _profile_data.get('SSHYNC', 'identity_file')
_client_device_id = listdir(f"{home}/.config/sshyp/devices")[0].rstrip() _client_device_id = listdir(f"{home}/.config/sshyp/devices")[0].rstrip()
return _user, _ip, _port, _local_dir, _remote_dir, _identity, _client_device_id return _user, _ip, _port, _local_dir, _remote_dir, _identity, _client_device_id
@@ -154,27 +154,31 @@ def run_profile(_profile_dir, _silent):
_index_local = sort_titles_mods(_remote_titles_mods, get_local_data(_user_data[3], 'client')) _index_local = sort_titles_mods(_remote_titles_mods, get_local_data(_user_data[3], 'client'))
_index_remote = sort_titles_mods(_index_local, _remote_titles_mods) _index_remote = sort_titles_mods(_index_local, _remote_titles_mods)
# sync new and updated files # sync new and updated files
_i = -1 _i, _synced = -1, False
for _title in _index_local[0]: for _title in _index_local[0]:
_i += 1 _i += 1
if _title in _index_remote[0]: if _title in _index_remote[0]:
# compare mod times and sync # compare mod times and sync
if int(_index_local[1][_i]) > int(_index_remote[1][_i]): if int(_index_local[1][_i]) > int(_index_remote[1][_i]):
_synced = True
print(f"\u001b[38;5;4m{_title[:-4]}\u001b[0m is newer locally, uploading...") print(f"\u001b[38;5;4m{_title[:-4]}\u001b[0m is newer locally, uploading...")
run(['scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5], _user_data[3] + _title, run(('scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5], _user_data[3] + _title,
f"{_user_data[0]}@{_user_data[1]}:{_user_data[4]}{'/'.join(_title.split('/')[:-1]) + '/'}"]) f"{_user_data[0]}@[{_user_data[1]}]:{_user_data[4]}{_title}"))
elif int(_index_local[1][_i]) < int(_index_remote[1][_i]): elif int(_index_local[1][_i]) < int(_index_remote[1][_i]):
_synced = True
print(f"\u001b[38;5;2m{_title[:-4]}\u001b[0m is newer remotely, downloading...") print(f"\u001b[38;5;2m{_title[:-4]}\u001b[0m is newer remotely, downloading...")
run(['scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5], run(('scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5],
f"{_user_data[0]}@{_user_data[1]}:{_user_data[4]}{_title}", f"{_user_data[0]}@[{_user_data[1]}]:{_user_data[4]}{_title}", f"{_user_data[3]}{_title}"))
f"{_user_data[3]}{'/'.join(_title.split('/')[:-1]) + '/'}"])
else: else:
_synced = True
print(f"\u001b[38;5;4m{_title[:-4]}\u001b[0m is not on remote server, uploading...") print(f"\u001b[38;5;4m{_title[:-4]}\u001b[0m is not on remote server, uploading...")
run(['scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5], _user_data[3] + _title, run(('scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5], _user_data[3] + _title,
f"{_user_data[0]}@{_user_data[1]}:{_user_data[4]}{'/'.join(_title.split('/')[:-1]) + '/'}"]) f"{_user_data[0]}@[{_user_data[1]}]:{_user_data[4]}{_title}"))
for _title in _index_remote[0]: for _title in _index_remote[0]:
if _title not in _index_local[0]: if _title not in _index_local[0]:
_synced = True
print(f"\u001b[38;5;2m{_title[:-4]}\u001b[0m is not in local directory, downloading...") print(f"\u001b[38;5;2m{_title[:-4]}\u001b[0m is not in local directory, downloading...")
run(['scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5], run(('scp', '-pqs', '-P', _user_data[2], '-i', _user_data[5],
f"{_user_data[0]}@{_user_data[1]}:{_user_data[4]}{_title}", f"{_user_data[0]}@[{_user_data[1]}]:{_user_data[4]}{_title}", f"{_user_data[3]}{_title}"))
f"{_user_data[3]}{'/'.join(_title.split('/')[:-1]) + '/'}"]) if _synced:
print()
+377 -565
View File
File diff suppressed because it is too large Load Diff
+734
View File
@@ -0,0 +1,734 @@
from configparser import ConfigParser
from curses import A_REVERSE, KEY_DOWN, KEY_UP, curs_set, newwin
from curses.textpad import rectangle, Textbox
from os import environ, listdir, remove
from os.path import exists, expanduser, isfile
from pathlib import Path
from random import randint
from shutil import which
from subprocess import CalledProcessError, DEVNULL, PIPE, run
# PORT START UNAME-IMPORT-STWEAK
from os import uname
# PORT END UNAME-IMPORT-STWEAK
home, sshyp_data, stdscr, gm_device_type = expanduser('~'), ConfigParser(interpolation=None), None, None
if isfile(f"{home}/.config/sshyp/sshyp.ini"):
_exists_flag = True
sshyp_data.read(f"{home}/.config/sshyp/sshyp.ini")
else:
_exists_flag = False
# writes data stored in ConfigParser to the correct config file
def write_config(_sshyp_data=sshyp_data):
with open(f"{home}/.config/sshyp/sshyp.ini", 'w') as configfile:
_sshyp_data.write(configfile)
# creates a radio selection between the provided options
def curses_radio(_options, _pretext):
curs_set(0)
_selected = 0
while True:
# clear curses window
stdscr.clear()
# get terminal size
_height, _width = stdscr.getmaxyx()
# track whether to generate interactive buttons (depending on terminal size)
_button_gen = False
# split text based on new lines
_pretext_lines = _pretext.split('\n')
# iterate through lines, splitting further (wrapping) as needed, to add to curses window
_current_line = 0
for _line in _pretext_lines:
if _current_line <= _height - 4:
_button_gen = True
while len(_line) > _width:
stdscr.addstr(_current_line, 0, _line[:_width])
_line = _line[_width:]
_current_line += 1
stdscr.addstr(_current_line, 0, _line)
_current_line += 1
else:
_button_gen = False
stdscr.addstr(_current_line, 0, '# warning: re-size terminal to see more information'[:_width - 1])
_current_line += 1
break
# create user-interactive options if all information has been displayed to the user
if _button_gen:
for _i, _option in enumerate(_options):
_y = _i + _current_line + 1
if _y < _height:
if _i == _selected:
stdscr.addstr(_y, 0, "[*] " + _option, A_REVERSE)
else:
stdscr.addstr(_y, 0, "[ ] " + _option)
else:
stdscr.addstr(_y - 1, 0, '# warning: re-size terminal to see more information')
break
# update _selected based on user input
_key = stdscr.getch()
if _button_gen:
if _key == KEY_UP:
_selected = (_selected - 1) % len(_options)
elif _key == KEY_DOWN:
_selected = (_selected + 1) % len(_options)
# ord('\n') == 10
elif _key == 10:
break
stdscr.refresh()
curs_set(1)
return _selected
# creates a text-box input
def curses_text(_pretext):
stdscr.clear()
stdscr.addstr(0, 0, _pretext)
_width = stdscr.getmaxyx()[1]
_editwin = newwin(1, _width - 2, 3, 1)
rectangle(stdscr, 2, 0, 4, _width - 1)
stdscr.refresh()
_box = Textbox(_editwin)
# let the user edit until ctrl+g/enter is struck
_box.edit()
# return resulting contents
return _box.gather().strip()
# device+sync type selection
def install_type():
_offline_mode = 'false'
# PORT START TWEAK-DEVTYPE
_install_type = curses_radio(('client (ssh-synchronized)', 'client (offline)', 'server'),
'device + sync type configuration')
# PORT END TWEAK-DEVTYPE
if _install_type == 2:
_dev_type = 'server'
Path(f"{home}/.config/sshyp/deleted").mkdir(mode=0o700, exist_ok=True)
Path(f"{home}/.config/sshyp/whitelist").mkdir(mode=0o700, exist_ok=True)
curses_radio(['okay'], 'make sure the ssh service is running and properly configured')
else:
_dev_type = 'client'
if _install_type == 1:
_offline_mode = 'true'
if not sshyp_data.has_section('CLIENT-GENERAL'):
sshyp_data.add_section('CLIENT-GENERAL')
sshyp_data.set('CLIENT-GENERAL', 'offline_mode_enabled', _offline_mode)
if not sshyp_data.has_section('GENERAL'):
sshyp_data.add_section('GENERAL')
sshyp_data.set('GENERAL', 'device_type', _dev_type)
write_config()
return _dev_type, _offline_mode
# gpg configuration
def gpg_config():
# gpg key selection
_uid_list = [_item for _item in run(('gpg', '-k', '--with-colons'),
stdout=PIPE, text=True).stdout.splitlines() if _item.startswith('uid')]
_named_uid_list = []
for _uid in _uid_list:
_named_uid_list.append(_uid.split(':')[9].replace('\\x3a', ':').replace('\\x5c', '\\'))
_named_uid_list.append('auto-generate')
_gpg_id_sel = curses_radio(_named_uid_list, 'gpg key selection')
if _gpg_id_sel == len(_named_uid_list) - 1:
if not isfile(f"{home}/.config/sshyp/gpg-gen"):
open(f"{home}/.config/sshyp/gpg-gen", 'w').writelines([
'Key-Type: 1\n', 'Key-Length: 4096\n', 'Key-Usage: sign encrypt\n', 'Name-Real: sshyp\n',
'Name-Comment: gpg-sshyp\n', 'Name-Email: github.com/rwinkhart/sshyp\n',
'Expire-Date: 0'])
curses_radio(['okay'], 'gpg key generation may take some time (especially on slower devices)\n\nselect "okay" '
'to start\n\ndo not terminate this process!')
try:
run(('gpg', '-q', '--batch', '--generate-key', f"{home}/.config/sshyp/gpg-gen"), stderr=PIPE, check=True)
except CalledProcessError as e:
if 'No pinentry' in e.stderr.decode("utf-8"):
curses_radio(['okay'], 'either a valid pinentry program is missing or gpg is not configured to use an '
'available pinentry program\n\nsshyp will now exit')
from sys import exit as s_exit
s_exit(6)
remove(f"{home}/.config/sshyp/gpg-gen")
_gpg_id = run(('gpg', '-k', '--with-colons'), stdout=PIPE, text=True).stdout.splitlines()[-1].split(':')[9]
else:
_gpg_id = _named_uid_list[_gpg_id_sel]
# lock file generation
if isfile(f"{home}/.config/sshyp/lock.gpg"):
remove(f"{home}/.config/sshyp/lock.gpg")
open(f"{home}/.config/sshyp/lock", 'w')
run(('gpg', '-qr', _gpg_id, '-e', f"{home}/.config/sshyp/lock"))
remove(f"{home}/.config/sshyp/lock")
if not sshyp_data.has_section('CLIENT-GENERAL'):
sshyp_data.add_section('CLIENT-GENERAL')
sshyp_data.set('CLIENT-GENERAL', 'gpg_id', _gpg_id)
write_config()
# text editor configuration
def editor_config(_env_mode):
if _env_mode:
# set default text editor to value of EDITOR environment variable, otherwise default to vi
if 'EDITOR' in environ:
_editor = environ['EDITOR']
else:
_editor = 'vi'
else:
_editor = curses_text('enter the name of your preferred text editor:\n\n\n\n\n(ctrl+g/enter to confirm)'
'\n\nthis will be used for writing notes\n\nexample input: vim')
if not sshyp_data.has_section('CLIENT-GENERAL'):
sshyp_data.add_section('CLIENT-GENERAL')
sshyp_data.set('CLIENT-GENERAL', 'text_editor', _editor)
write_config()
# ssh+sshync configuration
def ssh_config(_reconfig=False):
# private key selection/generation
_keys = []
# ensure ~/.ssh directory exists
Path(f"{home}/.ssh").mkdir(mode=0o700, exist_ok=True)
for _file in listdir(f"{home}/.ssh"):
if not _file.startswith('.') and _file not in ('known_hosts', 'known_hosts.old', 'authorized_keys') \
and not _file.endswith('.pub') and isfile(f"{home}/.ssh/{_file}"):
_keys.append(f"{home}/.ssh/{_file}")
_keys.extend(['auto-generate', 'other (type the location)'])
# append a back button if launched optionally
if _reconfig:
_keys.append('BACK')
_key_selected_num = curses_radio(_keys, 'which private ssh key would you like to use for sshyp?')
if _reconfig and _key_selected_num == len(_keys) - 1:
return
_gen_index = len(_keys) - 2
if _key_selected_num >= _gen_index:
_ssh_key = expanduser(curses_text('enter the location for your private ssh key:\n\n\n\n\n(ctrl+g/enter to '
'confirm)\n\nexample input:\n\n~/.ssh/privkey'))
if _key_selected_num == _gen_index:
_passphrase = curses_text('enter your desired ssh keyfile passphrase:\n\n\n\n\n(ctrl+g/enter to confirm)'
'\n\nnote: it is recommended to leave this blank and to use the keyfile without '
'a passphrase (the keyfile itself serves as your identity)')
run(('ssh-keygen', '-q', '-t', 'ed25519', '-N', _passphrase, '-f', _ssh_key))
else:
_ssh_key = _keys[_key_selected_num]
# ssh+sshync configuration
_uiport = curses_text('enter the username, ip, and ssh port of your sshyp server:\n\n\n\n\n(ctrl+g/enter to '
'confirm)\n\nexample inputs:\n\n ipv4: user@10.10.10.10:22\n ipv6: user@[2000:2000:2000:2000'
':2000:2000:2000:2000]:22\n domain: user@mydomain.com:22')
_uiport_split = _uiport.split('@')
_username_ssh = _uiport_split[0]
_iport = _uiport_split[1].lstrip('[').replace(']', '').rsplit(':', 1)
if not sshyp_data.has_section('SSHYNC'):
sshyp_data.add_section('SSHYNC')
sshyp_data.set('SSHYNC', 'user', _username_ssh)
sshyp_data.set('SSHYNC', 'ip', _iport[0])
sshyp_data.set('SSHYNC', 'port', _iport[1])
sshyp_data.set('SSHYNC', 'local_dir', f"{home}/.local/share/sshyp/")
sshyp_data.set('SSHYNC', 'remote_dir', f"/home/{_username_ssh}/.local/share/sshyp/")
sshyp_data.set('SSHYNC', 'identity_file', _ssh_key)
write_config()
return _iport[1], _username_ssh, _iport[0], _ssh_key
# device id configuration
def dev_id_config(_port, _username_ssh, _ip, _identity, _reconfig=False):
if _reconfig:
_sure = curses_radio(('no', 'yes'), "WARNING: ensure this sshyp client is synchronized (up-to-date) before "
"changing the device id\n\nfailure to do so may result in sync"
"hronization issues\n\nare you sure you wish to change the device id?")
if _sure != 1:
return
from sshyp import copy_id_check, string_gen
_device_id_prefix = curses_text('set this device\'s id:\n\n\n\n\n(ctrl+g/enter to confirm)\n\nimportant: this '
'id must be unique amongst your client devices\n\nthis is used to keep track of '
'database synchronization and quick-unlock permissions\n')
_device_id_suffix = string_gen('f', randint(24, 48))
_device_id = _device_id_prefix + '-' + _device_id_suffix
# remove existing device ids
_device_id_list = listdir(f"{home}/.config/sshyp/devices")
for _id in _device_id_list:
remove(f"{home}/.config/sshyp/devices/{_id}")
open(f"{home}/.config/sshyp/devices/{_device_id}", 'w')
# test server connection and attempt to register device id - only run if _reconfig is True, since the keyfile
# needs to be registered with the server before a successful connection can be made
if _reconfig:
# copy_id_check() returns false if successful
if not copy_id_check(_port, _username_ssh, _ip, _device_id, _identity, sshyp_data):
# remove old device id from registered pool and whitelist
run(('ssh', '-o', 'ConnectTimeout=3', '-i', _identity, '-p', _port, f"{_username_ssh}@{_ip}",
'python3 -c \'from pathlib import Path; '
f'Path("/home/{_username_ssh}/.config/sshyp/devices/{_device_id_list[0]}").unlink(missing_ok=True); '
f'Path("/home/{_username_ssh}/.config/sshyp/whitelist/{_device_id_list[0]}")'
f'.unlink(missing_ok=True)\''), stderr=DEVNULL, stdout=DEVNULL)
else:
sshyp_data.set('CLIENT-ONLINE', 'ssh_error', 'true')
write_config()
curses_radio(['okay'], 'this device will be registered with the server upon the first successful sync\n\n'
'you can force this now by running "sshyp sync"\n\nif you have not done so already, '
'ensure your ssh pubkey has been appended to the server\'s authorized_keys file!')
# quick-unlock configuration
def quick_unlock_config(_default):
if _default:
_enabled = 'false'
else:
_quick_unlock_sel = curses_radio(('no', 'yes'), 'WARNING: quick-unlock is only as secure as the environment you'
' use it in\n\nquick-unlock allows you to use a shorter version'
' of your gpg key passphrase and\nrequires a constant '
'connection to your sshyp server to authenticate\n\na '
'compromised program on your computer could scan the process '
'list in the\nbrief period during decryption to retrieve the '
'necessary information to decrypt your entries\n\nenable '
'quick-unlock?')
if _quick_unlock_sel == 1:
_enabled = 'true'
else:
_enabled = 'false'
if not sshyp_data.has_section('CLIENT-ONLINE'):
sshyp_data.add_section('CLIENT-ONLINE')
sshyp_data.set('CLIENT-ONLINE', 'quick_unlock_enabled', _enabled)
write_config()
return _enabled
# re-encrypt/optimize all entries
def refresh_encryption():
_directory = f"{home}/.local/share/sshyp"
# warn the user of potential data loss and prompt to continue
_sure = curses_radio(('no', 'yes'), "WARNING: proceeding with this action will remove/overwrite any directories"
f" matching the following:\n\n{home}/.local/share/sshyp.old\n{home}/.local/"
"share/sshyp.new\n\nare you sure you wish to re-encrypt all entries?")
if _sure != 1:
return 3
# set new gpg key
gpg_config()
from os import walk
from os.path import isdir
from shutil import move, rmtree
from sshyp import decrypt, encrypt
# prompt for unlock and display do not close warning
decrypt(None)
curses_radio(['okay'], 'entry optimization may take some time (especially on slower devices)\n\nselect "okay" '
'to start\n\ndo not terminate this process!')
# remove existing conflicts
for _extension in ('.new', '.old'):
if exists(f"{_directory}{_extension}"):
rmtree(f"{_directory}{_extension}")
# decrypt, optimize, and re-encrypt each entry with the newly selected key
if isdir(_directory):
_gpg_id = sshyp_data.get('CLIENT-GENERAL', 'gpg_id')
for _root, _dirs, _files in sorted(walk(_directory, topdown=True)):
for _filename in _files:
Path(_root.replace(_directory, _directory + '.new', 1)).mkdir(0o700, parents=True, exist_ok=True)
encrypt(decrypt(f"{_root}/{_filename[:-4]}"),
f"{_root.replace(_directory, _directory + '.new', 1)}/{_filename[:-4]}", _gpg_id)
# create a backup of the original version and activate the new version
move(_directory, _directory + '.old')
move(_directory + '.new', _directory)
return 1
else:
return 2
# PORT START WHITELIST-SERVER
# removes a registered device id from the server-side pool and prunes the quick-unlock whitelist
def registered_dev_id_remover(_back=False):
_device_ids = listdir(f"{home}/.config/sshyp/devices") + ['BACK']
_whitelisted_ids = listdir(f"{home}/.config/sshyp/whitelist")
while not _back:
_del_id = curses_radio(_device_ids, 'WARNING: only remove registered device ids if they are no longer in use'
'\n\nthe removal of an active device id will result in the malfunction of '
'the device still using the removed id\n\nregistered device id to remove:')
if _del_id == len(_device_ids) - 1:
_back = True
else:
# remove deleted device id from whitelist
if _device_ids[_del_id] in _whitelisted_ids:
remove(f"{home}/.config/sshyp/whitelist/{_whitelisted_ids[_del_id]}")
_whitelisted_ids = [_id for _id in _whitelisted_ids if _id != _device_ids[_del_id]]
# remove deleted device id from device pool
remove(f"{home}/.config/sshyp/devices/{_device_ids[_del_id]}")
del _device_ids[_del_id]
# takes input from the user to set up quick-unlock pin
def whitelist_setup():
_gpg_password_temp = str(curses_text('full gpg passphrase:\n\n\n\n\n(ctrl+g/enter to confirm)'))
_half_length = len(_gpg_password_temp) // 2
try:
_short_password_length = int(curses_text(f"quick unlock pin length ({_half_length}):\n\n\n\n\n(ctrl+g/enter "
"to confirm)\n\nnote: do NOT enter your desired pin - this is simply "
"an integer used to determine the length of the auto-generated pin"
"\n\npin must be half the length of the gpg passphrase or less and "
"must be greater than 0"))
if not 0 < _short_password_length <= _half_length:
_short_password_length = _half_length
except ValueError:
_short_password_length = _half_length
_i, _quick_unlock_password, _quick_unlock_password_excluded = 0, '', ''
for _char in _gpg_password_temp:
if _i % 2 == 1 and _i < _short_password_length * 2:
_quick_unlock_password += _char
else:
_quick_unlock_password_excluded += _char
_i += 1
# create assembly key
open(f"{home}/.config/sshyp/gpg-gen", 'w').writelines([
'Key-Type: 1\n', 'Key-Length: 4096\n', 'Key-Usage: sign encrypt\n', 'Name-Real: sshyp\n',
'Name-Comment: gpg-sshyp-whitelist\n', 'Name-Email: github.com/rwinkhart/sshyp\n', 'Expire-Date: 0'])
curses_radio(['okay'], 'gpg key generation may take some time (especially on slower devices)\n\nselect "okay" '
'to start\n\ndo not terminate this process!')
run(('gpg', '-q', '--pinentry-mode', 'loopback', '--batch', '--generate-key', '--passphrase',
_quick_unlock_password, f"{home}/.config/sshyp/gpg-gen"))
remove(f"{home}/.config/sshyp/gpg-gen")
_gpg_id = run(('gpg', '-k', '--with-colons'), stdout=PIPE, text=True).stdout.splitlines()[-1].split(':')[9]
# encrypt excluded with the assembly key
from sshyp import encrypt
encrypt([_quick_unlock_password_excluded], f"{home}/.config/sshyp/excluded", _gpg_id)
curses_radio(['okay, I have it memorized'], f"your quick-unlock pin: {_quick_unlock_password}")
# adds or removes quick-unlock whitelisted device ids
def whitelist_manage(_action, _back=False):
_whitelisted_ids = listdir(f"{home}/.config/sshyp/whitelist") + ['BACK']
_device_ids = listdir(f"{home}/.config/sshyp/devices")
_unwhitelisted_ids = []
for _id in _device_ids:
if _id not in _whitelisted_ids:
_unwhitelisted_ids.append(_id)
_unwhitelisted_ids.append('BACK')
while not _back:
# _action == True indicates adding
if _action:
_add_id = curses_radio(_unwhitelisted_ids, 'id to add to whitelist:')
if _add_id == len(_unwhitelisted_ids) - 1:
_back = True
else:
open(f"{home}/.config/sshyp/whitelist/{_unwhitelisted_ids[_add_id]}", 'w').write('')
del _unwhitelisted_ids[_add_id]
# _action == False indicates removing
else:
_del_id = curses_radio(_whitelisted_ids, 'id to remove from whitelist:')
if _del_id == len(_whitelisted_ids) - 1:
_back = True
else:
remove(f"{home}/.config/sshyp/whitelist/{_whitelisted_ids[_del_id]}")
del _whitelisted_ids[_del_id]
# runs quick-unlock configuration menu
def whitelist_menu():
while True:
_choice = curses_radio(('setup/create pin', 'add to whitelist', 'remove from whitelist',
'BACK'), 'quick-unlock/whitelist management')
if _choice == 0:
whitelist_setup()
elif _choice == 1:
whitelist_manage(True)
elif _choice == 2:
whitelist_manage(False)
else:
break
# PORT END WHITELIST-SERVER
# PORT START TWEAK-EXTEND-FUNCTIONS
# downloads/updates extensions
def extension_downloader():
from os import chmod
from tempfile import gettempdir
from urllib.request import urlopen, urlretrieve
# the version listed below will NOT always match the version of sshyp being used
# it is only updated if new extensions are incompatible with previous sshyp versions
_file_data = urlopen("https://raw.githubusercontent.com/rwinkhart/sshyp-labs/main/pointers/v1.5.2").read()
_pointer = ConfigParser(interpolation=None)
_pointer.read_string(_file_data.decode('utf-8'))
_extensions = _pointer.sections()
_extensions.append('BACK')
_choice = curses_radio(_extensions, 'select an extension for more info')
if _choice == len(_extensions) - 1:
return False
_selected = _extensions[_choice]
_divider = (stdscr.getmaxyx()[1]) * '-'
_choice = curses_radio(('no', 'yes'), '# description\n' + _divider + '\n\n' + _pointer.get(_selected, 'desc') +
'\n\n# usage\n' + _divider + '\n\n' + _pointer.get(_selected, 'usage').replace('<br>', '\n')
+ '\n\n' + _divider + '\n\ninstall ' + _selected + '?')
# if installing the extension...
if _choice == 1:
# download extension files to temporary directory
_exe_dir, _ini_dir = f"{gettempdir()}/sshyp_exe", f"{gettempdir()}/sshyp_ini"
urlretrieve(_pointer.get(_selected, 'exe'), _exe_dir)
urlretrieve(_pointer.get(_selected, 'ini'), _ini_dir)
# set permissions under active user
chmod(_exe_dir, 0o755)
chmod(_ini_dir, 0o644)
return _selected
return False
# uninstalls/deletes selected extensions
def extension_remover():
_installed = []
for _extension in listdir('/usr/lib/sshyp/extensions'):
_installed.append(_extension[:-4])
_installed.append('BACK')
_choice = curses_radio(_installed, 'select an extension to uninstall')
if _choice == len(_installed) - 1:
return False
_sure = curses_radio(('no', 'yes'), f"are you sure you want to remove {_installed[_choice]}?")
if _sure == 0:
return False
return _installed[_choice]
# provides options for managing extensions
def extension_menu():
_ext_name, _action = False, False
# determine which of the supported privilege escalation utilities is installed
if which('doas') is not None:
_escalator = 'doas'
elif which('sudo') is not None:
_escalator = 'sudo'
else:
# throw an error if no supported privilege escalation utility is found
raise ChildProcessError
while True:
_choice = curses_radio(('download/update extensions', 'remove extensions', 'BACK'), 'extension management')
if _choice == 0:
_ext_name = extension_downloader()
if _ext_name:
# True represents installation
_action = True
break
elif _choice == 1:
_ext_name = extension_remover()
if _ext_name:
break
else:
break
return _ext_name, _escalator, _action
# PORT END TWEAK-EXTEND-FUNCTIONS
# runs secondary configuration menu
def global_menu(_scr, _device_type, _top_message):
global stdscr
# only set global stdscr if running as entry point
if not isinstance(_scr, bool):
stdscr = _scr
while True:
_options, _choice, _exit_signal = ['change device/synchronization types'], 0, False
if _device_type == 'client':
_options.extend(['change gpg key', 're-configure ssh(ync)', 'change device id',
'[OPTIONAL, RECOMMENDED] set custom text editor',
'[OPTIONAL] enable/disable quick-unlock',
'[OPTIONAL] re-encrypt/optimize entries',
'[OPTIONAL] extension management'])
else:
_options.extend(['remove registered device ids', 'manage quick-unlock/whitelist'])
_options.append('EXIT/DONE')
_choice += curses_radio(_options, _top_message)
if _choice == 0:
_dev_sync_types = install_type()
# if switching to client mode...
if _dev_sync_types[0] == 'client':
# ...and gpg settings are missing
if not sshyp_data.has_option('CLIENT-GENERAL', 'gpg_id'):
gpg_config()
# ...and text editor settings are missing
if not sshyp_data.has_option('CLIENT-GENERAL', 'text_editor'):
editor_config(True)
# ...and online (synchronized) mode is enabled...
if _dev_sync_types[1] == 'false':
# ...and quick-unlock settings are missing
if not sshyp_data.has_option('CLIENT-ONLINE', 'quick_unlock_enabled'):
quick_unlock_config(True)
# set to None to check if modified later
_ip, _username_ssh, _port, _identity = None, None, None, None
# ...and there is no sshync config present
if not sshyp_data.has_section('SSHYNC'):
_ip, _username_ssh, _port, _identity = ssh_config()
# ...and there is no device ID present
if not listdir(f"{home}/.config/sshyp/devices"):
if None in (_ip, _username_ssh, _port):
_ip, _username_ssh, _port, _identity = ssh_config()
dev_id_config(_port, _username_ssh, _ip, _identity)
# ...or ssh_error is missing
elif not sshyp_data.has_option('CLIENT-ONLINE', 'ssh_error'):
sshyp_data.set('CLIENT-ONLINE', 'ssh_error', '1')
write_config()
_device_type = _dev_sync_types[0]
elif _choice == 1:
if _device_type == 'client':
gpg_config()
else:
registered_dev_id_remover()
elif _choice == 2:
if _device_type == 'client':
ssh_config(True)
else:
whitelist_menu()
elif _choice == 3:
if _device_type == 'client':
if not sshyp_data.has_section('SSHYNC'):
ssh_config()
dev_id_config(sshyp_data.get('SSHYNC', 'port'), sshyp_data.get('SSHYNC', 'user'),
sshyp_data.get('SSHYNC', 'ip'), sshyp_data.get('SSHYNC', 'identity_file'), True)
else:
_exit_signal = True
elif _choice == 4:
editor_config(False)
elif _choice == 5:
_enabled = quick_unlock_config(False)
if _enabled == 'true':
curses_radio(['okay'], 'quick-unlock has been enabled client-side - in order for this feature to '
'function,\nyou must first log in to the sshyp server and run:\n\nsshyp tweak\n'
'\nfrom there you can create a quick-unlock pin and add this device to the '
'whitelist')
elif _choice == 6:
_success = refresh_encryption()
if _success == 1:
curses_radio(['okay'], "a backup of your previous entry directory has been created:\n\n"
f"{home}/.local/share/sshyp.old")
elif _success == 2:
curses_radio(['okay'], '\u001b[38;5;9merror: re-encryption failed: entry directory not found\u001b[0m')
elif _choice == 7:
# PORT START TWEAK-EXTEND-OPTION
_ext_name, _escalator, _action = extension_menu()
# if root is needed for extension management...
if _ext_name:
return _ext_name, _escalator, _action
# PORT END TWEAK-EXTEND-OPTION
else:
_exit_signal = True
if _exit_signal:
break
return None, None, None
# runs initial configuration wizard
def initial_setup(_scr):
global stdscr
stdscr = _scr
# required directory creation
Path(f"{home}/.config/sshyp/devices").mkdir(mode=0o700, parents=True, exist_ok=True)
Path(f"{home}/.local/share/sshyp").mkdir(mode=0o700, parents=True, exist_ok=True)
# removal of old config files
if _exists_flag:
sshyp_data.clear()
# curses menu tree
# device+sync type selection
_dev_sync_types = install_type()
if _dev_sync_types[0] == 'client':
# gpg configuration
gpg_config()
# text editor configuration (automated)
editor_config(True)
# quick-unlock configuration (disabled by default)
quick_unlock_config(True)
# online (synchronized mode) configuration
if _dev_sync_types[1] != 'true':
# ssh+sshync configuration
_ip, _username_ssh, _port, _identity = ssh_config()
# device id configuration
dev_id_config(_port, _username_ssh, _ip, _identity)
# PORT START CLIPTOOL
# check for clipboard tool and display warning if missing
if uname()[0] in ('Linux', 'FreeBSD') and 'WSL_DISTRO_NAME' not in environ \
and not exists("/data/data/com.termux"):
_display_server, _clipboard_tool, _clipboard_package = None, None, None
if 'WAYLAND_DISPLAY' in environ:
_display_server, _clipboard_tool, _clipboard_package = 'Wayland', 'wl-copy', 'wl-clipboard'
elif 'DISPLAY' in environ:
_display_server, _clipboard_tool, _clipboard_package = 'X11', 'xclip', 'xclip'
if _display_server is not None and which(_clipboard_tool) is None:
curses_radio(['okay'], f'WARNING: you are using {_display_server} and "{_clipboard_tool}" is not '
'present - \ncopying entry fields will not function until '
f'"{_clipboard_package}" is installed')
# PORT END CLIPTOOL
# run optional configuration menu
curses_radio(['okay'], 'required configuration complete\n\na menu for additional (optional) configuration will be '
'displayed\n\nthis menu can be safely exited at any time')
# set gm_device_type so that after the init menu is terminated the global menu knows the device type
global gm_device_type
gm_device_type = _dev_sync_types[0]
return
# runs the specified entry function (menu start point) within a curses wrapper
def wrapped_entry(_gm_device_type, _gm_top_message='configuration options:'):
from curses import wrapper, use_default_colors
global gm_device_type
gm_device_type = _gm_device_type
# a boolean value represents init
if isinstance(gm_device_type, bool):
wrapper(lambda _wrap_stdscr: (use_default_colors(), initial_setup(_wrap_stdscr)))
# any other value will be interpreted as the global menu device type
# this code still runs when called for init once the init menu terminates
_repeat = True
while _repeat:
try:
_ext_name, _escalator, _action = \
wrapper(lambda _wrap_stdscr: (use_default_colors(),
global_menu(_wrap_stdscr, gm_device_type, _gm_top_message)))[1]
except ChildProcessError:
print("\n\u001b[38;5;9merror: privilege escalation required\n\nneither 'doas' nor 'sudo' were found in "
"the system's $PATH\u001b[0m\n")
return
# only run if privilege escalation is needed
if _action is not None:
if _action:
# install with privilege escalation (outside of curses)
from tempfile import gettempdir
_exe_dir, _ini_dir = f"{gettempdir()}/sshyp_exe", f"{gettempdir()}/sshyp_ini"
# PORT START TWEAK-EXT-CHOWN
if uname()[0] == 'FreeBSD':
run((_escalator, 'chown', 'root:wheel', _exe_dir, _ini_dir))
else:
run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))
# PORT END TWEAK-EXT-CHOWN
run((_escalator, 'mv', _exe_dir, f"/usr/lib/sshyp/{_ext_name}"))
run((_escalator, 'mv', _ini_dir, f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
else:
# uninstall with privilege escalation (outside of curses)
run((_escalator, 'rm', f"/usr/lib/sshyp/{_ext_name}",
f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
else:
_repeat = False
+104 -84
View File
@@ -1,12 +1,14 @@
#!/bin/sh #!/bin/sh
version=$(sed -n '1{p;q}' share/doc/sshyp/changelog | cut -c8-) version=$(head -n1 extra/changelog-archive/2024 | cut -c8-)
if [ -z "$2" ]; then if [ -z "$2" ]; then
revision=1 revision=1
else else
revision="$2" revision="$2"
fi fi
mkdir -p port-jobs/working
_create_generic_linux() { _create_generic_linux() {
printf '\npackaging as generic (Linux)...\n' printf '\npackaging as generic (Linux)...\n'
mkdir -p output/linuxtemp/usr/bin \ mkdir -p output/linuxtemp/usr/bin \
@@ -15,9 +17,11 @@ _create_generic_linux() {
output/linuxtemp/usr/share/bash-completion/completions \ output/linuxtemp/usr/share/bash-completion/completions \
output/linuxtemp/usr/share/zsh/functions/Completion/Unix output/linuxtemp/usr/share/zsh/functions/Completion/Unix
# START PORT # START PORT
cp -r lib/. port-jobs/working/ cp lib/* port-jobs/working/
cd port-jobs cd port-jobs
./CLIPTOOL.py LINUX
./CLIPBOARD.py LINUX ./CLIPBOARD.py LINUX
./CHOWN.py
./UNAME.py LINUX ./UNAME.py LINUX
./COMMENTS.py ALL ./COMMENTS.py ALL
./BLANKS.py ./BLANKS.py
@@ -33,14 +37,14 @@ _create_generic_linux() {
gzip output/linuxtemp/usr/share/man/man1/sshyp.1 gzip output/linuxtemp/usr/share/man/man1/sshyp.1
XZ_OPT=-e6 tar -C output/linuxtemp -cvJf output/GENERIC-LINUX-sshyp-"$version".tar.xz usr/ XZ_OPT=-e6 tar -C output/linuxtemp -cvJf output/GENERIC-LINUX-sshyp-"$version".tar.xz usr/
rm -rf output/linuxtemp rm -rf output/linuxtemp
sha512="$(sha512sum output/GENERIC-LINUX-sshyp-"$version".tar.xz | awk '{print $1;}')" sha512="$(sha512sum output/GENERIC-LINUX-sshyp-"$version".tar.xz | cut -d' ' -f1)"
printf '\ngeneric (Linux) packaging complete\n\n' printf '\ngeneric (Linux) packaging complete\n\n'
} && } &&
_create_pkgbuild() { _create_pkgbuild() {
printf '\ngenerating PKGBUILD...\n' printf '\ngenerating PKGBUILD...\n'
if [ "$1" = 'Deb' ]; then if [ "$1" = 'Deb' ]; then
local source='https://github.com/rwinkhart/sshyp/releases/download/v"$pkgver"/UBUNTU-sshyp_"$pkgver"-"$pkgrel"_all.deb' local source='https://github.com/rwinkhart/sshyp/releases/download/v"$pkgver"/DEBIAN-sshyp_"$pkgver"-"$pkgrel"_all.deb'
local decomp_target='data.tar.xz' local decomp_target='data.tar.xz'
else else
local source='https://github.com/rwinkhart/sshyp/releases/download/v"$pkgver"/GENERIC-LINUX-sshyp-"$pkgver".tar.xz' local source='https://github.com/rwinkhart/sshyp/releases/download/v"$pkgver"/GENERIC-LINUX-sshyp-"$pkgver".tar.xz'
@@ -54,8 +58,12 @@ pkgdesc='A light-weight, self-hosted, synchronized password manager'
url='https://github.com/rwinkhart/sshyp' url='https://github.com/rwinkhart/sshyp'
arch=('any') arch=('any')
license=('GPL-3.0-only') license=('GPL-3.0-only')
depends=(python gnupg openssh xclip wl-clipboard) depends=(python gnupg openssh)
optdepends=('bash-completion: bash completion support') optdepends=(
'wl-clipboard: wayland clipboard support'
'xclip: x11 clipboard support'
'bash-completion: bash completion support'
)
source=(\""$source"\") source=(\""$source"\")
sha512sums=('"$sha512"') sha512sums=('"$sha512"')
@@ -69,8 +77,8 @@ package() {
_create_apkbuild() { _create_apkbuild() {
printf '\ngenerating APKBUILD...\n' printf '\ngenerating APKBUILD...\n'
if [ "$1" = 'Deb' ]; then if [ "$1" = 'Deb' ]; then
local source="https://github.com/rwinkhart/sshyp/releases/download/v\"\$pkgver\"/UBUNTU-sshyp_\"\$pkgver\"-"$revision"_all.deb" local source="https://github.com/rwinkhart/sshyp/releases/download/v\"\$pkgver\"/DEBIAN-sshyp_\"\$pkgver\"-"$revision"_all.deb"
local sumsname="UBUNTU-sshyp_\"\$pkgver\"-"$revision"_all.deb" local sumsname="DEBIAN-sshyp_\"\$pkgver\"-"$revision"_all.deb"
local processing='mkdir -p "$pkgdir" local processing='mkdir -p "$pkgdir"
7z x "$srcdir"/* -o"$srcdir" 7z x "$srcdir"/* -o"$srcdir"
tar -xf "$srcdir"/data.tar -C "$pkgdir" tar -xf "$srcdir"/data.tar -C "$pkgdir"
@@ -95,7 +103,7 @@ options=!check
url='https://github.com/rwinkhart/sshyp' url='https://github.com/rwinkhart/sshyp'
arch='noarch' arch='noarch'
license='GPL-3.0-only' license='GPL-3.0-only'
depends='python3 gnupg openssh xclip wl-clipboard' depends='python3 gnupg openssh'
source=\""$source"\" source=\""$source"\"
package() { package() {
@@ -128,7 +136,7 @@ licenses {
\"GNU GPL v3\" \"GNU GPL v3\"
} }
copyrights { copyrights {
\"2021-2023 Randall Winkhart\" \"2021-2024 Randall Winkhart\"
} }
provides { provides {
sshyp_client = "$version" sshyp_client = "$version"
@@ -137,37 +145,39 @@ provides {
requires { requires {
gnupg gnupg
openssh openssh
python310 python3.11
} }
urls { urls {
\"https://github.com/rwinkhart/sshyp\" \"https://github.com/rwinkhart/sshyp\"
} }
" > output/haikutemp/.PackageInfo " > output/haikutemp/.PackageInfo
# START PORT # START PORT
cp -r lib/. port-jobs/working/ cp lib/* port-jobs/working/
cd port-jobs cd port-jobs
./SHEBANG.sh ./SHEBANG.sh
./RMSERVER.py ./RMSERVER.py
./RMEXTMAN.py
./CLIPTOOL.py
./CLIPBOARD.py HAIKU ./CLIPBOARD.py HAIKU
./COMMENTS.py ALL ./CHOWN.py
./UNAME.py TMP ./UNAME.py TMP
./COMMENTS.py ALL
./BLANKS.py ./BLANKS.py
./TABS.sh TABS ./TABS.sh TABS
cd .. cd ..
mv port-jobs/working/* output/haikutemp/lib/sshyp/ mv port-jobs/working/* output/haikutemp/lib/sshyp/
# END PORT # END PORT
ln -s /system/lib/sshyp/sshyp.py output/haikutemp/bin/sshyp ln -s /system/lib/sshyp/sshyp.py output/haikutemp/bin/sshyp
cp -r share/doc/sshyp/. output/haikutemp/documentation/packages/sshyp/
cp -r share/licenses/sshyp/. output/haikutemp/documentation/packages/sshyp/ cp -r share/licenses/sshyp/. output/haikutemp/documentation/packages/sshyp/
cp extra/completion.bash output/haikutemp/data/bash-completion/completions/sshyp cp extra/completion.bash output/haikutemp/data/bash-completion/completions/sshyp
cp extra/completion.zsh output/haikutemp/data/zsh/site-functions/_sshyp cp extra/completion.zsh output/haikutemp/data/zsh/site-functions/_sshyp
cp extra/manpage output/haikutemp/documentation/man/man1/sshyp.1 cp extra/manpage output/haikutemp/documentation/man/man1/sshyp.1
gzip output/haikutemp/documentation/man/man1/sshyp.1 gzip output/haikutemp/documentation/man/man1/sshyp.1
cd output/haikutemp cd output/haikutemp
package create -b HAIKU-sshyp-client-"$version"-"$revision"_all.hpkg package create -b HAIKU-sshyp_client-"$version"-"$revision"_all.hpkg
package add HAIKU-sshyp-client-"$version"-"$revision"_all.hpkg bin lib documentation data package add HAIKU-sshyp_client-"$version"-"$revision"_all.hpkg bin lib documentation data
cd ../.. cd ../..
mv output/haikutemp/HAIKU-sshyp-client-"$version"-"$revision"_all.hpkg output/ mv output/haikutemp/HAIKU-sshyp_client-"$version"-"$revision"_all.hpkg output/
rm -rf output/haikutemp rm -rf output/haikutemp
printf '\nHaiku packaging complete\n\n' printf '\nHaiku packaging complete\n\n'
} && } &&
@@ -180,34 +190,19 @@ _create_deb() {
output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/man/man1 \ output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/man/man1 \
output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/bash-completion/completions \ output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/bash-completion/completions \
output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/zsh/functions/Completion/Unix output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/zsh/functions/Completion/Unix
printf "Package: sshyp
Version: $version
Section: utils
Architecture: all
Maintainer: Randall Winkhart <idgr at tutanota dot com>
Description: A light-weight, self-hosted, synchronized password manager
" > output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
if [ "$1" = 'Debian' ]; then
printf "Depends: python3, gnupg, openssh-client, xclip, wl-clipboard
" >> output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
else
printf "Depends: python3, gnupg, openssh-client
" >> output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
fi
printf "Suggests: bash-completion
Priority: optional
Installed-Size: 71680
" >> output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
# START PORT # START PORT
cp -r lib/. port-jobs/working/ cp lib/* port-jobs/working/
cd port-jobs cd port-jobs
if [ "$1" = 'Debian' ]; then if [ "$1" = 'Debian' ]; then
./CLIPTOOL.py LINUX
./CLIPBOARD.py LINUX ./CLIPBOARD.py LINUX
special=UBUNTU special=DEBIAN
else else
./CLIPTOOL.py
./CLIPBOARD.py WSL ./CLIPBOARD.py WSL
special=WSL-ONLY-UBUNTU special=WSL-ONLY-DEBIAN
fi fi
./CHOWN.py
./UNAME.py LINUX ./UNAME.py LINUX
./COMMENTS.py ALL ./COMMENTS.py ALL
./BLANKS.py ./BLANKS.py
@@ -221,22 +216,62 @@ Installed-Size: 71680
cp extra/completion.zsh output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/zsh/functions/Completion/Unix/_sshyp cp extra/completion.zsh output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/zsh/functions/Completion/Unix/_sshyp
cp extra/manpage output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/man/man1/sshyp.1 cp extra/manpage output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/man/man1/sshyp.1
gzip output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/man/man1/sshyp.1 gzip output/debiantemp/sshyp_"$version"-"$revision"_all/usr/share/man/man1/sshyp.1
size=$(du --block-size=1024 -s output/debiantemp/sshyp_"$version"-"$revision"_all | cut -f1)
printf "Package: sshyp
Version: $version
Section: utils
Architecture: all
Maintainer: Randall Winkhart <idgr at tutanota dot com>
Description: A light-weight, self-hosted, synchronized password manager
Priority: optional
Installed-Size: $size
Depends: python3, gnupg, openssh-client
" > output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
if [ "$1" = 'Debian' ]; then
printf "Suggests: wl-clipboard, xclip, bash-completion, openssh-server
" >> output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
else
printf "Suggests: bash-completion, openssh-server
" >> output/debiantemp/sshyp_"$version"-"$revision"_all/DEBIAN/control
fi
dpkg-deb --build --root-owner-group -z6 -Sextreme -Zxz output/debiantemp/sshyp_"$version"-"$revision"_all/ dpkg-deb --build --root-owner-group -z6 -Sextreme -Zxz output/debiantemp/sshyp_"$version"-"$revision"_all/
mv output/debiantemp/sshyp_"$version"-"$revision"_all.deb output/"$special"-sshyp_"$version"-"$revision"_all.deb mv output/debiantemp/sshyp_"$version"-"$revision"_all.deb output/"$special"-sshyp_"$version"-"$revision"_all.deb
rm -rf output/debiantemp rm -rf output/debiantemp
sha512="$(sha512sum output/"$special"-sshyp_"$version"-"$revision"_all.deb | awk '{print $1;}')" sha512="$(sha512sum output/"$special"-sshyp_"$version"-"$revision"_all.deb | cut -d' ' -f1)"
printf "\n$1 packaging complete\n\n" printf "\n$1 packaging complete\n\n"
} && } &&
_create_termux() { _create_termux() {
printf '\npackaging for Termux...\n' printf '\npackaging for Termux...\n'
mkdir -p output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/DEBIAN \ mkdir -p output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/DEBIAN \
output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/lib/sshyp/extensions \ output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/lib/sshyp/extensions \
output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/bin \ output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/bin \
output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1 \ output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1 \
output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/bash-completion/completions \ output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/bash-completion/completions \
output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/zsh/site-functions output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/zsh/site-functions
printf "Package: sshyp # START PORT
cp lib/* port-jobs/working/
cd port-jobs
./RMSERVER.py
./RMEXTMAN.py
./CLIPTOOL.py
./CLIPBOARD.py TERMUX
./CHOWN.py
./UNAME.py TERMUX
./COMMENTS.py ALL
./BLANKS.py
./TABS.sh TABS
cd ..
mv port-jobs/working/* output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/lib/sshyp/
# END PORT
ln -s /data/data/com.termux/files/usr/lib/sshyp/sshyp.py output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/bin/sshyp
cp -r share output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/
cp extra/completion.bash output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/bash-completion/completions/sshyp
cp extra/completion.zsh output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/zsh/site-functions/_sshyp
cp extra/manpage output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp.1
gzip output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp.1
size=$(du --block-size=1024 -s output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux | cut -f1)
printf "Package: sshyp-client
Version: $version Version: $version
Section: utils Section: utils
Architecture: all Architecture: all
@@ -245,27 +280,10 @@ Description: A light-weight, self-hosted, synchronized password manager
Depends: python, gnupg, openssh, termux-api, termux-am Depends: python, gnupg, openssh, termux-api, termux-am
Suggests: bash-completion Suggests: bash-completion
Priority: optional Priority: optional
Installed-Size: 71680 Installed-Size: $size
" > output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/DEBIAN/control " > output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/DEBIAN/control
# START PORT dpkg-deb --build --root-owner-group -z6 -Sextreme -Zxz output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux/
cp -r lib/. port-jobs/working/ mv output/termuxtemp/TERMUX-sshyp-client_"$version"-"$revision"_all_termux.deb output/
cd port-jobs
./CLIPBOARD.py TERMUX
./UNAME.py TERMUX
./COMMENTS.py ALL
./BLANKS.py
./TABS.sh TABS
cd ..
mv port-jobs/working/* output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/lib/sshyp/
# END PORT
ln -s /data/data/com.termux/files/usr/lib/sshyp/sshyp.py output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/bin/sshyp
cp -r share output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/
cp extra/completion.bash output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/bash-completion/completions/sshyp
cp extra/completion.zsh output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/zsh/site-functions/_sshyp
cp extra/manpage output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp.1
gzip output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp.1
dpkg-deb --build --root-owner-group -z6 -Sextreme -Zxz output/termuxtemp/sshyp_"$version"-"$revision"_all_termux/
mv output/termuxtemp/sshyp_"$version"-"$revision"_all_termux.deb output/TERMUX-sshyp_"$version"-"$revision"_all_termux.deb
rm -rf output/termuxtemp rm -rf output/termuxtemp
printf '\nTermux packaging complete\n\n' printf '\nTermux packaging complete\n\n'
} && } &&
@@ -287,8 +305,8 @@ BuildArch: noarch
License: GPL-3.0-only License: GPL-3.0-only
URL: https://github.com/rwinkhart/sshyp URL: https://github.com/rwinkhart/sshyp
Source0: GENERIC-FEDORA-sshyp-"$version".tar.xz Source0: GENERIC-FEDORA-sshyp-"$version".tar.xz
Requires: python gnupg openssh-clients wl-clipboard Requires: python gnupg openssh-clients
Recommends: bash-completion Recommends: wl-clipboard xclip bash-completion openssh-server
%%description %%description
sshyp is a password-store compatible CLI password manager available for UNIX(-like) systems - its primary goal is to make syncing passwords and notes across devices as easy as possible via CLI. sshyp is a password-store compatible CLI password manager available for UNIX(-like) systems - its primary goal is to make syncing passwords and notes across devices as easy as possible via CLI.
%%install %%install
@@ -298,17 +316,21 @@ cp -r %%{_sourcedir}/usr %%{buildroot}
/usr/bin/sshyp /usr/bin/sshyp
/usr/lib/sshyp/sshyp.py /usr/lib/sshyp/sshyp.py
/usr/lib/sshyp/sshync.py /usr/lib/sshyp/sshync.py
/usr/lib/sshyp/stweak.py
/usr/lib/sshyp/clipclear.py
/usr/lib/sshyp/extensions/
/usr/share/bash-completion/completions/sshyp /usr/share/bash-completion/completions/sshyp
/usr/share/zsh/site-functions/_sshyp /usr/share/zsh/site-functions/_sshyp
%%license /usr/share/licenses/sshyp/license %%license /usr/share/licenses/sshyp/license
%%doc %%doc
/usr/share/doc/sshyp/changelog
/usr/share/man/man1/sshyp.1.gz /usr/share/man/man1/sshyp.1.gz
" > ~/rpmbuild/SPECS/sshyp.spec " > ~/rpmbuild/SPECS/sshyp.spec
# START PORT # START PORT
cp -r lib/. port-jobs/working/ cp lib/* port-jobs/working/
cd port-jobs cd port-jobs
./CLIPTOOL.py LINUX
./CLIPBOARD.py LINUX ./CLIPBOARD.py LINUX
./CHOWN.py
./UNAME.py LINUX ./UNAME.py LINUX
./COMMENTS.py ALL ./COMMENTS.py ALL
./BLANKS.py ./BLANKS.py
@@ -349,33 +371,31 @@ maintainer: <idgr at tutanota dot com>
www: https://github.com/rwinkhart/sshyp www: https://github.com/rwinkhart/sshyp
prefix: / prefix: /
\"deps\" : { \"deps\" : {
\"python\" : { \"python3\" : {
\"origin\" : \"lang/python\" \"origin\" : \"lang/python3\"
}, },
\"gnupg\" : { \"gnupg\" : {
\"origin\" : \"security/gnupg\" \"origin\" : \"security/gnupg\"
}, },
\"xclip\" : {
\"origin\" : \"x11/xclip\"
},
\"wl-clipboard\" : {
\"origin\" : \"x11/wl-clipboard\"
},
}, },
" > output/freebsdtemp/+MANIFEST " > output/freebsdtemp/+MANIFEST
printf "/usr/bin/sshyp printf "/usr/bin/sshyp
/usr/lib/sshyp/sshync.py
/usr/lib/sshyp/sshyp.py /usr/lib/sshyp/sshyp.py
/usr/lib/sshyp/sshync.py
/usr/lib/sshyp/stweak.py
/usr/lib/sshyp/clipclear.py
/usr/local/share/bash-completion/completions/sshyp /usr/local/share/bash-completion/completions/sshyp
/usr/local/share/zsh/site-functions/_sshyp /usr/local/share/zsh/site-functions/_sshyp
/usr/share/doc/sshyp/changelog
/usr/share/licenses/sshyp/license /usr/share/licenses/sshyp/license
/usr/share/man/man1/sshyp.1.gz /usr/share/man/man1/sshyp.1.gz
@dir /usr/lib/sshyp/extensions/
" > output/freebsdtemp/plist " > output/freebsdtemp/plist
# START PORT # START PORT
cp -r lib/. port-jobs/working/ cp lib/* port-jobs/working/
cd port-jobs cd port-jobs
./CLIPBOARD.py TERMUX ./CLIPTOOL.py LINUX
./CLIPBOARD.py BSD
./CHOWN.py BSD
./UNAME.py TMP ./UNAME.py TMP
./COMMENTS.py ALL ./COMMENTS.py ALL
./BLANKS.py ./BLANKS.py
@@ -460,6 +480,6 @@ case "$1" in
esac esac
;; ;;
*) *)
printf '\nusage: package.sh [target] <revision>\n\ntargets:\n mainline: pkgbuild pkgbuild-deb apkbuild apkbuild-deb fedora debian wsl haiku freebsd\n experimental: termux\n groups: buildable-arch buildable-arch-deb\n\n' printf '\nusage: package.sh [target] <revision>\n\ntargets:\n full support: pkgbuild pkgbuild-deb apkbuild apkbuild-deb fedora debian wsl freebsd\n client-only: haiku termux\n groups: buildable-arch buildable-arch-deb\n\n'
;; ;;
esac esac
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
import re
from sys import argv
# read arguments
arguments = argv[1:]
# define PORT target
string1 = '# PORT START TWEAK-EXT-CHOWN'
string2 = '# PORT END TWEAK-EXT-CHOWN'
# define replacement text depending on arguments
if len(arguments) > 0 and arguments[0] == 'BSD':
replacement = "run((_escalator, 'chown', 'root:wheel', _exe_dir, _ini_dir))"
else:
replacement = "run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))"
# read input file
text = open('working/stweak.py', 'r').read()
# compile regex and modify text
regex = re.compile(f"{string1}.*?{string2}", re.DOTALL)
# find and replace the defined PORT target
new_text = re.sub(regex, replacement, text)
# write updated text
open('working/stweak.py', 'w').write(new_text)
+45 -33
View File
@@ -3,48 +3,60 @@ import re
from sys import argv, exit as s_exit from sys import argv, exit as s_exit
# read arguments # read arguments
arguments = argv[1:] arguments, clip_replacement, clear_replacement = argv[1:], None, None
# define replacement text depending on arguments # define replacement text depending on arguments
if len(arguments) > 0: if len(arguments) > 0:
if arguments[0] == 'WSL': if arguments[0] == 'WSL':
replacement = """run(['powershell.exe', '-c', "Set-Clipboard '" + _copy_line[_index].rstrip().replace("'", "''") + "'"]) clip_replacement = """run(('powershell.exe', '-c', "Set-Clipboard '" + _copy_subject.replace("'", "''") + "'"))
Popen("sleep 30; pwsh.exe -c 'echo \\"\\" | Set-Clipboard'", shell=True)""" Popen((realpath(__file__).rsplit('/', 1)[0] + "/clipclear.py", _hash.hexdigest(), 'wsl'), stdout=DEVNULL, stderr=DEVNULL)"""
clear_replacement = """hash_paste.update(run(('powershell.exe', '-c', 'Get-Clipboard'), stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('powershell.exe', '-c', 'Set-Clipboard'))"""
elif arguments[0] == 'MAC': elif arguments[0] == 'MAC':
replacement = """run(['pbcopy'], stdin=Popen(['printf', _copy_line[_index].rstrip().replace('\\\\\\', '\\\\\\\\\\\\\\').replace('%', '%%')], clip_replacement = """run('pbcopy', stdin=Popen(('printf', '%b', _copy_subject.replace('\\\\\\', '\\\\\\\\\\\\\\')), stdout=PIPE).stdout)
stdout=PIPE).stdout) Popen((realpath(__file__).rsplit('/', 1)[0] + "/clipclear.py", _hash.hexdigest(), 'mac'))"""
Popen("sleep 30; printf '' | pbcopy", shell=True)""" clear_replacement = """hash_paste.update(run('pbpaste', stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run('pbcopy', input=b'')"""
elif arguments[0] == 'HAIKU': elif arguments[0] == 'HAIKU':
replacement = """run(['clipboard', '-c', _copy_line[_index].rstrip()]) clip_replacement = """run(('clipboard', '-c', _copy_subject))
Popen('sleep 30; clipboard -r', shell=True)""" Popen((realpath(__file__).rsplit('/', 1)[0] + "/clipclear.py", _hash.hexdigest(), 'haiku'))"""
clear_replacement = """hash_paste.update(run(('clipboard', '-p'), stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('clipboard', '-r'))"""
elif arguments[0] == 'TERMUX': elif arguments[0] == 'TERMUX':
replacement = """run(['termux-clipboard-set', _copy_line[_index].rstrip()]) clip_replacement = """run(('termux-clipboard-set', _copy_subject))
Popen("sleep 30; termux-clipboard-set ''", shell=True)""" Popen((realpath(__file__).rsplit('/', 1)[0] + "/clipclear.py", _hash.hexdigest(), 'termux'))"""
elif arguments[0] == 'BSD': clear_replacement = """hash_paste.update(run('termux-clipboard-get', stdout=PIPE).stdout.strip())
replacement = """run(['xclip', '-sel', 'c'], stdin=Popen(['printf', _copy_line[_index].rstrip().replace('\\', '\\\\') if argv[1] == hash_paste.hexdigest():
.replace('%', '%%')], stdout=PIPE).stdout) run(("termux-clipboard-set", "''"))"""
Popen("sleep 30; printf '' | xclip -sel c", shell=True)""" elif arguments[0] in ('LINUX', 'BSD'):
elif arguments[0] == 'LINUX': clip_replacement = """if 'WAYLAND_DISPLAY' in environ:
replacement = """if 'WAYLAND_DISPLAY' in environ: run('wl-copy', stdin=Popen(('printf', '%b', _copy_subject.replace('\\\\\\', '\\\\\\\\\\\\\\')), stdout=PIPE).stdout)
run(['wl-copy', _copy_line[_index].rstrip()]) Popen((realpath(__file__).rsplit('/', 1)[0] + "/clipclear.py", _hash.hexdigest(), 'wayland'))
Popen('sleep 30; wl-copy -c', shell=True)
else: else:
run(['xclip', '-sel', 'c'], stdin=Popen(['printf', _copy_line[_index].rstrip().replace('\\\\\\', '\\\\\\\\\\\\\\') run(('xclip', '-sel', 'c'), stdin=Popen(('printf', '%b', _copy_subject.replace('\\\\\\', '\\\\\\\\\\\\\\')), stdout=PIPE).stdout)
.replace('%', '%%')], stdout=PIPE).stdout) Popen((realpath(__file__).rsplit('/', 1)[0] + "/clipclear.py", _hash.hexdigest(), 'x11'))"""
Popen("sleep 30; printf '' | xclip -sel c", shell=True)""" clear_replacement = """if argv[2] == 'wayland':
hash_paste.update(run('wl-paste', stdout=PIPE, stderr=DEVNULL).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('wl-copy', '-c'))
else:
hash_paste.update(run(('xclip', '-o', '-sel', 'c'), stdout=PIPE).stdout.strip())
if argv[1] == hash_paste.hexdigest():
run(('xclip', '-i', '/dev/null', '-sel', 'c'))"""
else: else:
s_exit() s_exit()
# define PORT target targets = (('CLIPBOARD', 'sshyp.py', '', '', clip_replacement),
string1 = '# PORT START CLIPBOARD' ('CLIPCLEAR', 'clipclear.py', '\n', '', clear_replacement))
string2 = '# PORT END CLIPBOARD'
# read input file for target in targets:
text = open('working/sshyp.py', 'r').read() # read text from target file
text = open(f"working/{target[1]}", 'r').read()
# find and replace the defined PORT target # compile regex and modify text
regex = re.compile(f"{string1}.*?{string2}", re.DOTALL) regex = re.compile(f"{target[2]}# PORT START {target[0]}.*?# PORT END {target[0]}{target[3]}", re.DOTALL)
new_text = re.sub(regex, replacement, text) new_text = re.sub(regex, target[4], text)
# write updated text to target file
# write updated text open(f"working/{target[1]}", 'w').write(new_text)
open('working/sshyp.py', 'w').write(new_text)
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
import re
from sys import argv
# read arguments
arguments = argv[1:]
# define PORT target
string1 = '# PORT START CLIPTOOL'
string2 = '# PORT END CLIPTOOL'
# define replacement text depending on arguments
if len(arguments) > 0:
regex = re.compile(f"{string1}.*?{string2}", re.DOTALL)
replacement = """# check for clipboard tool and display warning if missing
_display_server, _clipboard_tool, _clipboard_package = None, None, None
if 'WAYLAND_DISPLAY' in environ:
_display_server, _clipboard_tool, _clipboard_package = 'Wayland', 'wl-copy', 'wl-clipboard'
elif 'DISPLAY' in environ:
_display_server, _clipboard_tool, _clipboard_package = 'X11', 'xclip', 'xclip'
if _display_server is not None and which(_clipboard_tool) is None:
curses_radio(['okay'], f'''WARNING: you are using {_display_server} and "{_clipboard_tool}" is not present -
copying entry fields will not function until "{_clipboard_package}" is installed'''
)"""
else:
regex = re.compile(f"{string1}.*?{string2}\n", re.DOTALL)
replacement = ''
# read input file
text = open('working/stweak.py', 'r').read()
# find and replace the defined PORT target
new_text = re.sub(regex, replacement, text)
# write updated text
open('working/stweak.py', 'w').write(new_text)
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env python3
import re
targets = (('TWEAK-EXTEND-FUNCTIONS', 'stweak.py', '\n', '\n\n', ''),
('TWEAK-EXTEND-OPTION', 'stweak.py', '', '', "curses_radio(['okay'], "
"'extension management is not supported on this platform\\\\n\\\\ninstead, you may install and manage "
"extensions through your system package manager\\\\n\\\\nofficial extension packages are available "
"at https://github.com/rwinkhart/sshyp-labs/releases')"))
for target in targets:
# read text from target file
text = open(f"working/{target[1]}", 'r').read()
# compile regex and modify text
regex = re.compile(f"{target[2]}# PORT START {target[0]}.*?# PORT END {target[0]}{target[3]}", re.DOTALL)
new_text = re.sub(regex, target[4], text)
# write updated text to target file
open(f"working/{target[1]}", 'w').write(new_text)
+13 -77
View File
@@ -1,82 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import re import re
# SSHYNC-REMOTE devtype_replacement = """_install_type = curses_radio(('client (ssh-synchronized)', 'client (offline)'),
# define PORT target 'device + sync type configuration')"""
string1 = '# PORT START SSHYNC-REMOTE'
string2 = '# PORT END SSHYNC-REMOTE'
# read input file targets = (('SSHYNC-REMOTE', 'sshync.py', '\n', '\n\n', ''), ('WHITELIST-SERVER', 'stweak.py', '\n', '\n\n', ''),
text = open('working/sshync.py', 'r').read() ('TWEAK-DEVTYPE', 'stweak.py', '', '', devtype_replacement),
('ARGS-SERVER', 'sshyp.py', '', '\n\n ', ''), ('HELP-SERVER', 'sshyp.py', '', '\n', ''))
# find and replace the defined PORT target for target in targets:
regex = re.compile(f"\n{string1}.*?{string2}\n\n", re.DOTALL) # read text from target file
new_text = re.sub(regex, '', text) text = open(f"working/{target[1]}", 'r').read()
# compile regex and modify text
# write updated text regex = re.compile(f"{target[2]}# PORT START {target[0]}.*?# PORT END {target[0]}{target[3]}", re.DOTALL)
open('working/sshync.py', 'w').write(new_text) new_text = re.sub(regex, target[4], text)
# write updated text to target file
# WHITELIST-SERVER open(f"working/{target[1]}", 'w').write(new_text)
# define PORT target
string1 = '# PORT START WHITELIST-SERVER'
string2 = '# PORT END WHITELIST-SERVER'
# read input file
text = open('working/sshyp.py', 'r').read()
# find and replace the defined PORT target
regex = re.compile(f"\n{string1}.*?{string2}\n\n", re.DOTALL)
new_text = re.sub(regex, '', text)
# write updated text
open('working/sshyp.py', 'w').write(new_text)
# TWEAK-DEVTYPE
# define PORT target
string1 = '# PORT START TWEAK-DEVTYPE'
string2 = '# PORT END TWEAK-DEVTYPE'
# set replacement text
replacement = """if True:
_sshyp_data = ['client']
Path(f"{home}/.local/share/sshyp").mkdir(mode=0o700, parents=True, exist_ok=True)"""
# read input file
text = open('working/sshyp.py', 'r').read()
# find and replace the defined PORT target
regex = re.compile(f"{string1}.*?{string2}", re.DOTALL)
new_text = re.sub(regex, replacement, text)
# write updated text
open('working/sshyp.py', 'w').write(new_text)
# ARGS-SERVER
# define PORT target
string1 = '# PORT START ARGS-SERVER'
string2 = '# PORT END ARGS-SERVER'
# read input file
text = open('working/sshyp.py', 'r').read()
# find and replace the defined PORT target
regex = re.compile(f"{string1}.*?{string2}\n\n ", re.DOTALL)
new_text = re.sub(regex, '', text)
# write updated text
open('working/sshyp.py', 'w').write(new_text)
# HELP-SERVER
# define PORT target
string1 = '# PORT START HELP-SERVER'
string2 = '# PORT END HELP-SERVER'
# read input file
text = open('working/sshyp.py', 'r').read()
# find and replace the defined PORT target
regex = re.compile(f"{string1}.*?{string2}\n", re.DOTALL)
new_text = re.sub(regex, '', text)
# write updated text
open('working/sshyp.py', 'w').write(new_text)
+4 -3
View File
@@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
if [ "$1" = 'HAIKU' ]; then if [ "$1" = 'PREP' ]; then
sed -i '1 s/.*/#!\/bin\/env\ python3.10/' ./working/sshync.py sed -i '1 s/.*/#!\/bin\/env\ python3.11/' ./*.py
sed -i '1 s/.*/#!\/bin\/env\ python3.10/' ./working/sshyp.py else
sed -i '1 s/.*/#!\/bin\/env\ python3.11/' ./working/sshyp.py ./working/clipclear.py
fi fi
+3 -1
View File
@@ -2,9 +2,11 @@
if [ "$1" = 'TABS' ]; then if [ "$1" = 'TABS' ]; then
unexpand -t 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123 working/sshyp.py > working/sshyp.py.new unexpand -t 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123 working/sshyp.py > working/sshyp.py.new
unexpand -t 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123 working/sshync.py > working/sshync.py.new unexpand -t 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123 working/sshync.py > working/sshync.py.new
unexpand -t 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123 working/stweak.py > working/stweak.py.new
mv working/sshyp.py.new working/sshyp.py mv working/sshyp.py.new working/sshyp.py
mv working/sshync.py.new working/sshync.py mv working/sshync.py.new working/sshync.py
chmod +x working/sshyp.py working/sshync.py mv working/stweak.py.new working/stweak.py
chmod +x working/sshyp.py working/sshync.py working/stweak.py
elif [ "$(grep -qP '\t' "$1" && echo TABS)" = 'TABS' ]; then elif [ "$(grep -qP '\t' "$1" && echo TABS)" = 'TABS' ]; then
printf "$1 contains tab characters...\n" printf "$1 contains tab characters...\n"
read -rp 'replace with (4) spaces? (Y/n) ' replace read -rp 'replace with (4) spaces? (Y/n) ' replace
+9 -43
View File
@@ -1,47 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import re import re
from sys import argv, exit as s_exit
# read arguments targets = (('UNAME-IMPORT-SSHYP', 'sshyp.py', ''), ('UNAME-IMPORT-STWEAK', 'stweak.py', ''))
arguments = argv[1:]
# define replacement text depending on arguments for target in targets:
if len(arguments) > 0: # read text from target file
if arguments[0] == 'TMP': text, special = open(f"working/{target[1]}", 'r').read(), ''
replacement = 'symlink("/tmp", f"{home}/.config/sshyp/tmp")' # compile regex and modify text
elif arguments[0] == 'TERMUX': regex = re.compile(f"# PORT START {target[0]}.*?# PORT END {target[0]}\n", re.DOTALL)
replacement = 'symlink("/data/data/com.termux/files/usr/tmp", f"{home}/.config/sshyp/tmp")' new_text = re.sub(regex, target[2], text)
elif arguments[0] == 'LINUX': # write updated text to target file
replacement = 'symlink("/dev/shm", f"{home}/.config/sshyp/tmp")' open(f"working/{target[1]}", 'w').write(new_text)
else:
s_exit()
# UNAME-IMPORT
# define PORT target
string1 = '# PORT START UNAME-IMPORT'
string2 = '# PORT END UNAME-IMPORT'
# read input file
text = open('working/sshyp.py', 'r').read()
# find and replace the defined PORT target
regex = re.compile(f"{string1}.*?{string2}\n", re.DOTALL)
new_text = re.sub(regex, '', text)
# write updated text
open('working/sshyp.py', 'w').write(new_text)
# UNAME-TMP
# define PORT target
string1 = '# PORT START UNAME-TMP'
string2 = '# PORT END UNAME-TMP'
# read input file
text = open('working/sshyp.py', 'r').read()
# find and replace the defined PORT target
regex = re.compile(f"{string1}.*?{string2}", re.DOTALL)
new_text = re.sub(regex, replacement, text)
# write updated text
open('working/sshyp.py', 'w').write(new_text)
-41
View File
@@ -1,41 +0,0 @@
sshyp v1.4.2
04/30/2023
the argumentative agronomist update - patch two
IMPORTANT: the next major release of sshyp, v1.5.0, will make breaking changes that will require
running through 'sshyp tweak' again - also starting with v1.5.0, a copy of the changelog will no
longer be packaged with sshyp (it will still be available on GitHub) and clipboard tools
(x-clip and wl-clipboard) will be set to optional dependencies ('sshyp tweak' will warn of this)
this release makes use of a new ports framework to make sshyp even smaller and faster than before
user-facing features:
- full WSL (Windows Subsystem for Linux) support
- partial MacOS support
^ fully functional; packaging support has not yet been added
- dedicated help screen for 'gen'
^ this was previously not included due to 'sshyp gen' being a valid command prior to v1.4.0
- removed interactive input for whitelist management
^ this is to be consistent with the removal of interactive input on clients in v1.4.0
fixes/optimizations:
- leading and following spaces are no longer stripped when printing entry contents
- properly display an error when trying to remove a device from the whitelist that is not whitelisted
- ports framework to remove unneeded code for each platform
^ BLANKS.py removes all blank lines
^ CLIPBOARD.py removes non-platform-critical clipboard code
^ COMMENTS.py removes all comments
^ RMSERVER.py removes server-only code for creating client-only packages
^ the Haiku package, which was already unsupported as a server, now only includes client code
^ SHEBANG.sh sets the shebang to what is required by the platform
^ TABS.sh converts all groups of spaces to tabs for space efficiency
^ UNAME.py removes all instances of platform detection and leaves only the platform-required code
^ THESE SCRIPTS ARE ONLY USED FOR PACKAGING AND DO NOT AFFECT THE SOURCE FILES IN THE GIT REPO
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
The full history of changes to "sshyp" can be found on the following page:
https://github.com/rwinkhart/sshyp/tree/main/extra/changelog-archive/
+1 -1
View File
@@ -1,5 +1,5 @@
sshyp is a FOSS password manager that uses an sftp-based syncing back-end. sshyp is a FOSS password manager that uses an sftp-based syncing back-end.
Copyright (C) 2021-2023 Randall Winkhart idgr@tutanota.com Copyright (C) 2021-2024 Randall Winkhart idgr@tutanota.com
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of version 3 (only) of the GNU General Public License it under the terms of version 3 (only) of the GNU General Public License