Project

General

Profile

« Previous | Next » 

Revision c7904e2c

Added by Marc Dequènes over 15 years ago

  • ID c7904e2c61b6eaa81c193b40bf87c9332410cf9a

[evol] replay protection #2 (should be done), and moved 'run' directory in the new workdir (temporary code until real path configuration)

View differences:

.gitignore
\#*#
config
log
run
var
lib/cyborghood/base.rb
include Singleton
CFG_DIR = './config/'
WORK_DIR = './var/lib/cyborghood/'
CONFFILE_GLOBAL = "cyborghood.conf"
CONFFILE_BOT = "cyborghood_%s.conf"
......
end
end
# temporary
def work_dir
WORK_DIR
end
private
def self.fetch_config(name = nil)
lib/cyborghood/mail.rb
require 'action_mailer/quoting'
require 'action_mailer/utils'
require 'net/smtp'
require 'fileutils'
require 'digest/md5'
# This class handles RFC3156 signed messages, validates them, and extract orders properly.
# Encrypted content are not implemented yet.
......
end
def parse
if is_marked?
logger.info "Replay detected"
return nil
end
return parse_signed() if is_pgp_signed?
return parse_encrypted() if is_pgp_encrypted?
{:ok => false, :msg => "mail not RFC3156 compliant"}.to_ostruct
......
drift = Time.new.to_i - sig_check.timestamp.to_i
logger.debug "Signature drift time: #{drift}"
if drift > 0 and drift < MAX_DRIFT_TIME
if drift.abs < MAX_DRIFT_TIME
signed_content = pgp_signed_part()
if signed_content.multipart?
if signed_content.parts[0].content_type == "text/plain"
......
end
logger.debug "Mail OK"
mark_processed(sig_check.timestamp)
order = {:ok => true, :user => user, :commands => commands, :refs => refs}
else
order[:user] = user
logger.info "Mail does not contain a proper MIME part for commands"
end
else
logger.info "Mail rejected as it may be a replay (signature timestamp is too old)"
order = {:ok => false, :user => user, :msg => "The signature was made too long ago (perhaps your system clock is not up-to-date). Rejected message to avoid replay attacks."}
if drift > 0
logger.info "Mail rejected as it may be a replay (signature timestamp is too old)"
order = {:ok => false, :user => user, :msg => "The signature was made too long ago (perhaps your system clock is not up-to-date). Rejected message to avoid replay attacks."}
else
# mark message to prevent later replay of the message
mark_processed(sig_check.timestamp)
logger.info "Mail rejected as it is coming from the future (and may allow later replay)"
order = {:ok => false, :user => user, :msg => "The signature was made in the future (perhaps your system clock is not up-to-date). Rejected message to avoid replay attacks."}
end
end
end
else
......
# create a fake mail and chain parsing operations
clear_mail = self.class.new(clear_message)
# propagate message_id to be able to mark messages (replay protection)
clear_mail.message_id = @mail.message_id
return clear_mail.parse
rescue GPGME::Error, NotImplementedError => e
raise CyberError.new(:unrecoverable, "protocol/mail", e.message)
......
order.to_ostruct
end
def mark_dir
File.join(@config.work_dir, "marks")
end
def mark_filename
File.join(mark_dir(), Digest::MD5.hexdigest(self.message_id))
end
def mark_processed(time)
FileUtils.mkdir_p(mark_dir())
File.open(mark_filename(), "w") do |fp|
fp.write self.message_id
end
File.utime(Time.now.to_i, time.to_i, mark_filename())
end
def is_marked?
File.exists?(mark_filename())
end
end
end
postman_daemon
options = {
:app_name => "CyborgHood_Postman",
:dir_mode => :normal,
:dir => "/opt/cyborghood/run",
:dir => "/opt/cyborghood/var/run",
:multiple => false,
:mode => :exec,
:monitor => true

Also available in: Unified diff