使用JSCH连接时,需要输入密码的解决方法
背景:
在做一个安装脚本,期间会执行一些数据库的操作,需要DBA帐号才可以执行。
我们用的JSCH创建SSH通道,直接连接到目标机器上执行,效果和打开命令行是一样的,唯一特殊的,就是关于DBA的密码的问题。
Oracle(我们的数据库用的Oracle)的脚本中是提供了连同密码一起输入的功能的,但是!凡事就怕但是!客户提出的要求是:对帐号密码的明文存储零容忍!
Ok,说白了,不能在配置文件里把DBA密码写进去,然后批量执行。必须在Oracle'提示输入密码的时候,输入之。
问题:
JSCH提供的原始的几个channel,还是比较直接的。 常用的有SFTP/ChannelShell/ChannelExec。为了取环境变量方便,我们用了ChannelShell。
ChannelShell是可以设置InputStream和OutputStream的。
但是输入密码只能从console输入,所以channelshell.setInputStream(System.in)么?
但是其他命令是从配置文件输入的,所以channelshell.setInputStream(new FileInputStream(filename))么?
无论如何,只能设置一个InputStream,怎么兼顾?
调查:
第一步,google之。 有几个文章参考了,但是不合适。
第二步,尝试使用Except4J,不过它也是全脚本的,不能中间切换到System.in.
第三步,就是按照Except4J的做法,自己控制JSCH的input/output stream。 于是有了此文。
方案:
前面说了那么多废话,其实目的就是一个:把来龙去脉介绍一下,或许有大侠发现易做图了个重复的事情,有更好的方案,可以给我指教一下。
如果也被这个问题困扰的话,可以看看,一起讨论下。
我的方法就是:
自己写InputStream和OutputStream,然后把它们设置到JSCH的channelshell里去,这样它就会从我这里读写了
然后呢,读的时候就从我的文件里读,我告诉它输入是“xyz”它就拿到xyz;
写的时候呢,它就写到我的outputstream里,我就知道结果是ABC啦。
有了以上两个前提,那么我再加一些小功能:
1. 读文件的时候,我多写一些配置信息,发现现在是password,那我就从System.in读数据,然后发给JSCH channel;
2. 获得response的时候,我判断是否和我期望的结果一样,然后我再执行下一条。
于是就有了这个配置文件:
[java]
[html]
## This file format just for POC, you can define yours.
## For my format, it is:
## 1. # starts for comments
## 2. There are 3 parts: [<expect>]<type>[<content>]
## 3. For <expect>, it's easy: [$] means you expect a '$' ends;
## 4. For <type>, support 'send' and 'password'.
## If 'send', means the <content> will be send to SSH channel.
## If 'password', means the <content> come from system console, that is, need you type in.
[$]send[pwd]
[$]send[whoami]
[$]send[su - root]
[Password:]password[]
[#]send[pwd]
[#]send[ls]
[#]send[whoami]
[#]send[exit]
[$]send[ls]
[$]send[pwd]
[$]send[whoami]
[$]send[su - root]
[Password:]password[]
[#]send[pwd]
[#]send[ls]
[#]send[whoami]
[#]send[exit]
[$]send[exit]
原理就是这样了,很简单的苦力活。
补充:web前端 , JavaScript ,