Repository: Azure/WALinuxAgent
Pull request #690 (2017-05-01 21:45:53)

Enabled FIPS support
Enable FIPS and address #668.
Support mixed case hostnames on RedHat (#686).

Signed-off-by: Brendan Dixon <brendandixon@me.com>


Patch:
diff --git a/azurelinuxagent/common/conf.py b/azurelinuxagent/common/conf.py
index 79116995..11b0aad4 100644
--- a/azurelinuxagent/common/conf.py
+++ b/azurelinuxagent/common/conf.py
@@ -113,6 +113,8 @@ def get_agent_pid_file_path(conf=__conf__):
 def get_ext_log_dir(conf=__conf__):
     return conf.get("Extension.LogDir", "/var/log/azure")
 
+def get_fips_enabled(conf=__conf__):
+    return conf.get_switch("OS.FIPSEnabled", False)
 
 def get_openssl_cmd(conf=__conf__):
     return conf.get("OS.OpensslPath", "/usr/bin/openssl")
diff --git a/azurelinuxagent/common/osutil/redhat.py b/azurelinuxagent/common/osutil/redhat.py
index 5254ea52..b94610c8 100644
--- a/azurelinuxagent/common/osutil/redhat.py
+++ b/azurelinuxagent/common/osutil/redhat.py
@@ -103,7 +103,7 @@ class RedhatOSUtil(Redhat6xOSUtil):
         Due to a bug in systemd in Centos-7.0, if this call fails, fallback
         to hostname.
         """
-        hostnamectl_cmd = "hostnamectl set-hostname {0}".format(hostname)
+        hostnamectl_cmd = "hostnamectl set-hostname {0} --static".format(hostname)
         if shellutil.run(hostnamectl_cmd, chk_err=False) != 0:
             logger.warn("[{0}] failed, attempting fallback".format(hostnamectl_cmd))
             DefaultOSUtil.set_hostname(self, hostname)
diff --git a/azurelinuxagent/daemon/main.py b/azurelinuxagent/daemon/main.py
index b0da02aa..9d7130c1 100644
--- a/azurelinuxagent/daemon/main.py
+++ b/azurelinuxagent/daemon/main.py
@@ -39,6 +39,8 @@ from azurelinuxagent.ga.update import get_update_handler
 from azurelinuxagent.pa.provision import get_provision_handler
 from azurelinuxagent.pa.rdma import get_rdma_handler
 
+OPENSSL_FIPS_ENVIRONMENT = "OPENSSL_FIPS"
+
 
 def get_daemon_handler():
     return DaemonHandler()
@@ -61,6 +63,12 @@ class DaemonHandler(object):
 
         self.check_pid()
 
+        # If FIPS is enabled, set the OpenSSL environment variable
+        # Note:
+        # -- Subprocesses inherit the current environment
+        if conf.get_fips_enabled():
+            os.environ[OPENSSL_FIPS_ENVIRONMENT] = '1'
+
         while self.running:
             try:
                 self.daemon()
diff --git a/config/alpine/waagent.conf b/config/alpine/waagent.conf
index 11615520..3be79f95 100644
--- a/config/alpine/waagent.conf
+++ b/config/alpine/waagent.conf
@@ -56,6 +56,9 @@ Logs.Verbose=n
 # Preferred network interface to communicate with Azure platform
 Network.Interface=eth0
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/arch/waagent.conf b/config/arch/waagent.conf
index 8bd53291..826cfd99 100644
--- a/config/arch/waagent.conf
+++ b/config/arch/waagent.conf
@@ -57,6 +57,9 @@ LBProbeResponder=y
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/bigip/waagent.conf b/config/bigip/waagent.conf
index 06e6931b..33ea9cb2 100644
--- a/config/bigip/waagent.conf
+++ b/config/bigip/waagent.conf
@@ -51,6 +51,9 @@ LBProbeResponder=y
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/clearlinux/waagent.conf b/config/clearlinux/waagent.conf
index c0d17a85..6a4f1feb 100644
--- a/config/clearlinux/waagent.conf
+++ b/config/clearlinux/waagent.conf
@@ -56,6 +56,9 @@ ResourceDisk.SwapSizeMB=0
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/coreos/waagent.conf b/config/coreos/waagent.conf
index 323331fe..3d93c269 100644
--- a/config/coreos/waagent.conf
+++ b/config/coreos/waagent.conf
@@ -57,6 +57,9 @@ LBProbeResponder=y
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/freebsd/waagent.conf b/config/freebsd/waagent.conf
index 0589831a..7312667e 100644
--- a/config/freebsd/waagent.conf
+++ b/config/freebsd/waagent.conf
@@ -51,6 +51,9 @@ ResourceDisk.MountOptions=None
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/suse/waagent.conf b/config/suse/waagent.conf
index ca53acfc..edb1ce3a 100644
--- a/config/suse/waagent.conf
+++ b/config/suse/waagent.conf
@@ -57,6 +57,9 @@ LBProbeResponder=y
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/ubuntu/waagent.conf b/config/ubuntu/waagent.conf
index dbc80fce..3ad1e89a 100644
--- a/config/ubuntu/waagent.conf
+++ b/config/ubuntu/waagent.conf
@@ -57,6 +57,9 @@ LBProbeResponder=y
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 
diff --git a/config/waagent.conf b/config/waagent.conf
index 8a694620..02b4bed0 100644
--- a/config/waagent.conf
+++ b/config/waagent.conf
@@ -54,6 +54,9 @@ ResourceDisk.MountOptions=None
 # Enable verbose logging (y|n)
 Logs.Verbose=n
 
+# Is FIPS enabled
+OS.FIPSEnabled=n
+
 # Root device timeout in seconds.
 OS.RootDeviceScsiTimeout=300
 


Test patch:
diff --git a/tests/daemon/test_daemon.py b/tests/daemon/test_daemon.py
index dd31fd70..5694dc9f 100644
--- a/tests/daemon/test_daemon.py
+++ b/tests/daemon/test_daemon.py
@@ -14,7 +14,9 @@
 #
 # Requires Python 2.4+ and Openssl 1.0+
 #
-from azurelinuxagent.daemon import get_daemon_handler
+
+from azurelinuxagent.daemon import *
+from azurelinuxagent.daemon.main import OPENSSL_FIPS_ENVIRONMENT
 from tests.tools import *
 
 
@@ -30,8 +32,9 @@ class MockDaemonCall(object):
             self.daemon_handler.running = False
         raise Exception("Mock unhandled exception")
 
-@patch("time.sleep")
 class TestDaemon(AgentTestCase):
+    
+    @patch("time.sleep")
     def test_daemon_restart(self, mock_sleep):
         #Mock daemon function
         daemon_handler = get_daemon_handler()
@@ -45,6 +48,7 @@ class TestDaemon(AgentTestCase):
         mock_sleep.assert_any_call(15)
         self.assertEquals(2, daemon_handler.daemon.call_count)
 
+    @patch("time.sleep")
     @patch("azurelinuxagent.daemon.main.conf")
     @patch("azurelinuxagent.daemon.main.sys.exit")
     def test_check_pid(self, mock_exit, mock_conf, mock_sleep):
@@ -58,6 +62,25 @@ class TestDaemon(AgentTestCase):
 
         daemon_handler.check_pid()
         mock_exit.assert_any_call(0)
+
+    @patch("azurelinuxagent.daemon.main.DaemonHandler.check_pid")
+    @patch("azurelinuxagent.common.conf.get_fips_enabled", return_value=True)
+    def test_set_openssl_fips(self, mock_conf, mock_daemon):
+        daemon_handler = get_daemon_handler()
+        daemon_handler.running = False
+        with patch.dict("os.environ"):
+            daemon_handler.run()
+            self.assertTrue(OPENSSL_FIPS_ENVIRONMENT in os.environ)
+            self.assertEqual('1', os.environ[OPENSSL_FIPS_ENVIRONMENT])
+
+    @patch("azurelinuxagent.daemon.main.DaemonHandler.check_pid")
+    @patch("azurelinuxagent.common.conf.get_fips_enabled", return_value=False)
+    def test_does_not_set_openssl_fips(self, mock_conf, mock_daemon):
+        daemon_handler = get_daemon_handler()
+        daemon_handler.running = False
+        with patch.dict("os.environ"):
+            daemon_handler.run()
+            self.assertFalse(OPENSSL_FIPS_ENVIRONMENT in os.environ)
    
 if __name__ == '__main__':
     unittest.main()