1 52 53 package freemarker.debug.impl; 54 55 import java.io.IOException ; 56 import java.io.ObjectInputStream ; 57 import java.io.ObjectOutputStream ; 58 import java.io.Serializable ; 59 import java.io.UnsupportedEncodingException ; 60 import java.net.ServerSocket ; 61 import java.net.Socket ; 62 import java.security.MessageDigest ; 63 import java.security.SecureRandom ; 64 import java.util.Arrays ; 65 import java.util.Random ; 66 67 import freemarker.debug.Debugger; 68 import freemarker.log.Logger; 69 import freemarker.template.utility.SecurityUtilities; 70 import freemarker.template.utility.UndeclaredThrowableException; 71 72 76 class DebuggerServer 77 { 78 private static final Logger logger = Logger.getLogger("freemarker.debug.server"); 79 private static final Random R = new SecureRandom (); 81 82 private final byte[] password; 83 private final int port; 84 private final Serializable debuggerStub; 85 86 public DebuggerServer(Serializable debuggerStub) 87 { 88 port = SecurityUtilities.getSystemProperty("freemarker.debug.port", Debugger.DEFAULT_PORT).intValue(); 89 try 90 { 91 password = SecurityUtilities.getSystemProperty("freemarker.debug.password", "").getBytes("UTF-8"); 92 } 93 catch (UnsupportedEncodingException e) 94 { 95 throw new UndeclaredThrowableException(e); 96 } 97 this.debuggerStub = debuggerStub; 98 } 99 100 public void start() 101 { 102 new Thread (new Runnable () 103 { 104 public void run() 105 { 106 startInternal(); 107 } 108 }, "FreeMarker Debugger Server Acceptor").start(); 109 } 110 111 private void startInternal() 112 { 113 try 114 { 115 ServerSocket ss = new ServerSocket (port); 116 for(;;) 117 { 118 Socket s = ss.accept(); 119 new Thread (new DebuggerAuthProtocol(s)).start(); 120 } 121 } 122 catch(IOException e) 123 { 124 logger.error("Debugger server shut down.", e); 125 } 126 } 127 128 private class DebuggerAuthProtocol implements Runnable 129 { 130 private final Socket s; 131 132 DebuggerAuthProtocol(Socket s) 133 { 134 this.s = s; 135 } 136 137 public void run() 138 { 139 try 140 { 141 ObjectOutputStream out = new ObjectOutputStream (s.getOutputStream()); 142 ObjectInputStream in = new ObjectInputStream (s.getInputStream()); 143 byte[] challenge = new byte[512]; 144 R.nextBytes(challenge); 145 out.writeInt(220); out.writeObject(challenge); 147 MessageDigest md = MessageDigest.getInstance("SHA"); 148 md.update(password); 149 md.update(challenge); 150 byte[] response = (byte[])in.readObject(); 151 if(Arrays.equals(response, md.digest())) 152 { 153 out.writeObject(debuggerStub); 154 } 155 else 156 { 157 out.writeObject(null); 158 } 159 } 160 catch(Exception e) 161 { 162 logger.warn("Connection to " + s.getInetAddress().getHostAddress() + " abruply broke", e); 163 } 164 } 165 166 } 167 } 168 | Popular Tags |