Skip to content

Commit

Permalink
Add support for ext-info-in-auth@openssh.com extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
norrisjeremy committed Dec 19, 2023
1 parent d7622c2 commit bbcf9c9
Show file tree
Hide file tree
Showing 5 changed files with 368 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/jcraft/jsch/JSch.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class JSch {
config.put("require_strict_kex", Util.getSystemProperty("jsch.require_strict_kex", "no"));
config.put("enable_server_sig_algs",
Util.getSystemProperty("jsch.enable_server_sig_algs", "yes"));
config.put("enable_ext_info_in_auth",
Util.getSystemProperty("jsch.enable_ext_info_in_auth", "yes"));
config.put("cipher.s2c", Util.getSystemProperty("jsch.cipher",
"aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com"));
config.put("cipher.c2s", Util.getSystemProperty("jsch.cipher",
Expand Down
91 changes: 71 additions & 20 deletions src/main/java/com/jcraft/jsch/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public class Session {

private volatile boolean isConnected = false;

private volatile boolean doExtInfo = false;
private boolean enable_server_sig_algs = true;
private boolean enable_ext_info_in_auth = true;

private volatile boolean initialKex = true;
private volatile boolean doStrictKex = false;
private boolean enable_strict_kex = true;
Expand Down Expand Up @@ -314,6 +318,8 @@ public void connect(int connectTimeout) throws JSchException {
getLogger().log(Logger.INFO, "Local version string: " + Util.byte2str(V_C));
}

enable_server_sig_algs = getConfig("enable_server_sig_algs").equals("yes");
enable_ext_info_in_auth = getConfig("enable_ext_info_in_auth").equals("yes");
enable_strict_kex = getConfig("enable_strict_kex").equals("yes");
require_strict_kex = getConfig("require_strict_kex").equals("yes");
send_kexinit();
Expand Down Expand Up @@ -376,7 +382,11 @@ public void connect(int connectTimeout) throws JSchException {
initialKex = false;
} else {
in_kex = false;
throw new JSchException("invalid protocol(newkyes): " + buf.getCommand());
throw new JSchException("invalid protocol(newkeys): " + buf.getCommand());
}

if (enable_server_sig_algs && enable_ext_info_in_auth && doExtInfo) {
send_extinfo();
}

try {
Expand Down Expand Up @@ -574,18 +584,27 @@ private KeyExchange receive_kexinit(Buffer buf) throws Exception {
}
System.arraycopy(buf.buffer, buf.s, I_S, 0, I_S.length);

if ((enable_strict_kex || require_strict_kex) && initialKex) {
doStrictKex = checkServerStrictKex();
if (doStrictKex) {
if (getLogger().isEnabled(Logger.INFO)) {
getLogger().log(Logger.INFO, "Doing strict KEX");
if (initialKex) {
if (enable_strict_kex || require_strict_kex) {
doStrictKex = checkServerStrictKex();
if (doStrictKex) {
if (getLogger().isEnabled(Logger.INFO)) {
getLogger().log(Logger.INFO, "Doing strict KEX");
}

if (seqi != 1) {
throw new JSchStrictKexException("KEXINIT not first packet from server");
}
} else if (require_strict_kex) {
throw new JSchStrictKexException("Strict KEX not supported by server");
}
}

if (seqi != 1) {
throw new JSchStrictKexException("KEXINIT not first packet from server");
if (enable_server_sig_algs) {
doExtInfo = checkServerExtInfo();
if (getLogger().isEnabled(Logger.INFO)) {
getLogger().log(Logger.INFO, "ext-info messaging supported by server");
}
} else if (require_strict_kex) {
throw new JSchStrictKexException("Strict KEX not supported by server");
}
}

Expand Down Expand Up @@ -643,6 +662,28 @@ private boolean checkServerStrictKex() {
return false;
}

private boolean checkServerExtInfo() {
Buffer sb = new Buffer(I_S);
sb.setOffSet(17);
byte[] sp = sb.getString(); // server proposal

int l = 0;
int m = 0;
while (l < sp.length) {
while (l < sp.length && sp[l] != ',')
l++;
if (m == l)
continue;
if ("ext-info-s".equals(Util.byte2str(sp, m, l - m))) {
return true;
}
l++;
m = l;
}

return false;
}

private volatile boolean in_kex = false;
private volatile boolean in_prompt = false;
private volatile String[] not_available_shks = null;
Expand Down Expand Up @@ -726,8 +767,7 @@ private void send_kexinit() throws Exception {
}
}

String enable_server_sig_algs = getConfig("enable_server_sig_algs");
if (enable_server_sig_algs.equals("yes") && !isAuthed) {
if (enable_server_sig_algs && !isAuthed) {
kex += ",ext-info-c";
}

Expand Down Expand Up @@ -862,6 +902,20 @@ private void send_newkeys() throws Exception {
}
}

private void send_extinfo() throws Exception {
// send SSH_MSG_EXT_INFO(7)
packet.reset();
buf.putByte((byte) SSH_MSG_EXT_INFO);
buf.putInt(1);
buf.putString(Util.str2byte("ext-info-in-auth@openssh.com"));
buf.putString(Util.str2byte("0"));
write(packet);

if (getLogger().isEnabled(Logger.INFO)) {
getLogger().log(Logger.INFO, "SSH_MSG_EXT_INFO sent");
}
}

private void checkHost(String chost, int port, KeyExchange kex) throws JSchException {
String shkc = getConfig("StrictHostKeyChecking");

Expand Down Expand Up @@ -1298,8 +1352,7 @@ Buffer read(Buffer buf) throws Exception {
buf.getInt();
buf.getShort();
boolean ignore = false;
String enable_server_sig_algs = getConfig("enable_server_sig_algs");
if (!enable_server_sig_algs.equals("yes")) {
if (!enable_server_sig_algs) {
ignore = true;
if (getLogger().isEnabled(Logger.INFO)) {
getLogger().log(Logger.INFO,
Expand Down Expand Up @@ -2091,6 +2144,8 @@ public void disconnect() {
seqo = 0;
initialKex = true;
doStrictKex = false;
doExtInfo = false;
serverSigAlgs = null;

// synchronized(jsch.pool){
// jsch.pool.removeElement(this);
Expand Down Expand Up @@ -2713,9 +2768,6 @@ public void setConfig(Hashtable<String, String> newconf) {
String key =
(newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey);
String value = newconf.get(newkey);
if (key.equals("enable_server_sig_algs") && !value.equals("yes")) {
serverSigAlgs = null;
}
config.put(key, value);
}
}
Expand All @@ -2729,9 +2781,6 @@ public void setConfig(String key, String value) {
if (key.equals("PubkeyAcceptedKeyTypes")) {
config.put("PubkeyAcceptedAlgorithms", value);
} else {
if (key.equals("enable_server_sig_algs") && !value.equals("yes")) {
serverSigAlgs = null;
}
config.put(key, value);
}
}
Expand Down Expand Up @@ -3148,6 +3197,8 @@ private void applyConfig() throws JSchException {
checkConfig(config, "kex");
checkConfig(config, "server_host_key");
checkConfig(config, "prefer_known_host_key_types");
checkConfig(config, "enable_server_sig_algs");
checkConfig(config, "enable_ext_info_in_auth");
checkConfig(config, "enable_strict_kex");
checkConfig(config, "require_strict_kex");
checkConfig(config, "enable_pubkey_auth_query");
Expand Down
Loading

0 comments on commit bbcf9c9

Please sign in to comment.