Skip to content

Commit d3280e0

Browse files
committed
Properly handle gpg2 errors
Fixes #940.
1 parent 310e9f4 commit d3280e0

File tree

1 file changed

+117
-116
lines changed

1 file changed

+117
-116
lines changed

src/appimagetool.c

Lines changed: 117 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,176 +1121,177 @@ main (int argc, char *argv[])
11211121

11221122
if (pclose(fp) != 0) {
11231123
fprintf(stderr, "ERROR: %s command did not succeed, could not sign, continuing\n", using_gpg ? "gpg" : "gpg2");
1124-
return 0;
1125-
}
1124+
} else {
11261125

1127-
fp = NULL;
1126+
fp = NULL;
11281127

1129-
FILE* destinationfp = fopen(destination, "r+");
1128+
FILE* destinationfp = fopen(destination, "r+");
11301129

1131-
// calculate signature
1132-
{
1133-
unsigned long sig_offset = 0;
1134-
unsigned long sig_length = 0;
1130+
// calculate signature
1131+
{
1132+
unsigned long sig_offset = 0;
1133+
unsigned long sig_length = 0;
11351134

1136-
bool rv = appimage_get_elf_section_offset_and_length(destination, ".sha256_sig", &sig_offset, &sig_length);
1135+
bool rv = appimage_get_elf_section_offset_and_length(destination, ".sha256_sig", &sig_offset,
1136+
&sig_length);
11371137

1138-
if (!rv || sig_offset == 0 || sig_length == 0) {
1139-
die("Could not find section .sha256_sig in runtime");
1140-
}
1138+
if (!rv || sig_offset == 0 || sig_length == 0) {
1139+
die("Could not find section .sha256_sig in runtime");
1140+
}
11411141

1142-
if (verbose) {
1143-
printf("sig_offset: %lu\n", sig_offset);
1144-
printf("sig_length: %lu\n", sig_length);
1145-
}
1142+
if (verbose) {
1143+
printf("sig_offset: %lu\n", sig_offset);
1144+
printf("sig_length: %lu\n", sig_length);
1145+
}
11461146

1147-
if (sig_offset == 0) {
1148-
die("Could not determine offset for signature");
1149-
}
1147+
if (sig_offset == 0) {
1148+
die("Could not determine offset for signature");
1149+
}
11501150

1151-
if (destinationfp == NULL)
1152-
die("Not able to open the destination file for writing, aborting");
1151+
if (destinationfp == NULL)
1152+
die("Not able to open the destination file for writing, aborting");
11531153

1154-
// if(strlen(updateinformation)>sig_length)
1155-
// die("signature does not fit into segment, aborting");
1154+
// if(strlen(updateinformation)>sig_length)
1155+
// die("signature does not fit into segment, aborting");
11561156

1157-
fseek(destinationfp, sig_offset, SEEK_SET);
1157+
fseek(destinationfp, sig_offset, SEEK_SET);
11581158

1159-
FILE* ascfilefp = fopen(ascfile, "rb");
1159+
FILE* ascfilefp = fopen(ascfile, "rb");
11601160

1161-
if (ascfilefp == NULL) {
1162-
die("Not able to open the asc file for reading, aborting");
1163-
}
1161+
if (ascfilefp == NULL) {
1162+
die("Not able to open the asc file for reading, aborting");
1163+
}
11641164

1165-
static const int bufsize = 1024;
1166-
char buffer[bufsize];
1165+
static const int bufsize = 1024;
1166+
char buffer[bufsize];
11671167

1168-
size_t totalBytesRead = 0;
1168+
size_t totalBytesRead = 0;
11691169

1170-
while (!feof(ascfilefp)) {
1171-
size_t bytesRead = fread(buffer, sizeof(char), bufsize, ascfilefp);
1172-
totalBytesRead += bytesRead;
1170+
while (!feof(ascfilefp)) {
1171+
size_t bytesRead = fread(buffer, sizeof(char), bufsize, ascfilefp);
1172+
totalBytesRead += bytesRead;
11731173

1174-
if (totalBytesRead > sig_length) {
1175-
die("Error: cannot embed key in AppImage: size exceeds reserved ELF section size");
1176-
}
1174+
if (totalBytesRead > sig_length) {
1175+
die("Error: cannot embed key in AppImage: size exceeds reserved ELF section size");
1176+
}
11771177

1178-
size_t bytesWritten = fwrite(buffer, sizeof(char), bytesRead, destinationfp);
1178+
size_t bytesWritten = fwrite(buffer, sizeof(char), bytesRead, destinationfp);
11791179

1180-
if (bytesRead != bytesWritten) {
1181-
char message[128];
1182-
sprintf(message, "Bytes read and written differ: %lu != %lu", (long unsigned) bytesRead,
1183-
(long unsigned) bytesWritten);
1184-
die(message);
1180+
if (bytesRead != bytesWritten) {
1181+
char message[128];
1182+
sprintf(message, "Bytes read and written differ: %lu != %lu", (long unsigned) bytesRead,
1183+
(long unsigned) bytesWritten);
1184+
die(message);
1185+
}
11851186
}
1186-
}
11871187

1188-
fclose(ascfilefp);
1189-
if (g_file_test(digestfile, G_FILE_TEST_IS_REGULAR))
1190-
unlink(digestfile);
1188+
fclose(ascfilefp);
1189+
if (g_file_test(digestfile, G_FILE_TEST_IS_REGULAR))
1190+
unlink(digestfile);
11911191

1192-
if (sign_key == NULL || strlen(sign_key) > 0) {
1193-
// read which key was used to sign from signature
1194-
sprintf(command, "%s --batch --list-packets %s", gpg2_path, ascfile);
1192+
if (sign_key == NULL || strlen(sign_key) > 0) {
1193+
// read which key was used to sign from signature
1194+
sprintf(command, "%s --batch --list-packets %s", gpg2_path, ascfile);
11951195

1196-
fp = popen(command, "r");
1196+
fp = popen(command, "r");
11971197

1198-
if (fp == NULL)
1199-
die("Failed to call gpg[2] to detect signature's key ID");
1198+
if (fp == NULL)
1199+
die("Failed to call gpg[2] to detect signature's key ID");
12001200

1201-
while (!feof(fp)) {
1202-
size_t bytesRead = fread(buffer, sizeof(char), bufsize, fp);
1201+
while (!feof(fp)) {
1202+
size_t bytesRead = fread(buffer, sizeof(char), bufsize, fp);
12031203

1204-
char* keyid_pos = strstr(buffer, "keyid");
1204+
char* keyid_pos = strstr(buffer, "keyid");
12051205

1206-
if (keyid_pos == NULL)
1207-
continue;
1206+
if (keyid_pos == NULL)
1207+
continue;
12081208

1209-
char* keyIDBegin = keyid_pos + strlen("keyid ");
1210-
char* endOfKeyID = strstr(keyIDBegin, "\n");
1209+
char* keyIDBegin = keyid_pos + strlen("keyid ");
1210+
char* endOfKeyID = strstr(keyIDBegin, "\n");
12111211

1212-
sign_key = calloc(endOfKeyID - keyIDBegin, sizeof(char));
1213-
memcpy(sign_key, keyIDBegin, endOfKeyID - keyIDBegin);
1214-
}
1212+
sign_key = calloc(endOfKeyID - keyIDBegin, sizeof(char));
1213+
memcpy(sign_key, keyIDBegin, endOfKeyID - keyIDBegin);
1214+
}
12151215

1216-
// read rest of process input to avoid broken pipe error
1217-
while (!feof(fp)) {
1218-
fread(buffer, sizeof(char), bufsize, fp);
1219-
}
1216+
// read rest of process input to avoid broken pipe error
1217+
while (!feof(fp)) {
1218+
fread(buffer, sizeof(char), bufsize, fp);
1219+
}
12201220

1221-
int retval = pclose(fp);
1222-
fp = NULL;
1221+
int retval = pclose(fp);
1222+
fp = NULL;
1223+
1224+
if (retval != 0)
1225+
die("Failed to call gpg[2] to detect signature's key ID");
1226+
}
12231227

1224-
if (retval != 0)
1225-
die("Failed to call gpg[2] to detect signature's key ID");
1228+
if (g_file_test(ascfile, G_FILE_TEST_IS_REGULAR))
1229+
unlink(ascfile);
12261230
}
12271231

1228-
if (g_file_test(ascfile, G_FILE_TEST_IS_REGULAR))
1229-
unlink(ascfile);
1230-
}
1232+
// export key and write into section
1233+
{
1234+
sprintf(command, "%s --batch --export --armor %s", gpg2_path, sign_key);
12311235

1232-
// export key and write into section
1233-
{
1234-
sprintf(command, "%s --batch --export --armor %s", gpg2_path, sign_key);
1236+
unsigned long key_offset = 0, key_length = 0;
12351237

1236-
unsigned long key_offset = 0, key_length = 0;
1238+
bool rv = appimage_get_elf_section_offset_and_length(destination, ".sig_key", &key_offset, &key_length);
12371239

1238-
bool rv = appimage_get_elf_section_offset_and_length(destination, ".sig_key", &key_offset, &key_length);
1240+
if (verbose) {
1241+
printf("key_offset: %lu\n", key_offset);
1242+
printf("key_length: %lu\n", key_length);
1243+
}
12391244

1240-
if (verbose) {
1241-
printf("key_offset: %lu\n", key_offset);
1242-
printf("key_length: %lu\n", key_length);
1243-
}
1245+
if (!rv || key_offset == 0 || key_length == 0) {
1246+
die("Could not find section .sig_key in runtime");
1247+
}
12441248

1245-
if (!rv || key_offset == 0 || key_length == 0) {
1246-
die("Could not find section .sig_key in runtime");
1247-
}
1249+
fseek(destinationfp, key_offset, SEEK_SET);
12481250

1249-
fseek(destinationfp, key_offset, SEEK_SET);
1251+
fp = popen(command, "r");
12501252

1251-
fp = popen(command, "r");
1253+
if (fp == NULL)
1254+
die("Failed to call gpg[2] to export the signature key");
12521255

1253-
if (fp == NULL)
1254-
die("Failed to call gpg[2] to export the signature key");
1256+
static const int bufsize = 1024;
1257+
char buffer[bufsize];
12551258

1256-
static const int bufsize = 1024;
1257-
char buffer[bufsize];
1259+
size_t totalBytesRead = 0;
1260+
while (!feof(fp)) {
1261+
size_t bytesRead = fread(buffer, sizeof(char), bufsize, fp);
1262+
totalBytesRead += bytesRead;
12581263

1259-
size_t totalBytesRead = 0;
1260-
while (!feof(fp)) {
1261-
size_t bytesRead = fread(buffer, sizeof(char), bufsize, fp);
1262-
totalBytesRead += bytesRead;
1264+
if (totalBytesRead > key_length) {
1265+
// read rest of process input to avoid broken pipe error
1266+
while (!feof(fp)) {
1267+
fread(buffer, sizeof(char), bufsize, fp);
1268+
}
12631269

1264-
if (totalBytesRead > key_length) {
1265-
// read rest of process input to avoid broken pipe error
1266-
while (!feof(fp)) {
1267-
fread(buffer, sizeof(char), bufsize, fp);
1270+
pclose(fp);
1271+
die("Error: cannot embed key in AppImage: size exceeds reserved ELF section size");
12681272
}
12691273

1270-
pclose(fp);
1271-
die("Error: cannot embed key in AppImage: size exceeds reserved ELF section size");
1274+
size_t bytesWritten = fwrite(buffer, sizeof(char), bytesRead, destinationfp);
1275+
1276+
if (bytesRead != bytesWritten) {
1277+
char message[128];
1278+
sprintf(message, "Error: Bytes read and written differ: %lu != %lu",
1279+
(long unsigned) bytesRead, (long unsigned) bytesWritten);
1280+
die(message);
1281+
}
12721282
}
12731283

1274-
size_t bytesWritten = fwrite(buffer, sizeof(char), bytesRead, destinationfp);
1284+
int exportexitcode = pclose(fp);
1285+
fp = NULL;
12751286

1276-
if (bytesRead != bytesWritten) {
1287+
if (exportexitcode != 0) {
12771288
char message[128];
1278-
sprintf(message, "Error: Bytes read and written differ: %lu != %lu",
1279-
(long unsigned) bytesRead, (long unsigned) bytesWritten);
1289+
sprintf(message, "GPG key export failed: exit code %d", exportexitcode);
12801290
die(message);
12811291
}
1282-
}
12831292

1284-
int exportexitcode = pclose(fp);
1285-
fp = NULL;
1286-
1287-
if (exportexitcode != 0) {
1288-
char message[128];
1289-
sprintf(message, "GPG key export failed: exit code %d", exportexitcode);
1290-
die(message);
1293+
fclose(destinationfp);
12911294
}
1292-
1293-
fclose(destinationfp);
12941295
}
12951296
}
12961297
}

0 commit comments

Comments
 (0)