Hello community,

here is the log from the commit of package yast2-rmt for openSUSE:Factory 
checked in at 2018-06-28 15:14:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-rmt (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-rmt.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-rmt"

Thu Jun 28 15:14:21 2018 rev:6 rq:619421 version:1.0.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-rmt/yast2-rmt.changes      2018-05-19 
15:43:02.937348524 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-rmt.new/yast2-rmt.changes 2018-06-28 
15:14:23.891485229 +0200
@@ -1,0 +2,7 @@
+Mon Jun 25 15:32:29 UTC 2018 - [email protected]
+
+- version 1.0.1
+- setting and validating CA private key password (bsc#1099324)
+- reload nginx after configuration
+
+-------------------------------------------------------------------

Old:
----
  yast2-rmt-1.0.0.tar.bz2

New:
----
  yast2-rmt-1.0.1.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-rmt.spec ++++++
--- /var/tmp/diff_new_pack.VFPMTj/_old  2018-06-28 15:14:25.331482591 +0200
+++ /var/tmp/diff_new_pack.VFPMTj/_new  2018-06-28 15:14:25.331482591 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-rmt
-Version:        1.0.0
+Version:        1.0.1
 Release:        0
 BuildArch:      noarch
 

++++++ yast2-rmt-1.0.0.tar.bz2 -> yast2-rmt-1.0.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-rmt-1.0.0/README.md 
new/yast2-rmt-1.0.1/README.md
--- old/yast2-rmt-1.0.0/README.md       2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/README.md       2018-06-27 16:36:27.000000000 +0200
@@ -12,7 +12,7 @@
 
 ### Running the module
 
-`yast2-ruby-bindings` RPM package is not available as a gem, Yast runs on the 
system-wide Ruby interpreter only.
+`yast2-ruby-bindings` RPM package is not available as a gem, YaST runs on the 
default system-wide Ruby interpreter only (available in the OSS repository).
 
 There different ways to run the module:
 
@@ -41,7 +41,7 @@
 rake osc:commit
 ```
 
-to commit the current version to OBS. 
+to commit the current version to OBS.
 
 
 #### Submit Requests to openSUSE Factory and SLES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-rmt-1.0.0/package/yast2-rmt.changes 
new/yast2-rmt-1.0.1/package/yast2-rmt.changes
--- old/yast2-rmt-1.0.0/package/yast2-rmt.changes       2018-05-18 
13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/package/yast2-rmt.changes       2018-06-27 
16:36:27.000000000 +0200
@@ -1,10 +1,18 @@
 -------------------------------------------------------------------
+Mon Jun 25 15:32:29 UTC 2018 - [email protected]
+
+- version 1.0.1
+- setting and validating CA private key password (bsc#1099324)
+- reload nginx after configuration
+
+-------------------------------------------------------------------
 Fri May 18 08:58:01 UTC 2018 - [email protected]
 
 - version 1.0.0
+- Release for SLES15 (bsc#1093879)
 - UI cleanups
 - Enable timers with rmt service start
-- Add final configuration summary 
+- Add final configuration summary
 
 -------------------------------------------------------------------
 Wed Apr 18 12:06:01 UTC 2018 - [email protected]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-rmt-1.0.0/package/yast2-rmt.spec 
new/yast2-rmt-1.0.1/package/yast2-rmt.spec
--- old/yast2-rmt-1.0.0/package/yast2-rmt.spec  2018-05-18 13:57:35.000000000 
+0200
+++ new/yast2-rmt-1.0.1/package/yast2-rmt.spec  2018-06-27 16:36:27.000000000 
+0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-rmt
-Version:        1.0.0
+Version:        1.0.1
 Release:        0
 BuildArch:      noarch
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/maria_db/current_root_password_dialog_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/maria_db/current_root_password_dialog_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/maria_db/current_root_password_dialog_spec.rb  
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/spec/rmt/maria_db/current_root_password_dialog_spec.rb  
2018-06-27 16:36:27.000000000 +0200
@@ -23,68 +23,15 @@
 describe RMT::MariaDB::CurrentRootPasswordDialog do
   subject(:dialog) { described_class.new }
 
-  describe '#dialog_content' do
-    it 'creates the UI elements' do
-      expect(Yast::Term).to receive(:new).exactly(22).times
-      dialog.dialog_content
-    end
-  end
-
-  describe '#user_input' do
-    it 'sets focus and waits for user input' do
-      expect(Yast::UI).to receive(:SetFocus).with(Id(:root_password))
-      expect_any_instance_of(UI::Dialog).to receive(:user_input)
-      dialog.user_input
-    end
-  end
-
-  describe '#ok_handler' do
-    context 'when the password field is empty' do
-      let(:password) { '' }
-
-      it 'reports an error' do
-        expect(Yast::UI).to receive(:QueryWidget).with(Id(:root_password), 
:Value).and_return(password)
-        expect(Yast::UI).to receive(:SetFocus).with(Id(:root_password))
-        expect(Yast::Report).to receive(:Error).with('Please provide the root 
password.')
-        expect(dialog).not_to receive(:finish_dialog)
-        dialog.ok_handler
-      end
-    end
-
-    context 'when the password is invalid' do
-      let(:password) { 'password' }
-
-      it 'reports an error' do
-        expect(Yast::UI).to receive(:QueryWidget).with(Id(:root_password), 
:Value).and_return(password)
-        expect(Yast::UI).to receive(:SetFocus).with(Id(:root_password))
-        expect(dialog).to receive(:root_password_valid?).and_return(false)
-        expect(Yast::Report).to receive(:Error).with('The provided password is 
not valid.')
-        expect(dialog).not_to receive(:finish_dialog)
-        dialog.ok_handler
-      end
-    end
-
-    context 'when the password is valid' do
-      let(:password) { 'password' }
-
-      it 'finishes the dialog and returns the password' do
-        expect(Yast::UI).to receive(:QueryWidget).with(Id(:root_password), 
:Value).and_return(password)
-        expect(dialog).to receive(:root_password_valid?).and_return(true)
-        expect(dialog).to receive(:finish_dialog).with(password)
-        dialog.ok_handler
-      end
-    end
-  end
-
-  describe '#root_password_valid?' do
+  describe '#password_valid?' do
     it 'returns true when exit code is 0' do
       expect(RMT::Utils).to receive(:run_command).and_return(0)
-      expect(dialog.root_password_valid?('password')).to be(true)
+      expect(dialog.send(:password_valid?, 'password')).to be(true)
     end
 
     it 'returns false when exit code is not 0' do
       expect(RMT::Utils).to receive(:run_command).and_return(1)
-      expect(dialog.root_password_valid?('password')).to be(false)
+      expect(dialog.send(:password_valid?, 'password')).to be(false)
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/maria_db/new_root_password_dialog_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/maria_db/new_root_password_dialog_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/maria_db/new_root_password_dialog_spec.rb      
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/spec/rmt/maria_db/new_root_password_dialog_spec.rb      
2018-06-27 16:36:27.000000000 +0200
@@ -23,64 +23,6 @@
 describe RMT::MariaDB::NewRootPasswordDialog do
   subject(:dialog) { described_class.new }
 
-  describe '#dialog_content' do
-    it 'creates the UI elements' do
-      expect(Yast::Term).to receive(:new).exactly(26).times
-      dialog.dialog_content
-    end
-  end
-
-  describe '#user_input' do
-    it 'sets focus and waits for user input' do
-      expect(Yast::UI).to receive(:SetFocus).with(Id(:new_root_password_1))
-      expect_any_instance_of(UI::Dialog).to receive(:user_input)
-      dialog.user_input
-    end
-  end
-
-  describe '#ok_handler' do
-    before do
-      expect(Yast::UI).to receive(:QueryWidget).with(Id(:new_root_password_1), 
:Value).and_return(password1)
-      expect(Yast::UI).to receive(:QueryWidget).with(Id(:new_root_password_2), 
:Value).and_return(password2)
-    end
-
-    context 'when the password is blank' do
-      let(:password1) { '' }
-      let(:password2) { 'good_password' }
-
-      it 'reports an error' do
-        expect(Yast::UI).to receive(:SetFocus).with(Id(:new_root_password_1))
-        expect(Yast::Report).to receive(:Error).with('Password must not be 
blank.')
-
-        expect(dialog).not_to receive(:finish_dialog)
-        dialog.ok_handler
-      end
-    end
-
-    context 'when the password is blank' do
-      let(:password1) { 'bad_password' }
-      let(:password2) { 'good_password' }
-
-      it 'reports an error' do
-        expect(Yast::UI).to receive(:SetFocus).with(Id(:new_root_password_2))
-        expect(Yast::Report).to receive(:Error).with('The first and the second 
passwords do not match.')
-
-        expect(dialog).not_to receive(:finish_dialog)
-        dialog.ok_handler
-      end
-    end
-
-    context 'when the passwords match' do
-      let(:password1) { 'good_password' }
-      let(:password2) { 'good_password' }
-
-      it 'finishes the dialog and returns the password' do
-        expect(dialog).to receive(:finish_dialog).with(password1)
-        dialog.ok_handler
-      end
-    end
-  end
-
   describe '#set_root_password' do
     it 'returns true when exit code is 0' do
       expect(RMT::Utils).to receive(:run_command).and_return(0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/shared/input_password_dialog_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/shared/input_password_dialog_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/shared/input_password_dialog_spec.rb   
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/spec/rmt/shared/input_password_dialog_spec.rb   
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,84 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/shared/input_password_dialog'
+
+Yast.import 'Report'
+
+describe RMT::Shared::InputPasswordDialog do
+  subject(:dialog) { described_class.new }
+
+  describe '#dialog_content' do
+    it 'creates the UI elements' do
+      expect(Yast::Term).to receive(:new).exactly(23).times
+      dialog.send(:dialog_content)
+    end
+  end
+
+  describe '#user_input' do
+    it 'sets focus and waits for user input' do
+      expect(Yast::UI).to receive(:SetFocus).with(Id(:password))
+      expect_any_instance_of(UI::Dialog).to receive(:user_input)
+      dialog.user_input
+    end
+  end
+
+  describe '#ok_handler' do
+    context 'when the password field is empty' do
+      let(:password) { '' }
+
+      it 'reports an error' do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:password), 
:Value).and_return(password)
+        expect(Yast::UI).to receive(:SetFocus).with(Id(:password))
+        expect(Yast::Report).to receive(:Error).with('Please provide the 
password.')
+        expect(dialog).not_to receive(:finish_dialog)
+        dialog.ok_handler
+      end
+    end
+
+    context 'when the password is invalid' do
+      let(:password) { 'password' }
+
+      it 'reports an error' do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:password), 
:Value).and_return(password)
+        expect(Yast::UI).to receive(:SetFocus).with(Id(:password))
+        expect(dialog).to receive(:password_valid?).and_return(false)
+        expect(Yast::Report).to receive(:Error).with('The provided password is 
not valid.')
+        expect(dialog).not_to receive(:finish_dialog)
+        dialog.ok_handler
+      end
+    end
+
+    context 'when the password is valid' do
+      let(:password) { 'password' }
+
+      it 'finishes the dialog and returns the password' do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:password), 
:Value).and_return(password)
+        expect(dialog).to receive(:password_valid?).and_return(true)
+        expect(dialog).to receive(:finish_dialog).with(password)
+        dialog.ok_handler
+      end
+    end
+  end
+
+  describe '#password_valid?' do
+    it 'raises error' do
+      expect { dialog.send(:password_valid?, 'password') }.to 
raise_error(NotImplementedError)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/shared/set_password_dialog_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/shared/set_password_dialog_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/shared/set_password_dialog_spec.rb     
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/spec/rmt/shared/set_password_dialog_spec.rb     
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,97 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/shared/set_password_dialog'
+
+Yast.import 'Report'
+
+describe RMT::Shared::SetPasswordDialog do
+  subject(:dialog) { described_class.new }
+
+  describe '#dialog_content' do
+    it 'creates the UI elements' do
+      expect(Yast::Term).to receive(:new).exactly(26).times
+      dialog.send(:dialog_content)
+    end
+  end
+
+  describe '#user_input' do
+    it 'sets focus and waits for user input' do
+      expect(Yast::UI).to receive(:SetFocus).with(Id(:password))
+      expect_any_instance_of(UI::Dialog).to receive(:user_input)
+      dialog.user_input
+    end
+  end
+
+  describe '#ok_handler' do
+    before do
+      expect(Yast::UI).to receive(:QueryWidget).with(Id(:password), 
:Value).and_return(password1)
+      expect(Yast::UI).to 
receive(:QueryWidget).with(Id(:password_confirmation), 
:Value).and_return(password2)
+    end
+
+    context 'when the password is blank' do
+      let(:password1) { '' }
+      let(:password2) { 'good_password' }
+
+      it 'reports an error' do
+        expect(Yast::UI).to receive(:SetFocus).with(Id(:password))
+        expect(Yast::Report).to receive(:Error).with('Password must not be 
blank.')
+
+        expect(dialog).not_to receive(:finish_dialog)
+        dialog.ok_handler
+      end
+    end
+
+    context 'when the password too short' do
+      before { dialog.instance_variable_set(:@min_password_size, 4) }
+      let(:password1) { '12' }
+      let(:password2) { '12' }
+
+      it 'reports an error' do
+        expect(Yast::UI).to receive(:SetFocus).with(Id(:password))
+        expect(Yast::Report).to receive(:Error).with('Password has to have at 
least 4 characters.')
+
+        expect(dialog).not_to receive(:finish_dialog)
+        dialog.ok_handler
+      end
+    end
+
+    context 'when the password is blank' do
+      let(:password1) { 'bad_password' }
+      let(:password2) { 'good_password' }
+
+      it 'reports an error' do
+        expect(Yast::UI).to receive(:SetFocus).with(Id(:password_confirmation))
+        expect(Yast::Report).to receive(:Error).with('The first and the second 
passwords do not match.')
+
+        expect(dialog).not_to receive(:finish_dialog)
+        dialog.ok_handler
+      end
+    end
+
+    context 'when the passwords match' do
+      let(:password1) { 'good_password' }
+      let(:password2) { 'good_password' }
+
+      it 'finishes the dialog and returns the password' do
+        expect(dialog).to receive(:finish_dialog).with(password1)
+        dialog.ok_handler
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/ssl/certificate_generator_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/ssl/certificate_generator_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/ssl/certificate_generator_spec.rb      
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/spec/rmt/ssl/certificate_generator_spec.rb      
2018-06-27 16:36:27.000000000 +0200
@@ -63,6 +63,41 @@
     end
   end
 
+  describe '#ca_encrypted?' do
+    subject(:method_call) { generator.ca_encrypted? }
+
+    it 'calls #valid_password? method' do
+      expect(generator).to receive(:valid_password?).with(' ')
+      method_call
+    end
+  end
+
+  describe '#valid_password?' do
+    subject(:method_call) { generator.valid_password?(password) }
+
+    let(:password) { 'foobar' }
+
+    context 'with valid password' do
+      it 'returns true' do
+        expect(RMT::Execute).to receive(:on_target!).with(
+          'openssl', 'rsa', '-passin', 'stdin', '-in', 
ssl_files[:ca_private_key],
+          stdin: password
+        ).and_return(true)
+        expect(method_call).to eq(true)
+      end
+    end
+
+    context 'with invalid password' do
+      it 'returns false' do
+        expect(RMT::Execute).to receive(:on_target!).with(
+          'openssl', 'rsa', '-passin', 'stdin', '-in', 
ssl_files[:ca_private_key],
+          stdin: password
+        ).and_raise(Cheetah::ExecutionFailed.new('', '', '', ''))
+        expect(method_call).to eq(false)
+      end
+    end
+  end
+
   describe '#server_cert_present??' do
     subject(:result) { generator.server_cert_present? }
 
@@ -104,6 +139,7 @@
     let(:server_cert) { 'server_cert' }
     let(:common_name) { 'example.org' }
     let(:alt_names) { ['foo.example.org', 'bar.example.org'] }
+    let(:ca_password) { 'foobar' }
 
     context 'when CA is not yet generated' do
       it 'generates the CA and server certificates' do
@@ -119,8 +155,9 @@
         expect(Yast::SCR).to receive(:Write).with(scr_path, 
ssl_files[:server_config], server_config)
 
         expect(RMT::Execute).to receive(:on_target!).with(
-          'openssl', 'genrsa', '-out',
-          ssl_files[:ca_private_key], described_class::OPENSSL_KEY_BITS
+          'openssl', 'genrsa', '-aes256', '-passout', 'stdin', '-out',
+          ssl_files[:ca_private_key], described_class::OPENSSL_KEY_BITS,
+          stdin: ca_password
         )
 
         expect(RMT::Execute).to receive(:on_target!).with(
@@ -131,7 +168,50 @@
         expect(RMT::Execute).to receive(:on_target!).with(
           'openssl', 'req', '-x509', '-new', '-nodes',
           '-key', ssl_files[:ca_private_key], '-sha256', '-days', 
described_class::OPENSSL_CA_VALIDITY_DAYS,
-          '-out', ssl_files[:ca_certificate], '-config', ssl_files[:ca_config]
+          '-out', ssl_files[:ca_certificate], '-passin', 'stdin', '-config', 
ssl_files[:ca_config],
+          stdin: ca_password
+        )
+
+        expect(RMT::Execute).to receive(:on_target!).with(
+          'openssl', 'req', '-new', '-key', ssl_files[:server_private_key],
+          '-out', ssl_files[:server_csr], '-config', ssl_files[:server_config]
+        )
+
+        expect(RMT::Execute).to receive(:on_target!).with(
+          'openssl', 'x509', '-req', '-in', ssl_files[:server_csr],
+          '-out', ssl_files[:server_certificate], '-CA', 
ssl_files[:ca_certificate],
+          '-CAkey', ssl_files[:ca_private_key], '-passin', 'stdin', '-days', 
described_class::OPENSSL_SERVER_CERT_VALIDITY_DAYS,
+          '-sha256', '-CAcreateserial', '-extensions', 'v3_server_sign',
+          '-extfile', ssl_files[:server_config],
+          stdin: ca_password
+        )
+
+        expect(Yast::SCR).to receive(:Read).with(scr_path, 
ssl_files[:server_certificate]).and_return(server_cert)
+        expect(Yast::SCR).to receive(:Read).with(scr_path, 
ssl_files[:ca_certificate]).and_return(ca_cert)
+        expect(Yast::SCR).to receive(:Write).with(scr_path, 
ssl_files[:server_certificate], server_cert + ca_cert)
+
+        expect(RMT::Execute).to receive(:on_target!).with('chown', 
'root:nginx', ssl_files[:ca_certificate])
+        expect(RMT::Execute).to receive(:on_target!).with('chmod', '0640', 
ssl_files[:ca_certificate])
+
+        generator.generate(common_name, alt_names, ca_password)
+      end
+    end
+
+    context 'when CA is generated without password' do
+      let(:ca_password) { '' }
+
+      it 'generates only the server certificate' do
+        expect(RMT::SSL::ConfigGenerator).to 
receive(:new).and_return(config_generator_double)
+        expect(generator).to 
receive(:ca_present?).and_return(true).exactly(2).times
+        expect(config_generator_double).to 
receive(:make_server_config).and_return(server_config)
+
+        expect(generator).to receive(:create_files)
+
+        expect(Yast::SCR).to receive(:Write).with(scr_path, 
ssl_files[:server_config], server_config)
+
+        expect(RMT::Execute).to receive(:on_target!).with(
+          'openssl', 'genrsa', '-out',
+          ssl_files[:server_private_key], described_class::OPENSSL_KEY_BITS
         )
 
         expect(RMT::Execute).to receive(:on_target!).with(
@@ -154,7 +234,7 @@
         expect(RMT::Execute).to receive(:on_target!).with('chown', 
'root:nginx', ssl_files[:ca_certificate])
         expect(RMT::Execute).to receive(:on_target!).with('chmod', '0640', 
ssl_files[:ca_certificate])
 
-        generator.generate(common_name, alt_names)
+        generator.generate(common_name, alt_names, ca_password)
       end
     end
 
@@ -181,9 +261,10 @@
         expect(RMT::Execute).to receive(:on_target!).with(
           'openssl', 'x509', '-req', '-in', ssl_files[:server_csr],
           '-out', ssl_files[:server_certificate], '-CA', 
ssl_files[:ca_certificate],
-          '-CAkey', ssl_files[:ca_private_key], '-days', 
described_class::OPENSSL_SERVER_CERT_VALIDITY_DAYS,
+          '-CAkey', ssl_files[:ca_private_key], '-passin', 'stdin', '-days', 
described_class::OPENSSL_SERVER_CERT_VALIDITY_DAYS,
           '-sha256', '-CAcreateserial', '-extensions', 'v3_server_sign',
-          '-extfile', ssl_files[:server_config]
+          '-extfile', ssl_files[:server_config],
+          stdin: ca_password
         )
 
         expect(Yast::SCR).to receive(:Read).with(scr_path, 
ssl_files[:server_certificate]).and_return(server_cert)
@@ -193,20 +274,20 @@
         expect(RMT::Execute).to receive(:on_target!).with('chown', 
'root:nginx', ssl_files[:ca_certificate])
         expect(RMT::Execute).to receive(:on_target!).with('chmod', '0640', 
ssl_files[:ca_certificate])
 
-        generator.generate(common_name, alt_names)
+        generator.generate(common_name, alt_names, ca_password)
       end
     end
 
     it 'handles Cheetah::ExecutionFailed exceptions' do
       expect(RMT::SSL::ConfigGenerator).to 
receive(:new).and_raise(Cheetah::ExecutionFailed.new('cmd', 1, '', 'Dummy 
error'))
       expect(Yast::Report).to receive(:Error).with("An error occurred during 
SSL certificate generation:\nDummy error\n")
-      generator.generate(common_name, alt_names)
+      generator.generate(common_name, alt_names, ca_password)
     end
 
     it 'handles RMT::SSL::Exception exceptions' do
       expect(RMT::SSL::ConfigGenerator).to 
receive(:new).and_raise(RMT::SSL::Exception.new('Dummy error'))
       expect(Yast::Report).to receive(:Error).with("An error occurred during 
SSL certificate generation:\nDummy error\n")
-      generator.generate(common_name, alt_names)
+      generator.generate(common_name, alt_names, ca_password)
     end
   end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/ssl/current_ca_password_dialog_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/ssl/current_ca_password_dialog_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/ssl/current_ca_password_dialog_spec.rb 
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/spec/rmt/ssl/current_ca_password_dialog_spec.rb 
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,40 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/shared/input_password_dialog'
+require 'rmt/ssl/current_ca_password_dialog'
+
+Yast.import 'Report'
+
+describe RMT::SSL::CurrentCaPasswordDialog do
+  subject(:dialog) { described_class.new }
+
+  describe '#password_valid?' do
+    let(:password) { 'foobar' }
+
+    it 'returns true when password is valid' do
+      expect_any_instance_of(RMT::SSL::CertificateGenerator).to 
receive(:valid_password?).with(password).and_return(true)
+      expect(dialog.send(:password_valid?, password)).to be(true)
+    end
+
+    it 'returns false when exit code is not 0' do
+      expect_any_instance_of(RMT::SSL::CertificateGenerator).to 
receive(:valid_password?).with(password).and_return(false)
+      expect(dialog.send(:password_valid?, password)).to be(false)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/ssl/new_ca_password_dialog_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/ssl/new_ca_password_dialog_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/ssl/new_ca_password_dialog_spec.rb     
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/spec/rmt/ssl/new_ca_password_dialog_spec.rb     
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,34 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/ssl/new_ca_password_dialog'
+
+Yast.import 'Report'
+
+describe RMT::SSL::NewCaPasswordDialog do
+  subject(:dialog) { described_class.new }
+
+  describe '#initialize' do
+    it 'creates the UI elements' do
+      expect(dialog.instance_variable_get(:@dialog_heading)).to eq('Setting CA 
private key password')
+      expect(dialog.instance_variable_get(:@dialog_label)).to eq('Please set 
new CA private key password')
+      expect(dialog.instance_variable_get(:@password_field_label)).to eq('New 
CA private key &Password')
+      
expect(dialog.instance_variable_get(:@password_confirmation_field_label)).to 
eq('New Password &Again')
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/spec/rmt/wizard_rmt_service_page_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/wizard_rmt_service_page_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/wizard_rmt_service_page_spec.rb        
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/spec/rmt/wizard_rmt_service_page_spec.rb        
2018-06-27 16:36:27.000000000 +0200
@@ -66,28 +66,50 @@
   end
 
   describe '#run' do
-    context 'when service restart failed' do
-      it 'shows an error and continues' do
-        expect(service_page).to receive(:render_content)
-        expect(service_page).to receive(:rmt_service_start).and_return(false)
-        expect(Yast::Report).to receive(:Error).with("Failed to enable and 
restart service 'rmt-server'")
-        expect(Yast::Popup).to receive(:Feedback).and_call_original
-        expect(service_page).to receive(:event_loop)
-        service_page.run
+    context 'successful run' do
+      context 'restarting succeeds' do
+        it 'reloads and restarts the services and continues' do
+          expect(service_page).to receive(:render_content)
+          expect(Yast::Popup).to receive(:Feedback).and_call_original
+          expect(service_page).to receive(:rmt_service_start).and_return(true)
+          expect(Yast::Popup).to receive(:Feedback).and_call_original
+          expect(service_page).to 
receive(:nginx_service_reload).and_return(true)
+          expect(service_page).to receive(:event_loop)
+          service_page.run
+        end
       end
     end
 
-    context 'when service restart succeeded' do
-      it 'restarts rmt service and enters event loop' do
-        expect(service_page).to receive(:render_content)
-        expect(service_page).to receive(:rmt_service_start).and_return(true)
-        expect(Yast::Popup).to receive(:Feedback).and_call_original
-        expect(service_page).to receive(:event_loop)
-        service_page.run
+    context 'unsuccessful run' do
+      context 'restarting fails' do
+        it 'shows an error and continues' do
+          expect(service_page).to receive(:render_content)
+          expect(service_page).to receive(:rmt_service_start).and_return(false)
+          expect(Yast::Report).to receive(:Error).with('Failed to enable and 
restart RMT services and timers')
+          expect(service_page).to 
receive(:nginx_service_reload).and_return(false)
+          expect(Yast::Report).to receive(:Error).with("Failed to reload 
service for 'nginx'")
+          expect(service_page).to receive(:event_loop)
+          service_page.run
+        end
       end
     end
   end
 
+  describe '#nginx_service_reload' do
+    context 'succeeds to reload' do
+      it 'returns true' do
+        expect(Yast::Service).to 
receive(:Reload).with('nginx').and_return(true)
+        service_page.nginx_service_reload
+      end
+    end
+
+    context 'fails to reload' do
+      it 'returns false' do
+        expect(Yast::Service).to 
receive(:Reload).with('nginx').and_return(false)
+        service_page.nginx_service_reload
+      end
+    end
+  end
   describe '#rmt_service_start' do
     context 'when restarting the service succeeds' do
       it 'shows confirmation' do
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-rmt-1.0.0/spec/rmt/wizard_ssl_page_spec.rb 
new/yast2-rmt-1.0.1/spec/rmt/wizard_ssl_page_spec.rb
--- old/yast2-rmt-1.0.0/spec/rmt/wizard_ssl_page_spec.rb        2018-05-18 
13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/spec/rmt/wizard_ssl_page_spec.rb        2018-06-27 
16:36:27.000000000 +0200
@@ -31,7 +31,7 @@
   let(:alt_names) { %w[rmt-main.example.com rmt-01.example.com] }
 
   before do
-    expect(RMT::SSL::CertificateGenerator).to 
receive(:new).and_return(generator_double)
+    allow(RMT::SSL::CertificateGenerator).to 
receive(:new).and_return(generator_double)
   end
 
   describe '#render_content' do
@@ -61,15 +61,72 @@
   describe '#next_handler' do
     let(:common_name) { 'rmt.example.com' }
     let(:alt_names_items) { alt_names.map { |i| Yast::Term.new(:Item, i, i) } }
+    let(:current_ca_password_dialog_double) { 
instance_double(RMT::SSL::CurrentCaPasswordDialog) }
+    let(:new_ca_password_dialog_double) { 
instance_double(RMT::SSL::NewCaPasswordDialog) }
+    let(:ca_password) { 'foobar' }
+
+    context 'with ca present' do
+      context 'with ca encrypted' do
+        it 'generates the certificates when next button is clicked' do
+          expect(Yast::UI).to receive(:QueryWidget).with(Id(:common_name), 
:Value).and_return(common_name)
+          expect(Yast::UI).to 
receive(:QueryWidget).with(Id(:alt_common_names), 
:Items).and_return(alt_names_items)
+          expect(generator_double).to receive(:ca_present?).and_return(true)
+          allow(generator_double).to receive(:ca_encrypted?).and_return(true)
+
+          expect(RMT::SSL::CurrentCaPasswordDialog).to 
receive(:new).and_return(current_ca_password_dialog_double)
+          expect(current_ca_password_dialog_double).to 
receive(:run).and_return(ca_password)
+          expect(generator_double).to receive(:generate).with(common_name, 
alt_names, ca_password)
+
+          expect(ssl_page).to receive(:finish_dialog).with(:next)
+          ssl_page.next_handler
+        end
+      end
 
-    it 'generates the certificates when next button is clicked' do
-      expect(Yast::UI).to receive(:QueryWidget).with(Id(:common_name), 
:Value).and_return(common_name)
-      expect(Yast::UI).to receive(:QueryWidget).with(Id(:alt_common_names), 
:Items).and_return(alt_names_items)
+      context 'with ca unencrypted' do
+        it 'generates the certificates when next button is clicked' do
+          expect(Yast::UI).to receive(:QueryWidget).with(Id(:common_name), 
:Value).and_return(common_name)
+          expect(Yast::UI).to 
receive(:QueryWidget).with(Id(:alt_common_names), 
:Items).and_return(alt_names_items)
+          expect(generator_double).to receive(:ca_present?).and_return(true)
+          allow(generator_double).to receive(:ca_encrypted?).and_return(false)
+
+          expect(RMT::SSL::CurrentCaPasswordDialog).not_to receive(:new)
+          expect(generator_double).to receive(:generate).with(common_name, 
alt_names, '')
+
+          expect(ssl_page).to receive(:finish_dialog).with(:next)
+          ssl_page.next_handler
+        end
+      end
+    end
 
-      expect(generator_double).to receive(:generate).with(common_name, 
alt_names)
+    context 'with ca empty' do
+      it 'generates the certificates when next button is clicked' do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:common_name), 
:Value).and_return(common_name)
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:alt_common_names), 
:Items).and_return(alt_names_items)
+
+        expect(generator_double).to receive(:ca_present?).and_return(false)
+        expect(RMT::SSL::NewCaPasswordDialog).to 
receive(:new).and_return(new_ca_password_dialog_double)
+        expect(new_ca_password_dialog_double).to 
receive(:run).and_return(ca_password)
+        expect(generator_double).to receive(:generate)
 
-      expect(ssl_page).to receive(:finish_dialog).with(:next)
-      ssl_page.next_handler
+        expect(ssl_page).to receive(:finish_dialog).with(:next)
+        ssl_page.next_handler
+      end
+    end
+
+    context 'with no ca password' do
+      it 'does not generate certificate when ca_password is not provided' do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:common_name), 
:Value).and_return(common_name)
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:alt_common_names), 
:Items).and_return(alt_names_items)
+
+        expect(generator_double).to receive(:ca_present?).and_return(false)
+        expect(RMT::SSL::NewCaPasswordDialog).to 
receive(:new).and_return(new_ca_password_dialog_double)
+        expect(new_ca_password_dialog_double).to receive(:run).and_return(nil)
+        expect(generator_double).not_to receive(:generate)
+        expect(Yast::Popup).to receive(:Error).with('CA password not provided, 
skipping SSL keys generation.')
+
+        expect(ssl_page).to receive(:finish_dialog).with(:next)
+        ssl_page.next_handler
+      end
     end
   end
 
@@ -115,12 +172,29 @@
   end
 
   describe '#run' do
-    context 'when certificates are already present' do
-      it 'shows a message and finishes' do
-        expect(generator_double).to 
receive(:server_cert_present?).and_return(true)
-        expect(Yast::Popup).to receive(:Message).with('SSL certificates 
already present, skipping generation.')
-        expect(ssl_page).to receive(:finish_dialog).with(:next)
-        ssl_page.run
+    context 'when server certificate is already present' do
+      context 'with encrypted' do
+        it 'shows proper error message' do
+          expect(generator_double).to 
receive(:server_cert_present?).and_return(true)
+          expect(generator_double).to receive(:ca_encrypted?).and_return(true)
+          expect(Yast::Popup).to receive(:Message).with(
+            'SSL certificates already present, skipping generation.'
+          )
+          expect(ssl_page).to receive(:finish_dialog).with(:next)
+          ssl_page.run
+        end
+      end
+
+      context 'with non-encrypted' do
+        it 'shows a message and finishes' do
+          expect(generator_double).to 
receive(:server_cert_present?).and_return(true)
+          expect(generator_double).to receive(:ca_encrypted?).and_return(false)
+          expect(Yast::Popup).to receive(:Message).with(
+            "SSL certificates already present, skipping generation.\nPlease 
consider encrypting your CA private key!"
+          )
+          expect(ssl_page).to receive(:finish_dialog).with(:next)
+          ssl_page.run
+        end
       end
     end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/maria_db/current_root_password_dialog.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/maria_db/current_root_password_dialog.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/maria_db/current_root_password_dialog.rb    
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/src/lib/rmt/maria_db/current_root_password_dialog.rb    
2018-06-27 16:36:27.000000000 +0200
@@ -17,61 +17,24 @@
 #  you may find current contact information at www.suse.com
 
 require 'rmt/utils'
+require 'rmt/shared/input_password_dialog'
 require 'ui/dialog'
 
 module RMT; end
 module RMT::MariaDB; end
 
-class RMT::MariaDB::CurrentRootPasswordDialog < UI::Dialog
+class RMT::MariaDB::CurrentRootPasswordDialog < 
RMT::Shared::InputPasswordDialog
   def initialize
-    textdomain 'rmt'
-  end
-
-  def dialog_content
-    VBox(
-      VSpacing(1),
-      Heading(_('Database root password is required')),
-      VSpacing(1),
-      HBox(
-        HSpacing(2),
-        VBox(
-          Label(_('Please provide the current database root password.')),
-          MinWidth(15, Password(Id(:root_password), _('MariaDB root 
&password')))
-        ),
-        HSpacing(2)
-      ),
-      VSpacing(1),
-      HBox(
-        PushButton(Id(:cancel), Opt(:key_F9), Yast::Label.CancelButton),
-        HSpacing(2),
-        PushButton(Id(:ok), Opt(:default, :key_F10), Yast::Label.OKButton)
-      ),
-      VSpacing(1)
-    )
-  end
-
-  def user_input
-    Yast::UI.SetFocus(Id(:root_password))
     super
-  end
-
-  def ok_handler
-    root_password = Yast::UI.QueryWidget(Id(:root_password), :Value)
 
-    if !root_password || root_password.empty?
-      Yast::UI.SetFocus(Id(:root_password))
-      Yast::Report.Error(_('Please provide the root password.'))
-      return
-    elsif !root_password_valid?(root_password)
-      Yast::UI.SetFocus(Id(:root_password))
-      Yast::Report.Error(_('The provided password is not valid.'))
-      return
-    end
-
-    finish_dialog(root_password)
+    @dialog_heading = 'Database root password is required'
+    @dialog_label = 'Please provide the current database root password.'
+    @password_field_label = 'MariaDB root &password'
   end
 
-  def root_password_valid?(password)
+  private
+
+  def password_valid?(password)
     RMT::Utils.run_command(
       "echo 'show databases;' | mysql -u root -p%1 2>/dev/null",
       password
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/maria_db/new_root_password_dialog.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/maria_db/new_root_password_dialog.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/maria_db/new_root_password_dialog.rb        
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/src/lib/rmt/maria_db/new_root_password_dialog.rb        
2018-06-27 16:36:27.000000000 +0200
@@ -17,66 +17,21 @@
 #  you may find current contact information at www.suse.com
 
 require 'rmt/utils'
+require 'rmt/shared/set_password_dialog'
 require 'ui/dialog'
 
 module RMT; end
 module RMT::MariaDB; end
 
-class RMT::MariaDB::NewRootPasswordDialog < UI::Dialog
+class RMT::MariaDB::NewRootPasswordDialog < RMT::Shared::SetPasswordDialog
   def initialize
-    textdomain 'rmt'
-  end
-
-  def dialog_content
-    VBox(
-      VSpacing(1),
-      Heading(_('Setting database root password')),
-      VSpacing(1),
-      HBox(
-        HSpacing(2),
-        VBox(
-          Label(
-            _(
-              "The current MariaDB root password is empty.\n" \
-                    'Setting a root password is required for security reasons.'
-            )
-          ),
-          VSpacing(1),
-          MinWidth(15, Password(Id(:new_root_password_1), _('New MariaDB root 
&Password'))),
-          MinWidth(15, Password(Id(:new_root_password_2), _('New Password 
&Again')))
-        ),
-        HSpacing(2)
-      ),
-      VSpacing(1),
-      HBox(
-        PushButton(Id(:cancel), Opt(:key_F9), Yast::Label.CancelButton),
-        HSpacing(2),
-        PushButton(Id(:ok), Opt(:default, :key_F10), Yast::Label.OKButton)
-      ),
-      VSpacing(1)
-    )
-  end
-
-  def user_input
-    Yast::UI.SetFocus(Id(:new_root_password_1))
     super
-  end
-
-  def ok_handler
-    pass1 = Yast::UI.QueryWidget(Id(:new_root_password_1), :Value)
-    pass2 = Yast::UI.QueryWidget(Id(:new_root_password_2), :Value)
 
-    if pass1.nil? || pass1 == ''
-      Yast::UI.SetFocus(Id(:new_root_password_1))
-      Yast::Report.Error(_('Password must not be blank.'))
-      return
-    elsif pass1 != pass2
-      Yast::UI.SetFocus(Id(:new_root_password_2))
-      Yast::Report.Error(_('The first and the second passwords do not match.'))
-      return
-    end
-
-    finish_dialog(pass1)
+    @dialog_heading = 'Setting database root password'
+    @dialog_label = "The current MariaDB root password is empty.\n" \
+                    'Setting a root password is required for security reasons.'
+    @password_field_label = 'New MariaDB root &Password'
+    @password_confirmation_field_label = 'New Password &Again'
   end
 
   def set_root_password(new_root_password, hostname)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/shared/input_password_dialog.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/shared/input_password_dialog.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/shared/input_password_dialog.rb     
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/src/lib/rmt/shared/input_password_dialog.rb     
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/utils'
+require 'ui/dialog'
+
+module RMT; end
+module RMT::Shared; end
+
+class RMT::Shared::InputPasswordDialog < UI::Dialog
+  def initialize
+    textdomain 'rmt'
+  end
+
+  def user_input
+    Yast::UI.SetFocus(Id(:password))
+    super
+  end
+
+  def ok_handler
+    password = Yast::UI.QueryWidget(Id(:password), :Value)
+
+    if !password || password.empty?
+      Yast::UI.SetFocus(Id(:password))
+      Yast::Report.Error(_('Please provide the password.'))
+      return
+    elsif !password_valid?(password)
+      Yast::UI.SetFocus(Id(:password))
+      Yast::Report.Error(_('The provided password is not valid.'))
+      return
+    end
+
+    finish_dialog(password)
+  end
+
+  private
+
+  def dialog_content
+    VBox(
+      VSpacing(1),
+      Heading(_(@dialog_heading)),
+      VSpacing(1),
+      HBox(
+        HSpacing(2),
+        VBox(
+          Label(_(@dialog_label)),
+          VSpacing(1),
+          MinWidth(15, Password(Id(:password), _(@password_field_label)))
+        ),
+        HSpacing(2)
+      ),
+      VSpacing(1),
+      HBox(
+        PushButton(Id(:cancel), Opt(:key_F9), Yast::Label.CancelButton),
+        HSpacing(2),
+        PushButton(Id(:ok), Opt(:default, :key_F10), Yast::Label.OKButton)
+      ),
+      VSpacing(1)
+    )
+  end
+
+  def password_valid?(_password)
+    raise NotImplementedError
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/shared/set_password_dialog.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/shared/set_password_dialog.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/shared/set_password_dialog.rb       
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/src/lib/rmt/shared/set_password_dialog.rb       
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,87 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/utils'
+require 'ui/dialog'
+
+module RMT; end
+module RMT::Shared; end
+
+class RMT::Shared::SetPasswordDialog < UI::Dialog
+  def initialize
+    @min_password_size = 0
+    textdomain 'rmt'
+  end
+
+  def user_input
+    Yast::UI.SetFocus(Id(:password))
+    super
+  end
+
+  def ok_handler
+    password = Yast::UI.QueryWidget(Id(:password), :Value)
+    password_confirmation = Yast::UI.QueryWidget(Id(:password_confirmation), 
:Value)
+
+    if password.nil? || password == ''
+      Yast::UI.SetFocus(Id(:password))
+      Yast::Report.Error(_('Password must not be blank.'))
+      return
+    elsif password.size < @min_password_size
+      Yast::UI.SetFocus(Id(:password))
+      Yast::Report.Error("Password has to have at least #{@min_password_size} 
characters.")
+      return
+    elsif password != password_confirmation
+      Yast::UI.SetFocus(Id(:password_confirmation))
+      Yast::Report.Error(_('The first and the second passwords do not match.'))
+      return
+    end
+
+    finish_dialog(password)
+  end
+
+  private
+
+  def dialog_content
+    VBox(
+      VSpacing(1),
+      Heading(_(@dialog_heading)),
+      VSpacing(1),
+      HBox(
+        HSpacing(2),
+        VBox(
+          Label(
+            _(
+              @dialog_label
+            )
+          ),
+          VSpacing(1),
+          MinWidth(15, Password(Id(:password), _(@password_field_label))),
+          MinWidth(15, Password(Id(:password_confirmation), 
_(@password_confirmation_field_label)))
+        ),
+        HSpacing(2)
+      ),
+      VSpacing(1),
+      HBox(
+        PushButton(Id(:cancel), Opt(:key_F9), Yast::Label.CancelButton),
+        HSpacing(2),
+        PushButton(Id(:ok), Opt(:default, :key_F10), Yast::Label.OKButton)
+      ),
+      VSpacing(1)
+    )
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/ssl/certificate_generator.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/ssl/certificate_generator.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/ssl/certificate_generator.rb        
2018-05-18 13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/src/lib/rmt/ssl/certificate_generator.rb        
2018-06-27 16:36:27.000000000 +0200
@@ -58,6 +58,20 @@
     false
   end
 
+  def ca_encrypted?
+    !valid_password?(' ') # check with emtpy password. password has one char 
otherwise command requires input
+  end
+
+  def valid_password?(password)
+    RMT::Execute.on_target!(
+      'openssl', 'rsa', '-passin', 'stdin', '-in', @ssl_paths[:ca_private_key],
+      stdin: password
+    )
+    true
+  rescue Cheetah::ExecutionFailed
+    false
+  end
+
   def server_cert_present?
     # NB this doesn't check the second file if the first one exists
     # An improvement would be to look for the absence of any ssl configuration 
and proceed in that case,
@@ -68,7 +82,8 @@
     false
   end
 
-  def generate(common_name, alt_names)
+  # rubocop:disable Metrics/MethodLength
+  def generate(common_name, alt_names, ca_password)
     config_generator = RMT::SSL::ConfigGenerator.new(common_name, alt_names)
 
     files = @ssl_paths.dup
@@ -77,16 +92,19 @@
     create_files(files)
 
     Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:server_config], 
config_generator.make_server_config)
-
     unless ca_present?
       Yast::SCR.Write(Yast.path('.target.string'), 
@ssl_paths[:ca_serial_file], '01')
       Yast::SCR.Write(Yast.path('.target.string'), @ssl_paths[:ca_config], 
config_generator.make_ca_config)
 
-      RMT::Execute.on_target!('openssl', 'genrsa', '-out', 
@ssl_paths[:ca_private_key], OPENSSL_KEY_BITS)
+      RMT::Execute.on_target!(
+        'openssl', 'genrsa', '-aes256', '-passout', 'stdin', '-out', 
@ssl_paths[:ca_private_key], OPENSSL_KEY_BITS,
+        stdin: ca_password
+      )
       RMT::Execute.on_target!(
         'openssl', 'req', '-x509', '-new', '-nodes', '-key', 
@ssl_paths[:ca_private_key],
         '-sha256', '-days', OPENSSL_CA_VALIDITY_DAYS, '-out', 
@ssl_paths[:ca_certificate],
-        '-config', @ssl_paths[:ca_config]
+        '-passin', 'stdin', '-config', @ssl_paths[:ca_config],
+        stdin: ca_password
       )
     end
 
@@ -96,13 +114,22 @@
       '-out', @ssl_paths[:server_csr], '-config', @ssl_paths[:server_config]
     )
 
-    RMT::Execute.on_target!(
-      'openssl', 'x509', '-req', '-in', @ssl_paths[:server_csr], '-out', 
@ssl_paths[:server_certificate],
-      '-CA', @ssl_paths[:ca_certificate], '-CAkey', 
@ssl_paths[:ca_private_key],
-      '-days', OPENSSL_SERVER_CERT_VALIDITY_DAYS, '-sha256',
-      '-CAcreateserial',
-      '-extensions', 'v3_server_sign', '-extfile', @ssl_paths[:server_config]
-    )
+    if !ca_password.empty?
+      RMT::Execute.on_target!(
+        'openssl', 'x509', '-req', '-in', @ssl_paths[:server_csr], '-out', 
@ssl_paths[:server_certificate],
+        '-CA', @ssl_paths[:ca_certificate], '-CAkey', 
@ssl_paths[:ca_private_key],
+        '-passin', 'stdin', '-days', OPENSSL_SERVER_CERT_VALIDITY_DAYS, 
'-sha256',
+        '-CAcreateserial', '-extensions', 'v3_server_sign', '-extfile', 
@ssl_paths[:server_config],
+        stdin: ca_password
+      )
+    else
+      RMT::Execute.on_target!(
+        'openssl', 'x509', '-req', '-in', @ssl_paths[:server_csr], '-out', 
@ssl_paths[:server_certificate],
+        '-CA', @ssl_paths[:ca_certificate], '-CAkey', 
@ssl_paths[:ca_private_key],
+        '-days', OPENSSL_SERVER_CERT_VALIDITY_DAYS, '-sha256',
+        '-CAcreateserial', '-extensions', 'v3_server_sign', '-extfile', 
@ssl_paths[:server_config]
+      )
+    end
 
     # create certificates bundle
     server_cert = Yast::SCR.Read(Yast.path('.target.string'), 
@ssl_paths[:server_certificate])
@@ -120,6 +147,7 @@
       }
     )
   end
+  # rubocop:enable Metrics/MethodLength
 
   protected
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/ssl/current_ca_password_dialog.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/ssl/current_ca_password_dialog.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/ssl/current_ca_password_dialog.rb   
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/src/lib/rmt/ssl/current_ca_password_dialog.rb   
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,42 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/utils'
+require 'rmt/ssl/certificate_generator'
+require 'rmt/shared/input_password_dialog'
+require 'ui/dialog'
+
+module RMT; end
+module RMT::SSL; end
+
+class RMT::SSL::CurrentCaPasswordDialog < RMT::Shared::InputPasswordDialog
+  def initialize
+    super
+
+    @dialog_heading = 'Your CA private key is encrypted.'
+    @dialog_label = 'Please input password.'
+    @password_field_label = '&Password'
+    @cert_generator = RMT::SSL::CertificateGenerator.new
+  end
+
+  private
+
+  def password_valid?(password)
+    @cert_generator.valid_password?(password)
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/ssl/new_ca_password_dialog.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/ssl/new_ca_password_dialog.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/ssl/new_ca_password_dialog.rb       
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-rmt-1.0.1/src/lib/rmt/ssl/new_ca_password_dialog.rb       
2018-06-27 16:36:27.000000000 +0200
@@ -0,0 +1,36 @@
+# Copyright (c) 2018 SUSE LLC.
+#  All Rights Reserved.
+
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of version 2 or 3 of the GNU General
+#  Public License as published by the Free Software Foundation.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, contact SUSE LLC.
+
+#  To contact SUSE about this file by physical or electronic mail,
+#  you may find current contact information at www.suse.com
+
+require 'rmt/utils'
+require 'rmt/shared/set_password_dialog'
+require 'ui/dialog'
+
+module RMT; end
+module RMT::SSL; end
+
+class RMT::SSL::NewCaPasswordDialog < RMT::Shared::SetPasswordDialog
+  def initialize
+    super
+
+    @dialog_heading = 'Setting CA private key password'
+    @dialog_label = 'Please set new CA private key password'
+    @password_field_label = 'New CA private key &Password'
+    @password_confirmation_field_label = 'New Password &Again'
+    @min_password_size = 4
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-rmt-1.0.0/src/lib/rmt/wizard_rmt_service_page.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/wizard_rmt_service_page.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/wizard_rmt_service_page.rb  2018-05-18 
13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/src/lib/rmt/wizard_rmt_service_page.rb  2018-06-27 
16:36:27.000000000 +0200
@@ -69,17 +69,33 @@
 
   def run
     render_content
-    ok = false
-    Yast::Popup.Feedback(_('Starting services'), _('Starting RMT server, sync, 
and mirror timers...')) do
-      ok = rmt_service_start
+    rmt_services_started = false
+    nginx_service_reloaded = false
+
+    Yast::Popup.Feedback(_('Starting RMT'), _('Starting RMT server, sync, and 
mirror timers ...')) do
+      rmt_services_started = rmt_service_start
+    end
+    unless rmt_services_started
+      UI.ChangeWidget(Id(:service_status), :Value, 'Could not start RMT 
services and timers.')
+      Yast::Report.Error(_('Failed to enable and restart RMT services and 
timers'))
+    end
+
+    Yast::Popup.Feedback(_('Reloading nginx'), _('Reloading the nginx service 
...')) do
+      nginx_service_reloaded = nginx_service_reload
     end
-    unless ok
-      UI.ChangeWidget(Id(:service_status), :Value, 'Could not start 
\'rmt-server\' service.')
-      Yast::Report.Error(_("Failed to enable and restart service 
'rmt-server'"))
+    unless nginx_service_reloaded
+      UI.ChangeWidget(Id(:service_status), :Value, 'Could not reload \'nginx\' 
service.')
+      Yast::Report.Error(_('Failed to reload service for \'nginx\''))
     end
+
     event_loop
   end
 
+  def nginx_service_reload
+    return true if Yast::Service.Reload('nginx')
+    false
+  end
+
   def rmt_service_start
     if Yast::Service.Enable('rmt-server') && 
Yast::Service.Restart('rmt-server')
       rmt_enable_timers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-rmt-1.0.0/src/lib/rmt/wizard_ssl_page.rb 
new/yast2-rmt-1.0.1/src/lib/rmt/wizard_ssl_page.rb
--- old/yast2-rmt-1.0.0/src/lib/rmt/wizard_ssl_page.rb  2018-05-18 
13:57:35.000000000 +0200
+++ new/yast2-rmt-1.0.1/src/lib/rmt/wizard_ssl_page.rb  2018-06-27 
16:36:27.000000000 +0200
@@ -17,6 +17,8 @@
 #  you may find current contact information at www.suse.com
 
 require 'rmt/ssl/alternative_common_name_dialog'
+require 'rmt/ssl/current_ca_password_dialog'
+require 'rmt/ssl/new_ca_password_dialog'
 require 'rmt/ssl/config_generator'
 require 'rmt/ssl/certificate_generator'
 require 'rmt/execute'
@@ -87,7 +89,21 @@
     alt_names_items = UI.QueryWidget(Id(:alt_common_names), :Items)
     alt_names = alt_names_items.map { |item| item.params[1] }
 
-    @cert_generator.generate(common_name, alt_names)
+    ca_password = if @cert_generator.ca_present?
+                    if @cert_generator.ca_encrypted?
+                      RMT::SSL::CurrentCaPasswordDialog.new.run
+                    else
+                      '' # use empty password
+                    end
+                  else
+                    RMT::SSL::NewCaPasswordDialog.new.run
+                  end
+
+    if ca_password
+      @cert_generator.generate(common_name, alt_names, ca_password)
+    else
+      Report.Error(_('CA password not provided, skipping SSL keys 
generation.'))
+    end
 
     finish_dialog(:next)
   end
@@ -117,7 +133,13 @@
 
   def run
     if @cert_generator.server_cert_present?
-      Yast::Popup.Message(_('SSL certificates already present, skipping 
generation.'))
+      if @cert_generator.ca_encrypted?
+        Yast::Popup.Message(_('SSL certificates already present, skipping 
generation.'))
+      else
+        Yast::Popup.Message(_("SSL certificates already present, skipping 
generation.\n" \
+                              'Please consider encrypting your CA private 
key!'))
+      end
+
       return finish_dialog(:next)
     end
     render_content


Reply via email to