#include "remoting/impl/SocketListener.h"
#include "util/IPRange.h"
+#include <boost/bind.hpp>
+#include <boost/algorithm/string.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/unicode.h>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
namespace shibsp {
m_port = 1600;
}
- int j = 0;
+ vector<string> rawacls;
string aclbuf = XMLHelper::getAttrString(e, "127.0.0.1", acl);
- for (unsigned int i = 0; i < aclbuf.length(); ++i) {
- if (aclbuf.at(i) == ' ') {
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, i-j).c_str()));
- }
- catch (exception& ex) {
- log->error("invalid CIDR block (%s): %s", aclbuf.substr(j, i-j).c_str(), ex.what());
- }
- j = i + 1;
+ boost::split(rawacls, aclbuf, boost::is_space(), algorithm::token_compress_on);
+ for (vector<string>::const_iterator i = rawacls.begin(); i < rawacls.end(); ++i) {
+ try {
+ m_acl.push_back(IPRange::parseCIDRBlock(i->c_str()));
+ }
+ catch (std::exception& ex) {
+ log->error("invalid CIDR block (%s): %s", i->c_str(), ex.what());
}
- }
- try {
- m_acl.push_back(IPRange::parseCIDRBlock(aclbuf.substr(j, aclbuf.length()-j).c_str()));
- }
- catch (exception& ex) {
- log->error("invalid CIDR block (%s): %s", aclbuf.substr(j, aclbuf.length()-j).c_str(), ex.what());
}
if (m_acl.empty()) {
return false;
}
#else
+ // Newer BSDs require the struct length be passed based on the socket address.
+ // Others have no field for that and take the whole struct size like Windows does.
+# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+# ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+ if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.ss_len) < 0) {
+# else
+ if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.sin_len) < 0) {
+# endif
+# else
if (::bind(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) < 0) {
+# endif
log_error("bind");
close(s);
return false;
if(SOCKET_ERROR==::connect(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)))
return log_error("connect");
#else
+ // Newer BSDs require the struct length be passed based on the socket address.
+ // Others have no field for that and take the whole struct size like Windows does.
+# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+# ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+ if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.ss_len) < 0)
+# else
+ if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.sin_len) < 0)
+# endif
+# else
if (::connect(s, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) < 0)
+# endif
return log_error("connect");
#endif
return true;
if (s < 0)
#endif
return log_error("accept");
- bool found = false;
- for (vector<IPRange>::const_iterator acl = m_acl.begin(); !found && acl != m_acl.end(); ++acl) {
- found = acl->contains((const struct sockaddr*)&addr);
- }
- if (!found) {
+
+ static bool (IPRange::* contains)(const struct sockaddr*) const = &IPRange::contains;
+ if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, (const struct sockaddr*)&addr)) == m_acl.end()) {
close(s);
s = -1;
log->error("accept() rejected client with invalid address");