IPCd: file ordering.
parent
da683e96fa
commit
01fdb317c1
115
src/ipcd.cr
115
src/ipcd.cr
|
@ -1,21 +1,64 @@
|
||||||
|
require "option_parser"
|
||||||
require "baguette-crystal-base"
|
|
||||||
require "./rules"
|
|
||||||
require "./ipcd_cli_parser"
|
|
||||||
require "ipc"
|
require "ipc"
|
||||||
require "uri"
|
require "uri"
|
||||||
|
|
||||||
|
require "baguette-crystal-base"
|
||||||
|
|
||||||
|
require "./lib_modifications" # All standard library modifications.
|
||||||
|
require "./ipcd/*"
|
||||||
|
|
||||||
Baguette::Context.verbosity = 4
|
Baguette::Context.verbosity = 4
|
||||||
|
|
||||||
class IPCd::Service < IPC::Server
|
class Baguette::Configuration
|
||||||
|
class IPC < Base
|
||||||
|
property rules_directory : String = "/etc/baguette/ipcd/rules" # default
|
||||||
|
property redirections_directory : String = "/etc/baguette/ipcd/redirections" # default
|
||||||
|
|
||||||
|
property verbosity : Int32 = 2
|
||||||
|
property ipc_timer : Int32 = 30_000 # 30 seconds
|
||||||
|
|
||||||
|
property print_ipc_timer : Bool = false
|
||||||
|
property print_ipc_connection : Bool = false
|
||||||
|
property print_ipc_disconnection : Bool = false
|
||||||
|
property print_ipc_extra_socket : Bool = false
|
||||||
|
property print_ipc_message_received : Bool = false
|
||||||
|
property print_ipc_message_sent : Bool = false
|
||||||
|
property print_ipc_switch : Bool = false
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module IPCd
|
||||||
|
class Service < IPC::Server
|
||||||
|
|
||||||
@rules = RuleSet.new
|
@rules = RuleSet.new
|
||||||
@redirections = RedirectionSet.new
|
@redirections = RedirectionSet.new
|
||||||
|
|
||||||
def parse_cli (argv : Array(String))
|
def parse_cli (argv : Array(String))
|
||||||
IPCdCLIParser.parse_rules argv, @rules, @redirections
|
CLIParser.parse_rules argv, @rules, @redirections
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_rule_files(directory : String)
|
||||||
|
unless File.directory? directory
|
||||||
|
raise "not a valid directory: #{directory}"
|
||||||
|
end
|
||||||
|
Array(Rule).from_yaml_files(Dir.new(directory).entries).each do |r|
|
||||||
|
@rules << r
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_redirection_files(directory : String)
|
||||||
|
unless File.directory? directory
|
||||||
|
raise "not a valid directory: #{directory}"
|
||||||
|
end
|
||||||
|
Array(Redirection).from_yaml_files(Dir.new(directory).entries).each do |r|
|
||||||
|
@redirections << r
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def to_s(io : IO)
|
def to_s(io : IO)
|
||||||
io << "ipcd\n"
|
io << "ipcd\n"
|
||||||
io << @rules.to_s + "\n" + @redirections.to_s
|
io << @rules.to_s + "\n" + @redirections.to_s
|
||||||
|
@ -114,38 +157,59 @@ class IPCd::Service < IPC::Server
|
||||||
# finally, the service should be closed in ipcd
|
# finally, the service should be closed in ipcd
|
||||||
service.close
|
service.close
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
ipcd = IPCd::Service.new "network"
|
def main
|
||||||
|
|
||||||
# --deny <in|out> <service> <url>
|
simulation, no_configuration, configuration_file = Baguette::Configuration.option_parser
|
||||||
# --allow <in|ou> <service> <url>
|
|
||||||
# --redirect <service> <service>
|
|
||||||
# --redirect <service-name> <new-service-name> <origin-url> <dest-url>
|
|
||||||
|
|
||||||
ipcd.parse_cli ARGV
|
config = if no_configuration
|
||||||
Baguette::Log.debug ipcd.to_s
|
Baguette::Configuration::IPC.new
|
||||||
|
elsif c = Baguette::Configuration::IPC.get configuration_file
|
||||||
|
c
|
||||||
|
else
|
||||||
|
Baguette::Configuration::IPC.new
|
||||||
|
end
|
||||||
|
|
||||||
ipcd.base_timer = 30_000
|
ipcd = IPCd::Service.new "network"
|
||||||
ipcd.timer = 30_000
|
|
||||||
|
|
||||||
ipcd.loop do |event|
|
# --deny <in|out> <service> <url>
|
||||||
|
# --allow <in|ou> <service> <url>
|
||||||
|
# --redirect <service> <service>
|
||||||
|
# --redirect <service-name> <new-service-name> <origin-url> <dest-url>
|
||||||
|
|
||||||
|
ipcd.parse_cli ARGV
|
||||||
|
ipcd.parse_rule_files config.rules_directory
|
||||||
|
ipcd.parse_redirection_files config.redirections_directory
|
||||||
|
Baguette::Log.debug ipcd.to_s
|
||||||
|
|
||||||
|
ipcd.base_timer = config.ipc_timer
|
||||||
|
ipcd.timer = config.ipc_timer
|
||||||
|
|
||||||
|
if simulation
|
||||||
|
pp! config
|
||||||
|
ipcd.close
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
ipcd.loop do |event|
|
||||||
case event
|
case event
|
||||||
when IPC::Event::Connection
|
when IPC::Event::Connection
|
||||||
Baguette::Log.debug "Connection: fd #{event.fd}"
|
Baguette::Log.debug "Connection: fd #{event.fd}" if config.print_ipc_connection
|
||||||
|
|
||||||
when IPC::Event::Disconnection
|
when IPC::Event::Disconnection
|
||||||
Baguette::Log.debug "Disconnection: fd #{event.fd}"
|
Baguette::Log.debug "Disconnection: fd #{event.fd}" if config.print_ipc_disconnection
|
||||||
|
|
||||||
when IPC::Event::ExtraSocket
|
when IPC::Event::ExtraSocket
|
||||||
Baguette::Log.debug "Extrasocket: fd #{event.fd}"
|
Baguette::Log.debug "Extrasocket: fd #{event.fd}" if config.print_ipc_extra_socket
|
||||||
|
|
||||||
when IPC::Event::Switch
|
when IPC::Event::Switch
|
||||||
Baguette::Log.debug "Switch"
|
Baguette::Log.debug "Switch" if config.print_ipc_switch
|
||||||
|
|
||||||
when IPC::Event::MessageReceived
|
when IPC::Event::MessageReceived
|
||||||
Baguette::Log.debug "Message received: #{event.fd}"
|
Baguette::Log.debug "Message received: #{event.fd}" if config.print_ipc_message_received
|
||||||
Baguette::Log.debug event.message.to_s
|
Baguette::Log.debug event.message.to_s
|
||||||
begin
|
begin
|
||||||
ipcd.service_lookup event.message, event.fd
|
ipcd.service_lookup event.message, event.fd
|
||||||
|
@ -161,14 +225,17 @@ ipcd.loop do |event|
|
||||||
end
|
end
|
||||||
|
|
||||||
when IPC::Event::MessageSent
|
when IPC::Event::MessageSent
|
||||||
Baguette::Log.debug "Message sent: #{event.fd}"
|
Baguette::Log.debug "Message sent: #{event.fd}" if config.print_ipc_message_sent
|
||||||
|
|
||||||
when IPC::Event::Timer
|
when IPC::Event::Timer
|
||||||
Baguette::Log.debug "Timer"
|
Baguette::Log.debug "Timer" if config.print_ipc_timer
|
||||||
|
|
||||||
when IPC::Exception
|
when IPC::Exception
|
||||||
Baguette::Log.debug "IPC::Exception: #{event}"
|
Baguette::Log.debug "IPC::Exception: #{event}"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# pp! rules.authorized? Rule::Direction::In, "authd", "tls:192.168.0.42"
|
||||||
end
|
end
|
||||||
|
|
||||||
# pp! rules.authorized? Rule::Direction::In, "authd", "tls:192.168.0.42"
|
main
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
module IPCd
|
||||||
|
class CLIParser
|
||||||
|
def self.pack_args (argv : Array(String))
|
||||||
|
last_flag = nil : String?
|
||||||
|
|
||||||
|
argv.chunks do |x|
|
||||||
|
if x[0..1] == "--"
|
||||||
|
last_flag = x
|
||||||
|
end
|
||||||
|
|
||||||
|
last_flag
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.parse_rules (argv : Array(String), rules : RuleSet, redirections : RedirectionSet)
|
||||||
|
args = IPCd::CLIParser.pack_args argv
|
||||||
|
|
||||||
|
args.each do |flag, parameters|
|
||||||
|
# puts "flag: #{flag}, params: #{parameters.join(' ')}"
|
||||||
|
if flag == "--allow" || flag == "--deny"
|
||||||
|
parameters[3] # will crash if non-existant
|
||||||
|
|
||||||
|
rules << Rule.from_args parameters
|
||||||
|
elsif flag == "--redirect"
|
||||||
|
if parameters.size == 3
|
||||||
|
redirections << Redirection.new parameters[1], parameters[2]
|
||||||
|
elsif parameters.size == 5
|
||||||
|
raise "--redirect with 4 parameters not implemented, yet"
|
||||||
|
else
|
||||||
|
raise "--redirect <service> <newservice> [<origin-url> <dest-url>]"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise "cannot understand flag: #{flag}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
module IPCd
|
||||||
|
class Redirection
|
||||||
|
include YAML::Serializable
|
||||||
|
|
||||||
|
property origin : String
|
||||||
|
property destination : String
|
||||||
|
|
||||||
|
property originurl : String?
|
||||||
|
property destinationurl : String?
|
||||||
|
|
||||||
|
def initialize (@origin, @destination)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize (@origin, @destination, @originurl, @destinationurl)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"Redirection #{origin} #{destination}"
|
||||||
|
# if @originurl
|
||||||
|
# "#{origin} #{destination}"
|
||||||
|
# else
|
||||||
|
# "#{origin} #{destination} #{originurl} #{destinationurl}"
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class RedirectionSet < Array(Redirection)
|
||||||
|
def to_s
|
||||||
|
map(&.to_s).join("\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Rule
|
||||||
|
include YAML::Serializable
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
Allow
|
||||||
|
Deny
|
||||||
|
end
|
||||||
|
|
||||||
|
enum Direction
|
||||||
|
In
|
||||||
|
Out
|
||||||
|
end
|
||||||
|
|
||||||
|
getter service : String
|
||||||
|
getter url : String
|
||||||
|
getter type : Type
|
||||||
|
getter direction : Direction
|
||||||
|
|
||||||
|
def initialize (@type, @direction, @service, @url)
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches_service?(service : String)
|
||||||
|
@service == "*" || @service == service
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches_uri?(uri)
|
||||||
|
u = Regex.new @url
|
||||||
|
!@u.match(uri).nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.from_args(args : Array(String))
|
||||||
|
Rule.new(
|
||||||
|
Type.parse(args[0][2..]),
|
||||||
|
Rule::Direction.parse(args[1]),
|
||||||
|
args[2],
|
||||||
|
args[3]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{type} #{direction} #{service} #{url}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class RuleSet < Array(Rule)
|
||||||
|
def authorized?(direction : Rule::Direction, service : String, uri : String) : Bool
|
||||||
|
self.select(&.direction.==(direction))
|
||||||
|
.select(&.matches_service?(service))
|
||||||
|
.select(&.matches_uri?(uri))
|
||||||
|
.[0]?.try &.type.allow? || false
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
map(&.to_s).join("\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
class IPCdCLIParser
|
|
||||||
def self.pack_args (argv : Array(String))
|
|
||||||
last_flag = nil : String?
|
|
||||||
|
|
||||||
argv.chunks do |x|
|
|
||||||
if x[0..1] == "--"
|
|
||||||
last_flag = x
|
|
||||||
end
|
|
||||||
|
|
||||||
last_flag
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.parse_rules (argv : Array(String), rules : RuleSet, redirections : RedirectionSet)
|
|
||||||
args = IPCdCLIParser.pack_args argv
|
|
||||||
|
|
||||||
args.each do |flag, parameters|
|
|
||||||
# puts "flag: #{flag}, params: #{parameters.join(' ')}"
|
|
||||||
if flag == "--allow" || flag == "--deny"
|
|
||||||
parameters[3] # will crash if non-existant
|
|
||||||
|
|
||||||
rules << Rule.from_args parameters
|
|
||||||
elsif flag == "--redirect"
|
|
||||||
if parameters.size == 3
|
|
||||||
redirections << Redirection.new parameters[1], parameters[2]
|
|
||||||
elsif parameters.size == 5
|
|
||||||
raise "--redirect with 4 parameters not implemented, yet"
|
|
||||||
else
|
|
||||||
raise "--redirect <service> <newservice> [<origin-url> <dest-url>]"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise "oh no"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
85
src/rules.cr
85
src/rules.cr
|
@ -1,85 +0,0 @@
|
||||||
|
|
||||||
class Redirection
|
|
||||||
property origin : String
|
|
||||||
property destination : String
|
|
||||||
|
|
||||||
property originurl : String | Nil
|
|
||||||
property destinationurl : String | Nil
|
|
||||||
|
|
||||||
def initialize (@origin, @destination)
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize (@origin, @destination, @originurl, @destinationurl)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"Redirection #{origin} #{destination}"
|
|
||||||
# if @originurl
|
|
||||||
# "#{origin} #{destination}"
|
|
||||||
# else
|
|
||||||
# "#{origin} #{destination} #{originurl} #{destinationurl}"
|
|
||||||
# end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class RedirectionSet < Array(Redirection)
|
|
||||||
def to_s
|
|
||||||
map(&.to_s).join("\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Rule
|
|
||||||
enum Type
|
|
||||||
Allow
|
|
||||||
Deny
|
|
||||||
end
|
|
||||||
|
|
||||||
enum Direction
|
|
||||||
In
|
|
||||||
Out
|
|
||||||
end
|
|
||||||
|
|
||||||
getter service : String
|
|
||||||
getter url : Regex
|
|
||||||
getter type : Type
|
|
||||||
getter direction : Direction
|
|
||||||
|
|
||||||
def initialize (@type, @direction, @service, @url)
|
|
||||||
end
|
|
||||||
|
|
||||||
def matches_service?(service : String)
|
|
||||||
@service == "*" || @service == service
|
|
||||||
end
|
|
||||||
|
|
||||||
def matches_uri?(uri)
|
|
||||||
!@url.match(uri).nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.from_args(args : Array(String))
|
|
||||||
Rule.new(
|
|
||||||
Type.parse(args[0][2..]),
|
|
||||||
Rule::Direction.parse(args[1]),
|
|
||||||
args[2],
|
|
||||||
Regex.new args[3]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{type} #{direction} #{service} #{url}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class RuleSet < Array(Rule)
|
|
||||||
def authorized?(direction : Rule::Direction, service : String, uri : String) : Bool
|
|
||||||
self.select(&.direction.==(direction))
|
|
||||||
.select(&.matches_service?(service))
|
|
||||||
.select(&.matches_uri?(uri))
|
|
||||||
.[0]?.try &.type.allow? || false
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
map(&.to_s).join("\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
Reference in New Issue