Files
djb-damo-manager/src/main/java/com/eactive/ext/djb/DamoCli.java
T
Rinjae 5db83e485d - damo-manager CLI 추가: DamoCli.java / Main-Class 선언
- Jenkinsfile 도입: 자동 빌드/테스트 워크플로 작성
- bypass 모드 도입: 시스템 프로퍼티로 암복호화 설정 분기
2026-06-22 15:18:07 +09:00

200 lines
7.4 KiB
Java

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 <t> | dec <t> | sha256 <t> | sha512 <t> | 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 <cmd> [text] # 파라미터식 1회 실행",
" echo \"<text>\" | java -jar damo-manager.jar <cmd> # stdin 입력",
"",
"Commands:",
" 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 무변환):",
" -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;
}
}