@@ -846,7 +846,7 @@ def test_sync_clock_chrony(self, mock_time_method, mock_execute):
846846 utils .sync_clock ()
847847 mock_execute .assert_has_calls ([
848848 mock .call ('chronyc' , 'shutdown' , check_exit_code = [0 , 1 ]),
849- mock .call (" chronyd -q 'server 192.168.1.1 iburst'" , shell = True ),
849+ mock .call (' chronyd' , '-q' , 'server 192.168.1.1 iburst' ),
850850 ])
851851
852852 @mock .patch .object (utils , 'determine_time_method' , autospec = True )
@@ -877,6 +877,126 @@ def test_sync_clock_ntp_server_is_none(self, mock_time_method,
877877 utils .sync_clock ()
878878 self .assertEqual (0 , mock_execute .call_count )
879879
880+ def test_sync_clock_invalid_ntp_server_shell_escape (
881+ self , mock_execute ):
882+ self .config (ntp_server = "'; rm -rf /; echo '" )
883+ self .assertRaisesRegex (
884+ errors .CommandExecutionError ,
885+ 'Invalid NTP server address' ,
886+ utils .sync_clock )
887+ mock_execute .assert_not_called ()
888+
889+ def test_sync_clock_invalid_ntp_server_command_sub (
890+ self , mock_execute ):
891+ self .config (ntp_server = '$(reboot)' )
892+ self .assertRaisesRegex (
893+ errors .CommandExecutionError ,
894+ 'Invalid NTP server address' ,
895+ utils .sync_clock )
896+ mock_execute .assert_not_called ()
897+
898+ def test_sync_clock_invalid_ntp_server_backtick (
899+ self , mock_execute ):
900+ self .config (ntp_server = '`reboot`' )
901+ self .assertRaisesRegex (
902+ errors .CommandExecutionError ,
903+ 'Invalid NTP server address' ,
904+ utils .sync_clock )
905+ mock_execute .assert_not_called ()
906+
907+ def test_sync_clock_invalid_ntp_server_pipe (
908+ self , mock_execute ):
909+ self .config (ntp_server = 'foo | bar' )
910+ self .assertRaisesRegex (
911+ errors .CommandExecutionError ,
912+ 'Invalid NTP server address' ,
913+ utils .sync_clock )
914+ mock_execute .assert_not_called ()
915+
916+ def test_sync_clock_invalid_ntp_server_chain (
917+ self , mock_execute ):
918+ self .config (ntp_server = 'foo && bar' )
919+ self .assertRaisesRegex (
920+ errors .CommandExecutionError ,
921+ 'Invalid NTP server address' ,
922+ utils .sync_clock )
923+ mock_execute .assert_not_called ()
924+
925+ def test_sync_clock_invalid_ntp_server_space (
926+ self , mock_execute ):
927+ self .config (ntp_server = 'foo bar' )
928+ self .assertRaisesRegex (
929+ errors .CommandExecutionError ,
930+ 'Invalid NTP server address' ,
931+ utils .sync_clock )
932+ mock_execute .assert_not_called ()
933+
934+ @mock .patch .object (utils , 'determine_time_method' , autospec = True )
935+ def test_sync_clock_valid_ipv6 (self , mock_time_method ,
936+ mock_execute ):
937+ self .config (ntp_server = '2001:db8::1' )
938+ mock_time_method .return_value = 'ntpdate'
939+ utils .sync_clock ()
940+ mock_execute .assert_has_calls (
941+ [mock .call ('ntpdate' , '2001:db8::1' )])
942+
943+ @mock .patch .object (utils , 'determine_time_method' , autospec = True )
944+ def test_sync_clock_valid_hostname (self , mock_time_method ,
945+ mock_execute ):
946+ self .config (ntp_server = 'ntp.example.com' )
947+ mock_time_method .return_value = 'ntpdate'
948+ utils .sync_clock ()
949+ mock_execute .assert_has_calls (
950+ [mock .call ('ntpdate' , 'ntp.example.com' )])
951+
952+ @mock .patch .object (utils , 'determine_time_method' , autospec = True )
953+ def test_sync_clock_valid_hostname_with_hyphens (
954+ self , mock_time_method , mock_execute ):
955+ self .config (ntp_server = 'my-ntp_server.example.com' )
956+ mock_time_method .return_value = 'ntpdate'
957+ utils .sync_clock ()
958+ mock_execute .assert_has_calls (
959+ [mock .call ('ntpdate' ,
960+ 'my-ntp_server.example.com' )])
961+
962+ def test_validate_ntp_server_valid_ipv4 (self , mock_execute ):
963+ utils ._validate_ntp_server ('192.168.1.1' )
964+
965+ def test_validate_ntp_server_valid_ipv6 (self , mock_execute ):
966+ utils ._validate_ntp_server ('2001:db8::1' )
967+
968+ def test_validate_ntp_server_valid_hostname (self ,
969+ mock_execute ):
970+ utils ._validate_ntp_server ('ntp.example.com' )
971+
972+ def test_validate_ntp_server_rejects_semicolon (
973+ self , mock_execute ):
974+ self .assertRaises (
975+ errors .CommandExecutionError ,
976+ utils ._validate_ntp_server ,
977+ "'; rm -rf /; echo '" )
978+
979+ def test_validate_ntp_server_rejects_dollar (self ,
980+ mock_execute ):
981+ self .assertRaises (
982+ errors .CommandExecutionError ,
983+ utils ._validate_ntp_server ,
984+ '$(reboot)' )
985+
986+ def test_validate_ntp_server_rejects_backtick (
987+ self , mock_execute ):
988+ self .assertRaises (
989+ errors .CommandExecutionError ,
990+ utils ._validate_ntp_server ,
991+ '`reboot`' )
992+
993+ def test_validate_ntp_server_rejects_space (self ,
994+ mock_execute ):
995+ self .assertRaises (
996+ errors .CommandExecutionError ,
997+ utils ._validate_ntp_server ,
998+ 'foo bar' )
999+
8801000
8811001@mock .patch .object (utils , '_unmount_any_config_drives' , autospec = True )
8821002@mock .patch .object (utils , '_booted_from_vmedia' , autospec = True )
0 commit comments