Skip to content

Commit 1ddf826

Browse files
committed
8316964: Security tools should not call System.exit
Reviewed-by: valeriep
1 parent 1f2a80b commit 1ddf826

File tree

8 files changed

+358
-208
lines changed

8 files changed

+358
-208
lines changed

src/java.base/share/classes/sun/security/tools/keytool/Main.java

+20-7
Original file line numberDiff line numberDiff line change
@@ -405,26 +405,38 @@ public String toString() {
405405
collator.setStrength(Collator.PRIMARY);
406406
}
407407

408-
private Main() { }
409-
410408
public static void main(String[] args) throws Exception {
411409
Main kt = new Main();
412-
kt.run(args, System.out);
410+
int exitCode = kt.run(args, System.out);
411+
if (exitCode != 0) {
412+
System.exit(exitCode);
413+
}
414+
}
415+
416+
private static class ExitException extends RuntimeException {
417+
@java.io.Serial
418+
static final long serialVersionUID = 0L;
419+
private final int errorCode;
420+
public ExitException(int errorCode) {
421+
this.errorCode = errorCode;
422+
}
413423
}
414424

415-
private void run(String[] args, PrintStream out) throws Exception {
425+
public int run(String[] args, PrintStream out) throws Exception {
416426
try {
417-
args = parseArgs(args);
427+
parseArgs(args);
418428
if (command != null) {
419429
doCommands(out);
420430
}
431+
} catch (ExitException ee) {
432+
return ee.errorCode;
421433
} catch (Exception e) {
422434
System.out.println(rb.getString("keytool.error.") + e);
423435
if (verbose) {
424436
e.printStackTrace(System.out);
425437
}
426438
if (!debug) {
427-
System.exit(1);
439+
return 1;
428440
} else {
429441
throw e;
430442
}
@@ -441,6 +453,7 @@ private void run(String[] args, PrintStream out) throws Exception {
441453
ksStream.close();
442454
}
443455
}
456+
return 0;
444457
}
445458

446459
/**
@@ -5247,7 +5260,7 @@ private void tinyHelp() {
52475260
if (debug) {
52485261
throw new RuntimeException("NO BIG ERROR, SORRY");
52495262
} else {
5250-
System.exit(1);
5263+
throw new ExitException(1);
52515264
}
52525265
}
52535266

src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Kinit.java

+40-38
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -92,14 +92,44 @@ public class Kinit {
9292
*/
9393

9494
public static void main(String[] args) {
95-
try {
96-
Kinit self = new Kinit(args);
95+
Kinit kinit = new Kinit();
96+
int exitCode = kinit.run(args);
97+
if (exitCode != 0) {
98+
System.exit(exitCode);
9799
}
98-
catch (Exception e) {
99-
String msg = null;
100-
if (e instanceof KrbException) {
101-
msg = ((KrbException)e).krbErrorMessage() + " " +
102-
((KrbException)e).returnCodeMessage();
100+
}
101+
102+
/**
103+
* Run the Kinit command.
104+
* @param args array of ticket request options.
105+
* Available options are: -f, -p, -c, principal, password.
106+
* @return the exit code
107+
*/
108+
public int run(String[] args) {
109+
try {
110+
if (args == null || args.length == 0) {
111+
options = new KinitOptions();
112+
} else {
113+
options = new KinitOptions(args);
114+
}
115+
switch (options.action) {
116+
case 0:
117+
// Help, already displayed in new KinitOptions().
118+
break;
119+
case 1:
120+
acquire();
121+
break;
122+
case 2:
123+
renew();
124+
break;
125+
default:
126+
throw new KrbException("kinit does not support action "
127+
+ options.action);
128+
}
129+
} catch (Exception e) {
130+
String msg;
131+
if (e instanceof KrbException ke) {
132+
msg = ke.krbErrorMessage() + " " + ke.returnCodeMessage();
103133
} else {
104134
msg = e.getMessage();
105135
}
@@ -109,37 +139,9 @@ public static void main(String[] args) {
109139
System.out.println("Exception: " + e);
110140
}
111141
e.printStackTrace();
112-
System.exit(-1);
113-
}
114-
return;
115-
}
116-
117-
/**
118-
* Constructs a new Kinit object.
119-
* @param args array of ticket request options.
120-
* Available options are: -f, -p, -c, principal, password.
121-
* @exception IOException if an I/O error occurs.
122-
* @exception RealmException if the Realm could not be instantiated.
123-
* @exception KrbException if error occurs during Kerberos operation.
124-
*/
125-
private Kinit(String[] args)
126-
throws IOException, RealmException, KrbException {
127-
if (args == null || args.length == 0) {
128-
options = new KinitOptions();
129-
} else {
130-
options = new KinitOptions(args);
131-
}
132-
switch (options.action) {
133-
case 1:
134-
acquire();
135-
break;
136-
case 2:
137-
renew();
138-
break;
139-
default:
140-
throw new KrbException("kinit does not support action "
141-
+ options.action);
142+
return -1;
142143
}
144+
return 0;
143145
}
144146

145147
private void renew()

src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/KinitOptions.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
4646
*/
4747
class KinitOptions {
4848

49-
// 1. acquire, 2. renew, 3. validate
49+
// 0. Help, 1. acquire, 2. renew, 3. validate
5050
public int action = 1;
5151

5252
// forwardable and proxiable flags have two states:
@@ -143,7 +143,8 @@ public KinitOptions(String[] args)
143143
// -help: legacy.
144144
args[i].equalsIgnoreCase("-help")) {
145145
printHelp();
146-
System.exit(0);
146+
action = 0;
147+
return;
147148
} else if (p == null) { // Haven't yet processed a "principal"
148149
p = args[i];
149150
try {

0 commit comments

Comments
 (0)