So I have a working ftp connection and I can upload files and whatnot. However currently I'm storing the pw/user as hardcoded values (which I know isn't good) and want to see if I can hide/encrypt them somehow. I would also like to encrypt the actual ftp connection if possible as well. Any information/pointers would be great!
private int ftpProcess(String serverName, String userName, String password) {
FTPClient ftp = new FTPClient();
int statusCode = 0;
try {
ftp.connect(serverName);
// was required to add this passive mode in TC8 to connect to the mainframe
ftp.enterLocalPassiveMode();
ftp.login(userName, password);
ftp.site("filetype=jes");
submitJcl(ftp, "submitTest.txt", serverName);
ftp.quit();
} catch (Exception e) {
logger.error(e);
statusCode = 3;
}
return statusCode;
}
You can encrypt values in your application.properties with Jasypt.
See the following link for a details description:
https://stackoverflow.com/a/37424296/13454816
If you are already using Spring, you could can add org.springframework.boot:spring-boot-starter-security dependency and use BCryptPasswordEncoder to encode the values:
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String enc = encoder.encode(value);
Documentation is here:
https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html
And this is a very helpful tutorial:
https://www.baeldung.com/spring-security-registration-password-encoding-bcrypt
Related
I have code where i'm connecting to TFS using java tfs sdk like below,
*
*Credentials credentials = new UsernamePasswordCredentials( "xxxxxx", "XXXXX"); getConnection(serverURI, credentials, maxDate, buildNo);
}
private static void getConnection(URI serverURI, final Credentials credentials, String maxDate, String buildNo)
{
TFSTeamProjectCollection tpc = null;
try{
tpc = new TFSTeamProjectCollection(serverURI, credentials);
tpc.authenticate();
}catch(Exception e){
System.out.println(e.getMessage());
}*
But its stop authenticating using username and password, what the alternative authentication type like PAT - i need code to authenticate it, please help on this.
I tested with username and password as credentials, and I can connect to TFS normally on my side.
Here is a ticket you can refer to .
sorry for my broken english, not a native speaker :)
Here is my problem:
I try to connect via JDBC to a DB hosted on a MySQL server (Version: 5.6.37). I don't host the server and can't change any server configs.
When I try to connect using SQuirreL everything works as expected. I get access to the DB.
When I try to connect via self-written app via my IDE (eclipse) I get an Caused by: java.sql.SQLException: Access denied for user ... (using password: YES)
I'm using HikariCP to manage the connections. Tried also non connection pool aproach via DriverManager.getConnection. Both times the same.
The driver I'm using is mysql-connector-java-5.1.44-bin.jar
// DriverManager approach
private static final Properties dbProps = new Properties();
static {
dbProps.put("password", dbPass);
dbProps.put("user", dbUser);
dbProps.put("autoReconnect", "true");
dbProps.put("failOverReadOnly", "false");
dbProps.put("maxReconnects", "1");
}
...
public static Connection getConnection() {
Connection con = null;
try {
con = DriverManager.getConnection(connectionString, dbProps);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
...
// HakiriCP approach
private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;
private static final Properties dbProps = new Properties();
static {
PropertyLoader.loadPropertiesFromFile(dbProps); // read properties from external source
config.setJdbcUrl(String.format("jdbc:mysql://%s:%s/%s", dbProps.getProperty("db.server"),
dbProps.getProperty("db.port"), dbProps.getProperty("db.database")));
config.setUsername(dbProps.getProperty("db.user"));
config.setPassword(dbProps.getProperty("db.pass"));
config.addDataSourceProperty("cachePrepStmts", dbProps.getProperty("db.cachePrepStmts", "true"));
config.addDataSourceProperty("prepStmtCacheSize", dbProps.getProperty("db.prepStmtCacheSize", "250"));
config.addDataSourceProperty("prepStmtCacheSqlLimit", dbProps.getProperty("db.prepStmtCacheSqlLimit", "2048"));
ds = new HikariDataSource(config);
}
...
public static Connection getConnection() {
Connection con = null;
try {
con = ds.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
...
EDIT - when I wireshark the connection tries, I see different encoded passwords (SQuirreL vs App). But when I print the password to the console it is exactly the one that work with SQuirreL.
EDIT - The connecttion handling is done in one single class. When I test it all alone without any of the other logic (it is a old swing app) everything works fine. But when I make the exact same call from the swing application it fails '(sends different password string).
What am I doing wrong?
I'm thankful for every help.
Cheers!
I found the solution. For all the project I have UTF-8 encoding. But eclipse decided to use UTF-16 when running or debugging code.
Option can be found here: Run Configurations -> Common -> Encoding
Ok, eclipse made some joke with me.
Thanks to wireshark givin me the hint that something is wrong with the encoding.
Thanks to you guys to trying to help (inluding the ones giving me -1, they don't know it better ;))
Cheers!
i have an issue transferring files to Windows FTP server from Unix/Mac/Linux env.
while the exact same java code works from windows pc.
from *Nix/Mac the transfer only worked with this commands on the ftp session
set ftps:initial-prot
set ftp:ssl-force true
set ftp:ssl-protect-data true
set ssl:verify-certificate no
while on my windows machine i didnt need them - i assume it relates to system variable.
This is my java code
protected FTPClient getClient(DeliveryDetails details) {
return new FTPSClient(false); // the connection is Explicit
}
public void setClient(FTPClient client, DeliveryDetails details) throws Exception {
client.setConnectTimeout(10000);
client.setDefaultTimeout(1000 * 60 * 2);
client.setControlKeepAliveTimeout(300);
client.setDataTimeout(15000);
client.connect(ftpDetails.host, ftpDetails.port);
client.setBufferSize(1024 * 1024);
client.login(ftpDetails.username, ftpDetails.getSensitiveData());
client.setControlEncoding("UTF-8");
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
FTPSClient ftpsClient = (FTPSClient) client;
ftpsClient.execPBSZ(0);
ftpsClient.execPROT("P");
// both with it and without it didnt work ftpsClient.setWantClientAuth(false);
}
public void saveToServer(FTPClient client, File fileName, InputStream stream){
BufferedInputStream bis = new BufferedInputStream(stream);
boolean isSaved = client.storeFile(filename, bis);
client.logout();
}
What is equivalent of this parameters in the FTPS Apache class ?
set ftps:initial-prot
set ftp:ssl-force true
set ftp:ssl-protect-data true
set ssl:verify-certificate no
It appears that Windows NT does not support writing data in FTP.BLOCK_TRANSFER_MODE
Easy fix is
private static final String WINDOWS_NT_SYTEM_TYPE = "Windows_NT";
....
....
try {
String res = client.getSystemType();
if (res.equals(WINDOWS_NT_SYTEM_TYPE)) {
client.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
} else {
client.setFileTransferMode(FTP.BLOCK_TRANSFER_MODE);
}
}
I am trying to establish an SSH connection through my Java code, but getting below exception .. I tested my connection through Putty/Winscp tools and it works fine. The problem is with my Java code...
SEVERE: The Transport Protocol thread failed
java.io.IOException: The socket is EOF
at com.sshtools.j2ssh.transport.TransportProtocolInputStream.readBufferedData(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolInputStream.readMessage(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolCommon.readMessage(Unknown Source)
at com.sshtools.j2ssh.transport.kex.DhGroup1Sha1.performClientExchange(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolClient.performKeyExchange(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolCommon.beginKeyExchange(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolCommon.onMsgKexInit(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolCommon.startBinaryPacketProtocol(Unknown Source)
at com.sshtools.j2ssh.transport.TransportProtocolCommon.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Below is my piece of Java code to establish the connection
public class MySSHClient {
static SshClient ssh = null;
static SshConnectionProperties properties = null;
SessionChannelClient session = null;
private static void MySSHClient(String hostName, String userName, String passwd )
{
try
{
// Make a client connection
ssh = new SshClient();
properties = new SshConnectionProperties();
properties.setHost("192.168.1.175");
// Connect to the host
ssh.connect(properties, new IgnoreHostKeyVerification());
// Create a password authentication instance
PasswordAuthenticationClient pwd = new PasswordAuthenticationClient();
pwd.setUsername("root");
pwd.setPassword("123456");
// Try the authentication
int result = ssh.authenticate(pwd);
// Evaluate the result
if (result==AuthenticationProtocolState.COMPLETE) {
System.out.println("Connection Authenticated");
}
}
catch(Exception e)
{
System.out.println("Exception : " + e.getMessage());
}
}//end of method.
public String execCmd(String cmd)
{
String theOutput = "";
try
{
// The connection is authenticated we can now do some real work!
session = ssh.openSessionChannel();
if ( session.executeCommand(cmd) )
{
IOStreamConnector output = new IOStreamConnector();
java.io.ByteArrayOutputStream bos = new
java.io.ByteArrayOutputStream();
output.connect(session.getInputStream(), bos );
session.getState().waitForState(ChannelState.CHANNEL_CLOSED);
theOutput = bos.toString();
}
//else
//throw Exception("Failed to execute command : " + cmd);
//System.out.println("Failed to execute command : " + cmd);
}
catch(Exception e)
{
System.out.println("Exception : " + e.getMessage());
}
return theOutput;
}
public static void main(String[] args){
MySSHClient(null, null, null);
}
Motivation
I stumbled across this question and answers while investigating the error in question java.io.IOException: The socket is EOF. Because changing the code to use some other SSH Java library is not immediately possible in my case and the stated explanation by #a3.14_Infinity was not detailed enough for me, I'd like to add my take on it.
java.io.IOException: The socket is EOF - Why?
Because this exception is not very helpful, I first tried Wireshark to see what's going on over the wire, but to no avail. So I configured the sshd_config (OpenSSH 6.9) to log on DEBUG3 level and got the answer in the /var/log/auth.log file of my test machine. It stated a fatal error while trying to negotiate the key exchange algorithm with the SSH client (the Java SSH library).
Because the SSH server and client could not agree on a mutual key exchange algorithm the OpenSSH server terminates the connection to the client. In consequence, the Java SSH library code throws the exception.
But why does it happen?
The sshtools.j2ssh (sshtools : j2ssh-core : 0.2.9) library code is pretty old and discontinued. Starting with OpenSSH 6.7 (released October, 2014) default ciphers and MAC have been altered to remove unsafe algorithms which includes the blowfish-cbc cipher. And with OpenSSH 6.9 (released June, 2015) the support for the 1024-bit diffie-hellman-group1-sha1 key exchange is disabled by default.
When you still use the prehistoric SSH Tools j2ssh library (God forbid) connecting to a newer OpenSSH server you will get the described error. The library code only offers the diffie-hellman-group1-sha1 key exchange algorithm to the OpenSSH server which it does not support by default. Thus, a secure connection cannot be established.
Cannot change the code?
If moving to another Java SSH library is not immediately possible (my case) then you can re-enable the disabled diffie-hellman-group1-sha1 key exchange algorithm in the OpenSSH's server config file sshd_config. For example like this.
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm#openssh.com,aes256-gcm#openssh.com,chacha20-poly1305#openssh.com,blowfish-cbc
KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,curve25519-sha256#libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1
But let me be clear on this. The diffie-hellman-group1-sha1 key exchange algorithm as well as the blowfish-cbc cipher are turned off by default because they are insecure. Reenabling them should only be a temporary measure until you can replace this obsolete Java SSH library.
Finally, I like to point out that the suggested Java Secure Channel (JSch) library in other answers is discontinued. So, you might want to consider sshj or even ssh2j-maverick instead.
Edit: I was wrong, the Java Secure Channel JSch library is alive (JSCH 0.1.54 was released on 2016-09-03 on MavenCentral) and certainly worth your consideration. Alternatively, you may want to consider also sshj or ssh2j-maverick.
Addendum: Migration
To keep the migration effort for the sshtools.j2ssh (sshtools : j2ssh-core : 0.2.9) library minimal I looked at the commercial legacy SSH client library from SSHTOOLS (version 1.7.1). This allowed to keep the existing library integration code with few minor changes regarding library API and exception handling. Thus, if you do not want to restart from scratch then biting the bullet and sticking with SSHTOOLS is probably your best option. Finally, to gauge the migration effort I first replaced the library with SSHTOOLS' open source library ssh2j-maverick which almost has the same API as its latest commercial version (version 1.7.1).
This error ("The Transport Protocol thread failed. java.io.IOException: The socket is EOF”) occurs when j2ssh.jar file is not compatible with current SSH version of SFTP server.
You can try using Java Secure Channel (JSch) from here.
Courtesy: http://techydiary.com/the-transport-protocol-thread-failed-java-io-ioexception-the-socket-is-eof/
The following sample Code may help you,
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class SSHClient {
/**
* Constant EXCUTE_CHANNEL
*/
public static final String EXCUTE_CHANNEL = "exec";
/**
* Constant STRICT_KEY_CHECKING
*/
public static final String STRICT_KEY_CHECKING = "StrictHostKeyChecking";
/** Name/ip of the remote machine/device **/
private String host;
private String userName;
private String password;
/**
* This method used to initilze user and host
*
* #param userName
* #param password
* #param host
*/
public SSHClient(String userName,String password, String host) {
super();
this.userName = userName;
this.password = password;
this.host = host;
}
/**
* This method used to execute commands remotly by using SSHV2
*
* #param host
* #param username
* #param password
* #param command
* #return
*/
public String executeCommand(String command) {
StringBuilder log = new StringBuilder();
String response = null;
Channel channel = null;
Session session = null;
try {
JSch jsch = new JSch();
JSch.setConfig(STRICT_KEY_CHECKING, Constants.NO);
session = jsch.getSession(userName, host, 22);
// If two machines have SSH passwordless logins setup, the following
// line is not needed:
session.setPassword(password);
session.connect();
channel = session.openChannel(EXCUTE_CHANNEL);
((ChannelExec) channel).setCommand(command);
// channel.setInputStream(System.in);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
response = IOUtils.toString(in);
} catch (Exception ex) {
//handle exception
} finally {
try {
if (session != null) {
session.disconnect();
}
} catch (Exception ex) {
//handle exception
}
try {
if (channel != null) {
channel.disconnect();
}
} catch (Exception ex) {
//handle exception
}
}
System.ou.println( "Response received :"+ response));
return response;
}
}
Here is the working code reused from some google source -
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.StreamGobbler;
Connection conn = new Connection(server);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(user_id, password);
System.out.println("Is server - " + server + " Authenticated? " + isAuthenticated);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
ch.ethz.ssh2.Session sess = conn.openSession();
String new_commands = "";
for (int i = 0; i < commands.size(); i++) {
new_commands = new_commands + commands.get(i) + "\n";
}
System.out.println("The command executed is: " + new_commands);
sess.requestDumbPTY();
sess.execCommand(new_commands);
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
InputStream errStrm = new StreamGobbler(sess.getStderr());
BufferedReader stderrRdr = new BufferedReader(new InputStreamReader(errStrm));
sess.getStdin().write("EXIT\n".getBytes());
System.out.println("the output of the command is");
while (true) {
String line_out = br.readLine();
if (line_out == null) {
break;
} else {
System.out.println(line_out);
output_logs.add(line_out);
}
}
while (true) {
String line_error = stderrRdr.readLine();
if (line_error == null) {
break;
} else {
System.out.println(line_error);
output_logs.add(line_error);
}
}
output_logs.add("Exit Code:" + sess.getExitStatus());
System.out.println("ExitCode: " + sess.getExitSignal());
sess.close();
conn.close();
found a simple solution on the OS:
comment out the Cipher line in /etc/ssh/sshd_config
and run service sshd restart
We are calling URL using proxy settings via java standalone sample code on our weblogic servers (node1/node2).
This code works fine on node 1 but same code doesn't work on node2 server.
We already checked proxy settings and credentials all are fine but still we get following error :
java.net.ProtocolException: Server redirected too many times (20)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1323)
at ProxyCode.start2(ProxyCode.java:54)
at ProxyCode.main(ProxyCode.java:23)
Exception in thread "Main Thread" java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:61)
at java.io.InputStreamReader.<init>(InputStreamReader.java:55)
at ProxyCode.readFromInputStream(ProxyCode.java:65)
at ProxyCode.start2(ProxyCode.java:59)
at ProxyCode.main(ProxyCode.java:22)
Also , Please find my code snippet below :
SimpleAuthenticator.java
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class SimpleAuthenticator extends Authenticator
{
private String username;
private String password;
public SimpleAuthenticator(String username,String password)
{
this.username = username;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(
username,password.toCharArray());
}
}
Main class :
String url = "http://www.oracle.com/technetwork/java/readme-2-149793.txt";
String proxy = "proxyserver";
String port = "8080";
String username = "username";
String password = "password";
Authenticator.setDefault(new SimpleAuthenticator(username,password));
URL server = null;
try {
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
server = new URL(url);
}
catch (MalformedURLException e) {
e.printStackTrace();
}
Properties systemProperties = System.getProperties();
systemProperties.setProperty("http.proxyHost", proxy);
systemProperties.setProperty("http.proxyPort", port);
InputStream in = null;
URLConnection connection = null;
try {
connection = (URLConnection) server.openConnection();
connection.connect();
in = connection.getInputStream();
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println(readFromInputStream(in));
}
public static String readFromInputStream(InputStream in) {
StringBuffer strBuf = new StringBuffer();
char ac[];
BufferedReader buf = new BufferedReader(new InputStreamReader(in));
try
{
while (buf.ready()) {
ac = new char[10000];
buf.read(ac);
strBuf.append(ac);
}
buf.close();
}
catch (IOException e) {
e.printStackTrace();
}
We are stuck in this since months now and not able to get any useful information anywhere.
kindly help.thanks
You will get this error if you provide wrong credentials (username or password).
This happened to me with a Glassfish based web app. I was expecting a 401 response however.
I think, the Authenticator tries the same credentials many times.
Found this open issue, still unfixed it would seem. Your user doesn't have access rights, but instead of prompting again it retries with the same user over and over
Update: The issue had another ticket open - this is apparently expected behaviour and
"To overcome this, your implementation of
Authenticator::getPasswordAuthentication needs to provide a means to
collect the correct password if the initial authentication attempt was
not successful."
See the ticket or the java.net.Authenticator documentation for more info.