#!/usr/bin/newlisp # # Blowfish-cbc encyption with: # openssl enc -e -a -salt -bf -in data.txt -out data.pwd -pass pass:test # # Simple frontend for SSL to keep passwords in a safe place. # # July 15, 2006 - PvE. GPL. # - First release 1.0 # # January 10, 2008 - version 1.1 # - Replaced buttons for stock buttons # - Improved embedded GTK search routine # - Added gridlines available since GTK 2.10 # - Set password icon in Window bars # # December 19, 2008 - version 1.2 # - Improved dynamic symbol creation to prevent overwriting existing symbols # - Compliant with newLisp 10, also requirement now # # December 28, 2008 - version 1.2a # - Adapted for MacOSX # - Fixed crash with redefinition, must use INT instead of LONG #-------------------------------------------------------------------------------------------------------------------------------- # Import GTK-server and create global symbols for GTK function names (case ostype ("Win32" (import "gtk-server.dll" "gtk")) ("OSX" (import "libgtk-server.dylib" "gtk")) (true (import "libgtk-server.so" "gtk"))) # Now try to find GTK-server configfile (set 'cfgfile (open "gtk-server.cfg" "read")) (when (not cfgfile) (set 'cfgfile (open "/usr/local/etc/gtk-server.cfg" "read")) (when (not cfgfile) (set 'cfgfile (open "/etc/gtk-server.cfg" "read")))) # No configfile? Exit (when (not cfgfile)(println "No GTK-server configfile found! Exiting...")(exit)) # Create global GTK symbols (while (read-line cfgfile) (when (and (starts-with (current-line) "FUNCTION_NAME") (regex "gtk_+|gdk_+|g_+" (current-line))) (set 'func (chop ((parse (current-line) " ") 2))) (set 'lb (append {(lambda()(setq s "} func {")(dolist (x (args))(setq s (string s " " x)))(get-string (gtk s)))})) (constant (global (sym func)) (eval-string lb)))) (close cfgfile) (set (global 'NULL) "NULL") #-------------------------------------------------------------------------------------------------------------------------------- (context 'GUI) #(gtk_server_cfg "-log=/tmp/password.lsp.log") # Main window (gtk_init NULL NULL) (setq mainwin (gtk_window_new 0)) (gtk_window_set_title mainwin {"Password manager v1.2a"}) (gtk_widget_set_size_request mainwin 550 450) (gtk_window_set_position mainwin 1) (gtk_window_set_icon_name mainwin "password") # Top panel (setq label (gtk_label_new {"Encryption string:"})) (setq entry (gtk_entry_new)) (gtk_entry_set_visibility entry 0) (setq filebutton (gtk_button_new_from_stock "gtk-open")) (setq frame1 (gtk_frame_new)) (gtk_frame_set_label frame1 {" Get file "}) (gtk_container_set_border_width frame1 5) # Setup list (gtk_server_redefine "gtk_list_store_new NONE WIDGET 4 INT INT INT INT") (setq iter (gtk_frame_new NULL)) (setq lst (gtk_list_store_new 3 64 64 64)) (setq tree (gtk_tree_view_new_with_model lst)) (gtk_server_connect tree "button-press-event" "tree 1") (gtk_tree_view_set_headers_clickable tree 1) (setq sel (gtk_tree_view_get_selection tree)) (setq column1 (gtk_tree_view_column_new_with_attributes "Instance" (gtk_cell_renderer_text_new) "text" 0 "NULL")) (gtk_tree_view_append_column tree column1) (gtk_tree_view_column_set_resizable column1 1) (gtk_tree_view_column_set_clickable column1 1) (setq column2 (gtk_tree_view_column_new_with_attributes "Userdata" (gtk_cell_renderer_text_new) "text" 1 "NULL")) (gtk_tree_view_append_column tree column2) (gtk_tree_view_column_set_resizable column2 1) (setq column3 (gtk_tree_view_column_new_with_attributes "Password" (gtk_cell_renderer_text_new) "text" 2 "NULL")) (gtk_tree_view_append_column tree column3) (gtk_tree_view_column_set_resizable column3 1) (setq sw (gtk_scrolled_window_new NULL NULL)) (gtk_scrolled_window_set_policy sw 1 1) (gtk_scrolled_window_set_shadow_type sw 1) (gtk_container_add sw tree) (gtk_tree_sortable_set_sort_column_id lst 0 0) (gtk_tree_view_set_grid_lines tree 3) # Setup middle panel (setq frame2 (gtk_frame_new)) (gtk_frame_set_label frame2 {" Passwords "}) (gtk_container_set_border_width frame2 5) # Setup lower panel (setq addbutton (gtk_button_new_from_stock "gtk-add")) (setq editbutton (gtk_button_new_from_stock "gtk-edit")) (setq delbutton (gtk_button_new_from_stock "gtk-delete")) (setq storebutton (gtk_button_new_from_stock "gtk-save")) (setq exitbutton (gtk_button_new_from_stock "gtk-quit")) # Setup statusbar (setq msg_bar (gtk_statusbar_new)) (setq msg_cid (gtk_statusbar_get_context_id msg_bar mainwin)) (if (= (last (sys-info)) 6) (gtk_statusbar_push msg_bar msg_cid (append {"GTK-server } (gtk_server_version) { on Win32"})) (gtk_statusbar_push msg_bar msg_cid (append {"GTK-server } (gtk_server_version) " on " (first (exec "uname -sr")) {"})) ) # Now arrange widgets on window using boxes (setq hbox1 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox1 8) (gtk_box_pack_start hbox1 label 0 0 1) (gtk_box_pack_start hbox1 entry 1 1 5) (gtk_box_pack_end hbox1 filebutton 0 0 1) (gtk_container_add frame1 hbox1) (setq hbox2 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox2 8) (gtk_box_pack_start hbox2 sw 1 1 1) (gtk_container_add frame2 hbox2) (setq hbox3 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox3 4) (gtk_box_pack_start hbox3 addbutton 0 0 1) (gtk_box_pack_start hbox3 editbutton 0 0 1) (gtk_box_pack_start hbox3 delbutton 0 0 1) (gtk_box_pack_end hbox3 exitbutton 0 0 1) (gtk_box_pack_end hbox3 storebutton 0 0 1) (setq vbox (gtk_vbox_new 0 0)) (gtk_box_pack_start vbox frame1 0 0 1) (gtk_box_pack_start vbox frame2 1 1 1) (gtk_box_pack_start vbox hbox3 0 0 1) (gtk_box_pack_start vbox msg_bar 0 0 1) (gtk_container_add mainwin vbox) # Show it all (gtk_widget_show_all mainwin) # Create error message (setq errorwin (gtk_message_dialog_new mainwin 0 3 2 {"Choose an entry first!"} "''")) (gtk_server_connect errorwin "delete-event" "delete_err") # Update statusbar (define (status_txt txt) (gtk_statusbar_pop msg_bar msg_cid) (gtk_statusbar_push msg_bar msg_cid (append {"} txt {"})) ) #-------------------------------------------------------------------------------------------------------------------------------- (context 'FILE) # Create fileselector (setq filewin (gtk_window_new 0)) (gtk_window_set_title filewin {"Choose file..."}) (gtk_window_set_transient_for filewin GUI:mainwin) (gtk_window_set_position filewin 4) (gtk_window_set_default_size filewin 650 500) (setq filsel (gtk_file_chooser_widget_new 0)) (setq filok (gtk_button_new_from_stock "gtk-ok")) (gtk_widget_set_size_request filok 100 30) (setq filcan (gtk_button_new_from_stock "gtk-cancel")) (gtk_widget_set_size_request filcan 100 30) (setq filfil1 (gtk_file_filter_new)) (gtk_file_filter_set_name filfil1 {"Password files - *.pwd"}) (gtk_file_filter_add_pattern filfil1 "*.pwd") (setq filfil2 (gtk_file_filter_new)) (gtk_file_filter_set_name filfil2 {"All files - *.*"}) (gtk_file_filter_add_pattern filfil2 "*") (gtk_file_chooser_add_filter filsel filfil1) (gtk_file_chooser_add_filter filsel filfil2) (setq filsep (gtk_hseparator_new)) # Arrange widgets on window (setq file_vbox (gtk_vbox_new 0 0)) (gtk_container_set_border_width file_vbox 5) (setq file_hbox (gtk_hbox_new 0 0)) (gtk_box_pack_start file_hbox filcan 0 0 1) (gtk_box_pack_end file_hbox filok 0 0 1) (gtk_box_pack_start file_vbox filsel 1 1 1) (gtk_box_pack_start file_vbox filsep 0 0 1) (gtk_box_pack_start file_vbox file_hbox 0 0 1) (gtk_container_add filewin file_vbox) (define (open_file, counter) (gtk_widget_hide filewin) (setq curname (gtk_file_chooser_get_filename filsel)) (replace "\\" curname "/") (if (and (file? curname) (not (directory? curname))) (begin (setq passwd (gtk_entry_get_text GUI:entry)) (gtk_list_store_clear GUI:lst) (setq out (exec (append "openssl enc -d -a -salt -bf -in " curname " -pass pass:" passwd " 2>&1"))) (if (and (= (out 0) "bad decrypt")(> (length out) 1)) (GUI:status_txt "ERROR: Wrong key!") (begin (setq counter 0) (dolist (x out) (gtk_list_store_append GUI:lst GUI:iter) (gtk_list_store_set GUI:lst GUI:iter 0 ((parse x " ") 0) -1) (gtk_list_store_set GUI:lst GUI:iter 1 ((parse x " ") 1) -1) (gtk_list_store_set GUI:lst GUI:iter 2 ((parse x " ") 2) -1) (push x All_Data -1) (inc counter) ) (sort All_Data) (GUI:status_txt (append "INFO: Data successfully loaded. There are " (string counter) " entries.")) ) ) ) ) ) #-------------------------------------------------------------------------------------------------------------------------------- (context 'EDIT) # Create editpanel (setq editwin (gtk_window_new 0)) (gtk_window_set_title editwin {"Edit entry..."}) (gtk_window_set_transient_for editwin GUI:mainwin) (gtk_window_set_position editwin 4) # (gtk_window_set_default_size editwin 450 300) (setq label1 (gtk_label_new {"Enter instance: "})) (setq entry1 (gtk_entry_new)) (setq label2 (gtk_label_new {"Enter userdata: "})) (setq entry2 (gtk_entry_new)) (setq label3 (gtk_label_new {"Enter passwd: "})) (setq entry3 (gtk_entry_new)) (setq okbutton (gtk_button_new_from_stock "gtk-ok")) (gtk_widget_set_size_request okbutton 100 30) (setq canbutton (gtk_button_new_from_stock "gtk-cancel")) (gtk_widget_set_size_request canbutton 100 30) # Pack on boxes (setq hbox1 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox1 5) (gtk_box_pack_start hbox1 label1 0 0 1) (gtk_box_pack_start hbox1 entry1 1 1 1) (setq hbox2 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox2 5) (gtk_box_pack_start hbox2 label2 0 0 1) (gtk_box_pack_start hbox2 entry2 1 1 1) (setq hbox3 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox3 5) (gtk_box_pack_start hbox3 label3 0 0 1) (gtk_box_pack_start hbox3 entry3 1 1 1) (setq hbox4 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox4 5) (gtk_box_pack_start hbox4 canbutton 0 0 1) (gtk_box_pack_end hbox4 okbutton 0 0 1) (setq vbox (gtk_vbox_new 0 0)) (gtk_box_pack_start vbox hbox1 0 0 1) (gtk_box_pack_start vbox hbox2 0 0 1) (gtk_box_pack_start vbox hbox3 0 0 1) (gtk_box_pack_start vbox hbox4 0 0 1) (gtk_container_add editwin vbox) (define (edit_entry, sel) (if (= (gtk_tree_selection_get_selected GUI:sel "NULL" GUI:iter) "1") (begin (setq sel (int (gtk_tree_model_get_string_from_iter GUI:lst GUI:iter))) (gtk_entry_set_text entry1 ((parse (FILE:All_Data sel) " ") 0)) (gtk_entry_set_text entry2 ((parse (FILE:All_Data sel) " ") 1)) (gtk_entry_set_text entry3 ((parse (FILE:All_Data sel) " ") 2)) (gtk_widget_show_all editwin) ) (gtk_widget_show_all GUI:errorwin) ) ) (define (submit_edit, sel) (gtk_list_store_set GUI:lst GUI:iter 0 (title-case (gtk_entry_get_text entry1)) -1) (gtk_list_store_set GUI:lst GUI:iter 1 (gtk_entry_get_text entry2) -1) (gtk_list_store_set GUI:lst GUI:iter 2 (gtk_entry_get_text entry3) -1) (setq sel (int (gtk_tree_model_get_string_from_iter GUI:lst GUI:iter))) (nth-set sel FILE:All_Data (append (title-case (gtk_entry_get_text entry1)) " " (gtk_entry_get_text entry2) " " (gtk_entry_get_text entry3))) (sort FILE:All_Data) (gtk_widget_hide editwin) (GUI:status_txt "INFO: Entry edited successfully.") (gtk_widget_grab_focus entry1) ) #-------------------------------------------------------------------------------------------------------------------------------- (context 'ADD) # Create addpanel (setq addwin (gtk_window_new 0)) (gtk_window_set_title addwin {"Add entry..."}) (gtk_window_set_transient_for addwin GUI:mainwin) (gtk_window_set_position addwin 4) # (gtk_window_set_default_size editwin 450 300) (setq label1 (gtk_label_new {"Enter instance: "})) (setq entry1 (gtk_entry_new)) (setq label2 (gtk_label_new {"Enter userdata: "})) (setq entry2 (gtk_entry_new)) (setq label3 (gtk_label_new {"Enter passwd: "})) (setq entry3 (gtk_entry_new)) (setq okbutton (gtk_button_new_from_stock "gtk-ok")) (gtk_widget_set_size_request okbutton 100 30) (setq canbutton (gtk_button_new_from_stock "gtk-cancel")) (gtk_widget_set_size_request canbutton 100 30) # Pack on boxes (setq hbox1 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox1 5) (gtk_box_pack_start hbox1 label1 0 0 1) (gtk_box_pack_start hbox1 entry1 1 1 1) (setq hbox2 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox2 5) (gtk_box_pack_start hbox2 label2 0 0 1) (gtk_box_pack_start hbox2 entry2 1 1 1) (setq hbox3 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox3 5) (gtk_box_pack_start hbox3 label3 0 0 1) (gtk_box_pack_start hbox3 entry3 1 1 1) (setq hbox4 (gtk_hbox_new 0 0)) (gtk_container_set_border_width hbox4 5) (gtk_box_pack_start hbox4 canbutton 0 0 1) (gtk_box_pack_end hbox4 okbutton 0 0 1) (setq vbox (gtk_vbox_new 0 0)) (gtk_box_pack_start vbox hbox1 0 0 1) (gtk_box_pack_start vbox hbox2 0 0 1) (gtk_box_pack_start vbox hbox3 0 0 1) (gtk_box_pack_start vbox hbox4 0 0 1) (gtk_container_add addwin vbox) (define (submit_add) (gtk_list_store_append GUI:lst GUI:iter) (gtk_list_store_set GUI:lst GUI:iter 0 (title-case (gtk_entry_get_text entry1)) -1) (gtk_list_store_set GUI:lst GUI:iter 1 (gtk_entry_get_text entry2) -1) (gtk_list_store_set GUI:lst GUI:iter 2 (gtk_entry_get_text entry3) -1) (push (append (title-case (gtk_entry_get_text entry1)) " " (gtk_entry_get_text entry2) " " (gtk_entry_get_text entry3)) FILE:All_Data -1) (sort FILE:All_Data) (gtk_widget_hide addwin) (GUI:status_txt "INFO: Entry added successfully.") (gtk_editable_delete_text entry1 0 -1) (gtk_editable_delete_text entry2 0 -1) (gtk_editable_delete_text entry3 0 -1) (gtk_widget_grab_focus entry1) ) #-------------------------------------------------------------------------------------------------------------------------------- (context 'DELETE) # Create warning message (setq warnwin (gtk_message_dialog_new GUI:mainwin 0 2 4 {"Delete this entry?"} "''")) (gtk_server_connect warnwin "delete-event" "delete_warn") (define (del_entry) (if (= (gtk_tree_selection_get_selected GUI:sel "NULL" GUI:iter) "1") (gtk_widget_show_all warnwin) (gtk_widget_show_all GUI:errorwin) ) ) (define (remove_entry, tmp) (setq tmp (gtk_server_callback_value 1 "INT")) (gtk_widget_hide warnwin) (cond ((= tmp "-8") (pop FILE:All_Data (int (gtk_tree_model_get_string_from_iter GUI:lst GUI:iter))) (gtk_list_store_remove GUI:lst GUI:iter) (GUI:status_txt "INFO: Entry deleted.")) ) ) #-------------------------------------------------------------------------------------------------------------------------------- (context 'SAVE) # Create fileselector (setq savewin (gtk_window_new 0)) (gtk_window_set_title savewin {"Save data"}) (gtk_window_set_transient_for savewin GUI:mainwin) (gtk_window_set_position savewin 4) (gtk_window_set_default_size savewin 650 500) (setq filsel (gtk_file_chooser_widget_new 1)) (setq filok (gtk_button_new_from_stock "gtk-ok")) (gtk_widget_set_size_request filok 100 30) (setq filcan (gtk_button_new_from_stock "gtk-cancel")) (gtk_widget_set_size_request filcan 100 30) (setq filfil1 (gtk_file_filter_new)) (gtk_file_filter_set_name filfil1 {"Password files - *.pwd"}) (gtk_file_filter_add_pattern filfil1 "*.pwd") (setq filfil2 (gtk_file_filter_new)) (gtk_file_filter_set_name filfil2 {"All files - *.*"}) (gtk_file_filter_add_pattern filfil2 "*") (gtk_file_chooser_add_filter filsel filfil1) (gtk_file_chooser_add_filter filsel filfil2) (setq filsep (gtk_hseparator_new)) # Arrange widgets on window (setq file_vbox (gtk_vbox_new 0 0)) (gtk_container_set_border_width file_vbox 5) (setq file_hbox (gtk_hbox_new 0 0)) (gtk_box_pack_start file_hbox filcan 0 0 1) (gtk_box_pack_end file_hbox filok 0 0 1) (gtk_box_pack_start file_vbox filsel 1 1 1) (gtk_box_pack_start file_vbox filsep 0 0 1) (gtk_box_pack_start file_vbox file_hbox 0 0 1) (gtk_container_add savewin file_vbox) # Create warning messages (setq warnwin (gtk_message_dialog_new GUI:mainwin 0 2 4 {"Save data with current encryption key?"} "''")) (gtk_server_connect warnwin "delete-event" "delete_save") (setq existwin (gtk_message_dialog_new GUI:mainwin 0 2 4 {"File exists, overwrite?"} "''")) (gtk_server_connect existwin "delete-event" "exist_save") (gtk_window_set_transient_for existwin savewin) (define (save_data, tmp) (setq tmp (gtk_server_callback_value 1 "INT")) (gtk_widget_hide warnwin) (cond ((= tmp "-8") (if FILE:curname (gtk_file_chooser_set_filename filsel FILE:curname)) (gtk_widget_show_all savewin) )) ) (define (store_data) (setq curname (gtk_file_chooser_get_filename filsel)) (replace "\\" curname "/") (if (file? curname) (gtk_widget_show_all existwin) (write_data) ) ) (define (handle_choice, tmp) (setq tmp (gtk_server_callback_value 1 "INT")) (gtk_widget_hide existwin) (cond ((= tmp "-8") (write_data))) ) (define (write_data, data counter) (gtk_widget_hide savewin) (setq curname (gtk_file_chooser_get_filename filsel)) (replace "\\" curname "/") (setq passwd (gtk_entry_get_text GUI:entry)) (setq data "") (setq counter 0) (dolist (x FILE:All_Data) (setq data (append data x "\n")) (inc counter)) (setq data (chop data)) (exec (append {echo "} data {" | openssl enc -e -a -salt -bf -out "} curname {" -pass pass:} passwd " 2>&1")) (GUI:status_txt (append "INFO: Data saved. There are " (string counter) " entries.")) ) #-------------------------------------------------------------------------------------------------------------------------------- (context 'MAIN) (setq order 0) (do-until (or (= event GUI:mainwin) (= event GUI:exitbutton)) (setq event (gtk_server_callback "wait")) (if (= event GUI:filebutton) (gtk_widget_show_all FILE:filewin) (= event GUI:addbutton) (gtk_widget_show_all ADD:addwin) (= event GUI:editbutton) (EDIT:edit_entry) (= event GUI:delbutton) (DELETE:del_entry) (= event GUI:storebutton) (gtk_widget_show_all SAVE:warnwin) (= event GUI:errorwin) (gtk_widget_hide GUI:errorwin) (= event FILE:filewin) (gtk_widget_hide FILE:filewin) (= event FILE:filok) (FILE:open_file) (= event FILE:filcan) (gtk_widget_hide FILE:filewin) (= event DELETE:warnwin) (DELETE:remove_entry) (= event EDIT:editwin) (gtk_widget_hide EDIT:editwin) (= event EDIT:canbutton) (begin (gtk_widget_hide EDIT:editwin)(gtk_widget_grab_focus EDIT:entry1)) (= event EDIT:okbutton) (EDIT:submit_edit) (= event ADD:addwin) (gtk_widget_hide ADD:addwin) (= event ADD:canbutton) (begin (gtk_widget_hide ADD:addwin) (gtk_widget_grab_focus ADD:entry1)) (= event ADD:okbutton) (ADD:submit_add) (= event SAVE:warnwin) (SAVE:save_data) (= event SAVE:existwin) (SAVE:handle_choice) (= event SAVE:filcan) (gtk_widget_hide SAVE:savewin) (= event SAVE:filok) (SAVE:store_data) (= event "delete_err") (gtk_widget_hide GUI:errorwin) (= event "delete_warn") (gtk_widget_hide DELETE:warnwin) (= event "delete_save") (gtk_widget_hide SAVE:warnwin) (= event "exist_save") (gtk_widget_hide SAVE:existwin) (= event GUI:column1) (begin (setq order (- 1 order)) (gtk_tree_sortable_set_sort_column_id GUI:lst 0 order) (sort FILE:All_Data) (if (= order 1)(reverse FILE:All_Data)) ) ) ) (exit)