174 } else if(!strcasecmp(cmd, "repository-url") |
174 } else if(!strcasecmp(cmd, "repository-url") |
175 || !strcasecmp(cmd, "repo-url")) { |
175 || !strcasecmp(cmd, "repo-url")) { |
176 ret = cmd_repository_url(args); |
176 ret = cmd_repository_url(args); |
177 } else if(!strcasecmp(cmd, "add-user")) { |
177 } else if(!strcasecmp(cmd, "add-user")) { |
178 ret = cmd_add_user(args); |
178 ret = cmd_add_user(args); |
|
179 } else if(!strcasecmp(cmd, "list-users")) { |
|
180 ret = cmd_list_users(args); |
|
181 } else if(!strcasecmp(cmd, "remove-user")) { |
|
182 ret = cmd_remove_user(args); |
179 } else if(!strcasecmp(cmd, "version") || !strcasecmp(cmd, "-version") |
183 } else if(!strcasecmp(cmd, "version") || !strcasecmp(cmd, "-version") |
180 || !strcasecmp(cmd, "--version")) { |
184 || !strcasecmp(cmd, "--version")) { |
181 fprintf(stderr, "dav %s\n", DAV_VERSION); |
185 fprintf(stderr, "dav %s\n", DAV_VERSION); |
182 } else if(!strcasecmp(cmd, "complete")) { |
186 } else if(!strcasecmp(cmd, "complete")) { |
183 if(args->argc < 2) { |
187 if(args->argc < 2) { |
294 fprintf(stderr, "\n"); |
298 fprintf(stderr, "\n"); |
295 fprintf(stderr, "Advanced commands:\n"); |
299 fprintf(stderr, "Advanced commands:\n"); |
296 fprintf(stderr, " versioncontrol list-versions checkout checkin uncheckout\n\n"); |
300 fprintf(stderr, " versioncontrol list-versions checkout checkin uncheckout\n\n"); |
297 fprintf(stderr, "Config commands:\n"); |
301 fprintf(stderr, "Config commands:\n"); |
298 fprintf(stderr, " add-repository remove-repository list-repositories repository-url\n"); |
302 fprintf(stderr, " add-repository remove-repository list-repositories repository-url\n"); |
299 fprintf(stderr, " add-user\n"); |
303 fprintf(stderr, " add-user remove-user list-users\n"); |
300 fprintf(stderr, " check-config\n"); |
304 fprintf(stderr, " check-config\n"); |
301 fprintf(stderr, "\n"); |
305 fprintf(stderr, "\n"); |
302 fprintf(stderr, |
306 fprintf(stderr, |
303 "Instead of an url you can pass a repository name " |
307 "Instead of an url you can pass a repository name " |
304 "with an optional path:\n"); |
308 "with an optional path:\n"); |
2623 return -1; |
2627 return -1; |
2624 } |
2628 } |
2625 return 0; |
2629 return 0; |
2626 } |
2630 } |
2627 |
2631 |
2628 int cmd_add_user(CmdArgs *args) { |
2632 |
|
2633 typedef int(*sscmd_func)(CmdArgs *, PwdStore *, void *userdata); |
|
2634 |
|
2635 static int secretstore_after_decrypt( |
|
2636 CmdArgs *args, |
|
2637 PwdStore *secrets, |
|
2638 sscmd_func cb, |
|
2639 void *userdata); |
|
2640 |
|
2641 |
|
2642 /* |
|
2643 * opens the secret store, executes a callback func before and after |
|
2644 * decryption |
|
2645 * Aborts if a callback returns 1 |
|
2646 */ |
|
2647 static int secretstore_cmd( |
|
2648 CmdArgs *args, |
|
2649 DavBool create, |
|
2650 sscmd_func beforedecrypt, |
|
2651 sscmd_func afterdecrypt, |
|
2652 void *userdata) |
|
2653 { |
|
2654 PwdStore *secrets = get_pwdstore(); |
|
2655 if(!secrets) { |
|
2656 if(create) { |
|
2657 secrets = pwdstore_new(); |
|
2658 } else { |
|
2659 return 1; |
|
2660 } |
|
2661 } |
|
2662 |
|
2663 int ret = 0; |
|
2664 if(beforedecrypt) { |
|
2665 ret = beforedecrypt(args, secrets, userdata); |
|
2666 if(ret) { |
|
2667 afterdecrypt = NULL; // exit |
|
2668 } |
|
2669 } |
|
2670 |
|
2671 if(afterdecrypt) { |
|
2672 ret = secretstore_after_decrypt(args, secrets, afterdecrypt, userdata); |
|
2673 } |
|
2674 |
|
2675 pwdstore_free(secrets); |
|
2676 |
|
2677 return ret; |
|
2678 } |
|
2679 |
|
2680 static int secretstore_after_decrypt( |
|
2681 CmdArgs *args, |
|
2682 PwdStore *secrets, |
|
2683 sscmd_func cb, |
|
2684 void *userdata) |
|
2685 { |
2629 char *master_pw = util_password_input("Master password: "); |
2686 char *master_pw = util_password_input("Master password: "); |
2630 if(!master_pw) { |
2687 if(!master_pw) { |
|
2688 fprintf(stderr, "Error: master password required.\nAbort.\n"); |
2631 return 1; |
2689 return 1; |
2632 } |
2690 } |
2633 |
2691 |
2634 PwdStore *secrets = get_pwdstore(); |
2692 int err = pwdstore_setpassword(secrets, master_pw); |
2635 if(!secrets) { |
2693 free(master_pw); |
2636 secrets = pwdstore_new(); |
2694 if(err) { |
2637 } |
|
2638 if(pwdstore_setpassword(secrets, master_pw)) { |
|
2639 fprintf(stderr, "Error: Cannot generate key from password.\nAbort.\n"); |
2695 fprintf(stderr, "Error: Cannot generate key from password.\nAbort.\n"); |
2640 return 1; |
2696 return 1; |
2641 } |
2697 } |
|
2698 |
2642 if(pwdstore_decrypt(secrets)) { |
2699 if(pwdstore_decrypt(secrets)) { |
2643 fprintf(stderr, "Error: Cannot decrypt secrets store.\nAbort.\n"); |
2700 fprintf(stderr, "Error: Cannot decrypt secrets store.\nAbort.\n"); |
2644 } |
2701 return 1; |
2645 |
2702 } |
2646 |
2703 |
|
2704 return cb(args, secrets, userdata); |
|
2705 } |
|
2706 |
|
2707 static int cmd_ss_add_user(CmdArgs *Args, PwdStore *secrets, void *userdata) { |
2647 char *id = assistant_getcfg("Credentials identifier"); |
2708 char *id = assistant_getcfg("Credentials identifier"); |
2648 if(id && pwdstore_get(secrets, id)) { |
2709 if(!id) { |
|
2710 fprintf(stderr, "Identifier required.\n"); |
|
2711 return 1; |
|
2712 } |
|
2713 if(pwdstore_get(secrets, id)) { |
2649 fprintf(stderr, "Credentials with this id already exist.\n"); |
2714 fprintf(stderr, "Credentials with this id already exist.\n"); |
2650 return 1; |
2715 return 1; |
2651 } |
2716 } |
2652 |
2717 |
|
2718 // get user name and password (required) |
2653 char *user = assistant_getcfg("User"); |
2719 char *user = assistant_getcfg("User"); |
2654 char *password = util_password_input("Password: "); |
2720 char *password = util_password_input("Password: "); |
2655 char *location = assistant_getoptcfg("Location"); |
2721 |
2656 UcxList *locations = location ? ucx_list_append(NULL, location) : NULL; |
2722 // optionally, get one or more locations |
|
2723 char *location = NULL; |
|
2724 UcxList *locations = NULL; |
|
2725 while((location = assistant_getoptcfg("Location"))) { |
|
2726 locations = ucx_list_append(locations, location); |
|
2727 } |
|
2728 |
2657 int ret = 1; |
2729 int ret = 1; |
2658 if(user && password) { |
2730 if(user && password) { |
2659 pwdstore_put_index(secrets, id, locations); |
2731 pwdstore_put_index(secrets, id, locations); |
2660 pwdstore_put(secrets, id, user, password); |
2732 pwdstore_put(secrets, id, user, password); |
2661 int ret = pwdstore_save(secrets); |
2733 ret = pwdstore_save(secrets); |
2662 if(ret) { |
2734 if(ret) { |
2663 fprintf(stderr, "Error: saving srcrets store failed.\n"); |
2735 fprintf(stderr, "Error: saving srcrets store failed.\n"); |
2664 } |
2736 } |
2665 } |
2737 } |
2666 |
2738 |
2667 pwdstore_free(secrets); |
|
2668 if(id) free(id); |
2739 if(id) free(id); |
2669 if(user) free(user); |
2740 if(user) free(user); |
2670 if(password) free(password); |
2741 if(password) free(password); |
2671 if(location) free(location); |
2742 |
2672 if(locations) ucx_list_free(locations); |
2743 ucx_list_free_content(locations, free); |
|
2744 ucx_list_free(locations); |
2673 |
2745 |
2674 return ret; |
2746 return ret; |
2675 } |
2747 } |
2676 |
2748 |
|
2749 int cmd_add_user(CmdArgs *args) { |
|
2750 return secretstore_cmd(args, TRUE, NULL, cmd_ss_add_user, NULL); |
|
2751 } |
|
2752 |
|
2753 /* |
|
2754 * called before the secret store is decrypted |
|
2755 */ |
|
2756 static int cmd_ss_list_users_bc(CmdArgs *Args, PwdStore *secrets, int *ret) { |
|
2757 if(secrets->index->count == 0) { |
|
2758 return 1; // abort, because the secret store is empty |
|
2759 } |
|
2760 // set ret to 1, because decrypt could fail and this should be an error |
|
2761 *ret = 1; |
|
2762 return 0; |
|
2763 } |
|
2764 |
|
2765 /* |
|
2766 * called after the secret store is decrypted |
|
2767 */ |
|
2768 static int cmd_ss_list_users(CmdArgs *args, PwdStore *secrets, int *ret) { |
|
2769 *ret = 0; |
|
2770 |
|
2771 UcxList *list = secrets->locations; |
|
2772 for(int i=0;i<2;i++) { |
|
2773 UCX_FOREACH(elm, list) { |
|
2774 PwdIndexEntry *index = elm->data; |
|
2775 PwdEntry *e = ucx_map_cstr_get(secrets->ids, index->id); |
|
2776 if(e) { |
|
2777 printf("Id: %s\n", e->id); |
|
2778 printf("User: %s\n", e->user); |
|
2779 UCX_FOREACH(loc, index->locations) { |
|
2780 char *location = loc->data; |
|
2781 printf("Location: %s\n", location); |
|
2782 } |
|
2783 printf("\n"); |
|
2784 } else { |
|
2785 // broken index |
|
2786 fprintf(stderr, |
|
2787 "Warning: id '%s' not in secret store.\n", |
|
2788 index->id); |
|
2789 } |
|
2790 } |
|
2791 list = secrets->noloc; |
|
2792 } |
|
2793 |
|
2794 |
|
2795 return 0; |
|
2796 } |
|
2797 |
|
2798 int cmd_list_users(CmdArgs *args) { |
|
2799 int ret = 0; |
|
2800 secretstore_cmd(args, FALSE, (sscmd_func)cmd_ss_list_users_bc, (sscmd_func)cmd_ss_list_users, &ret); |
|
2801 return ret; |
|
2802 } |
|
2803 |
|
2804 |
|
2805 static int cmd_ss_remove_user(CmdArgs *args, PwdStore *secrets, void *ud) { |
|
2806 char *id = assistant_getcfg("Credentials identifier"); |
|
2807 if(!id) { |
|
2808 fprintf(stderr, "Identifier required.\n"); |
|
2809 return 1; |
|
2810 } |
|
2811 if(!pwdstore_get(secrets, id)) { |
|
2812 fprintf(stderr, "Credentials with this id doesn't exist.\n"); |
|
2813 return 1; |
|
2814 } |
|
2815 |
|
2816 pwdstore_remove_entry(secrets, id); |
|
2817 |
|
2818 int ret = pwdstore_save(secrets); |
|
2819 if(ret) { |
|
2820 fprintf(stderr, "Error: saving srcrets store failed.\n"); |
|
2821 } |
|
2822 return ret; |
|
2823 } |
|
2824 |
|
2825 int cmd_remove_user(CmdArgs *args) { |
|
2826 return secretstore_cmd(args, FALSE, NULL, cmd_ss_remove_user, NULL); |
|
2827 } |
2677 |
2828 |
2678 int shell_completion(CmdArgs *args, int index) { |
2829 int shell_completion(CmdArgs *args, int index) { |
2679 if(args->argc < 2 || args->argc < 3) { |
2830 if(args->argc < 2 || args->argc < 3) { |
2680 return 1; |
2831 return 1; |
2681 } |
2832 } |