ConnectionKit和SFTP:如何验证CK2FileManager

时间:2013-11-15 11:06:04

标签: objective-c cocoa sftp connectionkit

对于我的Mac OS X Cocoa应用,我正在尝试

  • 连接到仅接受用户名/密码凭据的SFTP服务器
  • 获取远程目录的内容
  • 上传文件

并且发现它非常复杂。

尝试ConnectionKit(几乎没有文档),NMSSH(经常崩溃同时上传),rsync(服务器不支持),sftp(如果编写脚本需要密钥验证,不能使用用户名/密码),我现在回到ConnectionKit:https://github.com/karelia/ConnectionKit

但是,我正在努力应对身份验证挑战,因为我不知道如何在委托方法中使用我的凭据。

  • 我下载并编译了ConnectionKit(显然是版本2)。
  • 我正在尝试使用CK2FileManager作为Readme表示(这是正确的方法吗?或者我应该使用libssh2_sftp-Cocoa-wrapper吗?...但是我之前在NMSSH中遇到了libssh2阻塞方法的麻烦)
  • 我正在成功设置我的连接网址和
  • 我的代表'-didReceiveAuthenticationChallenge被称为

但这是我挣扎的地方:我知道如何创建一个NSURLCredential,但是,我无法弄清楚如何处理它=>

- (void)fileManager:(CK2FileManager *)manager
 didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{
  NSURLCredential *credentials = [NSURLCredential 
    credentialWithUser:self.username
    password:[self getPassword]
    persistence:NSURLCredentialPersistenceForSession];

    // what to do now?
    // [manager useCredential:] doesn’t exist, nor is there a manager.connection?
    // ...
}

我已阅读标题,我搜索了此列表的档案,但所有答案似乎都已过时。 我还搜索了Google,Bing和StackOverflow,并在2011年使用CKFTPConnection找到了一个很有希望的例子,它似乎不再包含在当前框架中。

非常感谢任何指向正确方向的指针。


TL;博士

我不知道如何回应ConnectionKit的CK2FileManager authenticationChallenge: 请参阅代码示例中的注释

2 个答案:

答案 0 :(得分:3)

对于CK2:

- (void)listDirectoryAtPath:(NSString *)path
{
    // path is here   @"download"
    NSURL *ftpServer = [NSURL URLWithString:@"sftp://companyname.topLevelDomain"];
    NSURL *directory = [CK2FileManager URLWithPath:path isDirectory:YES hostURL:ftpServer];

    CK2FileManager *fileManager = [[CK2FileManager alloc] init];
    fileManager.delegate = self;

    [fileManager contentsOfDirectoryAtURL:directory
               includingPropertiesForKeys:nil
                                  options:NSDirectoryEnumerationSkipsHiddenFiles
                        completionHandler:^(NSArray *contents, NSError *error) {
                            if (!error) {
                                NSLog(@"%@", contents);
                            } else {
                                NSLog(@"ERROR: %@", error.localizedDescription);
                            }
                        }];

}

并且您必须实施以下协议

- (void)fileManager:(CK2FileManager *)manager operation:(CK2FileOperation *)operation
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(CK2AuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
    if (![challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault]) {
        completionHandler(CK2AuthChallengePerformDefaultHandling, nil);
        return;
    }

    NSString * username = @"<username>";
    NSString * pathToPrivateSSHKey = @"</Users/myNameOnLocalMaschine/.ssh/id_rsa>"

    NSURLCredential *cred = [NSURLCredential ck2_credentialWithUser:username
                                                       publicKeyURL:nil
                                                      privateKeyURL:[NSURL fileURLWithPath:pathToPrivateSSHKey]
                                                           password:nil
                                                        persistence:NSURLCredentialPersistenceForSession];
    completionHandler(CK2AuthChallengeUseCredential, cred);

}

就是这样。

调用-listDirectoryAtPath:然后您将进入内容数组中的Completion Handler Block所有位于给定路径上的文件:)

答案 1 :(得分:1)

好的,这很简单,我可以自己发现;仅供参考:[[challenge sender] useCredential:credentials forAuthenticationChallenge:challenge];

很抱歉为自己的问题奖励自己,但也许这段代码片段可以帮助填写丢失的文档,这就是我使用ConnectionKit连接到SFTP服务器的方式:

- (void)connectWithCompletionBlock:(void (^)(void))completionBlock {
    if(!self.cFileManager) {
        self.cFileManager = [[CK2FileManager alloc] init];
        self.cFileManager.delegate = self;
    }
    NSURL *sftpServer = [NSURL URLWithString:[@"sftp://" stringByAppendingString:self.server]];
    self.remoteFolder = [CK2FileManager URLWithPath:self.remotePath relativeToURL:sftpServer];
    // try to get the contents of the current directory
    [self.cFileManager contentsOfDirectoryAtURL:self.remoteFolder
        includingPropertiesForKeys:nil
        options:NSDirectoryEnumerationSkipsHiddenFiles
        completionHandler:^(NSArray *contents, NSError *error) 
    {
        NSLog(@"remote folder contents: \n%@", contents);
    // invoke completion block
    completionBlock();
    }];
}



- (void)fileManager:(CK2FileManager *)manager
 didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{
    NSURLCredential *credentials = [NSURLCredential 
      credentialWithUser:self.username
      password:[self getPassword]
      persistence:NSURLCredentialPersistenceForSession];
    [[challenge sender] useCredential:credentials forAuthenticationChallenge:challenge]
}