get back the old gitx_asskpasswd

This commit is contained in:
German Laullon
2011-05-08 19:51:40 -07:00
parent 3c3b9ad6e1
commit fb6abc7de7
2 changed files with 149 additions and 226 deletions
+2 -2
View File
@@ -68,8 +68,8 @@
if ([PBGitDefaults useAskPasswd]) {
// Make sure Git's SSH password requests get forwarded to our little UI tool:
setenv( "SSH_ASKPASS", [[[NSBundle mainBundle] pathForResource: @"gitx_askpasswd" ofType: @""] UTF8String], 1 );
setenv( "DISPLAY", "localhost:0", 1 );
setenv( "SSH_ASKPASS", [[[NSBundle mainBundle] pathForResource: @"gitx_askpasswd" ofType: @""] UTF8String], 1 );
setenv( "DISPLAY", "localhost:0", 1 );
}
[self registerServices];
+147 -224
View File
@@ -9,243 +9,166 @@
#include <ApplicationServices/ApplicationServices.h>
#import <AppKit/AppKit.h>
#include <errno.h>
#include <string.h>
#include <sys/sysctl.h>
#include <Security/Security.h>
#include <CoreServices/CoreServices.h>
#include <Security/SecKeychain.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecAccess.h>
#include <Security/SecTrustedApplication.h>
#include <Security/SecACL.h>
#include <CoreFoundation/CoreFoundation.h>
#define OKBUTTONWIDTH 100.0
#define OKBUTTONHEIGHT 24.0
#define CANCELBUTTONWIDTH 100.0
#define CANCELBUTTONHEIGHT 24.0
#define PASSHEIGHT 22.0
#define PASSLABELHEIGHT 16.0
#define WINDOWAUTOSAVENAME @"GitXAskPasswordWindowFrame"
#define OKBUTTONWIDTH 100.0
#define OKBUTTONHEIGHT 24.0
#define CANCELBUTTONWIDTH 100.0
#define CANCELBUTTONHEIGHT 24.0
#define PASSHEIGHT 22.0
#define PASSLABELHEIGHT 16.0
#define WINDOWAUTOSAVENAME @"GitXAskPasswordWindowFrame"
@interface GAPAppDelegate : NSObject /*<NSApplicationDelegate>*/
@interface GAPAppDelegate : NSObject
{
NSPanel* mPasswordPanel;
NSSecureTextField* mPasswordField;
}
-(NSPanel*) passwordPanel;
-(IBAction) doOKButton: (id)sender;
-(IBAction) doCancelButton: (id)sender;
@end
@implementation GAPAppDelegate
-(NSPanel*) passwordPanel
{
if( !mPasswordPanel )
{
NSRect box = NSMakeRect( 100, 100, 400, 134 );
mPasswordPanel = [[NSPanel alloc] initWithContentRect: box
styleMask: NSTitledWindowMask
backing: NSBackingStoreBuffered defer: NO];
[mPasswordPanel setHidesOnDeactivate: NO];
[mPasswordPanel setLevel: NSFloatingWindowLevel];
[mPasswordPanel setTitle: @"GitX SSH Remote Login"];
if (![mPasswordPanel setFrameUsingName: WINDOWAUTOSAVENAME]) {
[mPasswordPanel center];
[mPasswordPanel setFrameAutosaveName: WINDOWAUTOSAVENAME];
}
box.origin = NSZeroPoint; // Only need local coords from now on.
// OK:
NSRect okBox = box;
okBox.origin.x = NSMaxX( box ) -OKBUTTONWIDTH -20;
okBox.size.width = OKBUTTONWIDTH;
okBox.origin.y += 20;
okBox.size.height = OKBUTTONHEIGHT;
NSButton *okButton = [[NSButton alloc] initWithFrame: okBox];
[okButton setTarget: self];
[okButton setAction: @selector(doOKButton:)];
[okButton setTitle: @"OK"]; // +++ Localize.
[okButton setKeyEquivalent: @"\r"];
[okButton setBordered: YES];
[okButton setBezelStyle: NSRoundedBezelStyle];
[[mPasswordPanel contentView] addSubview: okButton];
// Cancel:
NSRect cancelBox = box;
cancelBox.origin.x = NSMinX( okBox ) -CANCELBUTTONWIDTH -6;
cancelBox.size.width = CANCELBUTTONWIDTH;
cancelBox.origin.y += 20;
cancelBox.size.height = CANCELBUTTONHEIGHT;
NSButton *cancleButton = [[NSButton alloc] initWithFrame: cancelBox];
[cancleButton setTarget: self];
[cancleButton setAction: @selector(doCancelButton:)];
[cancleButton setTitle: @"Cancel"]; // +++ Localize.
[cancleButton setBordered: YES];
[cancleButton setBezelStyle: NSRoundedBezelStyle];
[[mPasswordPanel contentView] addSubview: cancleButton];
// Password field:
NSRect passBox = box;
passBox.origin.y = NSMaxY(okBox) + 24;
passBox.size.height = PASSHEIGHT;
passBox.origin.x += 104;
passBox.size.width -= 104 + 20;
mPasswordField = [[NSSecureTextField alloc] initWithFrame: passBox];
[mPasswordField setSelectable: YES];
[mPasswordField setEditable: YES];
[mPasswordField setBordered: YES];
[mPasswordField setBezeled: YES];
[mPasswordField setBezelStyle: NSTextFieldSquareBezel];
[mPasswordField selectText: self];
[[mPasswordPanel contentView] addSubview: mPasswordField];
// Password label:
NSRect passLabelBox = box;
passLabelBox.origin.y = NSMaxY(passBox) + 8;
passLabelBox.size.height = PASSLABELHEIGHT;
passLabelBox.origin.x += 100;
passLabelBox.size.width -= 100 + 20;
NSTextField *passwordLabel = [[NSTextField alloc] initWithFrame: passLabelBox];
[passwordLabel setSelectable: YES];
[passwordLabel setEditable: NO];
[passwordLabel setBordered: NO];
[passwordLabel setBezeled: NO];
[passwordLabel setDrawsBackground: NO];
[passwordLabel setStringValue: @"Please enter your password:"]; // +++ Localize.
[[mPasswordPanel contentView] addSubview: passwordLabel];
// GitX icon:
NSRect gitxIconBox = box;
gitxIconBox.origin.y = NSMaxY(box) - 78;
gitxIconBox.size.height = 64;
gitxIconBox.origin.x += 20;
gitxIconBox.size.width = 64;
NSImageView *gitxIconView = [[NSImageView alloc] initWithFrame: gitxIconBox];
[gitxIconView setEditable: NO];
NSString *gitxIconPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"gitx.icns"];
NSImage *gitxIcon = [[NSImage alloc] initWithContentsOfFile: gitxIconPath];
[gitxIconView setImage: gitxIcon];
[[mPasswordPanel contentView] addSubview: gitxIconView];
}
return mPasswordPanel;
}
-(IBAction) doOKButton: (id)sender
{
printf( "%s\n", [[mPasswordField stringValue] UTF8String] );
[[NSApplication sharedApplication] stopModalWithCode: 0];
}
// TODO: Need to find out how to get SSH to cancel.
// When the user cancels the window it is opened again for however
// many times the remote server allows failed attempts.
-(IBAction) doCancelButton: (id)sender
{
[[NSApplication sharedApplication] stopModalWithCode: 1];
}
@end
NSString* url;
OSStatus StorePasswordKeychain (const char *url, UInt32 urlLength, void* password,UInt32 passwordLength);
@implementation GAPAppDelegate
-(void)yesNo:(NSString *)prompt url:(NSString *)url{
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"YES"];
[alert addButtonWithTitle:@"NO"];
[alert setMessageText:[NSString stringWithFormat:@"%@?",url]];
[alert setInformativeText:prompt];
[alert setAlertStyle:NSWarningAlertStyle];
NSInteger result = [alert runModal];
Boolean yes=NO;
if ( result == NSAlertFirstButtonReturn ) {
yes=YES;
}
[alert release];
printf("%s",yes?"yes":"no");
}
- (void)pasword:(NSString *)prompt url:(NSString *)url{
NSRect box = NSMakeRect(0, 0, 200, 24);
NSSecureTextField * passView = [[NSSecureTextField alloc] initWithFrame: box];
[passView setSelectable: YES];
[passView setEditable: YES];
[passView setBordered: YES];
[passView setBezeled: YES];
[passView setBezelStyle: NSTextFieldSquareBezel];
[passView selectText: self];
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"Ok"];
[alert addButtonWithTitle:@"cancel"];
[alert setMessageText:[NSString stringWithFormat:@"%@?",url]];
[alert setInformativeText:prompt];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setAccessoryView:passView];
[alert setShowsSuppressionButton:YES];
[[alert suppressionButton] setTitle:@"Save on keychain"];
NSInteger result = [alert runModal];
if ( result == NSAlertFirstButtonReturn ) {
NSString *pas=[passView stringValue];
printf( "%s", [pas UTF8String] );
if ([[alert suppressionButton] state] == NSOnState) {
StorePasswordKeychain ([url cStringUsingEncoding:NSASCIIStringEncoding],
[url lengthOfBytesUsingEncoding:NSASCIIStringEncoding],
(void *)[pas cStringUsingEncoding:NSASCIIStringEncoding],
[pas lengthOfBytesUsingEncoding:NSASCIIStringEncoding]);
}
}
[alert release];
}
@end
void getproclline(pid_t pid, char *command_name);
void getproclline(pid_t pid, char *command_name)
int main( int argc, const char** argv )
{
int mib[3], argmax, nargs, c = 0;
size_t size;
char *procargs, *sp, *np, *cp;
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
size = sizeof(argmax);
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) {
return;
}
/* Allocate space for the arguments. */
procargs = (char *)malloc(argmax);
if (procargs == NULL) {
return;
}
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = pid;
size = (size_t)argmax;
if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) {
return;
}
memcpy(&nargs, procargs, sizeof(nargs));
cp = procargs + sizeof(nargs);
/* Skip the saved exec_path. */
for (; cp < &procargs[size]; cp++) {
if (*cp == '\0') {
/* End of exec_path reached. */
break;
}
}
if (cp == &procargs[size]) {
return;
}
/* Skip trailing '\0' characters. */
for (; cp < &procargs[size]; cp++) {
if (*cp != '\0') {
/* Beginning of first argument reached. */
break;
}
}
if (cp == &procargs[size]) {
return;
}
/* Save where the argv[0] string starts. */
sp = cp;
for (np = NULL; c < nargs && cp < &procargs[size]; cp++) {
if (*cp == '\0') {
c++;
if (np != NULL) {
*np = ' ';
}
np = cp;
}
}
sprintf(command_name, "%s",sp);
}
OSStatus StorePasswordKeychain (const char *url, UInt32 urlLength, void* password,UInt32 passwordLength)
{
OSStatus status;
status = SecKeychainAddGenericPassword (
NULL, // default keychain
4, // length of service name
"GitX", // service name
urlLength, // length of account name
url, // account name
passwordLength, // length of password
password, // pointer to password data
NULL // the item reference
);
return (status);
}
OSStatus GetPasswordKeychain (const char *url, UInt32 urlLength ,void *passwordData,UInt32 *passwordLength,
SecKeychainItemRef *itemRef)
{
OSStatus status ;
status = SecKeychainFindGenericPassword (
NULL, // default keychain
4, // length of service name
"GitX", // service name
urlLength, // length of account name
url, // account name
passwordLength, // length of password
passwordData, // pointer to password data
itemRef // the item reference
);
return (status);
}
int main( int argc, const char* argv[] )
{
// close stderr to stop cocoa log messages from being picked up by GitX
close(STDERR_FILENO);
// close stderr to stop cocoa log messages from being picked up by GitX
close(STDERR_FILENO);
ProcessSerialNumber myPSN = { 0, kCurrentProcess };
TransformProcessType( &myPSN, kProcessTransformToForegroundApplication );
NSApplication *app = [NSApplication sharedApplication];
GAPAppDelegate *appDel = [[GAPAppDelegate alloc] init];
[app setDelegate: appDel];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
char args[4024];
getproclline(getppid(),args);
NSString *cmd=[NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:args]];
ProcessSerialNumber myPSN = { 0, kCurrentProcess };
TransformProcessType( &myPSN, kProcessTransformToForegroundApplication );
NSLog(@"cmd: '%@'",cmd);
NSApplication *app = [NSApplication sharedApplication];
GAPAppDelegate *appDel = [[GAPAppDelegate alloc] init];
[app setDelegate: appDel];
NSWindow *passPanel = [appDel passwordPanel];
if([cmd hasPrefix:@"git-remote"]){
NSArray *args=[cmd componentsSeparatedByString:@" "];
NSString *url=[args objectAtIndex:[args count]-1];
void *passwordData = nil;
SecKeychainItemRef itemRef = nil;
UInt32 passwordLength = 0;
OSStatus status = GetPasswordKeychain ([url cStringUsingEncoding:NSASCIIStringEncoding],[url lengthOfBytesUsingEncoding:NSASCIIStringEncoding],&passwordData,&passwordLength,&itemRef);
if (status == noErr) {
SecKeychainItemFreeContent (NULL,passwordData);
NSString *pas=[[NSString stringWithCString:passwordData encoding:NSASCIIStringEncoding] substringToIndex:passwordLength];
printf( "%s", [pas UTF8String] );
return 0;
}
NSString *prompt=[NSString stringWithFormat:@"%@",[NSString stringWithCString:argv[1] encoding:NSASCIIStringEncoding]];
[appDel pasword:prompt url:url];
}else{ // yes/no?
NSString *prompt=[NSString stringWithFormat:@"%@",[NSString stringWithCString:argv[1] encoding:NSASCIIStringEncoding]];
NSArray *args=[cmd componentsSeparatedByString:@" "];
NSString *url=[args objectAtIndex:1];
[appDel yesNo:prompt url:url];
}
[app activateIgnoringOtherApps: YES];
[passPanel makeKeyAndOrderFront: nil];
NSInteger code = [app runModalForWindow: passPanel];
return 0;
}
[defaults synchronize];
return code;
}