showpubkeys.php3 9.8 KB
Newer Older
1
<?php
Leigh B. Stoller's avatar
Leigh B. Stoller committed
2
3
#
# EMULAB-COPYRIGHT
4
# Copyright (c) 2000-2003, 2005 University of Utah and the Flux Group.
Leigh B. Stoller's avatar
Leigh B. Stoller committed
5
6
# All rights reserved.
#
7
8
9
10
11
12
include("defs.php3");

#
# Only known and logged in users can do this.
#
$uid = GETLOGIN();
13
LOGGEDINORDIE($uid, CHECKLOGIN_USERSTATUS|CHECKLOGIN_WEBONLY);
14
15
16
$isadmin = ISADMIN($uid);

#
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Verify page/form arguments. Note that the target uid comes initially as a
# page arg, but later as a form argument, hence this odd check.
#
if (! isset($_POST['submit'])) {
    # First page load. Default to current user.
    if (! isset($_GET['target_uid']))
	$target_uid = $uid;
    else
	$target_uid = $_GET['target_uid'];
}
else {
    # Form submitted. Make sure we have a formfields array and a target_uid.
    if (!isset($_POST['formfields']) ||
	!is_array($_POST['formfields']) ||
	!isset($_POST['formfields']['target_uid'])) {
	PAGEARGERROR("Invalid form arguments.");
    }
    $formfields = $_POST['formfields'];
    $target_uid = $formfields['target_uid'];
}

# Pedantic check of uid before continuing.
if ($target_uid == "" || !TBvalid_uid($target_uid)) {
    PAGEARGERROR("Invalid uid: '$target_uid'");
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
}

#
# Check to make sure thats this is a valid UID.
#
if (! TBCurrentUser($target_uid)) {
    USERERROR("The user $target_uid is not a valid user", 1);
}

#
# Verify that this uid is a member of one of the projects that the
# target_uid is in. Must have proper permission in that group too. 
#
if (!$isadmin &&
    strcmp($uid, $target_uid)) {

    if (! TBUserInfoAccessCheck($uid, $target_uid, $TB_USERINFO_READINFO)) {
	USERERROR("You do not have permission to view ${user}'s keys!", 1);
    }
}

function SPITFORM($formfields, $errors)
{
64
    global $isadmin, $target_uid, $BOSSNODE;
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

    #
    # Standard Testbed Header, now that we know what we want to say.
    #
    if (strcmp($uid, $target_uid)) {
	PAGEHEADER("SSH Public Keys for user: $target_uid");
    }
    else {
	PAGEHEADER("My SSH Public Keys");
    }

    #
    # Get the list and show it.
    #
    $query_result =
	DBQueryFatal("select * from user_pubkeys where uid='$target_uid'");

    if (mysql_num_rows($query_result)) {
	echo "<table align=center border=1 cellpadding=2 cellspacing=2>\n";

	echo "<center>
                Current ssh public keys for user $target_uid.
              </center><br>\n";

	echo "<tr>
Chad Barb's avatar
   
Chad Barb committed
90
91
                 <th>Delete?</th>
                 <th>Key</th>
92
93
94
95
96
97
              </tr>\n";

	while ($row = mysql_fetch_array($query_result)) {
	    $comment = $row[comment];
	    $pubkey  = $row[pubkey];
	    $date    = $row[stamp];
98
	    $idx     = $row[idx];
99
100
101
102
103
104
	    $fnote   = "";

	    if (strstr($comment, $BOSSNODE)) {
		$fnote = "[<b>1</b>]";
	    }
	    $chunky  = chunk_split("$pubkey $fnote", 75, "<br>\n");
105
106
107
108

	    echo "<tr>
                     <td align=center>
                       <A href='deletepubkey.php3?target_uid=$target_uid" .
109
	                  "&key=$idx'><img alt=X src=redball.gif></A>
110
111
112
113
114
115
116
117
118
119
120
                     </td>
                     <td>$chunky</td>
                  </tr>\n";
	}
	echo "</table>\n";
    }
    else {
	echo "<center>
             There are no public keys on file for user $target_uid!
             </center>\n";
    }
121
122
123
124
125
    echo "<blockquote><blockquote><blockquote>
          <ol>
            <li> Please do not delete your Emulab generated public key.
          </ol>
          </blockquote></blockquote></blockquote>\n";
126
127
128

    echo "<br><hr size=4>\n";
    echo "<center>
129
130
131
132
133
          Enter ssh public keys for user
                    ${target_uid} [<b>1,2</b>]
          <br>
          (<em>We <b>strongly</b>
             encourage the use of Protocol 2 keys only!</em> [<b>6</b>])
134
135
136
          </center><br>\n";

    if ($errors) {
Chad Barb's avatar
   
Chad Barb committed
137
138
	echo "<table class=nogrid
                     align=center border=0 cellpadding=6 cellspacing=0>
139
              <tr>
Chad Barb's avatar
   
Chad Barb committed
140
                 <th align=center colspan=2>
141
                   <font size=+1 color=red>
Chad Barb's avatar
   
Chad Barb committed
142
                      &nbsp;Oops, please fix the following errors!&nbsp;
143
144
145
146
147
148
                   </font>
                 </td>
              </tr>\n";

	while (list ($name, $message) = each ($errors)) {
	    echo "<tr>
Chad Barb's avatar
   
Chad Barb committed
149
150
151
152
                     <td align=right>
                       <font color=red>$name:&nbsp;</font></td>
                     <td align=left>
                       <font color=red>$message</font></td>
153
154
155
156
157
158
159
                  </tr>\n";
	}
	echo "</table><br>\n";
    }

    echo "<table align=center border=1> 
          <form enctype=multipart/form-data
160
161
162
                action=showpubkeys.php3 method=post>\n";
    echo "<input type=hidden name=\"formfields[target_uid]\" ".
	         "value=$target_uid>\n";
163
164
165
166
167
168
169
170
171
172
173
174
175
176

    #
    # SSH public key
    # 
    echo "<tr>
              <td rowspan><center>Upload (4K max)[<b>3,4</b>]<br>
                              <b>Or</b><br>
                           Insert Key
                          </center></td>

              <td rowspan>
                  <input type=hidden name=MAX_FILE_SIZE value=4096>
	          <input type=file
                         name=usr_keyfile
177
                         value=\"" . $_FILES['usr_keyfile']['name'] . "\"
178
179
180
181
182
	                 size=50>
                  <br>
                  <br>
	          <input type=text
                         name=\"formfields[usr_key]\"
183
                         value=\"$formfields[usr_key]\"
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	                 size=50
	                 maxlength=1024>
              </td>
          </tr>\n";

    #
    # Verify with password.
    #
    if (!$isadmin) {
	echo "<tr>
                  <td>Password[<b>5</b>]:</td>
                  <td class=left>
                      <input type=password
                             name=\"formfields[password]\"
198
                             size=12></td>
199
200
201
202
203
204
205
206
207
208
209
210
              </tr>\n";
    }

    echo "<tr>
              <td colspan=2 align=center>
                 <b><input type=submit name=submit value='Add New Keys'></b>
              </td>
          </tr>\n";

    echo "</form>
          </table>\n";

211
    echo "<blockquote><blockquote><blockquote>
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
          <ol>
            <li> Please consult our
                 <a href = 'docwrapper.php3?docname=security.html#SSH'>
                 security policies</a> for information
                 regarding ssh public keys.
            <li> You should not hand edit your your authorized_keys file on
                 Emulab (.ssh/authorized_keys) since modifications via this
                 page will overwrite the file.
            <li> Note to <a href=http://www.opera.com><b>Opera 5</b></a> users:
                 The file upload mechanism is broken in Opera, so you cannot
                 specify a local file for upload. Instead, please paste your
                 key in.
            <li> Typically, the file you want to upload is your
                 identity.pub, contained in your .ssh directory.
            <li> As a security precaution, you must supply your password
                 when adding new ssh public keys. 
228
229
            <li> Protocol 2 keys are more secure then Protocol 1 keys, and
                 Emulab will soon <b>require</b> Protocol 2 keys.
230
          </ol>
231
          </blockquote></blockquote></blockquote>\n";
232
233
234
235
236
237
238
239

    echo "<font color=red>NOTE:</font> We use the
          <a href=www.openssh.org>OpenSSH</a> key format, which has a slightly
          different protocol 2 public key format than some of the commercial 
          vendors such as <a href=www.ssh.com>SSH Communications</a>. If you
          use one of these commercial vendors, then please upload the public
          key file and we will convert it for you. <i>Please do not paste
          it in.</i>\n";
240
241
242
243
244
}

#
# On first load, display a form of current values.
#
245
if (! isset($_POST['submit'])) {
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    $defaults = array();
    
    SPITFORM($defaults, 0);
    PAGEFOOTER();
    return;
}

#
# Otherwise, must validate and redisplay if errors
#
$errors = array();

if (isset($formfields[usr_key]) &&
    strcmp($formfields[usr_key], "")) {

261
262
263
    #
    # This is passed off to the shell, so taint check it.
    # 
264
    if (! preg_match("/^[-\w\s\.\@\+\/\=]*$/", $formfields[usr_key])) {
265
266
267
	$errors["PubKey"] = "Invalid characters";
    }
    else {
268
269
270
271
272
        #
        # Replace any embedded newlines first.
        #
	$formfields[usr_key] = ereg_replace("[\n]", "", $formfields[usr_key]);
	$usr_key = $formfields[usr_key];
273
	$addpubkeyargs = "-k $target_uid '$usr_key' ";
274
275
276
277
278
279
    }
}

#
# If usr provided a file for the key, it overrides the paste in text.
#
280
281
282
283
284
if (isset($_FILES['usr_keyfile']) &&
    $_FILES['usr_keyfile']['name'] != "" &&
    $_FILES['usr_keyfile']['name'] != "none") {

    $localfile = $_FILES['usr_keyfile']['tmp_name'];
285

286
    if (! stat($localfile)) {
287
	$errors["PubKey File"] = "No such file";
288
    }
289
290
291
292
    # Taint check shell arguments always!
    elseif (! preg_match("/^[-\w\.\/]*$/", $localfile)) {
	$errors["PubKey File"] = "Invalid characters";
    }
293
    else {
294
295
	$addpubkeyargs = "$target_uid $localfile";
	chmod($localfile, 0644);	
296
297
298
299
    }
}

#
300
301
302
# Must verify passwd to add keys.
#
if (isset($addpubkeyargs)) {
303
304
305
306
307
308
309
310
311
    if (! $isadmin) {
	if (!isset($formfields[password]) ||
	    strcmp($formfields[password], "") == 0) {
	    $errors["Password"] = "Must supply a verification password";
	}
	elseif (VERIFYPASSWD($target_uid, $formfields[password]) != 0) {
	    $errors["Password"] = "Incorrect password";
	}
    }
312
313
314
315
}
else {
    $errors["Missing Args"] = "Please supply a key or a keyfile";
}
316

317
318
319
320
321
322
# Spit the errors
if (count($errors)) {
    SPITFORM($formfields, $errors);
    PAGEFOOTER();
    return;
}
323

324
325
326
327
328
329
330
331
332
#
# Okay, first run the script in verify mode to see if the key is
# parsable. If it is, then do it for real.
#
if (ADDPUBKEY($uid, "webaddpubkey -n $addpubkeyargs")) {
    $errors["Pubkey Format"] = "Could not be parsed. Is it a public key?";
    SPITFORM($formfields, $errors);
    PAGEFOOTER();
    return;
333
}
334
#
335
# Insert key, update authkeys files and nodes if appropriate.
336
#
337
ADDPUBKEY($uid, "webaddpubkey $addpubkeyargs");
338

339
340
341
342
#
# Redirect back, avoiding a POST in the history.
# 
header("Location: showpubkeys.php3?target_uid=$target_uid");
343
?>