summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ball <nullspoon@oper.io>2018-10-29 11:07:13 -0600
committerAaron Ball <nullspoon@oper.io>2018-10-29 11:16:10 -0600
commitc7b940e9baffca703c9a54aa3b3a2ca42482751c (patch)
tree147108b043e42ddeab06d2895c7a3dbc2aed06f8
parent8213a660ed559679badb1158edb4269618435fe0 (diff)
downloadgpgedit-c7b940e9baffca703c9a54aa3b3a2ca42482751c.tar.gz
gpgedit-c7b940e9baffca703c9a54aa3b3a2ca42482751c.tar.xz
Support for additional recipients
Added basic support for additional recipients. This required a rewrite of the recipient memory management. Previously, recipients were stored in a char array, which was reallocated when a recipient was added. This was not done globally so the user could add additional recipients at runtime. This adds a new gpgedit_config object that handles the file path and the recipient list. The recipient list is now managed inside of a linked list (how cool are those?!), allowing for appending without reallocating. Now the recipient list is loaded from the specified file, and any additional recipients added via the -r,--recipient switch will be added to the list when the file is closed and re-encrypted. Note that this adds support for the -r,--recipient switch. This deprecates and removes the gpg_keyids.c and .h files, as they are no longer needed (relevant code was moved to gpg.c). This also adds the strll.c and strll.h files to handle memory management for linked lists of char arrays.
-rw-r--r--TODO.adoc2
-rw-r--r--src/gpg.c38
-rw-r--r--src/gpg.h4
-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.c39
-rw-r--r--src/strarray.c78
-rw-r--r--src/strll.c77
-rw-r--r--src/strll.h (renamed from src/gpg_keyids.h)27
9 files changed, 207 insertions, 149 deletions
diff --git a/TODO.adoc b/TODO.adoc
index a29d3bf..35fc661 100644
--- a/TODO.adoc
+++ b/TODO.adoc
@@ -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
diff --git a/src/gpg.c b/src/gpg.c
index 0657add..51e614f 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -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) {
diff --git a/src/gpg.h b/src/gpg.h
index 6e73d2e..17593df 100644
--- a/src/gpg.h
+++ b/src/gpg.h
@@ -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);
diff --git a/src/main.c b/src/main.c
index 7eed5b2..a5afe97 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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

Generated by cgit