Skip to content

Commit dbac546

Browse files
author
Jesse Van Hill
authored
Merge pull request #15741 from jvanhill/15740-SpnegoTimeoutFix
Issue #15740: Fix timeout issue with running KTPASS command on the KD…
2 parents ff11d20 + 7d1c80e commit dbac546

File tree

210 files changed

+145
-5300
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

210 files changed

+145
-5300
lines changed

dev/com.ibm.ws.security.spnego.fat.common/fat/src/com/ibm/ws/security/spnego/fat/config/KdcHelper.java

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2014, 2020 IBM Corporation and others.
2+
* Copyright (c) 2014, 2021 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -21,18 +21,22 @@
2121
import java.io.PrintWriter;
2222
import java.net.ConnectException;
2323
import java.rmi.RemoteException;
24+
import java.util.Arrays;
2425
import java.util.EnumSet;
2526
import java.util.Map;
2627
import java.util.Set;
2728
import java.util.Vector;
2829
import java.util.concurrent.TimeUnit;
30+
import java.util.stream.Collectors;
2931

3032
import org.apache.sshd.client.SshClient;
3133
import org.apache.sshd.client.channel.ChannelExec;
3234
import org.apache.sshd.client.channel.ClientChannelEvent;
3335
import org.apache.sshd.client.scp.ScpClient;
3436
import org.apache.sshd.client.scp.ScpClientCreator;
3537
import org.apache.sshd.client.session.ClientSession;
38+
import org.apache.sshd.common.channel.Channel;
39+
import org.apache.sshd.common.channel.ChannelListener;
3640
import org.junit.Ignore;
3741

3842
import com.ibm.websphere.simplicity.ConnectionInfo;
@@ -878,13 +882,15 @@ protected ClientSession getSshSession(SshClient sshClient, Machine machine) thro
878882
* @throws IOException If there was an error executing the command.
879883
*/
880884
protected ProgramOutput executeSshCommand(ClientSession sshSession, String command, int timeout) throws IOException {
881-
Log.info(thisClass, "executeSshCommand", "Executing SSH command --> \"{1}\" with a {2}s timeout on session {0}", new Object[] { sshSession, command, timeout });
885+
final String methodName = "executeSshCommand";
886+
Log.info(thisClass, methodName, "Executing SSH command --> \"{1}\" with a {2}s timeout on session {0}", new Object[] { sshSession, command, timeout });
882887

883888
try (ByteArrayOutputStream stderr = new ByteArrayOutputStream();
884889
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
885890
ChannelExec channel = sshSession.createExecChannel(command)) {
886891
channel.setOut(stdout);
887892
channel.setErr(stderr);
893+
channel.addChannelListener(new SshChannelListener());
888894
try {
889895
long remainingTimeoutMs = TimeUnit.SECONDS.toMillis(timeout);
890896

@@ -896,7 +902,7 @@ protected ProgramOutput executeSshCommand(ClientSession sshSession, String comma
896902
remainingTimeoutMs -= System.currentTimeMillis() - startTimeMs;
897903

898904
if (remainingTimeoutMs <= 0) {
899-
Log.info(thisClass, "executeSshCommand", "The SSH command timed out.");
905+
Log.info(thisClass, methodName, "The SSH command timed out.");
900906
throw new IOException("Timed out trying to open a channel with the host to execute the SSH command. The timeout was " + timeout + " seconds.");
901907
}
902908

@@ -909,17 +915,68 @@ protected ProgramOutput executeSshCommand(ClientSession sshSession, String comma
909915
* Did the command timeout? If so throw an exception.
910916
*/
911917
if (ccEvents.contains(ClientChannelEvent.TIMEOUT)) {
912-
Log.info(thisClass, "executeSshCommand", "The SSH command timed out.");
918+
Log.info(thisClass, methodName, "The SSH command timed out. The timeout was " + timeout + " seconds.");
913919
throw new IOException("The SSH command timed out while executing. The timeout was " + timeout + " seconds.");
914920
}
915-
Log.info(thisClass, "executeSshCommand", "SSH command returned status of {0}", channel.getExitStatus());
921+
916922
return new ProgramOutput(command, channel.getExitStatus(), new String(stdout.toByteArray()), new String(stderr.toByteArray()));
917923
} finally {
918-
channel.close(false);
924+
try {
925+
channel.close(false);
926+
} catch (Throwable t) {
927+
// Ignore.
928+
}
929+
930+
logSshOutput(new String(stdout.toByteArray()).trim(), new String(stderr.toByteArray()).trim());
919931
}
920932
}
921933
}
922934

935+
/**
936+
* Log stdout and stderr from an SSH channel.
937+
*
938+
* @param stdout Standard output from the channel.
939+
* @param stderr Standard input from the channel.
940+
*/
941+
private static void logSshOutput(String stdout, String stderr) {
942+
final String methodName = "logSshOutput";
943+
944+
/*
945+
* Process stdout.
946+
*/
947+
if (stdout.isEmpty()) {
948+
stdout = " [STDOUT] <NONE>";
949+
} else {
950+
/*
951+
* Add " [STDOUT] " to the beginning of each line. The split
952+
* method might be resource intensive if we have large strings.
953+
*/
954+
stdout = Arrays.stream(stdout.split("\\r?\\n"))
955+
.filter(line -> true)
956+
.map(line -> " [STDOUT] " + line + System.lineSeparator())
957+
.collect(Collectors.joining());
958+
}
959+
960+
/*
961+
* Process stderr.
962+
*/
963+
if (stderr.isEmpty()) {
964+
stderr = " [STDERR] <NONE>";
965+
} else {
966+
/*
967+
* Add " [STDERR] " to the beginning of each line. The split
968+
* method might be resource intensive if we have large strings.
969+
*/
970+
stderr = Arrays.stream(stderr.split("\\r?\\n"))
971+
.filter(line -> true)
972+
.map(line -> " [STDERR] " + line + System.lineSeparator())
973+
.collect(Collectors.joining());
974+
}
975+
976+
Log.info(thisClass, methodName, "SSH command standard output: \n{0}", stdout);
977+
Log.info(thisClass, methodName, "SSH command standard error: \n{0}", stderr);
978+
}
979+
923980
/**
924981
* Determine whether the remote file exists.
925982
*
@@ -1005,4 +1062,37 @@ protected boolean deleteRemoteFile(ClientSession sshSession, String remoteFile)
10051062
Log.info(thisClass, "deleteRemoteFile", "Delete of remote file was successful? " + success);
10061063
return success;
10071064
}
1065+
1066+
/**
1067+
* Handler for listenting to SSH channel events.
1068+
*/
1069+
class SshChannelListener implements ChannelListener {
1070+
private Class<?> thisClass = SshChannelListener.class;
1071+
1072+
@Override
1073+
public void channelInitialized(Channel channel) {
1074+
Log.info(thisClass, "channelInitialized", "Channel: " + channel);
1075+
}
1076+
1077+
@Override
1078+
public void channelOpenSuccess(Channel channel) {
1079+
Log.info(thisClass, "channelOpenSuccess", "Channel: " + channel);
1080+
}
1081+
1082+
@Override
1083+
public void channelOpenFailure(Channel channel,
1084+
Throwable reason) {
1085+
Log.error(thisClass, "channelOpenFailure", reason, "Channel: " + channel);
1086+
}
1087+
1088+
@Override
1089+
public void channelClosed(Channel channel, Throwable reason) {
1090+
Log.error(thisClass, "channelClosed", reason, "Channel: " + channel);
1091+
}
1092+
1093+
@Override
1094+
public void channelStateChanged(Channel channel, String hint) {
1095+
Log.info(thisClass, "channelStateChanged", "Channel: " + channel + ", hint: " + hint);
1096+
}
1097+
}
10081098
}

dev/com.ibm.ws.security.spnego.fat.common/fat/src/com/ibm/ws/security/spnego/fat/config/MsKdcHelper.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2014, 2020 IBM Corporation and others.
2+
* Copyright (c) 2014, 2021 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -221,8 +221,6 @@ public void setSpnForUser(String user, String spnHost) throws Exception {
221221
String setUserSpnCommand = "./" + remoteScriptName + " " + user + " HTTP " + spnHost;
222222
ProgramOutput output = executeRemoteCommand(remoteScriptName, setUserSpnCommand, true);
223223

224-
Log.info(thisClass, methodName, "command stdout: " + output.getStdout());
225-
Log.info(thisClass, methodName, "command stderr: " + output.getStderr());
226224
if (output.getReturnCode() != 0) {
227225
throw new RemoteException("Setting SPN for user failed with return code " + output.getReturnCode());
228226
}
@@ -273,8 +271,6 @@ public void deleteSpnForUser(String user, String spn) throws Exception {
273271
String setUserSpnCommand = "./" + remoteScriptName + " " + user + " HTTP " + spn;
274272
ProgramOutput output = executeRemoteCommand(remoteScriptName, setUserSpnCommand, true);
275273

276-
Log.info(thisClass, methodName, "command stdout: " + output.getStdout());
277-
Log.info(thisClass, methodName, "command stderr: " + output.getStderr());
278274
if (output.getReturnCode() != 0) {
279275
throw new RemoteException("Deleting SPN for user failed with return code " + output.getReturnCode());
280276
}
@@ -303,8 +299,6 @@ public void addSpnToKeytab(String user, String spn) throws Exception {
303299
ProgramOutput output = executeRemoteCommand(remoteScriptName, addSpnToKeytabCommand, true);
304300
InitClass.needToPushaddSPNKeytab = false;
305301

306-
Log.info(thisClass, methodName, "command stdout: " + output.getStdout());
307-
Log.info(thisClass, methodName, "command stderr: " + output.getStderr());
308302
if (output.getReturnCode() != 0) {
309303
throw new RemoteException("Adding SPN to keytab failed with return code " + output.getReturnCode());
310304
}
@@ -444,19 +438,15 @@ private ProgramOutput executeRemoteCommand(String scriptFile, String command, bo
444438

445439
Log.info(thisClass, methodName, "Call chmod 777 on script using command: " + chmodCMD);
446440
output = executeSshCommand(sshSession, chmodCMD, 30);
447-
Log.info(thisClass, methodName, "chmod command output: " + output.getStdout());
448-
Log.info(thisClass, methodName, "chmod command error:" + output.getStderr());
449441
} else {
450442
Log.info(thisClass, methodName, "The following command will not be run for: " + chmodCMD + " for the script file: " + scriptFile);
451443
}
452444

453445
Log.info(thisClass, methodName, "Executing command --> " + command);
454-
output = executeSshCommand(sshSession, command, 300);
446+
output = executeSshCommand(sshSession, command, 60);
455447

456448
if (retryUponFailure && output.getReturnCode() != 0) {
457449
Log.info(thisClass, methodName, "Remote command failed with return code " + output.getReturnCode());
458-
Log.info(thisClass, methodName, "command output: " + output.getStdout());
459-
Log.info(thisClass, methodName, "command error:" + output.getStderr());
460450
Log.info(thisClass, methodName, "Sleeping for a few seconds to see if that helps resolve any problems encountered");
461451
Thread.sleep(15 * 1000);
462452
Log.info(thisClass, methodName, "Attempting to retry the command");

dev/com.ibm.ws.security.spnego.fat.common/fat/src/com/ibm/ws/security/spnego/fat/config/SPNEGOConstants.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2020 IBM Corporation and others.
2+
* Copyright (c) 2020, 2021 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -52,7 +52,7 @@ public class SPNEGOConstants {
5252
public final static String CREATE_WIN_USER_LOCAL_FILE = SLASH_KERBEROS_SLASH + CREATE_WIN_USER_REMOTE_FILE;
5353
public final static String REMOVE_WIN_USER_REMOTE_FILE = "removeWinUsers.vbs";
5454
public final static String REMOTE_WIN_USER_LOCAL_FILE = SLASH_KERBEROS_SLASH + REMOVE_WIN_USER_REMOTE_FILE;
55-
public final static String CREATE_WIN_KEYTAB_REMOTE_FILE = "createWinKeytabFile.bat";
55+
public final static String CREATE_WIN_KEYTAB_REMOTE_FILE = "createWinKeytabFileOL.bat"; // "createWinKeytabFile.bat";
5656
public final static String CREATE_WIN_KEYTAB_LOCAL_FILE = SLASH_KERBEROS_SLASH + CREATE_WIN_KEYTAB_REMOTE_FILE;
5757
public final static String CREATE_WIN_USER_SET_SPN_REMOTE_FILE = "createUserAndSetSpn.bat";
5858
public final static String CREATE_WIN_USER_SET_SPN_LOCAL_FILE = SLASH_KERBEROS_SLASH + CREATE_WIN_USER_SET_SPN_REMOTE_FILE;

dev/com.ibm.ws.security.spnego_fat.1/bnd.bnd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ tested.features: pages-3.0
3030
com.ibm.ws.security.authentication.filter;version=latest,\
3131
com.ibm.ws.security.jaas.common;version=latest,\
3232
com.ibm.ws.security.kerberos.java8;version=latest,\
33+
com.ibm.ws.security.spnego_fat;version=latest,\
3334
com.ibm.ws.security.spnego.fat.common;version=latest,\
3435
com.ibm.ws.security.token;version=latest,\
3536
com.ibm.ws.security.token.s4u2;version=latest,\

dev/com.ibm.ws.security.spnego_fat.1/build.gradle

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2020 IBM Corporation and others.
2+
* Copyright (c) 2020, 2021 IBM Corporation and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -35,7 +35,16 @@ def appBuildDir = "${buildDir}/test-application"
3535
autoFVT.dependsOn ':com.ibm.ws.security.spnego.fat.common:SPNEGOTokenHelperFVT_EAR'
3636
autoFVT.dependsOn ':com.ibm.ws.webcontainer.security_test.servlets:war'
3737
autoFVT.doLast {
38-
38+
39+
/******************************************************************
40+
* Copy spnego_fat files.
41+
******************************************************************/
42+
copy {
43+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files')
44+
into new File(autoFvtDir, 'lib/LibertyFATTestFiles')
45+
include '**'
46+
}
47+
3948

4049
/******************************************************************
4150
* Setup server: BackendServer
@@ -46,8 +55,8 @@ autoFVT.doLast {
4655
into new File(autoFvtDir, 'publish/servers/' + server + '/apps')
4756
rename 'basicauth.zip', 'basicauth.war'
4857
}
49-
copy {
50-
from 'publish/files/resources/security'
58+
copy {
59+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/resources/security')
5160
into new File(autoFvtDir, 'publish/servers/' + server + '/resources/security')
5261
include '**'
5362
}
@@ -58,7 +67,7 @@ autoFVT.doLast {
5867
******************************************************************/
5968
server = 'com.ibm.ws.security.spnego.fat.setup'
6069
copy {
61-
from 'publish/files/resources/security'
70+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/resources/security')
6271
into new File(autoFvtDir, 'publish/servers/' + server + '/resources/security')
6372
include '**'
6473
}
@@ -74,7 +83,7 @@ autoFVT.doLast {
7483
rename 'basicauth.zip', 'basicauth.war'
7584
}
7685
copy {
77-
from 'publish/files/server_modules/'
86+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/server_modules')
7887
into new File(autoFvtDir, 'publish/servers/' + server + '/imports')
7988
include 'application_definition/**.xml'
8089
include 'configs/**.xml'
@@ -84,7 +93,7 @@ autoFVT.doLast {
8493
include 'spnego/serversettings/**.xml'
8594
}
8695
copy {
87-
from 'publish/files/resources/security'
96+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/resources/security')
8897
into new File(autoFvtDir, 'publish/servers/' + server + '/resources/security')
8998
include '**'
9099
}
@@ -109,7 +118,7 @@ autoFVT.doLast {
109118
rename 'com.ibm.ws.security.spnego_fat.jar', 'CustomLoginModule.jar'
110119
}
111120
copy {
112-
from 'publish/files/server_modules/'
121+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/server_modules')
113122
into new File(autoFvtDir, 'publish/servers/' + server + '/imports')
114123
include 'application_definition/spnegoTokenHelperFvt_location.xml'
115124
include 'configs/**.xml'
@@ -121,7 +130,7 @@ autoFVT.doLast {
121130
include 'spnego/serversettings/**.xml'
122131
}
123132
copy {
124-
from 'publish/files/resources/security'
133+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/resources/security')
125134
into new File(autoFvtDir, 'publish/servers/' + server + '/resources/security')
126135
include '**'
127136
}
@@ -139,8 +148,8 @@ autoFVT.doLast {
139148
into new File(autoFvtDir, 'publish/servers/' + server + '/apps')
140149
rename 'basicauth.zip', 'basicauth.war'
141150
}
142-
copy {
143-
from 'publish/files/server_modules/'
151+
copy {
152+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/server_modules')
144153
into new File(autoFvtDir, 'publish/servers/' + server + '/imports')
145154
include 'application_definition/**.xml'
146155
include 'configs/**.xml'
@@ -151,13 +160,13 @@ autoFVT.doLast {
151160
include 'spnego/authfilters/**.xml'
152161
include 'spnego/serversettings/**.xml'
153162
}
154-
copy {
155-
from 'publish/files/server_modules/constrained_delegation/s4u2self_servers/config/'
163+
copy {
164+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/server_modules/constrained_delegation/s4u2self_servers/config')
156165
into new File(autoFvtDir, 'publish/servers/' + server + '/imports/constrained_delegation/config')
157166
include '**.xml'
158167
}
159168
copy {
160-
from 'publish/files/resources/security'
169+
from new File(project(':com.ibm.ws.security.spnego_fat').projectDir, 'publish/files/resources/security')
161170
into new File(autoFvtDir, 'publish/servers/' + server + '/resources/security')
162171
include '**'
163172
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)