1 2 package ch.ethz.ssh2; 3 4 import java.io.IOException ; 5 import java.io.InputStream ; 6 import java.io.OutputStream ; 7 import java.security.SecureRandom ; 8 9 import ch.ethz.ssh2.channel.Channel; 10 import ch.ethz.ssh2.channel.ChannelManager; 11 import ch.ethz.ssh2.channel.X11ServerData; 12 13 22 public class Session 23 { 24 ChannelManager cm; 25 Channel cn; 26 27 boolean flag_pty_requested = false; 28 boolean flag_x11_requested = false; 29 boolean flag_execution_started = false; 30 boolean flag_closed = false; 31 32 String x11FakeCookie = null; 33 34 final SecureRandom rnd; 35 36 Session(ChannelManager cm, SecureRandom rnd) throws IOException 37 { 38 this.cm = cm; 39 this.cn = cm.openSessionChannel(); 40 this.rnd = rnd; 41 } 42 43 49 public void requestDumbPTY() throws IOException 50 { 51 requestPTY("dumb", 0, 0, 0, 0, null); 52 } 53 54 60 public void requestPTY(String term) throws IOException 61 { 62 requestPTY(term, 0, 0, 0, 0, null); 63 } 64 65 98 public void requestPTY(String term, int term_width_characters, int term_height_characters, int term_width_pixels, 99 int term_height_pixels, byte[] terminal_modes) throws IOException 100 { 101 if (term == null) 102 throw new IllegalArgumentException ("TERM cannot be null."); 103 104 if ((terminal_modes != null) && (terminal_modes.length > 0)) 105 { 106 if (terminal_modes[terminal_modes.length - 1] != 0) 107 throw new IOException ("Illegal terminal modes description, does not end in zero byte"); 108 } 109 else 110 terminal_modes = new byte[] { 0 }; 111 112 synchronized (this) 113 { 114 115 if (flag_closed) 116 throw new IOException ("This session is closed."); 117 118 if (flag_pty_requested) 119 throw new IOException ("A PTY was already requested."); 120 121 if (flag_execution_started) 122 throw new IOException ( 123 "Cannot request PTY at this stage anymore, a remote execution has already started."); 124 125 flag_pty_requested = true; 126 } 127 128 cm.requestPTY(cn, term, term_width_characters, term_height_characters, term_width_pixels, term_height_pixels, 129 terminal_modes); 130 } 131 132 148 public void requestX11Forwarding(String hostname, int port, byte[] cookie, boolean singleConnection) 149 throws IOException 150 { 151 if (hostname == null) 152 throw new IllegalArgumentException ("hostname argument may not be null"); 153 154 synchronized (this) 155 { 156 157 if (flag_closed) 158 throw new IOException ("This session is closed."); 159 160 if (flag_x11_requested) 161 throw new IOException ("X11 forwarding was already requested."); 162 163 if (flag_execution_started) 164 throw new IOException ( 165 "Cannot request X11 forwarding at this stage anymore, a remote execution has already started."); 166 167 flag_x11_requested = true; 168 } 169 170 171 172 X11ServerData x11data = new X11ServerData(); 173 174 x11data.hostname = hostname; 175 x11data.port = port; 176 x11data.x11_magic_cookie = cookie; 177 178 179 180 byte[] fakeCookie = new byte[16]; 181 String hexEncodedFakeCookie; 182 183 184 185 while (true) 186 { 187 rnd.nextBytes(fakeCookie); 188 189 190 191 StringBuffer tmp = new StringBuffer (32); 192 for (int i = 0; i < fakeCookie.length; i++) 193 { 194 String digit2 = Integer.toHexString(fakeCookie[i] & 0xff); 195 tmp.append((digit2.length() == 2) ? digit2 : "0" + digit2); 196 } 197 hexEncodedFakeCookie = tmp.toString(); 198 199 200 201 if (cm.checkX11Cookie(hexEncodedFakeCookie) == null) 202 break; 203 } 204 205 206 207 cm.requestX11(cn, singleConnection, "MIT-MAGIC-COOKIE-1", hexEncodedFakeCookie, 0); 208 209 210 211 212 synchronized (this) 213 { 214 if (flag_closed == false) 215 { 216 this.x11FakeCookie = hexEncodedFakeCookie; 217 cm.registerX11Cookie(hexEncodedFakeCookie, x11data); 218 } 219 } 220 221 222 } 223 224 231 public void execCommand(String cmd) throws IOException 232 { 233 if (cmd == null) 234 throw new IllegalArgumentException ("cmd argument may not be null"); 235 236 synchronized (this) 237 { 238 239 if (flag_closed) 240 throw new IOException ("This session is closed."); 241 242 if (flag_execution_started) 243 throw new IOException ("A remote execution has already started."); 244 245 flag_execution_started = true; 246 } 247 248 cm.requestExecCommand(cn, cmd); 249 } 250 251 256 public void startShell() throws IOException 257 { 258 synchronized (this) 259 { 260 261 if (flag_closed) 262 throw new IOException ("This session is closed."); 263 264 if (flag_execution_started) 265 throw new IOException ("A remote execution has already started."); 266 267 flag_execution_started = true; 268 } 269 270 cm.requestShell(cn); 271 } 272 273 280 public void startSubSystem(String name) throws IOException 281 { 282 if (name == null) 283 throw new IllegalArgumentException ("name argument may not be null"); 284 285 synchronized (this) 286 { 287 288 if (flag_closed) 289 throw new IOException ("This session is closed."); 290 291 if (flag_execution_started) 292 throw new IOException ("A remote execution has already started."); 293 294 flag_execution_started = true; 295 } 296 297 cm.requestSubSystem(cn, name); 298 } 299 300 public InputStream getStdout() 301 { 302 return cn.getStdoutStream(); 303 } 304 305 public InputStream getStderr() 306 { 307 return cn.getStderrStream(); 308 } 309 310 public OutputStream getStdin() 311 { 312 return cn.getStdinStream(); 313 } 314 315 339 public int waitUntilDataAvailable(long timeout) throws IOException 340 { 341 if (timeout < 0) 342 throw new IllegalArgumentException ("timeout must not be negative!"); 343 344 int conditions = cm.waitForCondition(cn, timeout, ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA 345 | ChannelCondition.EOF); 346 347 if ((conditions & ChannelCondition.TIMEOUT) != 0) 348 return -1; 349 350 if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) != 0) 351 return 1; 352 353 354 355 if ((conditions & ChannelCondition.EOF) != 0) 356 return 0; 357 358 throw new IllegalStateException ("Unexpected condition result (" + conditions + ")"); 359 } 360 361 384 385 public int waitForCondition(int condition_set, long timeout) 386 { 387 if (timeout < 0) 388 throw new IllegalArgumentException ("timeout must be non-negative!"); 389 390 return cm.waitForCondition(cn, timeout, condition_set); 391 } 392 393 402 public Integer getExitStatus() 403 { 404 return cn.getExitStatus(); 405 } 406 407 416 public String getExitSignal() 417 { 418 return cn.getExitSignal(); 419 } 420 421 431 public void close() 432 { 433 synchronized (this) 434 { 435 if (flag_closed) 436 return; 437 438 flag_closed = true; 439 440 if (x11FakeCookie != null) 441 cm.unRegisterX11Cookie(x11FakeCookie, true); 442 443 try 444 { 445 cm.closeChannel(cn, "Closed due to user request", true); 446 } 447 catch (IOException ignored) 448 { 449 } 450 } 451 } 452 } 453 | Popular Tags |