java - JSch:使用 JSCH tty 代码执行交互式命令我做错了什么?

标签 java ssh jsch

我正在尝试使用 JSch 连接到服务器,然后执行交互式 su 命令。

你能告诉我我错过了什么吗?这些东西每次都会挂起,我认为这种行为没有任何理由。 特别是在发送密码之前,我专门等待密码字符串(实际上是 assword ,没有 : )。

这就是我正在做的事情:

  1. 以 user1/pass1 身份登录
  2. 然后执行su - user2 -c 命令行
  3. 在 channel 输入流中传递密码。

无论如何,这是主要的执行函数,它需要 user1/pass1、user2/pass2 和命令行。

public String execute (String host, String nuser, String npass,
                       String puser, String ppass, String commandLine)
    {
      try{
        synchronized(this) 
        {
          session = jsch.getSession(nuser,host,22);
          session.setConfig("StrictHostKeyChecking", "no");
          pstr=npass;
          //session.setPassword(npass);
          String authmethods=  session.getConfig("PreferredAuthentications");
          System.out.println(authmethods);
          UserInfo ui=new SUSessionExecution.UInfo();
          Thread.sleep(150);
          if(authmethods.contains("keyboard-interactive"))
          { System.out.print("keyboard-interactive"); session.setUserInfo(ui); } 
          else if ( authmethods.contains("password") )
          { System.out.print("password"); session.setPassword(pstr);  }

          session.connect();
          channel = session.openChannel("exec");
          nuser=null;
          npass=null;


          ((ChannelExec)channel).setPty(true);
          ((ChannelExec)channel).setPtyType("vt100");
          String command= "su - " + puser + " -c " + commandLine  + "\n";
          //((ChannelExec)channel).setCommand(commandLine);

          byte[] cmdBuffer=command.getBytes();
          ByteArrayInputStream bi = new ByteArrayInputStream(cmdBuffer);
          channel.setInputStream(bi);

          ByteArrayOutputStream bo = new ByteArrayOutputStream();
          ((ChannelExec)channel).setErrStream(bo);

          sessionOutput = channel.getInputStream();
          //sessionError = channel.getExtInputStream();


          channel.connect();

          session_open=true;
          // it is only here our session is fully functional.

          boolean sustatus;//=establishSU(commandIO, channel,puser,ppass);
          // NEEDS REPLACE

          //commandIO.write(command.getBytes());
          //commandIO.flush();



          String standardOutBuffer="";
          String standardErrBuffer="";

          int counter;
          byte[] byteBuffer = new byte[1024];


          while(sessionOutput.available() > 0)
            { counter=0; //byteBuffer=null;
              counter=sessionOutput.read(byteBuffer, 0, byteBuffer.length);
              if(counter < 0) { throw new java.io.IOException(); }
              standardOutBuffer += new String(byteBuffer,0,counter);
              if(standardOutBuffer.contains("assword")){break;}
            }

            /*if(sessionError.available() > 0)
            { counter=0; //byteBuffer=null;
              counter=sessionError.read(byteBuffer, 0, byteBuffer.length);
              if(counter < 0) { throw new java.io.IOException(); }
              standardErrBuffer += new String(byteBuffer,0,counter);
              if(standardErrBuffer.contains("assword")){break;}}*/


        commandIO = new PipedOutputStream();
        sessionInput = new PipedInputStream(commandIO);
        channel.setInputStream(sessionInput);
        commandIO.write(new String(ppass+"\n").getBytes());
        commandIO.flush();

        counter=0; standardOutBuffer="";
        while((counter = sessionOutput.read(byteBuffer,0,byteBuffer.length)) != -1)
        { standardOutBuffer += new String(byteBuffer,0,counter); }

        closeComponents();
        return standardOutBuffer;
        }
      }
      catch(com.jcraft.jsch.JSchException jse) 
      { session_open=false;su_space_open=false;jse.printStackTrace();
        closeComponents(); return null; }
      catch(java.io.IOException ioe)
      { session_open=false;su_space_open=false;ioe.printStackTrace();
        closeComponents(); return null; }
      catch(InterruptedException ie)
      { ie.printStackTrace(); }

        return null;
    }

这是我的错误消息:

Exception in thread "main" java.lang.NullPointerException
  at com.jcraft.jsch.Buffer.putString(Buffer.java:59)
  at com.jcraft.jsch.UserAuthKeyboardInteractive.start(UserAuthKeyboardInteractive.ja‌va:183)
  at com.jcraft.jsch.Session.connect(Session.java:442)
  at com.jcraft.jsch.Session.connect(Session.java:162)
  at susessionexecution.SUExecute.execute(SUExecute.java:53)
  at Tester.<init>(Tester.java:12)
  at Tester.main(Tester.java:17) 

这是提示键盘交互方法

public String[] promptKeyboardInteractive (String destination, String name,
                                           String instruction, String[] prompt,
                                           boolean[] echo)
{
    System.out.println("\n"+prompt.length+"\n\n");
    String[] response=new String[prompt.length];
    response[0] = passwd;
    return response;
}

最佳答案

看来你的实现

  UIKeyboardInteractive#promptKeyboardInteractive()

返回一个字符串数组,其中包含“null”。

关于sudo,我建议引用 http://www.jcraft.com/jsch/examples/Sudo.java.html

关于java - JSch:使用 JSCH tty 代码执行交互式命令我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11055115/

相关文章:

java - xpages 和 java 框架

java - 来自配置的 JBPM 服务任务分配输入

Java 编译带有 spring "Validator"类的警告

c# - 通过 SSH 隧道的 mySQL 连接字符串,无需密码

python - 带有 paramiko 的 ssh 客户端 (python)

java - 使用 Spring 集成/JCraft JSch 在 SFTP 服务器上内部复制文件

java - JSch:ByteArrayInputStream:如何检查最终结果

java - CDI:来自同一 bean 的非拦截方法的拦截方法嵌套调用 - 应该调用吗?

java - 使用 JSch 分别为各个提示提供输入

eclipse - 在 Eclipse 中将 putty 的页面与 egit 一起使用