Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
python-rndc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
python-rndc
Commits
73d9e61e
Commit
73d9e61e
authored
Apr 25, 2017
by
Matthew Pounsett
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial import of rndc module
parent
11b34255
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
220 additions
and
0 deletions
+220
-0
README
README
+4
-0
rndc.py
rndc.py
+178
-0
setup.cfg
setup.cfg
+2
-0
setup.py
setup.py
+36
-0
No files found.
README
0 → 100644
View file @
73d9e61e
RNDC Protocol Library
This library implements the RNDC protocol natively in Python, to allow direct
control of BIND instances from within your Python programs.
rndc.py
0 → 100644
View file @
73d9e61e
############################################################################
# Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
############################################################################
# rndc.py
# This module implements the RNDC control protocol.
############################################################################
from
collections
import
OrderedDict
from
exceptions
import
TypeError
import
time
import
struct
import
hashlib
import
hmac
import
base64
import
random
import
socket
class
rndc
(
object
):
"""RNDC protocol client library"""
__algos
=
{
'md5'
:
157
,
'sha1'
:
161
,
'sha224'
:
162
,
'sha256'
:
163
,
'sha384'
:
164
,
'sha512'
:
165
}
def
__init__
(
self
,
host
,
algo
,
secret
):
"""Creates a persistent connection to RNDC and logs in
host - (ip, port) tuple
algo - HMAC algorithm, one of md5, sha1, sha224, sha256, sha384, sha512
secret - HMAC secret, base64 encoded"""
self
.
host
=
host
self
.
algo
=
algo
self
.
hlalgo
=
getattr
(
hashlib
,
algo
)
self
.
secret
=
base64
.
b64decode
(
secret
)
self
.
ser
=
random
.
randint
(
0
,
1
<<
24
)
self
.
nonce
=
None
self
.
__connect_login
()
def
call
(
self
,
cmd
):
"""Call a RNDC command, all parsing is done on the server side
cmd - a complete string with a command (eg 'reload zone example.com')
"""
return
dict
(
self
.
__command
(
type
=
cmd
)[
'_data'
])
def
__serialize_dict
(
self
,
data
,
ignore_auth
=
False
):
rv
=
''
for
k
,
v
in
data
.
iteritems
():
if
ignore_auth
and
k
==
'_auth'
:
continue
rv
+=
chr
(
len
(
k
))
rv
+=
k
if
type
(
v
)
==
str
:
rv
+=
struct
.
pack
(
'>BI'
,
1
,
len
(
v
))
+
v
elif
type
(
v
)
==
OrderedDict
:
sd
=
self
.
__serialize_dict
(
v
)
rv
+=
struct
.
pack
(
'>BI'
,
2
,
len
(
sd
))
+
sd
else
:
raise
NotImplementedError
(
'Cannot serialize element of type %s'
%
type
(
v
))
return
rv
def
__prep_message
(
self
,
*
args
,
**
kwargs
):
self
.
ser
+=
1
now
=
int
(
time
.
time
())
data
=
OrderedDict
(
*
args
,
**
kwargs
)
d
=
OrderedDict
()
d
[
'_auth'
]
=
OrderedDict
()
d
[
'_ctrl'
]
=
OrderedDict
()
d
[
'_ctrl'
][
'_ser'
]
=
str
(
self
.
ser
)
d
[
'_ctrl'
][
'_tim'
]
=
str
(
now
)
d
[
'_ctrl'
][
'_exp'
]
=
str
(
now
+
60
)
if
self
.
nonce
is
not
None
:
d
[
'_ctrl'
][
'_nonce'
]
=
self
.
nonce
d
[
'_data'
]
=
data
msg
=
self
.
__serialize_dict
(
d
,
ignore_auth
=
True
)
hash
=
hmac
.
new
(
self
.
secret
,
msg
,
self
.
hlalgo
).
digest
()
bhash
=
base64
.
b64encode
(
hash
)
if
self
.
algo
==
'md5'
:
d
[
'_auth'
][
'hmd5'
]
=
struct
.
pack
(
'22s'
,
bhash
)
else
:
d
[
'_auth'
][
'hsha'
]
=
struct
.
pack
(
'B88s'
,
self
.
__algos
[
self
.
algo
],
bhash
)
msg
=
self
.
__serialize_dict
(
d
)
msg
=
struct
.
pack
(
'>II'
,
len
(
msg
)
+
4
,
1
)
+
msg
return
msg
def
__verify_msg
(
self
,
msg
):
if
self
.
nonce
is
not
None
and
msg
[
'_ctrl'
][
'_nonce'
]
!=
self
.
nonce
:
return
False
bhash
=
msg
[
'_auth'
][
'hmd5'
if
self
.
algo
==
'md5'
else
'hsha'
]
bhash
+=
'='
*
(
4
-
(
len
(
bhash
)
%
4
))
remote_hash
=
base64
.
b64decode
(
bhash
)
my_msg
=
self
.
__serialize_dict
(
msg
,
ignore_auth
=
True
)
my_hash
=
hmac
.
new
(
self
.
secret
,
my_msg
,
self
.
hlalgo
).
digest
()
return
(
my_hash
==
remote_hash
)
def
__command
(
self
,
*
args
,
**
kwargs
):
msg
=
self
.
__prep_message
(
*
args
,
**
kwargs
)
sent
=
self
.
socket
.
send
(
msg
)
if
sent
!=
len
(
msg
):
raise
IOError
(
"Cannot send the message"
)
header
=
self
.
socket
.
recv
(
8
)
if
len
(
header
)
!=
8
:
# What should we throw here? Bad auth can cause this...
raise
IOError
(
"Can't read response header"
)
length
,
version
=
struct
.
unpack
(
'>II'
,
header
)
if
version
!=
1
:
raise
NotImplementedError
(
'Wrong message version %d'
%
version
)
# it includes the header
length
-=
4
data
=
self
.
socket
.
recv
(
length
,
socket
.
MSG_WAITALL
)
if
len
(
data
)
!=
length
:
raise
IOError
(
"Can't read response data"
)
msg
=
self
.
__parse_message
(
data
)
if
not
self
.
__verify_msg
(
msg
):
raise
IOError
(
"Authentication failure"
)
return
msg
def
__connect_login
(
self
):
self
.
socket
=
socket
.
create_connection
(
self
.
host
)
self
.
nonce
=
None
msg
=
self
.
__command
(
type
=
'null'
)
self
.
nonce
=
msg
[
'_ctrl'
][
'_nonce'
]
def
__parse_element
(
self
,
input
):
pos
=
0
labellen
=
ord
(
input
[
pos
])
pos
+=
1
label
=
input
[
pos
:
pos
+
labellen
]
pos
+=
labellen
type
=
ord
(
input
[
pos
])
pos
+=
1
datalen
=
struct
.
unpack
(
'>I'
,
input
[
pos
:
pos
+
4
])[
0
]
pos
+=
4
data
=
input
[
pos
:
pos
+
datalen
]
pos
+=
datalen
rest
=
input
[
pos
:]
if
type
==
1
:
# raw binary value
return
label
,
data
,
rest
elif
type
==
2
:
# dictionary
d
=
OrderedDict
()
while
len
(
data
)
>
0
:
ilabel
,
value
,
data
=
self
.
__parse_element
(
data
)
d
[
ilabel
]
=
value
return
label
,
d
,
rest
# TODO type 3 - list
else
:
raise
NotImplementedError
(
'Unknown element type %d'
%
type
)
def
__parse_message
(
self
,
input
):
rv
=
OrderedDict
()
hdata
=
None
while
len
(
input
)
>
0
:
label
,
value
,
input
=
self
.
__parse_element
(
input
)
rv
[
label
]
=
value
return
rv
setup.cfg
0 → 100644
View file @
73d9e61e
[bdist_wheel]
universal = 1
setup.py
0 → 100755
View file @
73d9e61e
"""
Pythin RNDC protocol library
A native python library that implements the RNDC protocol.
"""
from
setuptools
import
setup
,
find_packages
setup
(
name
=
"rndc"
,
version
=
"0.0.1"
,
description
=
"RNDC Protocol Library"
,
long_description
=
__doc__
,
keywords
=
"library DNS RNDC BIND"
,
author
=
""
,
author_email
=
""
,
license
=
""
,
classifiers
=
[
'Development Status :: 4 - Beta'
,
'Intended Audience :: Developers'
,
'Natural Language :: English'
,
'Operating System :: POSIX'
,
'Operating System :: Unix'
,
'Programming Language :: Python'
,
'Programming Language :: Python :: 2.7'
,
'Programming Language :: Python :: 3.6'
,
'Topic :: Internet :: Name Service (DNS)'
,
'Topic :: Software Development :: Libraries'
,
'Topic :: System :: Networking'
,
],
packages
=
find_packages
(),
install_requires
=
[],
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment