package com.eactive.ext.djb; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.Charset; /** * damo-manager.jar 의 CLI 진입점 (manifest Main-Class). * encrypt/decrypt/hash 동작을 운영/로컬에서 빠르게 확인하는 테스트 도구. * * 실행 방식: * java -jar damo-manager.jar # 대화식(REPL) * java -jar damo-manager.jar <cmd> [text] # 파라미터식 1회 실행 * echo "<text>" | java -jar damo-manager.jar <cmd> # stdin 입력 → stdout 출력 * * 명령: * enc|encrypt <text> 암호화 (real=ScpEncB64, fake=Base64, bypass=원문) * dec|decrypt <text> 복호화 * sha256|hash256 <text> SHA-256 해시 (bypass=원문) * sha512|hash512 <text> SHA-512 해시 (bypass=원문) * info|mode 현재 모드/리비전/리턴코드 * help|? 도움말 * quit|exit (대화식) 종료 * * 기본은 bypass(무변환). 실제 암복호화(real/fake) 를 쓰려면 -Ddamo-manager.enabled=true * * stdin/stdout: 파라미터식에서 text 인자를 생략하면 stdin 전체를 읽어 입력으로 사용하고 * 결과를 stdout 으로 출력하므로 파이프 연동이 가능하다 (후행 개행 1개는 제거). */ public final class DamoCli { private static final Charset UTF8 = Charset.forName("UTF-8"); private DamoCli() { } public static void main(String[] args) throws IOException { PrintStream out = new PrintStream(System.out, true, "UTF-8"); PrintStream err = new PrintStream(System.err, true, "UTF-8"); DamoManager damo = new DamoManager(); if (args.length == 0) { repl(damo, out, err); return; } String cmd = args[0]; String lower = cmd.toLowerCase(); if (lower.equals("info") || lower.equals("mode")) { out.println(modeLine(damo)); return; } if (lower.equals("help") || lower.equals("?") || lower.equals("-h") || lower.equals("--help")) { out.println(usage()); return; } String text; if (args.length >= 2) { StringBuilder sb = new StringBuilder(); for (int i = 1; i < args.length; i++) { if (i > 1) { sb.append(' '); } sb.append(args[i]); } text = sb.toString(); } else { if (System.console() != null) { err.println("(stdin 입력 대기중... 입력 후 Ctrl-D)"); } text = readAllStdin(); } String result = run(damo, cmd, text, err); if (result == null) { System.exit(2); } out.println(result); } private static void repl(DamoManager damo, PrintStream out, PrintStream err) throws IOException { boolean tty = System.console() != null; if (tty) { out.println("damo-manager CLI (" + modeLine(damo) + ")"); out.println("명령: enc | dec | sha256 | sha512 | info | help | quit"); } BufferedReader in = new BufferedReader(new InputStreamReader(System.in, UTF8)); String line; while (true) { if (tty) { out.print("damo> "); out.flush(); } line = in.readLine(); if (line == null) { break; // EOF } line = line.trim(); if (line.isEmpty()) { continue; } int sp = line.indexOf(' '); String cmd = sp < 0 ? line : line.substring(0, sp); String text = sp < 0 ? "" : line.substring(sp + 1); String lower = cmd.toLowerCase(); if (lower.equals("quit") || lower.equals("exit") || lower.equals("q")) { break; } if (lower.equals("info") || lower.equals("mode")) { out.println(modeLine(damo)); continue; } if (lower.equals("help") || lower.equals("?")) { out.println(usage()); continue; } String result = run(damo, cmd, text, err); if (result != null) { out.println(result); } } } /** 명령 실행. 알 수 없는 명령이면 stderr 에 안내 후 null 반환. */ private static String run(DamoManager damo, String cmd, String text, PrintStream err) { String lower = cmd.toLowerCase(); if (lower.equals("enc") || lower.equals("encrypt")) { return damo.encrypt(text); } if (lower.equals("dec") || lower.equals("decrypt")) { return damo.decrypt(text); } if (lower.equals("sha256") || lower.equals("hash256")) { return damo.hash(DamoManager.SHA256, text); } if (lower.equals("sha512") || lower.equals("hash512")) { return damo.hash(DamoManager.SHA512, text); } err.println("unknown command: " + cmd); err.println(usage()); return null; } private static String modeLine(DamoManager damo) { String mode = damo.isBypassMode() ? "BYPASS" : (damo.isFakeMode() ? "FAKE" : "REAL"); return "mode=" + mode + " revision=" + damo.getRevision() + " returnCode=" + damo.getReturnCode(); } private static String usage() { return String.join("\n", "Usage:", " java -jar damo-manager.jar # 대화식(REPL)", " java -jar damo-manager.jar [text] # 파라미터식 1회 실행", " echo \"\" | java -jar damo-manager.jar # stdin 입력", "", "Commands:", " enc|encrypt 암호화 (real=ScpEncB64, fake=Base64, bypass=원문)", " dec|decrypt 복호화", " sha256|hash256 SHA-256 해시 (bypass=원문)", " sha512|hash512 SHA-512 해시 (bypass=원문)", " info|mode 현재 모드/리비전/리턴코드", " help|? 도움말", " quit|exit 대화식 종료", "", "모드 옵션 (기본은 bypass 무변환):", " -Ddamo-manager.enabled=true real/fake 동작 활성화 (scpdb 있으면 real, 없으면 fake)", " -Ddamo-manager.require-real=true 운영: real 강제. real 불가 시 기동 실패(fake/bypass 폴백 금지)"); } private static String readAllStdin() throws IOException { InputStream in = System.in; ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[4096]; int n; while ((n = in.read(buf)) != -1) { bos.write(buf, 0, n); } String s = new String(bos.toByteArray(), UTF8); // echo 등으로 들어온 후행 개행 1개 제거 if (s.endsWith("\r\n")) { return s.substring(0, s.length() - 2); } if (s.endsWith("\n")) { return s.substring(0, s.length() - 1); } return s; } }