Source Code Cross Referenced for SshSession.java in  » IDE » J » org » armedbear » j » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » J » org.armedbear.j 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * SshSession.java
0003:         *
0004:         * Copyright (C) 2002-2003 Peter Graves
0005:         * $Id: SshSession.java,v 1.14 2004/09/13 00:49:30 piso Exp $
0006:         *
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License
0009:         * as published by the Free Software Foundation; either version 2
0010:         * of the License, or (at your option) any later version.
0011:         *
0012:         * This program is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015:         * GNU General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU General Public License
0018:         * along with this program; if not, write to the Free Software
0019:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0020:         */
0021:
0022:        package org.armedbear.j;
0023:
0024:        import gnu.regexp.RE;
0025:        import gnu.regexp.REException;
0026:        import gnu.regexp.REMatch;
0027:        import gnu.regexp.UncheckedRE;
0028:        import java.io.IOException;
0029:        import java.io.OutputStreamWriter;
0030:        import java.util.ArrayList;
0031:        import java.util.List;
0032:        import javax.swing.SwingUtilities;
0033:
0034:        public final class SshSession implements  Constants {
0035:            public static final int DEFAULT_PORT = 22;
0036:
0037:            private static final int TRY_AGAIN = 0;
0038:            private static final int AUTHENTICATED = 1;
0039:            private static final int PASSWORD = 2;
0040:            private static final int PASSPHRASE = 3;
0041:            private static final int YES = 4;
0042:            private static final int NO = 5;
0043:
0044:            private static final String PROMPT = "$ ";
0045:
0046:            private static ArrayList sessionList;
0047:
0048:            private static CleanupThread cleanupThread;
0049:
0050:            private String hostName;
0051:            private String userName;
0052:            private String password;
0053:            private String passphrase;
0054:            private int port;
0055:
0056:            private boolean locked;
0057:
0058:            private Process process;
0059:
0060:            private OutputStreamWriter stdin;
0061:            private StdoutThread stdoutThread;
0062:            private StderrThread stderrThread;
0063:
0064:            private FastStringBuffer output = new FastStringBuffer();
0065:
0066:            private boolean connected;
0067:
0068:            private String loginDirectory;
0069:
0070:            private boolean echo;
0071:
0072:            // tcsh doesn't like "\cd", so we may change it to "cd" later.
0073:            private String cd = "\\cd";
0074:
0075:            private Buffer outputBuffer;
0076:
0077:            private String passwordTitle;
0078:            private String passwordPrompt;
0079:
0080:            private SshSession(SshFile file, boolean locked) {
0081:                hostName = file.getHostName();
0082:                Debug.assertTrue(hostName != null);
0083:                userName = file.getUserName();
0084:                password = file.getPassword();
0085:                port = file.getPort();
0086:                this .locked = locked;
0087:                register(this );
0088:            }
0089:
0090:            private SshSession(SshSession other, boolean locked) {
0091:                hostName = other.getHostName();
0092:                Debug.assertTrue(hostName != null);
0093:                userName = other.getUserName();
0094:                password = other.getPassword();
0095:                passphrase = other.getPassphrase();
0096:                port = other.getPort();
0097:                this .locked = locked;
0098:                register(this );
0099:            }
0100:
0101:            private static synchronized void register(SshSession session) {
0102:                if (sessionList == null)
0103:                    sessionList = new ArrayList();
0104:                sessionList.add(session);
0105:                if (cleanupThread == null) {
0106:                    cleanupThread = new CleanupThread(cleanupRunnable);
0107:                    cleanupThread.start();
0108:                }
0109:                Log.debug("leaving register() session count = "
0110:                        + sessionList.size());
0111:            }
0112:
0113:            private static synchronized void unregister(SshSession session) {
0114:                if (sessionList == null) {
0115:                    Debug.bug();
0116:                    return;
0117:                }
0118:                if (!sessionList.contains(session))
0119:                    Debug.bug();
0120:                sessionList.remove(session);
0121:                Log.debug("leaving unregister() session count = "
0122:                        + sessionList.size());
0123:            }
0124:
0125:            public static synchronized SshSession getSession(SshFile file) {
0126:                if (file == null) {
0127:                    Debug.bug();
0128:                    return null;
0129:                }
0130:                if (file.getHostName() == null) {
0131:                    Debug.bug();
0132:                    return null;
0133:                }
0134:                if (file.getUserName() == null) {
0135:                    Debug.bug();
0136:                    file.setUserName(System.getProperty("user.name"));
0137:                }
0138:                SshSession session = lockSession(file);
0139:                if (session != null)
0140:                    return session;
0141:                // No idle session found for this file. Try to find a session to clone.
0142:                session = findSession(file);
0143:                if (session != null)
0144:                    return new SshSession(session, true);
0145:                // No session to clone.
0146:                return new SshSession(file, true);
0147:            }
0148:
0149:            // Called only from synchronized methods.
0150:            private static SshSession lockSession(SshFile file) {
0151:                if (sessionList != null) {
0152:                    for (int i = sessionList.size(); i-- > 0;) {
0153:                        SshSession session = (SshSession) sessionList.get(i);
0154:                        if (session.getUserName().equals(file.getUserName())) {
0155:                            if (session.getHostName()
0156:                                    .equals(file.getHostName())) {
0157:                                if (session.getPort() == file.getPort()) {
0158:                                    if (session.lock()) {
0159:                                        return session;
0160:                                    }
0161:                                }
0162:                            }
0163:                        }
0164:                    }
0165:                }
0166:                return null;
0167:            }
0168:
0169:            // Called only from synchronized methods.
0170:            private static SshSession findSession(SshFile file) {
0171:                if (sessionList != null) {
0172:                    for (int i = sessionList.size(); i-- > 0;) {
0173:                        SshSession session = (SshSession) sessionList.get(i);
0174:                        if (session.getUserName().equals(file.getUserName())) {
0175:                            if (session.getHostName()
0176:                                    .equals(file.getHostName())) {
0177:                                if (session.getPort() == file.getPort()) {
0178:                                    return session;
0179:                                }
0180:                            }
0181:                        }
0182:                    }
0183:                }
0184:                return null;
0185:            }
0186:
0187:            public final synchronized boolean isLocked() {
0188:                return locked;
0189:            }
0190:
0191:            private synchronized boolean lock() {
0192:                if (locked)
0193:                    return false;
0194:                locked = true;
0195:                return true;
0196:            }
0197:
0198:            public synchronized void unlock() {
0199:                if (locked)
0200:                    locked = false;
0201:                else
0202:                    Debug.bug("SshSession.unlock session was not locked");
0203:                synchronized (SshSession.class) {
0204:                    if (sessionList != null)
0205:                        Log.debug("unlock session count = "
0206:                                + sessionList.size());
0207:                    else
0208:                        Debug.bug("SshSession.unlock no session list");
0209:                }
0210:            }
0211:
0212:            public final String getHostName() {
0213:                return hostName;
0214:            }
0215:
0216:            public final String getUserName() {
0217:                return userName;
0218:            }
0219:
0220:            public final String getPassword() {
0221:                return password;
0222:            }
0223:
0224:            public final void setPassword(String password) {
0225:                this .password = password;
0226:            }
0227:
0228:            public final String getPassphrase() {
0229:                return passphrase;
0230:            }
0231:
0232:            public final int getPort() {
0233:                return port;
0234:            }
0235:
0236:            public final String getLoginDirectory() {
0237:                return loginDirectory;
0238:            }
0239:
0240:            public void setOutputBuffer(Buffer buf) {
0241:                outputBuffer = buf;
0242:            }
0243:
0244:            public boolean isDirectory(String canonicalPath) {
0245:                SshFile file = new SshFile(hostName, canonicalPath, userName,
0246:                        null, port);
0247:                if (DirectoryCache.getDirectoryCache().getListing(file) != null)
0248:                    return true;
0249:                if (!connect())
0250:                    return false;
0251:                try {
0252:                    return changeDirectory(canonicalPath);
0253:                } catch (Exception e) {
0254:                    Log.error(e);
0255:                }
0256:                // An exception occurred. We're confused. Wait a moment.
0257:                try {
0258:                    Thread.sleep(1000);
0259:                } catch (InterruptedException e) {
0260:                    Log.error(e);
0261:                }
0262:                //  Try again.
0263:                try {
0264:                    Log.warn("isDirectory() retrying after exception ...");
0265:                    // Send an empty command to flush the channel.
0266:                    command("");
0267:                    return changeDirectory(canonicalPath);
0268:                } catch (Exception e) {
0269:                    // Another exception. Give up.
0270:                    Log.error(e);
0271:                    return false;
0272:                }
0273:            }
0274:
0275:            private String stat(String canonicalPath) {
0276:                FastStringBuffer sb = new FastStringBuffer("stat -t \"");
0277:                sb.append(canonicalPath);
0278:                sb.append('"');
0279:                String cmd = sb.toString();
0280:                String response = command(cmd);
0281:                Log.debug(cmd + " " + response);
0282:                if (response != null && response.startsWith(canonicalPath))
0283:                    return response.substring(canonicalPath.length()).trim();
0284:                return null;
0285:            }
0286:
0287:            // Determines file type from string returned by stat.
0288:            private static int getType(String s) {
0289:                if (s != null) {
0290:                    List tokens = Utilities.tokenize(s);
0291:                    if (tokens.size() == 14) {
0292:                        String token = (String) tokens.get(2);
0293:                        Log.debug("token = |" + token + "|");
0294:                        try {
0295:                            int n = Integer.parseInt(token, 16);
0296:                            Log.debug("n = " + Integer.toString(n, 8));
0297:                            if ((n & 0040000) == 0040000)
0298:                                return File.TYPE_DIRECTORY;
0299:                            if ((n & 0120000) == 0120000)
0300:                                return File.TYPE_LINK;
0301:                            if ((n & 0100000) == 0100000)
0302:                                return File.TYPE_FILE;
0303:                        } catch (NumberFormatException e) {
0304:                        }
0305:                    }
0306:                }
0307:                return File.TYPE_UNKNOWN;
0308:            }
0309:
0310:            // Throws an exception if we don't recognize the response.
0311:            private boolean changeDirectory(String canonicalPath)
0312:                    throws Exception {
0313:                FastStringBuffer sb = new FastStringBuffer(cd);
0314:                sb.append(" \"");
0315:                sb.append(canonicalPath);
0316:                sb.append('"');
0317:                String cmd = sb.toString();
0318:                Log.debug("changeDirectory cmd = |" + cmd + "|");
0319:                String response = command(cmd);
0320:                Log.debug("changeDirectory response = |" + response + "|");
0321:                if (response == null)
0322:                    throw new Exception(); // Lost connection.
0323:                if (response.indexOf("Command not found") >= 0) {
0324:                    if (cd.equals("\\cd")) {
0325:                        // tcsh doesn't like "\cd". Try again with "cd".
0326:                        cd = "cd";
0327:                        response = command(cd + " \"" + canonicalPath + '"');
0328:                        if (response == null)
0329:                            throw new Exception(); // Lost connection.
0330:                    } else
0331:                        return false;
0332:                }
0333:                if (response.equals(PROMPT)) {
0334:                    // No news is good news.
0335:                    Log.debug("changeDirectory succeeded");
0336:                    return true;
0337:                }
0338:                String lower = response.toLowerCase();
0339:                if (lower.indexOf("not a directory") >= 0)
0340:                    return false;
0341:                else if (lower.indexOf("no such file or directory") >= 0)
0342:                    return false;
0343:                // If the directory name is very long (> 80 chars or so), bash will
0344:                // wrap (i.e. mangle) the response. Try to detect that situation.
0345:                int index = response.indexOf('\r');
0346:                if (index < 0)
0347:                    index = response.indexOf('\n');
0348:                if (index >= 0) {
0349:                    String beginning = response.substring(0, index);
0350:                    Log.debug("beginning = |" + beginning + "|");
0351:                    if (cmd.startsWith(beginning)) {
0352:                        Log.debug("cmd starts with beginning!");
0353:                        index = response.lastIndexOf((char) 8);
0354:                        if (index >= 0) {
0355:                            Log.debug("backspace found!");
0356:                            String end = response.substring(index + 1);
0357:                            Log.debug("end = |" + end + "|");
0358:                            if (cmd.endsWith(end)) {
0359:                                Log.debug("cmd ends with end!");
0360:                                return true;
0361:                            }
0362:                        }
0363:                    }
0364:                }
0365:                // Unknown response. We must be confused.
0366:                throw new Exception();
0367:            }
0368:
0369:            public boolean exists(String canonicalPath) {
0370:                if (connect()) {
0371:                    String response = lsld(canonicalPath);
0372:                    if (response != null && response.length() > 0) {
0373:                        char c = response.charAt(0);
0374:                        if (c == 'd' || c == '-')
0375:                            return true;
0376:                    }
0377:                }
0378:                return false;
0379:            }
0380:
0381:            public static String getDirectoryListing(File file) {
0382:                if (!(file instanceof  SshFile)) {
0383:                    Debug.assertTrue(false);
0384:                    return null;
0385:                }
0386:                String listing = DirectoryCache.getDirectoryCache().getListing(
0387:                        file);
0388:                if (listing == null) {
0389:                    SshSession session = getSession((SshFile) file);
0390:                    if (session != null) {
0391:                        listing = session.retrieveDirectoryListing(file);
0392:                        session.unlock();
0393:                        if (listing != null)
0394:                            DirectoryCache.getDirectoryCache().put(file,
0395:                                    listing);
0396:                    }
0397:                }
0398:                return listing;
0399:            }
0400:
0401:            public String retrieveDirectoryListing(File file) {
0402:                if (!(file instanceof  SshFile)) {
0403:                    Debug.bug();
0404:                    return null;
0405:                }
0406:                if (!isLocked()) {
0407:                    Debug.bug();
0408:                    return null;
0409:                }
0410:                if (connect()) {
0411:                    try {
0412:                        // Do it this way to support symlinks.
0413:                        if (changeDirectory(file.canonicalPath()))
0414:                            // Change directory succeeded. Do ls -la here.
0415:                            return lsla();
0416:                    } catch (Exception e) {
0417:                        Log.error(e);
0418:                    }
0419:                }
0420:                return null;
0421:            }
0422:
0423:            public synchronized boolean chmod(SshFile file, int permissions) {
0424:                if (permissions != 0 && connect()) {
0425:                    FastStringBuffer sb = new FastStringBuffer("chmod ");
0426:                    sb.append(Integer.toString(permissions, 8));
0427:                    sb.append(' ');
0428:                    sb.append(file.canonicalPath());
0429:                    final String response = command(sb.toString());
0430:                    // Look for error message in response.
0431:                    if (response != null && response.indexOf("chmod:") < 0) {
0432:                        // Success! Remove old entry (if any) from directory cache.
0433:                        DirectoryCache.getDirectoryCache().purge(file);
0434:                        return true;
0435:                    }
0436:                }
0437:                return false;
0438:            }
0439:
0440:            public synchronized boolean isConnected() {
0441:                return connected;
0442:            }
0443:
0444:            public synchronized boolean connect() {
0445:                if (connected) {
0446:                    Log.debug("SshSession.connect(): already connected");
0447:                    return true;
0448:                }
0449:                FastStringBuffer sb = new FastStringBuffer("jpty ssh ");
0450:                if (userName != null && userName.length() > 0) {
0451:                    sb.append("-l ");
0452:                    sb.append(userName);
0453:                    sb.append(' ');
0454:                }
0455:                if (port != DEFAULT_PORT) {
0456:                    sb.append("-p ");
0457:                    sb.append(port);
0458:                    sb.append(' ');
0459:                }
0460:                sb.append(hostName);
0461:                try {
0462:                    process = Runtime.getRuntime().exec(sb.toString());
0463:                } catch (Throwable t) {
0464:                    Log.error(t);
0465:                    return false;
0466:                }
0467:                try {
0468:                    stdin = new OutputStreamWriter(process.getOutputStream());
0469:                    int timeout = Editor.preferences().getIntegerProperty(
0470:                            Property.SSH_TIMEOUT);
0471:                    Log.debug("ssh timeout is " + timeout + " ms");
0472:                    stdoutThread = new StdoutThread();
0473:                    stdoutThread.setTimeOut(timeout);
0474:                    stderrThread = new StderrThread();
0475:                    stderrThread.setTimeOut(timeout);
0476:                    stdoutThread.start();
0477:                    stderrThread.start();
0478:                } catch (Throwable t) {
0479:                    Log.error(t);
0480:                    return false;
0481:                }
0482:                if (!authenticate()) {
0483:                    killProcess();
0484:                    String message = output.toString().trim();
0485:                    if (message.length() == 0)
0486:                        message = "Authentication failed";
0487:                    MessageDialog.showMessageDialog(message, "Error");
0488:                    return false;
0489:                }
0490:                if (!connected) {
0491:                    killProcess();
0492:                    MessageDialog.showMessageDialog("Lost connection", "Error");
0493:                }
0494:                return connected;
0495:            }
0496:
0497:            private void initializeConnection() {
0498:                boolean oldEcho = echo;
0499:                echo = true;
0500:                String response = command("exec /bin/sh");
0501:                Log.debug("response = |" + response + "|");
0502:                FastStringBuffer sb = new FastStringBuffer("PS1='");
0503:                sb.append(PROMPT);
0504:                sb.append('\'');
0505:                response = command(sb.toString());
0506:                Log.debug("response = |" + response + "|");
0507:                Log.debug("PROMPT   = |" + PROMPT + "|");
0508:                command("unset MAILCHECK");
0509:                loginDirectory = getCurrentDirectory();
0510:                connected = (loginDirectory != null);
0511:                echo = oldEcho;
0512:            }
0513:
0514:            private boolean authenticate() {
0515:                output.setLength(0);
0516:                int response;
0517:                while ((response = checkInitialResponse()) == TRY_AGAIN) {
0518:                    Log.debug("authenticate() TRY_AGAIN");
0519:                    try {
0520:                        final long TIMEOUT = 30000; // 30 seconds
0521:                        long start = System.currentTimeMillis();
0522:                        wait(TIMEOUT);
0523:                        if (System.currentTimeMillis() - start > TIMEOUT)
0524:                            return false;
0525:                    } catch (InterruptedException e) {
0526:                        Log.debug("SshSession.connect interrupted!");
0527:                        return false;
0528:                    }
0529:                }
0530:                if (response == AUTHENTICATED) {
0531:                    initializeConnection();
0532:                    return connected;
0533:                }
0534:                if (response == PASSWORD)
0535:                    return authenticateWithPassword();
0536:                if (response == PASSPHRASE)
0537:                    return authenticateWithPassphrase();
0538:                return false;
0539:            }
0540:
0541:            private boolean authenticateWithPassword() {
0542:                if (password == null) {
0543:                    password = Netrc.getPassword(hostName, userName);
0544:                    if (password == null) {
0545:                        if (SwingUtilities.isEventDispatchThread())
0546:                            getPasswordRunnable.run();
0547:                        else {
0548:                            try {
0549:                                SwingUtilities
0550:                                        .invokeAndWait(getPasswordRunnable);
0551:                            } catch (Exception e) {
0552:                                Log.error(e);
0553:                            }
0554:                        }
0555:                        if (password == null) {
0556:                            killProcess();
0557:                            return false;
0558:                        }
0559:                    }
0560:                }
0561:                return _authenticate(password);
0562:            }
0563:
0564:            private boolean authenticateWithPassphrase() {
0565:                if (passphrase == null) {
0566:                    if (SwingUtilities.isEventDispatchThread())
0567:                        getPassphraseRunnable.run();
0568:                    else {
0569:                        try {
0570:                            SwingUtilities.invokeAndWait(getPassphraseRunnable);
0571:                        } catch (Exception e) {
0572:                            Log.error(e);
0573:                        }
0574:                    }
0575:                    if (passphrase == null) {
0576:                        killProcess();
0577:                        return false;
0578:                    }
0579:                }
0580:                return _authenticate(passphrase);
0581:            }
0582:
0583:            private boolean _authenticate(String pass) {
0584:                output.setLength(0);
0585:                boolean oldEcho = echo;
0586:                echo = true;
0587:                sendPass(pass);
0588:                if (checkAuthenticationResponse()) {
0589:                    Log.debug("authenticate SUCCEEDED!");
0590:                    initializeConnection();
0591:                    echo = oldEcho;
0592:                    return connected;
0593:                } else {
0594:                    Log.debug("authenticate FAILED!");
0595:                    echo = oldEcho;
0596:                    return false;
0597:                }
0598:            }
0599:
0600:            private int checkInitialResponse() {
0601:                final String s = output.toString().trim();
0602:                String check;
0603:                int index = s.lastIndexOf("\r\n");
0604:                if (index >= 0) {
0605:                    check = s.substring(index + 2);
0606:                } else {
0607:                    index = s.lastIndexOf('\n');
0608:                    if (index >= 0)
0609:                        check = s.substring(index + 1);
0610:                    else
0611:                        check = s;
0612:                }
0613:                Log.debug("check = |" + check + "|");
0614:                String lower = check.toLowerCase();
0615:                if (lower.indexOf("connection refused") >= 0)
0616:                    return NO;
0617:                if (lower.endsWith("password:")) {
0618:                    passwordTitle = "Password";
0619:                    passwordPrompt = check;
0620:                    return PASSWORD;
0621:                }
0622:                if (s.startsWith("Password:") && lower.endsWith("response:")) {
0623:                    passwordTitle = "Password";
0624:                    passwordPrompt = check;
0625:                    return PASSWORD;
0626:                }
0627:                if (lower.startsWith("enter passphrase ")
0628:                        && lower.endsWith(":")) {
0629:                    // We don't want to use the password from .netrc in this situation.
0630:                    password = null;
0631:                    passwordTitle = "Passphrase";
0632:                    passwordPrompt = check;
0633:                    return PASSPHRASE;
0634:                }
0635:                RE promptRE = getPromptRE();
0636:                if (promptRE.getMatch(lower) != null)
0637:                    return AUTHENTICATED;
0638:                return TRY_AGAIN;
0639:            }
0640:
0641:            private boolean checkAuthenticationResponse() {
0642:                String s = output.toString();
0643:                Log.debug("checkAuthenticationResponse output = |" + output
0644:                        + "|");
0645:                int result = checkResponse(s);
0646:                Log.debug("checkAuthenticationResponse result = " + result);
0647:                while (result == TRY_AGAIN) {
0648:                    try {
0649:                        wait();
0650:                    } catch (InterruptedException e) {
0651:                        Log.error(e);
0652:                        return false;
0653:                    }
0654:                    s = output.toString();
0655:                    Log.debug("checkAuthenticationResponse output = |" + output
0656:                            + "|");
0657:                    result = checkResponse(s);
0658:                    Log.debug("checkAuthenticationResponse result = " + result);
0659:                }
0660:                Log.debug("checkAuthenticationResponse returning "
0661:                        + (result == YES));
0662:                return result == YES;
0663:            }
0664:
0665:            // Helper for checkAuthenticationResponse().
0666:            private int checkResponse(String s) {
0667:                if (s.toLowerCase().indexOf("denied") >= 0)
0668:                    return NO;
0669:                String prompt = null;
0670:                for (int i = s.length(); i-- > 0;) {
0671:                    char c = s.charAt(i);
0672:                    if (c == '\r' || c == '\n') {
0673:                        prompt = s.substring(i + 1);
0674:                        break;
0675:                    }
0676:                }
0677:                if (prompt == null)
0678:                    prompt = s;
0679:                Log.debug("prompt = |" + reveal(prompt) + "|");
0680:                RE promptRE = getPromptRE();
0681:                Debug.assertTrue(promptRE != null);
0682:                REMatch match = promptRE.getMatch(prompt);
0683:                if (match != null)
0684:                    return YES;
0685:                return TRY_AGAIN;
0686:            }
0687:
0688:            private RE _promptRE;
0689:
0690:            public RE getPromptRE() {
0691:                if (_promptRE == null) {
0692:                    try {
0693:                        _promptRE = new RE(Editor.preferences()
0694:                                .getStringProperty(Property.SSH_PROMPT_PATTERN));
0695:                    } catch (REException e) {
0696:                        Log.error(e);
0697:                        _promptRE = new UncheckedRE(
0698:                                DEFAULT_SHELL_PROMPT_PATTERN);
0699:                    }
0700:                }
0701:                Debug.assertTrue(_promptRE != null);
0702:                return _promptRE;
0703:            }
0704:
0705:            private Runnable getPasswordRunnable = new Runnable() {
0706:                public void run() {
0707:                    final Editor editor = Editor.currentEditor();
0708:                    editor.setDefaultCursor();
0709:                    password = PasswordDialog.showPasswordDialog(editor,
0710:                            passwordPrompt, passwordTitle);
0711:                    editor.setWaitCursor();
0712:                }
0713:            };
0714:
0715:            private Runnable getPassphraseRunnable = new Runnable() {
0716:                public void run() {
0717:                    final Editor editor = Editor.currentEditor();
0718:                    editor.setDefaultCursor();
0719:                    passphrase = PasswordDialog.showPasswordDialog(editor,
0720:                            passwordPrompt, passwordTitle);
0721:                    editor.setWaitCursor();
0722:                }
0723:            };
0724:
0725:            private String getCurrentDirectory() {
0726:                final String s = command("pwd");
0727:                if (s == null)
0728:                    return null; // Lost connection.
0729:                int index = s.indexOf("\r\n");
0730:                if (index < 0)
0731:                    index = s.indexOf('\n');
0732:                final String dir = index >= 0 ? s.substring(0, index) : s;
0733:                Log.debug("getCurrentDirectory() returning |" + dir + "|");
0734:                return dir;
0735:            }
0736:
0737:            private void disconnect() {
0738:                if (connected) {
0739:                    try {
0740:                        stdin.write("exit\n");
0741:                    } catch (Exception e) {
0742:                        Log.error(e);
0743:                    }
0744:                    killProcess();
0745:                }
0746:            }
0747:
0748:            private void killProcess() {
0749:                Process p = process; // Avoid races.
0750:                if (p != null) {
0751:                    try {
0752:                        Log.debug("calling Process.destroy()");
0753:                        p.destroy();
0754:                        Log.debug("calling Process.waitFor()");
0755:                        p.waitFor();
0756:                    } catch (InterruptedException e) {
0757:                        Log.error(e);
0758:                    }
0759:                    process = null;
0760:                    synchronized (this ) {
0761:                        if (stdin != null) {
0762:                            try {
0763:                                stdin.close();
0764:                            } catch (IOException e) {
0765:                                Log.error(e);
0766:                            }
0767:                            stdin = null;
0768:                        }
0769:                        if (stdoutThread != null) {
0770:                            stdoutThread.cancel();
0771:                            stdoutThread = null;
0772:                        }
0773:                        if (stderrThread != null) {
0774:                            stderrThread.cancel();
0775:                            stderrThread = null;
0776:                        }
0777:                    }
0778:                }
0779:                connected = false;
0780:            }
0781:
0782:            public synchronized final void dispose() {
0783:                Log.debug("SshSession.dispose");
0784:                if (connected)
0785:                    disconnect();
0786:                unregister(this );
0787:            }
0788:
0789:            private synchronized String command(String cmd) {
0790:                if (!write(cmd.concat("\n")))
0791:                    return null;
0792:                output.setLength(0);
0793:                while (output.length() == 0) {
0794:                    try {
0795:                        wait();
0796:                    } catch (InterruptedException e) {
0797:                        Log.error(e);
0798:                    }
0799:                }
0800:                String s = output.toString();
0801:                // Strip echo of original command.
0802:                if (s.startsWith(cmd)) {
0803:                    int i = cmd.length();
0804:                    while (i < s.length()) {
0805:                        char c = s.charAt(i);
0806:                        if (c == '\r' || c == '\n')
0807:                            ++i;
0808:                        else
0809:                            break;
0810:                    }
0811:                    if (i > cmd.length())
0812:                        s = s.substring(i);
0813:                }
0814:                // Strip prompt.
0815:                int index = s.lastIndexOf("\r\n");
0816:                if (index >= 0) {
0817:                    s = s.substring(0, index);
0818:                } else {
0819:                    index = s.lastIndexOf('\n');
0820:                    if (index >= 0)
0821:                        s = s.substring(0, index);
0822:                }
0823:                return s;
0824:            }
0825:
0826:            private static final RE totalRE = new UncheckedRE(
0827:                    "\\n?[^0-9]+ [0-9]+");
0828:
0829:            private synchronized String lsla() {
0830:                boolean valid = false;
0831:                if (!write("\\ls -la\n"))
0832:                    return null;
0833:                output.setLength(0);
0834:                String s = null;
0835:                for (int i = 0; i < 2; i++) {
0836:                    if (i > 0)
0837:                        Log.debug("lsla retry " + i);
0838:                    try {
0839:                        wait();
0840:                    } catch (InterruptedException e) {
0841:                        Log.error(e);
0842:                        return null;
0843:                    }
0844:                    s = output.toString();
0845:                    REMatch match = totalRE.getMatch(s);
0846:                    Log.debug("match = |" + match + "|");
0847:                    if (match == null) {
0848:                        Log.error("lsla no \"total\" line");
0849:                        continue;
0850:                    }
0851:                    s = s.substring(match.getEndIndex());
0852:                    int index = s.indexOf('\n');
0853:                    if (index < 0) {
0854:                        // Shouldn't happen.
0855:                        Log.error("lsla no '\\n'");
0856:                        continue;
0857:                    }
0858:                    s = s.substring(index + 1);
0859:                    valid = true;
0860:                    break;
0861:                }
0862:                if (!valid) {
0863:                    Log.error("lsla output not valid - returning null");
0864:                    return null;
0865:                }
0866:                // Strip prompt.
0867:                int index = s.lastIndexOf("\r\n");
0868:                if (index >= 0)
0869:                    s = s.substring(0, index);
0870:                else {
0871:                    index = s.lastIndexOf('\n');
0872:                    if (index >= 0)
0873:                        s = s.substring(0, index);
0874:                }
0875:                return s;
0876:            }
0877:
0878:            // Do ls -ld on one file or directory.
0879:            private synchronized String lsld(String path) {
0880:                Debug.assertTrue(path != null);
0881:                Debug.assertTrue(path.length() != 0);
0882:                FastStringBuffer sb = new FastStringBuffer("\\ls -ld \"");
0883:                sb.append(path);
0884:                sb.append('"');
0885:                sb.append('\n');
0886:                if (!write(sb.toString()))
0887:                    return null;
0888:                output.setLength(0);
0889:                while (output.length() == 0) {
0890:                    try {
0891:                        wait();
0892:                    } catch (InterruptedException e) {
0893:                        Log.error(e);
0894:                    }
0895:                }
0896:                String s = output.toString();
0897:
0898:                // Strip echo of original command.
0899:                if (s.startsWith("ls -ld ")) {
0900:                    // Strip through end of line.
0901:                    int index = s.indexOf('\n');
0902:                    if (index < 0)
0903:                        return null; // Shouldn't happen.
0904:                    s = s.substring(index + 1);
0905:                }
0906:
0907:                // Skip lines starting with '<'.
0908:                while (s.length() > 0 && s.charAt(0) == '<') {
0909:                    int index = s.indexOf('\n');
0910:                    if (index < 0)
0911:                        return null; // Shouldn't happen.
0912:                    s = s.substring(index + 1);
0913:                }
0914:
0915:                // Now we've arrived at the line we want. Strip "\r\n" or '\n'.
0916:                int index = s.indexOf("\r\n");
0917:                if (index >= 0) {
0918:                    s = s.substring(0, index);
0919:                } else {
0920:                    index = s.lastIndexOf('\n');
0921:                    if (index >= 0)
0922:                        s = s.substring(0, index);
0923:                }
0924:                return s;
0925:            }
0926:
0927:            // Password or passphrase.
0928:            private void sendPass(String pass) {
0929:                Debug.assertTrue(pass != null);
0930:                try {
0931:                    stdin.write(pass);
0932:                    stdin.write("\n");
0933:                    stdin.flush();
0934:                    if (outputBuffer != null) {
0935:                        FastStringBuffer sb = new FastStringBuffer("==> ");
0936:                        for (int i = pass.length(); i-- > 0;)
0937:                            sb.append('*');
0938:                        sb.append('\n');
0939:                        writeToOutputBuffer(sb.toString());
0940:                    }
0941:                } catch (Exception e) {
0942:                    Log.error(e);
0943:                }
0944:            }
0945:
0946:            private boolean write(String s) {
0947:                try {
0948:                    if (echo
0949:                            || Editor.preferences().getBooleanProperty(
0950:                                    Property.SSH_ECHO))
0951:                        Log.debug("==> |" + s + "|");
0952:                    if (outputBuffer != null)
0953:                        writeToOutputBuffer("==> " + s);
0954:                    stdin.write(s);
0955:                    stdin.flush();
0956:                    return true;
0957:                } catch (IOException e) {
0958:                    Log.error(e);
0959:                    killProcess();
0960:                    return false;
0961:                }
0962:            }
0963:
0964:            private void writeToOutputBuffer(final String s) {
0965:                Runnable r = new Runnable() {
0966:                    public void run() {
0967:                        // Avoid race (and NPE) if setOutputBuffer(null) gets called in
0968:                        // another thread.
0969:                        final Buffer buf = outputBuffer;
0970:                        if (buf == null)
0971:                            return;
0972:                        try {
0973:                            buf.lockWrite();
0974:                        } catch (InterruptedException e) {
0975:                            Log.debug(e);
0976:                            return;
0977:                        }
0978:                        try {
0979:                            buf.append(s);
0980:                            buf.renumber();
0981:                        } finally {
0982:                            buf.unlockWrite();
0983:                        }
0984:                        for (EditorIterator it = new EditorIterator(); it
0985:                                .hasNext();) {
0986:                            Editor ed = it.nextEditor();
0987:                            if (ed.getBuffer() == buf) {
0988:                                ed.setDot(buf.getEnd());
0989:                                ed.moveCaretToDotCol();
0990:                                ed.setUpdateFlag(REPAINT);
0991:                                ed.updateDisplay();
0992:                            }
0993:                        }
0994:                    }
0995:                };
0996:                SwingUtilities.invokeLater(r);
0997:            }
0998:
0999:            public void checkLogin() {
1000:                if (userName == null)
1001:                    userName = System.getProperty("user.name");
1002:                if (password == null) {
1003:                    for (BufferIterator it = new BufferIterator(); it.hasNext();) {
1004:                        Buffer buf = it.nextBuffer();
1005:                        if (buf.getFile() instanceof  SshFile) {
1006:                            SshFile f = (SshFile) buf.getFile();
1007:                            if (f.hostName != null
1008:                                    && f.hostName.equals(hostName)) {
1009:                                if (f.getUserName() != null
1010:                                        && f.getUserName().equals(userName)) {
1011:                                    password = f.getPassword();
1012:                                    break;
1013:                                }
1014:                            }
1015:                        }
1016:                    }
1017:                }
1018:            }
1019:
1020:            private static synchronized void cleanup() {
1021:                // Walk buffer list in event dispatch thread.
1022:                if (!SwingUtilities.isEventDispatchThread()) {
1023:                    Debug.bug();
1024:                    return;
1025:                }
1026:                if (sessionList != null) {
1027:                    for (int i = sessionList.size(); i-- > 0;) {
1028:                        SshSession session = (SshSession) sessionList.get(i);
1029:                        if (session.isLocked())
1030:                            continue;
1031:                        String hostName = session.getHostName();
1032:                        boolean inUse = false;
1033:                        for (BufferIterator it = new BufferIterator(); it
1034:                                .hasNext();) {
1035:                            Buffer buf = it.nextBuffer();
1036:                            if (buf.getFile() instanceof  SshFile) {
1037:                                if (hostName
1038:                                        .equals(buf.getFile().getHostName())) {
1039:                                    inUse = true;
1040:                                    break;
1041:                                }
1042:                            }
1043:                        }
1044:                        if (!inUse)
1045:                            session.dispose();
1046:                    }
1047:                    if (sessionList.size() == 0) {
1048:                        sessionList = null;
1049:                        if (cleanupThread != null) {
1050:                            cleanupThread.cancel();
1051:                            cleanupThread = null;
1052:                        }
1053:                    }
1054:                }
1055:            }
1056:
1057:            private static final Runnable cleanupRunnable = new Runnable() {
1058:                public void run() {
1059:                    cleanup();
1060:                }
1061:            };
1062:
1063:            private String stdOutFilter(String s) {
1064:                return s;
1065:            }
1066:
1067:            private synchronized void stdOutUpdate(final String s) {
1068:                if (echo
1069:                        || Editor.preferences().getBooleanProperty(
1070:                                Property.SSH_ECHO))
1071:                    Log.debug("<== |" + s + "|");
1072:                if (outputBuffer != null)
1073:                    writeToOutputBuffer(s);
1074:                output.append(s);
1075:                notify();
1076:            }
1077:
1078:            private String stdErrFilter(String s) {
1079:                return s;
1080:            }
1081:
1082:            private void stdErrUpdate(final String s) {
1083:                Log.debug("stderr: |" + s + "|");
1084:            }
1085:
1086:            private static String reveal(String s) {
1087:                FastStringBuffer sb = new FastStringBuffer();
1088:                final int length = s.length();
1089:                for (int i = 0; i < length; i++) {
1090:                    char c = s.charAt(i);
1091:                    switch (c) {
1092:                    case '\r':
1093:                        sb.append("\\r");
1094:                        break;
1095:                    case '\n':
1096:                        sb.append("\\n");
1097:                        break;
1098:                    case '\t':
1099:                        sb.append("\\t");
1100:                        break;
1101:                    default:
1102:                        sb.append(c);
1103:                        break;
1104:                    }
1105:                }
1106:                return sb.toString();
1107:            }
1108:
1109:            class StdoutThread extends ReaderThread {
1110:                // If this constructor is private, we run into jikes 1.15 bug #2256.
1111:                StdoutThread() {
1112:                    super (process.getInputStream());
1113:                }
1114:
1115:                public String filter(String s) {
1116:                    return stdOutFilter(s);
1117:                }
1118:
1119:                public void update(String s) {
1120:                    stdOutUpdate(s);
1121:                }
1122:            }
1123:
1124:            class StderrThread extends ReaderThread {
1125:                // If this constructor is private, we run into jikes 1.15 bug #2256.
1126:                StderrThread() {
1127:                    super (process.getErrorStream());
1128:                }
1129:
1130:                public String filter(String s) {
1131:                    return stdErrFilter(s);
1132:                }
1133:
1134:                public void update(String s) {
1135:                    stdErrUpdate(s);
1136:                }
1137:            }
1138:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.