9
9
10
10
#include < ApplicationServices/ApplicationServices.h>
11
11
#import < AppKit/AppKit.h>
12
+ #include < errno.h>
13
+ #include < string.h>
14
+ #include < sys/sysctl.h>
15
+ #include < Security/Security.h>
16
+ #include < CoreServices/CoreServices.h>
17
+ #include < Security/SecKeychain.h>
18
+ #include < Security/SecKeychainItem.h>
19
+ #include < Security/SecAccess.h>
20
+ #include < Security/SecTrustedApplication.h>
21
+ #include < Security/SecACL.h>
22
+ #include < CoreFoundation/CoreFoundation.h>
12
23
13
24
#define OKBUTTONWIDTH 100.0
14
25
#define OKBUTTONHEIGHT 24.0
@@ -23,19 +34,22 @@ @interface GAPAppDelegate : NSObject
23
34
{
24
35
NSPanel * mPasswordPanel;
25
36
NSSecureTextField * mPasswordField;
37
+ NSButton * rememberCheck;
26
38
}
27
39
28
- -(NSPanel *) passwordPanel ;
40
+ -(NSPanel *) passwordPanel ;
29
41
30
42
-(IBAction ) doOKButton : (id )sender ;
31
43
-(IBAction ) doCancelButton : (id )sender ;
32
44
33
45
@end
34
46
47
+ NSString * url;
48
+
35
49
36
50
@implementation GAPAppDelegate
37
51
38
- -(NSPanel *) passwordPanel
52
+ -(NSPanel *)passwordPanel : ( NSString *) prompt remember : ( BOOL ) remember
39
53
{
40
54
if ( !mPasswordPanel )
41
55
{
@@ -67,7 +81,7 @@ -(NSPanel*) passwordPanel
67
81
[okButton setBordered: YES ];
68
82
[okButton setBezelStyle: NSRoundedBezelStyle ];
69
83
[[mPasswordPanel contentView ] addSubview: okButton];
70
-
84
+
71
85
// Cancel:
72
86
NSRect cancelBox = box;
73
87
cancelBox.origin .x = NSMinX ( okBox ) -CANCELBUTTONWIDTH -6 ;
@@ -109,9 +123,24 @@ -(NSPanel*) passwordPanel
109
123
[passwordLabel setBordered: NO ];
110
124
[passwordLabel setBezeled: NO ];
111
125
[passwordLabel setDrawsBackground: NO ];
112
- [passwordLabel setStringValue: @" Please enter your password: " ]; // +++ Localize.
126
+ [passwordLabel setStringValue: prompt];
113
127
[[mPasswordPanel contentView ] addSubview: passwordLabel];
114
128
129
+ // remember buton:
130
+ if (remember){
131
+ NSRect rememberBox = box;
132
+ rememberBox.origin .x = 100 ;
133
+ rememberBox.size .width = CANCELBUTTONWIDTH;
134
+ rememberBox.origin .y += 20 ;
135
+ rememberBox.size .height = CANCELBUTTONHEIGHT;
136
+ rememberCheck = [[NSButton alloc ] initWithFrame: rememberBox];
137
+ [rememberCheck setButtonType: NSSwitchButton ];
138
+ [rememberCheck setTarget: self ];
139
+ [rememberCheck setTitle: @" Remenber" ]; // +++ Localize.
140
+ [rememberCheck setKeyEquivalent: @" \r " ];
141
+ [[mPasswordPanel contentView ] addSubview: rememberCheck];
142
+ }
143
+
115
144
// GitX icon:
116
145
NSRect gitxIconBox = box;
117
146
gitxIconBox.origin .y = NSMaxY (box) - 78 ;
@@ -132,7 +161,15 @@ -(NSPanel*) passwordPanel
132
161
133
162
-(IBAction ) doOKButton : (id )sender
134
163
{
135
- printf ( " %s \n " , [[mPasswordField stringValue ] UTF8String ] );
164
+ NSString *pas=[mPasswordField stringValue ];
165
+ printf ( " %s \n " , [pas UTF8String ] );
166
+
167
+ StorePasswordKeychain ([url cStringUsingEncoding: NSASCIIStringEncoding],
168
+ [url lengthOfBytesUsingEncoding: NSASCIIStringEncoding],
169
+ [pas cStringUsingEncoding: NSASCIIStringEncoding],
170
+ [pas lengthOfBytesUsingEncoding: NSASCIIStringEncoding]); // Call
171
+
172
+
136
173
[[NSApplication sharedApplication ] stopModalWithCode: 0 ];
137
174
}
138
175
@@ -147,9 +184,111 @@ -(IBAction) doCancelButton: (id)sender
147
184
148
185
@end
149
186
187
+ void getproclline (pid_t pid, char *command_name);
188
+
189
+ void getproclline (pid_t pid, char *command_name)
190
+ {
191
+ int mib[3 ], argmax, nargs, c = 0 ;
192
+ size_t size;
193
+ char *procargs, *sp, *np, *cp;
194
+
195
+ mib[0 ] = CTL_KERN;
196
+ mib[1 ] = KERN_ARGMAX;
197
+
198
+ size = sizeof (argmax);
199
+ if (sysctl (mib, 2 , &argmax, &size, NULL , 0 ) == -1 ) {
200
+ return ;
201
+ }
202
+
203
+ /* Allocate space for the arguments. */
204
+ procargs = (char *)malloc (argmax);
205
+ if (procargs == NULL ) {
206
+ return ;
207
+ }
208
+
209
+ mib[0 ] = CTL_KERN;
210
+ mib[1 ] = KERN_PROCARGS2;
211
+ mib[2 ] = pid;
212
+
213
+ size = (size_t )argmax;
214
+ if (sysctl (mib, 3 , procargs, &size, NULL , 0 ) == -1 ) {
215
+ return ;
216
+ }
217
+
218
+ memcpy (&nargs, procargs, sizeof (nargs));
219
+ cp = procargs + sizeof (nargs);
220
+
221
+ /* Skip the saved exec_path. */
222
+ for (; cp < &procargs[size]; cp++) {
223
+ if (*cp == ' \0 ' ) {
224
+ /* End of exec_path reached. */
225
+ break ;
226
+ }
227
+ }
228
+ if (cp == &procargs[size]) {
229
+ return ;
230
+ }
231
+
232
+ /* Skip trailing '\0' characters. */
233
+ for (; cp < &procargs[size]; cp++) {
234
+ if (*cp != ' \0 ' ) {
235
+ /* Beginning of first argument reached. */
236
+ break ;
237
+ }
238
+ }
239
+ if (cp == &procargs[size]) {
240
+ return ;
241
+ }
242
+ /* Save where the argv[0] string starts. */
243
+ sp = cp;
244
+
245
+ for (np = NULL ; c < nargs && cp < &procargs[size]; cp++) {
246
+ if (*cp == ' \0 ' ) {
247
+ c++;
248
+ if (np != NULL ) {
249
+ *np = ' ' ;
250
+ }
251
+ np = cp;
252
+ }
253
+ }
254
+ sprintf (command_name, " %s " ,sp);
255
+ }
256
+
257
+ OSStatus StorePasswordKeychain (const char *url, UInt32 urlLength, void * password,UInt32 passwordLength)
258
+ {
259
+ OSStatus status;
260
+ status = SecKeychainAddGenericPassword (
261
+ NULL , // default keychain
262
+ 4 , // length of service name
263
+ " GitX" , // service name
264
+ urlLength, // length of account name
265
+ url, // account name
266
+ passwordLength, // length of password
267
+ password, // pointer to password data
268
+ NULL // the item reference
269
+ );
270
+ return (status);
271
+ }
150
272
273
+ OSStatus GetPasswordKeychain (const char *url, UInt32 urlLength ,void *passwordData,UInt32 *passwordLength,
274
+ SecKeychainItemRef *itemRef)
275
+ {
276
+ OSStatus status ;
277
+ status = SecKeychainFindGenericPassword (
278
+ NULL , // default keychain
279
+ 4 , // length of service name
280
+ " GitX" , // service name
281
+ urlLength, // length of account name
282
+ url, // account name
283
+ passwordLength, // length of password
284
+ passwordData, // pointer to password data
285
+ itemRef // the item reference
286
+ );
287
+ return (status);
288
+ }
151
289
152
- int main ( int argc, const char ** argv )
290
+
291
+ int main ( int argc, const char * argv[] )
153
292
{
154
293
// close stderr to stop cocoa log messages from being picked up by GitX
155
294
close (STDERR_FILENO);
@@ -162,14 +301,47 @@ int main( int argc, const char** argv )
162
301
NSApplication *app = [NSApplication sharedApplication ];
163
302
GAPAppDelegate *appDel = [[GAPAppDelegate alloc ] init ];
164
303
[app setDelegate: appDel];
165
- NSWindow *passPanel = [appDel passwordPanel ];
166
304
167
- [app activateIgnoringOtherApps: YES ];
168
- [passPanel makeKeyAndOrderFront: nil ];
169
- NSInteger code = [app runModalForWindow: passPanel];
305
+ char args[4024 ];
306
+ getproclline (getppid (),args);
307
+ NSString *cmd=[NSString stringWithFormat: @" %@ " ,[NSString stringWithUTF8String: args]];
308
+
309
+ NSString *prompt=@" ???" ;
310
+
311
+ url=@" poipoi" ;
312
+
313
+ if ([cmd hasPrefix: @" git-remote-https" ]){
314
+ NSArray *args=[cmd componentsSeparatedByString: @" " ];
315
+ url=[args objectAtIndex: [args count ]-1 ];
316
+ }else if ((sizeof (argv)/sizeof (char *))>1 ){
317
+ prompt=[NSString stringWithCString: argv[1 ] encoding: NSASCIIStringEncoding];
318
+ }else {
319
+ prompt=@" null" ;
320
+ }
321
+
322
+
323
+ OSStatus status,status1;
324
+ void *passwordData = nil ;
325
+ SecKeychainItemRef itemRef = nil ;
326
+ UInt32 passwordLength = nil ;
327
+
328
+ status1 = GetPasswordKeychain ([url cStringUsingEncoding: NSASCIIStringEncoding],[url lengthOfBytesUsingEncoding: NSASCIIStringEncoding],&passwordData,&passwordLength,&itemRef);
329
+ if (status1 == noErr) {
330
+ SecKeychainItemFreeContent (NULL ,passwordData);
331
+ }
332
+
333
+ NSInteger code;
334
+
335
+ if (passwordLength>0 ){
336
+ NSString *pass=[NSString stringWithCString: passwordData encoding: NSASCIIStringEncoding];
337
+ }else {
338
+ NSWindow *passPanel = [appDel passwordPanel: prompt remember: NO ];
339
+ [app activateIgnoringOtherApps: YES ];
340
+ [passPanel makeKeyAndOrderFront: nil ];
341
+ code = [app runModalForWindow: passPanel];
342
+ }
170
343
171
344
[defaults synchronize ];
172
345
173
346
return code;
174
347
}
175
-
0 commit comments