From: kupcevic@sourceware.org <kupcevic@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] conga ./conga.spec.in.in luci/Makefile luci/si ...
Date: 8 Dec 2006 18:27:36 -0000 [thread overview]
Message-ID: <20061208182736.29493.qmail@sourceware.org> (raw)
CVSROOT: /cvs/cluster
Module name: conga
Branch: RHEL5
Changes by: kupcevic at sourceware.org 2006-12-08 18:27:32
Modified files:
. : conga.spec.in.in
luci : Makefile
luci/site : Makefile
luci/site/luci/Extensions: HelperFunctions.py StorageReport.py
ricci_communicator.py
storage_adapters.py
luci/storage : form-macros
ricci/ricci : SSLInstance.cpp
Added files:
luci/conga_ssl : Makefile SSLClient.cpp SSLClient.h
conga_ssl_lib.cpp setup.py
luci/site/luci/Extensions: conga_ssl.py
Log message:
Improved bz201394: luci doesn't verify ricci's SSL cert against trusted list (part 1 - backend)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/conga.spec.in.in.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.45.2.8&r2=1.45.2.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.20.2.1&r2=1.20.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/conga_ssl/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/conga_ssl/SSLClient.cpp.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/conga_ssl/SSLClient.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/conga_ssl/conga_ssl_lib.cpp.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/conga_ssl/setup.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/Makefile.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.11&r2=1.11.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_ssl.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/HelperFunctions.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4.2.1&r2=1.4.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/StorageReport.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.20.2.1&r2=1.20.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_communicator.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.9.2.6&r2=1.9.2.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/storage_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.7.2.1&r2=1.7.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.17.2.3&r2=1.17.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/SSLInstance.cpp.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.5.2.1&r2=1.5.2.2
--- conga/conga.spec.in.in 2006/11/29 22:33:50 1.45.2.8
+++ conga/conga.spec.in.in 2006/12/08 18:27:31 1.45.2.9
@@ -126,10 +126,11 @@
%{_sbindir}/luci_admin
%{_docdir}/luci-%{version}/
%defattr(-,luci,luci)
+ %{_localstatedir}/lib/luci
+ %{_libdir}/luci/ssl
%if "%{include_zope_and_plone}" == "yes"
- %{_libdir}/luci/
+ %{_libdir}/luci/zope
%endif
- %{_localstatedir}/lib/luci
%pre -n luci
if ! /bin/grep luci\:x /etc/group 2>&1 >/dev/null; then
@@ -283,14 +284,14 @@
%changelog
-* day month date 2006 Stanko Kupcevic <kupcevic@redhat.com> 0.8-26
+* Fri Dec 08 2006 Stanko Kupcevic <kupcevic@redhat.com> 0.8-26
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXX UPDATE NOT RELEASED YET XXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- luci storage: fix bytes->TB conversion
-
+- Improved bz201394: luci doesn't verify ricci's SSL cert against trusted list (part 1 - backend)
* Thu Nov 16 2006 Stanko Kupcevic <kupcevic@redhat.com> 0.8-25
--- conga/luci/Makefile 2006/11/16 19:34:52 1.20.2.1
+++ conga/luci/Makefile 2006/12/08 18:27:32 1.20.2.2
@@ -18,6 +18,7 @@
luci:
make -C site
+ make -C conga_ssl
make -C utils
make -C init.d
make -C sysconfig
@@ -46,6 +47,7 @@
install -d -m 700 ${DESTDIR}/var/lib/luci
make -C site install
+ make -C conga_ssl install
make -C utils install
make -C init.d install
make -C sysconfig install
/cvs/cluster/conga/luci/conga_ssl/Makefile,v --> standard output
revision 1.1.2.1
--- conga/luci/conga_ssl/Makefile
+++ - 2006-12-08 18:27:33.432667000 +0000
@@ -0,0 +1,21 @@
+
+include ../../make/version.in
+include ../make/defines.mk
+
+
+.PHONY: build
+
+build:
+ python setup.py build
+
+clean:
+ rm -rf build
+ rm -rf ricci
+
+install:
+ install -d ${libdir}/luci
+ install -d ${libdir}/luci/ssl
+ install -m 644 build/lib*/conga_ssl_lib.so ${libdir}/luci/ssl
+
+rebuild: clean build
+
/cvs/cluster/conga/luci/conga_ssl/SSLClient.cpp,v --> standard output
revision 1.1.2.1
--- conga/luci/conga_ssl/SSLClient.cpp
+++ - 2006-12-08 18:27:33.797469000 +0000
@@ -0,0 +1,552 @@
+/*
+ Copyright Red Hat, Inc. 2005
+
+ 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 2, 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; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#include "SSLClient.h"
+#include "Mutex.h"
+#include "Time.h"
+#include "Random.h"
+#include "utils.h"
+#include "File.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <list>
+#include <set>
+
+
+
+#include <openssl/err.h>
+
+
+
+using namespace std;
+
+
+
+static Mutex global_lock;
+static bool ssl_inited = false;
+static SSL_CTX* ctx = 0;
+static vector<counting_auto_ptr<Mutex> > ssl_locks;
+
+class file_cert
+{
+public:
+ file_cert(const String& file, const String& cert) :
+ file(file),
+ cert(cert) {}
+
+ String file;
+ String cert;
+};
+static list<file_cert> trusted_certs;
+
+
+
+static int
+verify_cert_callback(int preverify_ok, X509_STORE_CTX *ctx)
+{
+ return 1;
+}
+static void
+load_peer_certs()
+{
+ MutexLocker l(global_lock);
+
+ // load trusted CAs
+ if (!SSL_CTX_load_verify_locations(ctx,
+ _trust_CAs,
+ NULL))
+ cout << "failed to load trusted CAs" << endl;
+
+ STACK_OF(X509_NAME) *cert_names =
+ SSL_load_client_CA_file(_trust_CAs);
+ if (cert_names)
+ SSL_CTX_set_client_CA_list(ctx, cert_names);
+ else
+ cout << "failed to load trusted CAs" << endl;
+
+ // load saved certs
+
+ set<String> files;
+ String dir_path(_certs_store_dir);
+ DIR* d = opendir(dir_path.c_str());
+ if (d == NULL)
+ throw String("unable to open directory ") + dir_path;
+ try {
+ while (true) {
+ struct dirent* ent = readdir(d);
+ if (ent == NULL) {
+ closedir(d);
+ break;
+ }
+ String kid_path = ent->d_name;
+ if (kid_path == "." || kid_path == "..")
+ continue;
+ kid_path = dir_path + "/" + kid_path;
+ struct stat st;
+ if (stat(kid_path.c_str(), &st))
+ continue;
+ if (S_ISREG(st.st_mode))
+ files.insert(kid_path);
+ }
+ } catch ( ... ) {
+ closedir(d);
+ throw;
+ }
+
+ trusted_certs.clear();
+
+ for (set<String>::const_iterator iter = files.begin();
+ iter != files.end();
+ iter++) {
+ try {
+ String cert(File::open(*iter).read());
+ if (cert.size() && cert.size() < 10 * 1024)
+ trusted_certs.push_back(file_cert(*iter, cert));
+ } catch ( ... ) {}
+ }
+}
+static void
+ssl_mutex_callback(int mode,
+ int n,
+ const char *file,
+ int line)
+{
+ if (mode & CRYPTO_LOCK)
+ ssl_locks[n]->lock();
+ else
+ ssl_locks[n]->unlock();
+}
+static pthread_t
+ssl_id_callback(void)
+{
+ return pthread_self();
+}
+
+
+
+
+// ##### class SSLClient #####
+
+
+SSLClient::SSLClient(ClientSocket sock) :
+ _sock(sock),
+ _connected(false)
+{
+ {
+ MutexLocker l(global_lock);
+ if (!ssl_inited) {
+ // init library
+
+ SSL_library_init();
+ // TODO: random number generator,
+ // not on systems with /dev/urandom (eg. Linux)
+
+ // thread support
+ ssl_locks.clear();
+ for (int i=0; i<CRYPTO_num_locks()+1; i++)
+ ssl_locks.push_back(counting_auto_ptr<Mutex>(new Mutex()));
+ CRYPTO_set_locking_callback(ssl_mutex_callback);
+ CRYPTO_set_id_callback(ssl_id_callback);
+
+ // create context
+ if (!ctx)
+ ctx = SSL_CTX_new(SSLv23_client_method());
+ if (!ctx)
+ throw String("SSL context creation failed");
+ // set verify_callback() function
+ SSL_CTX_set_verify(ctx,
+ SSL_VERIFY_PEER,
+ verify_cert_callback);
+ // set mode
+ SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+
+ // load key
+ if (!SSL_CTX_use_PrivateKey_file(ctx,
+ _privkey,
+ SSL_FILETYPE_PEM))
+ throw String("error importing cert key file");
+ // load cert
+ if (!SSL_CTX_use_certificate_file(ctx,
+ _pubkey,
+ SSL_FILETYPE_PEM))
+ throw String("error importing cert file");
+ // load peers' certs
+ load_peer_certs();
+
+ ssl_inited = true;
+ }
+
+ // create SSL object, giving it context
+ _ssl = SSL_new(ctx);
+ if (!_ssl)
+ throw String("creation of ssl object failed");
+ }
+
+ // make socket non-blocking
+ try {
+ _sock.nonblocking(true);
+ } catch ( ... ) {
+ SSL_free(_ssl);
+ throw;
+ }
+
+ // assign fd to _ssl
+ if (!SSL_set_fd(_ssl, _sock.get_sock())) {
+ SSL_free(_ssl);
+ throw String("fd assignment to ssl_obj failed");
+ }
+}
+
+SSLClient::~SSLClient()
+{
+ SSL_shutdown(_ssl);
+ SSL_free(_ssl);
+}
+
+
+bool
+SSLClient::connect(unsigned int timeout)
+{
+ if (_connected)
+ return _connected;
+
+ unsigned int beg = time_mil();
+ while (time_mil() < beg + timeout) {
+ int ret = SSL_connect(_ssl);
+ if (ret == 1) {
+ _connected = true;
+ break;
+ } else {
+ bool want_read, want_write;
+ check_error(ret, want_read, want_write);
+ socket().ready(want_read, want_write, 250);
+ }
+ }
+
+ return _connected;
+}
+
+String
+SSLClient::send(const String& msg,
+ unsigned int timeout)
+{
+ if (!_connected)
+ throw String("cannot send, yet: SSL connection not connected");
+
+ if (msg.empty())
+ return msg;
+
+ unsigned int beg = time_mil();
+ while (time_mil() < beg + timeout) {
+ int ret = SSL_write(_ssl, msg.c_str(), msg.size());
+ if (ret > 0) {
+ return msg.substr(ret);
+ } else {
+ bool want_read, want_write;
+ check_error(ret, want_read, want_write);
+ socket().ready(want_read, want_write, 250);
+ }
+ }
+
+ return msg;
+}
+
+String
+SSLClient::recv(unsigned int timeout)
+{
+ if (!_connected)
+ throw String("cannot receive, yet: SSL connection not connected");
+
+ char buff[1024];
+
+ unsigned int beg = time_mil();
+ while (time_mil() < beg + timeout) {
+ int ret = SSL_read(_ssl, buff, sizeof(buff));
+ if (ret > 0) {
+ String data(buff, ret);
+ shred(buff, sizeof(buff));
+ return data;
+ } else {
+ bool want_read, want_write;
+ check_error(ret, want_read, want_write);
+ socket().ready(want_read, want_write, 250);
+ }
+ }
+
+ return "";
+}
+
+bool
+SSLClient::peer_has_cert()
+{
+ if (!_connected)
+ throw String("cannot determine if peer has certificate: SSL connection not connected");
+
+ if (_cert_pem.size())
+ return true;
+
+ X509* cert = SSL_get_peer_certificate(_ssl);
+ if (!cert)
+ return false;
+
+ // load cert into _cert_pem
+ FILE* f = NULL;
+ try {
+ if (!(f = tmpfile()))
+ throw String("unable to open temp file");
+ if (!PEM_write_X509(f, cert))
+ throw String("unable to write cert to tmp file");
+ X509_free(cert); cert = NULL;
+
+ // read cert
+ rewind(f);
+ while (true) {
+ char buff[1024];
+ size_t i = fread(buff, sizeof(char), sizeof(buff), f);
+ _cert_pem.append(buff, i);
+ if (i == 0) {
+ if (feof(f))
+ break;
+ else
+ throw String("error while reading certificate from temp file");
+ }
+ }
+ fclose(f); f = NULL;
+ } catch ( ... ) {
+ if (cert)
+ X509_free(cert);
+ if (f)
+ fclose(f);
+ _cert_pem.clear();
+ throw;
+ }
+
+ return true;
+}
+
+String
+SSLClient::peer_cert_fingerprint(String& digest)
+{
+ if (!peer_has_cert())
+ throw String("peer did not present cert");
+
+ String f_name("/tmp/luci_tmp_XXXXXX");
+ int fd = -1;
+ char* buff = new char[f_name.size() + 1];
+ try {
+ // pick a filename
+ strcpy(buff, f_name.c_str());
+ if ((fd = mkstemp(buff)) == -1)
+ throw String("unable to generate random file");
+ f_name = buff;
+ delete[] buff; buff = 0;
+ while (close(fd) && errno == EINTR) ; fd = -1;
+
+ File f = File::open(f_name, true);
+ f.replace(_cert_pem);
+
+ String out, err;
+ int status;
+ vector<String> args;
+ args.push_back("x509");
+ args.push_back("-sha1");
+ args.push_back("-in");
+ args.push_back(f_name);
+ args.push_back("-noout");
+ args.push_back("-fingerprint");
+ if (utils::execute("/usr/bin/openssl",
+ args,
+ out,
+ err,
+ status,
+ false))
+ throw command_not_found_error_msg("/usr/bin/openssl");
+ if (status)
+ throw String("openssl command failed");
+ unlink(f_name.c_str());
+
+ vector<String> words(utils::split(utils::strip(out)));
+ if (words.size() != 2)
+ throw String("error parsing fingerprint");
+
+ String finger(words[1]);
+ String::size_type idx = finger.find('=');
+ if (idx == finger.npos ||
+ idx+1 == finger.size())
+ throw String("error parsing fingerprint");
+
+ digest = words[0];
+ return finger.substr(idx+1);
+ } catch ( ... ) {
+ delete[] buff;
+ if (fd != -1)
+ while (close(fd) && errno == EINTR)
+ ;
+ unlink(f_name.c_str());
+ throw;
+ }
+}
+
+bool
+SSLClient::peer_cert_trusted()
+{
+ // signed by trusted CAs?
+ X509* cert = SSL_get_peer_certificate(_ssl);
+ if (!cert)
+ return false;
+ X509_free(cert);
+ if (SSL_get_verify_result(_ssl) == X509_V_OK)
+ return true;
+
+ // cert present among saved certs?
+ peer_has_cert(); // make sure cert is saved in _cert_pem
+ MutexLocker l(global_lock);
+ for (list<file_cert>::const_iterator iter = trusted_certs.begin();
+ iter != trusted_certs.end();
+ iter++)
+ if (iter->cert == _cert_pem)
+ return true;
+ return false;
+}
+
+bool
+SSLClient::trust_peer_cert()
+{
+ MutexLocker l(global_lock);
+
+ if (peer_cert_trusted())
+ return true;
+
+ if (!peer_has_cert())
+ throw String("peer did not present cert");
+
+ String f_name(_certs_store_dir);
+ f_name += "/peer_cert_XXXXXX";
+ int fd = -1;
+ char* buff = new char[f_name.size() + 1];
+ try {
+ // pick a filename
+ strcpy(buff, f_name.c_str());
+ if ((fd = mkstemp(buff)) == -1)
+ throw String("unable to generate random file");
+ f_name = buff;
+ delete[] buff; buff = 0;
+
+ String data(_cert_pem);
+ while (data.size()) {
+ ssize_t i = write(fd, data.c_str(), data.size());
+ if (i == -1) {
+ if (errno != EINTR)
+ throw String("error writing certificate");
+ } else
+ data = data.substr(i);
+ }
+ while (close(fd) && errno == EINTR)
+ ;
+ } catch ( ... ) {
+ delete[] buff;
+ if (fd != -1)
+ while (close(fd) && errno == EINTR)
+ ;
+ unlink(f_name.c_str());
+ return false;
+ }
+
+ load_peer_certs();
+
+ return true;
+}
+
+bool
+SSLClient::untrust_peer_cert()
+{
+ MutexLocker l(global_lock);
+
+ if (!peer_has_cert())
+ throw String("peer did not present cert");
+
+ for (list<file_cert>::const_iterator iter = trusted_certs.begin();
+ iter != trusted_certs.end();
+ iter++)
+ if (iter->cert == _cert_pem)
+ unlink(iter->file.c_str());
+
+ load_peer_certs();
+ return true;
+}
+
+ClientSocket&
+SSLClient::socket()
+{
+ return _sock;
+}
+
+void
+SSLClient::check_error(int value, bool& want_read, bool& want_write)
+{
+ want_read = want_write = false;
+
+ String e;
+ switch (SSL_get_error(_ssl, value)) {
+ case SSL_ERROR_NONE:
+ e = "SSL_ERROR_NONE";
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ e = "SSL_ERROR_ZERO_RETURN";
+ break;
+ case SSL_ERROR_WANT_READ:
+ want_read = true;
+ return;
+ case SSL_ERROR_WANT_WRITE:
+ want_write = true;
+ return;
+ case SSL_ERROR_WANT_CONNECT:
+ e = "SSL_ERROR_WANT_CONNECT";
+ break;
+ case SSL_ERROR_WANT_ACCEPT:
+ e = "SSL_ERROR_WANT_ACCEPT";
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ e = "SSL_ERROR_WANT_X509_LOOKUP";
+ break;
+ case SSL_ERROR_SYSCALL:
+ e = "SSL_ERROR_SYSCALL";
+ break;
+ case SSL_ERROR_SSL:
+ e = "SSL_ERROR_SSL";
+ break;
+ }
+
+ //FILE* f = fopen("/tmp/ssl_error_que", "a");
+ //ERR_print_errors_fp(f);
+ //fclose(f);
+
+ throw String("SSL error: ") + e;
+}
/cvs/cluster/conga/luci/conga_ssl/SSLClient.h,v --> standard output
revision 1.1.2.1
--- conga/luci/conga_ssl/SSLClient.h
+++ - 2006-12-08 18:27:34.372060000 +0000
@@ -0,0 +1,80 @@
+/*
+ Copyright Red Hat, Inc. 2005
+
+ 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 2, 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; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#ifndef SSLClient_h
+#define SSLClient_h
+
+#include "Socket.h"
+
+#include "String.h"
+#include <openssl/ssl.h>
+
+
+#define _privkey "/var/lib/luci/var/certs/privkey.pem"
+#define _pubkey "/var/lib/luci/var/certs/cacert.pem"
+#define _trust_CAs "/var/lib/luci/var/certs/trust_CAs"
+#define _certs_store_dir "/var/lib/luci/var/certs/peers"
+
+
+// NOT THREAD SAFE
+
+
+class SSLClient
+{
+ public:
+ SSLClient(ClientSocket sock);
+ virtual ~SSLClient();
+
+ bool connect(unsigned int timeout);
+
+ String send(const String& msg, unsigned int timeout);
+ String recv(unsigned int timeout);
+
+
+ bool peer_has_cert();
+ bool peer_cert_trusted(); // return true if peer's cert is trusted (either thru CA chain, or saved in cert_store)
+
+ String peer_cert_fingerprint(String& digest);
+
+ bool trust_peer_cert();
+ bool untrust_peer_cert(); // remove peer's cert from cert_store
+
+ ClientSocket& socket();
+
+ private:
+ SSLClient(const SSLClient&);
+ SSLClient operator=(const SSLClient&);
+
+ ClientSocket _sock;
+ SSL* _ssl;
+ String _cert_pem;
+
+ bool _connected;
+
+ void check_error(int value, bool& want_read, bool& want_write);
+
+
+}; // class SSLClient
+
+
+#endif // SSLClient_h
/cvs/cluster/conga/luci/conga_ssl/conga_ssl_lib.cpp,v --> standard output
revision 1.1.2.1
--- conga/luci/conga_ssl/conga_ssl_lib.cpp
+++ - 2006-12-08 18:27:34.717960000 +0000
@@ -0,0 +1,374 @@
+/*
+ Copyright Red Hat, Inc. 2006
+
+ 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 2, 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; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic@redhat.com>
+ */
+
+
+#include <Python.h>
+
+#include <Socket.h>
+#include <String.h>
+#include <Time.h>
+#include <XML.h>
+#include <utils.h>
+
+#include "SSLClient.h"
+
+#include <map>
+
+using namespace std;
+
+
+class PythonThreadsAllower
+{
+public:
+ PythonThreadsAllower()
+ { _save = PyEval_SaveThread(); }
+
+ ~PythonThreadsAllower()
+ { PyEval_RestoreThread(_save); }
+
+private:
+ PyThreadState *_save;
+};
+
+
+
+static Mutex mutex;
+static map<int, counting_auto_ptr<SSLClient> > ssls;
+
+
+
+static PyObject *
+conga_ssl_lib_connect(PyObject *self, PyObject *args);
+static PyObject *
+conga_ssl_lib_disconnect(PyObject *self, PyObject *args);
+
+static PyObject *
+conga_ssl_lib_send(PyObject *self, PyObject *args);
+static PyObject *
+conga_ssl_lib_recv(PyObject *self, PyObject *args);
+
+static PyObject *
+conga_ssl_lib_trust(PyObject *self, PyObject *args);
+static PyObject *
+conga_ssl_lib_trusted(PyObject *self, PyObject *args);
+static PyObject *
+conga_ssl_lib_untrust(PyObject *self, PyObject *args);
+
+static PyObject *
+conga_ssl_lib_peer_fingerprint(PyObject *self, PyObject *args);
+
+
+
+static PyMethodDef SSLMethods[] = {
+ {"connect", conga_ssl_lib_connect, METH_VARARGS,
+ "doc"},
+ {"disconnect", conga_ssl_lib_disconnect, METH_VARARGS,
+ "doc"},
+ {"send", conga_ssl_lib_send, METH_VARARGS,
+ "doc"},
+ {"recv", conga_ssl_lib_recv, METH_VARARGS,
+ "doc"},
+ {"trust", conga_ssl_lib_trust, METH_VARARGS,
+ "doc"},
+ {"trusted", conga_ssl_lib_trusted, METH_VARARGS,
+ "doc"},
+ {"untrust", conga_ssl_lib_untrust, METH_VARARGS,
+ "doc"},
+ {"peer_fingerprint", conga_ssl_lib_peer_fingerprint, METH_VARARGS,
+ "doc"},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+
+
+PyMODINIT_FUNC
+initconga_ssl_lib(void)
+{
+ (void) Py_InitModule("conga_ssl_lib", SSLMethods);
+}
+
+
+
+PyObject *
+conga_ssl_lib_connect(PyObject *self, PyObject *args)
+{
+ const char* hostname;
+ int port;
+ int timeout;
+ if (!PyArg_ParseTuple(args,
+ "sii",
+ &hostname,
+ &port,
+ &timeout))
+ return NULL;
+ if (port < 1 || port > 65535) {
+ PyErr_SetString(PyExc_ValueError, "invalid port number");
+ return NULL;
+ }
+ if (timeout < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative timeout");
+ return NULL;
+ }
+
+ try {
+ counting_auto_ptr<SSLClient> ss;
+ {
+ PythonThreadsAllower all;
+ ClientSocket sock(hostname, port);
+ ss = counting_auto_ptr<SSLClient>(new SSLClient(sock));
+ ss->connect(timeout * 1000);
+ }
+ int id = (int) ss->socket().get_sock();
+ ssls[id] = ss;
+ return Py_BuildValue("i", id);
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_disconnect(PyObject *self, PyObject *args)
+{
+ int id;
+ if (!PyArg_ParseTuple(args, "i", &id))
+ return NULL;
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::iterator iter =
+ ssls.find(id);
+ if (iter != ssls.end())
+ ssls.erase(iter);
+ Py_INCREF(Py_None);
+ return Py_None;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_send(PyObject *self, PyObject *args)
+{
+ int id;
+ const char* msg;
+ int timeout;
+ if (!PyArg_ParseTuple(args, "isi", &id, &msg, &timeout))
+ return NULL;
+ if (timeout < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative timeout");
+ return NULL;
+ }
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::const_iterator iter =
+ ssls.find(id);
+ if (iter == ssls.end())
+ throw String("SSL connection closed");
+
+ {
+ PythonThreadsAllower all;
+ int beg = int(time_sec());
+ String out(msg);
+ while (true) {
+ if (int(time_sec()) > beg + timeout)
+ throw String("timeout");
+ else
+ if ((out = iter->second->send(out, 400)).empty())
+ break;
+ }
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_recv(PyObject *self, PyObject *args)
+{
+ int id, timeout;
+ if (!PyArg_ParseTuple(args, "ii", &id, &timeout))
+ return NULL;
+ if (timeout < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative timeout");
+ return NULL;
+ }
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::const_iterator iter =
+ ssls.find(id);
+ if (iter == ssls.end())
+ throw String("SSL connection closed");
+
+ String resp;
+ {
+ PythonThreadsAllower all;
+ int beg = int(time_sec());
+ String xml_in;
+ while (true) {
+ if (int(time_sec()) > beg + timeout)
+ throw String("timeout");
+ else
+ xml_in += iter->second->recv(400);
+ try {
+ parseXML(xml_in);
+ resp = xml_in;
+ break;
+ } catch ( ... ) {}
+ }
+ }
+
+ PyObject* resp_p = Py_BuildValue("s", resp.c_str());
+ return resp_p;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_trust(PyObject *self, PyObject *args)
+{
+ int id;
+ if (!PyArg_ParseTuple(args, "i", &id))
+ return NULL;
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::const_iterator iter =
+ ssls.find(id);
+ if (iter == ssls.end())
+ throw String("SSL connection closed");
+
+ bool resp;
+ {
+ PythonThreadsAllower all;
+ resp = iter->second->trust_peer_cert();
+ }
+
+ PyObject* resp_p = Py_BuildValue("i", (resp)?1:0);
+ return resp_p;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_trusted(PyObject *self, PyObject *args)
+{
+ int id;
+ if (!PyArg_ParseTuple(args, "i", &id))
+ return NULL;
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::const_iterator iter =
+ ssls.find(id);
+ if (iter == ssls.end())
+ throw String("SSL connection closed");
+
+ bool resp;
+ {
+ PythonThreadsAllower all;
+ resp = iter->second->peer_cert_trusted();
+ }
+
+ PyObject* resp_p = Py_BuildValue("i", (resp)?1:0);
+ return resp_p;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_untrust(PyObject *self, PyObject *args)
+{
+ int id;
+ if (!PyArg_ParseTuple(args, "i", &id))
+ return NULL;
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::const_iterator iter =
+ ssls.find(id);
+ if (iter == ssls.end())
+ throw String("SSL connection closed");
+
+ bool resp;
+ {
+ PythonThreadsAllower all;
+ resp = iter->second->untrust_peer_cert();
+ }
+
+ PyObject* resp_p = Py_BuildValue("i", (resp)?1:0);
+ return resp_p;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
+
+PyObject *
+conga_ssl_lib_peer_fingerprint(PyObject *self, PyObject *args)
+{
+ int id;
+ if (!PyArg_ParseTuple(args, "i", &id))
+ return NULL;
+
+ try {
+ map<int, counting_auto_ptr<SSLClient> >::const_iterator iter =
+ ssls.find(id);
+ if (iter == ssls.end())
+ throw String("SSL connection closed");
+
+ String finger, digest;
+ {
+ PythonThreadsAllower all;
+ finger = iter->second->peer_cert_fingerprint(digest);
+ }
+
+ PyObject* resp_p = Py_BuildValue("(ss)", digest.c_str(), finger.c_str());
+ return resp_p;
+ } catch (String e) {
+ PyErr_SetString(PyExc_Exception, e.c_str());
+ } catch ( ... ) {
+ PyErr_SetString(PyExc_Exception, "unknown");
+ }
+ return NULL;
+}
/cvs/cluster/conga/luci/conga_ssl/setup.py,v --> standard output
revision 1.1.2.1
--- conga/luci/conga_ssl/setup.py
+++ - 2006-12-08 18:27:35.171396000 +0000
@@ -0,0 +1,37 @@
+
+from distutils.core import setup, Extension
+
+
+module1 = Extension('conga_ssl_lib',
+ define_macros = [('MAJOR_VERSION', '0'),
+ ('MINOR_VERSION', '8')],
+ include_dirs = ['../../ricci/include',
+ '/usr/include/libxml2'],
+ libraries = ['ssl', 'xml2'],
+ #library_dirs = ['/usr/local/lib'],
+ sources = ['conga_ssl_lib.cpp',
+ 'SSLClient.cpp',
+ '../../ricci/common/ClientSocket.cpp',
+ '../../ricci/common/Socket.cpp',
+ '../../ricci/common/Logger.cpp',
+ '../../ricci/common/Time.cpp',
+ '../../ricci/common/File.cpp',
+ '../../ricci/common/XML.cpp',
+ '../../ricci/common/utils.cpp',
+ '../../ricci/common/executils.cpp'])
+
+
+
+setup (name = 'conga_ssl_lib',
+ version = '0.8',
+ description = 'SSL Python bindings for Conga',
+ author = 'Stanko Kupcevic',
+ author_email = 'kupcevic at redhat.com',
+ copyright = 'Red Hat, Inc.',
+ license = 'GPL',
+ url = 'http://www.sourceware.org/cluster/conga',
+ long_description = '''
+ conga_ssl_lib
+ ''',
+ ext_modules = [module1])
+
--- conga/luci/site/Makefile 2006/08/24 14:38:28 1.11
+++ conga/luci/site/Makefile 2006/12/08 18:27:32 1.11.2.1
@@ -82,6 +82,7 @@
install -d ${DESTDIR}/var/lib/luci/var/pts
# install -m 644 `find luci/var/pts -maxdepth 1 -type f | grep .mo | grep -v \~ | grep -v \#` ${DESTDIR}/var/lib/luci/var/pts
install -d ${DESTDIR}/var/lib/luci/var/certs
+ install -d ${DESTDIR}/var/lib/luci/var/certs/peers
install -m 644 luci/var/certs/cacert.config ${DESTDIR}/var/lib/luci/var/certs
install -d ${DESTDIR}/var/lib/luci/var/stunnel
/cvs/cluster/conga/luci/site/luci/Extensions/conga_ssl.py,v --> standard output
revision 1.1.2.1
--- conga/luci/site/luci/Extensions/conga_ssl.py
+++ - 2006-12-08 18:27:35.466686000 +0000
@@ -0,0 +1,48 @@
+
+
+import sys
+sys.path.append('/usr/lib/luci/ssl')
+sys.path.append('/usr/lib64/luci/ssl')
+import conga_ssl_lib
+sys.path.remove('/usr/lib/luci/ssl')
+sys.path.remove('/usr/lib64/luci/ssl')
+
+
+
+# timeouts are in seconds (int)
+
+
+class SSLSocket:
+
+ def __init__(self,
+ hostname,
+ port,
+ timeout):
+ self.__id = -1
+ self.__id = conga_ssl_lib.connect(hostname, port, timeout)
+ pass
+ def __del__(self):
+ self.disconnect()
+ pass
+ def disconnect(self):
+ if self.__id != -1:
+ conga_ssl_lib.disconnect(self.__id)
+ self.__id = -1
+
+ def peer_fingerprint(self):
+ return conga_ssl_lib.peer_fingerprint(self.__id)
+
+ def trusted(self):
+ return conga_ssl_lib.trusted(self.__id) == 1
+ def trust(self):
+ if self.trusted():
+ return True
+ return conga_ssl_lib.trust(self.__id) == 1
+ def untrust(self):
+ return conga_ssl_lib.untrust(self.__id) == 1
+
+
+ def send(self, msg, timeout):
+ conga_ssl_lib.send(self.__id, msg, timeout)
+ def recv(self, timeout):
+ return conga_ssl_lib.recv(self.__id, timeout)
--- conga/luci/site/luci/Extensions/HelperFunctions.py 2006/11/29 22:33:50 1.4.2.1
+++ conga/luci/site/luci/Extensions/HelperFunctions.py 2006/12/08 18:27:32 1.4.2.2
@@ -1,6 +1,8 @@
import AccessControl
+import threading
+from ricci_communicator import RicciCommunicator
def add_commas(self, str1, str2):
@@ -29,17 +31,75 @@
+
+class Worker(threading.Thread):
+ def __init__(self,
+ mutex,
+ hosts,
+ riccis):
+ threading.Thread.__init__(self)
+ self.mutex = mutex
+ self.hosts = hosts
+ self.riccis = riccis
+ return
+ def run(self):
+ while True:
+ self.mutex.acquire()
+ if len(self.hosts) == 0:
+ self.mutex.release()
+ return
+ host = self.hosts.pop()
+ self.mutex.release()
+ r = None
+ try:
+ r = RicciCommunicator(host)
+ #print host, 'done'
+ except Exception, e:
+ #print host, 'failed', str(e)
+ pass
+ except:
+ #print host, 'failed'
+ pass
+ self.mutex.acquire()
+ self.riccis[host] = r
+ self.mutex.release()
+
+
+
# removes systems that user is not authorized access to
-def get_systems_statuses(self, systems):
- ss = {}
+def get_systems_statuses(self, systems, from_cache=False):
+ CACHED_INDEX = '_get_systems_statuses()_cached_result_'
+ session = self.REQUEST.SESSION
+ if session.has_key(CACHED_INDEX):
+ res = session[CACHED_INDEX]
+ if res != None:
+ session.set(CACHED_INDEX, None)
+ if from_cache:
+ return res
+ pass
+
ass = self.allowed_systems(self, None, systems)
+
+ mutex = threading.RLock()
+ hive = [] # workers
+ ss = {} # storage systems (will store riccis, and then use them to retrieve real info)
+ hosts = [] # hostnames
for system in ass:
- hostname = system[0]
+ hosts.append(system[0])
+ if len(hosts) < 10:
+ hive.append(Worker(mutex, hosts, ss))
+
+ for bee in hive:
+ bee.start()
+ for bee in hive:
+ bee.join()
+
+ for hostname in ss.keys():
OS = ''
cluname = ''
cluali = ''
authed = False
- ricci = self.get_ricci_communicator(hostname, ass)
+ ricci = ss[hostname]
if ricci != None:
OS = ricci.os()
cluname = ricci.cluster_info()[0]
@@ -53,6 +113,7 @@
'clualias' : cluali,
'available': ricci != None,
'authed' : authed}
+ # replace ricci with system's info
ss[hostname] = s
pass
ss_list = []
@@ -60,6 +121,9 @@
sorted_keys.sort()
for name in sorted_keys:
ss_list.append(ss[name])
+
+ session.set(CACHED_INDEX, ss_list)
+
return ss_list
@@ -88,7 +152,6 @@
response.setCookie(cookie_prefix + var_name,
value,
expires='Tue, 30 Jun 2060 12:00:00 GMT')
-
return value
--- conga/luci/site/luci/Extensions/StorageReport.py 2006/11/29 18:26:53 1.20.2.1
+++ conga/luci/site/luci/Extensions/StorageReport.py 2006/12/08 18:27:32 1.20.2.2
@@ -1878,17 +1878,8 @@
-def group_systems_by_cluster(self, allowed_systems, cache_it=False):
- CACHED_INDEX = '_group_systems_by_cluster_cached_result_'
- session = self.REQUEST.SESSION
- if session.has_key(CACHED_INDEX):
- res = session[CACHED_INDEX]
- if res != None:
- session.set(CACHED_INDEX, None)
- return res
- pass
-
- ss = get_systems_statuses(self, allowed_systems)
+def group_systems_by_cluster(self, allowed_systems, from_cache=False):
+ ss = get_systems_statuses(self, allowed_systems, from_cache)
clusters = {}
bad_list = []
for s in ss:
@@ -1912,10 +1903,6 @@
ret = [nonclu_list, clu_list, bad_list]
- if cache_it:
- session.set(CACHED_INDEX, ret)
- pass
-
return ret
--- conga/luci/site/luci/Extensions/ricci_communicator.py 2006/11/20 23:32:43 1.9.2.6
+++ conga/luci/site/luci/Extensions/ricci_communicator.py 2006/12/08 18:27:32 1.9.2.7
@@ -1,8 +1,8 @@
-from socket import socket, ssl, AF_INET, SOCK_STREAM
import xml
import xml.dom
from xml.dom import minidom
from LuciSyslog import LuciSyslog
+from conga_ssl import SSLSocket
CERTS_DIR_PATH = '/var/lib/luci/var/certs/'
@@ -15,32 +15,25 @@
pass
class RicciCommunicator:
- def __init__(self, hostname, port=11111):
+ def __init__(self, hostname, enforce_trust=False, port=11111):
self.__hostname = hostname
self.__port = port
+ self.__timeout_init = 4
+ self.__timeout_auth = 4
+ self.__timeout_short = 6
+ self.__timeout_long = 600
+
self.__privkey_file = CERTS_DIR_PATH + 'privkey.pem'
self.__cert_file = CERTS_DIR_PATH + 'cacert.pem'
- # socket
try:
- sock = socket(AF_INET, SOCK_STREAM)
- sock.settimeout(2.0)
- sock.connect((self.__hostname, self.__port))
- except Exception, e:
- raise RicciError, 'Error connecting to %s:%d: %s' \
- % (self.__hostname, self.__port, str(e))
- except:
- raise RicciError, 'Error connecting to %s:%d: unknown error' \
- % (self.__hostname, self.__port)
-
- luci_log.debug_verbose('RC:init0: Connected to %s:%d' \
- % (self.__hostname, self.__port))
- try:
- self.ss = ssl(sock, self.__privkey_file, self.__cert_file)
- # TODO: data transfer timeout should be much less,
- # leave until all calls are async ricci calls
- sock.settimeout(600.0) # 10 minutes
+ self.ss = SSLSocket(self.__hostname,
+ self.__port,
+ self.__timeout_init)
+ if enforce_trust:
+ if not self.ss.trusted():
+ raise RicciError, 'ricci\'s certificate is not trusted'
except Exception, e:
raise RicciError, 'Error setting up SSL for connection to %s: %s' \
% (self.__hostname, str(e))
@@ -49,20 +42,20 @@
% self.__hostname
# receive ricci header
- hello = self.__receive()
+ hello = self.__receive(self.__timeout_init)
try:
- luci_log.debug_verbose('RC:init1: Received header from %s: \"%s\"' \
+ luci_log.debug_verbose('RC:init0: Received header from %s: \"%s\"' \
% (self.__hostname, hello.toxml()))
except:
pass
-
+
self.__authed = hello.firstChild.getAttribute('authenticated') == 'true'
self.__cluname = hello.firstChild.getAttribute('clustername')
self.__clualias = hello.firstChild.getAttribute('clusteralias')
self.__reported_hostname = hello.firstChild.getAttribute('hostname')
self.__os = hello.firstChild.getAttribute('os')
self.__dom0 = hello.firstChild.getAttribute('xen_host') == 'true'
-
+
pass
@@ -104,10 +97,10 @@
ricci.setAttribute("function", "authenticate")
ricci.setAttribute("password", password)
doc.appendChild(ricci)
- self.__send(doc)
+ self.__send(doc, self.__timeout_auth)
# receive response
- resp = self.__receive()
+ resp = self.__receive(self.__timeout_auth)
self.__authed = resp.firstChild.getAttribute('authenticated') == 'true'
luci_log.debug_verbose('RC:auth1: auth call returning %d' \
@@ -121,8 +114,8 @@
ricci.setAttribute('version', '1.0')
ricci.setAttribute('function', 'unauthenticate')
doc.appendChild(ricci)
- self.__send(doc)
- resp = self.__receive()
+ self.__send(doc, self.__timeout_auth)
+ resp = self.__receive(self.__timeout_auth)
luci_log.debug_verbose('RC:unauth0: trying to unauthenticate to %s' \
% self.__hostname)
@@ -167,7 +160,7 @@
# send request
try:
- self.__send(doc)
+ self.__send(doc, self.__timeout_short)
except Exception, e:
luci_log.debug_verbose('RC:PB1: Error sending XML \"%s\" to host %s' \
% (doc.toxml(), self.__hostname))
@@ -177,7 +170,7 @@
raise RicciError, 'Error sending XML to host %s' % self.__hostname
# receive response
- doc = self.__receive()
+ doc = self.__receive(self.__timeout_long)
try:
luci_log.debug_verbose('RC:PB2: received from %s XML \"%s\"' \
% (self.__hostname, doc.toxml()))
@@ -243,11 +236,11 @@
doc.appendChild(ricci)
# send request
- self.__send(doc)
+ self.__send(doc, self.__timeout_short)
# receive response
- doc = self.__receive()
+ doc = self.__receive(self.__timeout_short)
if doc.firstChild.getAttribute('success') == '12':
return None
if doc.firstChild.getAttribute('success') != '0':
@@ -265,20 +258,18 @@
- def __send(self, xml_doc):
+ def __send(self, xml_doc, timeout):
buff = xml_doc.toxml() + '\n'
- while len(buff) != 0:
- try:
- pos = self.ss.write(buff)
- except Exception, e:
- luci_log.debug_verbose('RC:send0: Error sending XML \"%s\" to %s: %s' \
- % (buff, self.__hostname, str(e)))
- raise RicciError, 'write error while sending XML to host %s' \
- % self.__hostname
- except:
- raise RicciError, 'write error while sending XML to host %s' \
- % self.__hostname
- buff = buff[pos:]
+ try:
+ self.ss.send(buff, timeout)
+ except Exception, e:
+ luci_log.debug_verbose('RC:send0: Error sending XML \"%s\" to %s: %s' \
+ % (buff, self.__hostname, str(e)))
+ raise RicciError, 'write error while sending XML to host %s' \
+ % self.__hostname
+ except:
+ raise RicciError, 'write error while sending XML to host %s' \
+ % self.__hostname
try:
luci_log.debug_verbose('RC:send1: Sent XML \"%s\" to host %s' \
% (xml_doc.toxml(), self.__hostname))
@@ -286,21 +277,11 @@
pass
return
- def __receive(self):
+ def __receive(self, timeout):
doc = None
xml_in = ''
try:
- while True:
- buff = self.ss.read(10485760)
- if buff == '':
- break
- xml_in += buff
- try:
- doc = minidom.parseString(xml_in)
- break
- except:
- # we haven't received all of the XML data yet.
- continue
+ xml_in = self.ss.recv(timeout)
except Exception, e:
luci_log.debug_verbose('RC:recv0: Error reading data from %s: %s' \
% (self.__hostname, str(e)))
--- conga/luci/site/luci/Extensions/storage_adapters.py 2006/10/19 14:57:17 1.7.2.1
+++ conga/luci/site/luci/Extensions/storage_adapters.py 2006/12/08 18:27:32 1.7.2.2
@@ -61,7 +61,7 @@
#display_clusters = True
display_clusters = False
if display_clusters:
- sorted_data = self.group_systems_by_cluster(systems, cache_it=True)
+ sorted_data = self.group_systems_by_cluster(systems, from_cache=False)
for sdl in sorted_data[:2]:
for data in sdl:
createStorageChooser_inner(url,
@@ -70,7 +70,7 @@
data,
syslist)
else:
- sorted_data = get_systems_statuses(self, systems)
+ sorted_data = get_systems_statuses(self, systems, from_cache=False)
for data in sorted_data:
createStorageChooser_inner(url,
pagetype,
--- conga/luci/storage/form-macros 2006/10/31 17:48:33 1.17.2.3
+++ conga/luci/storage/form-macros 2006/12/08 18:27:32 1.17.2.4
@@ -293,7 +293,7 @@
</form>
</fieldset>
- <dl tal:define="tmp_triple python:here.group_systems_by_cluster(allowed_systems);
+ <dl tal:define="tmp_triple python:here.group_systems_by_cluster(allowed_systems, from_cache=True);
nonclu_list python:tmp_triple[0];
clu_list python:tmp_triple[1];
bad_list python:tmp_triple[2]">
--- conga/ricci/ricci/SSLInstance.cpp 2006/10/23 21:13:22 1.5.2.1
+++ conga/ricci/ricci/SSLInstance.cpp 2006/12/08 18:27:32 1.5.2.2
@@ -137,6 +137,11 @@
else
ssl_locks[n]->unlock();
}
+static pthread_t
+ssl_id_callback(void)
+{
+ return pthread_self();
+}
@@ -157,12 +162,12 @@
// TODO: random number generator,
// not on systems with /dev/urandom (eg. Linux)
- // set up lockings
+ // thread support
ssl_locks.clear();
- for (int i=0; i<CRYPTO_num_locks(); i++)
+ for (int i=0; i<CRYPTO_num_locks()+1; i++)
ssl_locks.push_back(counting_auto_ptr<Mutex>(new Mutex()));
CRYPTO_set_locking_callback(ssl_mutex_callback);
- //CRYPTO_set_id_callback(ssl_id_function); not needed on Linux
+ CRYPTO_set_id_callback(ssl_id_callback);
// create context
if (!ctx)
@@ -354,6 +359,7 @@
// cert present among saved certs?
client_has_cert(); // make sure cert is saved in _cert_pem
+ MutexLocker l(global_lock);
for (list<file_cert>::const_iterator iter = authorized_certs.begin();
iter != authorized_certs.end();
iter++)
next reply other threads:[~2006-12-08 18:27 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-08 18:27 kupcevic [this message]
-- strict thread matches above, loose matches on Subject: below --
2006-08-04 22:14 [Cluster-devel] conga ./conga.spec.in.in luci/Makefile luci/si kupcevic
2006-08-03 20:53 kupcevic
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061208182736.29493.qmail@sourceware.org \
--to=kupcevic@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.