gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r11250: add initial SSH support with


From: rob
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11250: add initial SSH support with test case.
Date: Mon, 13 Jul 2009 18:26:55 -0600
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 11250
committer: address@hidden
branch nick: trunk
timestamp: Mon 2009-07-13 18:26:55 -0600
message:
  add initial SSH support with test case.
added:
  libnet/sshclient.cpp
  libnet/sshclient.h
  testsuite/network.all/test_ssh.cpp
modified:
  Makefile.am
  configure.ac
  libnet/Makefile.am
  libnet/network.cpp
  libnet/network.h
  testsuite/network.all/Makefile.am
  testsuite/network.all/test_ssl.cpp
    ------------------------------------------------------------
    revno: 11246.1.1
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 11:24:54 -0600
    message:
      build sshclient
    modified:
      libnet/Makefile.am
    ------------------------------------------------------------
    revno: 11246.1.2
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 11:25:22 -0600
    message:
      add --enable-ssh option and flags.
    modified:
      Makefile.am
      configure.ac
    ------------------------------------------------------------
    revno: 11246.1.3
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 11:26:31 -0600
    message:
      add initial SSH client support.
    added:
      libnet/sshclient.cpp
      libnet/sshclient.h
    ------------------------------------------------------------
    revno: 11246.1.4
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 20:26:18 -0600
    message:
      add initial SSH support, improved SSLsupport.
    modified:
      libnet/network.cpp
      libnet/network.h
    ------------------------------------------------------------
    revno: 11246.1.5
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 20:28:19 -0600
    message:
      add initial SSH support files
    modified:
      libnet/sshclient.cpp
      libnet/sshclient.h
    ------------------------------------------------------------
    revno: 11246.1.6
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 20:29:36 -0600
    message:
      build with optional SSH and SSL support.
    modified:
      libnet/Makefile.am
    ------------------------------------------------------------
    revno: 11246.1.7
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 20:30:12 -0600
    message:
      add a SSH testc
    added:
      testsuite/network.all/test_ssh.cpp
    ------------------------------------------------------------
    revno: 11246.1.8
    committer: address@hidden
    branch nick: ssh
    timestamp: Sun 2009-07-12 20:31:29 -0600
    message:
      use the correct variables.
    modified:
      configure.ac
    ------------------------------------------------------------
    revno: 11246.1.9
    committer: address@hidden
    branch nick: ssh
    timestamp: Mon 2009-07-13 15:21:10 -0600
    message:
      fix typo in option.
    modified:
      testsuite/network.all/test_ssl.cpp
    ------------------------------------------------------------
    revno: 11246.1.10
    committer: address@hidden
    branch nick: ssh
    timestamp: Mon 2009-07-13 15:22:03 -0600
    message:
      add SSH test case that sucessfully makes an SSH client side connection to 
a server.
    modified:
      testsuite/network.all/Makefile.am
      testsuite/network.all/test_ssh.cpp
    ------------------------------------------------------------
    revno: 11246.1.11
    committer: address@hidden
    branch nick: ssh
    timestamp: Mon 2009-07-13 15:22:34 -0600
    message:
      make SSH support minimally functional.
    modified:
      libnet/sshclient.cpp
      libnet/sshclient.h
=== modified file 'Makefile.am'
--- a/Makefile.am       2009-07-07 07:52:53 +0000
+++ b/Makefile.am       2009-07-12 17:25:22 +0000
@@ -356,6 +356,10 @@
        @echo " SSL_CFLAGS is $(SSL_CFLAGS)"
        @echo " SSL_LIBS is $(SSL_LIBS)"
 endif
+if BUILD_SSH
+       @echo " SSH_CFLAGS is $(SSH_CFLAGS)"
+       @echo " SSH_LIBS is $(SSH_LIBS)"
+endif
 if BUILD_GTK_GUI
 if HAVE_XV
        @echo " Supported GUI: GTK (+XVideo)"

=== modified file 'configure.ac'
--- a/configure.ac      2009-07-08 07:40:21 +0000
+++ b/configure.ac      2009-07-13 02:31:29 +0000
@@ -1220,13 +1220,35 @@
 dnl  Select SSL support
 dnl --------------------------------------------------------
 
+dnl Enable using libssh with libnet
+AC_ARG_ENABLE(ssh,
+  AC_HELP_STRING([--enable-ssh], [Enable using SSH for network 
authentication]),
+[case "${enableval}" in
+  yes) build_ssh=yes ;;
+  no)  build_ssh=no ;;
+  *)   AC_MSG_ERROR([bad value ${enableval} for --enable-ssh option]) ;;
+esac], build_ssh=no)
+
+AM_CONDITIONAL(BUILD_SSH, test x"${build_ssh}" = xyes)
+if test x"${build_ssh}" = xyes; then
+  GNASH_PKG_FIND(ssh, [libssh/libssh.h], [libssh library], ssh_socket_init)
+dnl  GNASH_PKG_FIND(poppler, [popt.h], [Poppler library], poppler_init)
+fi
+if test x"${has_ssh}" = x"yes"; then
+  AC_DEFINE([USE_SSH], [1], [Use SSH for authentication])
+fi
+
+dnl --------------------------------------------------------
+dnl  Select SSL support
+dnl --------------------------------------------------------
+
 dnl Enable using OpenSSL with libnet.
 AC_ARG_ENABLE(ssl,
   AC_HELP_STRING([--enable-ssl], [Enable using OpenSSL directly]),
 [case "${enableval}" in
   yes) build_ssl=yes ;;
   no)  build_ssl=no ;;
-  *)   AC_MSG_ERROR([bad value ${enableval} for --enable-openssl option]) ;;
+  *)   AC_MSG_ERROR([bad value ${enableval} for --enable-ssl option]) ;;
 esac], build_ssl=no)
 
 with_cert=
@@ -1244,7 +1266,9 @@
 if test x"${build_ssl}" = xyes; then
   GNASH_PKG_FIND(ssl, [openssl/ssl.h], [OpenSSL library], SSL_library_init)
 fi
-
+if test x"${has_ssl}" = x"yes"; then
+  AC_DEFINE([USE_SSL], [1], [Use SSL for authentication])
+fi
 
 dnl -----------------------------------------------------------
 dnl   Verify dependencies for requested GUIs are met, and
@@ -3350,6 +3374,19 @@
   fi
 fi
 
+if test x${build_ssh} = xyes; then
+  if test x"${has_ssh}" = xyes; then
+    if test x"${SSH_CFLAGS}" = xyes; then
+      echo "        SSH flags are: default"
+    else
+      echo "        SSH flags are: $SSH_CFLAGS"
+    fi
+    echo "        SSH libs are: $SSH_LIBS"
+  else
+    echo "        ERROR: No SSH development package is installed, but it's 
enabled." >&3
+  fi
+fi
+
 if test x"${build_all_as3}" = x"yes"; then
   echo "        Building the entire ActionScript class libary"
 else

=== modified file 'libnet/Makefile.am'
--- a/libnet/Makefile.am        2009-06-11 03:08:00 +0000
+++ b/libnet/Makefile.am        2009-07-13 02:29:36 +0000
@@ -26,9 +26,10 @@
        ../libbase/libgnashbase.la \
        ../libamf/libgnashamf.la \
        $(LIBLTDL) \
+       $(SSH_LIBS) \
+       $(SSL_LIBS) \
        $(GLIB_LIBS) \
        $(CURL_LIBS) \
-       $(SSL_LIBS) \
        $(LIBADD_DL) \
        $(BOOST_LIBS) \
        $(PTHREAD_LIBS)
@@ -41,6 +42,7 @@
         -I$(top_srcdir)/libcore \
         -DLOCALEDIR=\"$(localedir)\" \
        $(SSL_CFLAGS) \
+       $(SSH_CFLAGS) \
        $(CURL_CFLAGS) \
        $(BOOST_CFLAGS) \
        $(PTHREAD_CFLAGS)
@@ -78,6 +80,11 @@
 noinst_HEADERS += sslclient.h
 endif
 
+if BUILD_SSH
+libgnashnet_la_SOURCES += sshclient.cpp # sshserver.cpp
+noinst_HEADERS += sshclient.h # sshserver.h
+endif
+
 if WIN32
   AM_LDFLAGS += -no-undefined
 endif

=== modified file 'libnet/network.cpp'
--- a/libnet/network.cpp        2009-06-23 21:37:39 +0000
+++ b/libnet/network.cpp        2009-07-13 02:26:18 +0000
@@ -899,7 +899,16 @@
             return 0;
         }
 
-        ret = read(fd, buffer, nbytes);
+#ifdef USE_SSL
+       if (_ssl) {
+           ret = _ssl->sslRead(buffer, nbytes);
+       } else {
+           ret = read(fd, buffer, nbytes);
+       }
+#else
+       ret = read(fd, buffer, nbytes);
+#endif
+
        // If we read zero bytes, the network may be closed, as we returned 
from the select()
         if (ret == -1) {
             log_error (_("The socket for fd #%d was never available for 
reading data"), fd);
@@ -1057,8 +1066,15 @@
            return 0;
         }
 
-        ret = write(fd, bufptr, nbytes);
-
+#ifdef USE_SSL
+       if (_ssl) {
+           ret = _ssl->sslWrite(buffer, nbytes);
+       } else {
+           ret = write(fd, bufptr, nbytes);
+       }
+#else
+       ret = write(fd, bufptr, nbytes);
+#endif
         if (ret == 0) {
             log_error (_("Wrote zero out of %d bytes to fd #%d: %s"), 
                nbytes, fd, strerror(errno));
@@ -1410,6 +1426,92 @@
     // toggleDebug(true);
 }
 
+#ifdef USE_SSL
+bool
+Network::initSSL(std::string &hostname)
+{
+    GNASH_REPORT_FUNCTION;
+    string nothing;
+    initSSL(hostname, nothing);
+}
+
+bool
+Network::initSSL(std::string &hostname, std::string &password)
+{
+    GNASH_REPORT_FUNCTION;
+    string nothing;
+
+    initSSL(hostname, password, nothing, nothing, nothing, true);
+}
+
+bool
+Network::initSSL(std::string &hostname, std::string &password, bool auth)
+{
+    GNASH_REPORT_FUNCTION;
+
+    string nothing;
+    initSSL(hostname, password, nothing, nothing, nothing, auth);
+}
+
+bool
+Network::initSSL(std::string &hostname, std::string &passwd, 
+                std::string &keyfile, std::string &calist,
+                std::string &rootpath, bool auth)
+{
+    GNASH_REPORT_FUNCTION;
+
+    // FIXME: make sure we have a connection
+
+    if (_sockfd == 0) {
+       if ((_sockfd = createClient(hostname, SSL_PORT) == false)) {
+           log_error("Can't connect to server %s", hostname);
+           return false;
+       }
+    }
+
+    if (!_ssl) {
+       _ssl.reset(new SSLClient);
+    }
+
+    if (!hostname.empty()) {
+       _ssl->setHostname(hostname);
+    } else {
+       log_debug("Using default hostname: \"%s\"", _host);
+    }
+    if (!keyfile.empty()) {
+       _ssl->setKeyfile(keyfile);
+    } else {
+       log_debug("Using default keyfile: \"%s\"", _ssl->getKeyfile());
+    }
+    if (!calist.empty()) {
+       _ssl->setCAlist(calist);
+    } else {
+       log_debug("Using default CA List: \"%s\"", _ssl->getCAlist());
+    }
+
+    if (!passwd.empty()) {
+       _ssl->setPassword(passwd);
+    } else {
+       log_debug("Using default Password: \"%s\"", _ssl->getPassword());
+    }
+    if (!rootpath.empty()) {
+       _ssl->setRootPath(rootpath);
+    } else {
+       log_debug("Using default Root Path to PEM files: \"%s\"",
+                 _ssl->getRootPath());
+    }
+
+    if (_ssl->sslConnect(_sockfd)) {
+        log_debug("Connected to SSL server");
+    } else {
+        log_error("Couldn't connect to SSL server");
+       return false;
+    }
+
+    // If we got this far, everthing worked
+    return true;
+}
+#endif
 
 // Trap Control-C so we can cleanly exit
 static void

=== modified file 'libnet/network.h'
--- a/libnet/network.h  2009-06-23 21:37:39 +0000
+++ b/libnet/network.h  2009-07-13 02:26:18 +0000
@@ -22,7 +22,6 @@
 #include "gnashconfig.h"
 #endif
 
-#include <boost/thread/mutex.hpp>
 #if !defined(HAVE_WINSOCK_H) || defined(__OS2__)
 # include <sys/types.h>
 # include <netinet/in.h>
@@ -43,14 +42,25 @@
 # include <io.h>
 #endif
 
-#include "dsodefs.h" //For DSOEXPORT.
 #include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
 #include <boost/cstdint.hpp>
+#include <boost/thread/mutex.hpp>
 #include <vector>
 #include <cassert>
 #include <string>
 #include <map>
 
+#ifdef USE_SSH
+# include "sshclient.h"
+#endif
+
+#ifdef USE_SSL
+# include "sslclient.h"
+#endif
+
+#include "dsodefs.h" //For DSOEXPORT.
+
 namespace amf {
 class Buffer;
 }
@@ -59,14 +69,26 @@
 ///    This is the main namespace for Gnash and it's libraries.
 namespace gnash {
 
+// forward declare the encryption protocols
+class SSLClient;
+class SSHClient;
+
+// Define the default ports
+const short SSL_PORT    = 443;
+const short SSH_PORT    = 22;
+const short HTTP_PORT   = 80;
+
+// Delay Tolerant Networking Research Group, http://www.dtnrg.org
+const short DTN1_PORT   = 2445;
+const short DTN2_PORT   = 4556;
+
 // Define the ports for the RTMP protocols
 const short ADMIN_PORT  = 1111;
 const short RTMP_PORT   = 1935;
 const short RTMPE_PORT  = 1935;
-const short RTMPT_PORT  = 80;
-const short RTMPTE_PORT = 80;
-const short RTMPTS_PORT = 443;
-const short SSL_PORT    = 4433;
+const short RTMPT_PORT  = HTTP_PORT;
+const short RTMPTE_PORT = HTTP_PORT;
+const short RTMPTS_PORT = SSL_PORT;
 
 #ifdef __OS2__
  typedef int    socklen_t;
@@ -274,6 +296,15 @@
     entry_t *getEntry(int fd);
     
 //    void executePollFD(int index) { _handler[index](); ];
+
+#ifdef USE_SSL
+    bool initSSL(std::string &hostname);
+    bool initSSL(std::string &hostname, std::string &password);
+    bool initSSL(std::string &hostname, std::string &password, bool auth);
+    bool initSSL(std::string &hostname, std::string &password, 
+                std::string &keyfile, std::string &calist,
+                std::string &rootpath, bool auth);
+#endif
     
  protected:
     in_addr_t   _ipaddr;
@@ -296,6 +327,12 @@
     // This is the mutex that controls access to the que.
     boost::mutex       _poll_mutex;
     boost::mutex       _net_mutex;
+#ifdef USE_SSL
+    boost::scoped_ptr<SSLClient> _ssl;
+#endif
+#ifdef USE_SSH
+    boost::scoped_ptr<SSHClient> _ssh;
+#endif
 };
 
 } // end of gnash namespace

=== added file 'libnet/sshclient.cpp'
--- a/libnet/sshclient.cpp      1970-01-01 00:00:00 +0000
+++ b/libnet/sshclient.cpp      2009-07-13 21:22:34 +0000
@@ -0,0 +1,355 @@
+// ssh.cpp:  HyperText Transport Protocol handler for Cygnal, for Gnash.
+// 
+//   Copyright (C) 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <boost/thread/mutex.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/array.hpp>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <cstring>
+#include <sstream>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <algorithm>
+#include <cstdlib> // getenv
+
+#include "GnashSystemIOHeaders.h" // read()
+#include "sshclient.h"
+#include "amf.h"
+#include "element.h"
+#include "cque.h"
+#include "log.h"
+#include "network.h"
+#include "utility.h"
+#include "buffer.h"
+#include "diskstream.h"
+#include "cache.h"
+
+extern "C" {
+# include <libssh/libssh.h>
+# include <libssh/sftp.h>
+}
+
+#if defined(_WIN32) || defined(WIN32)
+# define __PRETTY_FUNCTION__ __FUNCDNAME__
+# include <winsock2.h>
+# include <direct.h>
+#else
+# include <unistd.h>
+# include <sys/param.h>
+#endif
+
+using namespace gnash;
+using namespace std;
+
+static boost::mutex stl_mutex;
+
+namespace gnash
+{
+
+SSHClient::SSHClient()
+    : _hostname("localhost"),
+      _need_server_auth(true),
+      _state(0),
+      _session(0),
+      _options(0)
+{
+    GNASH_REPORT_FUNCTION;
+
+    // Set the default user name
+    setUser();
+}
+
+SSHClient::~SSHClient()
+{
+    GNASH_REPORT_FUNCTION;
+    
+    sshShutdown();
+}
+
+void
+SSHClient::setUser()
+{
+    GNASH_REPORT_FUNCTION;
+    string user = std::getenv("USER");
+    if (!user.empty()) {
+       _user = user;
+    }    
+}
+
+// Read bytes from the already opened SSH connection
+int
+SSHClient::sshRead(amf::Buffer &buf)
+{
+    GNASH_REPORT_FUNCTION;
+
+    return sshRead(buf.reference(), buf.allocated());
+}
+
+int
+SSHClient::sshRead(boost::uint8_t */* buf */, size_t /* size */)
+{
+    GNASH_REPORT_FUNCTION;
+    
+//     ERR_clear_error();
+//     int ret = SSH_read(_ssh.get(), buf, size);
+//     if (ret < 0) {
+//     log_error("Error was: \"%s\"!", 
ERR_reason_error_string(ERR_get_error()));
+//     }
+    
+//    return ret;
+}
+
+// Write bytes to the already opened SSH connection
+int
+SSHClient::sshWrite(amf::Buffer &buf)
+{
+    GNASH_REPORT_FUNCTION;
+
+    return sshWrite(buf.reference(), buf.allocated());
+}
+
+int
+SSHClient::sshWrite(const boost::uint8_t */* buf */, size_t /* length */)
+{
+    GNASH_REPORT_FUNCTION;
+    
+//     ERR_clear_error();
+//     int ret = SSH_write(_ssh.get(), buf, length);
+//     if (ret < 0) {
+//     log_error("Error was: \"%s\"!", 
ERR_reason_error_string(ERR_get_error()));
+//     }
+//    return ret;
+}
+
+// Shutdown the Context for this connection
+bool
+SSHClient::sshShutdown()
+{
+    GNASH_REPORT_FUNCTION;
+
+    if (_session) {
+       ssh_disconnect(_session);
+       ssh_finalize();
+    }
+
+    _session = 0;
+//     return closeNet();
+    return true;
+}
+
+// sshConnect() is how the client connects to the server 
+bool
+SSHClient::sshConnect(int fd)
+{
+    return sshConnect(fd, _hostname);
+}
+
+bool
+SSHClient::sshConnect(int fd, std::string &hostname)
+{
+    GNASH_REPORT_FUNCTION;
+    char *password;
+    char *banner;
+    char *hexa;
+    char buf[10];
+
+//    _options.reset(ssh_options_new());
+    // Setup the options to for this SSH session
+    _options = ssh_options_new();
+
+    // We always need a hostname to connect to
+    if (ssh_options_set_host(_options, hostname.c_str()) < 0) {
+       log_error("Couldn't set hostname option");
+       ssh_options_free(_options);
+       return false;
+    }
+
+    // We always need a user name for the connection
+    if (_user.empty()) {
+       if (ssh_options_set_username(_options, _user.c_str()) < 0) {
+           log_error("Couldn't set user name option");
+           ssh_options_free(_options);
+           return false;
+       }
+    }
+    
+    // Start a new session
+    _session = ssh_new();
+    ssh_set_options(_session, _options);
+    if(ssh_connect(_session)){
+        log_error("Connection failed : %s\n", ssh_get_error(_session));
+       sshShutdown();
+        return false;
+    }
+
+    _state = ssh_is_server_known(_session);
+
+    unsigned char *hash = 0;
+    int hlen = ssh_get_pubkey_hash(_session, &hash);
+    if (hlen < 0) {
+       sshShutdown();
+       return false;
+    }
+    switch(_state){
+      case SSH_SERVER_KNOWN_OK:        // ok
+         log_debug("SSH Server is cyrrently known: %d", _state);
+         break; 
+      case SSH_SERVER_KNOWN_CHANGED:
+         log_error("Host key for server changed : server's one is now: ");
+         ssh_print_hexa("Public key hash", hash, hlen);
+         free(hash);
+         log_error("For security reason, connection will be stopped");
+         sshShutdown();
+         return false;;
+      case SSH_SERVER_FOUND_OTHER:
+         log_error("The host key for this server was not found but an other 
type of key exists.");
+         log_error("An attacker might change the default server key to confuse 
your client"
+                   "into thinking the key does not exist\n"
+                   "We advise you to rerun the client with -d or -r for more 
safety.");
+         sshShutdown();
+         return false;;
+      case SSH_SERVER_NOT_KNOWN:
+         hexa = ssh_get_hexa(hash, hlen);
+         free(hash);
+#if 0
+         log_error("The server is unknown. Do you trust the host key ? 
(yes,no)");
+         log_error("Public key hash: %s", hexa);
+         free(hexa);
+         fgets(buf, sizeof(buf), stdin);
+         if(strncasecmp(buf, "yes", 3) != 0){
+             sshShutdown();
+             return false;
+         }
+         log_error("This new key will be written on disk for further usage. do 
you agree? (yes,no) ");
+         fgets(buf, sizeof(buf), stdin);
+         if(strncasecmp(buf, "yes", 3)==0){
+             if(ssh_write_knownhost(_session))
+                 log_error("%s", ssh_get_error(_session));
+         }
+#else
+         if(ssh_write_knownhost(_session)) {
+             log_error("%s", ssh_get_error(_session));
+         }
+#endif  
+         break;
+      case SSH_SERVER_ERROR:
+         free(hash);
+         log_error("%s", ssh_get_error(_session));
+         sshShutdown();
+         return false;
+    }
+    
+    free(hash);
+    
+    ssh_userauth_none(_session, NULL);
+    
+    int auth = ssh_auth_list(_session);
+
+//    log_debug("auth: 0x%04x", auth);
+    log_debug("supported auth methods: ");
+    if (auth & SSH_AUTH_METHOD_PUBLICKEY) {
+      log_debug("\tpublickey");
+    }
+    if (auth & SSH_AUTH_METHOD_INTERACTIVE) {
+      log_debug("\tkeyboard-interactive");
+    }
+
+    /* no ? you should :) */
+    auth=ssh_userauth_autopubkey(_session, NULL);
+    if(auth == SSH_AUTH_ERROR){
+        log_debug("Authenticating with pubkey: %s",ssh_get_error(_session));
+       ssh_finalize();
+        return false;
+    }
+    banner = ssh_get_issue_banner(_session);
+    if(banner){
+        log_debug("%s", banner);
+        free(banner);
+    }
+    if(auth != SSH_AUTH_SUCCESS){
+//        auth = auth_kbdint(_session);
+        if(auth == SSH_AUTH_ERROR){
+            log_error("authenticating with keyb-interactive: %s",
+                     ssh_get_error(_session));
+           ssh_finalize();
+            return false;
+        }
+    }
+    if(auth != SSH_AUTH_SUCCESS){
+        password = getpass("Password: ");
+        if(ssh_userauth_password(_session, NULL, password) != 
SSH_AUTH_SUCCESS){
+            log_error("Authentication failed: %s",ssh_get_error(_session));
+            ssh_disconnect(_session);
+                ssh_finalize();
+            return false;
+        }
+        memset(password, 0, strlen(password));
+    }
+    ssh_log(_session, SSH_LOG_FUNCTIONS, "Authentication success");
+
+#if 0
+    if(strstr(argv[0],"sftp")){
+        sftp = 1;
+        ssh_log(_session, SSH_LOG_FUNCTIONS, "Doing sftp instead");
+    }
+    if(!sftp){
+        if(!cmds[0])
+            shell(_session);
+        else
+            batch_shell(_session);
+    }
+    else
+        do_sftp(_session);
+    if(!sftp && !cmds[0])
+        do_cleanup(0);
+#endif
+    
+    return true;
+}
+
+void
+SSHClient::dump() {
+//    GNASH_REPORT_FUNCTION;
+    
+    boost::mutex::scoped_lock lock(stl_mutex);
+  
+    log_debug (_("==== The SSH header breaks down as follows: ===="));
+
+    ssh_version(0);
+}
+
+} // end of gnash namespace
+
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== added file 'libnet/sshclient.h'
--- a/libnet/sshclient.h        1970-01-01 00:00:00 +0000
+++ b/libnet/sshclient.h        2009-07-13 21:22:34 +0000
@@ -0,0 +1,126 @@
+// 
+//   Copyright (C) 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifndef GNASH_LIBNET_SSH_H
+#define GNASH_LIBNET_SSH_H
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <string>
+#include <boost/array.hpp>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/cstdint.hpp>
+#include <sstream>
+
+extern "C" {
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
+}
+
+#include "cque.h"
+#include "network.h"
+#include "buffer.h"
+
+namespace gnash
+{
+
+extern const char *ROOTPATH;
+extern const char *HOST;
+extern const char *CA_LIST;
+extern const char *RANDOM;
+extern const char *KEYFILE;
+extern const size_t SSH_PASSWD_SIZE;
+
+class DSOEXPORT SSHClient
+{
+public:
+    typedef enum {NO_AUTHTYPE,  DSS, RSA} authtype_t;
+    typedef enum {NO_TRANSPORT, RAW, SFTP} transport_type_t;
+    
+    SSHClient();
+    ~SSHClient();
+
+    // Read bytes from the already opened SSH connection
+    int sshRead(amf::Buffer &buf);
+    int sshRead(boost::uint8_t *buf, size_t length);
+    int sshRead(std::string &buf);
+
+    // Write bytes to the already opened SSH connection
+    int sshWrite(amf::Buffer &buf);
+    int sshWrite(const boost::uint8_t *buf, size_t length);
+    int sshWrite(std::string &buf);
+
+    // Shutdown the Context for this connection
+    bool sshShutdown();
+
+    // sshConnect() is how the client connects to the server 
+    bool sshConnect(int fd);
+    bool sshConnect(int fd, std::string &hostname);
+    
+    void setUser();
+    void setUser(std::string name) { _user = name; };
+    std::string &getUser() { return _user; };
+    
+    void setPassword(std::string pw) { _password = pw; };
+    std::string &getPassword() { return _password; };
+    
+    void setHostname(std::string name) { _hostname = name; };
+    std::string &getHostname() { return _hostname; };
+    
+    void setServerAuth(bool flag) { _need_server_auth = flag; };
+    bool getServerAuth() { return _need_server_auth; };
+    
+    void setAuthType(authtype_t type) { _authtype = type; };
+    authtype_t getAuthType() { return _authtype; };
+    
+    void setTransportType(transport_type_t type) { _transporttype = type; };
+    transport_type_t getTransportType() { return _transporttype; };
+    
+    void dump();
+ private:
+    std::string                _hostname;
+    std::string                _user;
+    std::string                _password;
+    bool               _need_server_auth;
+    authtype_t         _authtype;
+    transport_type_t   _transporttype;
+    int                        _state;
+#if 0
+    boost::shared_ptr<SSH_SESSION> _session;
+    boost::shared_ptr<SSH_OPTIONS> _options;
+#else
+    SSH_SESSION *_session;
+    SSH_OPTIONS *_options;
+#endif
+};
+    
+} // end of gnash namespace
+
+// end of GNASH_LIBNET_SSH_H
+#endif 
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

=== modified file 'testsuite/network.all/Makefile.am'
--- a/testsuite/network.all/Makefile.am 2009-06-15 03:21:27 +0000
+++ b/testsuite/network.all/Makefile.am 2009-07-13 21:22:03 +0000
@@ -65,6 +65,7 @@
        Dejagnu \
        Dejagnu.swf \
        test_ssl \
+       test_ssh \
        $(NULL)
 
 check_SCRIPTS = \
@@ -116,6 +117,12 @@
        $(top_builddir)/libamf/libgnashamf.la \
        $(top_builddir)/libnet/libgnashnet.la
 
+test_ssh_SOURCES = test_ssh.cpp
+test_ssh_LDADD = \
+       $(top_builddir)/libbase/libgnashbase.la \
+       $(top_builddir)/libamf/libgnashamf.la \
+       $(top_builddir)/libnet/libgnashnet.la
+
 test_ssl_DEPENDENCIES = site-update
 
 clean-local: 

=== added file 'testsuite/network.all/test_ssh.cpp'
--- a/testsuite/network.all/test_ssh.cpp        1970-01-01 00:00:00 +0000
+++ b/testsuite/network.all/test_ssh.cpp        2009-07-13 21:22:03 +0000
@@ -0,0 +1,271 @@
+// 
+//   Copyright (C) 2009 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#ifdef HAVE_DEJAGNU_H
+
+//#include <netinet/in.h>
+#include <boost/shared_ptr.hpp>
+#include <string>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <iostream>
+#include <string>
+#include <cstdio>
+
+#include "as_object.h"
+#include "dejagnu.h"
+#include "http.h"
+#include "log.h"
+#include "buffer.h"
+#include "network.h"
+#include "element.h"
+#include "sol.h"
+#include "arg_parser.h"
+#include "sshclient.h"
+#include "sslclient.h"
+
+using namespace amf;
+using namespace gnash;
+using namespace std;
+
+static void usage (void);
+
+static TestState runtest;
+
+static string infile;
+
+static void test_client();
+static SSHClient client;
+static Network net;
+
+LogFile& dbglogfile = LogFile::getDefaultInstance();
+
+int
+main(int argc, char *argv[])
+{
+    const Arg_parser::Option opts[] =
+        {
+            { 'h', "help",          Arg_parser::no  },
+            { 'v', "verbose",       Arg_parser::no  },
+            { 's', "hostname",      Arg_parser::yes },
+            { 'o', "port",          Arg_parser::yes },
+            { 'p', "password",      Arg_parser::yes },
+            { 'u', "user",          Arg_parser::yes },
+            { 'd', "dss",           Arg_parser::no },
+            { 'r', "rsa",           Arg_parser::no },
+            { 'f', "sftp",          Arg_parser::no },
+            { 'a', "raw",           Arg_parser::no },
+            { 'n', "netdebug",      Arg_parser::no },
+        };
+    
+    Arg_parser parser(argc, argv, opts);
+    if( ! parser.error().empty() ) {
+        cout << parser.error() << endl;
+        exit(EXIT_FAILURE);
+    }
+    
+    for( int i = 0; i < parser.arguments(); ++i ) {
+        const int code = parser.code(i);
+        try {
+            switch( code ) {
+              case 'h':
+                  usage ();
+                  exit(EXIT_SUCCESS);
+              case 'v':
+                    dbglogfile.setVerbosity();
+                    log_debug(_("Verbose output turned on"));
+                    break;
+              case 's':
+                  client.setHostname(parser.argument(i));
+                  log_debug(_("Hostname for SSH connection is: %s"),
+                            client.getHostname());
+                  break;
+              case 'o':
+                  net.setPort(parser.argument<short>(i));
+                  log_debug(_("Port for SSH connections is: %hd"),
+                            net.getPort());
+                  break; 
+              case 'p':
+                  client.setPassword(parser.argument(i));
+                  log_debug(_("SSH password is: %s"),
+                            client.getPassword());
+                  break;
+              case 'u':
+                  client.setUser(parser.argument(i));
+                  log_debug(_("SSH user is: %s"),
+                            client.getUser());
+                  break;
+              case 'd':
+                  client.setAuthType(SSHClient::DSS);
+                  log_debug(_("SSH Authentication type is: %d"),
+                            client.getAuthType());
+                  break;
+              case 'r':
+                  client.setAuthType(SSHClient::RSA);
+                  log_debug(_("SSH Authentication type is: %d"),
+                            client.getAuthType());
+                  break;
+              case 'a':
+                  client.setTransportType(SSHClient::RAW);
+                  log_debug(_("SSH Transport type is: %d"),
+                            client.getTransportType());
+                  break;
+              case 'f':
+                  client.setTransportType(SSHClient::SFTP);
+                  log_debug(_("SSH Transport type is: %d"),
+                            client.getTransportType());
+                  break;
+              case 'n':
+                  net.toggleDebug(true);
+                  break;
+              case 0:
+                  infile = parser.argument(i);
+                  log_debug(_("Input file for testing the SSH connection is: 
%s"), infile);
+                  break;
+            }
+        }
+        
+        catch (Arg_parser::ArgParserException &e) {
+            cerr << _("Error parsing command line options: ") << e.what() << 
endl;
+            cerr << _("This is a Gnash bug.") << endl;
+        }
+    }
+    
+    test_client();
+}
+
+static void test_client()
+{
+    size_t ret;
+    bool giveup = false;    
+
+    // Make a tcp/ip connect to the server
+    if (net.createClient(client.getHostname(), SSH_PORT) == false) {
+       log_error("Can't connect to server %s", client.getHostname());
+    }
+
+    if (client.sshConnect(net.getFileFd())) {
+        runtest.pass("Connected to SSH server");
+    } else {
+        runtest.fail("Couldn't connect to SSH server");
+        giveup = true;
+    }
+
+    // I haven't seen a password with the first character set to
+    // zero ever. so we assume it got set correctly by the callback.
+    if (client.getPassword()[0] != 0) {
+        runtest.pass("Password was set for SSH connection");
+    } else {
+        if (giveup) {
+            runtest.unresolved("Password wasn't set for SSH connection");
+        } else {
+            runtest.fail("Password wasn't set for SSH connection");
+        }
+    }
+
+#if 0
+    if (giveup) {
+        runtest.unresolved("Cert didn't match hostfor SSH connection");
+    } else {
+        if (client.checkCert()) {
+            runtest.xpass("Cert matched host for SSH connection");
+        } else {
+            runtest.xfail("Cert didn't match host for SSH connection");
+        }
+    }
+
+    HTTP http;
+
+    if (giveup) {
+        runtest.unresolved("Couldn't write to SSH connection");
+    } else {
+        amf::Buffer &request = http.formatRequest("/crossdomain.xml", 
HTTP::HTTP_GET);
+
+        if ((ret = client.sshWrite(request)) == request.allocated()) {
+            runtest.pass("Wrote bytes to SSH connection");
+        } else {
+            runtest.fail("Couldn't write to SSH connection.");
+        }
+    }
+#endif
+    
+#if 0
+    // This blocks forever unless data is received.
+    if (giveup) {
+        runtest.unresolved("Couldn't read bytes from SSH connection");
+    } else {
+        amf::Buffer buf;
+        if ((ret = client.sshRead(buf)) > 0) {
+            runtest.pass("Read bytes from SSH connection");
+        } else {
+            runtest.fail("Couldn't read bytes to SSH connection.");
+        }
+    }
+#endif
+
+    if (giveup) {
+        runtest.unresolved("Couldn't shutdown SSH connection");
+    } else {
+        if (client.sshShutdown()) {
+            runtest.pass("Shutdown SSH connection");
+        } else {
+            runtest.fail("Couldn't shutdown SSH connection");
+        }
+    }
+    
+}
+
+static void
+usage (void)
+{
+    cerr << "This program tests SSH support in the libnet library." << endl;
+    cerr << "Usage: test_ssh [hvsocpkwar]" << endl;
+    cerr << "-h\tHelp" << endl;
+    cerr << "-v\tVerbose" << endl;
+    cerr << "-s\thostname" << endl;
+    cerr << "-o\tPort" << endl;
+    cerr << "-p\tPassword" << endl;
+    cerr << "-u\tUser" << endl;
+    cerr << "-r\tUse RSA" << endl;
+    cerr << "-d\tUse DSS" << endl;
+    cerr << "-f\tUse SFTP for transport" << endl;
+    cerr << "-a\tUse RAW for transport" << endl;
+    cerr << "-n\tEnable network debug" << endl << endl;
+    
+    cerr << "Libssh version is: " << ssh_version(0) << endl;
+    exit (-1);
+}
+
+#else
+
+int
+main(int /*argc*/, char /* *argv[]*/)
+{
+  // nop
+    cerr << "This program needs to have DejaGnu installed!" << endl;
+    return 0;  
+}
+
+#endif

=== modified file 'testsuite/network.all/test_ssl.cpp'
--- a/testsuite/network.all/test_ssl.cpp        2009-06-17 00:54:07 +0000
+++ b/testsuite/network.all/test_ssl.cpp        2009-07-13 21:21:10 +0000
@@ -73,7 +73,7 @@
             { 'o', "port",          Arg_parser::yes },
             { 'c', "cert",          Arg_parser::yes },
             { 'p', "pem",           Arg_parser::yes },
-            { 'k', "leyfile",       Arg_parser::yes },
+            { 'k', "keyfile",       Arg_parser::yes },
             { 'w', "password",      Arg_parser::yes },
             { 'a', "calist",        Arg_parser::yes },
             { 'r', "rootpath",      Arg_parser::yes },


reply via email to

[Prev in Thread] Current Thread [Next in Thread]