aboutsummaryrefslogtreecommitdiffstats
path: root/dmvpn-ca
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2019-02-21 22:14:08 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2019-02-22 11:48:27 +0200
commit5c610ad458e3b15b91d7c0962e41d60e94d76995 (patch)
treeb30284d9056a37a428960f89a5686a8d85db3403 /dmvpn-ca
parenta0f7bd42c8acd4f4a74db02daf8387ac01f5b132 (diff)
downloaddmvpn-tools-5c610ad458e3b15b91d7c0962e41d60e94d76995.tar.bz2
dmvpn-tools-5c610ad458e3b15b91d7c0962e41d60e94d76995.tar.xz
dmvpn-ca: help on syntax
Diffstat (limited to 'dmvpn-ca')
-rwxr-xr-xdmvpn-ca1271
1 files changed, 682 insertions, 589 deletions
diff --git a/dmvpn-ca b/dmvpn-ca
index 20c2e7a..433b57d 100755
--- a/dmvpn-ca
+++ b/dmvpn-ca
@@ -189,12 +189,16 @@ function select_cert(serial)
end
+function user_error(msg) error{false, msg} end
+function syntax_error(msg) error{true, msg} end
+
+
function toint(s, min, max, desc)
local i = tonumber(s)
if i and i == math.floor(i) and i >= min and (not max or i <= max) then
return i
end
- if desc then error('Invalid '..desc..': '..s) end
+ if desc then user_error('Invalid '..desc..': '..s) end
end
function toid(s) return toint(s, 1, nil, 'ID') end
@@ -206,7 +210,7 @@ function detect_afi(s)
end
function detect_prefix_afi(s)
- local function fail() error('Invalid network address: '..s) end
+ local function fail() user_error('Invalid network address: '..s) end
local comps = stringy.split(s, '/')
if #comps ~= 2 then fail() end
@@ -276,7 +280,7 @@ function issue_cert(attrs, func)
local dn = x509n.new()
for _, rdn in ipairs(stringy.split(attrs.dn, ',')) do
local attr, value = string.match(rdn, '^%s*(%a+)=(.*)$')
- if not attr then error('Invalid RDN: '..rdn) end
+ if not attr then user_error('Invalid RDN: '..rdn) end
dn:add(attr, value)
end
cert:setSubject(dn)
@@ -439,7 +443,7 @@ end
function scan_next(desc)
if #arg == 0 then
- if desc then error('Missing '..desc) end
+ if desc then syntax_error('Missing '..desc) end
return
end
local res = arg[1]
@@ -463,7 +467,7 @@ function scan_choice(choices, desc)
local token = scan_next(desc)
if not token then return end
for k, v in pairs(choices) do if token == k then return v end end
- error('Invalid '..desc..': '..token)
+ syntax_error('Invalid '..desc..': '..token)
end
function scan_param(choices, desc, optional)
@@ -474,7 +478,7 @@ function scan_param(choices, desc, optional)
for _, v in ipairs(choices) do
if k == v then return k, scan_next(k..' specification') end
end
- error('Invalid '..desc..': '..k)
+ syntax_error('Invalid '..desc..': '..k)
end
@@ -483,7 +487,7 @@ function scan_site_code() return scan_next('site code'):upper() end
function validate_site(code, retired)
code = code:upper()
if exists('site', {code=code}, not retired) then return code end
- error('Invalid site code: '..code)
+ user_error('Invalid site code: '..code)
end
function scan_site(retired) return validate_site(scan_site_code(), retired) end
@@ -536,7 +540,7 @@ function scan_vpnc(options)
end
if res.id and not exists('vpnc', res, not options.retired) then
- error('Invalid '..obj..' number: '..res.id)
+ user_error('Invalid '..obj..' number: '..res.id)
end
return res
@@ -551,7 +555,7 @@ end
function scan_finished()
- if #arg > 0 then error('Invalid parameter: '..scan_next()) end
+ if #arg > 0 then syntax_error('Invalid parameter: '..scan_next()) end
end
@@ -648,7 +652,7 @@ function get_cert_by_serial(serial)
serial = toint(serial, 0, nil, 'serial number')
local cert = select_cert(serial)
- if not cert then error('Invalid serial number') end
+ if not cert then user_error('Invalid serial number') end
return cert
end
@@ -694,7 +698,7 @@ end
function load_crl_cert()
local cert, key = try_load_crl_cert()
- if not cert then error('No valid CRL signing key found') end
+ if not cert then user_error('No valid CRL signing key found') end
return cert, key
end
@@ -780,654 +784,743 @@ function confirm(object, action, tbl)
end
-output = scan_choice(
- scan_choice(
- {
- site={
- add=function()
- local site = scan_site_code()
- scan_finished()
+cert_select_syntax = '[serial <num>|hubs|hub <id>|site <abbr> [vpnc <id>]|crl]'
- add_site{code=site}
- end,
- set=function()
- local k, v = scan_param(
- {'asn', 'name'}, 'attribute'
- )
- local site = scan_site()
- scan_finished()
-
- if k == 'asn' then
- v = toint(
- v,
- 0,
- math.pow(2, 16) - 1,
- 'AS number'
- )
- end
+commands = {
+ site={
+ add={
+ '<abbr>',
+ function()
+ local site = scan_site_code()
+ scan_finished()
- update('site', {[k]=v}, {code=site})
- end,
- unset=function()
- local k = scan_choice(
- {name='name'}, 'attribute'
- )
- local site = scan_site()
- scan_finished()
-
- update('site', {[k]=false}, {code=site})
- end,
- show=function()
- local site = scan_site_filter{
- param='code', retired=true
- }
- scan_finished()
-
- return show_site(site or "code > ''")
- end,
- retire=function()
- local site = scan_site()
- scan_finished()
- confirm(
- 'site',
- 'retired',
- show_site{code=site}
- )
-
- delete('subnet', {site=site})
- local output = retire_vpnc(site)
- update(
- 'site',
- {active='0'},
- {code=site}
+ add_site{code=site}
+ end
+ },
+ set={
+ '{asn|name} <value> <abbr>',
+ function()
+ local k, v = scan_param(
+ {'asn', 'name'}, 'attribute'
+ )
+ local site = scan_site()
+ scan_finished()
+
+ if k == 'asn' then
+ v = toint(
+ v,
+ 0,
+ math.pow(2, 16) - 1,
+ 'AS number'
)
- return output
end
- },
- subnet={
- add=function()
- local addr = scan_subnet()
- local site = scan_site_selector()
- scan_finished()
-
- add_subnet(site, addr)
- end,
- show=function()
- local site = scan_site_filter()
- scan_finished()
-
- return show(
- 'subnet',
- {'site', 'address'},
- site and site_filter(site) or
- "site > ''"
- )
- end,
- del=function()
- local addr = scan_subnet()
- local filter = site_filter(
- scan_site_filter()
- )
- scan_finished()
-
- if not filter then filter = {} end
- filter.address = addr
- if not exists('subnet', filter) then
- error(
- 'Address does not exist: '..
- addr
- )
- end
+ update('site', {[k]=v}, {code=site})
+ end
+ },
+ unset={
+ 'name <abbr>',
+ function()
+ local k = scan_choice(
+ {name='name'}, 'attribute'
+ )
+ local site = scan_site()
+ scan_finished()
+
+ update('site', {[k]=false}, {code=site})
+ end
+ },
+ show={
+ '[code <abbr>]',
+ function()
+ local site = scan_site_filter{
+ param='code', retired=true
+ }
+ scan_finished()
- delete('subnet', filter)
- end
- },
- vpnc={
- create=function()
- local site = scan_site_selector()
- local _, id = scan_param(
- 'id', 'VPNc ID', true
+ return show_site(site or "code > ''")
+ end
+ },
+ retire={
+ '<abbr>',
+ function()
+ local site = scan_site()
+ scan_finished()
+ confirm('site', 'retired', show_site{code=site})
+
+ delete('subnet', {site=site})
+ local output = retire_vpnc(site)
+ update('site', {active='0'}, {code=site})
+ return output
+ end
+ }
+ },
+ subnet={
+ add={
+ '<addr> site <abbr>',
+ function()
+ local addr = scan_subnet()
+ local site = scan_site_selector()
+ scan_finished()
+
+ add_subnet(site, addr)
+ end
+ },
+ show={
+ '[site <abbr>]',
+ function()
+ local site = scan_site_filter()
+ scan_finished()
+
+ return show(
+ 'subnet',
+ {'site', 'address'},
+ site and site_filter(site) or
+ "site > ''"
+ )
+ end
+ },
+ del={
+ '<addr> [site <abbr>]',
+ function()
+ local addr = scan_subnet()
+ local filter = site_filter(scan_site_filter())
+ scan_finished()
+
+ if not filter then filter = {} end
+ filter.address = addr
+
+ if not exists('subnet', filter) then
+ user_error(
+ 'Address does not exist: '..addr
)
- scan_finished()
+ end
- insert(
- 'vpnc',
- {
- site=site,
- id=id and toid(id) or
- next_key(
- 'vpnc',
- 'id',
- {site=site}
- )
- }
- )
- end,
- set=function()
- local _, name = scan_param(
- 'name', 'attribute'
- )
- local vpnc = scan_vpnc{id_attr='id'}
- scan_finished()
-
- update('vpnc', {name=name}, vpnc)
- end,
- unset=function()
- scan_choice({name=true}, 'attribute')
- local vpnc = scan_vpnc{id_attr='id'}
- scan_finished()
-
- update('vpnc', {name=false}, vpnc)
- end,
- show=function()
- local site = scan_site_filter{
- retired=true
+ delete('subnet', filter)
+ end
+ }
+ },
+ vpnc={
+ create={
+ 'site <abbr> [id <num>]',
+ function()
+ local site = scan_site_selector()
+ local _, id = scan_param('id', 'VPNc ID', true)
+ scan_finished()
+
+ insert(
+ 'vpnc',
+ {
+ site=site,
+ id=id and toid(id) or
+ next_key(
+ 'vpnc',
+ 'id',
+ {site=site}
+ )
}
- scan_finished()
-
- return show_vpnc(site)
- end,
- retire=function()
- local id = toid(
- scan_next('VPNc number')
- )
- local site = scan_site_selector()
- scan_finished()
- confirm(
- 'VPNc',
- 'retired',
- show_vpnc({code=site}, id)
- )
+ )
+ end
+ },
+ set={
+ 'name <value> site <abbr> id <num>',
+ function()
+ local _, name = scan_param('name', 'attribute')
+ local vpnc = scan_vpnc{id_attr='id'}
+ scan_finished()
+
+ update('vpnc', {name=name}, vpnc)
+ end
+ },
+ unset={
+ 'name site <abbr> id <num>',
+ function()
+ scan_choice({name=true}, 'attribute')
+ local vpnc = scan_vpnc{id_attr='id'}
+ scan_finished()
+
+ update('vpnc', {name=false}, vpnc)
+ end
+ },
+ show={
+ '[site <abbr>]',
+ function()
+ local site = scan_site_filter{retired=true}
+ scan_finished()
- return retire_vpnc(site, id)
- end
- },
- ['gre-addr']={
- add=function()
- local addr = scan_addr()
- local vpnc = scan_vpnc()
- scan_finished()
-
- insert(
- 'greAddress',
- {
- site=vpnc.site,
- vpnc=vpnc.id,
- family=detect_afi(addr),
- address=addr
- }
- )
- end,
- del=function()
- local addr = scan_addr()
- scan_finished()
+ return show_vpnc(site)
+ end
+ },
+ retire={
+ '<id> site <abbr>',
+ function()
+ local id = toid(scan_next('VPNc number'))
+ local site = scan_site_selector()
+ scan_finished()
+ confirm(
+ 'VPNc',
+ 'retired',
+ show_vpnc({code=site}, id)
+ )
+
+ return retire_vpnc(site, id)
+ end
+ }
+ },
+ ['gre-addr']={
+ add={
+ '<addr> {hub <id>|site <abbr> [vpnc <id>]}',
+ function()
+ local addr = scan_addr()
+ local vpnc = scan_vpnc()
+ scan_finished()
+
+ insert(
+ 'greAddress',
+ {
+ site=vpnc.site,
+ vpnc=vpnc.id,
+ family=detect_afi(addr),
+ address=addr
+ }
+ )
+ end
+ },
+ del={
+ '<addr>',
+ function()
+ local addr = scan_addr()
+ scan_finished()
- delete('greAddress', {address=addr})
- end
- },
- hub={
- create=function()
- local id = scan_next()
- scan_finished()
-
- insert(
- 'vpnc',
- {
- site='',
- id=id and toid(id) or
- next_key(
- 'vpnc',
- 'id',
- {site=''}
- )
- }
- )
- end,
- set=function()
- local _, name = scan_param(
- 'name', 'attribute'
- )
- local id = toid(scan_next('hub number'))
- scan_finished()
+ delete('greAddress', {address=addr})
+ end
+ }
+ },
+ hub={
+ create={
+ '[<id>]',
+ function()
+ local id = scan_next()
+ scan_finished()
+
+ insert(
+ 'vpnc',
+ {
+ site='',
+ id=id and toid(id) or
+ next_key(
+ 'vpnc',
+ 'id',
+ {site=''}
+ )
+ }
+ )
+ end
+ },
+ set={
+ 'name <value> <id>',
+ function()
+ local _, name = scan_param('name', 'attribute')
+ local id = toid(scan_next('hub number'))
+ scan_finished()
+
+ update('vpnc', {name=name}, {site='', id=id})
+ end
+ },
+ unset={
+ 'name <id>',
+ function()
+ scan_choice({name=true}, 'attribute')
+ local id = toid(scan_next('hub number'))
+ scan_finished()
+
+ update('vpnc', {name=false}, {site='', id=id})
+ end
+ },
+ show={
+ '',
+ function()
+ scan_finished()
- update(
- 'vpnc',
- {name=name},
- {site='', id=id}
+ return show_vpnc{code=''}
+ end
+ },
+ retire={
+ '<id>',
+ function()
+ local id = toid(scan_next('hub number'))
+ scan_finished()
+ confirm(
+ 'hub',
+ 'retired',
+ show_vpnc({code=''}, id)
+ )
+
+ return retire_vpnc('', id)
+ end
+ }
+ },
+ ['root-cert']={
+ generate={
+ '',
+ function()
+ scan_finished()
+
+ if stat.stat(config.db.file) then
+ simple_confirm(
+ function()
+ io.write('Current configuration and all keys will be lost.\n')
+ end
)
- end,
- unset=function()
- scan_choice({name=true}, 'attribute')
- local id = toid(scan_next('hub number'))
- scan_finished()
+ end
- update(
- 'vpnc',
- {name=false},
- {site='', id=id}
- )
- end,
- show=function()
- scan_finished()
-
- return show_vpnc{code=''}
- end,
- retire=function()
- local id = toid(scan_next('hub number'))
- scan_finished()
- confirm(
- 'hub',
- 'retired',
- show_vpnc({code=''}, id)
- )
+ os.remove(config.db.file)
+ for _, statement in ipairs(
+ {
+ [[
+ CREATE TABLE site (
+ code VARCHAR(16) NOT NULL PRIMARY KEY,
+ asn INTEGER NOT NULL,
+ name VARCHAR(32),
+ active CHAR(1) DEFAULT '1'
+ )
+ ]],
+ [[
+ CREATE TABLE subnet (
+ site VARCHAR(16) NOT NULL REFERENCES site(code),
+ family INTEGER NOT NULL,
+ address CHAR(14) NOT NULL,
+ PRIMARY KEY(site, family, address)
+ )
+ ]],
+ [[
+ CREATE TABLE vpnc (
+ site VARCHAR(16) NOT NULL REFERENCES site(code),
+ id INTEGER NOT NULL,
+ name VARCHAR(32),
+ active CHAR(1) DEFAULT '1',
+ PRIMARY KEY(site, id)
+ )
+ ]],
+ [[
+ CREATE TABLE greAddress (
+ site VARCHAR(16) NOT NULL,
+ vpnc INTEGER NOT NULL,
+ family INTEGER NOT NULL,
+ address CHAR(14) NOT NULL,
+ PRIMARY KEY(site, vpnc, family),
+ FOREIGN KEY(site, vpnc) REFERENCES vpnc(site, id),
+ UNIQUE(family, address)
+ )
+ ]],
+ [[
+ CREATE TABLE certificate (
+ serial INTEGER NOT NULL PRIMARY KEY,
+ site VARCHAR(16),
+ vpnc INTEGER,
+ dn VARCHAR(128) NOT NULL,
+ issued DATETIME NOT NULL,
+ expires DATETIME NOT NULL,
+ revoked DATETIME,
+ privateKey TEXT NOT NULL,
+ data TEXT NOT NULL,
+ FOREIGN KEY(site, vpnc) REFERENCES vpnc(site, id)
+ )
+ ]],
+ [[
+ CREATE TABLE crl (
+ serial INTEGER NOT NULL PRIMARY KEY,
+ expires DATETIME NOT NULL,
+ data TEXT NOT NULL
+ )
+ ]]
+ }
+ ) do execute(statement) end
- return retire_vpnc('', id)
+ add_site{code=''}
+ for _, subnet in ipairs(config.hub.subnets) do
+ add_subnet('', subnet)
end
- },
- ['root-cert']={
- generate=function()
- scan_finished()
-
- if stat.stat(config.db.file) then
- simple_confirm(
- function()
- io.write('Current configuration and all keys will be lost.\n')
- end
+
+ issue_ca_cert{
+ keyCertSign=true,
+ cRLSign=not config.db['encrypt-keys']
+ }
+ end
+ },
+ show={
+ '',
+ function()
+ scan_finished()
+ print_cert(get_cert_by_serial(0))
+ end
+ }
+ },
+ cert={
+ generate={
+ '[hubs|hub <id>|site <abbr> [vpnc <id>]|crl]',
+ function()
+ local crl = arg[1] == 'crl'
+ local vpnc = not crl and vpnc_filter(
+ scan_vpnc{multiple=true},
+ 's.code',
+ 'v.id'
+ )
+
+ local dns = {}
+ local gen_crl_cert
+ if not vpnc then
+ gen_crl_cert = not try_load_crl_cert()
+ if gen_crl_cert then
+ table.insert(
+ dns, {config.ca.dn}
)
end
+ end
- os.remove(config.db.file)
- for _, statement in ipairs(
- {
- [[
- CREATE TABLE site (
- code VARCHAR(16) NOT NULL PRIMARY KEY,
- asn INTEGER NOT NULL,
- name VARCHAR(32),
- active CHAR(1) DEFAULT '1'
- )
- ]],
- [[
- CREATE TABLE subnet (
- site VARCHAR(16) NOT NULL REFERENCES site(code),
- family INTEGER NOT NULL,
- address CHAR(14) NOT NULL,
- PRIMARY KEY(site, family, address)
- )
- ]],
- [[
- CREATE TABLE vpnc (
- site VARCHAR(16) NOT NULL REFERENCES site(code),
- id INTEGER NOT NULL,
- name VARCHAR(32),
- active CHAR(1) DEFAULT '1',
- PRIMARY KEY(site, id)
- )
- ]],
- [[
- CREATE TABLE greAddress (
- site VARCHAR(16) NOT NULL,
- vpnc INTEGER NOT NULL,
- family INTEGER NOT NULL,
- address CHAR(14) NOT NULL,
- PRIMARY KEY(site, vpnc, family),
- FOREIGN KEY(site, vpnc) REFERENCES vpnc(site, id),
- UNIQUE(family, address)
- )
- ]],
- [[
- CREATE TABLE certificate (
- serial INTEGER NOT NULL PRIMARY KEY,
- site VARCHAR(16),
- vpnc INTEGER,
- dn VARCHAR(128) NOT NULL,
- issued DATETIME NOT NULL,
- expires DATETIME NOT NULL,
- revoked DATETIME,
- privateKey TEXT NOT NULL,
- data TEXT NOT NULL,
- FOREIGN KEY(site, vpnc) REFERENCES vpnc(site, id)
- )
- ]],
- [[
- CREATE TABLE crl (
- serial INTEGER NOT NULL PRIMARY KEY,
- expires DATETIME NOT NULL,
- data TEXT NOT NULL
- )
- ]]
- }
- ) do execute(statement) end
+ local subjects = {}
+
+ if not crl then
+ local filter = vpnc or {}
+ filter['s.active'] = '1'
+ filter['v.active'] = '1'
- add_site{code=''}
- for _, subnet in ipairs(
- config.hub.subnets
+ for row in select_many(
+ 's.code, v.id, s.asn, s.name, v.name',
+ 'site s INNER JOIN vpnc v ON s.code = v.site',
+ filter,
+ 'n'
) do
- add_subnet('', subnet)
- end
+ local attrs = {
+ site=row[1],
+ vpnc=row[2],
+ asn=row[3],
+ sname=row[4],
+ vname=row[5]
+ }
- issue_ca_cert{
- keyCertSign=true,
- cRLSign=not config.db['encrypt-keys']
- }
- end,
- show=function()
- scan_finished()
- print_cert(get_cert_by_serial(0))
- end
- },
- cert={
- generate=function()
- local crl = arg[1] == 'crl'
- local vpnc = not crl and vpnc_filter(
- scan_vpnc{multiple=true},
- 's.code',
- 'v.id'
- )
+ attrs.params = config[
+ attrs.site == '' and
+ 'hub' or 'spoke'
+ ]
+
+ local function insert()
+ attrs.dn = attrs.params.dn:gsub(
+ '%$(%u+)',
+ {
+ ROOT=config.ca.dn,
+ SITE=attrs.sname or
+ attrs.site,
+ NAME=attrs.vname or
+ attrs.params[
+ 'default-name'
+ ]:gsub(
+ '$ID',
+ attrs.vpnc
+ )
+ }
+ )
- local dns = {}
- local gen_crl_cert
- if not vpnc then
- gen_crl_cert = not try_load_crl_cert()
- if gen_crl_cert then
+ table.insert(
+ subjects, attrs
+ )
table.insert(
dns,
- {config.ca.dn}
+ {tostring(attrs.dn)}
)
end
- end
- local subjects = {}
+ if vpnc then insert()
- if not crl then
- local filter = vpnc or {}
- filter['s.active'] = '1'
- filter['v.active'] = '1'
-
- for row in select_many(
- 's.code, v.id, s.asn, s.name, v.name',
- 'site s INNER JOIN vpnc v ON s.code = v.site',
- filter,
- 'n'
- ) do
- local attrs = {
+ else
+ local valid
+ for cert in select_certs{
site=row[1],
- vpnc=row[2],
- asn=row[3],
- sname=row[4],
- vname=row[5]
- }
-
- attrs.params = config[
- attrs.site == '' and
- 'hub' or
- 'spoke'
- ]
-
- local function insert()
- attrs.dn = attrs.params.dn:gsub(
- '%$(%u+)',
- {
- ROOT=config.ca.dn,
- SITE=attrs.sname or
- attrs.site,
- NAME=attrs.vname or
- attrs.params[
- 'default-name'
- ]:gsub(
- '$ID',
- attrs.vpnc
- )
- }
- )
-
- table.insert(
- subjects,
- attrs
- )
- table.insert(
- dns,
- {tostring(attrs.dn)}
- )
- end
-
- if vpnc then insert()
-
- else
- local valid
- for cert in select_certs{
- site=row[1],
- vpnc=row[2]
- } do
- if is_valid(
- cert,
- attrs.params.renewal
- ) then
- valid = true
- end
- end
- if not valid then
- insert()
+ vpnc=row[2]
+ } do
+ if is_valid(
+ cert,
+ attrs.params.renewal
+ ) then
+ valid = true
end
end
+ if not valid then
+ insert()
+ end
end
end
+ end
- add_header(dns, {'dn'})
- confirm('certificates', 'issued', dns)
+ add_header(dns, {'dn'})
+ confirm('certificates', 'issued', dns)
- local issued = {}
+ local issued = {}
- if gen_crl_cert then
- table.insert(
- issued,
- issue_ca_cert{
- cRLSign=true
- }
- )
- end
+ if gen_crl_cert then
+ table.insert(
+ issued,
+ issue_ca_cert{cRLSign=true}
+ )
+ end
- for _, attrs in ipairs(subjects) do
- local asn = attrs.asn
- attrs.asn = nil
+ for _, attrs in ipairs(subjects) do
+ local asn = attrs.asn
+ attrs.asn = nil
- local cert = issue_cert(
- attrs,
- function(cert, attrs)
+ local cert = issue_cert(
+ attrs,
+ function(cert, attrs)
- local function get_subnets()
- return select_many(
- 'family, address',
- 'subnet',
- {site=attrs.site},
- 'a'
- )
- end
+ local function get_subnets()
+ return select_many(
+ 'family, address',
+ 'subnet',
+ {site=attrs.site},
+ 'a'
+ )
+ end
- local function get_gre_addrs()
- return select_many(
- 'family, address',
- 'greAddress',
- {site=attrs.site, vpnc=attrs.vpnc},
- 'a'
- )
- end
+ local function get_gre_addrs()
+ return select_many(
+ 'family, address',
+ 'greAddress',
+ {site=attrs.site, vpnc=attrs.vpnc},
+ 'a'
+ )
+ end
+
+ cert:addExtension(
+ x509ext.new(
+ dmvpn.OID_IS_HUB,
+ 'critical,DER',
+ asn1.boolean.encode(attrs.site == '')
+ )
+ )
+ local hosts = config.hub.hosts
+ if hosts then
cert:addExtension(
x509ext.new(
- dmvpn.OID_IS_HUB,
- 'critical,DER',
- asn1.boolean.encode(attrs.site == '')
+ dmvpn.OID_HUB_HOSTS,
+ 'DER',
+ asn1.sequence_of(asn1.ia5string).encode(hosts)
)
)
+ end
- local hosts = config.hub.hosts
- if hosts then
- cert:addExtension(
- x509ext.new(
- dmvpn.OID_HUB_HOSTS,
- 'DER',
- asn1.sequence_of(asn1.ia5string).encode(hosts)
- )
- )
- end
-
- local net_config = {}
- local pr_config = {}
- for subnet in get_subnets() do
- local f = subnet.family
- if not pr_config[f] then
- pr_config[f] = {}
- table.insert(
- net_config,
- {
- addressFamily={afi=f},
- ipAddressChoice={
- addressesOrRanges=pr_config[f]
- }
- }
- )
- end
+ local net_config = {}
+ local pr_config = {}
+ for subnet in get_subnets() do
+ local f = subnet.family
+ if not pr_config[f] then
+ pr_config[f] = {}
table.insert(
- pr_config[f],
- {addressPrefix=subnet.address}
- )
- end
- if net_config[1] then
- cert:addExtension(
- x509ext.new(
- 'sbgp-ipAddrBlock',
- 'critical,DER',
- rfc3779.IPAddrBlocks.encode(net_config)
- )
- )
- end
-
- local san
- for ga in get_gre_addrs() do
- if not san then
- san = x509an.new()
- end
- san:add(
- 'IP',
- ga.address
+ net_config,
+ {
+ addressFamily={afi=f},
+ ipAddressChoice={
+ addressesOrRanges=pr_config[f]
+ }
+ }
)
end
- if san then
- cert:setSubjectAlt(san)
- end
-
+ table.insert(
+ pr_config[f],
+ {addressPrefix=subnet.address}
+ )
+ end
+ if net_config[1] then
cert:addExtension(
x509ext.new(
- 'sbgp-autonomousSysNum',
+ 'sbgp-ipAddrBlock',
'critical,DER',
- rfc3779.ASIdentifiers.encode{
- asnum={asIdsOrRanges={{id=asn}}}
- }
+ rfc3779.IPAddrBlocks.encode(net_config)
)
)
end
- )
- export_cert(cert)
- table.insert(issued, cert)
- end
- return format_cert_info(issued)
- end,
- list=function()
- local certs = {}
- for cert in get_certs() do
- table.insert(certs, cert)
- end
- return format_cert_info(certs)
- end,
- show=function()
- for cert in get_certs() do
- print_cert(cert)
- end
- end,
- revoke=function()
- local certs = {}
- for cert, selector in get_certs() do
- local valid = is_valid(cert)
- if selector == 'serial' and
- not valid then
-
- error('Certificate already expired or revoked')
- end
- if valid then
- table.insert(
- certs, cert
+ local san
+ for ga in get_gre_addrs() do
+ if not san then
+ san = x509an.new()
+ end
+ san:add(
+ 'IP',
+ ga.address
+ )
+ end
+ if san then
+ cert:setSubjectAlt(san)
+ end
+
+ cert:addExtension(
+ x509ext.new(
+ 'sbgp-autonomousSysNum',
+ 'critical,DER',
+ rfc3779.ASIdentifiers.encode{
+ asnum={asIdsOrRanges={{id=asn}}}
+ }
+ )
)
end
- end
- confirm(
- 'certificates',
- 'revoked',
- format_cert_info(certs)
)
+ export_cert(cert)
+ table.insert(issued, cert)
+ end
- local revoked = {}
- for _, cert in ipairs(certs) do
- table.insert(
- revoked,
- revoke{serial=cert.serial}[1]
- )
+ return format_cert_info(issued)
+ end
+ },
+ list={
+ cert_select_syntax,
+ function()
+ local certs = {}
+ for cert in get_certs() do
+ table.insert(certs, cert)
+ end
+ return format_cert_info(certs)
+ end
+ },
+ show={
+ cert_select_syntax,
+ function()
+ for cert in get_certs() do print_cert(cert) end
+ end
+ },
+ revoke={
+ cert_select_syntax,
+ function()
+ local certs = {}
+ for cert, selector in get_certs() do
+ local valid = is_valid(cert)
+ if selector == 'serial' and
+ not valid then
+
+ user_error('Certificate already expired or revoked')
end
- return format_cert_info(revoked)
- end,
- export=function()
- local _, serial = scan_param(
- 'serial', 'selector'
- )
- local cert = get_cert_by_serial(serial)
- if not cert.site then
- error('Cannot export CA certificate')
+ if valid then
+ table.insert(certs, cert)
end
- export_cert(cert)
end
- },
- crl={
- generate=function()
- scan_finished()
- io.write(tostring(generate_crl()))
- end,
- show=function()
- scan_finished()
- io.write(get_crl():text())
- end,
- export=function()
- scan_finished()
- io.write(tostring(get_crl()))
+ confirm(
+ 'certificates',
+ 'revoked',
+ format_cert_info(certs)
+ )
+
+ local revoked = {}
+ for _, cert in ipairs(certs) do
+ table.insert(
+ revoked,
+ revoke{serial=cert.serial}[1]
+ )
end
- },
- password={
- set=function()
- for row in select_many(
- 'serial, privateKey',
- 'certificate',
- nil,
- 'n'
- ) do
- update(
- 'certificate',
- {privateKey=encrypt_key(decrypt_key(row[2]), true, 'new')},
- {serial=row[1]}
- )
- end
+ return format_cert_info(revoked)
+ end
+ },
+ export={
+ 'serial <num>',
+ function()
+ local _, serial = scan_param(
+ 'serial', 'selector'
+ )
+ local cert = get_cert_by_serial(serial)
+ if not cert.site then
+ user_error(
+ 'Cannot export CA certificate'
+ )
end
- }
+ export_cert(cert)
+ end
+ }
+ },
+ crl={
+ generate={
+ '',
+ function()
+ scan_finished()
+ io.write(tostring(generate_crl()))
+ end
+ },
+ show={
+ '',
+ function()
+ scan_finished()
+ io.write(get_crl():text())
+ end
},
- 'object type'
- ),
- 'action'
-)()
+ export={
+ '',
+ function()
+ scan_finished()
+ io.write(tostring(get_crl()))
+ end
+ }
+ },
+ password={
+ set={
+ '',
+ function()
+ for row in select_many(
+ 'serial, privateKey',
+ 'certificate',
+ nil,
+ 'n'
+ ) do
+ update(
+ 'certificate',
+ {
+ privateKey=encrypt_key(
+ decrypt_key(row[2]),
+ true,
+ 'new'
+ )
+ },
+ {serial=row[1]}
+ )
+ end
+ end
+ }
+ }
+}
+
+function scan_command(obj_type)
+ local prefix = 'dmvpn-ca '..(obj_type and obj_type..' ' or '')
+ local cmd = scan_next()
+ local choices = obj_type and commands[obj_type] or commands
+ local res = choices[cmd]
+ if res then
+ if obj_type then return prefix..cmd..' '..res[1], res[2] end
+ return scan_command(cmd)
+ end
+ print('Available commands:')
+ for k, v in pairs(choices) do
+ print('\t'..prefix..k..(obj_type and ' '..v[1] or ''))
+ end
+end
-if output then print_table(output) end
+syntax, func = scan_command()
+
+if syntax then
+ status, output = xpcall(
+ func,
+ function(err)
+ if type(err) == 'string' then
+ return err..'\n'..debug.traceback()
+ end
+ return err[2]..(err[1] and '\n\nSyntax: '..syntax or '')
+ end
+ )
+ if status then
+ if output then print_table(output) end
+ if sql then conn:commit() end
+ else print(output) end
+end
if sql then
- conn:commit()
conn:close()
sql:close()
end
+
+os.exit(status and 0 or 1)