|
1
|
|
|
<?php |
|
2
|
|
|
/* |
|
3
|
|
|
* ***************************************************************************** |
|
4
|
|
|
* Contributions to this work were made on behalf of the GÉANT project, a |
|
5
|
|
|
* project that has received funding from the European Union’s Framework |
|
6
|
|
|
* Programme 7 under Grant Agreements No. 238875 (GN3) and No. 605243 (GN3plus), |
|
7
|
|
|
* Horizon 2020 research and innovation programme under Grant Agreements No. |
|
8
|
|
|
* 691567 (GN4-1) and No. 731122 (GN4-2). |
|
9
|
|
|
* On behalf of the aforementioned projects, GEANT Association is the sole owner |
|
10
|
|
|
* of the copyright in all material which was developed by a member of the GÉANT |
|
11
|
|
|
* project. GÉANT Vereniging (Association) is registered with the Chamber of |
|
12
|
|
|
* Commerce in Amsterdam with registration number 40535155 and operates in the |
|
13
|
|
|
* UK as a branch of GÉANT Vereniging. |
|
14
|
|
|
* |
|
15
|
|
|
* Registered office: Hoekenrode 3, 1102BR Amsterdam, The Netherlands. |
|
16
|
|
|
* UK branch address: City House, 126-130 Hills Road, Cambridge CB2 1PQ, UK |
|
17
|
|
|
* |
|
18
|
|
|
* License: see the web/copyright.inc.php file in the file structure or |
|
19
|
|
|
* <base_url>/copyright.php after deploying the software |
|
20
|
|
|
*/ |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* This file creates Linux installers |
|
24
|
|
|
* |
|
25
|
|
|
* @author Tomasz Wolniewicz <[email protected]> |
|
26
|
|
|
* @author ..... |
|
27
|
|
|
* |
|
28
|
|
|
* @package ModuleWriting |
|
29
|
|
|
*/ |
|
30
|
|
|
namespace devices\linux; |
|
31
|
|
|
use Exception; |
|
32
|
|
|
class DeviceLinuxSh extends \core\DeviceConfig { |
|
33
|
|
|
|
|
34
|
|
|
final public function __construct() { |
|
|
|
|
|
|
35
|
|
|
parent::__construct(); |
|
36
|
|
|
$this->setSupportedEapMethods([\core\common\EAP::EAPTYPE_PEAP_MSCHAP2, \core\common\EAP::EAPTYPE_TTLS_PAP, \core\common\EAP::EAPTYPE_TTLS_MSCHAP2, \core\common\EAP::EAPTYPE_TLS, \core\common\EAP::EAPTYPE_SILVERBULLET]); |
|
37
|
|
|
$this->local_dir = '.cat_installer'; |
|
38
|
|
|
$this->conf_file = '$HOME/'.$this->local_dir.'/cat_installer.conf'; |
|
39
|
|
|
} |
|
40
|
|
|
|
|
41
|
|
|
public function writeInstaller() { |
|
|
|
|
|
|
42
|
|
|
$out_string = '#!/usr/bin/env bash |
|
43
|
|
|
if [ -z "$BASH" ] ; then |
|
44
|
|
|
bash $0 |
|
45
|
|
|
exit |
|
46
|
|
|
fi |
|
47
|
|
|
|
|
48
|
|
|
|
|
49
|
|
|
'; |
|
50
|
|
|
$out_string .= $this->printFunctions(); |
|
51
|
|
|
$out_string .= $this->printStart(); |
|
52
|
|
|
$out_string .= $this->printProfileConfirmation(); |
|
53
|
|
|
$out_string .= $this->printUserConsent(); |
|
54
|
|
|
$out_string .= $this->printCheckDirectory(); |
|
55
|
|
|
$CAs = $this->attributes['internal:CAs'][0]; |
|
56
|
|
|
$this->server_name = $this->glueServerNames($this->attributes['eap:server_name']); |
|
57
|
|
|
$this->server_alt_subject_name_list = $this->mkSubjectAltNameList($this->attributes['eap:server_name']); |
|
58
|
|
|
$out_string .= "# save certificates\n"; |
|
59
|
|
|
$out_string .= 'echo "'; |
|
60
|
|
|
foreach ($CAs as $ca) { |
|
61
|
|
|
$out_string .= $ca['pem']."\n"; |
|
62
|
|
|
} |
|
63
|
|
|
$out_string .= '"'." > \$HOME/$this->local_dir/ca.pem\n"; |
|
64
|
|
|
|
|
65
|
|
|
$SSIDs = $this->attributes['internal:SSID']; |
|
66
|
|
|
$delSSIDs = $this->attributes['internal:remove_SSID']; |
|
67
|
|
|
|
|
68
|
|
|
$out_string .= $this->printNMScript($SSIDs,$delSSIDs); |
|
69
|
|
|
$out_string .= $this->writeWpaConf($SSIDs); |
|
70
|
|
|
if($this->selected_eap == \core\common\EAP::EAPTYPE_TLS) |
|
|
|
|
|
|
71
|
|
|
$out_string .= $this->printP12Dialog(); |
|
72
|
|
|
else |
|
73
|
|
|
$out_string .= $this->printPasswordDialog(); |
|
74
|
|
|
$out_string .= $this->checkNMResultAndCont(); |
|
75
|
|
|
$installer_path = $this->installerBasename.'.sh'; |
|
76
|
|
|
file_put_contents($installer_path, $out_string); |
|
77
|
|
|
return($installer_path); |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
public function writeDeviceInfo() { |
|
|
|
|
|
|
81
|
|
|
$ssid_ct=count($this->attributes['internal:SSID']); |
|
82
|
|
|
$out = ''; |
|
83
|
|
|
|
|
84
|
|
|
$out .= _("The installer is in the form of a bash script. It will try to configure eduroam under Network Manager and if this is either not appropriate for your system or your version of Network Manager is too old, a wpa_supplicant config file will be created instead."); |
|
85
|
|
|
$out .= "<p>"; |
|
86
|
|
|
if($ssid_ct > 1) { |
|
87
|
|
|
if($ssid_ct > 2) { |
|
88
|
|
|
$out .= sprintf(_("In addition to <strong>%s</strong> the installer will also configure access to the following networks:"),implode(', ',\config\ConfAssistant::CONSORTIUM['ssid']))." "; |
|
89
|
|
|
} else |
|
90
|
|
|
$out .= sprintf(_("In addition to <strong>%s</strong> the installer will also configure access to:"),implode(', ',\config\ConfAssistant::CONSORTIUM['ssid']))." "; |
|
91
|
|
|
$i = 0; |
|
92
|
|
|
foreach ($this->attributes['internal:SSID'] as $ssid=>$v) { |
|
93
|
|
|
if(! in_array($ssid, \config\ConfAssistant::CONSORTIUM['ssid'])) { |
|
94
|
|
|
if($i > 0) |
|
95
|
|
|
$out .= ", "; |
|
96
|
|
|
$i++; |
|
97
|
|
|
$out .= "<strong>$ssid</strong>"; |
|
98
|
|
|
} |
|
99
|
|
|
} |
|
100
|
|
|
$out .= "<p>"; |
|
101
|
|
|
} |
|
102
|
|
|
$out .= _("The installer will create .cat_installer sub-directory in your home directory and will copy your server certificates there."); |
|
103
|
|
|
if($this->eap == \core\common\EAP::EAPTYPE_TLS) |
|
|
|
|
|
|
104
|
|
|
$out .= _("In order to connect to the network you will need a personal certificate in the form of a p12 file. You should obtain this certificate from your home institution. Consult the support page to find out how this certificate can be obtained. Such certificate files are password protected. You should have both the file and the password available during the installation process. Your p12 file will also be copied to the .cat_installer directory."); |
|
105
|
|
|
else { |
|
106
|
|
|
$out .= _("In order to connect to the network you will need an account from your home institution. You should consult the support page to find out how this account can be obtained. It is very likely that your account is already activated."); |
|
107
|
|
|
$out .= "<p>"; |
|
108
|
|
|
$out .= _("You will be requested to enter your account credentials during the installation. This information will be saved so that you will reconnect to the network automatically each time you are in the range."); |
|
109
|
|
|
} |
|
110
|
|
|
$out .= "<p>"; |
|
111
|
|
|
return $out; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
|
|
115
|
|
|
private function printCheckDirectory() { |
|
|
|
|
|
|
116
|
|
|
$out = 'if [ -d $HOME/'.$this->local_dir.' ] ; then |
|
117
|
|
|
if ! ask "'.sprintf(_("Directory %s exists; some of its files may be overwritten."),'$HOME/'.$this->local_dir).'" "'._("Continue").'" 1 ; then exit; fi |
|
118
|
|
|
else |
|
119
|
|
|
mkdir $HOME/'.$this->local_dir.' |
|
120
|
|
|
fi |
|
121
|
|
|
'; |
|
122
|
|
|
return $out; |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
private function checkNMResultAndCont() { |
|
|
|
|
|
|
126
|
|
|
$out = 'if run_python_script ; then |
|
127
|
|
|
show_info "'._("Installation successful").'" |
|
128
|
|
|
else |
|
129
|
|
|
show_info "'._("Network Manager configuration failed, generating wpa_supplicant.conf").'" |
|
130
|
|
|
if ! ask "'.("Network Manager configuration failed, but we may generate a wpa_supplicant configuration file if you wish. Be warned that your connection password will be saved in this file as clear text.").'" "'._("Write the file").'" 1 ; then exit ; fi |
|
131
|
|
|
|
|
132
|
|
|
if [ -f '.$this->conf_file.' ] ; then |
|
133
|
|
|
if ! ask "'.sprintf(_("File %s exists; it will be overwritten."),$this->conf_file).'" "'._("Continue").'" 1 ; then confirm_exit; fi |
|
134
|
|
|
rm '.$this->conf_file.' |
|
135
|
|
|
fi |
|
136
|
|
|
create_wpa_conf |
|
137
|
|
|
show_info "'.sprintf(_("Output written to %s"),$this->conf_file).'" |
|
138
|
|
|
fi |
|
139
|
|
|
'; |
|
140
|
|
|
return $out; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
private function printStart() { |
|
|
|
|
|
|
144
|
|
|
$out = "setup_environment\n"; |
|
145
|
|
|
$out .= 'show_info "'._("This installer has been prepared for \${ORGANISATION}").'\n\n'._("More information and comments:").'\n\nEMAIL: ${SUPPORT}\nWWW: ${URL}\n\n'. |
|
146
|
|
|
_("Installer created with software from the GEANT project.").'" |
|
147
|
|
|
'; |
|
148
|
|
|
return $out; |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
|
|
152
|
|
|
private function printProfileConfirmation() { |
|
|
|
|
|
|
153
|
|
|
if($this->attributes['internal:profile_count'][0] > 1) |
|
154
|
|
|
$out = 'if ! ask "'.sprintf(_("This installer will only work properly if you are a member of %s and the user group: %s."),'${bf}'.$this->attributes['general:instname'][0].'${n}','${bf}'.$this->attributes['profile:name'][0]).'${n}"'; |
|
155
|
|
|
else |
|
156
|
|
|
$out = 'if ! ask "'.sprintf(_("This installer will only work properly if you are a member of %s."),'${bf}'.$this->attributes['general:instname'][0]).'${n}"'; |
|
157
|
|
|
$out .= ' "'._("Continue").'" 1 ; then exit; fi |
|
158
|
|
|
'; |
|
159
|
|
|
return $out; |
|
160
|
|
|
|
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
|
|
164
|
|
|
private function printUserConsent() { |
|
|
|
|
|
|
165
|
|
|
$out = ''; |
|
166
|
|
|
if(isset($this->attributes['support:info_file'])) { |
|
167
|
|
|
if( $this->attributes['internal:info_file'][0]['mime'] == 'txt') { |
|
168
|
|
|
$handle = fopen($this->attributes['internal:info_file'][0]['name'],"r"); |
|
169
|
|
|
$consent = ''; |
|
170
|
|
|
while (($buffer = fgets($handle, 4096)) !== false) { |
|
|
|
|
|
|
171
|
|
|
$consent .= rtrim($buffer) . '\n'; |
|
172
|
|
|
} |
|
173
|
|
|
$out = 'if ! ask "'.$consent.'${n}" "'._("Continue").'" 1 ; then exit; fi |
|
174
|
|
|
'; |
|
175
|
|
|
} |
|
176
|
|
|
} |
|
177
|
|
|
return $out; |
|
178
|
|
|
} |
|
179
|
|
|
# ask user for confirmation |
|
180
|
|
|
# the first argument is the user prompt |
|
181
|
|
|
# if the second argument is 0 then the first element of yes_no array |
|
182
|
|
|
# will be the default value prompted to the user |
|
183
|
|
|
private function printFunctions() { |
|
|
|
|
|
|
184
|
|
|
$url = (isset($this->attributes['support:url'][0]) && $this->attributes['support:url'][0] ) ? $this->attributes['support:url'][0] : $this->support_url_substitute; |
|
185
|
|
|
$support=(isset($this->attributes['support:email'][0]) && $this->attributes['support:email'][0] ) ? $this->attributes['support:email'][0] : $this->support_email_substitute; |
|
186
|
|
|
$out =' |
|
187
|
|
|
my_name=$0 |
|
188
|
|
|
|
|
189
|
|
|
|
|
190
|
|
|
function setup_environment { |
|
191
|
|
|
bf="" |
|
192
|
|
|
n="" |
|
193
|
|
|
ORGANISATION="'.$this->attributes['general:instname'][0].'" |
|
194
|
|
|
URL="'.$url.'" |
|
195
|
|
|
SUPPORT="'.$support.'" |
|
196
|
|
|
if [ ! -z "$DISPLAY" ] ; then |
|
197
|
|
|
if which zenity 1>/dev/null 2>&1 ; then |
|
198
|
|
|
ZENITY=`which zenity` |
|
199
|
|
|
elif which kdialog 1>/dev/null 2>&1 ; then |
|
200
|
|
|
KDIALOG=`which kdialog` |
|
201
|
|
|
else |
|
202
|
|
|
if tty > /dev/null 2>&1 ; then |
|
203
|
|
|
if echo $TERM | grep -E -q "xterm|gnome-terminal|lxterminal" ; then |
|
204
|
|
|
bf="[1m"; |
|
205
|
|
|
n="[0m"; |
|
206
|
|
|
fi |
|
207
|
|
|
else |
|
208
|
|
|
find_xterm |
|
209
|
|
|
if [ -n "$XT" ] ; then |
|
210
|
|
|
$XT -e $my_name |
|
211
|
|
|
fi |
|
212
|
|
|
fi |
|
213
|
|
|
fi |
|
214
|
|
|
fi |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
function split_line { |
|
218
|
|
|
echo $1 | awk -F \'\\\\\\\\n\' \'END { for(i=1; i <= NF; i++) print $i }\' |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
function find_xterm { |
|
222
|
|
|
terms="xterm aterm wterm lxterminal rxvt gnome-terminal konsole" |
|
223
|
|
|
for t in $terms |
|
224
|
|
|
do |
|
225
|
|
|
if which $t > /dev/null 2>&1 ; then |
|
226
|
|
|
XT=$t |
|
227
|
|
|
break |
|
228
|
|
|
fi |
|
229
|
|
|
done |
|
230
|
|
|
} |
|
231
|
|
|
|
|
232
|
|
|
|
|
233
|
|
|
function ask { |
|
234
|
|
|
T="" |
|
235
|
|
|
# if ! [ -z "$3" ] ; then |
|
236
|
|
|
# T="$T: $3" |
|
237
|
|
|
# fi |
|
238
|
|
|
if [ ! -z $KDIALOG ] ; then |
|
239
|
|
|
if $KDIALOG --yesno "${1}\n${2}?" --title "$T" ; then |
|
240
|
|
|
return 0 |
|
241
|
|
|
else |
|
242
|
|
|
return 1 |
|
243
|
|
|
fi |
|
244
|
|
|
fi |
|
245
|
|
|
if [ ! -z $ZENITY ] ; then |
|
246
|
|
|
text=`echo "${1}" | fmt -w60` |
|
247
|
|
|
if $ZENITY --no-wrap --question --text="${text}\n${2}?" --title="$T" 2>/dev/null ; then |
|
248
|
|
|
return 0 |
|
249
|
|
|
else |
|
250
|
|
|
return 1 |
|
251
|
|
|
fi |
|
252
|
|
|
fi |
|
253
|
|
|
|
|
254
|
|
|
yes='._("Y").' |
|
255
|
|
|
no='._("N").' |
|
256
|
|
|
yes1=`echo $yes | awk \'{ print toupper($0) }\'` |
|
257
|
|
|
no1=`echo $no | awk \'{ print toupper($0) }\'` |
|
258
|
|
|
|
|
259
|
|
|
if [ $3 == "0" ]; then |
|
260
|
|
|
def=$yes |
|
261
|
|
|
else |
|
262
|
|
|
def=$no |
|
263
|
|
|
fi |
|
264
|
|
|
|
|
265
|
|
|
echo ""; |
|
266
|
|
|
while true |
|
267
|
|
|
do |
|
268
|
|
|
split_line "$1" |
|
269
|
|
|
read -p "${bf}$2 ${yes}/${no}? [${def}]:$n " answer |
|
270
|
|
|
if [ -z "$answer" ] ; then |
|
271
|
|
|
answer=${def} |
|
272
|
|
|
fi |
|
273
|
|
|
answer=`echo $answer | awk \'{ print toupper($0) }\'` |
|
274
|
|
|
case "$answer" in |
|
275
|
|
|
${yes1}) |
|
276
|
|
|
return 0 |
|
277
|
|
|
;; |
|
278
|
|
|
${no1}) |
|
279
|
|
|
return 1 |
|
280
|
|
|
;; |
|
281
|
|
|
esac |
|
282
|
|
|
done |
|
283
|
|
|
} |
|
284
|
|
|
|
|
285
|
|
|
function alert { |
|
286
|
|
|
if [ ! -z $KDIALOG ] ; then |
|
287
|
|
|
$KDIALOG --sorry "${1}" |
|
288
|
|
|
return |
|
289
|
|
|
fi |
|
290
|
|
|
if [ ! -z $ZENITY ] ; then |
|
291
|
|
|
$ZENITY --warning --text="$1" 2>/dev/null |
|
292
|
|
|
return |
|
293
|
|
|
fi |
|
294
|
|
|
echo "$1" |
|
295
|
|
|
|
|
296
|
|
|
} |
|
297
|
|
|
|
|
298
|
|
|
function show_info { |
|
299
|
|
|
if [ ! -z $KDIALOG ] ; then |
|
300
|
|
|
$KDIALOG --msgbox "${1}" |
|
301
|
|
|
return |
|
302
|
|
|
fi |
|
303
|
|
|
if [ ! -z $ZENITY ] ; then |
|
304
|
|
|
$ZENITY --info --width=500 --text="$1" 2>/dev/null |
|
305
|
|
|
return |
|
306
|
|
|
fi |
|
307
|
|
|
split_line "$1" |
|
308
|
|
|
} |
|
309
|
|
|
|
|
310
|
|
|
function confirm_exit { |
|
311
|
|
|
if [ ! -z $KDIALOG ] ; then |
|
312
|
|
|
if $KDIALOG --yesno "'._("Really quit?").'" ; then |
|
313
|
|
|
exit 1 |
|
314
|
|
|
fi |
|
315
|
|
|
fi |
|
316
|
|
|
if [ ! -z $ZENITY ] ; then |
|
317
|
|
|
if $ZENITY --question --text="'._("Really quit?").'" 2>/dev/null ; then |
|
318
|
|
|
exit 1 |
|
319
|
|
|
fi |
|
320
|
|
|
fi |
|
321
|
|
|
} |
|
322
|
|
|
|
|
323
|
|
|
|
|
324
|
|
|
|
|
325
|
|
|
function prompt_nonempty_string { |
|
326
|
|
|
prompt=$2 |
|
327
|
|
|
if [ ! -z $ZENITY ] ; then |
|
328
|
|
|
if [ $1 -eq 0 ] ; then |
|
329
|
|
|
H="--hide-text " |
|
330
|
|
|
fi |
|
331
|
|
|
if ! [ -z "$3" ] ; then |
|
332
|
|
|
D="--entry-text=$3" |
|
333
|
|
|
fi |
|
334
|
|
|
elif [ ! -z $KDIALOG ] ; then |
|
335
|
|
|
if [ $1 -eq 0 ] ; then |
|
336
|
|
|
H="--password" |
|
337
|
|
|
else |
|
338
|
|
|
H="--inputbox" |
|
339
|
|
|
fi |
|
340
|
|
|
fi |
|
341
|
|
|
|
|
342
|
|
|
|
|
343
|
|
|
out_s=""; |
|
344
|
|
|
if [ ! -z $ZENITY ] ; then |
|
345
|
|
|
while [ ! "$out_s" ] ; do |
|
346
|
|
|
out_s=`$ZENITY --entry --width=300 $H $D --text "$prompt" 2>/dev/null` |
|
347
|
|
|
if [ $? -ne 0 ] ; then |
|
348
|
|
|
confirm_exit |
|
349
|
|
|
fi |
|
350
|
|
|
done |
|
351
|
|
|
elif [ ! -z $KDIALOG ] ; then |
|
352
|
|
|
while [ ! "$out_s" ] ; do |
|
353
|
|
|
out_s=`$KDIALOG $H "$prompt" "$3"` |
|
354
|
|
|
if [ $? -ne 0 ] ; then |
|
355
|
|
|
confirm_exit |
|
356
|
|
|
fi |
|
357
|
|
|
done |
|
358
|
|
|
else |
|
359
|
|
|
while [ ! "$out_s" ] ; do |
|
360
|
|
|
read -p "${prompt}: " out_s |
|
361
|
|
|
done |
|
362
|
|
|
fi |
|
363
|
|
|
echo "$out_s"; |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
function user_cred { |
|
367
|
|
|
PASSWORD="a" |
|
368
|
|
|
PASSWORD1="b" |
|
369
|
|
|
|
|
370
|
|
|
if ! USER_NAME=`prompt_nonempty_string 1 "'._("enter your userid").'"` ; then |
|
371
|
|
|
exit 1 |
|
372
|
|
|
fi |
|
373
|
|
|
|
|
374
|
|
|
while [ "$PASSWORD" != "$PASSWORD1" ] |
|
375
|
|
|
do |
|
376
|
|
|
if ! PASSWORD=`prompt_nonempty_string 0 "'._("enter your password").'"` ; then |
|
377
|
|
|
exit 1 |
|
378
|
|
|
fi |
|
379
|
|
|
if ! PASSWORD1=`prompt_nonempty_string 0 "'._("repeat your password").'"` ; then |
|
380
|
|
|
exit 1 |
|
381
|
|
|
fi |
|
382
|
|
|
if [ "$PASSWORD" != "$PASSWORD1" ] ; then |
|
383
|
|
|
alert "'._("passwords do not match").'" |
|
384
|
|
|
fi |
|
385
|
|
|
done |
|
386
|
|
|
} |
|
387
|
|
|
'; |
|
388
|
|
|
return $out; |
|
389
|
|
|
|
|
390
|
|
|
} |
|
391
|
|
|
|
|
392
|
|
|
|
|
393
|
|
|
private function writeWpaConf($SSIDs) { |
|
|
|
|
|
|
394
|
|
|
$e = \core\common\EAP::eapDisplayName($this->selected_eap); |
|
|
|
|
|
|
395
|
|
|
$out = 'function create_wpa_conf { |
|
396
|
|
|
cat << EOFW >> '.$this->conf_file."\n"; |
|
397
|
|
|
foreach (array_keys($SSIDs) as $ssid) { |
|
398
|
|
|
$out .= ' |
|
399
|
|
|
network={ |
|
400
|
|
|
ssid="'.$ssid.'" |
|
401
|
|
|
key_mgmt=WPA-EAP |
|
402
|
|
|
pairwise=CCMP |
|
403
|
|
|
group=CCMP TKIP |
|
404
|
|
|
eap='.$e['OUTER'].' |
|
405
|
|
|
ca_cert="${HOME}/'.$this->local_dir.'/ca.pem" |
|
406
|
|
|
identity="${USER_NAME}"'; |
|
407
|
|
|
if($this->server_name) |
|
408
|
|
|
$out .= ' |
|
409
|
|
|
domain_suffix_match="'.$this->server_name.'"'; |
|
410
|
|
|
if($this->selected_eap == \core\common\EAP::EAPTYPE_TLS) { |
|
411
|
|
|
$out .= ' |
|
412
|
|
|
private_key="${HOME}/'.$this->local_dir.'/user.p12" |
|
413
|
|
|
private_key_passwd="${PASSWORD}"'; |
|
414
|
|
|
} else { |
|
415
|
|
|
$out .= ' |
|
416
|
|
|
phase2="auth='.$e['INNER'].'" |
|
417
|
|
|
password="${PASSWORD}"'; |
|
418
|
|
|
if($this->attributes['internal:use_anon_outer'][0] == 1) |
|
419
|
|
|
$out .= ' |
|
420
|
|
|
anonymous_identity="'.$this->attributes['internal:anon_local_value'][0].'@'.$this->attributes['internal:realm'][0].'"'; |
|
421
|
|
|
} |
|
422
|
|
|
$out .= ' |
|
423
|
|
|
}'; |
|
424
|
|
|
} |
|
425
|
|
|
$out .= ' |
|
426
|
|
|
EOFW |
|
427
|
|
|
chmod 600 '.$this->conf_file.' |
|
428
|
|
|
} |
|
429
|
|
|
'; |
|
430
|
|
|
return $out; |
|
431
|
|
|
} |
|
432
|
|
|
|
|
433
|
|
|
|
|
434
|
|
|
|
|
435
|
|
|
private function printPasswordDialog() { |
|
|
|
|
|
|
436
|
|
|
$out = '#prompt user for credentials |
|
437
|
|
|
user_cred |
|
438
|
|
|
'; |
|
439
|
|
|
return $out; |
|
440
|
|
|
} |
|
441
|
|
|
private function printP12Dialog() { |
|
|
|
|
|
|
442
|
|
|
$out ='function p12dialog { |
|
443
|
|
|
if [ ! -z $ZENITY ] ; then |
|
444
|
|
|
if ! cert=`$ZENITY --file-selection --file-filter="'._("personal certificate file (p12 or pfx)").' | *.p12 *.P12 *.pfx *.PFX" --file-filter="All files | *" --title="'._("personal certificate file (p12 or pfx)").'" 2>/dev/null` ; then |
|
445
|
|
|
exit |
|
446
|
|
|
fi |
|
447
|
|
|
elif [ ! -z $KDIALOG ] ; then |
|
448
|
|
|
if ! cert=`$KDIALOG --getopenfilename . "*.p12 *.P12 *.pfx *.PFX | '._("personal certificate file (p12 or pfx)").'" --title "'._("personal certificate file (p12 or pfx)").'"` ; then |
|
449
|
|
|
exit |
|
450
|
|
|
fi |
|
451
|
|
|
|
|
452
|
|
|
else |
|
453
|
|
|
cert="" |
|
454
|
|
|
fl_ct=`ls *.p12 *.P12 *.pfx *.PFX 2>/dev/null | wc -l` |
|
455
|
|
|
if [ "$fl_ct" = "1" ]; then |
|
456
|
|
|
cert=`ls *.p12 *.P12 *.pfx *.PFX 2>/dev/null ` |
|
457
|
|
|
fi |
|
458
|
|
|
|
|
459
|
|
|
while true ; do |
|
460
|
|
|
prompt="'._("personal certificate file (p12 or pfx)").'" |
|
461
|
|
|
read -p "${prompt} [$bf$cert${n}]" cert_f |
|
462
|
|
|
if [ "$cert" -a -z "$cert_f" ] ; then |
|
463
|
|
|
break |
|
464
|
|
|
else |
|
465
|
|
|
if [ -f "$cert_f" ] ; then |
|
466
|
|
|
cert=$cert_f |
|
467
|
|
|
break |
|
468
|
|
|
else |
|
469
|
|
|
echo "'._("file not found").'" |
|
470
|
|
|
cert="" |
|
471
|
|
|
fi |
|
472
|
|
|
fi |
|
473
|
|
|
done |
|
474
|
|
|
fi |
|
475
|
|
|
cp "$cert" $HOME/'.$this->local_dir.'/user.p12 |
|
476
|
|
|
cert=$HOME/'.$this->local_dir.'/user.p12 |
|
477
|
|
|
|
|
478
|
|
|
PASSWORD="" |
|
479
|
|
|
prompt="'._("enter the password for the certificate file").'" |
|
480
|
|
|
while [ ! "$PASSWORD" ] |
|
481
|
|
|
do |
|
482
|
|
|
if ! PASSWORD=`prompt_nonempty_string 0 "'._("enter the password for the certificate file").'"` ; then |
|
483
|
|
|
exit 1 |
|
484
|
|
|
fi |
|
485
|
|
|
if openssl pkcs12 -in $cert -passin pass:"$PASSWORD" -noout 2>/dev/null; then |
|
486
|
|
|
USER_NAME=`openssl pkcs12 -in $cert -passin pass:"$PASSWORD" -nokeys -clcerts 2>/dev/null | awk -F/ \'/subject=/ {for(i=1 ; i <= NF; i++) { if(match($i,\'/[cC][nN]=/\')) { print substr($i,RSTART+RLENGTH)}}}\' | grep \'@\'` |
|
487
|
|
|
if [ -z "$USER_NAME" ] ; then |
|
488
|
|
|
USER_NAME=`openssl pkcs12 -in $cert -passin pass:"$PASSWORD" -nokeys -clcerts 2>/dev/null | awk -F/ \'/subject=/ {for(i=1 ; i <= NF; i++) { if(match($i,\'/email[^=]*=/\')) { print substr($i,RSTART+RLENGTH)}}}\' | grep \'@\'` |
|
489
|
|
|
fi |
|
490
|
|
|
else |
|
491
|
|
|
alert "incorrect password" |
|
492
|
|
|
PASSWORD="" |
|
493
|
|
|
fi |
|
494
|
|
|
done |
|
495
|
|
|
'; |
|
496
|
|
|
if (isset($this->attributes['eap-specific:tls_use_other_id']) && $this->attributes['eap-specific:tls_use_other_id'][0] == 'on') { |
|
497
|
|
|
$out .= ' if ! USERNAME=`prompt_nonempty_string 1 "'._("enter your userid").'" "$USER_NAME"` ; then |
|
498
|
|
|
exit 1 |
|
499
|
|
|
fi |
|
500
|
|
|
'; |
|
501
|
|
|
} else { |
|
502
|
|
|
$out .= ' if [ -z "$USER_NAME" ] ; then |
|
503
|
|
|
if ! USER_NAME=`prompt_nonempty_string 1 "' . _("enter your userid") . '" ""` ; then |
|
504
|
|
|
exit 1 |
|
505
|
|
|
fi |
|
506
|
|
|
fi |
|
507
|
|
|
'; |
|
508
|
|
|
} |
|
509
|
|
|
$out .= ' |
|
510
|
|
|
} |
|
511
|
|
|
p12dialog |
|
512
|
|
|
'; |
|
513
|
|
|
return $out; |
|
514
|
|
|
} |
|
515
|
|
|
|
|
516
|
|
|
|
|
517
|
|
|
private function glueServerNames($server_list) { |
|
|
|
|
|
|
518
|
|
|
if(! $server_list) |
|
519
|
|
|
return ''; |
|
520
|
|
|
$A0 = array_reverse(explode('.',array_shift($server_list))); |
|
521
|
|
|
$B = $A0; |
|
522
|
|
|
foreach($server_list as $a) { |
|
523
|
|
|
$A= array_reverse(explode('.',$a)); |
|
524
|
|
|
$B = array_intersect_assoc($A0,$A); |
|
525
|
|
|
$A0 = $B; |
|
526
|
|
|
} |
|
527
|
|
|
return(implode('.',array_reverse($B))); |
|
528
|
|
|
} |
|
529
|
|
|
|
|
530
|
|
|
private function mkSubjectAltNameList($server_list) { |
|
|
|
|
|
|
531
|
|
|
if(! $server_list) |
|
532
|
|
|
return ''; |
|
533
|
|
|
$out = ''; |
|
534
|
|
|
foreach($server_list as $a) { |
|
535
|
|
|
if($out) |
|
536
|
|
|
$out .= ','; |
|
537
|
|
|
$out .= "'DNS:$a'"; |
|
538
|
|
|
} |
|
539
|
|
|
return $out; |
|
540
|
|
|
} |
|
541
|
|
|
|
|
542
|
|
|
private function printNMScript($SSIDs,$delSSIDs) { |
|
|
|
|
|
|
543
|
|
|
$e = \core\common\EAP::eapDisplayName($this->selectedEap); |
|
544
|
|
|
$out = 'function run_python_script { |
|
545
|
|
|
PASSWORD=$( echo "$PASSWORD" | sed "s/\'/\\\\\\\'/g" ) |
|
546
|
|
|
if python << EEE1 > /dev/null 2>&1 |
|
547
|
|
|
import dbus |
|
548
|
|
|
EEE1 |
|
549
|
|
|
then |
|
550
|
|
|
PYTHON=python |
|
551
|
|
|
elif python3 << EEE2 > /dev/null 2>&1 |
|
552
|
|
|
import dbus |
|
553
|
|
|
EEE2 |
|
554
|
|
|
then |
|
555
|
|
|
PYTHON=python3 |
|
556
|
|
|
else |
|
557
|
|
|
PYTHON=none |
|
558
|
|
|
return 1 |
|
559
|
|
|
fi |
|
560
|
|
|
|
|
561
|
|
|
$PYTHON << EOF > /dev/null 2>&1 |
|
562
|
|
|
#-*- coding: utf-8 -*- |
|
563
|
|
|
import dbus |
|
564
|
|
|
import re |
|
565
|
|
|
import sys |
|
566
|
|
|
import uuid |
|
567
|
|
|
import os |
|
568
|
|
|
|
|
569
|
|
|
class EduroamNMConfigTool: |
|
570
|
|
|
|
|
571
|
|
|
def connect_to_NM(self): |
|
572
|
|
|
#connect to DBus |
|
573
|
|
|
try: |
|
574
|
|
|
self.bus = dbus.SystemBus() |
|
575
|
|
|
except dbus.exceptions.DBusException: |
|
576
|
|
|
print("Can\'t connect to DBus") |
|
577
|
|
|
sys.exit(2) |
|
578
|
|
|
#main service name |
|
579
|
|
|
self.system_service_name = "org.freedesktop.NetworkManager" |
|
580
|
|
|
#check NM version |
|
581
|
|
|
self.check_nm_version() |
|
582
|
|
|
if self.nm_version == "0.9" or self.nm_version == "1.0": |
|
583
|
|
|
self.settings_service_name = self.system_service_name |
|
584
|
|
|
self.connection_interface_name = "org.freedesktop.NetworkManager.Settings.Connection" |
|
585
|
|
|
#settings proxy |
|
586
|
|
|
sysproxy = self.bus.get_object(self.settings_service_name, "/org/freedesktop/NetworkManager/Settings") |
|
587
|
|
|
#settings intrface |
|
588
|
|
|
self.settings = dbus.Interface(sysproxy, "org.freedesktop.NetworkManager.Settings") |
|
589
|
|
|
elif self.nm_version == "0.8": |
|
590
|
|
|
#self.settings_service_name = "org.freedesktop.NetworkManagerUserSettings" |
|
591
|
|
|
self.settings_service_name = "org.freedesktop.NetworkManager" |
|
592
|
|
|
self.connection_interface_name = "org.freedesktop.NetworkManagerSettings.Connection" |
|
593
|
|
|
#settings proxy |
|
594
|
|
|
sysproxy = self.bus.get_object(self.settings_service_name, "/org/freedesktop/NetworkManagerSettings") |
|
595
|
|
|
#settings intrface |
|
596
|
|
|
self.settings = dbus.Interface(sysproxy, "org.freedesktop.NetworkManagerSettings") |
|
597
|
|
|
else: |
|
598
|
|
|
print("This Network Manager version is not supported") |
|
599
|
|
|
sys.exit(2) |
|
600
|
|
|
|
|
601
|
|
|
def check_opts(self): |
|
602
|
|
|
self.cacert_file = \'${HOME}/'.$this->local_dir.'/ca.pem\' |
|
603
|
|
|
self.pfx_file = \'${HOME}/'.$this->local_dir.'/user.p12\' |
|
604
|
|
|
if not os.path.isfile(self.cacert_file): |
|
605
|
|
|
print("Certificate file not found, looks like a CAT error") |
|
606
|
|
|
sys.exit(2) |
|
607
|
|
|
|
|
608
|
|
|
def check_nm_version(self): |
|
609
|
|
|
try: |
|
610
|
|
|
proxy = self.bus.get_object(self.system_service_name, "/org/freedesktop/NetworkManager") |
|
611
|
|
|
props = dbus.Interface(proxy, "org.freedesktop.DBus.Properties") |
|
612
|
|
|
version = props.Get("org.freedesktop.NetworkManager", "Version") |
|
613
|
|
|
except dbus.exceptions.DBusException: |
|
614
|
|
|
version = "0.8" |
|
615
|
|
|
if re.match(r\'^1\.\', version): |
|
616
|
|
|
self.nm_version = "1.0" |
|
617
|
|
|
return |
|
618
|
|
|
if re.match(r\'^0\.9\', version): |
|
619
|
|
|
self.nm_version = "0.9" |
|
620
|
|
|
return |
|
621
|
|
|
if re.match(r\'^0\.8\', version): |
|
622
|
|
|
self.nm_version = "0.8" |
|
623
|
|
|
return |
|
624
|
|
|
else: |
|
625
|
|
|
self.nm_version = "Unknown version" |
|
626
|
|
|
return |
|
627
|
|
|
|
|
628
|
|
|
def byte_to_string(self, barray): |
|
629
|
|
|
return "".join([chr(x) for x in barray]) |
|
630
|
|
|
|
|
631
|
|
|
|
|
632
|
|
|
def delete_existing_connections(self, ssid): |
|
633
|
|
|
"checks and deletes earlier connections" |
|
634
|
|
|
try: |
|
635
|
|
|
conns = self.settings.ListConnections() |
|
636
|
|
|
except dbus.exceptions.DBusException: |
|
637
|
|
|
print("DBus connection problem, a sudo might help") |
|
638
|
|
|
exit(3) |
|
639
|
|
|
for each in conns: |
|
640
|
|
|
con_proxy = self.bus.get_object(self.system_service_name, each) |
|
641
|
|
|
connection = dbus.Interface(con_proxy, "org.freedesktop.NetworkManager.Settings.Connection") |
|
642
|
|
|
try: |
|
643
|
|
|
connection_settings = connection.GetSettings() |
|
644
|
|
|
if connection_settings[\'connection\'][\'type\'] == \'802-11-wireless\': |
|
645
|
|
|
conn_ssid = self.byte_to_string(connection_settings[\'802-11-wireless\'][\'ssid\']) |
|
646
|
|
|
if conn_ssid == ssid: |
|
647
|
|
|
connection.Delete() |
|
648
|
|
|
except dbus.exceptions.DBusException: |
|
649
|
|
|
pass |
|
650
|
|
|
|
|
651
|
|
|
def add_connection(self,ssid): |
|
652
|
|
|
server_alt_subject_name_list = dbus.Array({'.$this->server_alt_subject_name_list.'}) |
|
653
|
|
|
server_name = \''.$this->server_name.'\' |
|
654
|
|
|
if self.nm_version == "0.9" or self.nm_version == "1.0": |
|
655
|
|
|
match_key = \'altsubject-matches\' |
|
656
|
|
|
match_value = server_alt_subject_name_list |
|
657
|
|
|
else: |
|
658
|
|
|
match_key = \'subject-match\' |
|
659
|
|
|
match_value = server_name |
|
660
|
|
|
|
|
661
|
|
|
s_con = dbus.Dictionary({ |
|
662
|
|
|
\'type\': \'802-11-wireless\', |
|
663
|
|
|
\'uuid\': str(uuid.uuid4()), |
|
664
|
|
|
\'permissions\': [\'user:$USER\'], |
|
665
|
|
|
\'id\': ssid |
|
666
|
|
|
}) |
|
667
|
|
|
s_wifi = dbus.Dictionary({ |
|
668
|
|
|
\'ssid\': dbus.ByteArray(ssid.encode(\'utf8\')), |
|
669
|
|
|
\'security\': \'802-11-wireless-security\' |
|
670
|
|
|
}) |
|
671
|
|
|
s_wsec = dbus.Dictionary({ |
|
672
|
|
|
\'key-mgmt\': \'wpa-eap\', |
|
673
|
|
|
\'proto\': [\'rsn\',], |
|
674
|
|
|
\'pairwise\': [\'ccmp\',], |
|
675
|
|
|
\'group\': [\'ccmp\', \'tkip\'] |
|
676
|
|
|
}) |
|
677
|
|
|
s_8021x = dbus.Dictionary({ |
|
678
|
|
|
\'eap\': [\''.strtolower($e['OUTER']).'\'], |
|
679
|
|
|
\'identity\': \'$USER_NAME\', |
|
680
|
|
|
\'ca-cert\': dbus.ByteArray("file://{0}\0".format(self.cacert_file).encode(\'utf8\')),'; |
|
681
|
|
|
if($this->server_name) { |
|
682
|
|
|
$out .= ' |
|
683
|
|
|
match_key: match_value,'; |
|
684
|
|
|
} |
|
685
|
|
|
if($this->selected_eap == \core\common\EAP::EAPTYPE_TLS) { |
|
|
|
|
|
|
686
|
|
|
$out .= ' |
|
687
|
|
|
\'client-cert\': dbus.ByteArray("file://{0}\0".format(self.pfx_file).encode(\'utf8\')), |
|
688
|
|
|
\'private-key\': dbus.ByteArray("file://{0}\0".format(self.pfx_file).encode(\'utf8\')), |
|
689
|
|
|
\'private-key-password\': \'$PASSWORD\','; |
|
690
|
|
|
} else { |
|
691
|
|
|
$out .= ' |
|
692
|
|
|
\'password\': \'$PASSWORD\', |
|
693
|
|
|
\'phase2-auth\': \''.strtolower($e['INNER']).'\','; |
|
694
|
|
|
if($this->attributes['internal:use_anon_outer'][0] == 1) |
|
695
|
|
|
$out .= ' |
|
696
|
|
|
\'anonymous-identity\': \''.$this->attributes['internal:anon_local_value'][0].'@'.$this->attributes['internal:realm'][0].'\','; |
|
697
|
|
|
} |
|
698
|
|
|
$out .= ' |
|
699
|
|
|
}) |
|
700
|
|
|
s_ip4 = dbus.Dictionary({\'method\': \'auto\'}) |
|
701
|
|
|
s_ip6 = dbus.Dictionary({\'method\': \'auto\'}) |
|
702
|
|
|
con = dbus.Dictionary({ |
|
703
|
|
|
\'connection\': s_con, |
|
704
|
|
|
\'802-11-wireless\': s_wifi, |
|
705
|
|
|
\'802-11-wireless-security\': s_wsec, |
|
706
|
|
|
\'802-1x\': s_8021x, |
|
707
|
|
|
\'ipv4\': s_ip4, |
|
708
|
|
|
\'ipv6\': s_ip6 |
|
709
|
|
|
}) |
|
710
|
|
|
self.settings.AddConnection(con) |
|
711
|
|
|
|
|
712
|
|
|
def main(self): |
|
713
|
|
|
self.check_opts() |
|
714
|
|
|
ver = self.connect_to_NM()'; |
|
715
|
|
|
foreach (array_keys($SSIDs) as $ssid) { |
|
716
|
|
|
$out .=' |
|
717
|
|
|
self.delete_existing_connections(\''.$ssid.'\') |
|
718
|
|
|
self.add_connection(\''.$ssid.'\')'; |
|
719
|
|
|
} |
|
720
|
|
|
// create a list of profiles to be deleted after installation |
|
721
|
|
|
foreach ($delSSIDs as $ssid => $cipher) { |
|
722
|
|
|
if($cipher == 'DEL') |
|
723
|
|
|
$out .=' |
|
724
|
|
|
self.delete_existing_connections(\''.$ssid.'\')'; |
|
725
|
|
|
} |
|
726
|
|
|
|
|
727
|
|
|
$out .=' |
|
728
|
|
|
|
|
729
|
|
|
if __name__ == "__main__": |
|
730
|
|
|
ENMCT = EduroamNMConfigTool() |
|
731
|
|
|
ENMCT.main() |
|
732
|
|
|
EOF |
|
733
|
|
|
} |
|
734
|
|
|
'; |
|
735
|
|
|
return $out; |
|
736
|
|
|
} |
|
737
|
|
|
|
|
738
|
|
|
|
|
739
|
|
|
private $local_dir; |
|
|
|
|
|
|
740
|
|
|
private $conf_file; |
|
|
|
|
|
|
741
|
|
|
private $server_name; |
|
|
|
|
|
|
742
|
|
|
private $server_alt_subject_name_list; |
|
|
|
|
|
|
743
|
|
|
} |
|
744
|
|
|
|
|
745
|
|
|
?> |
|
|
|
|
|
|
746
|
|
|
|