mirror of
https://github.com/rwinkhart/sshyp-labs.git
synced 2026-08-28 04:46:48 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1216d06975 | ||
|
|
8e45b15fee | ||
|
|
6ee49d6b95 | ||
|
|
7b03cfdc5e | ||
|
|
45caab270e | ||
|
|
1c6150afe4 | ||
|
|
8916f9b2e2 | ||
|
|
c0281a4dc3 | ||
|
|
37efe8f96a | ||
|
|
2271281683 | ||
|
|
c5c3600e6d | ||
|
|
a97aa6052a | ||
|
|
d133406de9 | ||
|
|
25f608dd1e | ||
|
|
a957d80a67 | ||
|
|
521714fd12 | ||
|
|
3c80d72a36 | ||
|
|
68c370be55 | ||
|
|
bd09ab32cd | ||
|
|
755b1183e3 | ||
|
|
9c67f41199 | ||
|
|
951cb5adc5 | ||
|
|
4227a264c8 | ||
|
|
d19cc1ed2c | ||
|
|
04ab10fdd9 | ||
|
|
fd5266351e | ||
|
|
73947dd7ef | ||
|
|
fcf43986a8 | ||
|
|
dfb90ca294 | ||
|
|
42ef63c0d9 | ||
|
|
939d07e804 | ||
|
|
be41d32f78 | ||
|
|
ba2ac73965 | ||
|
|
ebb420d30f | ||
|
|
8cf5728c42 | ||
|
|
9e0c121843 |
Executable → Regular
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
@@ -1,41 +0,0 @@
|
||||
#!/bin/python3
|
||||
|
||||
from os import path, remove, system, walk
|
||||
from pathlib import Path
|
||||
from shutil import move, rmtree
|
||||
|
||||
if __name__ == "__main__":
|
||||
gpg_id = input('\nWhat is the ID of the GPG key you would like to use for re-encryption?\n\nID: ')
|
||||
directory = path.expanduser('~/.local/share/sshyp')
|
||||
if Path(f"{directory}.new").exists():
|
||||
rmtree(f"{directory}.new")
|
||||
if Path(f"{directory}.old").exists():
|
||||
rmtree(f"{directory}.old")
|
||||
if path.isdir(directory):
|
||||
for dirPath, dirNames, filenames in walk(directory):
|
||||
for filename in sorted(filenames):
|
||||
Path(dirPath.replace(directory, directory + '.new')).mkdir(0o700, parents=True, exist_ok=True)
|
||||
system(f"gpg -d '{dirPath}/{filename}' "
|
||||
f"> '{dirPath.replace(directory, directory + '.new')}/{filename[:-4]}'")
|
||||
_old_contents, _new_contents = \
|
||||
open(f"{dirPath.replace(directory, directory + '.new')}/{filename[:-4]}", 'r').readlines(), ''
|
||||
for _num in range(len(_old_contents)):
|
||||
if _num == 3:
|
||||
if _old_contents[_num] == ' ' or _old_contents[_num] == '\n':
|
||||
pass
|
||||
else:
|
||||
_new_contents += _old_contents[_num]
|
||||
else:
|
||||
_new_contents += _old_contents[_num]
|
||||
for _num in reversed(range(len(_new_contents))):
|
||||
if _new_contents[_num] == '\n' or _new_contents[_num] == '':
|
||||
_new_contents = _new_contents[:-1]
|
||||
else:
|
||||
break
|
||||
open(f"{dirPath.replace(directory, directory + '.new')}/{filename[:-4]}", 'w').writelines(_new_contents)
|
||||
system(f"gpg -qr {str(gpg_id)} -e '{dirPath.replace(directory, directory + '.new')}/{filename[:-4]}'")
|
||||
remove(f"{dirPath.replace(directory, directory + '.new')}/{filename[:-4]}")
|
||||
else:
|
||||
print(f"\nError: no entry folder ({directory}) found\n")
|
||||
move(directory, f"{directory}.old")
|
||||
move(f"{directory}.new", directory)
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from os import path, remove, system, walk
|
||||
from pathlib import Path
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from os import path, system, uname, walk
|
||||
from pathlib import Path
|
||||
from shutil import move, rmtree
|
||||
from sshyp import decrypt, encrypt, optimized_edit, shm_gen
|
||||
|
||||
if __name__ == "__main__":
|
||||
directory, tmp_dir = path.expanduser('~/.local/share/sshyp'), path.expanduser('~/.config/sshyp/tmp/')
|
||||
if uname()[0] == 'Haiku': # set proper gpg command for OS
|
||||
gpg = 'gpg --pinentry-mode loopback'
|
||||
else:
|
||||
gpg = 'gpg'
|
||||
system(f"{gpg} -k")
|
||||
gpg_id = input('\ngpg id for re-encryption: ')
|
||||
if Path(f"{directory}.new").exists():
|
||||
rmtree(f"{directory}.new")
|
||||
if Path(f"{directory}.old").exists():
|
||||
rmtree(f"{directory}.old")
|
||||
if path.isdir(directory):
|
||||
print('\nconverting... please wait, do not force close this process')
|
||||
for dirPath, dirNames, filenames in walk(directory):
|
||||
for filename in sorted(filenames):
|
||||
Path(dirPath.replace(directory, directory + '.new')).mkdir(0o700, parents=True, exist_ok=True)
|
||||
_shm_folder, _shm_entry = shm_gen()
|
||||
decrypt(f"{dirPath}/{filename[:-4]}", _shm_folder, _shm_entry, gpg)
|
||||
_new_lines = optimized_edit(open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'r').readlines(), None, -1)
|
||||
open(f"{tmp_dir}{_shm_folder}/{_shm_entry}", 'w').writelines(_new_lines)
|
||||
encrypt(f"{dirPath.replace(directory, directory + '.new', 1)}/{filename[:-4]}",
|
||||
_shm_folder, _shm_entry, gpg, gpg_id)
|
||||
move(directory, f"{directory}.old")
|
||||
move(f"{directory}.new", directory)
|
||||
else:
|
||||
print(f"\nError: no entry folder ({directory}) found\n")
|
||||
@@ -0,0 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(password_pasture C)
|
||||
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTK4 REQUIRED gtk4)
|
||||
|
||||
include_directories(${GTK4_INCLUDE_DIRS})
|
||||
link_directories(${GTK4_LIBRARY_DIRS})
|
||||
|
||||
add_definitions(${GTK4_CFLAGS_OTHER})
|
||||
|
||||
add_executable(password_pasture main.c)
|
||||
|
||||
target_link_libraries(password_pasture ${GTK4_LIBRARIES})
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
rm -rf CMakeFiles cmake_install.cmake CMakeCache.txt Makefile
|
||||
cmake ./
|
||||
sleep 10 # prevents clock skew
|
||||
make -j$(nproc)
|
||||
@@ -0,0 +1,380 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stddef.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
GtkWidget *label_selected; GtkListBox *list_box;
|
||||
char entries[1024][1024]; int entry_array_count = 0;
|
||||
|
||||
void str_remove(char *str, const char *sub) {
|
||||
char *p, *q, *r;
|
||||
if (*sub && (q = r = strstr(str, sub)) != 0) {
|
||||
size_t len = strlen(sub);
|
||||
while ((r = strstr(p = r + len, sub)) != 0) {
|
||||
while (p < r)
|
||||
*q++ = *p++;
|
||||
}
|
||||
while ((*q++ = *p++) != '\0')
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
void gen_entry_array(char *path, size_t size, const char *path_orig) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
size_t len = strlen(path);
|
||||
|
||||
if (!(dir = opendir(path))) {
|
||||
return; }
|
||||
|
||||
while ((entry = readdir(dir)) != 0) {
|
||||
char *name = entry->d_name;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||
continue; }
|
||||
path[len] = '/';
|
||||
strcpy(path + len + 1, name);
|
||||
gen_entry_array(path, size, path_orig);
|
||||
path[len] = '\0';
|
||||
} else {
|
||||
char path_filtered[1024];
|
||||
strcpy(path_filtered, path);
|
||||
str_remove(path_filtered, path_orig);
|
||||
size_t name_len = strlen(name);
|
||||
name[name_len-4] = 0;
|
||||
char sshyp_path[1024]; strcpy(sshyp_path, path_filtered); strcat(sshyp_path, "/"); strcat(sshyp_path, name);
|
||||
strcpy(entries[entry_array_count], sshyp_path);
|
||||
entry_array_count++;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
void password_convert(GtkEntryBuffer *buffer) {
|
||||
const char *password = gtk_entry_buffer_get_text(buffer);
|
||||
char *sub1 = "gpg --pinentry-mode loopback --batch --passphrase-fd 0 --armor -qd --output /dev/null ~/.config/sshyp/lock.gpg <<< '", *sub2 = "'", *command = (char *) malloc(2048);
|
||||
strcpy(command, sub1); strcat(command, password); strcat(command, sub2);
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
|
||||
void gpg_lock() {
|
||||
system("gpgconf --reload gpg-agent");
|
||||
}
|
||||
|
||||
void password_prompt(GtkWindow *window) {
|
||||
GtkWidget *dialog, *dialog_header, *box_header; // main window and header bar
|
||||
GtkWidget *button_unlock, *button_cancel, *button_lock; // header bar buttons
|
||||
GtkWidget *content_area, *password_entry; // content area and widgets
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
password_entry = gtk_entry_new();
|
||||
gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
|
||||
gtk_entry_set_placeholder_text(GTK_ENTRY(password_entry), "passphrase");
|
||||
dialog_header = gtk_header_bar_new();
|
||||
gtk_header_bar_set_show_title_buttons(GTK_HEADER_BAR(dialog_header), FALSE);
|
||||
box_header = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_halign(box_header, GTK_ALIGN_CENTER);
|
||||
button_unlock = gtk_button_new_with_label("unlock");
|
||||
button_cancel = gtk_button_new_with_label("cancel");
|
||||
button_lock = gtk_button_new_from_icon_name("changes-prevent");
|
||||
gtk_widget_set_size_request(button_lock, 20, -1);
|
||||
gtk_box_append(GTK_BOX(box_header), button_unlock);
|
||||
gtk_box_append(GTK_BOX(box_header), button_cancel);
|
||||
gtk_box_append(GTK_BOX(box_header), button_lock);
|
||||
gtk_header_bar_set_title_widget(GTK_HEADER_BAR(dialog_header), box_header);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "");
|
||||
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dialog), 50, 50);
|
||||
|
||||
// add password entry to dialog content area
|
||||
content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
gtk_box_append(GTK_BOX(content_area), password_entry);
|
||||
|
||||
gtk_window_set_titlebar(GTK_WINDOW(dialog), dialog_header);
|
||||
gtk_widget_show(dialog);
|
||||
|
||||
// button actions
|
||||
g_signal_connect_swapped(button_unlock, "clicked", G_CALLBACK(password_convert), gtk_entry_get_buffer(GTK_ENTRY(password_entry)));
|
||||
g_signal_connect_swapped(button_unlock, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_cancel, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect(button_lock, "clicked", G_CALLBACK(gpg_lock), 0);
|
||||
g_signal_connect_swapped(button_lock, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
}
|
||||
|
||||
void copy_item(GtkWidget *button) {
|
||||
char *command = malloc(2048); const char *button_label = gtk_button_get_label(GTK_BUTTON(button));
|
||||
strcpy(command, "sshyp copy ");
|
||||
strcat(command, button_label); strcat(command, " ");
|
||||
strcat(command, gtk_label_get_text((GtkLabel *) label_selected));
|
||||
system(command);
|
||||
free(command);
|
||||
}
|
||||
|
||||
void copy_edit_field_prompt(GtkWidget *button, gpointer *window) {
|
||||
GtkWidget *dialog, *dialog_header; // main window and header bar
|
||||
GtkWidget *button_cancel; // header bar buttons
|
||||
GtkWidget *content_area, *button_pwd, *button_usr, *button_url, *button_nte, *button_mfa; // content area and widgets
|
||||
int mode; // copy/edit mode flag
|
||||
|
||||
// set mode based on button pressed, copy = 1, edit = 2
|
||||
const char *button_label = gtk_button_get_icon_name(GTK_BUTTON(button));
|
||||
if (strcmp(button_label, "edit-copy") == 0) {
|
||||
mode = 1;
|
||||
} else {
|
||||
mode = 2;
|
||||
}
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
dialog_header = gtk_header_bar_new();
|
||||
gtk_header_bar_set_show_title_buttons(GTK_HEADER_BAR(dialog_header), FALSE);
|
||||
button_cancel = gtk_button_new_with_label("cancel");
|
||||
gtk_header_bar_set_title_widget(GTK_HEADER_BAR(dialog_header), button_cancel);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "");
|
||||
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dialog), 50, 50);
|
||||
|
||||
// add options to dialog content area
|
||||
content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
button_pwd = gtk_button_new_with_label("password");
|
||||
button_usr = gtk_button_new_with_label("username");
|
||||
button_url = gtk_button_new_with_label("url");
|
||||
button_nte = gtk_button_new_with_label("note");
|
||||
button_mfa = gtk_button_new_with_label("mfa");
|
||||
gtk_box_append(GTK_BOX(content_area), button_pwd);
|
||||
gtk_box_append(GTK_BOX(content_area), button_usr);
|
||||
gtk_box_append(GTK_BOX(content_area), button_url);
|
||||
gtk_box_append(GTK_BOX(content_area), button_nte);
|
||||
gtk_box_append(GTK_BOX(content_area), button_mfa);
|
||||
|
||||
gtk_window_set_titlebar(GTK_WINDOW(dialog), dialog_header);
|
||||
gtk_widget_show(dialog);
|
||||
|
||||
// button actions
|
||||
if (mode == 1) {
|
||||
g_signal_connect(button_pwd, "clicked", G_CALLBACK(copy_item), 0);
|
||||
g_signal_connect(button_usr, "clicked", G_CALLBACK(copy_item), 0);
|
||||
g_signal_connect(button_url, "clicked", G_CALLBACK(copy_item), 0);
|
||||
g_signal_connect(button_nte, "clicked", G_CALLBACK(copy_item), 0);
|
||||
g_signal_connect(button_mfa, "clicked", G_CALLBACK(copy_item), 0);
|
||||
}
|
||||
|
||||
g_signal_connect_swapped(button_cancel, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_pwd, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_usr, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_url, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_nte, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_mfa, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
}
|
||||
|
||||
void set_selection_label(GtkWidget *button, gpointer *label) {
|
||||
const char *button_label = gtk_button_get_label(GTK_BUTTON(button));
|
||||
gtk_label_set_text(GTK_LABEL(label), button_label);
|
||||
}
|
||||
|
||||
void entry_list_gen() {
|
||||
GtkWidget *entry_button;
|
||||
|
||||
GtkWidget *iter = gtk_widget_get_first_child ((GtkWidget *) list_box);
|
||||
while (iter != 0) {
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (iter);
|
||||
gtk_list_box_remove (list_box, iter);
|
||||
iter = next;
|
||||
}
|
||||
|
||||
char path[1024]; char *user_home = getenv("HOME"); strcpy(path, user_home); strcat(path, "/.local/share/sshyp");
|
||||
char path_orig[1024]; strcpy(path_orig, path); strcat(path_orig, "/");
|
||||
gen_entry_array(path, sizeof path, path_orig);
|
||||
|
||||
// bubble sort entries array
|
||||
char *temp = (char *) malloc(1024);
|
||||
for(int i=0; i<entry_array_count; i++){
|
||||
for(int j=0; j<entry_array_count-1-i; j++){
|
||||
if(strcmp(entries[j], entries[j+1]) > 0){
|
||||
strcpy(temp, entries[j]);
|
||||
strcpy(entries[j], entries[j+1]);
|
||||
strcpy(entries[j+1], temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(temp);
|
||||
|
||||
strcpy(entries[entry_array_count], "\0");
|
||||
|
||||
for (int i_2 = 0; strcmp(entries[i_2], "\0") != 0; i_2++) {
|
||||
entry_button = gtk_button_new_with_label(entries[i_2]);
|
||||
gtk_label_set_xalign(GTK_LABEL(gtk_button_get_child(GTK_BUTTON(entry_button))), GTK_JUSTIFY_LEFT);
|
||||
gtk_button_set_has_frame(GTK_BUTTON(entry_button), FALSE);
|
||||
g_signal_connect(entry_button, "clicked", G_CALLBACK(set_selection_label), (gpointer *)label_selected);
|
||||
gtk_list_box_append(list_box, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
|
||||
gtk_list_box_append(list_box, entry_button);
|
||||
}
|
||||
}
|
||||
|
||||
void sshyp_sync() {
|
||||
system("sshyp sync");
|
||||
entry_array_count = 0;
|
||||
entry_list_gen();
|
||||
}
|
||||
|
||||
void delete_entry() {
|
||||
char *command = (char *) malloc(2048);
|
||||
strcpy(command, "sshyp shear "); strcat(command, gtk_label_get_text(GTK_LABEL(label_selected)));
|
||||
system(command);
|
||||
free(command);
|
||||
entry_array_count = 0;
|
||||
entry_list_gen();
|
||||
}
|
||||
|
||||
void are_they_sure(GtkWindow *window) {
|
||||
GtkWidget *dialog, *dialog_header, *box_header; // main window and header bar
|
||||
GtkWidget *button_delete, *button_cancel; // header bar buttons
|
||||
GtkWidget *content_area, *label_sure; // content area and widgets
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
dialog_header = gtk_header_bar_new();
|
||||
gtk_header_bar_set_show_title_buttons(GTK_HEADER_BAR(dialog_header), FALSE);
|
||||
box_header = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_halign(box_header, GTK_ALIGN_CENTER);
|
||||
button_delete = gtk_button_new_with_label("delete");
|
||||
button_cancel = gtk_button_new_with_label("cancel");
|
||||
gtk_box_append(GTK_BOX(box_header), button_delete);
|
||||
gtk_box_append(GTK_BOX(box_header), button_cancel);
|
||||
gtk_header_bar_set_title_widget(GTK_HEADER_BAR(dialog_header), box_header);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "");
|
||||
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
|
||||
gtk_window_set_default_size(GTK_WINDOW(dialog), 50, 50);
|
||||
|
||||
// add label to dialog content area
|
||||
content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
gtk_widget_set_halign(content_area, GTK_ALIGN_CENTER);
|
||||
char *label_text = malloc(2048);
|
||||
strcpy(label_text, "this will delete:\n");
|
||||
strcat(label_text, gtk_label_get_text(GTK_LABEL(label_selected)));
|
||||
strcat(label_text, "\nare you sure?");
|
||||
label_sure = gtk_label_new(label_text);
|
||||
free(label_text);
|
||||
gtk_label_set_justify(GTK_LABEL(label_sure), GTK_JUSTIFY_CENTER);
|
||||
gtk_box_append(GTK_BOX(content_area), label_sure);
|
||||
|
||||
// button actions
|
||||
g_signal_connect(button_delete, "clicked", G_CALLBACK(delete_entry), 0);
|
||||
g_signal_connect_swapped(button_delete, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
g_signal_connect_swapped(button_cancel, "clicked", G_CALLBACK(gtk_window_close), dialog);
|
||||
|
||||
gtk_window_set_titlebar(GTK_WINDOW(dialog), dialog_header);
|
||||
gtk_widget_show(dialog);
|
||||
}
|
||||
|
||||
static void activate(GtkApplication* app) {
|
||||
GtkWidget *window, *header_bar; // main window and header bar
|
||||
GtkWidget *button_sync, *button_unlock; // header bar buttons
|
||||
GtkWidget *stack, *stack_switcher; GtkStackPage *page_info; // stack widgets
|
||||
GtkWidget *box_info, *sshyp_logo, *label_home1; // info page widgets
|
||||
GtkWidget *box_browse_page, *box_browse_controls; // browse page boxes
|
||||
GtkWidget *button_shear, *button_read, *button_edit, *button_copy; // browse buttons
|
||||
GtkWidget *scrollable; // scrollable entry list container
|
||||
|
||||
window = gtk_application_window_new(app);
|
||||
gtk_window_set_title(GTK_WINDOW(window), "");
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 360, 720);
|
||||
|
||||
header_bar = gtk_header_bar_new();
|
||||
gtk_header_bar_set_show_title_buttons(GTK_HEADER_BAR(header_bar), FALSE);
|
||||
|
||||
// !!start main stack stuff!!
|
||||
|
||||
// create the stack
|
||||
stack = gtk_stack_new();
|
||||
gtk_stack_set_transition_type(GTK_STACK(stack), GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
|
||||
|
||||
// attach the stack to the main window
|
||||
gtk_window_set_child(GTK_WINDOW(window), stack);
|
||||
|
||||
// browse
|
||||
button_shear = gtk_button_new_from_icon_name("edit-delete");
|
||||
gtk_widget_set_hexpand(button_shear, FALSE);
|
||||
gtk_widget_set_size_request(button_shear, 50, -1);
|
||||
g_signal_connect_swapped(button_shear, "clicked", G_CALLBACK(are_they_sure), window);
|
||||
button_read = gtk_button_new_from_icon_name("mail-read");
|
||||
gtk_widget_set_hexpand(button_read, TRUE);
|
||||
button_edit = gtk_button_new_from_icon_name("document-edit");
|
||||
gtk_widget_set_hexpand(button_edit, TRUE);
|
||||
g_signal_connect(button_edit, "clicked", G_CALLBACK(copy_edit_field_prompt), (gpointer *) window);
|
||||
button_copy = gtk_button_new_from_icon_name("edit-copy");
|
||||
gtk_widget_set_hexpand(button_copy, TRUE);
|
||||
g_signal_connect(button_copy, "clicked", G_CALLBACK(copy_edit_field_prompt), (gpointer *) window);
|
||||
box_browse_page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
label_selected = gtk_label_new("no entry selected");
|
||||
gtk_widget_set_hexpand(label_selected, TRUE);
|
||||
gtk_widget_set_halign(label_selected, GTK_ALIGN_CENTER);
|
||||
box_browse_controls = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_valign(box_browse_controls, GTK_ALIGN_START);
|
||||
gtk_widget_set_size_request(box_browse_controls, -1, 50);
|
||||
gtk_box_append(GTK_BOX(box_browse_controls), button_shear);
|
||||
gtk_box_append(GTK_BOX(box_browse_controls), button_read);
|
||||
gtk_box_append(GTK_BOX(box_browse_controls), button_edit);
|
||||
gtk_box_append(GTK_BOX(box_browse_controls), button_copy);
|
||||
gtk_box_append(GTK_BOX(box_browse_page), label_selected);
|
||||
gtk_box_append(GTK_BOX(box_browse_page), box_browse_controls);
|
||||
|
||||
// !!start scrollable list!!
|
||||
scrollable = gtk_scrolled_window_new();
|
||||
list_box = (GtkListBox *) gtk_list_box_new();
|
||||
gtk_widget_set_vexpand(GTK_WIDGET(list_box), TRUE);
|
||||
|
||||
entry_list_gen();
|
||||
|
||||
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrollable), GTK_WIDGET(list_box));
|
||||
// !!end scrollable list!!
|
||||
|
||||
gtk_box_append(GTK_BOX(box_browse_page), GTK_WIDGET(scrollable));
|
||||
|
||||
// info
|
||||
box_info = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
|
||||
sshyp_logo = gtk_image_new_from_file("PLACEHOLDER");
|
||||
gtk_image_set_pixel_size(GTK_IMAGE(sshyp_logo), 300);
|
||||
label_home1 = gtk_label_new("password pasture\nexperimental gui client for sshyp");
|
||||
gtk_label_set_justify(GTK_LABEL(label_home1), GTK_JUSTIFY_CENTER);
|
||||
gtk_label_set_markup(GTK_LABEL(label_home1), "<span size='large'><b>password pasture</b></span>\n<span size='small'>experimental gui client for sshyp</span>");
|
||||
gtk_box_append(GTK_BOX(box_info), sshyp_logo);
|
||||
gtk_box_append(GTK_BOX(box_info), label_home1);
|
||||
|
||||
stack_switcher = gtk_stack_switcher_new();
|
||||
page_info = gtk_stack_add_titled(GTK_STACK(stack), box_info, "info", "info");
|
||||
gtk_stack_page_set_icon_name(GTK_STACK_PAGE(page_info), "help-about");
|
||||
gtk_stack_add_titled(GTK_STACK(stack), box_browse_page, "browse", "browse");
|
||||
gtk_stack_switcher_set_stack(GTK_STACK_SWITCHER(stack_switcher), GTK_STACK(stack));
|
||||
gtk_header_bar_pack_start(GTK_HEADER_BAR(header_bar), stack_switcher);
|
||||
|
||||
// !!end main stack stuff!!
|
||||
|
||||
// header bar buttons
|
||||
button_sync = gtk_button_new_from_icon_name("view-refresh");
|
||||
g_signal_connect(button_sync, "clicked", G_CALLBACK(sshyp_sync), 0);
|
||||
gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button_sync);
|
||||
|
||||
button_unlock = gtk_button_new_from_icon_name("changes-allow");
|
||||
g_signal_connect_swapped(button_unlock, "clicked", G_CALLBACK(password_prompt), window);
|
||||
gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button_unlock);
|
||||
|
||||
//GtkWidget *button_debug = gtk_button_new_from_icon_name("applications-science");
|
||||
//g_signal_connect(button_debug, "clicked", G_CALLBACK(0), 0);
|
||||
//gtk_header_bar_pack_end(GTK_HEADER_BAR(header_bar), button_debug);
|
||||
|
||||
gtk_window_set_titlebar(GTK_WINDOW(window), header_bar);
|
||||
gtk_widget_show(window);
|
||||
}
|
||||
|
||||
int main(int argc,
|
||||
char **argv) {
|
||||
GtkApplication *app = gtk_application_new("org.rwinkhart.sshyp", G_APPLICATION_FLAGS_NONE);
|
||||
g_signal_connect(app, "activate", G_CALLBACK(activate), 0);
|
||||
int status = g_application_run(G_APPLICATION(app), argc, argv);
|
||||
g_object_unref(app);
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
arch: base-devel gtk4 cmake make gcc
|
||||
|
||||
alpine: build-base gtk4.0 gtk4.0-dev cmake make gcc binutils abuild
|
||||
Executable → Regular
@@ -1,22 +1,18 @@
|
||||
#!/bin/python3
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from base64 import b32decode
|
||||
from hmac import new as new_mac
|
||||
from os import environ, path, system, uname
|
||||
from os import environ, listdir, path, uname
|
||||
from pathlib import Path
|
||||
from shutil import rmtree
|
||||
from sshync import get_profile
|
||||
from sshyp import decrypt, entry_list_gen, shm_gen
|
||||
from struct import pack, unpack
|
||||
from sshyp import decrypt, entry_list_gen, shm_gen, whitelist_verify
|
||||
from subprocess import PIPE, Popen, run
|
||||
from sys import argv, exit as s_exit
|
||||
from time import sleep, strftime, time
|
||||
try:
|
||||
from steam.guard import generate_twofactor_code as steam_totp
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
pass
|
||||
|
||||
|
||||
def totp(_secret, _algo, _digits, _period): # uses provided information to generate a standard totp key
|
||||
from hmac import new as new_mac
|
||||
from struct import pack, unpack
|
||||
_secret = b32decode(_secret.upper() + '=' * ((8 - len(_secret)) % 8))
|
||||
_counter = pack('>Q', int(time() / _period))
|
||||
_mac = new_mac(_secret, _counter, _algo).digest()
|
||||
@@ -26,11 +22,15 @@ def totp(_secret, _algo, _digits, _period): # uses provided information to gene
|
||||
|
||||
|
||||
def mfa_read_shortcut(): # reads and extracts MFA info from the user-specified sshyp entry
|
||||
from shutil import rmtree
|
||||
if not Path(f"{directory}{argument}.gpg").exists():
|
||||
print(f"\n\u001b[38;5;9merror: entry ({argument}) does not exist\u001b[0m\n")
|
||||
s_exit(1)
|
||||
_shm_folder, _shm_entry = shm_gen()
|
||||
decrypt(directory + argument, _shm_folder, _shm_entry, gpg)
|
||||
if quick_unlock_enabled == 'y':
|
||||
decrypt(directory + argument, _shm_folder, _shm_entry, whitelist_verify(port, username_ssh, ip, device_id))
|
||||
else:
|
||||
decrypt(directory + argument, _shm_folder, _shm_entry, False)
|
||||
try:
|
||||
_mfa_data = open(f"{path.expanduser('~/.config/sshyp/tmp/')}{_shm_folder}/{_shm_entry}", 'r').readlines()
|
||||
_type = _mfa_data[4].split('otpauth://')[1].split('/')[0]
|
||||
@@ -54,14 +54,15 @@ if __name__ == '__main__':
|
||||
s_exit(1)
|
||||
|
||||
# user data fetcher
|
||||
device_id = listdir(path.expanduser('~/.config/sshyp/devices'))[0]
|
||||
quick_unlock_enabled = open(path.expanduser('~/.config/sshyp/sshyp-data')).readlines()[3].rstrip()
|
||||
ssh_info = get_profile(path.expanduser('~/.config/sshyp/sshyp.sshync'))
|
||||
directory = str(ssh_info[3].replace('\n', ''))
|
||||
if uname()[0] == 'Haiku': # set proper gpg command for OS
|
||||
gpg = 'gpg --pinentry-mode loopback'
|
||||
else:
|
||||
gpg = 'gpg'
|
||||
username_ssh = str(ssh_info[0].rstrip())
|
||||
ip = str(ssh_info[1].rstrip())
|
||||
port = str(ssh_info[2].rstrip())
|
||||
directory = str(ssh_info[3].rstrip())
|
||||
|
||||
# main process; runs functions to generate MFA key, then continuously copies up-to-date MFA key to clipboard
|
||||
# main process: runs functions to generate MFA key, then continuously copies up-to-date MFA key to clipboard
|
||||
try:
|
||||
if len(argument_list) == 1:
|
||||
entry_list_gen()
|
||||
@@ -75,18 +76,19 @@ if __name__ == '__main__':
|
||||
if copied is None:
|
||||
copied = 1
|
||||
if mfa_data[0] == 'steam':
|
||||
from steam.guard import generate_twofactor_code as steam_totp
|
||||
_mfa_key = steam_totp(b32decode(mfa_data[1]))
|
||||
else:
|
||||
_mfa_key = totp(mfa_data[1], mfa_data[2], mfa_data[3], mfa_data[4])
|
||||
if uname()[0] == 'Haiku': # Haiku clipboard detection
|
||||
system(f"clipboard -c '{_mfa_key}'")
|
||||
if 'WAYLAND_DISPLAY' in environ: # Wayland clipboard detection
|
||||
run(['wl-copy', _mfa_key])
|
||||
elif uname()[0] == 'Haiku': # Haiku clipboard detection
|
||||
run(['clipboard', '-c', _mfa_key])
|
||||
elif Path("/data/data/com.termux").exists(): # Termux (Android) clipboard detection
|
||||
system(f"termux-clipboard-set '{_mfa_key}'")
|
||||
elif environ.get('WAYLAND_DISPLAY') == 'wayland-0': # Wayland clipboard detection
|
||||
system(f"wl-copy '{_mfa_key}'")
|
||||
run(['termux-clipboard-set', _mfa_key])
|
||||
else: # X11 clipboard detection
|
||||
system(f"echo -n '{_mfa_key}' | xclip -sel c")
|
||||
run(['xclip', '-sel', 'c'], stdin=Popen(['echo', '-n', _mfa_key], stdout=PIPE).stdout)
|
||||
sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
print('\n')
|
||||
s_exit()
|
||||
s_exit(0)
|
||||
+174
-142
@@ -1,39 +1,81 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script packages sshyp-mfa (from source) for various UNIX(-like) environments.
|
||||
# Dependencies (Arch Linux): dpkg (packaging for Debian/Termux), freebsd-pkg (packaging for FreeBSD)
|
||||
# Dependencies (Fedora) (can only package for self): rpmdevtools
|
||||
# NOTE It is recommended to instead use the latest officially packaged and tagged release.
|
||||
|
||||
echo -e '\nOptions (please enter the number only):'
|
||||
echo -e '\nPackage Formats:\n\n1. Haiku\n2. Debian&Ubuntu Linux\n3. Fedora Linux\n4. FreeBSD\n5. Termux\n6. Generic (used for PKGBUILD/APKBUILD)'
|
||||
echo -e '\nBuild Scripts:\n\n7. Arch Linux (PKGBUILD)'
|
||||
echo -e '\nOther:\n\n8. All (generates all distribution packages (excluding Haiku and Fedora, as these must be packaged on their respective distributions) and build scripts)\n'
|
||||
read -n 1 -r -p "Distribution: " distro
|
||||
|
||||
echo -e '\n\nThe value entered in this field will only affect the version reported to the package manager. The latest source is used regardless.\n'
|
||||
read -r -p "Version number: " version
|
||||
|
||||
echo -e '\nThe value entered in this field will only affect the revision number for build scripts.\n'
|
||||
read -r -p "Revision number: " revision
|
||||
|
||||
if [ "$distro" == "7" ] || [ "$distro" == "8" ]; then
|
||||
echo -e '\nOptions (please enter the number only):'
|
||||
echo -e '\n1. GitHub Release Tag\n2. Local\n'
|
||||
read -r -p "Source (for build scripts): " source
|
||||
|
||||
if [ "$source" == "1" ]; then
|
||||
source='https://github.com/rwinkhart/sshyp-labs/releases/download/v$pkgver/sshyp-mfa-$pkgver.tar.xz'
|
||||
else
|
||||
source=local://sshyp-mfa-"$version".tar.xz
|
||||
fi
|
||||
version=$(sed -n '1{p;q}' ../version)
|
||||
if [ -z "$2" ]; then
|
||||
revision=1
|
||||
else
|
||||
revision="$2"
|
||||
fi
|
||||
|
||||
mkdir -p packages
|
||||
_create_generic() {
|
||||
echo -e '\npackaging as generic...\n'
|
||||
mkdir -p output/generictemp/usr/{bin,lib/sshyp,share/man/man1}
|
||||
cp -r lib/. output/generictemp/usr/lib/sshyp/
|
||||
ln -s /usr/lib/sshyp/sshyp-mfa.py output/generictemp/usr/bin/sshyp-mfa
|
||||
cp -r share output/generictemp/usr/
|
||||
cp extra/manpage output/generictemp/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip output/generictemp/usr/share/man/man1/sshyp-mfa.1
|
||||
tar -C output/generictemp -cvJf output/sshyp-mfa-"$version".tar.xz usr/
|
||||
rm -rf output/generictemp
|
||||
sha512="$(sha512sum output/sshyp-mfa-"$version".tar.xz | awk '{print $1;}')"
|
||||
echo -e "\nsha512 sum:\n$sha512"
|
||||
echo -e "\ngeneric packaging complete\n"
|
||||
} &&
|
||||
|
||||
if [ "$distro" == "1" ]; then
|
||||
echo -e '\nPackaging for Haiku...\n'
|
||||
mkdir -p packages/haikutemp/documentation/{man/man1,packages/sshyp-mfa}
|
||||
_create_pkgbuild() {
|
||||
source='https://github.com/rwinkhart/sshyp-labs/releases/download/v$pkgver/sshyp-mfa-$pkgver.tar.xz'
|
||||
echo -e '\ngenerating PKGBUILD...'
|
||||
echo "# Maintainer: Randall Winkhart <idgr at tutanota dot com>
|
||||
pkgname=sshyp-mfa
|
||||
pkgver="$version"
|
||||
pkgrel="$revision"
|
||||
pkgdesc='An MFA (TOTP/Steam) key generator for the sshyp password manager'
|
||||
url='https://github.com/rwinkhart/sshyp-labs'
|
||||
arch=('any')
|
||||
license=('GPL-3.0-only')
|
||||
depends=(sshyp)
|
||||
source=(\""$source"\")
|
||||
sha512sums=('"$sha512"')
|
||||
|
||||
package() {
|
||||
|
||||
tar xf sshyp-mfa-"\"\$pkgver\"".tar.xz -C "\"\${pkgdir}\""
|
||||
|
||||
}
|
||||
" > output/PKGBUILD
|
||||
echo -e "\nPKGBUILD generated\n"
|
||||
} &&
|
||||
|
||||
_create_apkbuild() {
|
||||
source='https://github.com/rwinkhart/sshyp-labs/releases/download/v$pkgver/sshyp-mfa-$pkgver.tar.xz'
|
||||
echo -e '\ngenerating APKBUILD...'
|
||||
echo "# Maintainer: Randall Winkhart <idgr@tutanota.com>
|
||||
pkgname=sshyp-mfa
|
||||
pkgver="$version"
|
||||
pkgrel="$revision"
|
||||
pkgdesc='An MFA (TOTP/Steam) key generator for the sshyp password manager'
|
||||
options=!check
|
||||
url='https://github.com/rwinkhart/sshyp-labs'
|
||||
arch='noarch'
|
||||
license='GPL-3.0-only'
|
||||
depends='sshyp'
|
||||
source=\""$source"\"
|
||||
|
||||
package() {
|
||||
mkdir -p "\"\$pkgdir\""
|
||||
cp -r "\"\$srcdir/usr/"\" "\"\$pkgdir\""
|
||||
}
|
||||
|
||||
sha512sums=\"
|
||||
"$sha512' 'sshyp-mfa-\"\$pkgver\".tar.xz"
|
||||
\"
|
||||
" > output/APKBUILD
|
||||
echo -e "\nAPKBUILD generated\n"
|
||||
} &&
|
||||
|
||||
_create_hpkg() {
|
||||
echo -e '\npackaging for Haiku...\n'
|
||||
mkdir -p output/haikutemp/{bin,lib/sshyp,documentation/{man/man1,packages/sshyp-mfa}}
|
||||
echo "name sshypmfa
|
||||
version "$version"-"$revision"
|
||||
architecture any
|
||||
@@ -42,7 +84,7 @@ description \"sshyp-mfa is an extension for the sshyp password manager that rea
|
||||
packager \"Randall Winkhart <idgr at tutanota dot com>\"
|
||||
vendor \"Randall Winkhart\"
|
||||
licenses {
|
||||
\"GNU GPL v3\"
|
||||
\"GNU GPL v3\"
|
||||
}
|
||||
copyrights {
|
||||
\"2021-2022 Randall Winkhart\"
|
||||
@@ -53,129 +95,108 @@ provides {
|
||||
}
|
||||
requires {
|
||||
sshyp
|
||||
python3
|
||||
}
|
||||
urls {
|
||||
\"https://github.com/rwinkhart/sshyp-labs\"
|
||||
}
|
||||
" > packages/haikutemp/.PackageInfo
|
||||
cp -r bin packages/haikutemp/
|
||||
ln -s /bin/sshyp-mfa.py packages/haikutemp/bin/sshyp-mfa
|
||||
cp -r share/licenses/sshyp-mfa/ packages/haikutemp/documentation/packages/
|
||||
cp extra/manpage packages/haikutemp/documentation/man/man1/sshyp-mfa.1
|
||||
gzip packages/haikutemp/documentation/man/man1/sshyp-mfa.1
|
||||
cd packages/haikutemp
|
||||
" > output/haikutemp/.PackageInfo
|
||||
cp -r lib/. output/haikutemp/lib/sshyp/
|
||||
sed -i '1 s/.*/#!\/bin\/env\ python3.10/' output/haikutemp/lib/sshyp/sshyp-mfa.py
|
||||
ln -s /system/lib/sshyp/sshyp-mfa.py output/haikutemp/bin/sshyp-mfa
|
||||
cp -r share/licenses/sshyp-mfa/. output/haikutemp/documentation/packages/sshyp-mfa/
|
||||
cp extra/manpage output/haikutemp/documentation/man/man1/sshyp-mfa.1
|
||||
gzip output/haikutemp/documentation/man/man1/sshyp-mfa.1
|
||||
cd output/haikutemp
|
||||
package create -b sshyp-mfa-"$version"-"$revision"_all.hpkg
|
||||
package add sshyp-mfa-"$version"-"$revision"_all.hpkg bin documentation
|
||||
package add sshyp-mfa-"$version"-"$revision"_all.hpkg bin lib documentation
|
||||
cd ../..
|
||||
mv packages/haikutemp/sshyp-mfa-"$version"-"$revision"_all.hpkg packages/
|
||||
rm -rf packages/haikutemp
|
||||
echo -e "\nHaiku packaging complete.\n"
|
||||
fi
|
||||
mv output/haikutemp/sshyp-mfa-"$version"-"$revision"_all.hpkg output/
|
||||
rm -rf output/haikutemp
|
||||
echo -e "\nHaiku packaging complete\n"
|
||||
} &&
|
||||
|
||||
if [ "$distro" == "2" ] || [ "$distro" == "8" ]; then
|
||||
echo -e '\nPackaging for Debian...\n'
|
||||
mkdir -p packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/{DEBIAN,usr/share/man/man1}
|
||||
_create_deb() {
|
||||
echo -e '\npackaging for Debian/Ubuntu...\n'
|
||||
mkdir -p output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/{DEBIAN,usr/{lib/sshyp,bin,share/man/man1}}
|
||||
echo "Package: sshyp-mfa
|
||||
Version: $version
|
||||
Section: utils
|
||||
Architecture: all
|
||||
Maintainer: Randall Winkhart <idgr at tutanota dot com>
|
||||
Description: An MFA (TOTP/Steam) key generator for the sshyp password manager
|
||||
Depends: sshyp, python3
|
||||
Depends: sshyp
|
||||
Priority: optional
|
||||
Installed-Size: 100
|
||||
" > packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/DEBIAN/control
|
||||
cp -r bin packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/
|
||||
ln -s /usr/bin/sshyp-mfa.py packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/bin/sshyp-mfa
|
||||
cp -r share packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/
|
||||
cp extra/manpage packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/share/man/man1/sshyp-mfa.1
|
||||
dpkg-deb --build --root-owner-group packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all/
|
||||
mv packages/debiantemp/sshyp-mfa_"$version"-"$revision"_all.deb packages/
|
||||
rm -rf packages/debiantemp
|
||||
echo -e "\nDebian packaging complete.\n"
|
||||
fi
|
||||
" > output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/DEBIAN/control
|
||||
cp -r lib/. output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/lib/sshyp/
|
||||
ln -s /usr/lib/sshyp/sshyp-mfa.py output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/bin/sshyp-mfa
|
||||
cp -r share output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/
|
||||
cp extra/manpage output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/usr/share/man/man1/sshyp-mfa.1
|
||||
dpkg-deb --build --root-owner-group output/debiantemp/sshyp-mfa_"$version"-"$revision"_all/
|
||||
mv output/debiantemp/sshyp-mfa_"$version"-"$revision"_all.deb output/
|
||||
rm -rf output/debiantemp
|
||||
echo -e "\nDebian/Ubuntu packaging complete\n"
|
||||
} &&
|
||||
|
||||
if [ "$distro" == "5" ] || [ "$distro" == "8" ]; then
|
||||
echo -e '\nPackaging for Termux...\n'
|
||||
mkdir -p packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/{data/data/com.termux/files/usr/share/man/man1,DEBIAN}
|
||||
_create_termux() {
|
||||
echo -e '\npackaging for Termux...\n'
|
||||
mkdir -p output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/{DEBIAN,data/data/com.termux/files/usr/{lib/sshyp,bin,share/man/man1}}
|
||||
echo "Package: sshyp-mfa
|
||||
Version: $version
|
||||
Section: utils
|
||||
Architecture: all
|
||||
Maintainer: Randall Winkhart <idgr at tutanota dot com>
|
||||
Description: An MFA (TOTP/Steam) key generator for the sshyp password manager
|
||||
Depends: sshyp, python3
|
||||
Depends: sshyp
|
||||
Priority: optional
|
||||
Installed-Size: 100
|
||||
" > packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/DEBIAN/control
|
||||
cp -r bin packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/
|
||||
ln -s /data/data/com.termux/files/usr/bin/sshyp-mfa.py packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/bin/sshyp-mfa
|
||||
cp -r share packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/
|
||||
cp extra/manpage packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp-mfa.1
|
||||
dpkg-deb --build --root-owner-group packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/
|
||||
mv packages/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux.deb packages/
|
||||
rm -rf packages/termuxtemp
|
||||
echo -e "\nTermux packaging complete.\n"
|
||||
fi
|
||||
" > output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/DEBIAN/control
|
||||
cp -r lib/. output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/lib/sshyp/
|
||||
ln -s /data/data/com.termux/files/usr/lib/sshyp/sshyp-mfa.py output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/bin/sshyp-mfa
|
||||
cp -r share output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/
|
||||
cp extra/manpage output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/data/data/com.termux/files/usr/share/man/man1/sshyp-mfa.1
|
||||
dpkg-deb --build --root-owner-group output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux/
|
||||
mv output/termuxtemp/sshyp-mfa_"$version"-"$revision"_all_termux.deb output/
|
||||
rm -rf output/termuxtemp
|
||||
echo -e "\nTermux packaging complete\n"
|
||||
} &&
|
||||
|
||||
if [ "$distro" == "3" ] || [ "$distro" == "4" ] || [ "$distro" == "6" ] || [ "$distro" == "7" ] || [ "$distro" == "8" ]; then
|
||||
echo -e '\nPackaging as generic...\n'
|
||||
mkdir -p packages/generictemp/usr/share/man/man1
|
||||
cp -r bin packages/generictemp/usr/
|
||||
ln -s /usr/bin/sshyp-mfa.py packages/generictemp/usr/bin/sshyp-mfa
|
||||
cp -r share packages/generictemp/usr/
|
||||
cp extra/manpage packages/generictemp/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip packages/generictemp/usr/share/man/man1/sshyp-mfa.1
|
||||
tar -C packages/generictemp -cvf packages/sshyp-mfa-"$version".tar.xz usr/
|
||||
rm -rf packages/generictemp
|
||||
sha512="$(sha512sum packages/sshyp-mfa-"$version".tar.xz | awk '{print $1;}')"
|
||||
echo -e "\nsha512 sum:\n$sha512"
|
||||
echo -e "\nGeneric packaging complete.\n"
|
||||
fi
|
||||
|
||||
if [ "$distro" == "3" ]; then
|
||||
echo -e '\nPackaging for Fedora...\n'
|
||||
_create_rpm() {
|
||||
echo -e '\npackaging for Fedora...\n'
|
||||
rm -rf ~/rpmbuild
|
||||
rpmdev-setuptree
|
||||
cp packages/sshyp-mfa-"$version".tar.xz ~/rpmbuild/SOURCES
|
||||
cp output/sshyp-mfa-"$version".tar.xz ~/rpmbuild/SOURCES
|
||||
echo "Name: sshyp-mfa
|
||||
Version: "$version"
|
||||
Release: "$revision"
|
||||
Summary: An MFA (TOTP/Steam) key generator for the sshyp password manager
|
||||
BuildArch: noarch
|
||||
|
||||
License: GPLv3
|
||||
License: GPL-3.0-only
|
||||
URL: https://github.com/rwinkhart/sshyp-labs
|
||||
Source0: sshyp-mfa-"$version".tar.xz
|
||||
|
||||
Requires: sshyp python
|
||||
|
||||
Requires: sshyp
|
||||
%description
|
||||
sshyp-mfa is an extension for the sshyp password manager that reads MFA data from sshyp entries and generates generic TOTP and Steam keys.
|
||||
|
||||
%install
|
||||
tar xf %{_sourcedir}/sshyp-mfa-"$version".tar.xz -C %{_sourcedir}
|
||||
cp -r %{_sourcedir}/usr %{buildroot}
|
||||
|
||||
%files
|
||||
/usr/bin/sshyp-mfa
|
||||
/usr/bin/sshyp-mfa.py
|
||||
/usr/lib/sshyp/sshyp-mfa.py
|
||||
%license /usr/share/licenses/sshyp-mfa/license
|
||||
%doc /usr/share/man/man1/sshyp-mfa.1.gz
|
||||
" > ~/rpmbuild/SPECS/sshyp-mfa.spec
|
||||
rpmbuild -bb ~/rpmbuild/SPECS/sshyp-mfa.spec
|
||||
mv ~/rpmbuild/RPMS/noarch/* packages/
|
||||
mv ~/rpmbuild/RPMS/noarch/* output/
|
||||
rm -rf ~/rpmbuild
|
||||
echo -e "\nFedora packaging complete.\n"
|
||||
fi
|
||||
echo -e "\nFedora packaging complete\n"
|
||||
} &&
|
||||
|
||||
if [ "$distro" == "4" ] || [ "$distro" == "8" ]; then
|
||||
echo -e '\nPackaging for FreeBSD...\n'
|
||||
mkdir -p packages/FreeBSDtemp/bin
|
||||
tar xf packages/sshyp-mfa-"$version".tar.xz -C packages/FreeBSDtemp
|
||||
_create_freebsd_pkg() {
|
||||
echo -e '\npackaging for FreeBSD...\n'
|
||||
mkdir -p output/freebsdtemp/usr/{lib/sshyp,bin,share/man/man1}
|
||||
echo "name: sshyp-mfa
|
||||
version: \""$version"\"
|
||||
abi = \"FreeBSD:13:*\";
|
||||
@@ -190,42 +211,53 @@ prefix: /
|
||||
\"sshyp\" : {
|
||||
\"origin\" : \"security/sshyp\"
|
||||
},
|
||||
\"python\" : {
|
||||
\"origin\" : \"lang/python\"
|
||||
},
|
||||
},
|
||||
" > packages/FreeBSDtemp/+MANIFEST
|
||||
" > output/freebsdtemp/+MANIFEST
|
||||
echo "/usr/bin/sshyp-mfa
|
||||
/usr/bin/sshyp-mfa.py
|
||||
/usr/lib/sshyp/sshyp-mfa.py
|
||||
/usr/share/licenses/sshyp-mfa/license
|
||||
/usr/share/man/man1/sshyp-mfa.1.gz
|
||||
" > packages/FreeBSDtemp/plist
|
||||
pkg create -m packages/FreeBSDtemp/ -r packages/FreeBSDtemp/ -p packages/FreeBSDtemp/plist -o packages/
|
||||
rm -rf packages/FreeBSDtemp
|
||||
echo -e "\nFreeBSD packaging complete.\n"
|
||||
fi
|
||||
" > output/freebsdtemp/plist
|
||||
cp -r lib/. output/freebsdtemp/usr/lib/sshyp/
|
||||
ln -s /usr/lib/sshyp/sshyp-mfa.py output/freebsdtemp/usr/bin/sshyp-mfa
|
||||
cp -r share output/freebsdtemp/usr/
|
||||
cp extra/manpage output/freebsdtemp/usr/share/man/man1/sshyp-mfa.1
|
||||
gzip output/freebsdtemp/usr/share/man/man1/sshyp-mfa.1
|
||||
pkg create -m output/freebsdtemp/ -r output/freebsdtemp/ -p output/freebsdtemp/plist -o output/
|
||||
rm -rf output/freebsdtemp
|
||||
echo -e "\nFreeBSD packaging complete\n"
|
||||
} &&
|
||||
|
||||
if [ "$distro" == "7" ] || [ "$distro" == "8" ]; then
|
||||
echo -e '\nGenerating PKGBUILD...'
|
||||
echo "# Maintainer: Randall Winkhart <idgr at tutanota dot com>
|
||||
|
||||
pkgname=sshyp-mfa
|
||||
pkgver="$version"
|
||||
pkgrel="$revision"
|
||||
pkgdesc='An MFA (TOTP/Steam) key generator for the sshyp password manager'
|
||||
url='https://github.com/rwinkhart/sshyp-labs'
|
||||
arch=('any')
|
||||
license=('GPL3')
|
||||
depends=(sshyp python)
|
||||
|
||||
source=(\""$source"\")
|
||||
sha512sums=('"$sha512"')
|
||||
|
||||
package() {
|
||||
|
||||
tar xf sshyp-mfa-"\"\$pkgver\"".tar.xz -C "\"\${pkgdir}\""
|
||||
|
||||
}
|
||||
" > packages/PKGBUILD
|
||||
echo -e "\nPKGBUILD generated.\n"
|
||||
if [ "$1" == "generic" ]; then # build scripts
|
||||
_create_generic
|
||||
elif [ "$1" == "pkgbuild" ]; then
|
||||
_create_generic
|
||||
_create_pkgbuild
|
||||
elif [ "$1" == "apkbuild" ]; then
|
||||
_create_generic
|
||||
_create_apkbuild
|
||||
elif [ "$1" == "haiku" ]; then # distribution packages
|
||||
_create_hpkg
|
||||
elif [ "$1" == "debian" ]; then
|
||||
_create_deb
|
||||
elif [ "$1" == "termux" ]; then
|
||||
_create_termux
|
||||
elif [ "$1" == "fedora" ]; then
|
||||
_create_generic
|
||||
_create_rpm
|
||||
elif [ "$1" == "freebsd" ]; then
|
||||
_create_freebsd_pkg
|
||||
elif [ "$1" == "buildable-arch" ]; then
|
||||
_create_generic
|
||||
_create_pkgbuild
|
||||
_create_apkbuild
|
||||
if [[ $(pacman -Q dpkg) == "dpkg"* ]]; then
|
||||
_create_deb
|
||||
_create_termux
|
||||
fi
|
||||
if [[ "$(pacman -Q freebsd-pkg)" == "freebsd-pkg"* ]]; then
|
||||
_create_freebsd_pkg
|
||||
fi
|
||||
else
|
||||
echo -e '\nusage: package.sh [target] <revision>\n\ntargets:\n mainline: pkgbuild apkbuild haiku fedora debian\n experimental: freebsd termux\n other: buildable-arch\n'
|
||||
fi
|
||||
|
||||
Executable → Regular
Executable → Regular
+3
-4
@@ -2,9 +2,8 @@
|
||||
Copyright (C) 2022 Randall Winkhart idgr@tutanota.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
it under the terms of version 3 (only) of the GNU General Public License
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -12,4 +11,4 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Reference in New Issue
Block a user