[Top][All Lists]
[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 },
- [Gnash-commit] /srv/bzr/gnash/trunk r11250: add initial SSH support with test case.,
rob <=