forked from Kicksecure/sdwdate
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
09ec978
commit 907cd7c
Showing
4 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
|
||
rm --force /var/run/sdwdate/first_success |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
#!/usr/bin/env ruby | ||
|
||
module SneakyClockAdjusterCLI | ||
require 'optparse' | ||
require 'ostruct' | ||
|
||
def self.parse args | ||
options = OpenStruct.new | ||
options.add_or_substract = :add | ||
options.amount = nil | ||
options.move_min = nil | ||
options.move_max = nil | ||
options.wait_min = nil | ||
options.wait_max = nil | ||
options.first_wait = false | ||
options.verbose = true | ||
options.debug = false | ||
options.systohc = false | ||
|
||
opt_parser = OptionParser.new do |opts| | ||
opts.banner = "" | ||
opts.separator "Specific options:" | ||
|
||
opts.on("--add num", Integer, "(Required) Nanoseconds to add") do |v| | ||
options.add_or_substract = :add | ||
options.amount = v | ||
end | ||
opts.on("--subtract num", Integer, "(Required) Nanoseconds to subtract") do |v| | ||
options.add_or_substract = :subtract | ||
options.amount = v | ||
end | ||
opts.on("--wait-min num", Integer, "(Required) Minimum random seconds to wait") do |v| | ||
options.wait_min = v | ||
end | ||
opts.on("--wait-max num", Integer, "(Required) Maximum random seconds to wait") do |v| | ||
options.wait_max = v | ||
end | ||
opts.on("--move-min num", Integer, "(Required) Minimum random nanoseconds to change") do |v| | ||
options.move_min = v | ||
end | ||
opts.on("--move-max num", Integer, "(Required) Maximum random nanoseconds to change") do |v| | ||
options.move_max = v | ||
end | ||
opts.on("--[no-]first-wait", "Wait before first change?") do |v| | ||
options.first_wait = v | ||
end | ||
opts.on("--[no-]verbose", "Run Verbosely?") do |v| | ||
options.verbose = v | ||
end | ||
opts.on("--[no-]debug", "Debug messages. Don't change date.") do |v| | ||
options.debug = v | ||
end | ||
opts.on("--[no-]systohc", "Update hardware clock.") do |v| | ||
options.systohc = v | ||
end | ||
opts.on_tail("-h", "--help", "Show this message") do | ||
puts opts | ||
exit | ||
end | ||
|
||
end | ||
|
||
opt_parser.parse! | ||
if options.amount == nil then puts opt_parser; exit 1 end | ||
if options.move_min == nil then puts opt_parser; exit 1 end | ||
if options.move_max == nil then puts opt_parser; exit 1 end | ||
if options.wait_min == nil then puts opt_parser; exit 1 end | ||
if options.wait_max == nil then puts opt_parser; exit 1 end | ||
if options.amount == nil then puts opt_parser; exit 1 end | ||
if options.amount <= 0 then raise OptionParser::InvalidArgument, "Input must be positive!" end | ||
if options.wait_min < 0 then raise OptionParser::InvalidArgument, "Input must be positive!" end | ||
if options.wait_max < options.wait_min then raise OptionParser::InvalidArgument, "Max must > min!" end | ||
if options.move_min < 0 then raise OptionParser::InvalidArgument, "Input must be positive!" end | ||
if options.move_max < options.move_min then raise OptionParser::InvalidArgument, "Max must > min!" end | ||
|
||
return options | ||
end # self.parse | ||
end # module SneakyClockAdjusterCLI | ||
|
||
module SneakyClockAdjuster | ||
require 'openssl' | ||
require 'securerandom' | ||
require 'bigdecimal' | ||
require 'bigdecimal/util' | ||
require 'inline' | ||
|
||
def self.execute add_or_substract, amount, move_min, move_max, wait_min, wait_max, first_wait = false, verbose = true, debug = false, systohc = false | ||
|
||
puts "Running with PID: #{Process.pid}" if verbose | ||
Kernel.trap("TERM") do | ||
puts "Exiting..." | ||
exit 143 | ||
end | ||
Kernel.trap("INT") do | ||
puts "Exiting..." | ||
exit 130 | ||
end | ||
|
||
jumps = make_jumps amount, move_min, move_max | ||
jumps_c = jumps.count | ||
intervals = make_intervals jumps_c, wait_min, wait_max | ||
if not first_wait then intervals[0] = 0 end | ||
if debug | ||
puts "DEBUG: Using these sleep intervals: #{intervals}" | ||
puts "DEBUG: with these time jumps: #{jumps}" | ||
end | ||
|
||
c = Cinline.new | ||
|
||
jumps.each_index do |index| | ||
|
||
if verbose | ||
puts "---" | ||
puts "Iteration: #{index+1} of #{jumps_c}" | ||
end | ||
|
||
wait_ns = intervals[index] | ||
wait_s = wait_ns.to_f / 1000000000 | ||
jump_ns = jumps[index] | ||
jump_s = jump_ns.to_f / 1000000000 | ||
|
||
if wait_ns > 0 then | ||
puts "Waiting #{wait_ns} nanoseconds [#{wait_s} seconds]" if verbose | ||
sleep(wait_s) | ||
end | ||
|
||
if verbose | ||
print "Aproximate system date with nanoseconds: " | ||
puts %x[echo "$(date) | $(date +%N)"] | ||
end | ||
|
||
if add_or_substract == :add then | ||
puts "Adding #{jump_ns} nanoseconds [#{jump_s} seconds]" if verbose | ||
else | ||
puts "Subtracting #{jump_ns} nanoseconds [#{jump_s} seconds]" if verbose | ||
jump_ns = -jump_ns | ||
end | ||
|
||
if not debug | ||
c_return_code = c.getAndSet(jump_ns) | ||
puts "c_return_code: #{c_return_code}" if verbose | ||
if c_return_code != 0 then | ||
warn "ERROR: c_return_code was: #{c_return_code}" | ||
exit c_return_code | ||
end | ||
end | ||
|
||
if systohc then | ||
cmd = "hwclock --systohc" | ||
puts "Set hwclock with: #{cmd}" if verbose | ||
system cmd unless debug | ||
end | ||
|
||
if verbose | ||
print "Aproximate system date with nanoseconds: " | ||
puts %x[echo "$(date) | $(date +%N)"] | ||
end | ||
|
||
end # jumps.each_index | ||
|
||
if verbose | ||
puts "---" | ||
puts "Done! Exiting..." | ||
end | ||
end | ||
|
||
def self.make_intervals count, min, max, intervals = [] | ||
count.times do | ||
intervals << (SecureRandom.random_number max-min+1) + min | ||
end | ||
return intervals | ||
end | ||
|
||
def self.make_jumps amount, min, max, jumps = [] | ||
loop do | ||
if amount < 1 then return jumps end | ||
if amount < min then return jumps << amount end | ||
|
||
if amount - max < 1 then max = amount end | ||
random_jump = (SecureRandom.random_number max-min+1) + min | ||
jumps << random_jump | ||
amount -= random_jump | ||
end | ||
end | ||
end # module SneakyClockAdjuster | ||
|
||
class Cinline | ||
|
||
inline :C do |builder| | ||
builder.include '<stdio.h>' | ||
builder.include '<time.h>' | ||
builder.include '<sys/time.h>' | ||
builder.c ' | ||
int getAndSet(long long addNsec) { | ||
/* receive time adjustment, negative or positive, in nanoseconds */ | ||
/* get current time in seconds since epoch + nanoseconds offset */ | ||
struct timespec tps; /* tv_sec; tv_nsec */ | ||
if( clock_gettime(0, &tps) == -1 ) { | ||
perror( "getclock" ); | ||
return EXIT_FAILURE; | ||
} | ||
/* combine seconds and nanoseconds offset to manipulate */ | ||
long long nanosecondsSinceEpoch = | ||
(long long)(tps.tv_sec) * 1000000000 + /* convert seconds to nanoseconds */ | ||
(long long)(tps.tv_nsec); /* add offset */ | ||
long long newNanosecondsSinceEpoch = nanosecondsSinceEpoch += addNsec; | ||
/* separate adjusted nanoseconds since epoch into seconds + nanoseconds offset */ | ||
long newNS = newNanosecondsSinceEpoch % 1000000000; /* pulls out nanoseconds */ | ||
long newS = newNanosecondsSinceEpoch / 1000000000; /* truncates into seconds */ | ||
/* set struct with new values; set time */ | ||
tps.tv_sec = newS; /* reusing old struct */ | ||
tps.tv_nsec = newNS; | ||
if( clock_settime(0, &tps) == -1 ) { | ||
perror( "setclock" ); | ||
return EXIT_FAILURE; | ||
} | ||
return EXIT_SUCCESS; | ||
} | ||
' | ||
end | ||
|
||
end | ||
|
||
options = SneakyClockAdjusterCLI.parse(ARGV) | ||
SneakyClockAdjuster.execute options.add_or_substract, options.amount, options.move_min, options.move_max, options.wait_min, options.wait_max, options.first_wait, options.verbose, options.debug |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/bin/bash | ||
|
||
## This file is part of Whonix. | ||
## Copyright (C) 2012 - 2014 Patrick Schleizer <adrelanos@riseup.net> | ||
## See the file COPYING for copying conditions. | ||
|
||
set -x | ||
|
||
find /var/cache/sdwdate -printf "%p %u %g %m\n" | ||
true "\$?: $?" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#!/bin/bash | ||
|
||
## This file is part of Whonix. | ||
## Copyright (C) 2012 - 2014 Patrick Schleizer <adrelanos@riseup.net> | ||
## See the file COPYING for copying conditions. | ||
|
||
pid="$1" | ||
|
||
if [[ "$pid" != *[!0-9]* ]]; then | ||
true "pid '$pid' is strictly numeric." | ||
else | ||
echo "pid '$pid' is NOT strictly numeric!" | ||
exit 1 | ||
fi | ||
|
||
ps_output="$(ps h --format command "$pid")" | ||
|
||
## Example ps_output: | ||
## sudo INLINEDIR=/var/cache/sdwdate/sclockadj /usr/lib/sdwdate/sclockadj --no-verbose --no-debug --no-first-wait --move-min 500000 --move-max 500000 --wait-min 1000000000 --wait-max 1000000000 --add 172807620812 | ||
|
||
read -t 2 first second third _ <<< "$ps_output" | ||
|
||
## Example first: | ||
## sudo | ||
|
||
## Example third: | ||
## /usr/lib/sdwdate/sclockadj | ||
|
||
if [ "$first" = "sudo" ]; then | ||
if [ "$third" = "/usr/lib/sdwdate/sclockadj" ]; then | ||
echo "kill -sigterm $pid" | ||
kill -sigterm "$pid" | ||
exit 0 | ||
fi | ||
fi | ||
|
||
echo "Nothing killed. ps_output: $ps_output" | ||
exit 0 |