瀏覽代碼

AMBARI-2602. javax.crypto.BadPaddingException (final block not properly padded) thrown on ambari-server startup. (Oleksandr Diachenko via smohanty)

Sumit Mohanty 12 年之前
父節點
當前提交
ec3d6d5d77
共有 2 個文件被更改,包括 110 次插入16 次删除
  1. 53 7
      ambari-server/src/main/python/ambari-server.py
  2. 57 9
      ambari-server/src/test/python/TestAmbaryServer.py

+ 53 - 7
ambari-server/src/main/python/ambari-server.py

@@ -91,8 +91,12 @@ NR_CHOWN_CMD = 'chown {0} {1} {2}'
 
 
 RECURSIVE_RM_CMD = 'rm -rf {0}'
 RECURSIVE_RM_CMD = 'rm -rf {0}'
 
 
+SSL_PASSWORD_FILE = "pass.txt"
+SSL_PASSIN_FILE = "passin.txt" 
+
 # openssl command
 # openssl command
-EXPRT_KSTR_CMD = "openssl pkcs12 -export -in {0} -inkey {1} -certfile {0} -out {3} -password pass:{2} -passin pass:{2}"
+VALIDATE_KEYSTORE_CMD = "openssl pkcs12 -info -in '{0}' -password file:'{1}' -passout file:'{2}'"
+EXPRT_KSTR_CMD = "openssl pkcs12 -export -in '{0}' -inkey '{1}' -certfile '{0}' -out '{4}' -password file:'{2}' -passin file:'{3}'"
 CHANGE_KEY_PWD_CND = 'openssl rsa -in {0} -des3 -out {0}.secured -passout pass:{1}'
 CHANGE_KEY_PWD_CND = 'openssl rsa -in {0} -des3 -out {0}.secured -passout pass:{1}'
 GET_CRT_INFO_CMD = 'openssl x509 -dates -subject -in {0}'
 GET_CRT_INFO_CMD = 'openssl x509 -dates -subject -in {0}'
 
 
@@ -1761,6 +1765,24 @@ def find_jdbc_driver(args):
       return drivers
       return drivers
     return -1
     return -1
   return 0
   return 0
+  
+def copy_file(src, dest_file):
+  try:
+    shutil.copyfile(src, dest_file)
+  except Exception, e:
+    err = "Can not copy file {0} to {1} due to: {2} . Please check file " \
+              "permissions and free disk space.".format(src, dest_file, e.message)
+    raise FatalException(1, err)
+
+def remove_file(filePath):
+  if os.path.exists(filePath):
+    try:
+      os.remove(filePath)
+    except Exception, e:
+      print_warning_msg('Unable to remove file: ' + str(e))
+      return 1
+  pass
+  return 0
 
 
 def copy_files(files, dest_dir):
 def copy_files(files, dest_dir):
   if os.path.isdir(dest_dir):
   if os.path.isdir(dest_dir):
@@ -2930,20 +2952,44 @@ def import_cert_and_key(security_server_keys_dir):
                                     SSL_KEYSTORE_FILE_NAME)
                                     SSL_KEYSTORE_FILE_NAME)
     passFilePath = os.path.join(security_server_keys_dir,\
     passFilePath = os.path.join(security_server_keys_dir,\
                                 SSL_KEY_PASSWORD_FILE_NAME)
                                 SSL_KEY_PASSWORD_FILE_NAME)
+    passinFilePath = os.path.join(tempfile.gettempdir(),\
+                                   SSL_PASSIN_FILE)
+    passwordFilePath = os.path.join(tempfile.gettempdir(),\
+                                   SSL_PASSWORD_FILE)
+  
+    with open(passFilePath, 'w+') as passFile:
+      passFile.write(pem_password)
+      passFile.close
+      pass
+   
+    set_file_permissions(passFilePath, "660", read_ambari_user(), False)
+ 
+    copy_file(passFilePath, passinFilePath)
+    copy_file(passFilePath, passwordFilePath)
+ 
     retcode, out, err = run_os_command(EXPRT_KSTR_CMD.format(import_cert_path,\
     retcode, out, err = run_os_command(EXPRT_KSTR_CMD.format(import_cert_path,\
-    import_key_path, pem_password, keystoreFilePath))
-
+    import_key_path, passwordFilePath, passinFilePath, keystoreFilePath))
   if retcode == 0:
   if retcode == 0:
    print 'Importing and saving certificate...done.'
    print 'Importing and saving certificate...done.'
    set_file_permissions(keystoreFilePath, "660", read_ambari_user(), False)
    set_file_permissions(keystoreFilePath, "660", read_ambari_user(), False)
-   with open(passFilePath, 'w+') as passFile:
-    passFile.write(pem_password)
-    pass
-   set_file_permissions(passFilePath, "660", read_ambari_user(), False)
+
    import_file_to_keystore(import_cert_path, os.path.join(\
    import_file_to_keystore(import_cert_path, os.path.join(\
                           security_server_keys_dir, SSL_CERT_FILE_NAME))
                           security_server_keys_dir, SSL_CERT_FILE_NAME))
    import_file_to_keystore(import_key_path, os.path.join(\
    import_file_to_keystore(import_key_path, os.path.join(\
                           security_server_keys_dir, SSL_KEY_FILE_NAME))
                           security_server_keys_dir, SSL_KEY_FILE_NAME))
+
+   #Validate keystore
+   retcode, out, err = run_os_command(VALIDATE_KEYSTORE_CMD.format(keystoreFilePath,\
+   passwordFilePath, passinFilePath))
+   
+   remove_file(passinFilePath)
+   remove_file(passwordFilePath)
+
+   if not retcode == 0:
+     print 'Error during keystore validation occured!:'
+     print err
+     return False
+   
    return True
    return True
   else:
   else:
    print_error_msg('Could not import Certificate and Private Key.')
    print_error_msg('Could not import Certificate and Private Key.')

+ 57 - 9
ambari-server/src/test/python/TestAmbaryServer.py

@@ -1121,6 +1121,8 @@ class TestAmbariServer(TestCase):
     self.assertEqual(str(properties.process_pair.call_args_list),\
     self.assertEqual(str(properties.process_pair.call_args_list),\
                      expect_process_pair)
                      expect_process_pair)
     
     
+  @patch.object(ambari_server, "remove_file")
+  @patch.object(ambari_server, "copy_file")
   @patch.object(ambari_server, "read_ambari_user")
   @patch.object(ambari_server, "read_ambari_user")
   @patch.object(ambari_server, "set_file_permissions")
   @patch.object(ambari_server, "set_file_permissions")
   @patch.object(ambari_server, "import_file_to_keystore")
   @patch.object(ambari_server, "import_file_to_keystore")
@@ -1137,14 +1139,15 @@ class TestAmbariServer(TestCase):
                                get_validated_filepath_input_mock,\
                                get_validated_filepath_input_mock,\
                                os_path_join_mock, run_os_command_mock,\
                                os_path_join_mock, run_os_command_mock,\
                                open_mock, import_file_to_keystore_mock,\
                                open_mock, import_file_to_keystore_mock,\
-                               set_file_permissions_mock, read_ambari_user_mock):
+                               set_file_permissions_mock, read_ambari_user_mock, copy_file_mock,\
+                               remove_file_mock):
     is_valid_cert_exp_mock.return_value=True
     is_valid_cert_exp_mock.return_value=True
     is_valid_cert_host_mock.return_value=True
     is_valid_cert_host_mock.return_value=True
     get_validated_string_input_mock.return_value = "password"
     get_validated_string_input_mock.return_value = "password"
     get_validated_filepath_input_mock.side_effect = \
     get_validated_filepath_input_mock.side_effect = \
                                             ["cert_file_path","key_file_path"]
                                             ["cert_file_path","key_file_path"]
-    os_path_join_mock.side_effect = ["cert_file_path","key_file_path",\
-                                        "keystore_cert_file_path",\
+    os_path_join_mock.side_effect = ["keystore_file_path","pass_file_path",\
+                                        "passin_file_path","password_file_path","keystore_cert_file_path",\
                                         "keystore_cert_key_file_path",]
                                         "keystore_cert_key_file_path",]
     run_os_command_mock.return_value = (0, "",	"")
     run_os_command_mock.return_value = (0, "",	"")
     om = open_mock.return_value
     om = open_mock.return_value
@@ -1156,11 +1159,13 @@ class TestAmbariServer(TestCase):
     ambari_server.import_cert_and_key("key_dir")
     ambari_server.import_cert_and_key("key_dir")
     self.assertTrue(get_validated_filepath_input_mock.call_count == 2)
     self.assertTrue(get_validated_filepath_input_mock.call_count == 2)
     self.assertTrue(get_validated_string_input_mock.called)
     self.assertTrue(get_validated_string_input_mock.called)
-    self.assertTrue(os_path_join_mock.call_count == 4)
+    self.assertEqual(os_path_join_mock.call_count, 6)
     self.assertTrue(set_file_permissions_mock.call_count == 2)
     self.assertTrue(set_file_permissions_mock.call_count == 2)
     self.assertEqual(str(import_file_to_keystore_mock.call_args_list),\
     self.assertEqual(str(import_file_to_keystore_mock.call_args_list),\
                          expect_import_file_to_keystore)
                          expect_import_file_to_keystore)
 
 
+  @patch.object(ambari_server, "remove_file")
+  @patch.object(ambari_server, "copy_file")
   @patch.object(ambari_server, "generate_random_string")
   @patch.object(ambari_server, "generate_random_string")
   @patch.object(ambari_server, "read_ambari_user")
   @patch.object(ambari_server, "read_ambari_user")
   @patch.object(ambari_server, "set_file_permissions")
   @patch.object(ambari_server, "set_file_permissions")
@@ -1177,16 +1182,17 @@ class TestAmbariServer(TestCase):
     get_validated_string_input_mock, get_validated_filepath_input_mock,\
     get_validated_string_input_mock, get_validated_filepath_input_mock,\
     os_path_join_mock, run_os_command_mock, open_mock, \
     os_path_join_mock, run_os_command_mock, open_mock, \
     import_file_to_keystore_mock, set_file_permissions_mock,
     import_file_to_keystore_mock, set_file_permissions_mock,
-    read_ambari_user_mock, generate_random_string_mock):
+    read_ambari_user_mock, generate_random_string_mock, copy_file_mock,\
+    remove_file_mock):
       
       
     is_valid_cert_exp_mock.return_value=True
     is_valid_cert_exp_mock.return_value=True
     is_valid_cert_host_mock.return_value=True
     is_valid_cert_host_mock.return_value=True
     get_validated_string_input_mock.return_value = ""
     get_validated_string_input_mock.return_value = ""
     get_validated_filepath_input_mock.side_effect =\
     get_validated_filepath_input_mock.side_effect =\
     ["cert_file_path","key_file_path"]
     ["cert_file_path","key_file_path"]
-    os_path_join_mock.side_effect = ["cert_file_path","key_file_path",\
-                                     "keystore_cert_file_path",\
-                                     "keystore_cert_key_file_path",]
+    os_path_join_mock.side_effect = ["keystore_file_path","pass_file_path",\
+                                    "passin_file_path","password_file_path","keystore_cert_file_path",\
+                                    "keystore_cert_key_file_path",]
     run_os_command_mock.return_value = (0, "",	"")
     run_os_command_mock.return_value = (0, "",	"")
 
 
     expect_import_file_to_keystore = "[call('cert_file_path',"+\
     expect_import_file_to_keystore = "[call('cert_file_path',"+\
@@ -1197,7 +1203,7 @@ class TestAmbariServer(TestCase):
     ambari_server.import_cert_and_key("key_dir")
     ambari_server.import_cert_and_key("key_dir")
     self.assertEquals(get_validated_filepath_input_mock.call_count, 2)
     self.assertEquals(get_validated_filepath_input_mock.call_count, 2)
     self.assertTrue(get_validated_string_input_mock.called)
     self.assertTrue(get_validated_string_input_mock.called)
-    self.assertEquals(os_path_join_mock.call_count, 4)
+    self.assertEquals(os_path_join_mock.call_count, 6)
     self.assertEquals(set_file_permissions_mock.call_count, 2)
     self.assertEquals(set_file_permissions_mock.call_count, 2)
     self.assertEqual(str(import_file_to_keystore_mock.call_args_list),\
     self.assertEqual(str(import_file_to_keystore_mock.call_args_list),\
       expect_import_file_to_keystore)
       expect_import_file_to_keystore)
@@ -2752,6 +2758,48 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
 
 
     sys.stdout = sys.__stdout__
     sys.stdout = sys.__stdout__
 
 
+  
+  @patch("os.path.exists")
+  @patch("os.remove")
+  @patch.object(ambari_server,"print_warning_msg")
+  def test_remove_file(self, printWarningMsgMock, removeMock, pathExistsMock):
+    def side_effect():
+      raise Exception(-1, "Failed to delete!")
+    
+    removeMock.side_effect = side_effect
+    pathExistsMock.return_value = 1
+    
+    res = ambari_server.remove_file("/someNonExsistantDir/filename")
+    self.assertEquals(res,1)
+    
+    removeMock.side_effect = None
+    res = ambari_server.remove_file("/someExsistantDir/filename")
+    self.assertEquals(res, 0)
+  
+  @patch("shutil.copyfile")
+  def test_copy_file(self, shutilCopyfileMock):
+    def side_effect():
+      raise Exception(-1, "Failed to copy!")
+    
+    shutilCopyfileMock.side_effect = side_effect
+    
+    try:
+      ambari_server.copy_file("/tmp/psswd","/someNonExsistantDir/filename")
+      self.fail("Exception on file not copied has not been thrown!")
+    except FatalException:
+      # Expected
+      pass
+    
+    self.assertTrue(shutilCopyfileMock.called)
+    
+    
+    shutilCopyfileMock.side_effect = None
+    try:
+      ambari_server.copy_file("/tmp/psswd","/root/psswd")
+    except FatalException:
+        self.fail("Exception on file copied should not be thrown!")
+        
+    self.assertTrue(shutilCopyfileMock.called)
 
 
   @patch.object(ambari_server, "get_ambari_properties")
   @patch.object(ambari_server, "get_ambari_properties")
   @patch.object(ambari_server, "find_jdbc_driver")
   @patch.object(ambari_server, "find_jdbc_driver")