Skip to content

Commit

Permalink
Bug-fixes for support to spice and rdp URI schemes.
Browse files Browse the repository at this point in the history
  • Loading branch information
iiordanov committed Feb 11, 2015
1 parent 2ff7ef5 commit 816b118
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 65 deletions.
2 changes: 1 addition & 1 deletion eclipse_projects/bVNC/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iiordanov.bVNC" android:installLocation="auto"
android:versionCode="3760" android:versionName="v3.7.6">
android:versionCode="3770" android:versionName="v3.7.7">

<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10"></uses-sdk>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Expand Down
147 changes: 86 additions & 61 deletions eclipse_projects/bVNC/src/com/iiordanov/bVNC/ConnectionBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -265,64 +265,84 @@ static ConnectionBean createLoadFromUri(Uri dataUri, Context ctx)
return connection;
}

void parseFromUri(Uri dataUri)
{
void parseFromUri(Uri dataUri) {
Log.i(TAG, "Parsing VNC URI.");
if (dataUri == null)
{
if (dataUri == null) {
m_isReadyForConnection = false;
m_saved = true;
return;
}
String host = dataUri.getHost();
if (host != null)
{

String host = dataUri.getHost();
if (host != null) {
setAddress(host);

// by default, the connection name is the host name
String nickName = getNickname();
if (Utils.isNullOrEmptry(nickName))
if (Utils.isNullOrEmptry(nickName)) {
setNickname(host);
}

// default to use same host for ssh
if (Utils.isNullOrEmptry(getSshServer()))
setSshServer(host);
if (Utils.isNullOrEmptry(getSshServer())) {
setSshServer(host);
}
}

final int PORT_NONE = -1;
int port = dataUri.getPort();
if (port != PORT_NONE)
{
if (port != PORT_NONE) {
if (!isValidPort(port))
throw new IllegalArgumentException("The specified VNC port is not valid.");
setPort(port);
}

// handle legacy android-vnc-viewer parsing vnc://host:port/colormodel/password
List<String> path = dataUri.getPathSegments();
if (path.size() >= 1)
{
if (path.size() >= 1) {
setColorModel(path.get(0));
}
if (path.size() >= 2)
{

if (path.size() >= 2) {
setPassword(path.get(1));
}

// query based parameters
String connectionName = dataUri.getQueryParameter(Constants.PARAM_CONN_NAME);
if (connectionName != null)

if (connectionName != null) {
setNickname(connectionName);
String username = dataUri.getQueryParameter(Constants.PARAM_USER);
if (username != null)
setUserName(username);
String password = dataUri.getQueryParameter(Constants.PARAM_PWD);
if (password != null) // constructor avoids null values
setPassword(password);
}

ArrayList<String> supportedUserParams = new ArrayList<String>() {{
add(Constants.PARAM_RDP_USER); add(Constants.PARAM_SPICE_USER); add(Constants.PARAM_VNC_USER);
}};
for (String userParam : supportedUserParams) {
String username = dataUri.getQueryParameter(userParam);
if (username != null) {
setUserName(username);
break;
}
}

ArrayList<String> supportedPwdParams = new ArrayList<String>() {{
add(Constants.PARAM_RDP_PWD); add(Constants.PARAM_SPICE_PWD); add(Constants.PARAM_VNC_PWD);
}};
for (String pwdParam : supportedPwdParams) {
String password = dataUri.getQueryParameter(pwdParam);
if (password != null) {
setPassword(password);
break;
}
}

setKeepPassword(false); // we should not store the password unless it is encrypted

String securityTypeParam = dataUri.getQueryParameter(Constants.PARAM_SECTYPE);
int secType = 0; //invalid
if (securityTypeParam != null)
{
if (securityTypeParam != null) {
secType = Integer.parseInt(securityTypeParam); // throw if invalid
switch (secType)
{
switch (secType) {
case Constants.SECTYPE_NONE:
case Constants.SECTYPE_VNC:
setConnectionType(Constants.CONN_TYPE_PLAIN);
Expand All @@ -346,29 +366,36 @@ void parseFromUri(Uri dataUri)
throw new IllegalArgumentException("The specified security type is invalid or unsupported.");
}
}

// ssh parameters
String sshHost = dataUri.getQueryParameter(Constants.PARAM_SSH_HOST);
if (sshHost != null) setSshServer(sshHost);
if (sshHost != null) {
setSshServer(sshHost);
}

String sshPortParam = dataUri.getQueryParameter(Constants.PARAM_SSH_PORT);
if (sshPortParam != null)
{
if (sshPortParam != null) {
int sshPort = Integer.parseInt(sshPortParam);
if (!isValidPort(sshPort))
throw new IllegalArgumentException("The specified SSH port is not valid.");
setSshPort(sshPort);
}

String sshUser = dataUri.getQueryParameter(Constants.PARAM_SSH_USER);
if (sshUser != null) setSshUser(sshUser);
if (sshUser != null) {
setSshUser(sshUser);
}

String sshPassword = dataUri.getQueryParameter(Constants.PARAM_SSH_PWD);
if (sshPassword != null) setSshPassword(sshPassword);
if (sshPassword != null) {
setSshPassword(sshPassword);
}

// security hashes
String idHashAlgParam = dataUri.getQueryParameter(Constants.PARAM_ID_HASH_ALG);
if (idHashAlgParam != null)
{
if (idHashAlgParam != null) {
int idHashAlg = Integer.parseInt(idHashAlgParam); // throw if invalid
switch (idHashAlg)
{
switch (idHashAlg) {
case Constants.ID_HASH_MD5:
case Constants.ID_HASH_SHA1:
case Constants.ID_HASH_SHA256:
Expand All @@ -381,15 +408,15 @@ void parseFromUri(Uri dataUri)
}

String idHash = dataUri.getQueryParameter(Constants.PARAM_ID_HASH);
if (idHash != null) setIdHash(idHash);
if (idHash != null) {
setIdHash(idHash);
}

// color model
String colorModelParam = dataUri.getQueryParameter(Constants.PARAM_COLORMODEL);
if (colorModelParam != null)
{
if (colorModelParam != null) {
int colorModel = Integer.parseInt(colorModelParam); // throw if invalid
switch (colorModel)
{
switch (colorModel) {
case Constants.COLORMODEL_BLACK_AND_WHITE:
setColorModel(COLORMODEL.C2.nameString());
break;
Expand Down Expand Up @@ -422,43 +449,42 @@ void parseFromUri(Uri dataUri)
}
String saveConnectionParam = dataUri.getQueryParameter(Constants.PARAM_SAVE_CONN);
boolean saveConnection = true;
if (saveConnectionParam != null)
if (saveConnectionParam != null) {
saveConnection = Boolean.parseBoolean(saveConnectionParam); // throw if invalid
}

// if we are going to save the connection, we will do so here
// it may make sense to confirm overwriting data but is probably unnecessary
if (saveConnection)
{
if (saveConnection) {
Database database = new Database(c);
save(database.getWritableDatabase());
database.close();
m_saved = true;
}

// we do not currently use API keys

// check if we need to show data-entry screen
// it may be possible to prompt for data later
m_isReadyForConnection = true;
if (Utils.isNullOrEmptry(getAddress()))
{
if (Utils.isNullOrEmptry(getAddress())) {
m_isReadyForConnection = false;
Log.i(TAG, "URI missing remote address.");
}

int connType = getConnectionType();
if (secType == Constants.SECTYPE_VNC || connType == Constants.CONN_TYPE_STUNNEL
|| connType == Constants.CONN_TYPE_SSH)
{
|| connType == Constants.CONN_TYPE_SSH) {
// we can infer a password is required
// while we could have implemented tunnel/ssh without one
// the user can supply a blank value and the server will not
// request it and it is better to support the common case
if (Utils.isNullOrEmptry(getPassword()))
{
if (Utils.isNullOrEmptry(getPassword())) {
m_isReadyForConnection = false;
Log.i(TAG, "URI missing VNC password.");
}
}
if (connType == Constants.CONN_TYPE_SSH)
{
if (connType == Constants.CONN_TYPE_SSH) {
// the below should not occur
if (Utils.isNullOrEmptry(getSshServer()))
m_isReadyForConnection = false;
Expand All @@ -469,8 +495,7 @@ void parseFromUri(Uri dataUri)
// however main screen doesn't validate this
}

boolean isValidPort(int port)
{
boolean isValidPort(int port) {
final int PORT_MAX = 65535;
if (port <= 0 || port > PORT_MAX)
return false;
Expand All @@ -479,20 +504,21 @@ boolean isValidPort(int port)

@Override
public String toString() {
if (isNew())
{
if (isNew()) {
return c.getString(R.string.new_connection);
}
String result = new String("");

// Add the nickname if it has been set.
if (!getNickname().equals(""))
if (!getNickname().equals("")) {
result += getNickname()+":";
}

// If this is an VNC over SSH connection, add the SSH server:port in parentheses
if (getConnectionType() == Constants.CONN_TYPE_SSH)
if (getConnectionType() == Constants.CONN_TYPE_SSH) {
result += "(" + getSshServer() + ":" + getSshPort() + ")" + ":";

}

// Add the VNC server and port.
result += getAddress()+":"+getPort();
return result;
Expand Down Expand Up @@ -529,8 +555,7 @@ public int compareTo(ConnectionBean another) {
* @return Object representing the single persistent instance of MostRecentBean, which
* is the app's global state
*/
public static MostRecentBean getMostRecent(SQLiteDatabase db)
{
public static MostRecentBean getMostRecent(SQLiteDatabase db) {
ArrayList<MostRecentBean> recents = new ArrayList<MostRecentBean>(1);
MostRecentBean.getAll(db, MostRecentBean.GEN_TABLE_NAME, recents, MostRecentBean.GEN_NEW);
if (recents.size() == 0)
Expand Down
8 changes: 6 additions & 2 deletions eclipse_projects/bVNC/src/com/iiordanov/bVNC/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ public class Constants {

// URI Parameters
public static final String PARAM_CONN_NAME = "ConnectionName";
public static final String PARAM_USER = "VncUsername";
public static final String PARAM_PWD = "VncPassword";
public static final String PARAM_RDP_USER = "RdpUsername";
public static final String PARAM_RDP_PWD = "RdpPassword";
public static final String PARAM_SPICE_USER = "SpiceUsername";
public static final String PARAM_SPICE_PWD = "SpicePassword";
public static final String PARAM_VNC_USER = "VncUsername";
public static final String PARAM_VNC_PWD = "VncPassword";
public static final String PARAM_SECTYPE = "SecurityType";
public static final String PARAM_SSH_HOST = "SshHost";
public static final String PARAM_SSH_PORT = "SshPort";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,14 @@ void initialize () {
connection = null;

Uri data = i.getData();
if ((data != null) && (data.getScheme().equals("vnc")) || !Utils.isNullOrEmptry(i.getType())) {

boolean isSupportedScheme = false;
if (data != null) {
String s = data.getScheme();
isSupportedScheme = s.equals("rdp") || s.equals("spice") || s.equals("vnc");
}

if (isSupportedScheme || !Utils.isNullOrEmptry(i.getType())) {
if (isMasterPasswordEnabled()) {
Utils.showFatalErrorMessage(this, getResources().getString(R.string.master_password_error_intents_not_supported));
return;
Expand Down

0 comments on commit 816b118

Please sign in to comment.