[ Index ] |
PHP Cross Reference of phpSSH |
[Summary view] [Print]
1 <? 2 /** 3 * General utility functions 4 * 5 * This file contains convenience functions used throughout the package. 6 * 7 * @author José R. Valverde <jrvalverde@cnb.uam.es> 8 * @version 1.0 9 * @copyright CSIC - GPL 10 */ 11 12 /** 13 * include global configuration definitions 14 */ 15 require_once("./config.php"); 16 17 // ------------- COMMODITY ROUTINES ---------------- 18 19 /** 20 * Start the display of a www page 21 * 22 * We have it as a function so we can customise all pages generated as 23 * needed. This routine will open HTML, create the page header, and 24 * include any needed style sheets (if any) to provide a common 25 * look-and-feel for all pages generated. 26 */ 27 function set_header() 28 { 29 global $app_name, $app_dir; 30 // Start HTML vx.xx output 31 echo "<html>"; 32 // Print headers 33 echo "<head>"; 34 echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">"; 35 echo "<meta name=\"DESCRIPTION\" content=\"a web interface to run TINKER molecular modelling on the EGEE grid\">"; 36 echo "<meta name=\"AUTHOR\" content=\"EMBnet/CNB\">"; 37 echo "<meta name=\"COPYRIGHT\" content=\"(c) 2004-5 by CSIC - Open Source Software\">"; 38 echo "<meta name=\"GENERATOR\" content=\"$app_name\">"; 39 echo "<link rel=\"StyleSheet\" href=\"$app_dir/style/style.css\" type=\"text/css\"/>"; 40 echo "<link rel=\"shortcut icon\" href=\"$app_dir/images/favicon.ico\"/>"; 41 echo "<title=\"$app_name\">"; 42 echo "</head>"; 43 // Prepare body 44 echo "<body bgcolor=\"white\" background=\"$app_dir/images/6h2o-w-small.gif\" link=\"ffc600\" VLINK=\"#cc9900\" ALINK=\"#4682b4\">"; 45 } 46 47 /** 48 * close a web page 49 * 50 * Make sure we end the page with all the appropriate formulisms: 51 * close the body, include copyright notice, state creator and 52 * any needed details, and close the page. 53 */ 54 function set_footer() 55 { 56 global $maintainer, $app_dir; 57 // close body 58 echo "</body><hr>"; 59 // footer 60 echo "<center><table border=\"0\" width=\"90%\"><tr>"; 61 // Copyright and author 62 echo "<td><A HREF=\"$app_dir/c/copyright.html\">©</a>EMBnet/CNB</td>"; 63 // contact info 64 echo "<td align=\"RIGHT\"><A HREF=\"emailto:$maintainer\">$maintainer</a></td>"; 65 echo "</tr></table></center>"; 66 // Page 67 echo "</html>"; 68 } 69 70 /** 71 * print a warning 72 * 73 * Prints a warning in a separate pop-up window. 74 * A warning is issued when a non-critical problem has been detected. 75 * Execution can be resumed using some defaults, but the user should 76 * be notified. In order to not disrupt the web page we are displaying 77 * we use a JavaScript pop-up alert to notify the user. 78 * 79 * @param msg the warning message to send the user 80 */ 81 function warning($msg) 82 { 83 echo "<script language=\"JavaScript\">"; 84 echo "alert(\"WARNING:\n $msg\");"; 85 echo "</script>"; 86 } 87 88 /** 89 * print an error message and exit 90 * 91 * Whenever we detect something wrong, we must tell the user. This function 92 * will take an error message as its argument, format it suitably and 93 * spit it out. 94 * 95 * @note This might look nicer using javascript to pop up a nice window with 96 * the error message. Style sheets would be nice too. 97 * 98 * @param where the name of the caller routine or the process where the 99 * error occurred 100 * @param what a description of the abnormal condition that triggered 101 * the error 102 */ 103 104 function error($where, $what) 105 { 106 // format the message 107 echo "<p></p><center><table border=\"2\">\n"; 108 echo "<tr><td><center><font color=\"red\"><strong>\n"; 109 110 // output the message 111 echo "ERROR - HORROR\n"; 112 113 // close format 114 echo "</strong></font></center></td></tr>\n"; 115 echo "<tr><td><center><b>$where</b></center></td></tr>\n"; 116 echo "<tr><td><center>$what</center></td></tr>\n"; 117 echo "</table></center><p></p>\n"; 118 } 119 120 /** 121 * print a letal error message and die 122 * 123 * This function is called whenever a letal error (one that prevents 124 * further processing) is detected. The function will spit out an 125 * error message, close the page and exit the program. 126 * It should seldomly be used, since it may potentially disrupt the 127 * page layout (e.g. amid a table) by not closing open tags of which 128 * it is unaware. 129 * Actually it is a wrapper for error + terminate. 130 * 131 * @param where location (physical or logical) where the error was 132 * detected: a physical location (routine name/line number) may be 133 * helpful for debugging, a logical location (during which part of 134 * the processing it happened) will be more helful to the user. 135 * 136 * @param what a descrition of the abnormality detected. 137 */ 138 function letal($what, $where) 139 { 140 error($what, $where); 141 set_footer(); 142 exit(); 143 } 144 145 // ------------- SSH ROUTINES ---------------- 146 147 /** 148 * Execute a single command remotely using ssh and 149 * return its entire output (like passthru) 150 * 151 * This might be done as well using a pipe on /tmp and 152 * making the command 'cat' the pipe: when ssh runs, it 153 * runs the command 'cat' on the pipe and hangs on read. 154 * Then we just need a thread to open the pipe, put the 155 * password and close the pipe. 156 * This other way the password is never wirtten down. 157 * But, OTOH, the file life is so ephemeral that most 158 * of the time it will only exist in the internal system 159 * cache, so this approach is not that bad either. 160 * 161 * @param remote The remote end to run the command, in 162 * the form 'user@host' (or 'host' if the 163 * username is the same). 164 * @param password The remote password. Note that if direct 165 * RSA/DSA/.shosts/.rhosts login is enabled 166 * then the password should be ignored as 167 * SSH should not run the ASKPASS command). 168 * @param command The command to execute on the remote end 169 * NOTE: if you want to use redirection, the 170 * entire remote command line should be 171 * enclosed in additional quotes! 172 * @param status Optional, this will hold the termination 173 * status of SSH after invocation, which 174 * should be the exit status of the remote 175 * command or 255 if an error occurred 176 * @return output The output of the remote command. 177 */ 178 function ssh_passthru($remote, $password, $command, $status) 179 { 180 umask(0077); 181 $tmpfname = tempnam("/tmp", "egTinker"); 182 chmod($tmpfname, 0700); 183 $fp = fopen($tmpfname, "w"); 184 fputs($fp, "#!/bin/sh\necho $password\n"); 185 fputs($fp, "rm -f $tmpfname\n"); 186 fclose($fp); 187 putenv("DISPLAY=none:0."); 188 putenv("SSH_ASKPASS=$tmpfname"); 189 return passthru("ssh -x -t -t $remote $command", $status); 190 } 191 192 // Do a remote scp connection with local password 193 /** 194 * Copy a file or directory from one source to a destination 195 * 196 * This function copies source to dest, where one of them is a 197 * local filespec and the other a remote filespec of the form 198 * [user@]host:path 199 * 200 * If the original source is a directory, it will be copied 201 * recursively to destination (hence easing file transfers). 202 * 203 * The function returns TRUE on success or FALSE on failure. 204 * 205 */ 206 function ssh_copy($origin, $destination, $password) 207 { 208 umask(0077); 209 $tmpfname = tempnam("/tmp", "egTinker"); 210 chmod($tmpfname, 0700); 211 $fp = fopen($tmpfname, "w"); 212 fputs($fp, "#!/bin/sh\necho $password\n"); 213 fputs($fp, "rm $tmpfname\n"); 214 fclose($fp); 215 putenv("DISPLAY=none:0."); 216 putenv("SSH_ASKPASS=$tmpfname"); 217 system("scp -pqrC $origin $destination", $status); 218 if ($status == 0) 219 return TRUE; 220 else 221 return FALSE; 222 } 223 224 function ssh_open($remote, $password) 225 { 226 global $php_version; 227 global $debug; 228 229 // Open a child process with the 'proc_open' function. 230 // 231 // Some tricks: we must open the connection using '-x' to disable 232 // X11 forwarding, and use '-t -t' to avoid SSH generating an error 233 // because we are not connected to any terminal. 234 // NOTE: 235 // We require users to have an account and password on 236 // the UI and provide their user/password through the web or 237 // otherwise (e.g. using myproxy) 238 // 239 // NOTE: if the web server is trusted remotely (i.e. it's SSH public 240 // key is accepted in ~user@host:.ssh/authorized_keys) then any 241 // password will do. 242 if ($php_version < 5) { 243 // Prepare I/O 244 $descriptorspec = array( 245 0 => array("pipe", "r"), // connect child's stdin to the read end of a pipe 246 1 => array("pipe", "w"), // connect child's stdout to the write end of a pipe 247 2 => array("pipe", "w") // stderr is a pipe to read from 248 ); 249 // prepare password 250 putenv("DISPLAY=none:0."); 251 putenv("SSH_ASKPASS=$tmpfname"); 252 umask(0077); 253 $tmpfname = tempnam("/tmp", "egTinker"); 254 chmod($tmpfname, 0700); 255 $fp = fopen($tmpfname, "w"); 256 fputs($fp, "#!/bin/sh\necho $password\n"); 257 fputs($fp, "rm $tmpfname\n"); 258 fclose($fp); 259 260 $process = proc_open("ssh -x -t -t $remote", 261 $descriptorspec, 262 $pipes); 263 if ($debug) echo "ssh -x -t -t $remote<br />\n"; 264 // check status 265 if (!is_resource($process)) 266 { 267 letal("SSH::connect", "cannot connect to the remote host"); 268 return; 269 } 270 if ($debug) echo "proc_open<br />\n"; 271 272 } 273 else { /* php5 -- we can use PTYs */ 274 /* XXX -- untested -- probably unneeded */ 275 $descriptorspec = array( 276 0 => array("pty"), 277 1 => array("pty"), 278 2 => array("pty") 279 ); 280 // prepare password 281 putenv("DISPLAY=none:0."); 282 putenv("SSH_ASKPASS=$tmpfname"); 283 umask(0077); 284 $tmpfname = tempnam("/tmp", "egTinker"); 285 chmod($tmpfname, 0700); 286 $fp = fopen($tmpfname, "w"); 287 fputs($fp, "#!/bin/sh\necho $password\n"); 288 fputs($fp, "rm $tmpfname\n"); 289 fclose($fp); 290 291 $process = proc_open("ssh -x -t -t $remote", 292 $descriptorspec, 293 $pipes); 294 295 // check status 296 if (!is_resource($process)) 297 { 298 letal("SSH::connect", "cannot connect to the remote host"); 299 return; 300 } 301 302 $status = proc_get_status($process); 303 if ($status->running == FALSE) { 304 fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); 305 proc_close($process); 306 letal("SSH::connect", "connection exited ".$status->exitcode); 307 return; 308 } 309 if ($status->signaled) { 310 fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); 311 proc_close($process); 312 letal("SSH::connect", "connection terminated by ".$status->termsig); 313 return; 314 } 315 if ($status->stopped) { 316 // Tell the user and hope for the best 317 warning("SSH::connect stopped by ".$status->stopsig. 318 " it may still have a chance though"); 319 } 320 321 } 322 323 // $pipes now looks like this: 324 // 0 => writeable handle connected to child stdin 325 // 1 => readable handle connected to child stdout 326 327 // We now have a connection to the remote Grid User Interface 328 // Server which we may use to send commands/receive output 329 return array('stdin' => $pipes[0], 330 'stdout' => $pipes[1], 331 'stderr' => $pipes[2] ); 332 } 333 334 ?>
title
Description
Body
title
Description
Body
title
Body
Generated: Tue May 31 15:44:47 2005 | Cross-referenced by PHPXref 0.4.1 |