source: trunk/locker/bin/webaccess @ 1404

Last change on this file since 1404 was 1188, checked in by andersk, 13 years ago
webaccess: No more chmod 777 .ht*.
  • Property svn:executable set to *
File size: 5.1 KB
Line 
1#!/bin/bash
2
3# webaccess
4# Manage access control for scripts.mit.edu in .htaccess and .htpasswd files.
5# Anders Kaseorg <andersk@mit.edu>
6
7set -e
8
9on_exit=
10trap 'eval "$on_exit"' EXIT
11
12dir="$(pwd)"
13htaccess=$dir/.htaccess
14authuserfile=$dir/.htpasswd
15
16add_users=
17del_users=
18enable_auth=1
19def_authname=\"Private\"
20
21begin_section="### BEGIN webaccess directives"
22end_section="### END webaccess directives"
23
24usage () {
25    cat <<EOF >&2
26usage:
27  webaccess -a <user>   Allow access from <user> and set password.
28  webaccess -d <user>   Deny access from <user>.
29  webaccess -r          Reset default access control.
30EOF
31    exit 1
32}
33
34getpass () {
35    user=$1
36    (
37        echo -n "New password for $user: " >/dev/tty
38        trap 'stty echo; echo >/dev/tty' EXIT
39        stty -echo
40        perl -e 'chop($_ = <>); print crypt($_, "\$1\$" . join "", (".", "/", "0".."9", "A".."Z", "a".."z") [rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64])' </dev/tty
41    )
42}
43
44if [ $# -eq 0 ]; then usage; fi
45
46while [ $# -gt 0 ]; do
47    arg="$1"; shift
48    case "$arg" in
49        -a*)
50            user="${arg#-a}"
51            if [ -z "$user" ]; then user=$1; shift; fi
52            if [ -z "$user" ]; then usage; fi
53            add_users=$add_users\ $user
54            ;;
55        allow)
56            user="$1"; shift
57            if [ -z "$user" ]; then usage; fi
58            add_users=$add_users\ $user
59            ;;
60        -d*)
61            user="${arg#-d}"
62            if [ -z "$user" ]; then user=$1; shift; fi
63            if [ -z "$user" ]; then usage; fi
64            del_users=$del_users\ $user
65            ;;
66        remove)
67            user="$1"; shift
68            if [ -z "$user" ]; then usage; fi
69            del_users=$del_users\ $user
70            ;;
71        -r|reset)
72            enable_auth=0
73            ;;
74        -n*)
75            authname="${arg#-n}"
76            if [ -z "$authname" ]; then authname=\"$1\"; shift; fi
77            if [ -z "$authname" ]; then usage; fi
78            ;;
79        *)
80            usage
81            ;;
82    esac
83done
84
85tmp_htaccess=$htaccess.webaccess-new
86trap 'rm -f "$tmp_htaccess"' EXIT
87exec 3>"$tmp_htaccess"
88
89config_written=0
90write_config () {
91    if [ $config_written -eq 1 ]; then return 0; fi
92    config_written=1
93    if [ $enable_auth -eq 1 ]; then
94        echo "$begin_section" >&3
95        echo "# See http://scripts.mit.edu/faq/23" >&3
96        echo "AuthUserFile $authuserfile" >&3
97        echo "AuthName ${authname:-$def_authname}" >&3
98        echo "AuthType Basic" >&3
99        echo "Require valid-user" >&3
100        echo "$end_section" >&3
101    fi
102}
103
104if [ -e "$htaccess" ]; then
105    exec 4<"$htaccess"
106   
107    oldconfig_state=0
108    oldconfig_buffer=__END__
109   
110    while read -r line <&4; do
111        oldconfig_newstate=0
112        case "$line" in
113            "AuthUserFile "*)     oldconfig_newstate=1 ;;
114            "AuthName "*)         oldconfig_newstate=2; oldconfig_authname=${line#AuthName } ;;
115            "AuthType Basic")     oldconfig_newstate=3 ;;
116            "<Limit GET>")        oldconfig_newstate=4 ;;
117            "require valid-user") oldconfig_newstate=5 ;;
118            "</Limit>")           oldconfig_newstate=6 ;;
119        esac
120       
121        if [ $oldconfig_newstate -ne $(($oldconfig_state + 1)) ]; then
122            if [ $oldconfig_state -ne 0 ]; then
123                echo "${oldconfig_buffer%
124__END__}" >&3
125                oldconfig_state=0
126                oldconfig_buffer=__END__
127            fi
128        fi
129       
130        if [ "$line" = "$begin_section" ]; then
131            while read -r line <&4 && [ "$line" != "$end_section" ]; do
132                case "$line" in
133                    "AuthName "*)
134                        def_authname=${line#AuthName }
135                        ;;
136                esac
137            done
138            write_config
139        elif [ $oldconfig_newstate -eq $(($oldconfig_state + 1)) ]; then
140            oldconfig_buffer=$(echo "${oldconfig_buffer%__END__}$line"; echo __END__)
141            oldconfig_state=$oldconfig_newstate
142            if [ $oldconfig_state -eq 6 ]; then
143                echo "Replacing obsolete webaccess configuration." >&2
144                oldconfig_state=0
145                oldconfig_buffer=__END__
146                def_authname=$oldconfig_authname
147            fi
148        else
149            echo "$line" >&3
150        fi
151    done
152   
153    if [ $oldconfig_state -ne 0 ]; then
154        echo "${oldconfig_buffer%
155__END__}"
156        oldconfig_state=0
157        oldconfig_buffer=__END__
158    fi
159   
160    exec 4<&-
161fi
162
163write_config
164
165exec 3>&-
166if ! cmp -s "$htaccess" "$tmp_htaccess"; then
167    if [ -s "$tmp_htaccess" ]; then
168        echo "Updating $htaccess" >&2
169        mv -f "$tmp_htaccess" "$htaccess"
170    else
171        if [ -e "$htaccess" ]; then
172            echo "Deleting $htaccess" >&2
173            rm -f "$htaccess"
174        fi
175        rm -f "$tmp_htaccess"
176    fi
177fi
178trap - EXIT
179
180if [ $enable_auth -eq 1 ]; then
181    if [ ! -e "$authuserfile" ]; then touch "$authuserfile"; fi
182   
183    tmp_authuserfile=$authuserfile.webaccess-new
184    trap 'rm -f "$tmp_authuserfile"' EXIT
185    exec 3>"$tmp_authuserfile"
186
187    exec 4<"$authuserfile"
188    while IFS=: read user pass <&4; do
189        for del_user in $del_users; do
190            if [ "$del_user" = "$user" ]; then
191                echo "Deleting user $del_user:" >&2
192                pass=
193            fi
194        done
195        new_add_users=
196        for add_user in $add_users; do
197            if [ "$add_user" = "$user" ]; then
198                pass=$(getpass "$user")
199            else
200                new_add_users=$new_add_users\ $add_user
201            fi
202        done
203        add_users=$new_add_users
204        if [ -n "$pass" ]; then
205            echo "$user:$pass" >&3
206        fi
207    done
208    exec 4<&-
209   
210    for add_user in $add_users; do
211        pass=$(getpass "$add_user")
212        echo "$add_user:$pass" >&3
213    done
214   
215    exec 3>&-
216    mv -f "$tmp_authuserfile" "$authuserfile"
217    trap - EXIT
218   
219    echo "Done.  New list of valid users:" >&2
220    sed -n 's/^\([^:]*\):.*$/  \1/ p' "$authuserfile"
221else
222    rm -f "$authuserfile"
223fi
Note: See TracBrowser for help on using the repository browser.