https://issues.shibboleth.net/jira/browse/SSPCPP-569
[shibboleth/cpp-sp.git] / shibsp / remoting / impl / UnixListener.cpp
index 795a2cf..9fc5408 100644 (file)
@@ -1,17 +1,21 @@
-/*
- *  Copyright 2001-2010 Internet2
- * 
- * Licensed 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
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ *
+ * UCAID 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
+ * 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.
+ * 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.
  */
 
 /**
@@ -40,6 +44,7 @@
 #include <sys/stat.h>          /* for chmod() */
 #include <stdio.h>
 #include <stdlib.h>
+#include <fcntl.h>
 #include <errno.h>
 
 using namespace shibsp;
@@ -83,8 +88,10 @@ namespace shibsp {
 };
 
 UnixListener::UnixListener(const DOMElement* e)
-    : SocketListener(e), m_address(XMLHelper::getAttrString(e, "shibd.sock", address)), m_bound(false)
+    : SocketListener(e), m_address(XMLHelper::getAttrString(e, getenv("SHIBSP_LISTENER_ADDRESS"), address)), m_bound(false)
 {
+    if (m_address.empty())
+        m_address = "shibd.sock";
     XMLToolingConfig::getConfig().getPathResolver()->resolve(m_address, PathResolver::XMLTOOLING_RUN_FILE);
 }
 
@@ -92,11 +99,24 @@ UnixListener::UnixListener(const DOMElement* e)
 #define UNIX_PATH_MAX 100
 #endif
 
-bool UnixListener::create(ShibSocket& sock) const
+bool UnixListener::create(ShibSocket& s) const
 {
-    sock = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (sock < 0)
-        return log_error();
+    int type = SOCK_STREAM;
+#ifdef HAVE_SOCK_CLOEXEC
+    type |= SOCK_CLOEXEC;
+#endif
+    s = socket(PF_UNIX, type, 0);
+    if (s < 0)
+        return log_error("socket");
+
+#if !defined(HAVE_SOCK_CLOEXEC) && defined(HAVE_FD_CLOEXEC)
+    int fdflags = fcntl(s, F_GETFD);
+    if (fdflags != -1) {
+        fdflags |= FD_CLOEXEC;
+        fcntl(s, F_SETFD, fdflags);
+    }
+#endif
+
     return true;
 }
 
@@ -111,7 +131,7 @@ bool UnixListener::bind(ShibSocket& s, bool force) const
         unlink(m_address.c_str());
 
     if (::bind(s, (struct sockaddr *)&addr, sizeof (addr)) < 0) {
-        log_error();
+        log_error("bind");
         close(s);
         return false;
     }
@@ -119,7 +139,7 @@ bool UnixListener::bind(ShibSocket& s, bool force) const
     // Make sure that only the creator can read -- we don't want just
     // anyone connecting, do we?
     if (chmod(m_address.c_str(),0777) < 0) {
-        log_error();
+        log_error("chmod");
         close(s);
         unlink(m_address.c_str());
         return false;
@@ -137,7 +157,7 @@ bool UnixListener::connect(ShibSocket& s) const
     strncpy(addr.sun_path, m_address.c_str(), UNIX_PATH_MAX);
 
     if (::connect(s, (struct sockaddr *)&addr, sizeof (addr)) < 0)
-        return log_error();
+        return log_error("connect");
     return true;
 }
 
@@ -151,6 +171,6 @@ bool UnixListener::accept(ShibSocket& listener, ShibSocket& s) const
 {
     s=::accept(listener,nullptr,nullptr);
     if (s < 0)
-        return log_error();
+        return log_error("accept");
     return true;
 }