diff options
-rw-r--r-- | TODO.adoc | 2 | ||||
-rw-r--r-- | src/gpg.c | 38 | ||||
-rw-r--r-- | src/gpg.h | 4 | ||||
-rw-r--r-- | src/gpgedit_config.c (renamed from src/gpg_keyids.c) | 69 | ||||
-rw-r--r-- | src/gpgedit_config.h (renamed from src/strarray.h) | 22 | ||||
-rw-r--r-- | src/main.c | 39 | ||||
-rw-r--r-- | src/strarray.c | 78 | ||||
-rw-r--r-- | src/strll.c | 77 | ||||
-rw-r--r-- | src/strll.h (renamed from src/gpg_keyids.h) | 27 |
9 files changed, 207 insertions, 149 deletions
@@ -10,7 +10,7 @@ Implement * [ ] Read environment variable $EDITOR, default to vim (only parse arg 0 to some avoid security concerns) * [ ] Argument parser (eg: -r,--recipient) -* [ ] Recipient addition beyond the list already in the file +* [x] Recipient addition beyond the list already in the file * [ ] Recipient removal from existing file * [ ] New file creation (at least one recipient required) * [ ] Helptext @@ -101,6 +101,37 @@ int gpg_recip_count(gpgme_recipient_t firstrecip) { } +// gpg_strll_to_key_t: +// Converts a string linked list containing keyids (multiple identifier types +// are supported) into an array of gpgme_key_t objects. +// +// @ctx GPGME context (already initialized) +// @firstrecip First linkedlist recipient item +// +// @return gpgme_key_t* Array of gpgme_key_t objects, one for each keyid string +gpgme_key_t* gpg_strll_to_key_t(gpgme_ctx_t ctx, struct strll* firstrecip) { + gpgme_key_t* out; + gpgme_error_t err; + int i = 0; + struct strll* recip = firstrecip; + + // Initialize the gpgme_key_t pointer array + out = (gpgme_key_t*) malloc(1); + out = NULL; + + // Loop over the keys back to zero + while(recip != NULL) { + out = realloc(out, sizeof(gpgme_key_t) * (i + 1)); + err = gpgme_get_key(ctx, recip->str, &out[i], 0); + gpg_failiferr(err); + recip = recip->next; + i++; + } + out[i] = NULL; + return out; +} + + void gpg_key_dump(gpgme_key_t key) { printf("Recipient: %s\n", key->fpr); printf(" protocol: %d\n", key->protocol); @@ -114,15 +145,13 @@ void gpg_key_dump(gpgme_key_t key) { printf(" can_auth: %d\n", key->can_authenticate); printf(" qualified: %d\n", key->is_qualified); printf(" secret: %d\n", key->secret); - printf(" origin: %d\n", key->origin); printf(" issuer_serial: %s\n", key->issuer_serial); printf(" issuer_name: %s\n", key->issuer_name); printf(" chain_id: %s\n", key->chain_id); - printf(" last_update: %ld\n", key->last_update); } -size_t gpg_encrypt_file(char* infile, char* outfile, char** keyids) { +size_t gpg_encrypt_file(char* infile, char* outfile, struct strll* recipll) { gpgme_ctx_t ctx; gpgme_data_t indata; gpgme_data_t outdata; @@ -141,7 +170,8 @@ size_t gpg_encrypt_file(char* infile, char* outfile, char** keyids) { gpg_failiferr(err); // Get key id objects from keyids char array - keys = gpg_keyids_to_key_t(ctx, keyids); + keys = gpg_strll_to_key_t(ctx, recipll); + // For debugging purposes // int i = 0; // while(keys[i] != NULL) { @@ -24,7 +24,7 @@ #include <gpgme.h> #include <locale.h> -#include "gpg_keyids.h" +#include "strll.h" #define READSIZE 256 @@ -34,7 +34,7 @@ gpgme_error_t init_gpg(gpgme_ctx_t*, gpgme_protocol_t); gpgme_decrypt_result_t gpg_decrypt_file(char*, char*, gpgme_ctx_t); -size_t gpg_encrypt_file(char*, char*, char**); +size_t gpg_encrypt_file(char*, char*, struct strll*); int gpg_failiferr(gpg_error_t); diff --git a/src/gpg_keyids.c b/src/gpgedit_config.c index 5b0edfe..dbf2e6b 100644 --- a/src/gpg_keyids.c +++ b/src/gpgedit_config.c @@ -13,10 +13,36 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -#include "gpg_keyids.h" +#include "gpgedit_config.h" -// gpg_keyids_load_from_recip: +struct gpgedit_config* gpgedit_config_new() { + struct gpgedit_config* c = NULL; + c = malloc(sizeof(struct gpgedit_config)); + c->file = NULL; + c->recipients = strll_new(); + + return c; +} + + +void gpgedit_config_file_set(struct gpgedit_config* c, char* file) { + c->file = malloc(strlen(file) + 1); + strcpy(c->file, file); +} + + +void gpgedit_config_recipients_add(struct gpgedit_config* c, char* recipient) { + strll_add(c->recipients, recipient); +} + +void gpgedit_config_release(struct gpgedit_config* c) { + free(c->file); + strll_release(c->recipients); + free(c); +} + +// gpgedit_config_recip_from_gpgme_recip: // Converts a gpgme_recipient_t linked list to a string array of key ids. This // is useful when storing a list of recipients for an already-encrypted file to // be used when later re-encrypting that file. @@ -25,44 +51,13 @@ // to this will be updated by the array growth process. // @firstrecip First recipient in the linked list. The list will be traversed // starting here. -void gpg_keyids_load_from_recip(char*** keyids, gpgme_recipient_t firstrecip) { - gpgme_recipient_t recip; // Current recipient object +void gpgedit_config_recip_from_gpgme_recip(struct gpgedit_config* c, gpgme_recipient_t firstrecip) { + gpgme_recipient_t recip = firstrecip; // Current recipient object + // Write each recipient key id to the char array - recip = firstrecip; while(recip != NULL) { - strarray_add(keyids, recip->keyid); + strll_add(c->recipients, recip->keyid); recip = recip->next; } } - -// gpg_keyids_to_key_t: -// Converts a string array containing keyids (multiple identifier types are -// supported) into an array of gpgme_key_t objects. -// -// @ctx GPGME context (already initialized) -// @keyids Pointer to string array of key id strings -// -// @return gpgme_key_t* Array of gpgme_key_t objects, one for each keyid string -gpgme_key_t* gpg_keyids_to_key_t(gpgme_ctx_t ctx, char** keyids) { - gpgme_key_t* out; - gpgme_error_t err; - int count = 0; // Number of recipients - int i = 0; - - // Count the keys - while(keyids[count] != NULL) - count++; - - // Allocate the gpgme_key_t pointer array - out = (gpgme_key_t*) malloc(sizeof(gpgme_key_t) * (count + 1)); - - // Loop over the keys back to zero - while(i < count) { - err = gpgme_get_key(ctx, keyids[i], &out[i], 0); - gpg_failiferr(err); - i++; - } - out[i] = NULL; - return out; -} diff --git a/src/strarray.h b/src/gpgedit_config.h index 69d91a4..1c74a29 100644 --- a/src/strarray.h +++ b/src/gpgedit_config.h @@ -13,15 +13,21 @@ // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -#ifndef GPGEDIT_STRARRAY_H -#define GPGEDIT_STRARRAY_H -#include <stdio.h> -#include <stdlib.h> +#include <gpgme.h> #include <string.h> -char** strarray_new(); -void strarray_add(char***, char*); -void strarray_release(char***); +#include "strll.h" -#endif +struct gpgedit_config { + char* file; // File path to be edited + struct strll* recipients; // Pointer to first item in the linked list + struct gpgme_key_t* keys; +}; + +struct gpgedit_config* gpgedit_config_new(); +void gpgedit_config_file_set(struct gpgedit_config*, char*); +void gpgedit_config_recipients_set(struct gpgedit_config*, char**); +void gpgedit_config_recipients_add(struct gpgedit_config*, char*); +void gpgedit_config_release(struct gpgedit_config*); +void gpgedit_config_recip_from_gpgme_recip(struct gpgedit_config* c, gpgme_recipient_t firstrecip); @@ -21,8 +21,8 @@ #include <gpgme.h> #include "gpg.h" -#include "gpg_keyids.h" -#include "strarray.h" +#include "gpgedit_config.h" +#include "strll.h" void system_edit(char* file) { char cmd[256]; // Buffer for editor command @@ -31,17 +31,36 @@ void system_edit(char* file) { } +void parseargs(int argc, char* argv[], struct gpgedit_config* config) { + int i = 1; + + while(i < argc) { + if(strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--recipient") == 0) { + i++; + //printf("Adding recipient %s\n", argv[i]); + strll_add(config->recipients, argv[i]); + } else { + gpgedit_config_file_set(config, argv[i]); + } + i++; + } +} + + int main(int argc, char* argv[]) { char tmpfile[32] = "/tmp/gpgedit-XXXXXX"; gpgme_ctx_t decctx; gpgme_error_t err; - char** keyids; + struct gpgedit_config* config; if(argc == 1) { printf("Please specify a gpg encrypted file to edit\n"); return 1; } + config = gpgedit_config_new(); + parseargs(argc, argv, config); + // Initialize decryption context, create tmp file to write decrypted contents // to, and run decryption operation. err = init_gpg(&decctx, GPGME_PROTOCOL_OPENPGP); @@ -51,22 +70,24 @@ int main(int argc, char* argv[]) { } mkstemp(tmpfile); - gpgme_decrypt_result_t res = gpg_decrypt_file(argv[1], tmpfile, decctx); + gpgme_decrypt_result_t res = gpg_decrypt_file(config->file, tmpfile, decctx); // Get keyids array from recipients list - keyids = strarray_new(); - gpg_keyids_load_from_recip(&keyids, res->recipients); + gpgedit_config_recip_from_gpgme_recip(config, res->recipients); // Freedom! gpgme_release(decctx); // Open the system editor system_edit(tmpfile); + printf("Recipients:\n"); + strll_dump(config->recipients); + // Re-encrypt the plaintext tmp file - //printf("Re-encrypting file '%s' -> '%s'\n", tmpfile, argv[1]); - gpg_encrypt_file(tmpfile, argv[1], keyids); + //printf("Re-encrypting file '%s' -> '%s'\n", tmpfile, config->file); + gpg_encrypt_file(tmpfile, config->file, config->recipients); // Clean up tmpfile - strarray_release(&keyids); + gpgedit_config_release(config); unlink(tmpfile); return 0; } diff --git a/src/strarray.c b/src/strarray.c deleted file mode 100644 index 12ddbf8..0000000 --- a/src/strarray.c +++ /dev/null @@ -1,78 +0,0 @@ -// GPGEdit edits GPG encrypted files -// Copyright (C) 2018 Aaron Ball <nullspoon@oper.io> -// -// 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. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// 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 <https://www.gnu.org/licenses/>. -#include "strarray.h" - - -// strarray_new: -// Pretty much useless constructor. Here mostly for consistency. This can -// easily be replaced with your own malloc statement provided index 0 is set to -// NULL. -// -// NOTE: If not using this, initialized memory *must* be allocated in the heap, -// as growing the string array requires reallocating the memory, which -// can't be done in the stack. -char** strarray_new() { - char** out = malloc(sizeof(char*)); - out[0] = NULL; - return out; -} - - -// strarray_add: -// Dynamically grows a string array (pointer to char array containing pointers -// to char arrays - sorry). Reallocates storage for the original array plus -// room for one additional pointer. Once data is copied in, the source array -// pointer is updated to point to the new storage. -// -// @strorig Source string array pointer -// @newstr New string to add to the string array. -void strarray_add(char*** strorig, char* newstr) { - int i = 0; - char** newstrarr; - - // Count the number of existing strings - while(*strorig[i] != NULL) - i++; - - // Reallocate old array + 1 - newstrarr = (char**) realloc(*strorig, sizeof(char*) * (i + 1)); - - // Append new string to the array - newstrarr[i] = malloc(strlen(newstr) + 1); - strcpy(newstrarr[i], newstr); - // Don't forget the null terminator! - newstrarr[i + 1] = NULL; - - // Repoint strorig to newstrarr memory - *strorig = newstrarr; -} - - -// strarray_release: -// Destructor for a string array. Frees each item in the array before freeing -// the array itself. -// -// @strarray Array to free -void strarray_release(char*** strarray) { - int i = 0; - - while(*strarray[i] != NULL) { - free(*strarray[i]); - i++; - } - free(*strarray); -} - diff --git a/src/strll.c b/src/strll.c new file mode 100644 index 0000000..fd47b5e --- /dev/null +++ b/src/strll.c @@ -0,0 +1,77 @@ +// GPGEdit edits GPG encrypted files +// Copyright (C) 2018 Aaron Ball <nullspoon@oper.io> +// +// 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. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// 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 <https://www.gnu.org/licenses/>. + +#include "strll.h" + +struct strll* strll_new() { + struct strll* out; + out = malloc(sizeof(struct strll)); + out->next = NULL; + out->str = NULL; + + return out; +} + + +struct strll* strll_add(struct strll* listitem, char* str) { + struct strll* cur = listitem; + + // If str == null, we're inside the first item of a new list + if(cur->str == NULL) { + cur->str = malloc(sizeof(char) * (strlen(str) + 1)); + strcpy(cur->str, str); + cur->next = NULL; + return cur; + } + + // Traverse to the last item in the list + while(cur->next != NULL) + cur = cur->next; + + // Allocate the next item and update the next pointer + cur->next = malloc(sizeof(struct strll)); + // Repoint cur to the newly allocated struct + cur = cur->next; + + // Allocate string, copy in, and set next to null + cur->str = malloc(sizeof(char) * (strlen(str) + 1)); + strcpy(cur->str, str); + cur->next = NULL; + + return cur; +} + + +void strll_release(struct strll* listitem) { + struct strll* item = listitem; + struct strll* next = NULL; + + while(item != NULL) { + next = item->next; + free(item->str); + free(item); + item = next; + } +} + + +void strll_dump(struct strll* listitem) { + struct strll* cur = listitem; + while(cur != NULL) { + printf("%s\n", cur->str); + cur = cur->next; + } +} diff --git a/src/gpg_keyids.h b/src/strll.h index 70ad9d9..4b473fa 100644 --- a/src/gpg_keyids.h +++ b/src/strll.h @@ -14,22 +14,29 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -#ifndef GPGEDIT_GPG_KEYIDS_H -#define GPGEDIT_GPG_KEYIDS_H +#ifndef gpgedit_strll_h +#define gpgedit_strll_h #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <gpgme.h> -#include <locale.h> -#include "gpg.h" -#include "strarray.h" +struct strll { + char* str; + struct strll* next; +}; -void gpg_keyids_load_from_recip(char***, gpgme_recipient_t); -gpgme_key_t* gpg_keyids_to_key_t(gpgme_ctx_t, char**); -//void gpg_keyids_release(char**); -//char** gpg_keyids_new(); +// Create new linked list +struct strll* strll_new(); + +// Adds new item to the linked list +struct strll* strll_add(struct strll*, char*); + +// Destructor for strll object +void strll_release(struct strll*); + +// Dump linked list content to stdout +void strll_dump(struct strll*); #endif |