Index: wp-admin/includes/class-wp-filesystem-ssh2.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-ssh2.php	(revision 8856)
+++ wp-admin/includes/class-wp-filesystem-ssh2.php	(working copy)
@@ -41,10 +41,11 @@
  */
 class WP_Filesystem_SSH2 extends WP_Filesystem_Base {
 
-	var $debugtest = false;	//	this is my var that will output the text when debuggin this class
+	var $debugtest = false;	//	set this to true only if your a debuging your connection
 
 	var $link = null;
 	var $sftp_link = null;
+	var $keys = false;
 	/*
 	 * This is the timeout value for ssh results to comeback.
 	 * Slower servers might need this incressed, but this number otherwise should not change.
@@ -88,24 +89,46 @@
 		else
 			$this->options['username'] = $opt['username'];
 
+		if (( !empty ($opt['public_key']) ) && ( !empty ($opt['private_key']) )) {
+			$this->options['public_key'] = $opt['public_key'];	
+			$this->options['private_key'] = $opt['private_key'];
+			
+			$this->options['hostkey'] = array("hostkey" => "ssh-rsa");
+			
+			$this->keys = true;			
+		}
+
+
 		if ( empty ($opt['password']) )
-			$this->errors->add('empty_password', __('SSH2 password is required'));
+			if ( !$this->keys )	//	 password can be blank if we are using keys
+				$this->errors->add('empty_password', __('SSH2 password is required'));
 		else
 			$this->options['password'] = $opt['password'];
+			
 	}
 
 	function connect() {
 		$this->debug("connect();");
-		$this->link = @ssh2_connect($this->options['hostname'], $this->options['port']);
-
+		if ( ! $this->keys )
+			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port']);
+		else
+			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']);	
+			
 		if ( ! $this->link ) {
 			$this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
 			return false;
 		}
 
-		if ( ! @ssh2_auth_password($this->link,$this->options['username'], $this->options['password']) ) {
-			$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
-			return false;
+		if ( !$this->keys ) {
+			if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) {
+				$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
+				return false;
+			}
+		} else {
+			if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) {
+				$this->errors->add('auth', sprintf(__('Public and Private keys incorrent for %s'), $this->options['username']));
+				return false;
+			}
 		}
 
 		$this->sftp_link = ssh2_sftp($this->link);
@@ -114,7 +137,7 @@
 	}
 
 	function run_command($link, $command, $returnbool = false) {
-		//$this->debug("run_command(".$command.",".$returnbool.");");
+		$this->debug("run_command();");
 		if(!($stream = @ssh2_exec( $link, $command . "; echo \"__COMMAND_FINISHED__\";"))) {
 			$this->errors->add('command', sprintf(__('Unable to perform command: %s'), $command));
 		} else {
@@ -136,15 +159,11 @@
 			}
 			fclose($stream);
 			$data = str_replace("__COMMAND_FINISHED__", "", $data);
-			//$this->debug("run_command(".$command."); --> \$data = " . $data);
 			if (($returnbool) && ( (int) $data )) {
-				$this->debug("Data. Returning: True");
 				return true;
 			} elseif (($returnbool) && (! (int) $data )) {
-				$this->debug("Data. Returning: False");
 				return false;
 			} else {
-				$this->debug("Data Only.");
 				return $data;
 			}
 		}
@@ -166,6 +185,7 @@
 	}
 
 	function get_contents($file, $type = '', $resumepos = 0 ) {
+		$this->debug("get_contents();");
 		$tempfile = wp_tempnam( $file );
 		if ( ! $tempfile )
 			return false;
@@ -182,6 +202,7 @@
 	}
 
 	function put_contents($file, $contents, $type = '' ) {
+		$this->debug("put_contents();");
 		$tempfile = wp_tempnam( $file );
 		$temp = fopen($tempfile, 'w');
 		if ( ! $temp )
@@ -194,6 +215,7 @@
 	}
 
 	function cwd() {
+		$this->debug("cwd();");
 		$cwd = $this->run_command($this->link, 'pwd');
 		if( $cwd )
 			$cwd = trailingslashit($cwd);
@@ -201,6 +223,7 @@
 	}
 
 	function chdir($dir) {
+		$this->debug("chdir();");
 		return $this->run_command($this->link, 'cd ' . $dir, true);
 	}
 
@@ -269,6 +292,7 @@
 	}
 
 	function delete($file, $recursive = false) {
+		$this->debug("delete();");
 		if ( $this->is_file($file) )
 			return ssh2_sftp_unlink($this->sftp_link, $file);
 		if ( ! $recursive )
@@ -283,11 +307,13 @@
 	}
 
 	function exists($file) {
+		$this->debug("exists();");
 		$list = $this->run_command($this->link, sprintf('ls -lad %s', $file));
 		return (bool) $list;
 	}
 
 	function is_file($file) {
+		$this->debug("is_file();");
 		//DO NOT RELY ON dirlist()!
 		$list = $this->run_command($this->link, sprintf('ls -lad %s', $file));
 		$list = $this->parselisting($list);
@@ -298,6 +324,7 @@
 	}
 
 	function is_dir($path) {
+		$this->debug("is_dir();");
 		//DO NOT RELY ON dirlist()!
 		$list = $this->parselisting($this->run_command($this->link, sprintf('ls -lad %s', rtrim($path, '/'))));
 		if ( ! $list )
@@ -329,8 +356,10 @@
 	function touch($file, $time = 0, $atime = 0) {
 		//Not implmented.
 	}
-
+	
 	function mkdir($path, $chmod = null, $chown = false, $chgrp = false) {
+		$this->debug("mkdir();");
+		$path = trim($path, '/');
 		if( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) )
 			return false;
 		if( $chown )
@@ -341,6 +370,7 @@
 	}
 
 	function rmdir($path, $recursive = false) {
+		$this->debug("rmdir();");
 		return $this->delete($path, $recursive);
 	}
 
@@ -463,8 +493,8 @@
 		}
 		return $ret;
 	}
-
-	function __destruct(){
+	function __destruct() {
+		$this->debug("__destruct();");
 		if ( $this->link )
 			unset($this->link);
 		if ( $this->sftp_link )
Index: wp-admin/includes/file.php
===================================================================
--- wp-admin/includes/file.php	(revision 8856)
+++ wp-admin/includes/file.php	(working copy)
@@ -405,7 +405,7 @@
 		for ( $i = count($path) - 1; $i >= 0; $i-- ) { //>=0 as the first element contains data, count()-1, as we do not want the file component
 			$tmppath = $to . implode('/', array_slice($path, 0, $i) );
 			if ( $fs->is_dir($tmppath) ) {//Found the highest folder that exists, Create from here
-				for ( $i = $i + 1; $i < count($path); $i++ ) { //< count() no file component please.
+				for ( $i = $i + 1; $i <= count($path); $i++ ) { //< count() no file component please.
 					$tmppath = $to . implode('/', array_slice($path, 0, $i) );
 					if ( ! $fs->mkdir($tmppath, 0755) )
 						return new WP_Error('mkdir_failed', __('Could not create directory'), $tmppath);
@@ -510,6 +510,10 @@
 	$credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? $_POST['username'] : $credentials['username']);
 	$credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? $_POST['password'] : $credentials['password']);
 	
+	// Check to see if we are setting the public/private keys for ssh
+	$credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : (!empty($_POST['public_key']) ? $_POST['public_key'] : $credentials['public_key']);
+	$credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : (!empty($_POST['private_key']) ? $_POST['private_key'] : $credentials['private_key']);		
+	
 	if ( strpos($credentials['hostname'], ':') )
 		list( $credentials['hostname'], $credentials['port'] ) = explode(':', $credentials['hostname'], 2);
 
@@ -522,7 +526,7 @@
 
 	if ( ! $error && !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) {
 		$stored_credentials = $credentials;
-		unset($stored_credentials['password']);
+		unset($stored_credentials['password'], $stored_credentials['private_key'], $stored_credentials['public_key']);
 		update_option('ftp_credentials', $stored_credentials);
 		return $credentials;
 	}
@@ -539,6 +543,27 @@
 		echo '<div id="message" class="error"><p>' . $error_string . '</p></div>';
 	}
 ?>
+<script type="text/javascript">
+<!--
+jQuery(function($){
+	jQuery("#ssh").click(function () {
+		jQuery("#ssh_keys").show();		
+	});
+	jQuery("#ftp").click(function () {
+		jQuery("#ssh_keys").hide();		
+	});	
+	jQuery("#ftps").click(function () {
+		jQuery("#ssh_keys").hide();		
+	});
+	jQuery(document).ready(function(){
+		if ( jQuery("#ssh:checked").length )
+		{
+			jQuery("#ssh_keys").show();
+		}
+	});
+});
+-->
+</script>
 <form action="<?php echo $form_post ?>" method="post">
 <div class="wrap">
 <h2><?php _e('FTP Connection Information') ?></h2>
@@ -556,13 +581,17 @@
 <th scope="row"><label for="password"><?php _e('Password') ?></label></th>
 <td><input name="password" type="password" id="password" value=""<?php if( defined('FTP_PASS') ) echo ' disabled="disabled"' ?> size="40" /><?php if( defined('FTP_PASS') && !empty($password) ) echo '<em>'.__('(Password not shown)').'</em>'; ?></td>
 </tr>
+<tr id="ssh_keys" valign="top" style="display:none">
+<th scope="row"><label id="keys" for="keys"><?php _e('Authentication Keys') ?></label></th>
+<td><label for="public_key"><?php _e('Public Key:') ?></label ><input name="public_key" type="text" id="public_key" value=""<?php if( defined('FTP_PUBKEY') ) echo ' disabled="disabled"' ?> size="40" /> <label for="private_key"><?php _e('Private Key:') ?></label> <input name="private_key" type="text" id="private_key" value=""<?php if( defined('FTP_PRIKEY') ) echo ' disabled="disabled"' ?> size="40" /><br/><div><?php _e('Enter the location on the server where the keys are located. If a passphrase is needed, enter that in the password field above.') ?></div></td>
+</tr>
 <tr valign="top">
 <th scope="row"><?php _e('Connection Type') ?></th>
 <td>
 <fieldset><legend class="hidden"><?php _e('Connection Type') ?> </legend>
-<p><label><input name="connection_type"  type="radio" value="ftp" <?php checked('ftp', $connection_type); ?>	/> <?php _e('FTP') ?></label><br />
-<label><input name="connection_type" type="radio" value="ftps" <?php checked('ftps', $connection_type); ?> /> <?php _e('FTPS (SSL)') ?></label><br />
-<?php if ( extension_loaded('ssh2') ) { ?><label><input name="connection_type" type="radio" value="ssh" <?php checked('ssh', $connection_type); ?> /> <?php _e('SSH') ?></label><?php } ?></p>
+<p><label><input id="ftp" name="connection_type"  type="radio" value="ftp" <?php checked('ftp', $connection_type); ?>	/> <?php _e('FTP') ?></label><br />
+<label><input id="ftps" name="connection_type" type="radio" value="ftps" <?php checked('ftps', $connection_type); ?> /> <?php _e('FTPS (SSL)') ?></label><br />
+<?php if ( extension_loaded('ssh2') ) { ?><label><input id="ssh" name="connection_type" type="radio" value="ssh" <?php checked('ssh', $connection_type); ?> /> <?php _e('SSH') ?></label><?php } ?></p>
 </fieldset>
 </td>
 </tr>
