Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability for Scripts to Launch Commands for Arch Linux in Termux PRoot on Device #54

Closed
MolotovCherry opened this issue Mar 6, 2018 · 25 comments

Comments

@MolotovCherry
Copy link

MolotovCherry commented Mar 6, 2018

Hi,

It would be incredibly useful if scripts had the ability to launch commands in Arch Linux, much the same way you can do a bash -c, maybe a startarch -c

This would benefit scripts that run from Termux:Boot or Termux:Task

@SDRausty
Copy link
Owner

SDRausty commented Mar 7, 2018

Hello,

Thank you for your time and insight. Can you explain this a little bit more? First, what is the intended outcome? Second:

would benefit scripts that run from Termux:Boot or Termux:Task

This is a very good suggestion. Can you provide some examples?

@MolotovCherry
Copy link
Author

MolotovCherry commented Mar 7, 2018

Sure, let me see if I can explain a little more detailed.

The purpose is so that, from Termux point of view, you can "access" arch just as if it were another part of Termux, being able to run scripts and binaries in arch, from termux. Since arch still has access to the system, this is easy to do, as long as we can pass commands to it like we can do with bash

So, the outcome is to make it possible to run arch binaries and commands directly in Termux. Arch has tons more packages that can be useful, especially when there isn't a Termux package available. It gives more versatility, augmenting Termux shortcomings (the fact it doesn't have every package there is)

I imagine the implementation to be simple, just pass any commands to arch via startarch -c "commands". A use case even this simple should be more than adequate to do anything.

Termux example

$ cat echo.sh
#!/bin/bash
echo foo $1
$ startarch -c "bash echo.sh arg1"
foo arg1
$

I first got this idea because I wanted to use my imagemagick script on Termux, but Termux imagemagick is broken, where termuxarch one works. In the end I found a clang compiled imagemagick , but I'd rather use a "more official" method.

Did that make sense? Or do you need a little more clarification?

@SDRausty SDRausty changed the title Ability for scripts to launch commands in Arch Ability for Scripts to Launch Commands for Arch Linux in Termux PRoot on Device Mar 8, 2018
@SDRausty
Copy link
Owner

SDRausty commented Mar 9, 2018

Thanks for contributing f88b9d1 and expanding this topic. Options have been introduced to startarch https://github.com/sdrausty/TermuxArch/blob/master/necessaryfunctions.sh#L215&L249 thanks to this issue. They are -c (--command), -l (--login username [-c command]) and -r (--raw).

Does option -c fulfill the requirement @cherryleafroad for resolving this issue?

@tomty89 thank you for participating and expanding upon this issue. Can you explain -b $ANDROID_DATA -b $EXTERNAL_STORAGE in a little more detail?

Use addauser or addauserps before using startarch --login username args. For example: addauser newuser in Arch Linux in Termux PRoot will create user newuser and the home directory for newuser. Then in a new Termux session startarch --login newuser -c ~/echo.sh args1 should fulfill the request in this thread as I understand it, with the addition of running the command as a normal user account (in this example newuser) in Arch Linux in Termux PRoot as opposed to the root account which should be reserved for system maintenance.

@SDRausty
Copy link
Owner

SDRausty commented Mar 9, 2018

@cherryleafroad

This would benefit scripts that run from Termux:Boot or Termux:Task

Can you provide some examples? This does sound useful.

@MolotovCherry
Copy link
Author

Forgive the beginner question, but how do I update the script when arch is already installed? I'll write a simple example once I get it working

@SDRausty
Copy link
Owner

SDRausty commented Mar 9, 2018

Forgive the beginner question, but how do I update the script when arch is already installed?

Thank you for your question. Thanks to your request one more enhancement has just been implemented with this 4615d7e commit. setupTermuxArch.sh --refresh should do what you want it to do now as well as startarch --command.

$ cat ./arch/startarch
#!/data/data/com.termux/files/usr/bin/bash -e
# Copyright 2017-2018 by SDRausty. All rights reserved.  🌎 🌍 🌏 🌐 🗺
# Hosting https://sdrausty.github.io/TermuxArch courtesy https://pages.github.com
# https://sdrausty.github.io/TermuxArch/CONTRIBUTORS Thank you for your help.
# https://sdrausty.github.io/TermuxArch/README has information about this project.
################################################################################
unset LD_PRELOAD
# [command args] Execute a command in BASH as root.
if [[ $1 = [Cc]* ]] || [[ $1 = -[Cc]* ]] || [[ $1 = --[Cc]* ]];then
exec proot --kill-on-exit --link2symlink -0 -r /data/data/com.termux/files/home/arch/ -b /dev/ -b /sys/ -b /proc/ -b /storage/ -b /data/data/com.termux/files/home -w /data/data/com.termux/files/home /bin/env -i HOME=/root TERM="xterm-256color" PS1='[termux@arch \W]$ ' LANG=en_US.UTF-8 PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/bash -lc $@ ||:
# [login user|su user] || [login user -c command|su user -c command] Login as user.  Alternatively, login as user and execute command.  Use `addauser user` first to create this user and the user home directory
elif [[ $1 = [Ll]* ]] || [[ $1 = -[Ll]* ]] || [[ $1 = --[Ll]* ]] || [[ $1 = [Ss]* ]] || [[ $1 = -[Ss]* ]] || [[ $1 = --[Ss]* ]];then
exec proot --kill-on-exit --link2symlink -0 -r /data/data/com.termux/files/home/arch/ -b /dev/ -b /sys/ -b /proc/ -b /storage/ -b /data/data/com.termux/files/home -w /data/data/com.termux/files/home /bin/env -i HOME=/root TERM="xterm-256color" PS1='[termux@arch \W]$ ' LANG=en_US.UTF-8 PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/su - ${@:2} ||:
# [raw args] Construct the `startarch` proot statement.  For example `startarch r su - archuser` will login as user archuser.  Use `addauser archuser` first to create this user and the user home directory.
elif [[ $1 = [Rr]* ]] || [[ $1 = -[Rr]* ]] || [[ $1 = --[Rr]* ]];then
exec proot --kill-on-exit --link2symlink -0 -r /data/data/com.termux/files/home/arch/ -b /dev/ -b /sys/ -b /proc/ -b /storage/ -b /data/data/com.termux/files/home -w /data/data/com.termux/files/home /bin/env -i HOME=/root TERM="xterm-256color" PS1='[termux@arch \W]$ ' LANG=en_US.UTF-8 PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/$@ ||:
else
# [] Default Arch Linux in Termux PRoot root login.
exec proot --kill-on-exit --link2symlink -0 -r /data/data/com.termux/files/home/arch/ -b /dev/ -b /sys/ -b /proc/ -b /storage/ -b /data/data/com.termux/files/home -w /data/data/com.termux/files/home /bin/env -i HOME=/root TERM="xterm-256color" PS1='[termux@arch \W]$ ' LANG=en_US.UTF-8 PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/bash --login ||:
fi

@tomty89
Copy link

tomty89 commented Mar 9, 2018

You don't want -w $HOME but -w $PWD for the direct execute ones, because otherwise when you cd to somewhere else and try to work on files there, you will fail coz proot gets you back to $HOME. And $PWD should be double-quoted in case of spaces or so in it.

And you need double-quoted $* (${*:2} in your case) instead of $@, because you need to pass the whole line of command to bash -lc as a single arugument:

if [[ $1 = -c ]]; then
    echo root; bash -c ${@:2}
    echo root; bash -c "${@:2}"
    echo root; bash -c ${*:2}
    echo root; bash -c "${*:2}"
elif [[ $1 = -u ]]; then
    user=$2
    shift 2;
    if [[ $1 = -c ]]; then
	echo $user; bash -c ${@:2}
	echo $user; bash -c "${@:2}"
	echo $user; bash -c ${*:2}
	echo $user; bash -c "${*:2}"
    else
	echo $user shell
    fi
else
    echo root shell
fi
$ ./test.sh
root shell
$ ./test.sh -u alarm
alarm shell
$ ./test.sh -c echo a b c
root

root

root

root
a b c
$ ./test.sh -u alarm -c echo a b c
alarm

alarm

alarm

alarm
a b c
$

If you want direct execute for other users (if it ever make sense), you should do it seperately (su - $2 and su - $2 -c "${*:3}").

And you always want the login shell (bash -l) even when you want to direct execute a command (-c or not) because you want the env vars to be set by /etc/profile properly, including but not limited to LANG and PATH. You should never have hardcoded these, especially for PATH (coz it's NOT always just /usr/bin/path and its symlink variants). So the third one (/bin/$@) should go. It's silly to hardcode PS1 as well. (I remember it didn't even work).

In conclusion, you should have four variants:

bash -l
bash -lc "${*:2}"
su - $2
su - $2 -c "${*:3}"`

(The - for su is equivalent to -l for bash. You don't want to omit it in either case.)

@tomty89
Copy link

tomty89 commented Mar 9, 2018

@SDRausty oh for your question

$ printenv ANDROID_DATA
/data
$ printenv EXTERNAL_STORAGE
/sdcard
$

I use these instead of -b $HOME and -b /storage respectively. They are set by Termux btw (like $HOME and $TERM), not me.

Btw you probably want to omit -b /sys coz I don't think it's ever useful or accessible. IIRC on some Android build it cause proot to fail. termux-chroot doesn't do -b /sys either.

@barre121
Copy link

barre121 commented Mar 9, 2018

Greetings!
Guys, i have arch installed for days and i haven't done
anything with it because of my short knowledge of it.
I wanted was to grab some pentesting tools from it's
repo play with them.
like these once:

Metasploit,
routersploit
Empire,
beEF
Vega
Maltego,
NMap,
wifite

I run

Pacman -Su routersploit.

Says terget not found.

They say edit by adding:

/etc/pacman.conf and add:

[archstrike]

Server = https://mirror.archstrike.org/$arch/$repo

[blackarch]

Server = http://blackarch.org/blackarch/$repo/os/$arch

Next run pacman -Syu to update your repository listing. To install either distribution, run one of these commands:

pacman -S archstrike –needed

pacman -S blackarch –needed

If that is so
I copy this and then where in the file should i past?

Can't i grab these tools without adding and installing
these big sized distros?

help please!
i don't know where to start.

@SDRausty
Copy link
Owner

SDRausty commented Mar 9, 2018

@tomty89 awesome advice with details. Thank you. TermuxArch v.1.2 is available for testing and should meet all the requirements of this topic.

@tomty89
Copy link

tomty89 commented Mar 9, 2018

Well you are still using $@, and all those unnecessary hard coded env vars, and variants should be added and removed...

Should I be glad that you at least got -w right? (Actually not so right because $PWD should just use for the direct execute variants.) I am definitely glad that I am capable of writing the appropriate script myself though...

@tomty89
Copy link

tomty89 commented Mar 9, 2018

Geez $HOME$rootdir? I don't know what's rootdir but can't you even put the slash betwewn the variables instead of in $rootdir, just to make it read/look better.

LANG=$LANG is the most hilarious one because in Termux LANG will only be en_US.UTF-8, while in the Arch proot you can generate other locales and set LANG to other values in locale.conf, not to mention there's no reason to set LANG/PATH here.

@SDRausty
Copy link
Owner

SDRausty commented Mar 9, 2018

@tomty89 compare startarch -l user -c top with @ and *. * doesn't work.

@ works for startarch -l user -c top:
exec proot --kill-on-exit --link2symlink -0 -r $HOME/arch/ -b /dev/ -b $ANDROID_DATA -b $EXTERNAL_STORAGE -b /proc/ -w "$PWD" /bin/env -i HOME=/root TERM=$TERM LANG=$LANG PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/su - "${@:2}"

* does not:
exec proot --kill-on-exit --link2symlink -0 -r $HOME/arch/ -b /dev/ -b $ANDROID_DATA -b $EXTERNAL_STORAGE -b /proc/ -w "$PWD" /bin/env -i HOME=/root TERM=$TERM LANG=$LANG PATH=/bin:/usr/bin:/sbin:/usr/sbin /bin/su - "${*:2}"

Can any of these proot statements be dropped? Ideas how to get startarch -l user -c top -v to load correctly are welcome 🎼🎵🎶✏🗒

@tomty89
Copy link

tomty89 commented Mar 9, 2018

I already told you:

su - $2
su - $2 -c "${*:3}"`

Whether to have su variants is your choice. I don't think it's necessary coz in my experience "reverting" to normal user in proot with su is only problematic. You rarely want to do it anyway. You may as well only do the first/shell one but not the second/direct-execute one.

And this variant should be dropped totally:

/bin/$@

And please please please drop the setting of LANG (and PATH) because it prevents /etc/profile.d/locale.sh (-z $LANG) from setting it to value in /etc/locale.conf. Please get to know Arch.

@tomty89
Copy link

tomty89 commented Mar 9, 2018

The reason top worked is because it didn't take any argument, Like in my tests echo "worked" for both quoted and unquoted $@ and unquoted $*, it's just that they only print the default newline but not a b c as for quoted $*, since a b c got passed as arguments for bash instead as for echo, and eventually got silently ignored.

@tomty89
Copy link

tomty89 commented Mar 9, 2018

$ cat ../usr/bin/alarm
#!/data/data/com.termux/files/usr/bin/sh
unset LD_PRELOAD
exec proot --link2symlink -0 -b /proc -b /dev -b $ANDROID_DATA -b $EXTERNAL_STORAGE -r $HOME/../arch -w /root /usr/bin/env -i HOME=/root TERM=$TERM /usr/bin/bash -l
$ alarm
[root@localhost ~]# printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
[root@localhost ~]# printenv LANG
en_US.UTF-8
[root@localhost ~]# cat /etc/locale.conf
LANG=en_US.UTF-8
[root@localhost ~]# cat -h
cat: invalid option -- 'h'
Try 'cat --help' for more information.
[root@localhost ~]# echo 'LANG=es_ES.UTF-8' > /etc/locale.conf
[root@localhost ~]# logout
$ alarm
[root@localhost ~]# printenv LANG
es_ES.UTF-8
[root@localhost ~]# cat /etc/locale.conf
LANG=es_ES.UTF-8
[root@localhost ~]# cat -h
cat: opción inválida -- 'h'
Pruebe 'cat --help' para más información.
[root@localhost ~]#

@tomty89
Copy link

tomty89 commented Mar 9, 2018

$ cat ../usr/bin/alex
#!/data/data/com.termux/files/usr/bin/sh
unset LD_PRELOAD
exec proot --link2symlink -0 -b /proc -b /dev -b $ANDROID_DATA -b $EXTERNAL_STORAGE -r $HOME/../arch -w "$PWD" /usr/bin/env -i HOME=/root TERM=$TERM /usr/bin/bash -lc "umask $(umask); $*"
$ alex printenv LANG
en_US.UTF-8
$ alex cat /etc/locale.conf
LANG=en_US.UTF-8
$ alex cat -h
cat: invalid option -- 'h'
Try 'cat --help' for more information.
$ alex "echo 'LANG=es_ES.UTF-8' > /etc/locale.conf"
$ alex printenv LANG
es_ES.UTF-8
$ alex cat /etc/locale.conf
LANG=es_ES.UTF-8
$ alex cat -h
cat: opción inválida -- 'h'
Pruebe 'cat --help' para más información.
$ alex printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
$

@MolotovCherry
Copy link
Author

MolotovCherry commented Mar 9, 2018

@SDRausty
The new script is working perfectly, thank you very much. Here is how I've configured my scripts:

I created a helper run-arch-script.sh

if [ $# -lt 1 ]; then
    echo Usage: run-arch-script.sh /full/script/path.sh arg1 arg2
    exit
fi

startarch -c "bash $*"

In Tasker, use command
File run-arch-script.sh
Arguments /sdcard/Tasker/bin/convert-image.sh %asfile1 (script to execute, and a special variable in Tasker)

Convert-image.sh

if [ -L $0 ]; then
    cdir=$(dirname $(readlink $0))
else
    cdir=$(dirname $(realpath $0))
fi

# using other clang build so far
#unset LD_PRELOAD
#PATH=$PATH:$HOME/usr/bin
#LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/usr/lib

#compatible path with arch
f=${1/\/storage\/emulated\/0/\/sdcard}

border=15
octagon=4
fuzz=3
blur=2x20

magick \( $f +repage -bordercolor white -border 1x1 \
-fuzz $fuzz% -fill transparent -floodfill +0+0 white -shave 1x1 \
-bordercolor transparent -border ${border}x${border} \) \
\( -clone 0 -fill white -colorize 100% \) \
\( -clone 0 -alpha extract -write mpr:alpha -morphology edgeout octagon:$octagon -write mpr:edge \
mpr:alpha -fill transparent -floodfill +0+0 black \
-compose over -composite \
-fill white -floodfill +0+0 transparent -alpha off -negate \
-fill transparent -floodfill +0+0 black -write mpr:chunk \
mpr:edge -compose dst_over -composite \) \
-alpha off -compose over -composite \
\( mpr:alpha mpr:chunk -compose over -composite \
-morphology dilate octagon:$octagon  \
-blur $blur -level 50x100% \) \
-alpha off -compose copy_opacity -composite -trim  +repage \
$f.gif

touch $cdir/.done

@tomty89
Copy link

tomty89 commented Mar 9, 2018

For what is worth:

$ alarm
[root@localhost ~]# ls -ld /{,usr/}{,s}bin
lrwxrwxrwx 1 root root     7 Dec 10 14:18 /bin -> usr/bin
lrwxrwxrwx 1 root root     7 Dec 10 14:18 /sbin -> usr/bin
drwxr-xr-x 5 root root 24576 Mar  9 20:20 /usr/bin
lrwxrwxrwx 1 root root     3 Dec 10 14:18 /usr/sbin -> bin
[root@localhost ~]#

That's why PATH set by Arch includes only /usr/bin. Please get to know Arch. Just don't hardcode PATH in the proot/env command.

@SDRausty
Copy link
Owner

SDRausty commented Mar 9, 2018

startarch -r bash -lc pwd && whoami works with @ not with *.
Ditto for startarch -l e -c pwd && whoami --version.

LANG=$LANG is depreceated; So is $PATH. Awesome. Thanks for pointing out the Arch way @tomty89. This makes the proot statements leaner, nice.

@cherryleafroad I am glad to hear that the script is working for you.

@tomty89
Copy link

tomty89 commented Mar 10, 2018

Please read carefully what I told you **multiple times.

  1. Drop the -r variant, coz it sucks and is pointless. You don't want to execute Arch program without invoking a login shell.

  2. Do not expect the -l variant to accept direct execution. If you want that, implement a separate variant for it. I already told you how twice how to do that on posts above. It will be used like this startarch -x myuser echo hello world.

  3. You simply didn't notice that both of your cases didn't really work. You didn't even know how to test appropriately.

In both cases, you successfully executes Arch's pwd because it didn't take any argument. Didn't you see I test with echo a b c instead of just echo?

But you didn't got Arch's whoami executed but Termux's.

When you are passing more than just a command (multiple commands linked with &&, ; or so on; or command line involves redirection / piping), you need to quote the line anyway.

You really want to understand these:

$ bash -c echo $$ && echo $$

12943
$ bash -c 'echo $$' && echo $$
12974
12943
$ bash -c "echo $$" && echo $$
12943
12943
$ bash -c 'echo $$ && echo $$'
13033
13033
$ bash -c "echo $$ && echo $$"
12943
12943
$

Please at least get to know a bit more about bash before testing inappropriately and saying what "work" and "not work" blindly.

@tomty89
Copy link

tomty89 commented Mar 10, 2018

More fun:

$ cat meh
bash -c "$1"
bash -c "$@"
bash -c "$*"
$ ./meh whoami
u0_a292
u0_a292
u0_a292
$ ./meh whoami -h
u0_a292
u0_a292
whoami: invalid option -- 'h'
Try 'whoami --help' for more information.
$ ./meh whoami && pwd
u0_a292
u0_a292
u0_a292
/data/data/com.termux/files/home
$ echo false >> meh
$ ./meh whoami && pwd
u0_a292
u0_a292
u0_a292
$ ./meh "whoami && pwd"
u0_a292
/data/data/com.termux/files/home
u0_a292
/data/data/com.termux/files/home
u0_a292
/data/data/com.termux/files/home
$

@SDRausty
Copy link
Owner

SDRausty commented Mar 15, 2018

"The implementation of "$*" has always been a problem and realistically should have been replaced with the behavior of "$@". In almost every case where coders use "$*", they mean "$@"," from https://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html

All the exec proot invocations are in one place for study. Is there any thing else that we might want to discuss @tomty89 about Termux PRoot and how it is being called?

without invoking a login shell.

Raw is raw, complete control. Choose the desired shell and options to login. Default no options tap enter can echo usage with examples: startarch raw should be called with complete options including login shell. For example startarch raw su - newuser -c pwd && whoami after creating the user with addauser newuser.

@tomty89
Copy link

tomty89 commented Mar 15, 2018

It's pointless to quote random sources while ignoring the context.

The reason why we need "$*" intead of "$@" is because we are not passing multiple arguments as multiple arguments, but multiple arguments as single argument, which is in turn because what we are wrapping is -c of bash/su. (That's why I never told you to use "$*" for your raw variant.)

"$@" would work if you expect users to always quote the passed command line themselves, but in that case you don't even need "$@", but "$2" or so will do (which will be less confusing/misleading than "$@" for anyone who reads the script), because a quoted command line is a single argument.

"$*" allows the wrapper to work like sudo, where quoting is only needed in certain cases. (EDIT: actually this is oversimplifying, but I am not going to further explain it while you don't even understand what we are talking about)

Raw is raw, complete control. Choose the desired shell and options to login.

No. Complete control is write your own start/execute script (more of "line" actually). The raw variant you are having could only mislead people to think that it could be safely used for executing any program in Arch, while it is not because you need a login shell to set all the env vars for you (except the two that need to be hardcoded with env).

If you want non-root direct execution, write a variant for it, $2 be the username and "$3" or "${*:3}" be the command line passed.

And your "example" is still wrong. You always need to quote the command line passed to -c when it consists of more than one command, no matter if a wrapper is involved or if it uses "$@" or "$*", so it should be:

startarch raw su - newuser -c "pwd && whoami"

Otherwise you will be running pwd in Arch proot but whoami in Termux.

@SDRausty

This comment has been minimized.

@SDRausty SDRausty added repository Working with this git repository and removed repository Working with this git repository labels Sep 30, 2018
Repository owner locked as resolved and limited conversation to collaborators Jan 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants