存档在 ‘技术’ 分类

在Mac OS下创建自动重连、自动保存密码登录的SSH隧道链接

2009年3月19日

SSH的详细用途就不再重复说明了,总之这是一个很强大的技术。
在这之前你需要一个SSH帐号,你可以在淘宝找到卖家,或者直接在Dreamhost、MT等服务商购买。

创建SSH的Socket隧道链接本身其实很简单,在Mac OS的命令行下面只需要一行就可以了:
ssh -D 7777 username@yourhost.com 参看livid的关于SSH/PAC配置的详细说明

然而每次都需要密码,并且超时断线的时候也需要手工重连,实在是很麻烦的事情,我参考网上的一系列资料拼装了自己的方案,开机自动链接,保存密码输入,断线自动重连。

首先是保存密码输入问题,需要创建密钥,在你的命令行输入:
local:~ yourname$ ssh-keygen -t rsa

然后依次回车,输入密码,这个密码和SSH的帐号密码无关。
整个界面看上去类似:
local:~ yourname$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/u/kim/.ssh/id_rsa): 【回车】
Enter passphrase (empty for no passphrase): 【第一次密码】
Enter same passphrase again: 【第二次密码】
Your identification has been saved in /u/kim/.ssh/id_rsa.
Your public key has been saved in /u/kim/.ssh/id_rsa.pub.

接下来把密钥文件传到你的SSH帐号下:
local:~ yourname$ cd ~/.ssh
local:~ yourname$ cp id_rsa.pub authorized_keys
local:~ yourname$ scp -p ~/.ssh/authorized_keys hrothgar:.ssh/

最后一步会提示你输入SSH帐号的密码,不是你刚才创建密钥的密码。
如果最后一步提示错误,通常是因为远程权限的问题。
你需要用root身份登录到远程机器,为这个SSH帐号创建相关目录,并且设置权限:

在SSH帐号登录的Home目录设置:
root# mkdir .ssh
root# chown username .
root# chrown username .ssh
root# chmod go-w . .ssh

然后重新执行刚才最后一步。

如果你在Mac OS的用户名和SSH的帐户名一致(推荐),那么你现在可以直接输入:
$ ssh yourhost.com

系统就会自动提示你输入刚才所创建密钥的密码(弹出一个对话框,而不是命令行里的密码提示),这时,请记得输入正确的密码,并且选择在钥匙环里记住该密码了。这以后你重复使用这个命令,应该就可以自动无缝登录而不需要任何提示了。

如果你使用不同的帐户,试试:
$ ssh yourname@yourhost.com

如果测试通过,就可以进入最后一步。

OK,最后一步是登录自动连接和断线自动重连,本来也可以用各种命令行实现的,但是我发现了一个更好用的东东:SSH Tunnel Manager,你可以下载到最新的2.0版本。

按照以下步骤设置:
1、把程序拖到你的Application目录,运行;
2、在Dock上右键点击选中“登录时打开”。
3、单击程序图标一次,在主界面点击“Configuration”打开配置;
4、单击“+”号创建一个新的连接设置;
5、随便取一个名字,输入你的SSH主机名(例如:yourhost.com)和用户名;
6、点击Option,选中Auto Connect(自动连接)和Enable Socket Proxy(允许Socket代理),填写一个没有被占用,并且数字大于1500的端口号。

关掉设置按钮,现在你可以看到在SSH Tunnel Manager的主窗口里面有你刚才创建的配置和一个灰色的启动按钮,点击启动。

最后一步,在你的浏览器里面设置Socket代理到127.0.0.1:你的端口号。
我自己通常用Safari作为日常浏览,Firefox则对所有URL通过代理。

参考资料:
SSH自动登录保存密码指南 Getting started with SSH》
以及上文的中文译稿(非常感谢):《SSH记住密码,自动登录
SSH Tunnel Manager软件下载
chmod,chown命令详解

在Cocoa Objective-C里面判断空字符串

2008年12月4日

-(Void)YourFunction:(id)sender{
NSString *urlString = [urlInput stringValue];

if (!urlString) {
NSLog(@”NO INPUT.”);
}else {
if ([urlString length] == 0) {
NSLog(@”NO INPUT.”);
} else {
}
}
}

这之前我尝试过nil,以及等于空字符串@”",似都没有什么效果,最后请教Livid 同学,得到以上传授的办法,感谢。

如何使用Cocoa Objective-C在一个类(Class)里面呼叫主文档(Docuemnt)的方法(Function)

2008年11月23日
#import “MyDocument.h”

MyDocument *currentDocument=(MyDocument *)[[NSDocumentController sharedDocumentController] currentDocument];

if(currentDocument==nil){
    currentDocument=(MyDocument *)[[NSApp orderedDocuments] objectAtIndex:0];
    if(currentDocument==nil){
        NSLog(@”currentDocument playing up.”);
        NSBeep();
        return nil;
    }
}
[currentDocument yourFunctionName];



来自Eraserhead 的办法。

使用SSH/PAC快速无缝访问互联网

2008年11月17日

现在来看,SSH 确实是最理想、简单、快速地自由访问互联网地方式,唯一的要求是用户需要架设自己的海外SSH Server主机。

现在你可以在淘宝轻易买到价格低至3RMB/年的独立SSH帐户 ,这种每个人单独设置私有隧道的方式其实正是最正确而理想的方式,你也可以找你的朋友帮你设置一个,但一定不要使用共享的隧道多。个人,独立,多点,多分布,如生命本身一样生生不息。

然后你需要PAC,也就是代理自动配置文件,这个文件可以帮助你把需要通过代理访问的网站自动引导启动代理,而不需要的则正常访问,整个访问从内网到墙内外都是无缝的,并且速度很快。

具体的设置方法可以参考Livid精简的介绍:
http://livid.cn/doc_view.php?doc_id=5744

如果你使用的正是Mac,你需要在系统设置-网络设置-高级设置里面设置你的自动代理:

设置以后记得确认,并且重启你的Safari。
如果你使用Firefox,可以在Firefox的设置里面单独设置并且重新载入PAC文件。

用Cocoa Objective-C捕获浏览器自定义协议

2008年11月17日

搜索出来的大量结果都是说怎么在Windows下面,办法不外乎是在注册表里面添加关联协议,所以最后还是在英文搜索里找到如何在Mac OS的实现。

目标是:
捕获浏览器地址栏里面自定义的协议,或者是点击自定义协议链接自动激活程序。

Kimbro Staken写于2003的全文《Handling URL schemes in Cocoa》已经说得很清晰了,我这里简单地用中文把几个重要步骤复述一次。

首先下载这个压缩文件 ,然后把解压出来的文件放到项目的根目录。
这两个文件的内文如下,不需要任何修改:

// file URLHandler.scriptSuite:

{
    Name = URLHandler;
    AppleEventCode = "UrHD";

    Commands = {
        "GetURL" = {
            CommandClass = URLHandlerCommand;
            AppleEventCode = GURL;
            AppleEventClassCode = GURL;
        };
    };
}

// URLHandler.scriptTerminology:
{
    Name = "URLHandler commands";
    Description = "Commands to handle a URL";

    Commands = {
       "GetURL" = {
          "Name" = "get URL";
          "Description" = "Open a URL";
       };
    };
}


接下来修改项目的info.plist属性文件,把以下信息添加进去,简单说来,放在最后plist/ditc节点下。
<key>NSAppleScriptEnabled</key>
<string>YES</string>
<key>CFBundleURLTypes</key>
<array>

    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myscheme</string>
        </array>
    </dict>
</array>

这里注意CFBundleURLSchemes节点下的myscheme,这个值就是所需要注册的协议。
最后创建并且实现具体的程序,为project新加Objective-C Class,命名可以随意。
首先定义Interface

// file URLHandlerCommand.h

#import 

@interface URLHandlerCommand : NSScriptCommand {

}

@end

然后是实现捕捉的代码

// file URLHandlerCommand.m

#import "URLHandlerCommand.h"

@implementation URLHandlerCommand

- (id)performDefaultImplementation {
    NSString *urlString = [self directParameter];

    NSLog(@"url = %@", urlString);

    return nil;
}

@end
其中,NSLog部分可以看到已经可以在Console里面显示你自定义URL部分的值了。
比如你定义的协议头是“my_http:”,你的URL是”my_http:goodday”,这是在浏览器地址栏输入这个URL,回车,程序就能捕捉到,并且自动弹送到前台来,当然如果是点击一个链接也同样适用。

如果需要具体了解为什么,可以参看原文。

用Cocoa Objective-C向共享的Cookie储存进行读写

2008年11月13日

NSURL *cookieURL = [NSURL URLWithString:@"http://www.tudou.com"];

//read
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL];

//creat a new cookie
NSArray *newCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary dictionaryWithObject:@"yourKey=yourValue;expires=2100-01-11 11:11:11 +0800" forKey:@"Set-Cookie"] forURL:cookieURL];

//wirte
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:newCookies forURL:cookieURL mainDocumentURL:nil];


代码调试通过,具体可以参看Xcode Document

语义和Avalon的消解

2008年2月3日

YES,我来承认一个错误。

以XML+XSL作为前端的blog程序Avalon——已经作为我自己的原生blog运行了一年了,它的地址是(http://woooh.com),如果大家还有一点兴趣,可以赶来瞻仰它的遗容。
经过一年的实践,现在,我可以用我自己的经验来表达我的看法,而不是拍一拍脑袋。

ZBlog的创始作者,Rainbowsoft,zx,朱暄,什么名字都好……(汗),在一开始的讨论中,最终所纠缠的概念,也大致在于:“为什么要放弃一个通用的HTML?这是互联网交互的语言”。
现在,我承认他说的是对的了——当我们所有的人都在讨论XML是未来的语义基础的时候,HTML——在现实意义上确实是,从搜索引擎,到整个WWW用来低声细语或者畅谈高论的语言。

好吧,我承认我喜欢拿維根特斯坦说话,包括我是很喜欢他。
还记得维根特斯坦在上个世纪创立逻辑哲学学派的时候,他也近乎苛刻地指责了自然语言的种种缺陷,然后企图以数学版精美无误的逻辑创立新的语言,用来解决当代哲学最紧急的问题。然而二十年之后,当他回归的时候,他放弃了他的观点,他不再认为这个世界上存在一种精确无误的语言——那只是人偏执的梦想,而看上去杂乱无章的自然语言——却有着本身天生的,无可匹敌的优点——从存在就是合理的角度来说——自然语言本身看上去没有逻辑和意义,然而它肩负并且实现了它本身最直接而真实的目的:交流和沟通。

当一个人说出:“这是铅笔”的时候,他不需要什么论证,他也不需要理会一个看不懂中文的同学完全不理解这四个字的意义,他只要——他所交流的对方明白他的思想,就可以了,仅此而已。因而这个世界上最广泛通用的交流工具,就是自然语言,在WWW的实现端,就是HTML。

除非两个交互的客体只需要点对点的交流,这个时候,他们可以使用任意的语言,比如简单或复杂到任何人都看不懂的编码:“%……&×()(×(&×……%×¥”,这个时候,任何协议只要双方达成共识,足够交流,就可以了,在WWW的实现端,我认为,这就是XML。
它们之间的联系和区别,就像是生活大辞典和量子物理专用辞典之间的联系和区别一样,它们之间并不排斥,也不完全重合,他们相容,但不完全一致。

这是一个多么美好的世界。

在适合它们的地方使用它们,无需拘泥,这就是我最终的想法,让它们在该它们出现的地方出现,就对了:)