summaryrefslogtreecommitdiff
path: root/trunk/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp')
-rw-r--r--trunk/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp297
1 files changed, 0 insertions, 297 deletions
diff --git a/trunk/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/trunk/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
deleted file mode 100644
index aa8cf127d7..0000000000
--- a/trunk/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/sys/ssl/SslSocket.h"
-#include "qpid/sys/ssl/check.h"
-#include "qpid/sys/ssl/util.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/sys/posix/PrivatePosix.h"
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <cstdlib>
-#include <string.h>
-#include <iostream>
-
-#include <private/pprio.h>
-#include <nss.h>
-#include <pk11pub.h>
-#include <ssl.h>
-#include <key.h>
-
-#include <boost/format.hpp>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-namespace {
-std::string getName(int fd, bool local, bool includeService = false)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return std::string(dispName) + ":" + std::string(servName);
-
- } else {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName), 0, 0, NI_NUMERICHOST) != 0)
- throw QPID_POSIX_ERROR(rc);
- return dispName;
- }
-}
-
-std::string getService(int fd, bool local)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, 0, 0,
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return servName;
-}
-
-}
-
-SslSocket::SslSocket() : IOHandle(new IOHandlePrivate()), socket(0), prototype(0)
-{
- impl->fd = ::socket (PF_INET, SOCK_STREAM, 0);
- if (impl->fd < 0) throw QPID_POSIX_ERROR(errno);
- socket = SSL_ImportFD(0, PR_ImportTCPSocket(impl->fd));
-}
-
-/**
- * This form of the constructor is used with the server-side sockets
- * returned from accept. Because we use posix accept rather than
- * PR_Accept, we have to reset the handshake.
- */
-SslSocket::SslSocket(IOHandlePrivate* ioph, PRFileDesc* model) : IOHandle(ioph), socket(0), prototype(0)
-{
- socket = SSL_ImportFD(model, PR_ImportTCPSocket(impl->fd));
- NSS_CHECK(SSL_ResetHandshake(socket, true));
-}
-
-void SslSocket::setNonblocking() const
-{
- PRSocketOptionData option;
- option.option = PR_SockOpt_Nonblocking;
- option.value.non_blocking = true;
- PR_SetSocketOption(socket, &option);
-}
-
-void SslSocket::connect(const std::string& host, uint16_t port) const
-{
- std::stringstream namestream;
- namestream << host << ":" << port;
- connectname = namestream.str();
-
- void* arg = SslOptions::global.certName.empty() ? 0 : const_cast<char*>(SslOptions::global.certName.c_str());
- NSS_CHECK(SSL_GetClientAuthDataHook(socket, NSS_GetClientAuthData, arg));
- NSS_CHECK(SSL_SetURL(socket, host.data()));
-
- char hostBuffer[PR_NETDB_BUF_SIZE];
- PRHostEnt hostEntry;
- PR_CHECK(PR_GetHostByName(host.data(), hostBuffer, PR_NETDB_BUF_SIZE, &hostEntry));
- PRNetAddr address;
- int value = PR_EnumerateHostEnt(0, &hostEntry, port, &address);
- if (value < 0) {
- throw Exception(QPID_MSG("Error getting address for host: " << ErrorString()));
- } else if (value == 0) {
- throw Exception(QPID_MSG("Could not resolve address for host."));
- }
- PR_CHECK(PR_Connect(socket, &address, PR_INTERVAL_NO_TIMEOUT));
-}
-
-void SslSocket::close() const
-{
- if (impl->fd > 0) {
- PR_Close(socket);
- impl->fd = -1;
- }
-}
-
-int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, bool clientAuth) const
-{
- //configure prototype socket:
- prototype = SSL_ImportFD(0, PR_NewTCPSocket());
- if (clientAuth) {
- NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUEST_CERTIFICATE, PR_TRUE));
- NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUIRE_CERTIFICATE, PR_TRUE));
- }
-
- //get certificate and key (is this the correct way?)
- CERTCertificate *cert = PK11_FindCertFromNickname(const_cast<char*>(certName.c_str()), 0);
- if (!cert) throw Exception(QPID_MSG("Failed to load certificate '" << certName << "'"));
- SECKEYPrivateKey *key = PK11_FindKeyByAnyCert(cert, 0);
- if (!key) throw Exception(QPID_MSG("Failed to retrieve private key from certificate"));
- NSS_CHECK(SSL_ConfigSecureServer(prototype, cert, key, NSS_FindCertKEAType(cert)));
- SECKEY_DestroyPrivateKey(key);
- CERT_DestroyCertificate(cert);
-
- //bind and listen
- const int& socket = impl->fd;
- int yes=1;
- QPID_POSIX_CHECK(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)));
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
- name.sin_addr.s_addr = 0;
- if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0)
- throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(errno)));
- if (::listen(socket, backlog) < 0)
- throw Exception(QPID_MSG("Can't listen on port " << port << ": " << strError(errno)));
-
- socklen_t namelen = sizeof(name);
- if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0)
- throw QPID_POSIX_ERROR(errno);
-
- return ntohs(name.sin_port);
-}
-
-SslSocket* SslSocket::accept() const
-{
- int afd = ::accept(impl->fd, 0, 0);
- if ( afd >= 0) {
- return new SslSocket(new IOHandlePrivate(afd), prototype);
- } else if (errno == EAGAIN) {
- return 0;
- } else {
- throw QPID_POSIX_ERROR(errno);
- }
-}
-
-int SslSocket::read(void *buf, size_t count) const
-{
- return PR_Read(socket, buf, count);
-}
-
-int SslSocket::write(const void *buf, size_t count) const
-{
- return PR_Write(socket, buf, count);
-}
-
-std::string SslSocket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string SslSocket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
-std::string SslSocket::getPeerAddress() const
-{
- if (!connectname.empty())
- return connectname;
- return getName(impl->fd, false, true);
-}
-
-std::string SslSocket::getLocalAddress() const
-{
- return getName(impl->fd, true, true);
-}
-
-uint16_t SslSocket::getLocalPort() const
-{
- return std::atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t SslSocket::getRemotePort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-int SslSocket::getError() const
-{
- int result;
- socklen_t rSize = sizeof (result);
-
- if (::getsockopt(impl->fd, SOL_SOCKET, SO_ERROR, &result, &rSize) < 0)
- throw QPID_POSIX_ERROR(errno);
-
- return result;
-}
-
-void SslSocket::setTcpNoDelay(bool nodelay) const
-{
- if (nodelay) {
- PRSocketOptionData option;
- option.option = PR_SockOpt_NoDelay;
- option.value.no_delay = true;
- PR_SetSocketOption(socket, &option);
- }
-}
-
-
-/** get the bit length of the current cipher's key */
-int SslSocket::getKeyLen() const
-{
- int enabled = 0;
- int keySize = 0;
- SECStatus rc;
-
- rc = SSL_SecurityStatus( socket,
- &enabled,
- NULL,
- NULL,
- &keySize,
- NULL, NULL );
- if (rc == SECSuccess && enabled) {
- return keySize;
- }
- return 0;
-}
-
-}}} // namespace qpid::sys::ssl