Skip to content
This repository has been archived by the owner on Jan 14, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Split RUN_SCRIPT handling out into its own activity
We currently use intent filters to direct jackpal.androidterm.RUN_SCRIPT
actions to the RunScript activity, which is gated in the manifest by the
permission jackpal.androidterm.permission.RUN_SCRIPT.  However,
RunScript is an alias for the RemoteInterface activity, which is exposed
without the permission requirement; because applications are permitted to
explicitly specify a component when sending an intent, this allows an
application to trigger a RUN_SCRIPT action without having the
corresponding permission.

Fix this by removing RUN_SCRIPT handling from RemoteInterface and
creating a new RunScript activity (a subclass of RemoteInterface) to
handle RUN_SCRIPT actions.  Any scripts supplied by callers to
RemoteInterface will now be ignored, though the call will open a new
terminal window.

Thanks to Daoyuan Wu for reporting and analyzing the issue.  Fixes #374.
  • Loading branch information
steven676 committed Jan 25, 2015
1 parent 9eb5731 commit 5112961
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 63 deletions.
6 changes: 3 additions & 3 deletions term/src/main/AndroidManifest.xml
Expand Up @@ -71,14 +71,14 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity-alias>
<activity-alias android:name="RunScript"
android:targetActivity="RemoteInterface"
<activity android:name="RunScript"
android:excludeFromRecents="true"
android:permission="jackpal.androidterm.permission.RUN_SCRIPT">
<intent-filter>
<action android:name="jackpal.androidterm.RUN_SCRIPT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity-alias>
</activity>
<activity android:name="TermPreferences"
android:label="@string/preferences"/>
<activity android:name="WindowList"
Expand Down
85 changes: 25 additions & 60 deletions term/src/main/java/jackpal/androidterm/RemoteInterface.java
Expand Up @@ -35,23 +35,11 @@
import jackpal.androidterm.util.SessionList;
import jackpal.androidterm.util.TermSettings;

/*
* New procedure for launching a command in ATE.
* Build the path and arguments into a Uri and set that into Intent.data.
* intent.data(new Uri.Builder().setScheme("file").setPath(path).setFragment(arguments))
*
* The old procedure of using Intent.Extra is still available but is discouraged.
*/
public class RemoteInterface extends Activity {
private static final String ACTION_RUN_SCRIPT = "jackpal.androidterm.RUN_SCRIPT";

static final String PRIVACT_OPEN_NEW_WINDOW = "jackpal.androidterm.private.OPEN_NEW_WINDOW";
static final String PRIVACT_SWITCH_WINDOW = "jackpal.androidterm.private.SWITCH_WINDOW";

private static final String EXTRA_WINDOW_HANDLE = "jackpal.androidterm.window_handle";
private static final String EXTRA_INITIAL_COMMAND = "jackpal.androidterm.iInitialCommand";
protected static final String PRIVACT_OPEN_NEW_WINDOW = "jackpal.androidterm.private.OPEN_NEW_WINDOW";
protected static final String PRIVACT_SWITCH_WINDOW = "jackpal.androidterm.private.SWITCH_WINDOW";

static final String PRIVEXTRA_TARGET_WINDOW = "jackpal.androidterm.private.target_window";
protected static final String PRIVEXTRA_TARGET_WINDOW = "jackpal.androidterm.private.target_window";

private TermSettings mSettings;

Expand Down Expand Up @@ -83,52 +71,30 @@ protected void onCreate(Bundle savedInstanceState) {
}
}

private void handleIntent() {
TermService service = mTermService;
@Override
public void finish() {
ServiceConnection conn = mTSConnection;
if (conn != null) {
unbindService(conn);
mTSConnection = null;
}
super.finish();
}

protected TermService getTermService() {
return mTermService;
}

protected void handleIntent() {
TermService service = getTermService();
if (service == null) {
finish();
return;
}

Intent myIntent = getIntent();
String action = myIntent.getAction();
if (action.equals(ACTION_RUN_SCRIPT)) {
/* Someone with the appropriate permissions has asked us to
run a script */
String handle = myIntent.getStringExtra(EXTRA_WINDOW_HANDLE);
String command=null;
/*
* First look in Intent.data for the path; if not there, revert to
* the EXTRA_INITIAL_COMMAND location.
*/
Uri uri=myIntent.getData();
if(uri!=null) // scheme[path][arguments]
{
String s=uri.getScheme();
if(s!=null && s.toLowerCase().equals("file"))
{
command=uri.getPath();
// Allow for the command to be contained within the arguments string.
if(command==null) command="";
if(!command.equals("")) command=quoteForBash(command);
// Append any arguments.
if(null!=(s=uri.getFragment())) command+=" "+s;
}
}
// If Intent.data not used then fall back to old method.
if(command==null) command=myIntent.getStringExtra(EXTRA_INITIAL_COMMAND);
if (handle != null) {
// Target the request at an existing window if open
handle = appendToWindow(handle, command);
} else {
// Open a new window
handle = openNewWindow(command);
}
Intent result = new Intent();
result.putExtra(EXTRA_WINDOW_HANDLE, handle);
setResult(RESULT_OK, result);
}
else if (action.equals(Intent.ACTION_SEND)
if (action.equals(Intent.ACTION_SEND)
&& myIntent.hasExtra(Intent.EXTRA_STREAM)) {
/* "permission.RUN_SCRIPT" not required as this is merely opening a new window. */
Object extraStream = myIntent.getExtras().get(Intent.EXTRA_STREAM);
Expand All @@ -143,14 +109,13 @@ else if (action.equals(Intent.ACTION_SEND)
openNewWindow(null);
}

unbindService(mTSConnection);
finish();
}

/**
* Quote a string so it can be used as a parameter in bash and similar shells.
*/
private String quoteForBash(String s) {
protected String quoteForBash(String s) {
StringBuilder builder = new StringBuilder();
String specialChars = "\"\\$`!";
builder.append('"');
Expand All @@ -166,8 +131,8 @@ private String quoteForBash(String s) {
return builder.toString();
}

private String openNewWindow(String iInitialCommand) {
TermService service = mTermService;
protected String openNewWindow(String iInitialCommand) {
TermService service = getTermService();

String initialCommand = mSettings.getInitialCommand();
if (iInitialCommand != null) {
Expand All @@ -193,8 +158,8 @@ private String openNewWindow(String iInitialCommand) {
return handle;
}

private String appendToWindow(String handle, String iInitialCommand) {
TermService service = mTermService;
protected String appendToWindow(String handle, String iInitialCommand) {
TermService service = getTermService();

// Find the target window
SessionList sessions = service.getSessions();
Expand Down
87 changes: 87 additions & 0 deletions term/src/main/java/jackpal/androidterm/RunScript.java
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2012 Steven Luo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package jackpal.androidterm;

import android.content.Intent;
import android.net.Uri;
import android.util.Log;

/*
* New procedure for launching a command in ATE.
* Build the path and arguments into a Uri and set that into Intent.data.
* intent.data(new Uri.Builder().setScheme("file").setPath(path).setFragment(arguments))
*
* The old procedure of using Intent.Extra is still available but is discouraged.
*/
public final class RunScript extends RemoteInterface {
private static final String ACTION_RUN_SCRIPT = "jackpal.androidterm.RUN_SCRIPT";

private static final String EXTRA_WINDOW_HANDLE = "jackpal.androidterm.window_handle";
private static final String EXTRA_INITIAL_COMMAND = "jackpal.androidterm.iInitialCommand";

@Override
protected void handleIntent() {
TermService service = getTermService();
if (service == null) {
finish();
return;
}

Intent myIntent = getIntent();
String action = myIntent.getAction();
if (action.equals(ACTION_RUN_SCRIPT)) {
/* Someone with the appropriate permissions has asked us to
run a script */
String handle = myIntent.getStringExtra(EXTRA_WINDOW_HANDLE);
String command=null;
/*
* First look in Intent.data for the path; if not there, revert to
* the EXTRA_INITIAL_COMMAND location.
*/
Uri uri=myIntent.getData();
if(uri!=null) // scheme[path][arguments]
{
String s=uri.getScheme();
if(s!=null && s.toLowerCase().equals("file"))
{
command=uri.getPath();
// Allow for the command to be contained within the arguments string.
if(command==null) command="";
if(!command.equals("")) command=quoteForBash(command);
// Append any arguments.
if(null!=(s=uri.getFragment())) command+=" "+s;
}
}
// If Intent.data not used then fall back to old method.
if(command==null) command=myIntent.getStringExtra(EXTRA_INITIAL_COMMAND);
if (handle != null) {
// Target the request at an existing window if open
handle = appendToWindow(handle, command);
} else {
// Open a new window
handle = openNewWindow(command);
}
Intent result = new Intent();
result.putExtra(EXTRA_WINDOW_HANDLE, handle);
setResult(RESULT_OK, result);

finish();
} else {
super.handleIntent();
}
}
}

0 comments on commit 5112961

Please sign in to comment.