一直钟情于PuTTY的小巧精悍,是我SSH连接之必选。虽然喜欢这款软件的小巧,但亦要承受其不方便之苦。最希望PuTTY添加的两个功能是自动登录和Tab支持。这也是众多使用者的wishlist,但官方已明确的断了大家的念想。
关于自动登录(auto-login password),当然需要保存密码的功能,官方的回应是记住密码会带来显著的安全问题:任何能使用你的设备的人都能轻而易举的得到你的密码,使用它,甚至滥用他。建议通过SSH的公钥验证来自动登录,它更加方便和安全。详细回应参看这里 。
关于Tab支持,官方的回应是需要重构windows相关的代码,代价比较大,再者并不是所有人都喜欢tab…,详细回应参看这里 。
PuTTY是开源的,我们可以很容易得到它的源代码,这是能够修改PuTTY功能的前提。在PuTTY的Connection->Data选项中有Auto-login username这一项,我们可以在源代码中定位到插入点,文件为Config.c ,Auto-login password就是要插入的密码文本框项(Line5-9)。事实上,username是修改整个代码的参照系,从以下代码片段中也可以看出。
ctrl_editbox(s, "Auto-login username" , 'u' , 50 , HELPCTX(connection_username), dlg_stdeditbox_handler, I(offsetof(Config,username)), I(sizeof (((Config *)0 )->username))); c = ctrl_editbox(s, "Auto-login password" , 'w' , 50 , HELPCTX(connection_password), dlg_stdeditbox_handler, I(offsetof(Config,password)), I(sizeof (((Config *)0 )->password))); c->editbox.password = 1 ; ``` 定位HELPCTX函数,文件为windows/<del>Winhelp.c</del>Winhelp.h,在connection_username行下插入(Line2): ``` c #define WINHELP_CTX_connection_username "connection.username:config-username" #define WINHELP_CTX_connection_password "connection.password:config-password"
定位Config变量,得知其为config_tag类型的结构体,定位到putty.h,在该结构体中加入password的声明(Line2):
char username[100 ];char password[100 ];
接下来就是对password的处理了,在ssh连接的auto login时,会处理username,同理在该函数中,添加对password的处理。ssh连接有两种方式:ssh1和ssh2,所以对应的两个函数都要修改。文件为Ssh.c。对ssh1的修改如下(位于do_ssh1_login()中)(Line8-18):
{ int ret; if (strlen (ssh->cfg.password) == 0 ) { ret = get_userpass_input(s->cur_prompt, NULL , 0 ); while (ret < 0 ) { ssh->send_ok = 1 ; crWaitUntil(!pktin); ret = get_userpass_input(s->cur_prompt, in, inlen); ssh->send_ok = 0 ; } } else { ret = 1 ; strcpy (s->cur_prompt->prompts[0 ]->result, ssh->cfg.password); }
对ssh2的修改如下(位于do_ssh2_authconn()中)(Line17-27):
int ret; int changereq_first_time; ssh->pkt_actx = SSH2_PKTCTX_PASSWORD; s->cur_prompt = new_prompts(ssh->frontend); s->cur_prompt->to_server = TRUE; s->cur_prompt->name = dupstr("SSH password" ); add_prompt(s->cur_prompt, dupprintf("%.90s@%.90s's password: " , s->username,ssh->savedhost),FALSE, SSH_MAX_PASSWORD_LEN); if (strlen (ssh->cfg.password) == 0 ) { ret = get_userpass_input(s->cur_prompt, NULL , 0 ); while (ret < 0 ) { ssh->send_ok = 1 ; crWaitUntilV(!pktin); ret = get_userpass_input(s->cur_prompt, in, inlen); ssh->send_ok = 0 ; } } else { ret = 1 ; strcpy (s->cur_prompt->prompts[0 ]->result, ssh->cfg.password); }
至此,ssh的Auto-login password已实现。但是还需要就password的保存绑定到load和save功能上,这两个功能的实现位于在Settings.c文件中。在函数save_open_settings()中添加(Line2):
write_setting_s(sesskey, "UserName" , cfg->username); write_setting_s(sesskey, "PassWord" , cfg->password);
在函数load_open_settings()中添加(Line2):
gpps(sesskey, "UserName" , "" , cfg->username, sizeof (cfg->username)); gpps(sesskey, "PassWord" , "" , cfg->password, sizeof (cfg->password));
至此,所有代码修改完成,根据README文件的提示,我使用MinGW编译了一下,MinGW可以在这里 得到。编译方法如下:
$cd putty-src/windows
$make -f makefile.cyg
在该windows目录下生成所有的可执行文件。如果你不想修改编译,可以直接下载我编译好的,下载地址在这里 。
Update: 修改后的源代码已经放在Github上:putty-improvement 。