aboutsummaryrefslogtreecommitdiff
path: root/contrib/tor-ctrl.sh
blob: e28c45d6131bcaa54802df936b3d7900c6f28b83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/bin/bash
#
# tor-ctrl is a commandline tool for executing commands on a tor server via
# the controlport.  In order to get this to work, add "ControlPort 9051" and
# "CookieAuthentication 1" to your torrc and reload tor.  Or - if you want a
# fixed password - leave out "CookieAuthentication 1" and use the following
# line to create the appropriate HashedControlPassword entry for your torrc
# (you need to change yourpassword, of course):
#
# echo "HashedControlPassword $(tor --hash-password yourpassword | tail -n 1)"
#
# tor-ctrl will return 0 if it was successful and 1 if not, 2 will be returned
# if something (telnet, xxd) is missing.  4 will be returned if it executed
# several commands from a file.
#
# For setting the bandwidth for specific times of the day, I suggest calling
# tor-ctrl via cron, e.g.:
#
# 0 22 * * * /path/to/tor-ctrl -c "SETCONF bandwidthrate=1mb"
# 0 7 * * *  /path/to/tor-ctrl -c "SETCONF bandwidthrate=100kb"
#
# This would set the bandwidth to 100kb at 07:00 and to 1mb at 22:00.  You can
# use notations like 1mb, 1kb or the number of bytes.
#
# Many, many other things are possible, see
#              http://tor.eff.org/svn/trunk/doc/spec/control-spec.txt
#
# Copyright (c) 2007 by Stefan Behte
#
# tor-ctrl is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# tor-ctrl is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with tor-ctrl; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# Written by Stefan Behte
#
# Please send bugs, comments, wishes, thanks and success stories to:
# Stefan dot Behte at gmx dot net
#
# Also have a look at my page:
# http://ge.mine.nu/
#
# 2007-10-03: First version, only changing bandwidth possible.
# 2007-10-04: Renaming to "tor-ctrl", added a lot of functions, it's now a
#             general-purpose tool.
#             Added control_auth_cookie/controlpassword auth, getopts,
#             program checks, reading from file etc.

VERSION=v1
TORCTLIP=127.0.0.1
TORCTLPORT=9051
TOR_COOKIE="/var/lib/tor/data/control_auth_cookie"
SLEEP_AFTER_CMD=1
VERBOSE=0

usage()
{
cat <<EOF

tor-ctrl $VERSION by Stefan Behte (http://ge.mine.nu)
You should have a look at 
       http://tor.eff.org/svn/trunk/doc/spec/control-spec.txt 

usage: tor-ctrl [-switch] [variable]

       [-c] [command] = command to execute
                        notice: always "quote" your command

       [-f] [file]    = file to execute commands from
                        notice: only one command per line

       [-a] [path]    = path to tor's control_auth_cookie
                        default: /var/lib/tor/data/control_auth_cookie
                        notice: do not forget to adjust your torrc

       [-s] [time]    = sleep [var] seconds after each command sent
                        default: 1 second
                        notice: for GETCONF, you can use smaller pause times
                        than for SETCONF; this is due to telnet's behaviour.

       [-p] [pwd]     = Use password [var] instead of tor's control_auth_cookie
                        default: not used
                        notice: do not forget to adjust your torrc
                                
       [-P] [port]     = Tor ControlPort
                        default: 9051

       [-v]           = verbose
                        default: not set
                        notice: the default output is the return code ;)
                        You propably want to set -v when running manually

       Examples:      $0 -c "SETCONF bandwidthrate=1mb"
                      $0 -v -c "GETINFO version"
                      $0 -v -s 0 -P 9051 -p foobar -c "GETCONF bandwidthrate"

EOF
exit 2
}

checkprogs()
{
        programs="telnet"
        if [ "$PASSWORD" = "" ]   
        then
                # you only need xxd when using control_auth_cookie
                programs="$programs xxd"
        fi

        for p in $programs
        do
                which $p &>/dev/null            # are you there?
                if [ "$?" != "0" ]
                then
                        echo "$p is missing."
                        exit 2
                fi
        done
}

sendcmd()
{
        echo "$@"
        sleep ${SLEEP_AFTER_CMD}
}

login()
{
        if [ "$PASSWORD" = "" ]
        then
                sendcmd "AUTHENTICATE $(xxd -c 32 -g 0 ${TOR_COOKIE} | awk '{print $2}')"
        else
                sendcmd "AUTHENTICATE \"${PASSWORD}\""
        fi
}

cmdpipe()
{
        login
        sendcmd "$@"
        sendcmd "QUIT"
}

vecho()
{
        if [ $VERBOSE -ge 1 ]
        then
                echo "$@"
        fi
}

myecho()
{
        STR=$(cat)
        vecho "$STR"

        echo "$STR" | if [ "$(grep -c ^"250 ")" = 3 ]
        then
                exit 0
        else
                exit 1
        fi
}

filepipe()
{
        login
        cat "$1" | while read line
        do
                sendcmd "$line"
        done
        sendcmd "QUIT"
}

while getopts ":a:c:s:p:P:f:vh" Option
do
        case $Option in
                a) TOR_COOKIE="${OPTARG}";;
                c) CMD="${OPTARG}";;
                s) SLEEP_AFTER_CMD="${OPTARG}";;
                p) PASSWORD="${OPTARG}";;
                P) TORCTLPORT="${OPTARG}";;
                f) FILE="${OPTARG}";;
                v) VERBOSE=1;;
                h) usage;;
                *) usage;;
        esac
done

if [ -e "$FILE" ]
then
        checkprogs
        filepipe "$FILE" | telnet $TORCTLIP $TORCTLPORT 2>/dev/null | myecho
        exit 4
fi

if [ "$CMD" != "" ]
then
        checkprogs
        cmdpipe $CMD | telnet $TORCTLIP $TORCTLPORT 2>/dev/null | myecho
else
        usage
fi