Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #23

Open
wants to merge 59 commits into
base: build-refactoring
Choose a base branch
from
Open

Dev #23

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
038ddb7
installerHelper requests privileges.
Mento Jan 14, 2015
e0b45a4
Symlink for installerHelper
Mento Jan 14, 2015
69e8957
XPC_INSTALLATION_DIR for Release.
Mento Mar 11, 2015
60309de
Get fingerprints from weak keys.
Mento Mar 28, 2015
722b5aa
[NEW] GPGUserIDSignature hashAlgorithm.
Mento Apr 1, 2015
ae68234
GPGKeyManager allowWeakDigestAlgos.
Mento Apr 1, 2015
4b92856
Use KeyID if the fingerprint is nulled.
Mento Apr 1, 2015
92e4934
Call pinentryPath in GPGTask -start.
Mento Apr 1, 2015
9165138
[FIX] Don't reference self directly within hasCompleted check [#142 s…
lukele Apr 22, 2015
c35351c
Merge commit '91651388801eb8f11b8d7493d3dddc5d52f52f5f' into dev
lukele Apr 22, 2015
e112b32
Merge branch 'installerHelper' into dev
Mento Apr 27, 2015
119f140
retainArguments after setTarget.
Mento Apr 27, 2015
bd1db9c
retain autorelease for _allKeysAndSubkeys.
Mento Apr 27, 2015
636e7b4
Fill keys synchronous.
Mento Apr 28, 2015
67c9066
Use a script instead of a symlink.
Mento Apr 29, 2015
1d7d9a6
Stop building, when script fails.
Mento May 14, 2015
9be4444
Start preparing release of version 0.5
lukele May 27, 2015
f7e29b1
References to GPGTools_Core removed.
Mento May 28, 2015
e8a7a24
Merge branch 'master' into stable-release-test
lukele May 28, 2015
3edfa9b
[FIX] Prevent Libmacgpg from segfaulting if XPC connection can't be e…
lukele Jun 19, 2015
aef7546
[FIX] Reply to a processStatus request even if no handler is setup
lukele Jun 19, 2015
bca33c3
GPGStream offset methods added.
Mento Jul 2, 2015
ae86481
GPGUnArmor added.
Mento Jul 2, 2015
717be7a
Use GPGUnArmor.
Mento Jul 2, 2015
eb388f5
Missing commit message for ae86481.
Mento Jul 2, 2015
80b82f8
Handle cacheData correctly.
Mento Jul 3, 2015
d47805e
Un armor before passing to keysInExportedData.
Mento Jul 3, 2015
e643f02
[FIX] Properly close socket connection to gpg-agent when querying if …
lukele Jul 4, 2015
f88d306
GPGPacket copy NSData.
Mento Jul 6, 2015
211c65e
GPGStream readByte added.
Mento Jul 10, 2015
1d1f8ee
Little fixes in GPGUnArmor
Mento Jul 10, 2015
e7658ca
GPGPacket rewrite.
Mento Jul 13, 2015
ab1f195
Wrong name of delegate method.
Mento Jul 13, 2015
0fb5d1f
GPGKeyManager homedir added.
Mento Jul 13, 2015
ba0bed8
UnitTests fixed.
Mento Jul 13, 2015
96b63cc
GPGPacket commented.
Mento Jul 14, 2015
5e4218b
Some strange code fragment removed.
Mento Jul 14, 2015
02a9ee4
More unit tests.
Mento Jul 14, 2015
696aa0a
GPGPacket unit test added.
Mento Jul 15, 2015
b751742
Run all unit tests.
Mento Jul 15, 2015
5306783
Correct handle clear-text with an even number of newlines at the end.
Mento Jul 19, 2015
bcf3ff1
Newline bug in clear-signed text.
Mento Jul 19, 2015
137332c
Clear-signed unit test for GPGUnArmor.
Mento Jul 20, 2015
df30d90
GPGKey revocationSignature added.
Mento Jul 24, 2015
84cca8e
MACOSX_DEPLOYMENT_TARGET for installerHelper removed.
Mento Jul 24, 2015
2e5b21f
base64DecodedData crash on 10.6
Mento Aug 4, 2015
7f92bd3
Better way to find the right pinentry.
Mento Aug 7, 2015
143a118
GPGPacket use seconds instead of date.
Mento Aug 7, 2015
a38a029
Add +capabilitiesOfPackets to GPGPacket.
Mento Aug 7, 2015
092579b
sig field 15 is optional.
Mento Aug 7, 2015
8e02c0c
Fixed install path for Release configuration.
Mento Aug 11, 2015
b4805fc
Version 0.6
Mento Aug 14, 2015
3c1bdc2
[FIX] Crash when parsing PGP messages.
Mento Sep 7, 2015
5e7154d
Working on GPGKeyFetcher.
Mento Sep 7, 2015
cd5c730
GPGRemoteKey fingerprint added.
Mento Sep 7, 2015
c3bec96
Use malloc and limit string length.
Mento Sep 18, 2015
52f2351
GPGPacket: Use the right expiration date.
Mento Sep 21, 2015
f27b8ad
Version 0.6.1
Mento Sep 23, 2015
f9498f3
GPGUnArmor: Handle unicode line separators.
Mento Sep 29, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
797 changes: 570 additions & 227 deletions Libmacgpg.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Script"
scriptText = "mkdir -p &quot;$SOURCE_ROOT/build/$CONFIGURATION&quot;&#10;&#10;if [ ! -z &quot;$(ls &quot;$BUILT_PRODUCTS_DIR&quot;)&quot; ]; then&#10; cp -R &quot;$BUILT_PRODUCTS_DIR/&quot;/* &quot;$SOURCE_ROOT/build/$CONFIGURATION/&quot;&#10; cp -R &quot;$BUILD_ROOT/org.gpgtools.Libmacgpg.xpc.plist&quot; &quot;$SOURCE_ROOT/build/&quot;&#10;fi">
scriptText = "mkdir -p &quot;$SOURCE_ROOT/build/$CONFIGURATION&quot;&#10;&#10;if [ ! -z &quot;$(ls &quot;$BUILT_PRODUCTS_DIR&quot; 2&gt;/dev/null)&quot; ]; then&#10; cp -R &quot;$BUILT_PRODUCTS_DIR/&quot;* &quot;$SOURCE_ROOT/build/$CONFIGURATION/&quot;&#10; cp -R &quot;$BUILD_ROOT/org.gpgtools.Libmacgpg.xpc.plist&quot; &quot;$SOURCE_ROOT/build/&quot;&#10;fi&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
Expand Down Expand Up @@ -67,7 +67,7 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
Expand Down
224 changes: 224 additions & 0 deletions NewUnitTests/GPGSocketCloseTest.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
//
// GPGSocketCloseTest.m
// Libmacgpg
//
// Created by Lukas Pitschl on 04.07.15.
//
//

#import <XCTest/XCTest.h>
#import <Foundation/Foundation.h>
#import <sys/proc.h>
#import <sys/sysctl.h>
#import <sys/proc.h>
#import <sys/proc_info.h>
#import <libproc.h>
#import "Libmacgpg.h"
#import "GPGUnitTest.h"
#import "GPGTaskHelper.h"



@interface GPGSocketCloseTest : XCTestCase
@end

@implementation GPGSocketCloseTest


+ (void)setUp {
[GPGUnitTest setUpTestDirectory];
}


- (uid_t)uidFromPid:(pid_t)pid {
uid_t uid = -1;

struct kinfo_proc process;
size_t procBufferSize = sizeof(process);

// Compose search path for sysctl. Here you can specify PID directly.
const u_int pathLenth = 4;
int path[pathLenth] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};

int sysctlResult = sysctl(path, pathLenth, &process, &procBufferSize, NULL, 0);

// If sysctl did not fail and process with PID available - take UID.
if ((sysctlResult == 0) && (procBufferSize != 0)) {
uid = process.kp_eproc.e_ucred.cr_uid;
}

return uid;
}


- (NSInteger)pidForProcessWithName:(NSString *)name {
NSMutableArray *ret = [NSMutableArray arrayWithCapacity:1];

int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
pid_t pids[1024];
bzero(pids, 1024);
proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
for (int i = 0; i < numberOfProcesses; ++i) {
if (pids[i] == 0) { continue; }
char pathBuffer[PROC_PIDPATHINFO_MAXSIZE];
bzero(pathBuffer, PROC_PIDPATHINFO_MAXSIZE);
proc_pidpath(pids[i], pathBuffer, sizeof(pathBuffer));

NSMutableDictionary *process = [[NSMutableDictionary alloc] init];

process[@"pid"] = @(pids[i]);
process[@"uid"] = @([self uidFromPid:pids[i]]);
process[@"name"] = [@(pathBuffer) lastPathComponent];

[ret addObject:process];
}


unsigned int current_user_id = getuid();

NSInteger pid = -1;
for(NSDictionary *process in ret) {
// Skip processes that don't belong to the current user.
if([process[@"uid"] integerValue] != current_user_id)
continue;
if([process[@"name"] isEqualToString:name])
pid = [process[@"pid"] integerValue];
}

return pid;
}

- (NSArray *)openSocketConnectionForPid:(NSInteger)pid {
int i, nb, nf;
struct proc_fdinfo *fdp;
struct proc_taskallinfo tai;

NSMutableArray *sockets = [NSMutableArray array];

static struct proc_fdinfo *Fds = (struct proc_fdinfo *)NULL;
/* FD buffer */
static int NbFds = 0; /* bytes allocated to FDs */

nb = proc_pidinfo((int)pid, PROC_PIDTASKALLINFO, 0, &tai, sizeof(tai));
int n = tai.pbsd.pbi_nfiles;

/*
* Make sure an FD buffer has been allocated.
*/
if (!Fds) {
NbFds = sizeof(struct proc_fdinfo) * n;
Fds = (struct proc_fdinfo *)malloc(NbFds);
} else if (NbFds < sizeof(struct proc_fdinfo) * n) {

/*
* More proc_fdinfo space is required. Allocate it.
*/
NbFds = sizeof(struct proc_fdinfo) * n;
Fds = (struct proc_fdinfo *)realloc((void *)Fds,
NbFds);
}
/*
* Get FD information for the process.
*/
nb = proc_pidinfo((int)pid, PROC_PIDLISTFDS, 0, Fds, NbFds);
if (nb <= 0) {
if (errno == ESRCH) {

/*
* Quit if no FD information is available for the process.
*/
return nil;
}
}
nf = (int)(nb / sizeof(struct proc_fdinfo));
/*
* Loop through the file descriptors.
*/
for (i = 0; i < nf; i++) {
fdp = &Fds[i];
int fd = fdp->proc_fd;

if(fdp->proc_fdtype != PROX_FDTYPE_SOCKET)
continue;

struct socket_fdinfo si;
nb = proc_pidfdinfo((int)pid, fd, PROC_PIDFDSOCKETINFO, &si, sizeof(si));
// Not necessary to add any error code, since the test will simply fail if an error occurs.

int fam = si.psi.soi_family;
if(fam != AF_UNIX)
continue;
if (si.psi.soi_kind != SOCKINFO_UN)
continue;

int unl;
if (si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path[0]) {
unl = si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_len - offsetof(struct sockaddr_un, sun_path);
if ((unl < 0) || (unl >= sizeof(si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path)))
unl = sizeof(si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path) - 1;
si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path[unl] = '\0';

[sockets addObject:@{@"sunPath": @(si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path)}];
}
}


return sockets;
}

- (NSInteger)numberOfOpenSocketConnections {
NSArray *sockets = [self openSocketConnectionForPid:[self pidForProcessWithName:@"gpg-agent"]];
NSInteger nrOfSockets = 0;
for(NSDictionary *socket in sockets) {
if(![[socket[@"sunPath"] lastPathComponent] isEqualToString:@"S.gpg-agent"])
continue;
nrOfSockets++;
}
return nrOfSockets;
}

- (void)testPassphraseInAgentSocketCloseBug {
// Calling isPassphraseForKeyInGPGAgentCache: seems to trigger a bug where the socket connection
// which is established to the gpg-agent is not always closed.
// This test will only pass if all sockets are properly closed after usage.

// In order to warm the passphrase cache some random data is signed.
NSString *content = @"This content is signed to warm up the passphrase cache.";
NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding];

gpgc.useArmor = YES;
gpgc.useTextMode = YES;
// Automatically trust keys, even though they are not specifically
// marked as such.
// Eventually add warning for this.
gpgc.trustAllKeys = YES;

GPGKey *signerKey = [[GPGKeyManager sharedInstance].allKeys member:testKey2];
XCTAssert(signerKey != nil, @"For this test to run properly, it's necessary to have at least one secret key.");

gpgc.signerKey = signerKey;

NSData *signedContent = [gpgc processData:contentData withEncryptSignMode:GPGSign recipients:nil hiddenRecipients:nil];
XCTAssertNil(gpgc.error, @"Error occured while signing data: %@", gpgc.error);
XCTAssertNotNil(signedContent, @"Failed to sign data");

NSInteger currentNumberOfOpenSocketConnections = [self numberOfOpenSocketConnections];

int maxRuns = 300;
int i = 0;
for(; i < 300; i++) {
BOOL inCache = [GPGTaskHelper isPassphraseInGPGAgentCache:signerKey.fingerprint];
if(!inCache) {
if(i > 0 && i < maxRuns - 1) {
XCTFail(@"Number of available FDs probably exhausted. Bug caught!");
}
else {
XCTFail(@"The passphrase has to be cached in order for the bug to reveal itself.");
}
break;
}
}
XCTAssert([self numberOfOpenSocketConnections] == currentNumberOfOpenSocketConnections, @"What now, a connection still open? Houston, we have a bug");
}

@end
18 changes: 18 additions & 0 deletions Release Notes/0.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Libmacgpg 0.6 - Release Notes
==============================

Features
--------
### Be more tolerant toward malformed messages

* To many line breaks or other minor malformations so far resulted in a message that could not be decrypted. We are now much more tolerant and flexible. [#63, #145, #14, #38]


Bugfixes
--------

* One of the most annoying, infamous bugs has finally gone down meaning users will no longer see the "no pinentry" error. Socket connection to gpg-agent was not closed under some circumstances. [#147]
* One of the most common crashes in the 2015.06 release has been fixed. GPGTaskHelperXPC no longer crashes. [#143]
* Crash in Libmacgpg GPGPacket fixed. [#146]
* Fix: Empty key list in GPG Keychain main window. [#149]
* Fix: Use new pinentry with keychain support for new MacGPG. [#148]
Binary file added Resources/gpgtools.icns
Binary file not shown.
Loading