FTP: Add SSl encryption preference

This commit is contained in:
Vishal
2017-03-26 18:57:20 +05:30
parent 4b13d23b82
commit 5a4074bbdf
11 changed files with 644 additions and 223 deletions
+1
View File
@@ -55,3 +55,4 @@ libs/libs.iml
.idea/
gradle.properties
projectFilesBackup
/src/main/res/raw/key.bks
@@ -192,7 +192,7 @@ public class AboutActivity extends BasicActivity implements View.OnClickListener
private void switchIcons() {
if (getAppTheme().equals(AppTheme.DARK)) {
// dark theme
mAuthorsDivider.setBackgroundColor(getResources().getColor(R.color.divider_dark));
mAuthorsDivider.setBackgroundColor(getResources().getColor(R.color.divider_dark_card));
}
}
@@ -11,8 +11,13 @@ import android.net.NetworkInfo;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.AppCompatEditText;
import android.text.Html;
import android.text.InputType;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -20,8 +25,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@@ -34,56 +39,23 @@ import com.amaze.filemanager.utils.color.ColorUsage;
import com.amaze.filemanager.utils.theme.AppTheme;
import java.io.File;
import java.io.InputStream;
/**
* Created by yashwanthreddyg on 10-06-2016.
*/
public class FTPServerFragment extends Fragment {
TextView statusText, warningText, ftpAddrText;
TextView statusText, username, password, port, sharedPath;
private AppCompatEditText usernameEditText, passwordEditText;
private TextInputLayout usernameTextInput, passwordTextInput;
private AppCompatCheckBox mAnonymousCheckBox, mSecureCheckBox;
Button ftpBtn;
private MainActivity mainActivity;
private View rootView;
private int skin_color, skinTwoColor;
private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMan.getActiveNetworkInfo();
if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) {
warningText.setText("");
} else {
stopServer();
statusText.setText(getResources().getString(R.string.ftp_status_not_running));
warningText.setText(getResources().getString(R.string.ftp_no_wifi));
ftpAddrText.setText("");
ftpBtn.setText(getResources().getString(R.string.start_ftp));
}
}
};
private BroadcastReceiver ftpReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == FTPService.ACTION_STARTED) {
statusText.setText(getResources().getString(R.string.ftp_status_running));
warningText.setText("");
ftpAddrText.setText(getFTPAddressString());
ftpBtn.setText(getResources().getString(R.string.stop_ftp));
} else if (action == FTPService.ACTION_FAILEDTOSTART) {
statusText.setText(getResources().getString(R.string.ftp_status_not_running));
warningText.setText("Oops! Something went wrong");
ftpAddrText.setText("");
ftpBtn.setText(getResources().getString(R.string.start_ftp));
} else if (action == FTPService.ACTION_STOPPED) {
statusText.setText(getResources().getString(R.string.ftp_status_not_running));
ftpAddrText.setText("");
ftpBtn.setText(getResources().getString(R.string.start_ftp));
}
}
};
private View rootView, startDividerView, statusDividerView;
private int skin_color, skinTwoColor, accentColor;
private Spanned spannedStatusNoConnection, spannedStatusConnected;
private Spanned spannedStatusSecure, spannedStatusNotRunning;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -92,13 +64,98 @@ public class FTPServerFragment extends Fragment {
mainActivity = (MainActivity) getActivity();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_ftp, container, false);
statusText =(TextView) rootView.findViewById(R.id.text_view_ftp_status);
username = (TextView) rootView.findViewById(R.id.text_view_ftp_username);
password = (TextView) rootView.findViewById(R.id.text_view_ftp_password);
port = (TextView) rootView.findViewById(R.id.text_view_ftp_port);
sharedPath = (TextView) rootView.findViewById(R.id.text_view_ftp_path);
ftpBtn = (Button) rootView.findViewById(R.id.startStopButton);
startDividerView = rootView.findViewById(R.id.divider_ftp_start);
statusDividerView = rootView.findViewById(R.id.divider_ftp_status);
String statusHead = getResources().getString(R.string.ftp_status_title) + ": ";
skin_color = mainActivity.getColorPreference().getColor(ColorUsage.PRIMARY);
skinTwoColor = mainActivity.getColorPreference().getColor(ColorUsage.PRIMARY_TWO);
accentColor = mainActivity.getColorPreference().getColor(ColorUsage.ACCENT);
spannedStatusConnected = Html.fromHtml(statusHead + "<b>&nbsp;&nbsp;&nbsp;&nbsp;" +
"<font color='" + accentColor + "'>"
+ getResources().getString(R.string.ftp_status_running) + "</font></b>");
spannedStatusNoConnection = Html.fromHtml(statusHead + "<b>&nbsp;&nbsp;&nbsp;&nbsp;" +
"<font color='" + getResources().getColor(android.R.color.holo_red_light) + "'>"
+ getResources().getString(R.string.ftp_status_no_connection) + "</font></b>");
spannedStatusNotRunning = Html.fromHtml(statusHead + "<b>&nbsp;&nbsp;&nbsp;&nbsp;" +
getResources().getString(R.string.ftp_status_not_running) + "</b>");
spannedStatusSecure = Html.fromHtml(statusHead + "<b>&nbsp;&nbsp;&nbsp;&nbsp;" +
"<font color='" + getResources().getColor(android.R.color.holo_green_light) + "'>"
+ getResources().getString(R.string.ftp_status_secure_connection) + "</font></b>");
updateStatus();
//light theme
if (mainActivity.getAppTheme().equals(AppTheme.LIGHT)) {
startDividerView.setBackgroundColor(getResources().getColor(R.color.divider));
statusDividerView.setBackgroundColor(getResources().getColor(R.color.divider));
} else {
//dark
startDividerView.setBackgroundColor(getResources().getColor(R.color.divider_dark_card));
statusDividerView.setBackgroundColor(getResources().getColor(R.color.divider_dark_card));
}
ftpBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!FTPService.isRunning()) {
if (FTPService.isConnectedToWifi(getContext()))
startServer();
else {
// no wifi, we shouldn't be here in the first place, because of broadcast
// receiver, but just to be sure
statusText.setText(spannedStatusNoConnection);
}
} else {
stopServer();
}
}
});
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
mainActivity.setActionBarTitle(getResources().getString(R.string.ftp));
mainActivity.floatingActionButton.hideMenuButton(true);
mainActivity.buttonBarFrame.setVisibility(View.GONE);
mainActivity.supportInvalidateOptionsMenu();
mainActivity.updateViews(new ColorDrawable(MainActivity.currentTab==1 ?
skinTwoColor : skin_color));
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
switch (item.getItemId()) {
case R.id.choose_ftp_port:
int currentFtpPort = FTPService.getDefaultPortFromPreferences(preferences);
int currentFtpPort = getDefaultPortFromPreferences();
new MaterialDialog.Builder(getActivity())
.input(getString(R.string.ftp_port_edit_menu_title), Integer.toString(currentFtpPort), true, new MaterialDialog.InputCallback() {
@@ -120,7 +177,7 @@ public class FTPServerFragment extends Fragment {
Toast.makeText(getActivity(), R.string.ftp_port_change_error_invalid, Toast.LENGTH_SHORT)
.show();
} else {
FTPService.changeFTPServerPort(preferences, portNumber);
changeFTPServerPort(portNumber);
Toast.makeText(getActivity(), R.string.ftp_port_change_success, Toast.LENGTH_SHORT)
.show();
}
@@ -136,7 +193,7 @@ public class FTPServerFragment extends Fragment {
MaterialDialog.Builder dialogBuilder = new MaterialDialog.Builder(getActivity());
dialogBuilder.title(getString(R.string.ftp_path));
dialogBuilder.input(getString(R.string.ftp_path_hint),
FTPService.getDefaultPathFromPreferences(preferences),
getDefaultPathFromPreferences(),
false, new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
@@ -154,7 +211,8 @@ public class FTPServerFragment extends Fragment {
File pathFile = new File(path);
if (pathFile.exists() && pathFile.isDirectory()) {
FTPService.changeFTPServerPath(preferences, pathFile.getPath());
changeFTPServerPath(pathFile.getPath());
Toast.makeText(getActivity(), R.string.ftp_path_change_success,
Toast.LENGTH_SHORT)
.show();
@@ -163,7 +221,7 @@ public class FTPServerFragment extends Fragment {
File pathParentFile = new File(pathFile.getParent());
if (pathParentFile.exists() && pathParentFile.isDirectory()) {
FTPService.changeFTPServerPath(preferences, pathParentFile.getPath());
changeFTPServerPath(pathParentFile.getPath());
Toast.makeText(getActivity(), R.string.ftp_path_change_success,
Toast.LENGTH_SHORT)
.show();
@@ -183,6 +241,84 @@ public class FTPServerFragment extends Fragment {
.negativeText(R.string.cancel)
.build()
.show();
return true;
case R.id.ftp_login:
MaterialDialog.Builder loginDialogBuilder = new MaterialDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View rootView = inflater.inflate(R.layout.dialog_ftp_login, null);
initLoginDialogViews(rootView);
loginDialogBuilder.customView(rootView, true);
loginDialogBuilder.title(getString(R.string.ftp_login));
loginDialogBuilder.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
if (mAnonymousCheckBox.isChecked()) {
// remove preferences
setFTPUsername("");
setFTPPassword("");
} else {
if (passwordEditText.getText().toString().equals("")) {
passwordTextInput.setError(getResources().getString(R.string.field_empty));
} else if (usernameEditText.getText().toString().equals("")) {
usernameTextInput.setError(getResources().getString(R.string.field_empty));
} else {
// password and username field not empty, let's set them to preferences
setFTPUsername(usernameEditText.getText().toString());
setFTPPassword(passwordEditText.getText().toString());
}
}
if (mSecureCheckBox.isChecked()) {
setSecurePreference(true);
} else setSecurePreference(false);
}
});
loginDialogBuilder.positiveText(getResources().getString(R.string.set).toUpperCase())
.negativeText(getResources().getString(R.string.cancel))
.build()
.show();
return true;
case R.id.ftp_timeout:
MaterialDialog.Builder timeoutBuilder = new MaterialDialog.Builder(getActivity());
timeoutBuilder.title(getResources().getString(R.string.ftp_timeout) + "(" +
getResources().getString(R.string.ftp_seconds) + ")");
timeoutBuilder.input(String.valueOf(FTPService.DEFAULT_TIMEOUT + " " +
getResources().getString(R.string.ftp_seconds)), String.valueOf(getFTPTimeout()),
true, new MaterialDialog.InputCallback() {
@Override
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
boolean isInputInteger;
try {
// try parsing for integer check
Integer.parseInt(input.toString());
isInputInteger = true;
} catch (NumberFormatException e) {
isInputInteger = false;
}
if (input.length()==0 || !isInputInteger)
setFTPTimeout(FTPService.DEFAULT_TIMEOUT);
else
setFTPTimeout(Integer.valueOf(input.toString()));
}
});
timeoutBuilder.positiveText(getResources().getString(R.string.set).toUpperCase())
.negativeText(getResources().getString(R.string.cancel))
.build()
.show();
return true;
}
return false;
@@ -193,65 +329,51 @@ public class FTPServerFragment extends Fragment {
mainActivity.getMenuInflater().inflate(R.menu.ftp_server_menu, menu);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_ftp, container, false);
statusText =(TextView) rootView.findViewById(R.id.statusText);
warningText = (TextView) rootView.findViewById(R.id.warningText);
ftpAddrText = (TextView) rootView.findViewById(R.id.ftpAddressText);
ftpBtn = (Button) rootView.findViewById(R.id.startStopButton);
private BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
ImageView ftpImage = (ImageView)rootView.findViewById(R.id.ftp_image);
//light theme
if (mainActivity.getAppTheme().equals(AppTheme.LIGHT)) {
ftpImage.setImageResource(R.drawable.ic_ftp_light);
} else {
//dark
ftpImage.setImageResource(R.drawable.ic_ftp_dark);
}
ftpBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!FTPService.isRunning()) {
if (FTPService.isConnectedToWifi(getContext()))
startServer();
else
warningText.setText(getResources().getString(R.string.ftp_no_wifi));
} else {
stopServer();
}
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMan.getActiveNetworkInfo();
if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// connected to wifi
ftpBtn.setEnabled(true);
} else {
// wifi connection lost
stopServer();
statusText.setText(spannedStatusNoConnection);
ftpBtn.setEnabled(true);
ftpBtn.setEnabled(false);
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
}
});
}
};
return rootView;
}
private BroadcastReceiver ftpReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == FTPService.ACTION_STARTED) {
if (getSecurePreference()) {
statusText.setText(spannedStatusSecure);
} else {
statusText.setText(spannedStatusConnected);
}
ftpBtn.setText(getResources().getString(R.string.stop_ftp).toUpperCase());
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
mainActivity.setActionBarTitle(getResources().getString(R.string.ftp));
mainActivity.floatingActionButton.hideMenuButton(true);
mainActivity.buttonBarFrame.setVisibility(View.GONE);
mainActivity.supportInvalidateOptionsMenu();
} else if (action == FTPService.ACTION_FAILEDTOSTART) {
statusText.setText(spannedStatusNotRunning);
skin_color = mainActivity.getColorPreference().getColor(ColorUsage.PRIMARY);
skinTwoColor = mainActivity.getColorPreference().getColor(ColorUsage.PRIMARY_TWO);
Toast.makeText(getContext(),
getResources().getString(R.string.unknown_error), Toast.LENGTH_LONG).show();
mainActivity.updateViews(new ColorDrawable(MainActivity.currentTab==1 ?
skinTwoColor : skin_color));
}
@Override
public void onDestroy() {
super.onDestroy();
}
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
} else if (action == FTPService.ACTION_STOPPED) {
statusText.setText(spannedStatusNotRunning);
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
}
}
};
/**
* Sends a broadcast to start ftp server
@@ -270,7 +392,7 @@ public class FTPServerFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
updateStatus();
IntentFilter wifiFilter = new IntentFilter();
wifiFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
getContext().registerReceiver(mWifiReceiver, wifiFilter);
@@ -289,16 +411,79 @@ public class FTPServerFragment extends Fragment {
}
/**
* Update UI widgets based on connection status
* Update UI widgets after change in shared preferences
*/
private void updateStatus() {
if (FTPService.isRunning()) {
statusText.setText(getResources().getString(R.string.ftp_status_running));
ftpBtn.setText(getResources().getString(R.string.stop_ftp));
ftpAddrText.setText(getFTPAddressString());
if (!FTPService.isRunning()) {
if (!FTPService.isConnectedToWifi(getContext())) {
statusText.setText(spannedStatusNoConnection);
ftpBtn.setEnabled(false);
} else {
statusText.setText(spannedStatusNotRunning);
ftpBtn.setEnabled(true);
}
ftpBtn.setText(getResources().getString(R.string.start_ftp).toUpperCase());
} else {
statusText.setText(getResources().getString(R.string.ftp_status_not_running));
ftpBtn.setText(getResources().getString(R.string.start_ftp));
statusText.setText(spannedStatusConnected);
ftpBtn.setEnabled(true);
ftpBtn.setText(getResources().getString(R.string.stop_ftp).toUpperCase());
}
username.setText(getResources().getString(R.string.username) + ": " +
getUsernameFromPreferences());
password.setText(getResources().getString(R.string.password) + ": " +
getPasswordFromPreferences());
port.setText(getResources().getString(R.string.ftp_port) + ": " +
getDefaultPortFromPreferences());
sharedPath.setText(getResources().getString(R.string.ftp_path) + ": " +
getDefaultPathFromPreferences());
}
private void initLoginDialogViews(View loginDialogView) {
usernameEditText = (AppCompatEditText) loginDialogView.findViewById(R.id.edit_text_dialog_ftp_username);
passwordEditText = (AppCompatEditText) loginDialogView.findViewById(R.id.edit_text_dialog_ftp_password);
usernameTextInput = (TextInputLayout) loginDialogView.findViewById(R.id.text_input_dialog_ftp_username);
passwordTextInput = (TextInputLayout) loginDialogView.findViewById(R.id.text_input_dialog_ftp_password);
mAnonymousCheckBox = (AppCompatCheckBox) loginDialogView.findViewById(R.id.checkbox_ftp_anonymous);
mSecureCheckBox = (AppCompatCheckBox) loginDialogView.findViewById(R.id.checkbox_ftp_secure);
mAnonymousCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
usernameEditText.setEnabled(false);
passwordEditText.setEnabled(false);
} else {
usernameEditText.setEnabled(true);
passwordEditText.setEnabled(true);
}
}
});
// init dialog views as per preferences
if (getUsernameFromPreferences().equals(FTPService.DEFAULT_USERNAME)) {
mAnonymousCheckBox.setChecked(true);
} else {
usernameEditText.setText(getUsernameFromPreferences());
passwordEditText.setText(getPasswordFromPreferences());
}
if (getSecurePreference()) {
mSecureCheckBox.setChecked(true);
} else mSecureCheckBox.setChecked(false);
// check if we have a keystore
InputStream stream = getResources().openRawResource(R.raw.key);
if (stream == null) {
mSecureCheckBox.setEnabled(false);
mSecureCheckBox.setChecked(false);
setSecurePreference(false);
}
}
@@ -308,4 +493,82 @@ public class FTPServerFragment extends Fragment {
private String getFTPAddressString() {
return "ftp://" + FTPService.getLocalInetAddress(getContext()).getHostAddress() + ":" + FTPService.getPort();
}
private int getDefaultPortFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getInt(FTPService.PORT_PREFERENCE_KEY, FTPService.DEFAULT_PORT);
}
private String getUsernameFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getString(FTPService.KEY_PREFERENCE_USERNAME, FTPService.DEFAULT_USERNAME);
}
private String getPasswordFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getString(FTPService.KEY_PREFERENCE_PASSWORD, "");
}
private String getDefaultPathFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getString(FTPService.KEY_PREFERENCE_PATH, FTPService.DEFAULT_PATH);
}
private void changeFTPServerPort(int port) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit()
.putInt(FTPService.PORT_PREFERENCE_KEY, port)
.apply();
updateStatus();
}
private void changeFTPServerPath(String path) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putString(FTPService.KEY_PREFERENCE_PATH, path).apply();
updateStatus();
}
private void setFTPUsername(String username) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putString(FTPService.KEY_PREFERENCE_USERNAME, username).apply();
updateStatus();
}
private void setFTPPassword(String password) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putString(FTPService.KEY_PREFERENCE_PASSWORD, password).apply();
updateStatus();
}
/**
* Returns timeout from preferences
* @return timeout in seconds
*/
private int getFTPTimeout() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getInt(FTPService.KEY_PREFERENCE_TIMEOUT, FTPService.DEFAULT_TIMEOUT);
}
private void setFTPTimeout(int seconds) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putInt(FTPService.KEY_PREFERENCE_TIMEOUT, seconds).apply();
}
private boolean getSecurePreference() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
return preferences.getBoolean(FTPService.KEY_PREFERENCE_SECURE, FTPService.DEFAULT_SECURE);
}
private void setSecurePreference(boolean isSecureEnabled) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.edit().putBoolean(FTPService.KEY_PREFERENCE_SECURE, isSecureEnabled).apply();
}
}
@@ -19,16 +19,23 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.Log;
import com.amaze.filemanager.R;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.ftpserver.ConnectionConfigFactory;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.ssl.SslConfigurationFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.DatagramSocket;
import java.net.InetAddress;
@@ -44,35 +51,17 @@ import java.util.List;
public class FTPService extends Service implements Runnable {
public static final int DEFAULT_PORT = 2211;
public static final String DEFAULT_USERNAME = "";
public static final int DEFAULT_TIMEOUT = 600; // default timeout, in sec
public static final boolean DEFAULT_SECURE = false;
public static final String PORT_PREFERENCE_KEY = "ftpPort";
public static final String KEY_PREFERENCE_PATH = "ftp_path";
public static final String KEY_PREFERENCE_USERNAME = "ftp_username";
public static final String KEY_PREFERENCE_PASSWORD = "ftp_password";
public static final String KEY_PREFERENCE_TIMEOUT = "ftp_timeout";
public static final String KEY_PREFERENCE_SECURE = "ftp_secure";
public static final String DEFAULT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
public static int getDefaultPortFromPreferences(SharedPreferences preferences) {
try {
return preferences.getInt(PORT_PREFERENCE_KEY, DEFAULT_PORT);
} catch (ClassCastException ex) {
Log.e("FtpService", "Default port preference is not an int. Resetting to default.");
changeFTPServerPort(preferences, DEFAULT_PORT);
return DEFAULT_PORT;
}
}
public static String getDefaultPathFromPreferences(SharedPreferences preferences) {
return preferences.getString(KEY_PREFERENCE_PATH, DEFAULT_PATH);
}
public static void changeFTPServerPort(SharedPreferences preferences, int port) {
preferences.edit()
.putInt(PORT_PREFERENCE_KEY, port)
.apply();
}
public static void changeFTPServerPath(SharedPreferences preferences, String path) {
preferences.edit().putString(KEY_PREFERENCE_PATH, path).apply();
}
private static final String TAG = FTPService.class.getSimpleName();
/**
@@ -109,11 +98,6 @@ public class FTPService extends Service implements Runnable {
}
}
if (intent != null && intent.getStringExtra("username") != null && intent.getStringExtra("password") != null) {
username = intent.getStringExtra("username");
password = intent.getStringExtra("password");
isPasswordProtected = true;
}
serverThread = new Thread(this);
serverThread.start();
@@ -136,6 +120,13 @@ public class FTPService extends Service implements Runnable {
serverFactory.setConnectionConfig(connectionConfigFactory.createConnectionConfig());
String usernamePreference = preferences.getString(KEY_PREFERENCE_USERNAME, DEFAULT_USERNAME);
if (!usernamePreference.equals(DEFAULT_USERNAME)) {
username = usernamePreference;
password = preferences.getString(KEY_PREFERENCE_PASSWORD, "");
isPasswordProtected = true;
}
BaseUser user = new BaseUser();
if (!isPasswordProtected) {
user.setName("anonymous");
@@ -144,7 +135,7 @@ public class FTPService extends Service implements Runnable {
user.setPassword(password);
}
user.setHomeDirectory(getDefaultPathFromPreferences(preferences));
user.setHomeDirectory(preferences.getString(KEY_PREFERENCE_PATH, DEFAULT_PATH));
List<Authority> list = new ArrayList<>();
list.add(new WritePermission());
user.setAuthorities(list);
@@ -155,9 +146,36 @@ public class FTPService extends Service implements Runnable {
}
ListenerFactory fac = new ListenerFactory();
port = getDefaultPortFromPreferences(preferences);
port = preferences.getInt(PORT_PREFERENCE_KEY, DEFAULT_PORT);
if (preferences.getBoolean(KEY_PREFERENCE_SECURE, DEFAULT_SECURE)) {
SslConfigurationFactory sslConfigurationFactory = new SslConfigurationFactory();
File file;
try {
InputStream stream = getResources().openRawResource(R.raw.key);
file = File.createTempFile("keystore", "bks");
FileOutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(stream, outputStream);
} catch (Exception e) {
e.printStackTrace();
file = null;
}
if (file != null) {
sslConfigurationFactory.setKeystoreFile(file);
sslConfigurationFactory.setKeystorePassword("vishal007");
fac.setSslConfiguration(sslConfigurationFactory.createSslConfiguration());
fac.setImplicitSsl(true);
} else {
// no keystore found
preferences.edit().putBoolean(KEY_PREFERENCE_SECURE, false).apply();
}
}
fac.setPort(port);
fac.setIdleTimeout(preferences.getInt(KEY_PREFERENCE_TIMEOUT, DEFAULT_TIMEOUT));
serverFactory.addListener("default", fac.createListener());
try {
@@ -211,7 +229,6 @@ public class FTPService extends Service implements Runnable {
SystemClock.elapsedRealtime() + 2000, restartServicePI);
}
public static boolean isRunning() {
// return true if and only if a server Thread is running
if (serverThread == null) {
@@ -268,7 +285,6 @@ public class FTPService extends Service implements Runnable {
return connected;
}
public static boolean isConnectedToWifi(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
+58
View File
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
app:errorEnabled="false"
android:id="@+id/text_input_dialog_ftp_username"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textUri"
android:hint="@string/username"
android:id="@+id/edit_text_dialog_ftp_username"
android:layout_gravity="center_horizontal" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:id="@+id/text_input_dialog_ftp_password"
app:errorEnabled="true"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword"
android:hint="@string/password"
android:id="@+id/edit_text_dialog_ftp_password"
android:layout_gravity="center_horizontal" />
</android.support.design.widget.TextInputLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<android.support.v7.widget.AppCompatCheckBox
android:id="@+id/checkbox_ftp_anonymous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/anonymous"
android:layout_gravity="start" />
<android.support.v7.widget.AppCompatCheckBox
android:id="@+id/checkbox_ftp_secure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ftp_status_secure_connection"
android:layout_gravity="end"
/>
</LinearLayout>
</LinearLayout>
+102 -38
View File
@@ -1,45 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/statusText"
android:layout_above="@+id/startStopButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="99dp" />
android:id="@+id/card_view_ftp"
android:layout_margin="@dimen/material_generic"
app:cardElevation="@dimen/material_generic_card_elevation"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/ftpAddressText"
android:layout_below="@+id/startStopButton"
android:layout_centerHorizontal="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/material_generic"
android:paddingBottom="@dimen/material_generic"
android:paddingTop="@dimen/material_generic"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start_ftp"
android:id="@+id/startStopButton"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<!-- status -->
<TextView
android:id="@+id/text_view_ftp_status"
android:layout_width="wrap_content"
android:layout_height="@dimen/material_generic_medium"
android:textSize="@dimen/material_generic_title_large"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/primary_red"
android:id="@+id/warningText"
android:layout_above="@+id/startStopButton"
android:layout_centerHorizontal="true" />
<View
android:id="@+id/divider_ftp_status"
android:layout_width="match_parent"
android:layout_height="@dimen/height_divider"
android:background="@color/divider"
android:layout_marginTop="@dimen/material_generic"
android:layout_marginBottom="@dimen/material_generic"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ftp_image"
android:layout_above="@+id/warningText"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<!-- username -->
<TextView
android:id="@+id/text_view_ftp_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/material_generic_title"
android:layout_marginBottom="@dimen/material_generic"
/>
<!-- password -->
<TextView
android:id="@+id/text_view_ftp_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/material_generic_title"
android:layout_marginBottom="@dimen/material_generic"
/>
<!-- port -->
<TextView
android:id="@+id/text_view_ftp_port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/material_generic_title"
android:layout_marginBottom="@dimen/material_generic"
/>
<!-- shared path -->
<TextView
android:id="@+id/text_view_ftp_path"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/material_generic_title"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/divider_ftp_start"
android:layout_width="match_parent"
android:layout_height="@dimen/height_divider"
android:background="@color/divider"
android:layout_marginBottom="@dimen/material_generic"
/>
<Button
android:layout_width="match_parent"
android:layout_height="@dimen/material_generic_medium"
android:text="@string/start_ftp"
android:id="@+id/startStopButton"
android:background="?android:attr/selectableItemBackground"
android:layout_marginBottom="@dimen/material_generic"
/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
+38 -38
View File
@@ -9,14 +9,14 @@
app:errorEnabled="true"
android:id="@+id/connectionTIL"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textUri"
android:hint="@string/connectionname"
android:id="@+id/connectionET"
android:layout_gravity="center_horizontal" />
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textUri"
android:hint="@string/connectionname"
android:id="@+id/connectionET"
android:layout_gravity="center_horizontal" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
@@ -24,14 +24,14 @@
android:id="@+id/ipTIL"
app:errorEnabled="true"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textUri"
android:hint="@string/smb_server"
android:id="@+id/ipET"
android:layout_gravity="center_horizontal" />
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textUri"
android:hint="@string/smb_server"
android:id="@+id/ipET"
android:layout_gravity="center_horizontal" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
@@ -54,38 +54,38 @@
app:errorEnabled="true"
android:layout_height="wrap_content"
android:id="@+id/usernameTIL" >
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="@string/username"
android:ems="10"
android:id="@+id/usernameET" />
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="@string/username"
android:ems="10"
android:id="@+id/usernameET" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
app:errorEnabled="true"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:hint="@string/password"
android:id="@+id/passwordET"
android:layout_gravity="center_horizontal" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:hint="@string/password"
android:id="@+id/passwordET"
android:layout_gravity="center_horizontal" />
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/anonymous"
android:id="@+id/checkBox2"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:id="@+id/wanthelp"
android:layout_height="wrap_content"
android:text="@string/wanthelp"
/>
<TextView
android:layout_width="wrap_content"
android:id="@+id/wanthelp"
android:layout_height="wrap_content"
android:text="@string/wanthelp"
/>
</LinearLayout>
+6
View File
@@ -6,4 +6,10 @@
<item
android:id="@+id/ftp_path"
android:title="@string/ftp_path" />
<item
android:id="@+id/ftp_login"
android:title="@string/ftp_login" />
<item
android:id="@+id/ftp_timeout"
android:title="@string/ftp_timeout" />
</menu>
+2 -1
View File
@@ -32,7 +32,8 @@
<color name="holo_dark_action_mode">#212121</color>
<color name="holo_dark_selection">#424242</color>
<color name="divider">#e0e0e0</color>
<color name="divider_dark">#474747</color>
<color name="divider_dark_card">#575757</color>
<color name="divider_dark">#484848</color>
<color name="search_text_highlight">#FF9632</color>
<!-- TODO: replace this hardcoded color with default list item selection color -->
<color name="check_background">#EEEEEE</color>
+3
View File
@@ -26,6 +26,9 @@
<dimen name="material_generic_large">72dp</dimen>
<dimen name="material_generic_card_elevation">4dp</dimen>
<dimen name="material_generic_title">16sp</dimen>
<dimen name="material_generic_title_large">20sp</dimen>
<dimen name="material_generic_title_summary">12sp</dimen>
<dimen name="material_generic_list_item">72dp</dimen>
<dimen name="height_divider">1dp</dimen>
</resources>
+10 -1
View File
@@ -411,7 +411,7 @@
<string name="ftp_notif_title">Amaze FTP Server running</string>
<string name="ftp_notif_text">at %s</string>
<string name="ftp_notif_stop_server">STOP</string>
<string name="ftp_port_edit_menu_title">Choose FTP port</string>
<string name="ftp_port_edit_menu_title">FTP port</string>
<string name="ftp_port_change_success">FTP port changed successfully</string>
<string name="ftp_port_change_error_invalid">Invalid port number selected</string>
<string name="primary_two_title">Primary Color (Right Tab)</string>
@@ -575,8 +575,17 @@
<string name="ftp_path_hint">Path to the root of directory to share</string>
<string name="error_ftp_path_file">Path not a directory</string>
<string name="change">Change</string>
<string name="unknown_error">Oops, something went wrong!</string>
<string name="ftp_path_change_success">FTP path changed successfully</string>
<string name="ftp_path_change_error_invalid">Invalid path</string>
<string name="ftp_status_no_connection">No Connection</string>
<string name="ftp_status_secure_connection">Secure Connection</string>
<string name="ftp_status_title">Status</string>
<string name="ftp_port">Port</string>
<string name="ftp_login">Login</string>
<string name="field_empty">Field can\'t be empty</string>
<string name="ftp_timeout">Idle timeout</string>
<string name="ftp_seconds">Seconds</string>
</resources>