Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
W
Warden
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Pavel Valach
Warden
Commits
28cbcd7b
Commit
28cbcd7b
authored
7 years ago
by
Pavel Kácha
Browse files
Options
Downloads
Patches
Plain Diff
Support for 'openssl ca' backend
parent
2fb036f5
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
warden3/contrib/warden_ra/warden_ra.py
+222
-135
222 additions, 135 deletions
warden3/contrib/warden_ra/warden_ra.py
with
222 additions
and
135 deletions
warden3/contrib/warden_ra/warden_ra.py
+
222
−
135
View file @
28cbcd7b
...
@@ -6,13 +6,22 @@
...
@@ -6,13 +6,22 @@
import
sys
import
sys
import
os
import
os
import
time
import
fcntl
import
errno
import
string
import
string
import
random
import
random
import
struct
import
struct
import
operator
import
argparse
import
argparse
import
subprocess
import
json
import
json
import
logging
import
logging
import
os.path
as
pth
import
subprocess
import
shlex
import
tempfile
import
M2Crypto
import
ConfigParser
# *ph* server vulnerable to logjam, local openssl too new, use hammer to disable Diffie-Helmann
# *ph* server vulnerable to logjam, local openssl too new, use hammer to disable Diffie-Helmann
import
ssl
import
ssl
ssl
.
_DEFAULT_CIPHERS
+=
"
:!DH
"
ssl
.
_DEFAULT_CIPHERS
+=
"
:!DH
"
...
@@ -20,105 +29,55 @@ ssl._DEFAULT_CIPHERS += ":!DH"
...
@@ -20,105 +29,55 @@ ssl._DEFAULT_CIPHERS += ":!DH"
import
ejbcaws
import
ejbcaws
# usual path to warden server
# usual path to warden server
sys
.
path
.
append
(
os
.
pa
th
.
join
(
os
.
pa
th
.
dirname
(
__file__
),
"
..
"
,
"
warden-server
"
))
sys
.
path
.
append
(
p
th
.
join
(
p
th
.
dirname
(
__file__
),
"
..
"
,
"
warden-server
"
))
import
warden_server
import
warden_server
from
warden_server
import
Request
,
ObjectBase
,
FileLogger
,
SysLogger
,
Server
,
expose
,
read_cfg
from
warden_server
import
Request
,
ObjectBase
,
FileLogger
,
SysLogger
,
Server
,
expose
,
read_cfg
class
ClientDisabledError
(
Exception
):
class
ClientDisabledError
(
Exception
):
pass
pass
class
ClientNotIssuableError
(
Exception
):
pass
class
AuthenticationError
(
Exception
):
pass
class
PopenError
(
Exception
):
pass
class
EjbcaClient
(
object
):
def
__init__
(
self
,
registry
,
ejbca_data
=
None
):
class
Client
(
object
):
self
.
registry
=
registry
self
.
ejbca_data
=
ejbca_data
or
{}
@property
def
admins
(
self
):
return
[
u
if
not
u
.
startswith
(
"
RFC822NAME
"
)
else
u
[
11
:]
for
u
in
self
.
ejbca_data
[
"
subjectAltName
"
].
split
(
"
,
"
)]
@admins.setter
def
admins
(
self
,
emails
):
self
.
ejbca_data
[
"
subjectAltName
"
]
=
"
,
"
.
join
((
"
RFC822NAME=%s
"
%
e
for
e
in
emails
))
@property
def
name
(
self
):
username
=
self
.
ejbca_data
[
"
username
"
]
if
not
username
.
endswith
(
self
.
registry
.
username_suffix
):
raise
ValueError
((
"
Ejbca user username does not conform to config
"
,
self
.
ejbca_data
))
return
username
[:
-
len
(
self
.
registry
.
username_suffix
)]
@name.setter
def
name
(
self
,
new
):
self
.
ejbca_data
[
"
username
"
]
=
new
+
self
.
registry
.
username_suffix
self
.
ejbca_data
[
"
subjectDN
"
]
=
self
.
registry
.
subject_dn_template
%
new
@property
def
enabled
(
self
):
return
self
.
ejbca_data
[
"
status
"
]
!=
ejbcaws
.
STATUS_HISTORICAL
@enabled.setter
def
enabled
(
self
,
new
):
if
self
.
enabled
:
if
not
new
:
self
.
ejbca_data
[
"
status
"
]
=
ejbcaws
.
STATUS_HISTORICAL
else
:
if
new
:
self
.
ejbca_data
[
"
status
"
]
=
ejbcaws
.
STATUS_GENERATED
@property
def
status
(
self
):
s
=
self
.
ejbca_data
[
"
status
"
]
if
s
==
ejbcaws
.
STATUS_NEW
:
return
"
Issuable
"
elif
s
==
ejbcaws
.
STATUS_GENERATED
:
return
"
Passive
"
elif
s
==
ejbcaws
.
STATUS_INITIALIZED
:
return
"
New
"
elif
s
==
ejbcaws
.
STATUS_HISTORICAL
:
return
"
Disabled
"
else
:
return
"
EJBCA status %d
"
%
s
def
get_certs
(
self
):
def
__init__
(
self
,
name
,
admins
=
None
,
status
=
None
,
pwd
=
None
,
opaque
=
None
):
return
self
.
registry
.
ejbca
.
find_certs
(
self
.
ejbca_data
[
"
username
"
],
validOnly
=
False
)
self
.
name
=
name
self
.
admins
=
admins
or
[]
self
.
status
=
status
or
"
New
"
self
.
pwd
=
pwd
self
.
opaque
=
opaque
or
{}
def
allow_new_cert
(
self
,
pwd
=
None
):
def
update
(
self
,
admins
=
None
,
status
=
None
,
pwd
=
None
):
if
not
self
.
enabled
:
if
admins
is
not
None
:
self
.
admins
=
admins
if
status
:
if
self
.
status
==
"
Disabled
"
and
status
not
in
(
"
Passive
"
,
"
Disabled
"
):
raise
ClientDisabledError
(
"
This client is disabled
"
)
raise
ClientDisabledError
(
"
This client is disabled
"
)
self
.
ejbca_data
[
"
status
"
]
=
ejbcaws
.
STATUS_NEW
self
.
status
=
status
if
pwd
is
not
None
:
self
.
pwd
=
pwd
if
status
==
"
Issuable
"
and
pwd
else
None
self
.
ejbca_data
[
"
password
"
]
=
pwd
self
.
ejbca_data
[
"
clearPwd
"
]
=
True
def
new_cert
(
self
,
csr
,
pwd
):
cert
=
self
.
registry
.
ejbca
.
pkcs10_request
(
self
.
ejbca_data
[
"
username
"
],
pwd
,
csr
,
0
,
ejbcaws
.
RESPONSETYPE_CERTIFICATE
)
return
cert
def
__str__
(
self
):
def
__str__
(
self
):
return
(
return
(
"
Client: %s
(%s)
\n
"
"
Client: %s
\n
"
"
Admins: %s
\n
"
"
Admins: %s
\n
"
"
Status: %s
\n
"
"
Status: %s
\n
"
)
%
(
)
%
(
self
.
name
,
"
,
"
.
join
(
self
.
admins
),
self
.
status
)
self
.
name
,
self
.
ejbca_data
[
"
subjectDN
"
],
"
,
"
.
join
(
self
.
admins
),
self
.
status
)
def
verbose_
str
(
self
):
def
str
(
self
,
verbose
=
False
):
return
"
%s
\n
"
%
self
.
ejbca_data
return
str
(
self
)
+
(
str
(
self
.
opaque
)
if
self
.
opaque
and
verbose
else
""
)
def
save
(
self
):
self
.
registry
.
ejbca
.
edit_user
(
self
.
ejbca_data
)
class
EjbcaRegistry
(
OpenSSLRegistry
):
class
EjbcaRegistry
(
object
):
status_ejbca_to_str
=
{
ejbcaws
.
STATUS_NEW
:
"
Issuable
"
,
ejbcaws
.
STATUS_GENERATED
:
"
Passive
"
,
ejbcaws
.
STATUS_INITIALIZED
:
"
New
"
,
ejbcaws
.
STATUS_HISTORICAL
:
"
Disabled
"
}
status_str_to_ejbca
=
dict
((
v
,
k
)
for
k
,
v
in
status_ejbca_to_str
.
items
())
def
__init__
(
self
,
log
,
url
,
cert
=
None
,
key
=
None
,
def
__init__
(
self
,
log
,
url
,
cert
=
None
,
key
=
None
,
ca_name
=
""
,
certificate_profile_name
=
""
,
end_entity_profile_name
=
""
,
ca_name
=
""
,
certificate_profile_name
=
""
,
end_entity_profile_name
=
""
,
...
@@ -131,8 +90,15 @@ class EjbcaRegistry(object):
...
@@ -131,8 +90,15 @@ class EjbcaRegistry(object):
self
.
subject_dn_template
=
subject_dn_template
self
.
subject_dn_template
=
subject_dn_template
self
.
username_suffix
=
username_suffix
self
.
username_suffix
=
username_suffix
def
client_data
(
self
,
ejbca_data
):
ejbca_username
=
ejbca_data
[
"
username
"
]
username
=
ejbca_username
[:
-
len
(
self
.
username_suffix
)]
if
ejbca_username
.
endswith
(
self
.
username_suffix
)
else
ejbca_username
admins
=
[
u
if
not
u
.
startswith
(
"
RFC822NAME
"
)
else
u
[
11
:]
for
u
in
ejbca_data
[
"
subjectAltName
"
].
split
(
"
,
"
)]
status
=
self
.
status_ejbca_to_str
.
get
(
ejbca_data
[
"
status
"
],
"
Other
"
)
return
username
,
admins
,
status
,
None
,
ejbca_data
def
get_clients
(
self
):
def
get_clients
(
self
):
return
(
Ejbca
Client
(
registry
=
self
,
ejbca_data
=
data
)
for
data
in
self
.
ejbca
.
get_users
()
)
return
[
Client
(
*
self
.
client_
data
(
u
)
)
for
u
in
self
.
ejbca
.
get_users
()
]
def
get_client
(
self
,
name
):
def
get_client
(
self
,
name
):
users
=
self
.
ejbca
.
find_user
(
ejbcaws
.
MATCH_WITH_USERNAME
,
ejbcaws
.
MATCH_TYPE_EQUALS
,
name
+
self
.
username_suffix
)
users
=
self
.
ejbca
.
find_user
(
ejbcaws
.
MATCH_WITH_USERNAME
,
ejbcaws
.
MATCH_TYPE_EQUALS
,
name
+
self
.
username_suffix
)
...
@@ -140,35 +106,151 @@ class EjbcaRegistry(object):
...
@@ -140,35 +106,151 @@ class EjbcaRegistry(object):
raise
LookupError
(
"
%d users %s found (more than one?!)
"
%
(
len
(
users
),
name
))
raise
LookupError
(
"
%d users %s found (more than one?!)
"
%
(
len
(
users
),
name
))
if
not
users
:
if
not
users
:
return
None
return
None
return
Ejbca
Client
(
registry
=
self
,
ejbca
_data
=
users
[
0
])
return
Client
(
*
self
.
client
_data
(
users
[
0
])
)
def
new_client
(
self
,
name
,
admins
):
def
save_client
(
self
,
client
):
user
=
self
.
get_client
(
name
)
edata
=
client
.
opaque
or
dict
(
if
user
:
raise
LookupError
(
"
Client %s already exists
"
%
name
)
new_ejbca_data
=
dict
(
caName
=
self
.
ca_name
,
caName
=
self
.
ca_name
,
certificateProfileName
=
self
.
certificate_profile_name
,
certificateProfileName
=
self
.
certificate_profile_name
,
endEntityProfileName
=
self
.
end_entity_profile_name
,
endEntityProfileName
=
self
.
end_entity_profile_name
,
keyRecoverable
=
False
,
keyRecoverable
=
False
,
sendNotification
=
False
,
sendNotification
=
False
,
status
=
ejbcaws
.
STATUS_INITIALIZED
,
subjectAltName
=
""
,
subjectDN
=
""
,
tokenType
=
ejbcaws
.
TOKEN_TYPE_USERGENERATED
,
tokenType
=
ejbcaws
.
TOKEN_TYPE_USERGENERATED
,
username
=
""
,
password
=
""
.
join
((
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
dummy
in
range
(
16
))),
password
=
""
.
join
((
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
dummy
in
range
(
16
))),
clearPwd
=
True
clearPwd
=
True
,
username
=
client
.
name
+
self
.
username_suffix
,
subjectDN
=
self
.
subject_dn_template
%
client
.
name
)
)
client
=
EjbcaClient
(
registry
=
self
,
ejbca_data
=
new_ejbca_data
)
edata
[
"
subjectAltName
"
]
=
"
,
"
.
join
((
"
RFC822NAME=%s
"
%
a
for
a
in
client
.
admins
))
client
.
name
=
name
edata
[
"
status
"
]
=
self
.
status_str_to_ejbca
.
get
(
client
.
status
,
edata
[
"
status
"
])
client
.
admins
=
admins
if
client
.
pwd
:
return
client
edata
[
"
password
"
]
=
client
.
pwd
edata
[
"
clearPwd
"
]
=
True
self
.
ejbca
.
edit_user
(
edata
)
def
get_certs
(
self
,
client
):
return
self
.
ejbca
.
find_certs
(
client
.
opaque
[
"
username
"
],
validOnly
=
False
)
def
new_cert
(
self
,
client
,
csr
,
pwd
):
cert
=
self
.
ejbca
.
pkcs10_request
(
client
.
opaque
[
"
username
"
],
pwd
,
csr
,
0
,
ejbcaws
.
RESPONSETYPE_CERTIFICATE
)
return
cert
def
verbose
_str
(
self
):
def
_
_str
__
(
self
):
return
self
.
ejbca
.
get_version
()
return
self
.
ejbca
.
get_version
()
class
OpenSSLRegistry
(
object
):
def
__init__
(
self
,
log
,
base_dir
,
subject_dn_template
,
openssl_sign
,
lock_timeout
):
self
.
base_dir
=
base_dir
self
.
cnf_file
=
pth
.
join
(
base_dir
,
"
openssl.cnf
"
)
self
.
client_dir
=
pth
.
join
(
base_dir
,
"
clients
"
)
self
.
serial_file
=
pth
.
join
(
base_dir
,
"
serial
"
)
self
.
newcerts_dir
=
pth
.
join
(
base_dir
,
"
newcerts
"
)
self
.
csr_dir
=
pth
.
join
(
base_dir
,
"
csr
"
)
self
.
lock_file
=
pth
.
join
(
base_dir
,
"
lock
"
)
self
.
lock_timeout
=
lock_timeout
self
.
log
=
log
self
.
subject_dn_template
=
subject_dn_template
self
.
openssl_sign
=
openssl_sign
def
get_clients
(
self
):
return
[
self
.
get_client
(
c
)
for
c
in
os
.
listdir
(
self
.
client_dir
)
if
pth
.
isdir
(
pth
.
join
(
self
.
client_dir
,
c
))]
def
get_client
(
self
,
name
):
config
=
ConfigParser
.
RawConfigParser
()
if
not
config
.
read
(
pth
.
join
(
self
.
client_dir
,
name
,
"
state
"
)):
return
None
datum
=
dict
(
config
.
items
(
"
Client
"
))
return
Client
(
name
,
admins
=
datum
[
"
admins
"
].
split
(
"
,
"
),
status
=
datum
[
"
status
"
],
pwd
=
datum
.
get
(
"
password
"
))
def
new_client
(
self
,
name
,
admins
=
None
):
user
=
self
.
get_client
(
name
)
if
user
:
raise
LookupError
(
"
Client %s already exists
"
%
name
)
return
Client
(
name
,
admins
)
def
save_client
(
self
,
client
):
config
=
ConfigParser
.
RawConfigParser
()
config
.
add_section
(
"
Client
"
)
config
.
set
(
"
Client
"
,
"
admins
"
,
"
,
"
.
join
(
client
.
admins
))
config
.
set
(
"
Client
"
,
"
status
"
,
client
.
status
)
if
client
.
pwd
:
config
.
set
(
"
Client
"
,
"
password
"
,
client
.
pwd
)
client_path
=
pth
.
join
(
self
.
client_dir
,
client
.
name
)
try
:
os
.
makedirs
(
client_path
)
except
OSError
as
e
:
if
e
.
errno
!=
errno
.
EEXIST
:
raise
with
tempfile
.
NamedTemporaryFile
(
dir
=
client_path
,
delete
=
False
)
as
cf
:
config
.
write
(
cf
)
os
.
rename
(
cf
.
name
,
pth
.
join
(
client_path
,
"
state
"
))
# atomic + rewrite, so no need for locking
def
get_certs
(
self
,
client
):
files
=
[
fname
for
fname
in
os
.
listdir
(
pth
.
join
(
self
.
client_dir
,
client
.
name
))
if
not
fname
.
startswith
(
"
.
"
)
and
fname
.
endswith
(
"
.pem
"
)]
certs
=
[
M2Crypto
.
X509
.
load_cert
(
pth
.
join
(
self
.
client_dir
,
client
.
name
,
fname
))
for
fname
in
files
]
return
certs
def
__enter__
(
self
):
self
.
_lockfd
=
os
.
open
(
self
.
lock_file
,
os
.
O_CREAT
)
start
=
time
.
time
()
while
True
:
try
:
fcntl
.
flock
(
self
.
_lockfd
,
fcntl
.
LOCK_EX
|
fcntl
.
LOCK_NB
)
return
except
(
OSError
,
IOError
)
as
e
:
if
e
.
errno
!=
errno
.
EAGAIN
or
time
.
time
()
>
start
+
self
.
lock_timeout
:
raise
time
.
sleep
(
0.5
)
def
__exit__
(
self
,
type_
,
value
,
traceback
):
fcntl
.
flock
(
self
.
_lockfd
,
fcntl
.
LOCK_UN
)
os
.
close
(
self
.
_lockfd
)
try
:
os
.
unlink
(
self
.
lock_file
)
except
:
pass
def
run_openssl
(
self
,
command
,
**
kwargs
):
cmdline
=
shlex
.
split
(
command
%
kwargs
)
process
=
subprocess
.
Popen
(
cmdline
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
res
=
process
.
communicate
()
if
process
.
returncode
:
raise
PopenError
(
"
Popen returned nonzero code
"
,
process
.
returncode
,
'
'
.
join
(
cmdline
),
res
[
0
],
res
[
1
])
return
res
def
new_cert
(
self
,
client
,
csr
,
pwd
):
if
client
.
status
!=
"
Issuable
"
or
not
client
.
pwd
:
raise
ClientNotIssuableError
(
"
Client not allowed to issue request or password not set
"
)
if
client
.
pwd
!=
pwd
:
raise
AuthenticationError
(
"
Wrong credentials
"
)
dn
=
self
.
subject_dn_template
.
replace
(
"
/
"
,
"
//
"
).
replace
(
"
,
"
,
"
/
"
)
%
client
.
name
if
not
dn
.
startswith
(
"
/
"
):
dn
=
"
/
"
+
dn
with
tempfile
.
NamedTemporaryFile
(
dir
=
self
.
csr_dir
,
delete
=
False
)
as
csr_file
:
csr_file
.
write
(
csr
)
with
self
:
# lock dance
with
open
(
self
.
serial_file
)
as
f
:
serial
=
f
.
read
().
strip
()
output
=
self
.
run_openssl
(
self
.
openssl_sign
,
cnf
=
self
.
cnf_file
,
csr
=
csr_file
.
name
,
dn
=
dn
)
self
.
log
.
debug
(
output
)
os
.
rename
(
csr_file
.
name
,
pth
.
join
(
self
.
csr_dir
,
serial
+
"
.csr.pem
"
))
client_pem_name
=
pth
.
join
(
self
.
client_dir
,
client
.
name
,
serial
+
"
.cert.pem
"
)
os
.
symlink
(
pth
.
join
(
self
.
newcerts_dir
,
serial
+
"
.pem
"
),
client_pem_name
)
with
open
(
client_pem_name
)
as
pem
:
cert
=
M2Crypto
.
X509
.
load_cert_string
(
pem
.
read
(),
M2Crypto
.
X509
.
FORMAT_PEM
)
client
.
update
(
status
=
"
Passive
"
,
pwd
=
None
)
self
.
save_client
(
client
)
return
cert
def
__str__
(
self
):
return
"
%s<%s>
"
%
(
type
(
self
).
__name__
,
self
.
base_dir
)
def
format_cert
(
cert
):
def
format_cert
(
cert
):
return
(
return
(
"
Subject: %s
\n
"
"
Subject: %s
\n
"
...
@@ -186,6 +268,7 @@ def format_cert(cert):
...
@@ -186,6 +268,7 @@ def format_cert(cert):
cert
.
get_issuer
().
as_text
()
cert
.
get_issuer
().
as_text
()
)
)
# Server side
# Server side
class
OptionalAuthenticator
(
ObjectBase
):
class
OptionalAuthenticator
(
ObjectBase
):
...
@@ -242,21 +325,21 @@ class CertHandler(ObjectBase):
...
@@ -242,21 +325,21 @@ class CertHandler(ObjectBase):
client
=
self
.
registry
.
get_client
(
name
[
0
])
client
=
self
.
registry
.
get_client
(
name
[
0
])
if
not
client
:
if
not
client
:
raise
self
.
req
.
error
(
message
=
"
Unknown client
"
,
error
=
403
,
name
=
name
,
password
=
password
)
raise
self
.
req
.
error
(
message
=
"
Unknown client
"
,
error
=
403
,
name
=
name
,
password
=
password
)
self
.
log
.
info
(
"
Client %s
"
%
client
.
name
)
self
.
log
.
info
(
"
Client %s
"
%
client
)
if
self
.
req
.
client
==
"
cert
"
:
if
self
.
req
.
client
==
"
cert
"
:
# Correctly authenticated by cert, most probably not preactivated with password,
# Correctly authenticated by cert, most probably not preactivated with password,
# so generate oneshot password and allow now
# so generate oneshot password and allow now
password
=
""
.
join
((
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
dummy
in
range
(
16
)))
password
=
""
.
join
((
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
dummy
in
range
(
16
)))
self
.
log
.
debug
(
"
Authorized by X509, enabling cert generation with password %s
"
%
password
)
self
.
log
.
debug
(
"
Authorized by X509, enabling cert generation with password %s
"
%
password
)
try
:
try
:
client
.
allow_new_cert
(
pwd
=
password
)
client
.
update
(
status
=
"
Issuable
"
,
pwd
=
password
)
self
.
registry
.
save_client
(
client
)
except
ClientDisabledError
as
e
:
except
ClientDisabledError
as
e
:
raise
self
.
req
.
error
(
message
=
"
Error enabling cert generation
"
,
error
=
403
,
exc
=
sys
.
exc_info
())
raise
self
.
req
.
error
(
message
=
"
Error enabling cert generation
"
,
error
=
403
,
exc
=
sys
.
exc_info
())
client
.
save
()
if
not
password
:
if
not
password
:
raise
self
.
req
.
error
(
message
=
"
Missing password and certificate validation failed
"
,
error
=
403
,
name
=
name
,
password
=
password
)
raise
self
.
req
.
error
(
message
=
"
Missing password and certificate validation failed
"
,
error
=
403
,
name
=
name
,
password
=
password
)
try
:
try
:
newcert
=
client
.
new_cert
(
csr_data
,
password
)
newcert
=
self
.
registry
.
new_cert
(
client
,
csr_data
,
password
)
except
Exception
as
e
:
except
Exception
as
e
:
raise
self
.
req
.
error
(
message
=
"
Processing error
"
,
error
=
403
,
exc
=
sys
.
exc_info
())
raise
self
.
req
.
error
(
message
=
"
Processing error
"
,
error
=
403
,
exc
=
sys
.
exc_info
())
self
.
log
.
info
(
"
Generated.
"
)
self
.
log
.
info
(
"
Generated.
"
)
...
@@ -272,7 +355,7 @@ section_order = ("log", "auth", "registry", "handler", "server")
...
@@ -272,7 +355,7 @@ section_order = ("log", "auth", "registry", "handler", "server")
section_def
=
{
section_def
=
{
"
log
"
:
[
FileLogger
,
SysLogger
],
"
log
"
:
[
FileLogger
,
SysLogger
],
"
auth
"
:
[
OptionalAuthenticator
],
"
auth
"
:
[
OptionalAuthenticator
],
"
registry
"
:
[
EjbcaRegistry
],
"
registry
"
:
[
OpenSSLRegistry
,
EjbcaRegistry
],
"
handler
"
:
[
CertHandler
],
"
handler
"
:
[
CertHandler
],
"
server
"
:
[
Server
]
"
server
"
:
[
Server
]
}
}
...
@@ -286,11 +369,18 @@ param_def = {
...
@@ -286,11 +369,18 @@ param_def = {
"
req
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
req
"
},
"
req
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
req
"
},
"
log
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
log
"
}
"
log
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
log
"
}
},
},
OpenSSLRegistry
:
{
"
log
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
log
"
},
"
base_dir
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
pth
.
join
(
pth
.
dirname
(
__file__
),
"
ca
"
)},
"
subject_dn_template
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
DC=cz,DC=example-ca,DC=warden,CN=%s
"
},
"
openssl_sign
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
openssl ca -config %(cnf)s -batch -extensions server_cert -days 375 -notext -md sha256 -in %(csr)s -subj
'
%(dn)s
'"
},
"
lock_timeout
"
:
{
"
type
"
:
"
natural
"
,
"
default
"
:
"
3
"
}
},
EjbcaRegistry
:
{
EjbcaRegistry
:
{
"
log
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
log
"
},
"
log
"
:
{
"
type
"
:
"
obj
"
,
"
default
"
:
"
log
"
},
"
url
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
https://ejbca.example.org/ejbca/ejbcaws/ejbcaws?wsdl
"
},
"
url
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
https://ejbca.example.org/ejbca/ejbcaws/ejbcaws?wsdl
"
},
"
cert
"
:
{
"
type
"
:
"
filepath
"
,
"
default
"
:
os
.
pa
th
.
join
(
os
.
pa
th
.
dirname
(
__file__
),
"
warden_ra.cert.pem
"
)},
"
cert
"
:
{
"
type
"
:
"
filepath
"
,
"
default
"
:
p
th
.
join
(
p
th
.
dirname
(
__file__
),
"
warden_ra.cert.pem
"
)},
"
key
"
:
{
"
type
"
:
"
filepath
"
,
"
default
"
:
os
.
pa
th
.
join
(
os
.
pa
th
.
dirname
(
__file__
),
"
warden_ra.key.pem
"
)},
"
key
"
:
{
"
type
"
:
"
filepath
"
,
"
default
"
:
p
th
.
join
(
p
th
.
dirname
(
__file__
),
"
warden_ra.key.pem
"
)},
"
ca_name
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
Example CA
"
},
"
ca_name
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
Example CA
"
},
"
certificate_profile_name
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
Example
"
},
"
certificate_profile_name
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
Example
"
},
"
end_entity_profile_name
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
Example EE
"
},
"
end_entity_profile_name
"
:
{
"
type
"
:
"
str
"
,
"
default
"
:
"
Example EE
"
},
...
@@ -304,7 +394,7 @@ param_def = {
...
@@ -304,7 +394,7 @@ param_def = {
}
}
}
}
param_def
[
FileLogger
][
"
filename
"
]
=
{
"
type
"
:
"
filepath
"
,
"
default
"
:
os
.
pa
th
.
join
(
os
.
pa
th
.
dirname
(
__file__
),
os
.
pa
th
.
splitext
(
os
.
pa
th
.
split
(
__file__
)[
1
])[
0
]
+
"
.log
"
)}
param_def
[
FileLogger
][
"
filename
"
]
=
{
"
type
"
:
"
filepath
"
,
"
default
"
:
p
th
.
join
(
p
th
.
dirname
(
__file__
),
p
th
.
splitext
(
p
th
.
split
(
__file__
)[
1
])[
0
]
+
"
.log
"
)}
def
build_server
(
conf
):
def
build_server
(
conf
):
...
@@ -313,36 +403,33 @@ def build_server(conf):
...
@@ -313,36 +403,33 @@ def build_server(conf):
# Command line
# Command line
def
list_clients
(
registry
,
name
=
None
,
verbose
=
False
):
def
list_clients
(
registry
,
name
=
None
,
verbose
=
False
,
show_cert
=
True
):
if
name
is
not
None
:
if
name
is
not
None
:
client
=
registry
.
get_client
(
name
)
client
=
registry
.
get_client
(
name
)
if
client
is
None
:
if
client
is
None
:
print
"
No such client.
"
print
"
No such client.
"
return
return
else
:
else
:
print
(
client
)
print
(
client
.
str
(
verbose
))
if
verbose
:
if
show_cert
:
print
(
client
.
verbose_str
())
for
cert
in
sorted
(
registry
.
get_certs
(
client
),
key
=
lambda
c
:
c
.
get_not_after
().
get_datetime
()):
for
cert
in
sorted
(
client
.
get_certs
(),
key
=
lambda
c
:
c
.
get_not_after
().
get_datetime
()):
print
(
format_cert
(
cert
))
print
(
format_cert
(
cert
))
if
verbose
:
if
verbose
:
print
(
cert
.
as_text
())
print
(
cert
.
as_text
())
else
:
else
:
clients
=
registry
.
get_clients
()
clients
=
registry
.
get_clients
()
for
client
in
sorted
(
clients
,
key
=
lambda
c
:
c
.
name
):
for
client
in
sorted
(
clients
,
key
=
operator
.
attrgetter
(
"
name
"
)):
print
(
client
)
print
(
client
.
str
(
verbose
))
if
verbose
:
print
(
client
.
verbose_str
())
def
register_client
(
registry
,
name
,
admins
=
None
,
verbose
=
False
):
def
register_client
(
registry
,
name
,
admins
=
None
,
verbose
=
False
):
try
:
try
:
client
=
registry
.
new_client
(
name
,
admins
or
[]
)
client
=
registry
.
new_client
(
name
,
admins
)
except
LookupError
as
e
:
except
LookupError
as
e
:
print
(
e
)
print
(
e
)
return
return
client
.
save
(
)
registry
.
save_client
(
client
)
list_clients
(
registry
,
name
,
verbose
)
list_clients
(
registry
,
name
,
verbose
,
show_cert
=
False
)
def
applicant
(
registry
,
name
,
password
=
None
,
verbose
=
False
):
def
applicant
(
registry
,
name
,
password
=
None
,
verbose
=
False
):
...
@@ -353,12 +440,12 @@ def applicant(registry, name, password=None, verbose=False):
...
@@ -353,12 +440,12 @@ def applicant(registry, name, password=None, verbose=False):
if
password
is
None
:
if
password
is
None
:
password
=
""
.
join
((
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
dummy
in
range
(
16
)))
password
=
""
.
join
((
random
.
choice
(
string
.
ascii_letters
+
string
.
digits
)
for
dummy
in
range
(
16
)))
try
:
try
:
client
.
allow_new_cert
(
pwd
=
password
)
client
.
update
(
status
=
"
Issuable
"
,
pwd
=
password
)
except
ClientDisabledError
:
except
ClientDisabledError
:
print
"
This client is disabled. Use
'
enable
'
first.
"
print
"
This client is disabled. Use
'
enable
'
first.
"
return
return
client
.
save
(
)
registry
.
save_client
(
client
)
list_clients
(
registry
,
name
,
verbose
)
list_clients
(
registry
,
name
,
verbose
,
show_cert
=
False
)
print
(
"
Application password is: %s
\n
"
%
password
)
print
(
"
Application password is: %s
\n
"
%
password
)
...
@@ -367,9 +454,9 @@ def enable(registry, name, verbose=False):
...
@@ -367,9 +454,9 @@ def enable(registry, name, verbose=False):
if
not
client
:
if
not
client
:
print
"
No such client.
"
print
"
No such client.
"
return
return
client
.
enabled
=
True
client
.
update
(
status
=
"
Passive
"
)
client
.
save
(
)
registry
.
save_client
(
client
)
list_clients
(
registry
,
name
,
verbose
)
list_clients
(
registry
,
name
,
verbose
,
show_cert
=
False
)
def
disable
(
registry
,
name
,
verbose
=
False
):
def
disable
(
registry
,
name
,
verbose
=
False
):
...
@@ -377,9 +464,9 @@ def disable(registry, name, verbose=False):
...
@@ -377,9 +464,9 @@ def disable(registry, name, verbose=False):
if
not
client
:
if
not
client
:
print
"
No such client.
"
print
"
No such client.
"
return
return
client
.
enabled
=
False
client
.
update
(
status
=
"
Disabled
"
)
client
.
save
(
)
registry
.
save_client
(
client
)
list_clients
(
registry
,
name
,
verbose
)
list_clients
(
registry
,
name
,
verbose
,
show_cert
=
False
)
def
request
(
registry
,
key
,
csr
,
verbose
=
False
):
def
request
(
registry
,
key
,
csr
,
verbose
=
False
):
...
@@ -409,7 +496,7 @@ def gen_cert(registry, name, csr, cert, password, verbose=False):
...
@@ -409,7 +496,7 @@ def gen_cert(registry, name, csr, cert, password, verbose=False):
with
open
(
csr
,
"
r
"
)
as
f
:
with
open
(
csr
,
"
r
"
)
as
f
:
csr_data
=
f
.
read
()
csr_data
=
f
.
read
()
client
=
registry
.
get_client
(
name
)
client
=
registry
.
get_client
(
name
)
newcert
=
client
.
new_cert
(
csr_data
,
password
)
newcert
=
registry
.
new_cert
(
client
,
csr_data
,
password
)
print
(
format_cert
(
newcert
))
print
(
format_cert
(
newcert
))
if
verbose
:
if
verbose
:
print
(
newcert
.
as_text
())
print
(
newcert
.
as_text
())
...
@@ -510,7 +597,7 @@ def get_args():
...
@@ -510,7 +597,7 @@ def get_args():
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
args
=
get_args
()
args
=
get_args
()
config
=
os
.
pa
th
.
join
(
os
.
pa
th
.
dirname
(
__file__
),
args
.
config
or
"
warden_ra.cfg
"
)
config
=
p
th
.
join
(
p
th
.
dirname
(
__file__
),
args
.
config
or
"
warden_ra.cfg
"
)
server
=
build_server
(
read_cfg
(
config
))
server
=
build_server
(
read_cfg
(
config
))
registry
=
server
.
handler
.
registry
registry
=
server
.
handler
.
registry
if
args
.
verbose
:
if
args
.
verbose
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment