Filter Ip remote SFTP - java

Currently, I'm implementing SFTP server which using ssh-core and apache mina-core.
I want to filter ip remote address. I implemented class CustomFilterAdapter extends IoFilterAdapter and I check if Ip remote is not in range of whitelist, i will not create session
public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception
{
log.debug(String.format("Start check access for ip %s.", ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress()));
try
{
isAllowAccess(session);
}
catch (Exception ex)
{
log.error("Access dinied. " + ex.getMessage());
return;
}
super.sessionCreated(nextFilter, session);
}
However, It's not work. It's not run my code.
What steps i was missed or I implemented wrong filter.

Related

Java Server Socket connection over different routers

I am currently developing a client and a server for a small game.
The client which connects to the server establishes the connection with this method:
// This method is called, passing on an ipv6 address and port number 6666
public void startConnection(String ip, int port) throws IOException {
try {
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//some other code handling responses
} catch (IOException e) {
LOG.debug("Error when initializing connection", e);
throw new IOException();
}
}
The Server I built accepts connections using this method:
public void start(int port) {
try {
serverSocket = new ServerSocket(port); //port = 6666
//This part is used to handle multiple connections at once
while (b){
try {
map.add(new EchoClientHandler(serverSocket.accept())); //EchoClientHandler is a class used to send and receive data instructions
x = map.size() - 1;
System.out.println("Establishing connection from port " + port);
map.get(x).start();
System.out.println("Connection established");
} catch (SocketTimeoutException e) {
}
}
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Both methods work fine and establish a stable connection between the client and the server, but when i try and establish a connection from different routers or general internet connections (like via cellular data) it doesn't work.
Is there a way to establish connections without both the client and the server having to connect from the same router?
Edit:
Here is the error i get from the client, the server doesn't show anything:
18:03:24.288 [AWT-EventQueue-0] DEBUG dorusblanken.werwolfclient.Client - Error when initializing connection
java.net.SocketException: Network is unreachable: connect
"Network is unreachable" means there is no way to get to the destination network from the current network.
You mentioned that you are trying to establish a connection via the Internet. For that to work, the destination host (your server) must be connected to the Internet, it must have a public IP address, and the clients need to use the public IP address when connecting.
That is the simplest configuration. Most companies don't actually put their servers directly on the Internet. Instead, the public IP frequently belongs to a CDN or DDoS mitigation layer, which forwards connections to a load balancer, and the load balancer forwards connections to servers.

Send files to server via FTPS protocol

I'm creating an app which generates a CSV file and some PDFs. I want my app to send those files to a server via FTPS protocol.
I'm using Apache Commons Net FTP library and it was perfectly working when I had "Require TLS session resumption on data connection when using PORT P" unchecked, but since I enabled it I can't send my files.
An error appeared :
450 TLS session of data connection has not resumed or the session does not match the control connection.
After some researches on this site I have overriden _prepareDataSocket_ in order to overcome this problem but now it just creates empty files on the server.
There is my overriden function :
#Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
// Control socket is SSL
final SSLSession session = ((SSLSocket) _socket_).getSession();
if (session.isValid()) {
final SSLSessionContext context = session.getSessionContext();
try {
final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method method = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
method.setAccessible(true);
method.invoke(cache, String
.format("%s:%s", socket.getInetAddress().getHostName(), String.valueOf(socket.getPort()))
.toLowerCase(Locale.ROOT), session);
method.invoke(cache, String
.format("%s:%s", socket.getInetAddress().getHostAddress(), String.valueOf(socket.getPort()))
.toLowerCase(Locale.ROOT), session);
} catch (NoSuchFieldException e) {
throw new IOException(e);
} catch (Exception e) {
throw new IOException(e);
}
} else {
throw new IOException("Invalid SSL Session");
}
}
}
and this is what FileZilla Server displays:
FileZilla Response
will this answer on another forum help?
http://forum.rebex.net/5673/450-error-connecting-to-ftp-requiring-explicit-ftp-over-tls

Using JDBC MySQL to connect database in Android?

I create an Android app to connect database using MySQL. When I test connection with localhost 10.0.2.2:3306, I can get database, but when I use the real host to get database from my server, I can not get anything. My host is: https://192.168.1.xxx:xxxxx and my database name is test. What is my problem? Please help me. Thank you.
This is my code:
private class MyTask extends AsyncTask<Void, Void, Void> {
private String idFromServer;
private String url="jdbc:mysql://192.168.1.xxx:xxxxx/test";
String name = "AAA";
#Override
protected Void doInBackground(Void... params) {
try {
ResultSet result = null;
String a = "SELECT * FROM testtable";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url,"aaa","abcdef");
Statement state = con.createStatement();
result = state.executeQuery(a);
while (result.next()) {
if (name.equals(result.getString("name"))) {
idFromServer = result.getString("id");
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void result) {
id.setText(idFromServer);
super.onPostExecute(result);
}
}
Generally MySql is installed with security restrictions so it is possible to access to it only from localhost.
You need to execute a command similar to the following to permit access from other ip
GRANT ALL PRIVILEGES
ON database.*
TO 'youruser'#'%'
IDENTIFIED BY 'yourpassword';
Note that it is a bad practice to offer access to MySql from any IP because it opens the possibility to be hacked. So generally it is a good idea to place a server that intercept requests from your android application and directly call the database.
Note: check also if it is open the route between your application and the mysql server.
If you use 3G you are not using a local network and the IP of the MySql server is different from 192.168.1.xxx (that is the ip of a local network). It is also possible that outside of the local network the MySql Server is not visible. It depends from the configuration of your network.
You need to "open" your network exposing the port to access mysql and checking which is the ip of your local network as seen from internet. Otherwise you can access to the local network using a phone with wireless connection to your local network.

RMI connection failure detection on callback

I'm writing a distributed app by Java RMI. The RMI client registers event handler / callback to RMI server, and the server calls the client's callback function when required. Now the problem is, when network connection failure (for example, Ethernet cable plugged out...), the RMI server and client won't be notified, and the RMI server fails when attempts to call the client's registered callback function.The RMI server cannot notify the RMI client about this issue too. Even worse, when network connection recovers, the RMI client service will still lose contact with RMI server because nobody notify her to reconnect.
My current idea is to implement a ping() method in RMI client in separate thread.
This thread could wake up at regular intervals and check on the server.
if failed, then farce to reconnect.
Any other elegant solutions? Hope you guys can help !
the interface
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyInterface extends Remote {
public int RegisterEventHandler(RemoteMyEventHandler eventHandler) throws RemoteException;
public void unRegisterEventHandler(int eventHandlerId) throws RemoteException;
}
the RMI Server impelementation
import java.rmi.RemoteException;
import com.me.MyInterface;
public class MyInterfaceImpl implements MyInterface {
{
public void init() {
try {
//... initialize RMI server....
//....
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Override
public int RegisterEventHandler(RemoteMyEventHandler eventHandler)
throws RemoteException {
return MyEventHandlerImp.getInstance().addHandler(eventHandler);
}
#Override
public void unRegisterEventHandler(int eventHandlerId)
throws RemoteException {
MyEventHandlerImp.getInstance().removeHandler(eventHandlerId);
}
}
//handler.notifyEventSnap(events);
the RMI Client implementation
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.me.MyInterface;
public class MyService implements NotifyHandler{
{
private MyInterface client;
private MyEventHandler myEventHandler;
private void connectToServer() {
try {
//...
Registry registry = LocateRegistry.getRegistry(rmiHost, rmiPort);
client = (MyInterface) registry.lookup(MyCInterface.class.getName());
} catch (RemoteException er) {
} catch (NotBoundException en) {
} catch (Exception en) {
}
}
private void startService(){
//Attach my event handler
if(client != null)
{
myEventHandler = new MyEventHandler();
myEventHandlerId = client.RegisterEventHandler(myEventHandler);
}
}
}
when network connection failure (for example, Ethernet cable plugged out...), the RMI server and client won't be notified, and the RMI server fails when attempts to call the client's registered callback function.
Err, that is the notification to the server. The server just has to note this and try again later.
The RMI server cannot notify the RMI client about this issue too.
The client doesn't need to know.
Even worse, when network connection recovers, the RMI client service will still lose contact with RMI server because nobody notify her to reconnect.
The client doesn't have to 'reconnect'. There is no connect or reconnect step in RMI. As long as the client's JVM and remote objects remain up and exported respectively, the stubs at the server remain valid and can continue to be used by the server.
You're solving a non-problem.
You seem to be partially implementing a client/server session. This is a token that the server can track to ensure a client is valid. If there is an error while the server is communicating with the client the session should be ended and all references to the client removed.
Your server is already implementing a session with the integer used to unRegisterEventHandler. You should keep track of those integers somewhere like a Map. If the server cannot connect to a client it should simply unregister that client and make the session invalid by removing it from the map. The server should remove all references to the client and not attempt to communicate with the client until a new session is created.
If a client tries to communicate with the server it should get an InvalidException exception from the server. This way the client can attempt to make a new session by calling RegisterEventHandler in the catch block.
I worked on a project that dealt with this problem using a ping like you suggested at https://code.google.com/p/umuc-team-factor/
All client communication with the server was in a looped try catch block like
private void getSession() {
while(isRun()) {
try {
if(server == null) {
Logger.getLogger(JobClient.class.getName()).info("Server is null.");
setupServer();
}
UUID sid = server.getSession(this);
synchronized (this) {
id = sid;
}
Logger.getLogger(JobClient.class.getName()).info("Session id is " + id);
return;
} catch (RemoteException ex) {
Logger.getLogger(JobClient.class.getName()).info("Could not get session from server: " + ex + ". setting up server.");
setupServer();
}
}
}
This try to setup a session with the server until the program is stopped.
All server communication with the client should end the session for the client if there is a RemoteException thrown. c.status() is similar to a ping.
List<UUID> endSessions = new ArrayList<UUID>();
for (UUID id : copy.keySet()) {
ClientCallback c = copy.get(id).client;
try {
ClientStatus status = c.status();
Logger.getLogger(ProcessManager.class.getName()).info("got client status for " + id + ": " + status.getSessionID() + " -" + status.getJobStatus());
if (status.getSessionID() == null || !status.getSessionID().equals(id)) {
endSessions.add(id);
}
} catch (Exception ex) {
endSessions.add(id);
Logger.getLogger(ProcessManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
for (UUID id : endSessions) {
try {
endSession(id);
} catch (SessionExpiredException ex) {
Logger.getLogger(ProcessManager.class.getName()).log(Level.SEVERE, null, ex);
}
}

RMI cannot connect to remote server

I've been plying with RMI recently and while I managed to make it work on locahost I've been having all sorts of problem when trying to use a remote server. Here's the basic code I'm trying to run:
Server:
public class RmiServer extends UnicastRemoteObject implements RmiServerIntf {
public static final String MESSAGE = "Hello world";
public RmiServer() throws RemoteException {
}
public String getMessage() {
return MESSAGE;
}
public static void main(String args[]) {
System.out.println("RMI server started");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
System.out.println("Security manager installed.");
} else {
System.out.println("Security manager already exists.");
}
try {
LocateRegistry.createRegistry(1099);
System.out.println("java RMI registry created.");
} catch (RemoteException e) {
e.printStackTrace();
}
try {
RmiServer obj = new RmiServer();
Naming.rebind("rmi://localhost/RmiServer", obj);
System.out.println("PeerServer bound in registry");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Remote class interface:
public interface RmiServerIntf extends Remote {
public String getMessage() throws RemoteException;
}
Client:
public class RmiClient {
RmiServerIntf obj = null;
public String getMessage() {
try {
obj = (RmiServerIntf)Naming.lookup("rmi://54.229.66.xxx/RmiServer");
return obj.getMessage();
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
public static void main(String args[]) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
RmiClient cli = new RmiClient();
System.out.println(cli.getMessage());
}
}
rmi.policy file:
grant {
permission java.security.AllPermission;
};
I compiled the classes and created a stub for the server. Then I placed client, stub, interface and policy on my machine and server, stub, interface and policy on the remote machine. The remote server being a Linux machine I made all the files executable. I also added a rule on the local firewall allowing port 1099, and opened all ports on the remote machine
After this I navigated to the server's directory on the remote machine and inserted the following command:
java -Djava.security.policy=rmi.policy RmiServer
This didn't give me problems so I went back to the local machine and entered
java -Djava.security.policy=rmi.policy RmiClient
I wait, and wait and I get the error message:
Connection refused to host: 172.31.xx.xx; nested exception is: java.net.ConnectException: Connection timed out: connect
I've been fighting with these connection errors all day yesterday and this is as far as I got. I'm sure there's only one very small thing I'm still doing wrong but I just can't find what it is.
This may not solve your problem, but I've had similar issues with JPPF (via Java RMI) on Linux. The solution was to ensure that the ephemeral port range on the Client-side machine covered only ports that were allowable by the Client-side's local firewall. E.g., if your firewall allows ports 48000 to 64000 to be connected to by an external machine, ensure that your ephemeral port range also falls within 48000 to 64000. Give that a try and let us know what happens.
System.setProperty("java.rmi.server.hostname","10.0.3.73");
Please use the above statements in your RMIServer side code, and try and connect from remote client again. It worked for me

Categories