Android端末のProxy設定（未解決）

#キッカケ
Android端末に自動でproxy設定を行いたい。少なくとも、http-proxyのアドレスを自動で振ってやって、有効にするプログラムを書きたいので、Proxyの設定を調べてみた。（Androidアプリケーションを使って設定なんて皆やるのでadbフル活用で書きたい。）

wifiの状態を獲得するコマンドが`adb shell dumpsys wifi`でproxyの設定状態を取得できる。


###基本:wifi選択画面から設定する方法
簡単。設定すると、Android標準ブラウザの通信にhttp-proxyが入る。ただし、設定値がadb shell経由で取れるか調べてない。


```adb_logcat.log
D/WifiConfigStore(  448): proxy changed SSID = "hogehoge"
D/WifiConfigStore(  448): proxy changed SSID = "hogehoge"
D/WifiConfigStore(  448):  proxyProperties: [192.168.11.3] 8118 xl=
```



###基本2:ProxyDroidで設定する方法
簡単。Root化済みの端末にProxyDroid入れて設定する。しかし、ProxyDroidから設定した場合、`adb shell`から設定値が見えない。

###試行:Androidのshellからsetporpで設定する方法
これもGoogle先生に聞くとでてくる。しかし、JellyBeans(4.2.2)だとどうも上手くいかない。
`adb shell setporp http-proxy http://<porxy-server>:<port>`

[How to Use Proxy to Access Network in Android](https://community.freescale.com/docs/DOC-93581)によれば開発コードによって方法が違うらしい。
Gingerbread(2.3.x)は以下の通り。

```
1. Enable http proxy
>  sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure VALUES (99, 'http_proxy', 'wwwgate0.freescale.net:1080');"
 
With this setting, you can access network for web browsing.
 
If you want to play some http streaming content, you need to set a property for the player,
> setprop rw.HTTP_PROXY http://wwwgate0-az.freescale.net:1080
 
2. Disable http proxy
>  sqlite3 /data/data/com.android.providers.settings/databases/settings.db "delete from secure where name='http_proxy'"
>  setprop rw.HTTP_PROXY ""
```

ICS(Ice Cream Sandwith:4.0.x)は以下の通り。

```
1. Enable http proxy
>  setprop net.proxy wwwgate0-az.freescale.net:1080
 
With this setting, you can access network for web browsing.
 
If you want to play some http streaming content, you need to set a proxy property for the player,
>  setprop rw.HTTP_PROXY http://wwwgate0-az.freescale.net:1080
 
2. Disable http proxy
>  setprop net.proxy ""
>  setprop rw.HTTP_PROXY ""
```

私が使っているOSは4.2.2なので、Jelly Beans(4.1.x,4.2.x,4.3)を調べるが特に言及されてないので、Gingerbread(2.3.x)の方法を試す。`sqlite3 /data/data/com.android.providers.settings/databases/settings.db`から、直にSettingの値を変えてるのではないか、と思う。

設定を変える前に、JellyBeansにsqlite3をインストールする。
1.[sqlite3](http://www.zois.co.uk/dl/sqlite3) をダウンロードする。
2.端末をUSB接続して、ダウンロードしたコマンドをSDカードに転送する。
`adb push sqlite3 /mnt/sdcard`
3.sqlite3を/system/xbin/下に置く。

```
>adb shell
shell@android:/ $ su
shell@android:/ # mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
shell@android:/ # cp /mnt/sdcard/sqlite3 /system/xbin/sqlite3
shell@android:/ # chmod 777 /system/xbin/sqlite3
shell@android:/ # mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system
shell@android:/ # sqlite3
```

その後、
`sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO secure VALUES (99, 'http_proxy', 'http-server:port');"`を実行する。

何してたかというと、com.android.proviers.settingのhttp_proxyの値を直接変更していた。公式ドキュメントでは、
>public static final String HTTP_PROXY
Added in API level 3
This constant was deprecated in API level 17.
Use HTTP_PROXY
Host name and port for global http proxy. Uses ':' seperator for between host and port.
Constant Value: "http_proxy"

とある。しかし、この方法では有効にならなかった。

ProxyDroidを有効にしたときに出力されるログを見ると、

```ProxyDroid.log
D/ProxyDroidService( 4388): Service Start
D/ProxyDroidService( 4388): Proxy: 192.168.11.3
D/ProxyDroidService( 4388): Local Port: 8118
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/iptables
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/redsocks
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/proxy.sh
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/cntlm
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/stunnel
D/ProxyDroid( 4388): chmod 700 /data/data/org.proxydroid/shrpx
D/ProxyDroid( 4388): Connecting start
D/ProxyDroid( 4388): /data/data/org.proxydroid/proxy.sh start http 192.168.11.3 8118 false "" ""
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp -d 192.168.11.5 -j RETURN
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to 8123
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to 8124
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -A OUTPUT -p tcp --dport 5228 -j REDIRECT --to 8124
D/ProxyDroid( 4388): Connecting finish
D/ProxyDroid( 4388): /data/data/org.proxydroid/iptables -t nat -F OUTPUT
D/ProxyDroid( 4388): /data/data/org.proxydroid/proxy.sh stop
```
とあって、直接settingするというよりも、iptablesを設定している模様。iptablesをadb shell経由で設定すれば、できるのかな。

手動でlogcatに出てきたログを実行すると、
`protoent* getprotobyname(char const*)(3) is not implemented on Android`
というエラーが出てきた。


前述のログから、設定前に`/data/data/org.proxydroid/proxy.sh start http 192.168.11.3 8118`を行ってるから、proxy.shのコードを読み変える読む。

```proxy.sh
#!/system/bin/sh

DIR=/data/data/org.proxydroid
type=$2　=http
host=$3  =192.168.11.3
port=$4  =8118
auth=$5  =false
user=$6  =""
pass=$7  =""
($1=start)

PATH=$DIR:$PATH

case $1 in
 start)

echo "
base {
 log_debug = off;
 log_info = off;
 log = stderr;
 daemon = on;
 redirector = iptables;
}
" >$DIR/redsocks.conf

 case $type in
  http)
 case $auth in
  true)
  echo "
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8123;
 ip = $host;
 port = $port;
 type = http-relay;
 login = \"$user\";
 password = \"$pass\";
} 
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8124;
 ip = $host;
 port = $port;
 type = http-connect;
 login = \"$user\";
 password = \"$pass\";
} 
" >>$DIR/redsocks.conf
   ;;
<-- 今回はここ以下の設定 -->
   false) 
   echo "
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8123;
 ip = $host;
 port = $port;
 type = http-relay;
} 
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8124;
 ip = $host;
 port = $port;
 type = http-connect;
} 
 " >>$DIR/redsocks.conf
   ;;
 esac
   ;; 　
<-- 今回はここまでの設定 -->
  socks5)
   case $auth in
  true)
    echo "
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8123;
 ip = $host;
 port = $port;
 type = socks5;
 login = \"$user\";
 password = \"$pass\";
 }
 " >>$DIR/redsocks.conf
   ;;
<-- 今回はここ以下の設定 -->
 false)
  echo "
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8123;
 ip = $host;
 port = $port;
 type = socks5;
 }
 " >>$DIR/redsocks.conf
   ;;
 esac
 ;;
<-- 今回はここまでの設定 -->
   socks4)
   case $auth in
  true)
    echo "
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8123;
 ip = $host;
 port = $port;
 type = socks4;
 login = \"$user\";
 password = \"$pass\";
 }
 " >>$DIR/redsocks.conf
   ;;
<-- 今回はここ以下の設定 -->
 false)
  echo "
redsocks {
 local_ip = 127.0.0.1;
 local_port = 8123;
 ip = $host;
 port = $port;
 type = socks4;
 }
 " >>$DIR/redsocks.conf
   ;;
<-- 今回はここまでの設定 -->
 esac
 ;;
 esac

 $DIR/redsocks -p $DIR/redsocks.pid -c $DIR/redsocks.conf
 ;;
stop)

  killall -9 redsocks
  killall -9 cntlm
  killall -9 stunnel
  killall -9 tproxy
  
  kill -9 `cat $DIR/redsocks.pid`
  
  rm $DIR/redsocks.pid
  
  rm $DIR/redsocks.conf
esac
```

resocksのファイルタイプは
`redsocks: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), stripped`

どっちにせよ、redsocks.confを調べないとわからない。
ProxyDroidを見る限りだと、proxy設定はデフォルトのandroidでは難しそう。。



###参考
[Android 端末上で透過型プロキシを動かしてみる 〜 VPN のように使えて、しかも省電力](http://www.gcd.org/blog/2011/06/806/)
[WiFi接続とHTTP-Proxyを取り巻く状況まとめ(2011-05現在)](http://www.glamenv-septzen.net/view/966#idbb9232)
[Root for Android](https://sites.google.com/site/root4android/)
[脳みそタンス](https://sites.google.com/site/umibenojinjin/home/android)