Skip to content
Snippets Groups Projects
Commit c32125ff authored by George Nachman's avatar George Nachman
Browse files

Work around an apparent bug in libssh2 where it clobbers known_hosts entries...

Work around an apparent bug in libssh2 where it clobbers known_hosts entries with key types it does not recognize. Issue 4250.
parent 65fc01fd
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -25,4 +25,10 @@
 
- (BOOL)hasPrefixOfBytes:(char *)bytes length:(int)length;
 
// Appends this data to the file at |path|. If |addNewline| is YES then a '\n' is appended if the
// file does not already end with \n or \r. This plays a little fast and loose with character
// encoding, but it gets the job done.
- (BOOL)appendToFile:(NSString *)path addLineBreakIfNeeded:(BOOL)addNewline;
@end
Loading
Loading
@@ -7,6 +7,8 @@
//
 
#import "NSData+iTerm.h"
#import "DebugLogging.h"
#import "RegexKitLite.h"
#import <apr-1/apr_base64.h>
 
Loading
Loading
@@ -105,4 +107,42 @@
return nil;
}
 
- (BOOL)appendToFile:(NSString *)path addLineBreakIfNeeded:(BOOL)addNewline {
NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:path];
if (!fileHandle) {
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
if (!fileHandle) {
DLog(@"Failed to open for writing or create %@", path);
return NO;
}
}
@try {
[fileHandle seekToEndOfFile];
if (addNewline) {
unsigned long long length = fileHandle.offsetInFile;
if (length > 0) {
[fileHandle seekToFileOffset:length - 1];
NSData *data = [fileHandle readDataOfLength:1];
if (data.length == 1) {
char lastByte = ((const char *)data.bytes)[0];
if (lastByte != '\r' && lastByte != '\n') {
[fileHandle seekToEndOfFile];
[fileHandle writeData:[NSData dataWithBytes:"\n" length:1]];
}
}
}
}
[fileHandle writeData:self];
return YES;
}
@catch (NSException * e) {
return NO;
}
@finally {
[fileHandle closeFile];
}
}
@end
Loading
Loading
@@ -13,7 +13,9 @@
#import <NMSSH/libssh2.h>
#import "NSFileManager+iTerm.h"
#import "NSObject+iTerm.h"
#import "NSStringITerm.h"
#import "NSData+iTerm.h"
#import "NSStringiTerm.h"
#import "NSWorkspace+iTerm.h"
 
@interface NMSSHSession(iTerm)
- (id)agent;
Loading
Loading
@@ -401,10 +403,21 @@ static NSError *SCPFileError(NSString *description) {
}
if (_okToAdd) {
// Issue 4250 reveals that libssh2 deletes lines out of known_hosts if it
// does not recognize them. The workaround is to write to a temp file and then append it to
// the real file so libssh2 doesn't have a chance to mess up the real file.
NSString *tempFileName = [[NSWorkspace sharedWorkspace] temporaryFileNameWithPrefix:@"iTerm2" suffix:@"knownHost"];
[[NSFileManager defaultManager] setAttributes:@{ NSFilePosixPermissions: @(0600) }
ofItemAtPath:tempFileName
error:nil];
[self.session addKnownHostName:self.session.host
port:[self.session.port intValue]
toFile:nil
toFile:tempFileName
withSalt:nil];
NSData *newEntry = [NSData dataWithContentsOfFile:tempFileName];
[[NSFileManager defaultManager] removeItemAtPath:tempFileName error:nil];
[newEntry appendToFile:[@"~/.ssh/known_hosts" stringByExpandingTildeInPath] addLineBreakIfNeeded:YES];
}
 
if (isDownload) {
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment