1 13 14 package org.ejbca.samples; 15 16 import java.io.BufferedReader ; 17 import java.io.IOException ; 18 import java.io.InputStream ; 19 import java.io.InputStreamReader ; 20 import java.util.Date ; 21 import java.util.Enumeration ; 22 import java.util.Hashtable ; 23 import java.util.Map ; 24 import java.util.StringTokenizer ; 25 26 import javax.servlet.ServletConfig ; 27 import javax.servlet.ServletException ; 28 import javax.servlet.ServletOutputStream ; 29 import javax.servlet.http.HttpServlet ; 30 import javax.servlet.http.HttpServletRequest ; 31 import javax.servlet.http.HttpServletResponse ; 32 33 import org.apache.log4j.Logger; 34 import org.ejbca.ui.web.RequestHelper; 35 36 37 62 public class RemoteVerifyServlet extends HttpServlet { 63 private static Logger log = Logger.getLogger(RemoteVerifyServlet.class); 64 65 66 public static final String MSG_OK = "200 OK"; 67 68 69 public static final String MSG_PROTOCOL_MISMATCH = "400 Wrong protocol version"; 70 71 72 public static final String MSG_GENERIC_ERROR = "500 ERROR (Missing parameter?) : "; 73 74 75 public static final String REQUEST_USERNAME = "username"; 76 77 78 public static final String REQUEST_PASSWORD = "password"; 79 80 81 public static final String REQUEST_VERSION = "version"; 82 83 84 public static final String RESPONSE_END = "end"; 85 86 87 public static final String RESPONSE_STATUS = "status"; 88 89 90 public static final String RESPONSE_RESULT = "result"; 91 92 93 public static final String RESPONSE_MESSAGE = "message"; 94 95 96 public static final String GRANT = "grant"; 97 98 99 public static final String REJECT = "reject"; 100 101 102 protected static final int PROTOCOL_VERSION_MAJOR = 1; 103 104 105 protected static final int PROTOCOL_VERSION_MINOR = 0; 106 107 111 protected static Hashtable users; 112 113 120 protected static final String DNPART_DELIMITER = ":"; 121 122 129 protected static final String DNPART_NAME_VALUE_SEPARATOR = "="; 130 131 138 protected static final String RECORD_SEPARATOR = ";"; 139 140 147 protected static final String LINE_COMMENT = ";"; 148 149 150 protected static final String STATUS_KEY = "status"; 151 152 153 protected static int countAccess = 0; 154 155 156 protected static int countGranted = 0; 157 158 159 protected static int countRejected = 0; 160 161 167 void addUserDataToResult(AuthResult result, final String dnPartsString) { 168 if (dnPartsString == null) { 169 return; 170 } 171 172 Enumeration dnParts = new StringTokenizer (dnPartsString, DNPART_DELIMITER); 173 174 while (dnParts.hasMoreElements()) { 175 String dnPart = (String ) dnParts.nextElement(); 176 int separatorPosition = dnPart.indexOf(DNPART_NAME_VALUE_SEPARATOR); 177 String dnName = dnPart.substring(0, separatorPosition); 178 String dnValue = dnPart.substring(separatorPosition + 1); result.add(dnName, dnValue); 180 debugLog("addUserDataToResult: result=" + result); 181 } 182 } 183 184 193 protected AuthResult authenticateUser(String username, String password) { 194 AuthResult result = new AuthResult(); 195 String [] userData = findUserData(username); 196 197 if (userData == null) { 198 result.reject(); 199 result.setReason("Failed to authenticate credentials."); 200 debugLog("authenticateUser: No such user. REJECTING"); 201 } else { 202 debugLog("authenticateUser: Got userData for user '" + username + "'"); 203 204 if (password.equals(userData[0])) { 205 debugLog("authenticateUser: Password matched. GRANTING"); 206 result.grant(); 207 addUserDataToResult(result, userData[1]); 208 } else { 209 debugLog("authenticateUser: Password missmatch. REJECTING"); 210 result.reject(); 211 result.setReason("Failed to authenticate credentials."); 212 } 213 } 214 215 return result; 216 } 217 218 223 protected void debugLog(final String s) { 224 log.debug(s); 225 } 226 227 232 protected void infoLog(final String s) { 233 log.info(s); 234 } 235 236 241 protected void errorLog(final String s) { 242 log.error(s); 243 } 244 245 251 protected void errorLog(final String s, java.lang.Exception e) { 252 log.error(s, e); 253 } 254 255 263 protected void doGet(HttpServletRequest req, HttpServletResponse res) 264 throws ServletException , IOException { 265 res.setContentType("text/plain"); 266 267 ServletOutputStream out = res.getOutputStream(); 268 269 String remoteAddr = req.getRemoteAddr(); 271 272 String method = req.getMethod(); 275 String path = req.getServletPath(); 276 log.debug("Received request: method="+method+", path="+path); 277 278 out.print("You called from " + remoteAddr); 279 out.println(" using " + method + " as method."); 280 281 RequestHelper.setDefaultCharacterEncoding(req); 282 try { 283 Map params = req.getParameterMap(); 284 285 if (params.containsKey(STATUS_KEY)) { 286 out.println("\n"); 287 out.println((new Date ()).toString() + " RemoteVerify status: "); 288 out.println("Accesses: " + countAccess); 289 out.println("Granted: " + countGranted); 290 out.println("Rejected: " + countRejected); 291 292 if (users != null) { 293 out.println("Number of users in database: " + users.size()); 294 } else { 295 out.println("No users in database."); 296 } 297 298 out.println("\n"); 299 out.println("Protocol version: " + PROTOCOL_VERSION_MAJOR + "." + 300 PROTOCOL_VERSION_MINOR); 301 out.println("Database loaded from: " + getInitParameter("dbfilename")); 302 out.println((new Date ()).toString() + " DONE."); 303 } 304 } catch (IllegalArgumentException ignored) { 305 out.println("Couldn't parse that request. Check parameters and try again."); 306 } 307 308 out.println("Request done."); 309 } 310 311 357 protected void doPost(HttpServletRequest req, HttpServletResponse res) 358 throws ServletException , IOException { 359 increaseAccess(); 360 361 res.setContentType("text/plain"); 362 363 ServletOutputStream out = res.getOutputStream(); 364 365 String remoteAddr = req.getRemoteAddr(); 368 369 String method = req.getMethod(); 373 String path = req.getServletPath(); 374 log.debug("Received request: method="+method+", path="+path); 375 376 Map params = req.getParameterMap(); 381 382 try { 383 String username = ""; 385 String password = ""; 386 String version = ""; 387 388 try { 389 username = ((String []) params.get(REQUEST_USERNAME))[0]; 390 password = ((String []) params.get(REQUEST_PASSWORD))[0]; 391 version = ((String []) params.get(REQUEST_VERSION))[0]; 392 } catch (ArrayIndexOutOfBoundsException ignored) { 393 } catch (NullPointerException ignoredAsWell) { 396 } 399 400 int majorversion = 0; 403 int minorversion = 0; 404 405 int dotAt = version.indexOf('.'); 407 408 if (dotAt == -1) { 409 try { 411 majorversion = Integer.parseInt(version); 412 } catch (NumberFormatException nfe) { 413 errorLog("doPost: Got " + nfe + " on call from " + remoteAddr + 414 " for username '" + username + 415 "'. Asuming version is OK. Tried to parse '" + version + "'"); 416 } 417 418 minorversion = 0; 419 } else { 420 try { 421 majorversion = Integer.parseInt(version.substring(0, dotAt)); 422 minorversion = Integer.parseInt(version.substring(1 + dotAt, version.length())); 423 } catch (NumberFormatException nfe) { 424 errorLog("doPost: Got " + nfe + " on call from " + remoteAddr + 425 " for username '" + username + 426 "'. Asuming version is OK. Tried to parse '" + version + "'"); 427 } 428 } 429 430 if ((majorversion == PROTOCOL_VERSION_MAJOR) && 433 (minorversion <= PROTOCOL_VERSION_MINOR)) { 434 AuthResult result = authenticateUser(username, password); 442 443 if (result.granted()) { 447 increaseGranted(); 448 out.println(RESPONSE_STATUS + "=" + MSG_OK); 449 out.println(RESPONSE_RESULT + "=" + GRANT); 450 debugLog("GRANTING request for '" + username + "'"); 451 452 Hashtable resultParams = result.getResult(); 454 String key; 455 456 for (Enumeration keys = resultParams.keys(); keys.hasMoreElements();) { 458 key = (String ) keys.nextElement(); 459 out.println(key + "=" + ((String ) resultParams.get(key))); 460 } 461 } else { increaseRejected(); 463 out.println(RESPONSE_STATUS + "=" + MSG_OK); 464 out.println(RESPONSE_RESULT + "=" + REJECT); 465 out.println(RESPONSE_MESSAGE + "=" + result.getReason()); 466 debugLog("REJECTING request for '" + username + "'. Reason: " + 467 result.getReason()); 468 } 469 470 out.println(RESPONSE_END); } else { 472 out.println(RESPONSE_STATUS + "=" + MSG_PROTOCOL_MISMATCH); 474 out.println("message=Accepting at most " + PROTOCOL_VERSION_MAJOR + "." + 475 PROTOCOL_VERSION_MINOR); 476 errorLog("PROTOCOL MISSMATCH. Got '" + version + "', but accepts only '" + 477 PROTOCOL_VERSION_MAJOR + "." + PROTOCOL_VERSION_MINOR + "'"); 478 } 479 } catch (Exception e) { 480 out.println(RESPONSE_STATUS + "=" + MSG_GENERIC_ERROR + e); 481 out.println(RESPONSE_END); errorLog("?Caught exception ", e); 483 } 484 } 485 486 494 protected String [] findUserData(String username) { 495 if (users == null) { 496 debugLog("findUserData: No users found. Returning null for user '" + username + "'."); 497 498 return null; 499 } 500 501 String [] result = (String []) users.get(username.toLowerCase()); 502 503 if (result != null) { 504 debugLog("findUserData: Information for user '" + username + "'found."); 505 } else { 506 debugLog("findUserData: No information for user '" + username + "'found."); 507 } 508 509 return result; 510 } 511 512 protected synchronized void increaseAccess() { 513 countAccess++; 514 } 515 516 protected synchronized void increaseGranted() { 517 countGranted++; 518 } 519 520 protected synchronized void increaseRejected() { 521 countRejected++; 522 } 523 524 531 public void init(ServletConfig config) throws ServletException { 532 super.init(config); 533 534 log = Logger.getLogger(this.getClass()); 535 536 debugLog((new Date ()).toString() + " RemoteVerify.init:"); 537 loadUserDB(); 538 } 539 540 544 protected synchronized void loadUserDB() { 545 Hashtable oldEnUsers = users; 547 users = null; 548 549 BufferedReader in = null; 550 debugLog((new Date ()).toString() + "loadUserDB: Loading from file: '" + 551 getInitParameter("dbfilename") + "'."); 552 553 InputStream is = getServletContext().getResourceAsStream(getInitParameter("dbfilename")); 554 in = new BufferedReader (new InputStreamReader (is)); 555 556 String line; 557 boolean readMore = true; 558 559 try { 560 while (readMore) { 561 line = in.readLine(); 562 563 if (line == null) { 564 readMore = false; 565 } else { 566 if (!line.startsWith(LINE_COMMENT)) { 567 Enumeration lineParts = new StringTokenizer (line, RECORD_SEPARATOR); 568 String username = (String ) lineParts.nextElement(); 569 debugLog("loadUserDB: username=" + username); 570 571 String password = (String ) lineParts.nextElement(); 572 debugLog("loadUserDB: password=" + password); 573 574 String userDataString = (String ) lineParts.nextElement(); 575 debugLog("loadUserDB: userDataString=" + userDataString); 576 577 StringTokenizer st = new StringTokenizer (userDataString, DNPART_DELIMITER); 578 debugLog("loadUserDB: st=" + st); 579 580 String [] userData = new String [2]; 581 userData[0] = password; 582 userData[1] = userDataString; 583 debugLog("loadUserDB: calling addUserData." + userData); 584 addUserData(username, userData); 585 } else { 586 debugLog("loadUserDB: skipping comment line." + line); 587 } 588 } 589 } 590 } catch (IOException ioe) { 591 errorLog("loadUserDB: FAILED TO PARSE FILE: '" + getInitParameter("dbfilename") + "'."); 592 errorLog("loadUserDB: Got exception: ", ioe); 593 errorLog("loadUserDB: Restored previous version of DB"); 594 users = oldEnUsers; 595 } finally { 596 try { 597 in.close(); 598 } catch (IOException ignored) { 599 } 600 } 601 602 debugLog((new Date ()).toString() + "loadUserDB: Done."); 603 } 604 605 611 protected void addUserData(String username, String [] userData) { 612 if (users == null) { 613 debugLog("addUserData: Creating new users."); 614 users = new Hashtable (); 615 } 616 617 debugLog("addUserData: Adding '" + username); 618 619 users.put(username.toLowerCase(), userData); 620 } 621 } | Popular Tags |