|
13 | 13 | // You should have received a copy of the GNU General Public License
|
14 | 14 | // along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15 | 15 |
|
16 |
| -#import <Security/Security.h> |
17 | 16 | #pragma clang diagnostic push
|
18 | 17 | #pragma clang diagnostic ignored "-Wobjc-interface-ivars"
|
19 | 18 | #import <HockeySDK/HockeySDK.h>
|
20 | 19 | #pragma clang diagnostic pop
|
21 | 20 | #import <Sparkle/Sparkle.h>
|
22 | 21 |
|
| 22 | +#import <GitUpKit/GitUpKit.h> |
23 | 23 | #import <GitUpKit/XLFacilityMacros.h>
|
24 | 24 |
|
25 | 25 | #import "AppDelegate.h"
|
@@ -52,11 +52,6 @@ @implementation AppDelegate {
|
52 | 52 | BOOL _updatePending;
|
53 | 53 | BOOL _manualCheck;
|
54 | 54 |
|
55 |
| - BOOL _authenticationUseKeychain; |
56 |
| - NSURL* _authenticationURL; |
57 |
| - NSString* _authenticationUsername; |
58 |
| - NSString* _authenticationPassword; |
59 |
| - |
60 | 55 | CFMessagePortRef _messagePort;
|
61 | 56 | }
|
62 | 57 |
|
@@ -103,89 +98,6 @@ + (instancetype)sharedDelegate {
|
103 | 98 | return (AppDelegate*)[NSApp delegate];
|
104 | 99 | }
|
105 | 100 |
|
106 |
| -// WARNING: We are using the same attributes for the keychain items than Git CLT appears to be using as of version 1.9.3 |
107 |
| -+ (BOOL)loadPlainTextAuthenticationFormKeychainForURL:(NSURL*)url user:(NSString*)user username:(NSString**)username password:(NSString**)password allowInteraction:(BOOL)allowInteraction { |
108 |
| - const char* serverName = url.host.UTF8String; |
109 |
| - if (serverName && serverName[0]) { // TODO: How can this be NULL? |
110 |
| - const char* accountName = (*username).UTF8String; |
111 |
| - SecKeychainItemRef itemRef; |
112 |
| - UInt32 passwordLength; |
113 |
| - void* passwordData; |
114 |
| - SecKeychainSetUserInteractionAllowed(allowInteraction); // Ignore errors |
115 |
| - OSStatus status = SecKeychainFindInternetPassword(NULL, |
116 |
| - (UInt32)strlen(serverName), serverName, |
117 |
| - 0, NULL, // Any security domain |
118 |
| - accountName ? (UInt32)strlen(accountName) : 0, accountName, |
119 |
| - 0, NULL, // Any path |
120 |
| - 0, // Any port |
121 |
| - kSecProtocolTypeAny, |
122 |
| - kSecAuthenticationTypeAny, |
123 |
| - &passwordLength, &passwordData, &itemRef); |
124 |
| - if (status == noErr) { |
125 |
| - BOOL success = NO; |
126 |
| - *password = [[NSString alloc] initWithBytes:passwordData length:passwordLength encoding:NSUTF8StringEncoding]; |
127 |
| - if (accountName == NULL) { |
128 |
| - UInt32 tag = kSecAccountItemAttr; |
129 |
| - UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING; |
130 |
| - SecKeychainAttributeInfo info = {1, &tag, &format}; |
131 |
| - SecKeychainAttributeList* attributes; |
132 |
| - status = SecKeychainItemCopyAttributesAndData(itemRef, &info, NULL, &attributes, NULL, NULL); |
133 |
| - if (status == noErr) { |
134 |
| - XLOG_DEBUG_CHECK(attributes->count == 1); |
135 |
| - XLOG_DEBUG_CHECK(attributes->attr[0].tag == kSecAccountItemAttr); |
136 |
| - *username = [[NSString alloc] initWithBytes:attributes->attr[0].data length:attributes->attr[0].length encoding:NSUTF8StringEncoding]; |
137 |
| - success = YES; |
138 |
| - SecKeychainItemFreeAttributesAndData(attributes, NULL); |
139 |
| - } else { |
140 |
| - XLOG_ERROR(@"SecKeychainItemCopyAttributesAndData() returned error %i", status); |
141 |
| - } |
142 |
| - } else { |
143 |
| - success = YES; |
144 |
| - } |
145 |
| - SecKeychainItemFreeContent(NULL, passwordData); |
146 |
| - CFRelease(itemRef); |
147 |
| - if (success) { |
148 |
| - return YES; |
149 |
| - } |
150 |
| - } else if (status != errSecItemNotFound) { |
151 |
| - XLOG_ERROR(@"SecKeychainFindInternetPassword() returned error %i", status); |
152 |
| - } |
153 |
| - } else { |
154 |
| - XLOG_WARNING(@"Unable to extract hostname from remote URL: %@", url); |
155 |
| - } |
156 |
| - return NO; |
157 |
| -} |
158 |
| - |
159 |
| -+ (void)savePlainTextAuthenticationToKeychainForURL:(NSURL*)url withUsername:(NSString*)username password:(NSString*)password { |
160 |
| - SecProtocolType type; |
161 |
| - if ([url.scheme isEqualToString:@"http"]) { |
162 |
| - type = kSecProtocolTypeHTTP; |
163 |
| - } else if ([url.scheme isEqualToString:@"https"]) { |
164 |
| - type = kSecProtocolTypeHTTPS; |
165 |
| - } else { |
166 |
| - XLOG_DEBUG_UNREACHABLE(); |
167 |
| - return; |
168 |
| - } |
169 |
| - const char* serverName = url.host.UTF8String; |
170 |
| - const char* accountName = username.UTF8String; |
171 |
| - const char* accountPassword = password.UTF8String; |
172 |
| - SecKeychainSetUserInteractionAllowed(true); // Ignore errors |
173 |
| - OSStatus status = SecKeychainAddInternetPassword(NULL, |
174 |
| - (UInt32)strlen(serverName), serverName, |
175 |
| - 0, NULL, // Any security domain |
176 |
| - accountName ? (UInt32)strlen(accountName) : 0, accountName, |
177 |
| - 0, NULL, // Any path |
178 |
| - 0, // Any port |
179 |
| - type, |
180 |
| - kSecAuthenticationTypeAny, |
181 |
| - (UInt32)strlen(accountPassword), accountPassword, NULL); |
182 |
| - if (status != noErr) { |
183 |
| - XLOG_ERROR(@"SecKeychainAddInternetPassword() returned error %i", status); |
184 |
| - } else { |
185 |
| - XLOG_VERBOSE(@"Successfully saved authentication in Keychain"); |
186 |
| - } |
187 |
| -} |
188 |
| - |
189 | 101 | - (void)_setDocumentWindowModeID:(NSArray*)arguments {
|
190 | 102 | [(Document*)arguments[0] setWindowModeID:[arguments[1] unsignedIntegerValue]];
|
191 | 103 | }
|
@@ -704,49 +616,6 @@ - (void)userNotificationCenter:(NSUserNotificationCenter*)center didActivateNoti
|
704 | 616 | }
|
705 | 617 | }
|
706 | 618 |
|
707 |
| -#pragma mark - GCRepositoryDelegate |
708 |
| - |
709 |
| -- (void)repository:(GCRepository*)repository willStartTransferWithURL:(NSURL*)url { |
710 |
| - _authenticationUseKeychain = YES; |
711 |
| - _authenticationURL = nil; |
712 |
| - _authenticationUsername = nil; |
713 |
| - _authenticationPassword = nil; |
714 |
| -} |
715 |
| - |
716 |
| -- (BOOL)repository:(GCRepository*)repository requiresPlainTextAuthenticationForURL:(NSURL*)url user:(NSString*)user username:(NSString**)username password:(NSString**)password { |
717 |
| - if (_authenticationUseKeychain) { |
718 |
| - _authenticationUseKeychain = NO; |
719 |
| - if ([self.class loadPlainTextAuthenticationFormKeychainForURL:url user:user username:username password:password allowInteraction:YES]) { |
720 |
| - return YES; |
721 |
| - } |
722 |
| - } else { |
723 |
| - XLOG_VERBOSE(@"Skipping Keychain lookup for repeated authentication failures"); |
724 |
| - } |
725 |
| - |
726 |
| - _authenticationURLTextField.stringValue = url.absoluteString; |
727 |
| - _authenticationNameTextField.stringValue = *username ? *username : @""; |
728 |
| - _authenticationPasswordTextField.stringValue = @""; |
729 |
| - [_authenticationWindow makeFirstResponder:(*username ? _authenticationPasswordTextField : _authenticationNameTextField)]; |
730 |
| - if ([NSApp runModalForWindow:_authenticationWindow] && _authenticationNameTextField.stringValue.length && _authenticationPasswordTextField.stringValue.length) { |
731 |
| - _authenticationURL = url; |
732 |
| - _authenticationUsername = [_authenticationNameTextField.stringValue copy]; |
733 |
| - _authenticationPassword = [_authenticationPasswordTextField.stringValue copy]; |
734 |
| - *username = _authenticationNameTextField.stringValue; |
735 |
| - *password = _authenticationPasswordTextField.stringValue; |
736 |
| - return YES; |
737 |
| - } |
738 |
| - return NO; |
739 |
| -} |
740 |
| - |
741 |
| -- (void)repository:(GCRepository*)repository didFinishTransferWithURL:(NSURL*)url success:(BOOL)success { |
742 |
| - if (success && _authenticationURL && _authenticationUsername && _authenticationPassword) { |
743 |
| - [self.class savePlainTextAuthenticationToKeychainForURL:_authenticationURL withUsername:_authenticationUsername password:_authenticationPassword]; |
744 |
| - } |
745 |
| - _authenticationURL = nil; |
746 |
| - _authenticationUsername = nil; |
747 |
| - _authenticationPassword = nil; |
748 |
| -} |
749 |
| - |
750 | 619 | #pragma mark - SUUpdaterDelegate
|
751 | 620 |
|
752 | 621 | - (NSString*)feedURLStringForUpdater:(SUUpdater*)updater {
|
|
0 commit comments