Lines 3-496
Link Here
|
3 |
# $FreeBSD: /tmp/pcvs/ports/sysutils/bsdstats/files/300.statistics.in,v 1.45 2011-09-25 21:35:26 eadler Exp $ |
3 |
# $FreeBSD: /tmp/pcvs/ports/sysutils/bsdstats/files/300.statistics.in,v 1.45 2011-09-25 21:35:26 eadler Exp $ |
4 |
# |
4 |
# |
5 |
|
5 |
|
|
|
6 |
# |
7 |
# options |
8 |
# |
9 |
CURR_VERSION="%%VERSION%%" |
10 |
USE_TOR=NO |
11 |
DO_LOG_NET_TRAFFIC=0 |
12 |
|
13 |
# |
14 |
# Standard commands used here |
15 |
# |
16 |
PCICONF=/usr/sbin/pciconf |
17 |
UNAME=/usr/bin/uname |
18 |
UMASK=/usr/bin/umask |
19 |
SYSCTL=/sbin/sysctl |
20 |
AWK=/usr/bin/awk |
21 |
SED=/usr/bin/sed |
22 |
CUT=/usr/bin/cut |
23 |
JOT=/usr/bin/jot |
24 |
SLEEP=/bin/sleep |
25 |
CHMOD=/bin/chmod |
26 |
WC=/usr/bin/wc |
27 |
MV=/bin/mv |
28 |
RM=/bin/rm |
29 |
case $(${UNAME}) in |
30 |
FreeBSD) |
31 |
OPENSSL=/usr/bin/openssl |
32 |
CHOWN=/usr/sbin/chown |
33 |
NC=/usr/bin/nc |
34 |
;; |
35 |
OpenBSD) |
36 |
OPENSSL=/usr/sbin/openssl |
37 |
CHOWN=/sbin/chown |
38 |
NC=/usr/bin/nc |
39 |
;; |
40 |
DragonFly) |
41 |
OPENSSL=/usr/bin/openssl |
42 |
CHOWN=/usr/sbin/chown |
43 |
NC=/usr/local/bin/netcat |
44 |
;; |
45 |
*) |
46 |
OPENSSL=/usr/bin/openssl |
47 |
CHOWN=/usr/sbin/chown |
48 |
NC=/usr/bin/nc |
49 |
;; |
50 |
esac |
51 |
|
52 |
# |
53 |
# constants |
54 |
# |
55 |
CR=$'\r' |
56 |
NL=$'\n' |
57 |
|
58 |
# |
6 |
# If there is a global system configuration file, suck it in. |
59 |
# If there is a global system configuration file, suck it in. |
7 |
# |
60 |
# |
8 |
if [ -r /etc/defaults/periodic.conf ] |
61 |
if [ -r /etc/defaults/periodic.conf ]; then |
9 |
then |
62 |
. /etc/defaults/periodic.conf |
10 |
. /etc/defaults/periodic.conf |
63 |
source_periodic_confs |
11 |
source_periodic_confs |
64 |
periodic_conf=/etc/periodic.conf |
12 |
periodic_conf=/etc/periodic.conf |
|
|
13 |
else |
65 |
else |
14 |
. /etc/rc.conf # For systems without periodic.conf, use rc.conf |
66 |
. /etc/rc.conf # For systems without periodic.conf, use rc.conf |
15 |
if [ -r /etc/rc.conf.local ] |
67 |
if [ -r /etc/rc.conf.local ]; then |
16 |
then |
68 |
. /etc/rc.conf.local |
17 |
. /etc/rc.conf.local |
69 |
fi |
18 |
fi |
70 |
periodic_conf=/etc/rc.conf.local |
19 |
periodic_conf=/etc/rc.conf.local |
|
|
20 |
fi |
71 |
fi |
21 |
|
72 |
|
22 |
oldmask=$(umask) |
73 |
# |
23 |
umask 066 |
74 |
# global values |
24 |
timeout=10 |
75 |
# |
25 |
|
|
|
26 |
version="5.5" |
27 |
checkin_server=${monthly_statistics_checkin_server:-"rpt.bsdstats.org"} |
76 |
checkin_server=${monthly_statistics_checkin_server:-"rpt.bsdstats.org"} |
28 |
bsdstats_log=${monthly_statistics_logfile:-"/var/log/bsdstats"} |
77 |
bsdstats_log=${monthly_statistics_logfile:-"/var/log/bsdstats"} |
29 |
id_token_file='/var/db/bsdstats' |
78 |
id_token_file='/var/db/bsdstats' |
|
|
79 |
checkin_server_description=${checkin_server} |
80 |
nc_host=${checkin_server} |
81 |
nc_port=80 |
82 |
http_header_proxy_auth="" |
30 |
|
83 |
|
31 |
PATH=/sbin:/bin:/usr/sbin:/usr/bin:%%PREFIX%%/sbin:%%PREFIX%%/bin |
|
|
32 |
export PATH |
33 |
|
84 |
|
34 |
unset HTTP_USER_AGENT |
85 |
oldmask=$(${UMASK}) |
|
|
86 |
${UMASK} 066 |
87 |
timeout=10 |
35 |
|
88 |
|
36 |
IFS=" |
89 |
## |
37 |
" |
90 |
## Procedures |
|
|
91 |
## |
92 |
|
93 |
echo_begin() { |
94 |
echo -n "$1 ... " |
95 |
} |
38 |
|
96 |
|
39 |
random () { |
97 |
echo_end_success() { |
40 |
jot -r 1 0 900 |
98 |
echo "SUCCESS" |
41 |
} |
99 |
} |
42 |
|
100 |
|
43 |
# RFC 2396 |
101 |
echo_err() { |
44 |
uri_escape () { |
102 |
echo "$1" >&2 |
45 |
echo ${1+$@} | sed -e ' |
103 |
} |
46 |
s/%/%25/g |
104 |
|
47 |
s/;/%3b/g |
105 |
log() { # log(categ,msg) |
48 |
s,/,%2f,g |
106 |
echo "[`date "+%Y-%m-%d %H:%M:%S"`] $1 $2" >> $bsdstats_log |
49 |
s/?/%3f/g |
107 |
} |
50 |
s/:/%3a/g |
108 |
|
51 |
s/@/%40/g |
109 |
fail() { # fail(msg): argument is simple user-level message, detailed log message is assumed to be printed before 'fail' invokation |
52 |
s/&/%26/g |
110 |
# log error |
53 |
s/=/%3d/g |
111 |
log "TERM" "$1 (failure)" |
54 |
s/+/%2b/g |
112 |
# let user know |
55 |
s/\$/%24/g |
113 |
echo_err "BSDstats failed: $1" |
56 |
s/,/%2c/g |
114 |
# bail out |
57 |
s/ /%20/g |
115 |
${UMASK} $oldmask |
58 |
' |
116 |
exit 1 |
59 |
} |
117 |
} |
60 |
|
118 |
|
61 |
do_fetch () { |
119 |
random() { |
62 |
url="http://$checkin_server/scripts/$1" |
120 |
${JOT} -r 1 0 900 |
63 |
case $(uname) in |
121 |
} |
64 |
FreeBSD ) |
122 |
|
65 |
/usr/bin/fetch -T "$timeout" -q -o - "$url" |
123 |
nlog() { |
66 |
;; |
124 |
if [ $DO_LOG_NET_TRAFFIC -eq 1 ]; then |
67 |
* ) |
125 |
echo "--$(date)--" >> /tmp/bsdstats.$1.log |
68 |
/usr/bin/ftp -q "$timeout" -V -o - "$url" |
126 |
tee -a /tmp/bsdstats.$1.log |
69 |
;; |
127 |
else |
70 |
esac |
128 |
cat |
71 |
} |
129 |
fi |
72 |
|
130 |
} |
73 |
check_dns () { |
131 |
|
74 |
if [ `%%DIG%% bsdstats.org txt | grep TXT | grep UP | wc -l` = 0 ] |
132 |
# do_http_request: if success returns 0, and prints http.body, otherwise returns 1 |
75 |
then |
133 |
do_http_request() { |
76 |
echo "DNS not reachable, Network Down?" |
134 |
local meth="$1" |
77 |
exit |
135 |
local url="$2" |
78 |
fi |
136 |
local body="$3" |
79 |
} |
137 |
local content_type="$4" |
80 |
|
138 |
local do_log="$5" |
81 |
send_devices () { |
139 |
|
82 |
case $(uname) in |
140 |
local resp |
83 |
FreeBSD ) |
141 |
local lineno |
84 |
for line in `/usr/sbin/pciconf -l` |
142 |
local in_header |
85 |
do |
143 |
local result_count |
86 |
DRIVER=`echo $line | awk -F\@ '{print $1}'` |
144 |
|
87 |
DEV=`echo $line | awk '{print $4}' | cut -c8-15` |
145 |
if [ -n "${HTTP_PROXY}" ]; then url="http://${checkin_server}${url}"; fi |
88 |
CLASS=`echo $line | awk '{print $2}' | cut -c9-14` |
146 |
|
89 |
query_string=$query_string`echo \&dev[]=$DRIVER:$DEV:$CLASS` |
147 |
local txt="${meth} ${url} HTTP/1.0" |
90 |
done |
148 |
local http_req="${txt}" |
91 |
|
149 |
txt="${txt}${CR}${NL}Host: ${checkin_server}" |
92 |
report_devices |
150 |
if [ -n "${http_header_proxy_auth}" ]; then txt="${txt}${CR}${NL}Proxy-Authorization: ${http_header_proxy_auth}"; fi |
93 |
;; |
151 |
txt="${txt}${CR}${NL}User-Agent: bsdstats-${CURR_VERSION}" |
94 |
* ) |
152 |
txt="${txt}${CR}${NL}Connection: close" |
95 |
# Not supported |
153 |
if [ -n "${content_type}" ]; then txt="${txt}${NL}Content-Type: ${content_type}"; fi |
96 |
;; |
154 |
if [ -n "${body}" ]; then txt="${txt}${CR}${NL}Content-Length: ${#body}"; fi |
97 |
esac |
155 |
txt="${txt}${CR}${NL}${CR}${NL}${body}" |
98 |
} |
156 |
|
99 |
|
157 |
resp=$(echo "${txt}" | nlog "in" | ${NC} ${nc_host} ${nc_port} | nlog "out" 2>/dev/null) |
100 |
send_ports () { |
158 |
if [ $? -ne 0 ]; then |
101 |
case $(uname) in |
159 |
if [ ${do_log} -ne 0 ]; then |
102 |
FreeBSD ) |
160 |
log "FAIL" "Failed to send data to the host ${nc_host}:${nc_port}, is network or host down?" |
103 |
|
161 |
fi |
104 |
############################################################################ |
162 |
return 1 |
105 |
# At the time of this writing (2012-07-24), FreeBSD is switching from |
163 |
fi |
106 |
# pkg_* tools to pkgng. Starting in FreeBSD 9.1, pkgng will become the |
164 |
|
107 |
# default tool for package management. |
165 |
local IFS=${NL}${CR} |
108 |
# |
166 |
lineno=0 |
109 |
# Until pkg_* tools are officially declared unsupported, they will need |
167 |
in_header=1 |
110 |
# legacy support in ports like this one. When the need for this support is |
168 |
http_result="" |
111 |
# officially discontinued, please do the following: |
169 |
for str in ${resp}; do |
112 |
# |
170 |
if [ $lineno -eq 0 ] ; then |
113 |
# 1. Delete the contents of this "LEGACY" section: |
171 |
if expr "${str}" : "^HTTP/1\.[01] 200 OK$" > /dev/null; then |
114 |
# |
172 |
# ok |
115 |
#-----BEGIN LEGACY----- |
173 |
true |
116 |
# Detect pkgng |
174 |
else |
117 |
if [ -e /var/db/pkg/local.sqlite ]; then |
175 |
if [ ${do_log} -ne 0 ]; then |
118 |
|
176 |
log "FAIL" "Failed HTTP query: request='${http_req}' -> response='${str}'" |
119 |
# Use pkgng |
177 |
fi |
120 |
|
178 |
return 2 |
121 |
for line in `pkg info | awk '{ print $1 }'` |
179 |
fi |
122 |
do |
180 |
elif [ $lineno -ge 1 -a $in_header -eq 1 ] ; then |
123 |
category=`pkg info -q -o ${line} | sed 's/\/.*//g'` |
181 |
if [ -z "${str}" ]; then |
124 |
line=$(uri_escape $line) |
182 |
in_header=0 |
125 |
category=$(uri_escape $category) |
183 |
result_count=0 |
126 |
query_string=$query_string`echo \&port[]=${category}:${line}` |
184 |
fi |
127 |
done |
185 |
else |
128 |
|
186 |
if [ $result_count -eq 0 ]; then |
129 |
else |
187 |
http_result="${str}" |
130 |
|
188 |
else |
131 |
# Use pkg_* tools |
189 |
http_result="${http_result}${NL}${str}" |
132 |
|
|
|
133 |
for line in `pkg_info | awk '{ print $1 }'` |
134 |
do |
135 |
category=`grep "@comment ORIGIN" /var/db/pkg/${line}/+CONTENTS | sed -E 's/^\@comment ORIGIN:(.+)\/.+/\1/g'` |
136 |
line=$(uri_escape $line) |
137 |
category=$(uri_escape $category) |
138 |
query_string=$query_string`echo \&port[]=${category}:${line}` |
139 |
done |
140 |
|
141 |
fi |
142 |
#-----END LEGACY----- |
143 |
# |
144 |
# 2. Uncomment the contents of this "PKGNG" section: |
145 |
# |
146 |
#-----BEGIN PKGNG----- |
147 |
# for line in `pkg info | awk '{ print $1 }'` |
148 |
# do |
149 |
# category=`pkg info -q -o ${line} | sed 's/\/.*//g'` |
150 |
# line=$(uri_escape $line) |
151 |
# category=$(uri_escape $category) |
152 |
# query_string=$query_string`echo \&port[]=${category}:${line}` |
153 |
# done |
154 |
#-----END PKGNG----- |
155 |
# |
156 |
# 3. Delete these comments. |
157 |
# |
158 |
# Thank you! |
159 |
############################################################################ |
160 |
|
161 |
report_ports |
162 |
;; |
163 |
* ) |
164 |
# Not supported |
165 |
;; |
166 |
esac |
167 |
} |
168 |
|
169 |
report_ports () { |
170 |
# Handle HTTP proxy services |
171 |
# |
172 |
# HTTP_PROXY/http_proxy can take the following form: |
173 |
# [http://][username:password@]proxy[:port][/] |
174 |
# Authentication details may also be provided via HTTP_PROXY_AUTH: |
175 |
# HTTP_PROXY_AUTH="basic:*:username:password" |
176 |
# |
177 |
|
178 |
if [ -z "$HTTP_PROXY" -a -n "$http_proxy" ]; then |
179 |
HTTP_PROXY=$http_proxy |
180 |
fi |
181 |
if [ -n "$HTTP_PROXY" ]; then |
182 |
# Attempt to resolve any HTTP authentication |
183 |
if [ -n "$HTTP_PROXY_AUTH" ]; then |
184 |
PROXY_AUTH_USER=`echo $HTTP_PROXY_AUTH | sed -E 's/^.+:\*:(.+):.+$/\1/g'` |
185 |
PROXY_AUTH_PASS=`echo $HTTP_PROXY_AUTH | sed -E 's/^.+:\*:.+:(.+)$/\1/g'` |
186 |
else |
187 |
# Check for authentication within HTTP_PROXY |
188 |
HAS_HTTP_AUTH=`echo $HTTP_PROXY | sed -E 's/^(http:\/\/)?(.+:.+@)?.+/\2/'` |
189 |
if [ -n "$HAS_HTTP_AUTH" ]; then |
190 |
# Found HTTP authentication details |
191 |
PROXY_AUTH_USER=`echo $HAS_HTTP_AUTH | cut -d: -f1` |
192 |
PROXY_AUTH_PASS=`echo $HAS_HTTP_AUTH | cut -d: -f2` |
193 |
fi |
194 |
fi |
195 |
|
196 |
# Determine the proxy components |
197 |
PROXY_HOST=`echo $HTTP_PROXY | sed -E 's/^(http:\/\/)?(.+:.+@)?([^@:]+)(:.+)?/\3/'` |
198 |
PROXY_PORT=`echo $HTTP_PROXY | sed -E 's/^(http:\/\/)?(.+:.+@)?(.+):([0-9]+)/\4/' | sed -e 's/[^0-9]//g'` |
199 |
if [ -z "$PROXY_PORT" ]; then |
200 |
# Use default proxy port |
201 |
PROXY_PORT=3128 |
202 |
fi |
203 |
fi |
204 |
|
205 |
# Determine the host/port netcat should connect to |
206 |
if [ -n "$PROXY_HOST" -a -n "$PROXY_PORT" ]; then |
207 |
nc_host=$PROXY_HOST |
208 |
nc_port=$PROXY_PORT |
209 |
url_prefix="http://${checkin_server}" |
210 |
else |
211 |
nc_host=$checkin_server |
212 |
nc_port=80 |
213 |
fi |
214 |
|
215 |
# Proxy authentication, if required |
216 |
if [ -n "$PROXY_AUTH_USER" -a -n "$PROXY_AUTH_PASS" ]; then |
217 |
auth_base64=`echo "$PROXY_AUTH_USER:$PROXY_AUTH_PASS" | openssl base64` |
218 |
proxy_auth="Proxy-Authorization: Basic $auth_base64 |
219 |
" |
220 |
fi |
221 |
|
222 |
|
223 |
# Make the request |
224 |
string_length=`echo ${query_string} | wc -m` |
225 |
string_length=$((string_length - 1)) |
226 |
|
227 |
echo "POST ${url_prefix}/scripts/report_ports.php HTTP/1.0 |
228 |
Host: ${checkin_server} |
229 |
User-Agent: bsdstats ${version} |
230 |
Connection: close |
231 |
${proxy_auth}Content-Type: application/x-www-form-urlencoded |
232 |
Content-Length: ${string_length} |
233 |
|
234 |
token=${TOKEN}&key=${KEY}${query_string}" | \ |
235 |
nc $nc_host $nc_port | \ |
236 |
grep STATUS= | { |
237 |
local IFS |
238 |
IFS='= |
239 |
' |
240 |
|
241 |
while read var val |
242 |
do |
243 |
case $var in |
244 |
STATUS) |
245 |
if [ $val = "OK" ] |
246 |
then |
247 |
echo "[`date`] System Ports reported" |
248 |
else |
249 |
echo "[`date`] System Ports not reported, exiting" |
250 |
exit |
251 |
fi |
252 |
;; |
253 |
*) |
254 |
echo "[`date`] Error with fetch to server" |
255 |
exit |
256 |
;; |
257 |
esac |
258 |
done |
259 |
} >> $bsdstats_log |
260 |
|
261 |
} |
262 |
|
263 |
report_devices () { |
264 |
do_fetch report_devices.php?token=$TOKEN\&key=$KEY$query_string | { |
265 |
local IFS |
266 |
IFS='= |
267 |
' |
268 |
|
269 |
while read var val |
270 |
do |
271 |
case $var in |
272 |
STATUS) |
273 |
if [ $val = "OK" ] |
274 |
then |
275 |
echo "[`date`] System Devices reported" |
276 |
else |
277 |
echo "[`date`] System Devices not reported, exiting" |
278 |
exit |
279 |
fi |
280 |
;; |
281 |
*) |
282 |
echo "[`date`] Error with fetch to server" |
283 |
exit |
284 |
;; |
285 |
esac |
286 |
done |
287 |
} >> $bsdstats_log |
288 |
} |
289 |
|
290 |
get_id_token () { |
291 |
if [ -f $id_token_file ] |
292 |
then |
293 |
if [ `wc -l < $id_token_file` -lt 3 ] |
294 |
then |
295 |
rm $id_token_file |
296 |
fi |
190 |
fi |
|
|
191 |
result_count=$(($result_count+1)) |
297 |
fi |
192 |
fi |
|
|
193 |
lineno=$(($lineno+1)) |
194 |
done |
195 |
echo "${http_result}" |
196 |
return 0 |
197 |
} |
198 |
|
199 |
extract_field() { |
200 |
# charset of the value, besides alnum covers base64 encoding charset (/+), and single quote |
201 |
echo "$1" | grep "^${2}=" | tail -1 | sed -E -e "s/^${2}=([a-zA-Z0-9=/+']+).*/\1/g" |
202 |
} |
203 |
|
204 |
do_http_request_check_status() { |
205 |
local body |
206 |
local status |
207 |
local what="$5" |
208 |
# run request |
209 |
body=$(do_http_request "$1" "$2" "$3" "$4" 1) |
210 |
if [ $? -ne 0 ]; then |
211 |
fail "HTTP query failed during ${what}" |
212 |
fi |
213 |
# check status |
214 |
status=$(extract_field "${body}" "STATUS") |
215 |
case "${status}" in |
216 |
OK) |
217 |
# pass |
218 |
true |
219 |
;; |
220 |
FAIL) |
221 |
log "FAIL" "Got STATUS=FAIL from the server in during ${what}" |
222 |
fail "${what} request failed" |
223 |
;; |
224 |
*) |
225 |
fail "Server didn't return the status for ${what}" |
226 |
;; |
227 |
esac |
228 |
} |
298 |
|
229 |
|
299 |
if [ ! -f $id_token_file -o ! -s $id_token_file ] ; |
230 |
uri_escape() { |
300 |
then |
231 |
# RFC 2396 |
301 |
IDTOKEN=$(uri_escape $( openssl rand -base64 32 ) ) |
232 |
echo "${1+$@}" | ${SED} -e ' |
302 |
|
233 |
s/%/%25/g |
303 |
idf=$( mktemp "$id_token_file.XXXXXX" ) && \ |
234 |
s/;/%3b/g |
304 |
chown root:wheel $idf && \ |
235 |
s,/,%2f,g |
305 |
chmod 600 $idf |
236 |
s/?/%3f/g |
306 |
|
237 |
s/:/%3a/g |
307 |
do_fetch getid.php?key=$IDTOKEN | { |
238 |
s/@/%40/g |
308 |
local IFS |
239 |
s/&/%26/g |
309 |
IFS='= |
240 |
s/=/%3d/g |
310 |
' |
241 |
s/+/%2b/g |
311 |
|
242 |
s/\$/%24/g |
312 |
while read var val |
243 |
s/,/%2c/g |
313 |
do |
244 |
s/ /%20/g |
314 |
case $var in |
245 |
' |
315 |
KEY) |
|
|
316 |
echo "KEY=$val" |
317 |
;; |
318 |
TOKEN) |
319 |
echo "TOKEN=$val" |
320 |
;; |
321 |
*) |
322 |
;; |
323 |
esac |
324 |
done |
325 |
echo "VERSION=$version" |
326 |
} > $idf && \ |
327 |
|
328 |
mv $idf $id_token_file |
329 |
if [ ! -s $id_token_file ] ; |
330 |
then |
331 |
echo "Nothing returned from $checkin_server" |
332 |
exit 1 |
333 |
fi |
334 |
fi |
335 |
. $id_token_file |
336 |
KEY=$( uri_escape $KEY ) |
337 |
TOKEN=$( uri_escape $TOKEN ) |
338 |
} |
339 |
|
340 |
|
341 |
enable_token () { |
342 |
do_fetch enable_token.php?key=$TOKEN\&token=$KEY | { |
343 |
local IFS |
344 |
IFS='= |
345 |
' |
346 |
|
347 |
while read var val |
348 |
do |
349 |
case $var in |
350 |
STATUS) |
351 |
if [ $val = "OK" ] |
352 |
then |
353 |
echo "[`date`] System enabled" |
354 |
else |
355 |
echo "[`date`] System not enabled, exiting" |
356 |
exit |
357 |
fi |
358 |
;; |
359 |
*) |
360 |
echo "[`date`] Error with fetch to server" |
361 |
exit |
362 |
;; |
363 |
esac |
364 |
done |
365 |
} >> $bsdstats_log |
366 |
} |
367 |
|
368 |
disable_token () { |
369 |
do_fetch disable_token.php?key=$TOKEN\&token=$KEY | { |
370 |
local IFS |
371 |
IFS='= |
372 |
' |
373 |
|
374 |
while read var val |
375 |
do |
376 |
case $var in |
377 |
STATUS) |
378 |
if [ $val = "OK" ] |
379 |
then |
380 |
echo "[`date`] System disabled" |
381 |
else |
382 |
echo "[`date`] System not disabled, exiting" |
383 |
exit |
384 |
fi |
385 |
;; |
386 |
*) |
387 |
echo "[`date`] Error with fetch to server" |
388 |
exit |
389 |
;; |
390 |
esac |
391 |
done |
392 |
} >> $bsdstats_log |
393 |
} |
394 |
|
395 |
report_system () { |
396 |
do_fetch report_system.php?token=$TOKEN\&key=$KEY\&rel=$REL\&arch=$ARCH\&opsys=$OS | { |
397 |
local IFS |
398 |
IFS='= |
399 |
' |
400 |
|
401 |
while read var val |
402 |
do |
403 |
case $var in |
404 |
STATUS) |
405 |
if [ $val = "OK" ] |
406 |
then |
407 |
echo "[`date`] System reported" |
408 |
else |
409 |
echo "[`date`] System report failed, exiting" |
410 |
exit |
411 |
fi |
412 |
;; |
413 |
*) |
414 |
echo "[`date`] Error with fetch to server" |
415 |
exit |
416 |
;; |
417 |
esac |
418 |
done |
419 |
} >> $bsdstats_log |
420 |
} |
421 |
|
422 |
report_cpu () { |
423 |
do_fetch report_cpu.php?token=$TOKEN\&key=$KEY\&cpus=$count\&vendor=$VEN\&cpu_type=$DEV | { |
424 |
local IFS |
425 |
IFS='= |
426 |
' |
427 |
|
428 |
while read var val |
429 |
do |
430 |
case $var in |
431 |
STATUS) |
432 |
if [ $val = "OK" ] |
433 |
then |
434 |
echo "[`date`] System CPU reported" |
435 |
else |
436 |
echo "[`date`] System CPU report failed, exiting" |
437 |
exit |
438 |
fi |
439 |
;; |
440 |
*) |
441 |
echo "[`date`] Error with fetch to server" |
442 |
exit |
443 |
;; |
444 |
esac |
445 |
done |
446 |
} >> $bsdstats_log |
447 |
} |
246 |
} |
448 |
case "$monthly_statistics_enable" in |
247 |
|
449 |
[Yy][Ee][Ss]) |
248 |
parse_http_proxy_string() { |
450 |
check_dns |
249 |
# Handle HTTP proxy services |
451 |
REL=`/usr/bin/uname -r` |
250 |
# |
452 |
ARCH=`/usr/bin/uname -m` |
251 |
# HTTP_PROXY/http_proxy can take the following form: |
453 |
OS=`/usr/bin/uname -s` |
252 |
# [http://][username:password@]proxy[:port][/] |
454 |
get_id_token |
253 |
# Authentication details may also be provided via HTTP_PROXY_AUTH: |
455 |
test X"$1" = X-nodelay || sleep `random` |
254 |
# HTTP_PROXY_AUTH="basic:*:username:password" |
456 |
enable_token |
255 |
# |
457 |
report_system |
256 |
# IN: * HTTP_PROXY or http_proxy |
458 |
echo "Posting monthly OS statistics to $checkin_server" |
257 |
# IN: * HTTP_PROXY_AUTH |
459 |
if [ X"$1" != X-nodelay ]; then |
258 |
# OUT: * http_header_proxy_auth |
460 |
case "$monthly_statistics_report_devices" in |
259 |
# OUT: * nc_host |
461 |
[Yy][Ee][Ss]) |
260 |
# OUT: * nc_port |
462 |
send_devices |
261 |
|
463 |
echo "Posting monthly device statistics to $checkin_server" |
262 |
local PROXY_AUTH_USER |
464 |
line=$( sysctl -n hw.model ) |
263 |
local PROXY_AUTH_PASS |
465 |
VEN=$( echo $line | cut -d ' ' -f 1 ) |
264 |
local PROXY_HOST |
466 |
DEV=$( uri_escape $( echo $line | cut -d ' ' -f 2- ) ) |
265 |
local PROXY_PORT |
467 |
count=$( sysctl -n hw.ncpu ) |
266 |
|
468 |
report_cpu |
267 |
if [ -z "$HTTP_PROXY" -a -n "$http_proxy" ]; then |
469 |
echo "Posting monthly CPU statistics to $checkin_server" |
268 |
HTTP_PROXY=$http_proxy |
470 |
;; |
269 |
fi |
471 |
*) |
270 |
if [ -n "$HTTP_PROXY" ]; then |
472 |
echo "Posting monthly device/CPU statistics disabled" |
271 |
# Attempt to resolve any HTTP authentication |
473 |
echo " set monthly_statistics_report_devices=\"YES\" in $periodic_conf" |
272 |
if [ -n "$HTTP_PROXY_AUTH" ]; then |
474 |
;; |
273 |
PROXY_AUTH_USER=$(echo $HTTP_PROXY_AUTH | ${SED} -E 's/^.+:\*:(.+):.+$/\1/g') |
475 |
esac |
274 |
PROXY_AUTH_PASS=$(echo $HTTP_PROXY_AUTH | ${SED} -E 's/^.+:\*:.+:(.+)$/\1/g') |
476 |
case "$monthly_statistics_report_ports" in |
275 |
else |
477 |
[Yy][Ee][Ss]) |
276 |
# Check for authentication within HTTP_PROXY |
478 |
send_ports |
277 |
HAS_HTTP_AUTH=$(echo $HTTP_PROXY | ${SED} -E 's/^(http:\/\/)?((.+:.+)@)?.+/\3/') |
479 |
echo "Posting monthly ports statistics to $checkin_server" |
278 |
if [ -n "$HAS_HTTP_AUTH" ]; then |
480 |
;; |
279 |
# Found HTTP authentication details |
481 |
*) |
280 |
PROXY_AUTH_USER=$(echo $HAS_HTTP_AUTH | ${CUT} -d: -f1) |
482 |
echo "Posting monthly ports statistics disabled" |
281 |
PROXY_AUTH_PASS=$(echo $HAS_HTTP_AUTH | ${CUT} -d: -f2) |
483 |
echo " set monthly_statistics_report_ports=\"YES\" in $periodic_conf" |
282 |
fi |
484 |
;; |
283 |
fi |
485 |
esac |
284 |
|
|
|
285 |
# Determine the proxy components |
286 |
PROXY_HOST=$(echo $HTTP_PROXY | ${SED} -E 's/^(http:\/\/)?(.+:.+@)?([^@:]+)(:.+)?/\3/') |
287 |
PROXY_PORT=$(echo $HTTP_PROXY | ${SED} -E 's/^(http:\/\/)?(.+:.+@)?(.+):([0-9]+)/\4/' | ${SED} -e 's/[^0-9]//g') |
288 |
if [ -z "$PROXY_PORT" ]; then |
289 |
# Use default proxy port |
290 |
PROXY_PORT=3128 |
291 |
fi |
292 |
fi |
293 |
|
294 |
# Determine the host/port netcat should connect to |
295 |
if [ -n "$PROXY_HOST" -a -n "$PROXY_PORT" ]; then |
296 |
nc_host=$PROXY_HOST |
297 |
nc_port=$PROXY_PORT |
298 |
# Proxy authentication, if required |
299 |
if [ -n "$PROXY_AUTH_USER" -a -n "$PROXY_AUTH_PASS" ]; then |
300 |
local auth_base64=$(echo -n "$PROXY_AUTH_USER:$PROXY_AUTH_PASS" | ${OPENSSL} base64) |
301 |
http_header_proxy_auth="Basic $auth_base64" |
302 |
fi |
303 |
return 0 |
304 |
else |
305 |
nc_host=$checkin_server |
306 |
nc_port=80 |
307 |
return 1 |
308 |
fi |
309 |
} |
310 |
|
311 |
test_connection() { |
312 |
local body |
313 |
body=$(do_http_request "HEAD" "/" "" "" 0) |
314 |
if [ $? -ne 0 -a $? -ne 2 ]; then |
315 |
log "FAIL" "Unable to connect to ${checkin_server_description}" |
316 |
fail "Network or host is down?" |
317 |
fi |
318 |
} |
319 |
|
320 |
setup_proxies() { |
321 |
# TOR |
322 |
if [ "${USE_TOR}" = "YES" ]; then |
323 |
if [ -n "${HTTP_PROXY}" -o -n "${http_proxy}" ]; then |
324 |
echo_err "Ignoring HTTP_PROXY since TOR is used" |
325 |
fi |
326 |
NC="${NC} -x localhost:9050 -X 5" |
327 |
checkin_server_description="${checkin_server_description} (through TOR)" |
328 |
return 0 |
329 |
fi |
330 |
|
331 |
# HTTP proxy |
332 |
if [ -n "${HTTP_PROXY}" -o -n "${http_proxy}" ]; then |
333 |
parse_http_proxy_string |
334 |
if [ $? -eq 0 ]; then |
335 |
checkin_server_description="${checkin_server_description} (through proxy)" |
336 |
return 0 |
337 |
fi |
338 |
fi |
339 |
|
340 |
# no proxy |
341 |
} |
342 |
|
343 |
report_devices() { |
344 |
case $(${UNAME}) in |
345 |
FreeBSD|DragonFly) |
346 |
local query_string="" |
347 |
local line |
348 |
for line in $(${PCICONF} -l); do |
349 |
local DRIVER=$(echo "${line}" | ${AWK} -F\@ '{print $1}') |
350 |
local DEV=$(echo "${line}" | ${AWK} '{print $4}' | ${CUT} -c8-15) |
351 |
local CLASS=$(echo "${line}" | ${AWK} '{print $2}' | ${CUT} -c9-14) |
352 |
query_string=$query_string`echo \&dev[]=${DRIVER}:${DEV}:${CLASS}` |
353 |
done |
354 |
|
355 |
echo_begin "Posting device statistics to ${checkin_server_description}" |
356 |
do_http_request_check_status "GET" "/scripts/report_devices.php?token=${TOKEN}&key=${KEY}$query_string" \ |
357 |
"" "" "system devices submission" |
358 |
echo_end_success |
359 |
log "INFO" "System devices reported to ${checkin_server_description}" |
360 |
;; |
361 |
*) |
362 |
# Not supported |
363 |
;; |
364 |
esac |
365 |
} |
366 |
|
367 |
report_ports() { |
368 |
case $(${UNAME}) in |
369 |
FreeBSD|DragonFly) |
370 |
local query_string="" |
371 |
# Detect pkgng |
372 |
if [ -e /var/db/pkg/local.sqlite ]; then |
373 |
# Use pkgng |
374 |
query_string="${query_string}$(pkg info -o "*" | ${SED} -E -e 's/\+/%2b/g' -e 's/,/%2c/g' -e 's/^([^ ]+) +([^\/]+)\/.+$/\&port[]=\2:\1/g' | tr -d '\n')" |
375 |
else |
376 |
#-----BEGIN LEGACY: to delete when FreeBSD with pkg_ tools is out of support period (!!! don't forget to clarify what does DragonFly use before removing !!!) ----- |
377 |
# Use obsolete pkg_* tools |
378 |
local line |
379 |
for line in `pkg_info | ${AWK} '{ print $1 }'`; do |
380 |
local category=`grep "@comment ORIGIN" /var/db/pkg/${line}/+CONTENTS | ${SED} -E 's/^\@comment ORIGIN:(.+)\/.+/\1/g'` |
381 |
line=$(uri_escape $line) |
382 |
category=$(uri_escape $category) |
383 |
query_string=$query_string`echo \&port[]=${category}:${line}` |
384 |
done |
385 |
#-----END LEGACY----- |
486 |
fi |
386 |
fi |
487 |
disable_token |
387 |
echo_begin "Posting port statistics to ${checkin_server_description}" |
|
|
388 |
do_http_request_check_status "POST" "/scripts/report_ports.php" \ |
389 |
"token=${TOKEN}&key=${KEY}${query_string}" "application/x-www-form-urlencoded" "ports submission" |
390 |
echo_end_success |
391 |
log "INFO" "Posted port statistics to ${checkin_server_description}" |
488 |
;; |
392 |
;; |
489 |
*) |
393 |
*) |
490 |
echo "Posting monthly OS statistics disabled" |
394 |
# Not supported |
491 |
echo " set monthly_statistics_enable=\"YES\" in $periodic_conf" |
395 |
;; |
|
|
396 |
esac |
397 |
} |
398 |
|
399 |
get_id_token() { |
400 |
if [ -f $id_token_file ]; then |
401 |
if [ $(${WC} -l < $id_token_file) -lt 3 ]; then |
402 |
${RM} -f $id_token_file |
403 |
fi |
404 |
fi |
405 |
|
406 |
if [ ! -f $id_token_file -o ! -s $id_token_file ]; then |
407 |
# generate the token file |
408 |
echo "BSDstats runs on this system for the first time, generating registration ID" |
409 |
IDTOKEN=$(uri_escape $(${OPENSSL} rand -base64 32)) |
410 |
if [ $? -ne 0 ]; then |
411 |
fail "Failed to generate IDTOKEN" |
412 |
fi |
413 |
|
414 |
# receive KEY/TOKEN |
415 |
local body |
416 |
body=$(do_http_request "GET" "/scripts/getid.php?key=${IDTOKEN}" "" "" 1) |
417 |
if [ $? -ne 0 ]; then |
418 |
fail "HTTP query failed during key/token generation" |
419 |
fi |
420 |
KEY=$(extract_field "${body}" "KEY") |
421 |
TOKEN=$(extract_field "${body}" "TOKEN") |
422 |
# validate KEY/TOKEN |
423 |
if [ ${#KEY} -lt 10 -o ${#KEY} -gt 64 -o ${#TOKEN} -lt 10 -o ${#TOKEN} -gt 64 ]; then |
424 |
log "FAIL" "Invalid key/token received for IDTOKEN=${TOKEN}" |
425 |
fail "Invalid key/token combination received from the server" |
426 |
fi |
427 |
log "INFO" "Generated idtoken='${IDTOKEN}', received key=${KEY} and token=${TOKEN}" |
428 |
# save KEY/TOKEN |
429 |
(echo "# This file was auto-generated on $(date),"; \ |
430 |
echo "# and contains the BSDstats registration credentials"; \ |
431 |
echo "KEY=${KEY}"; echo "TOKEN=${TOKEN}"; echo "VERSION=${CURR_VERSION}") > $id_token_file && \ |
432 |
${CHOWN} root:wheel $id_token_file && \ |
433 |
${CHMOD} 600 $id_token_file |
434 |
if [ $? -ne 0 ]; then |
435 |
${RM} -f $id_token_file |
436 |
fail "Failed to create identification file $id_token_file" |
437 |
fi |
438 |
log "INFO" "Created identification file $id_token_file" |
439 |
fi |
440 |
# read the token file into the global variables |
441 |
. $id_token_file |
442 |
KEY=$(uri_escape $KEY) |
443 |
TOKEN=$(uri_escape $TOKEN) |
444 |
PREV_VERSION="${VERSION}" |
445 |
VERSION="" |
446 |
} |
447 |
|
448 |
enable_token() { |
449 |
# XXX key and token are swapped here, this has been like that from version 5.5, not sure if fixing will break it |
450 |
do_http_request_check_status "GET" "/scripts/enable_token.php?key=${TOKEN}&token=${KEY}" \ |
451 |
"" "" "token enabling" |
452 |
log "INFO" "System enabled" |
453 |
} |
454 |
|
455 |
disable_token() { |
456 |
do_http_request_check_status "GET" "/scripts/disable_token.php?key=${TOKEN}&token=${KEY}" \ |
457 |
"" "" "token disabling" |
458 |
log "INFO" "System disabled" |
459 |
} |
460 |
|
461 |
report_system() { |
462 |
local REL=$(${UNAME} -r) |
463 |
local ARCH=$(${UNAME} -m) |
464 |
local OS=$(${UNAME} -s) |
465 |
echo_begin "Posting OS statistics to ${checkin_server_description}" |
466 |
do_http_request_check_status "GET" "/scripts/report_system.php?token=${TOKEN}&key=${KEY}&rel=${REL}&arch=${ARCH}&opsys=${OS}" \ |
467 |
"" "" "OS statistics submission" |
468 |
echo_end_success |
469 |
log "INFO" "Posted OS statistics to ${checkin_server_description}" |
470 |
} |
471 |
|
472 |
report_cpu() { |
473 |
local line=$(${SYSCTL} -n hw.model) |
474 |
local VEN=$(echo $line | ${CUT} -d ' ' -f 1) |
475 |
local DEV=$(uri_escape $(echo $line | ${CUT} -d ' ' -f 2-)) |
476 |
local count=$(${SYSCTL} -n hw.ncpu) |
477 |
echo_begin "Posting CPU information to ${checkin_server_description}" |
478 |
do_http_request_check_status "GET" "/scripts/report_cpu.php?token=${TOKEN}&key=${KEY}&cpus=${count}&vendor=${VEN}&cpu_type=${DEV}" \ |
479 |
"" "" "CPU information submission" |
480 |
echo_end_success |
481 |
log "INFO" "Posted CPU information to ${checkin_server_description}" |
482 |
} |
483 |
|
484 |
report_all() { |
485 |
# network setup |
486 |
setup_proxies |
487 |
test_connection |
488 |
log "INIT" "Connected to ${checkin_server_description}" |
489 |
# sleep random number of seconds by default |
490 |
test X"$1" = X-nodelay || ${SLEEP} $(random) |
491 |
# prepare |
492 |
get_id_token |
493 |
# begin |
494 |
enable_token |
495 |
report_system |
496 |
# optional parts |
497 |
case "$monthly_statistics_report_devices" in |
498 |
[Yy][Ee][Ss]) |
499 |
report_devices |
500 |
report_cpu |
501 |
;; |
502 |
[Nn][Oo]) |
503 |
echo "Posting monthly device/CPU statistics disabled" |
504 |
echo " set monthly_statistics_report_devices=\"YES\" in $periodic_conf" |
505 |
;; |
506 |
*) |
507 |
# opt-out for devices |
508 |
report_devices |
509 |
report_cpu |
510 |
;; |
511 |
esac |
512 |
case "$monthly_statistics_report_ports" in |
513 |
[Yy][Ee][Ss]) |
514 |
report_ports |
515 |
;; |
516 |
[Nn][Oo]) |
517 |
echo "Posting monthly ports statistics disabled" |
518 |
echo " set monthly_statistics_report_ports=\"YES\" in $periodic_conf" |
519 |
;; |
520 |
*) |
521 |
# opt-out for ports |
522 |
report_ports |
523 |
;; |
524 |
esac |
525 |
# end |
526 |
disable_token |
527 |
} |
528 |
|
529 |
## |
530 |
## MAIN: processing begins here |
531 |
## |
532 |
|
533 |
rc=0 |
534 |
|
535 |
case "$monthly_statistics_enable" in |
536 |
[Yy][Ee][Ss]) |
537 |
# explicitly enabled: report it |
538 |
report_all "$1" |
539 |
;; |
540 |
[Nn][Oo]) |
541 |
echo "Posting monthly OS statistics disabled" |
542 |
echo " set monthly_statistics_enable=\"YES\" in $periodic_conf" |
543 |
rc=1 |
544 |
;; |
545 |
*) |
546 |
# opt-out: we report when user have BSDstats installed, and user didn't say "NO" |
547 |
report_all "$1" |
492 |
;; |
548 |
;; |
493 |
esac |
549 |
esac |
494 |
|
550 |
|
495 |
umask $oldmask |
551 |
# success |
496 |
exit $rc |
552 |
log "SUCC" "Finished successfully" |
|
|
553 |
${UMASK} $oldmask |
554 |
exit ${rc} |