[Cluster-devel] conga ./conga.spec.in.in luci/Makefile luci/si ...
kupcevic at sourceware.org
kupcevic at sourceware.org
Fri Dec 8 18:27:36 UTC 2006
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 at redhat.com> 0.8-26
+* Fri Dec 08 2006 Stanko Kupcevic <kupcevic at 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 at 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 at 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 at 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 at 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++)
More information about the Cluster-devel
mailing list