Skip to content
Commits on Source (2)
......@@ -33,17 +33,15 @@ pip install cx_Freeze
You may find that you also need to install the package 'patchelf'.
Change to the root directory of the NTPsec source distribution and
run the following commands:
run the following command:
```
cxfreeze ntpq/ntpq
cxfreeze ntpstats/ntpviz
cxfreeze ntpsweep/ntpsweep
cxfreeze ntptrace/ntptrace
waf cxfreeze
```
The four executables (pyntpq, ntpviz, ntpsweep, and ntptrace) will now
be in the directory named dist along with the other files required run.
Binary executables corresponding to every Python script will now be in
the directory named dist along with the other files required for them
to run.
You can copy the dist directory, and its contents, to a host that does
not have Python installed and execute the programs there.
......@@ -51,3 +49,5 @@ not have Python installed and execute the programs there.
There appears to be no speed advantage, or disadvantage, to running the
binaries created by cx_freeze.
// end
#!/usr/bin/env python
#
# ntpkeygen - program to generate cryptographic keys for ntp clients and servers
#
# All file names are like "ntpkey_<type>_<hostname>.<filestamp>", where
# <type> is the file type, <hostname> the generating host name and
# <filestamp> the generation time in NTP seconds. The NTP programs
# expect generic names such as "ntpkey_<type>_whimsy.udel.edu" with the
# association maintained by soft links. Following is a list of file
# types.
#
# ntpkey_MD5key_<hostname>.<filestamp>
# MD5 (128-bit) keys used to compute message digests in symmetric
# key cryptography
import os, sys, socket, random, time, getopt, stat
#
# Cryptodefines
#
MD5KEYS = 10 # number of keys generated of each type
MD5SIZE = 20 # maximum key size
def gen_md5(id, groupname):
"Generate semi-random MD5 and SHA1 keys compatible with NTPv3 and NTPv4."
with fheader("MD5key", id, groupname) as wp:
for i in range(1, MD5KEYS+1):
md5key = ""
for j in range(MD5SIZE):
while True:
r = randomizer.randint(0x21, 0x7e)
if r != ord('#'):
break
md5key += chr(r)
wp.write("%2d MD5 %s # MD5 key\n" % (i, md5key))
for i in range(1, MD5KEYS+1):
sha1key = ""
for j in range(MD5SIZE):
sha1key += "%02x" % randomizer.randint(0x00, 0xff)
wp.write("%2d SHA1 %s # SHA1 key\n" % (i + MD5KEYS, sha1key))
#
# Generate file header and link
#
def fheader(
file, # file name id
ulink, # linkname
owner # owner name
):
try:
filename = "ntpkey_%s_%s.%u" % (file, owner, int(time.time()))
orig_umask = os.umask(stat.S_IWGRP | stat.S_IRWXO)
wp = open(filename, "w")
os.umask(orig_umask)
linkname = "ntp.keys"
if os.path.exists(linkname):
os.remove(linkname) # The symlink() line below matters
os.symlink(filename, linkname)
sys.stderr.write("Generating new %s file and link\n" % ulink)
sys.stderr.write("%s->%s\n" % (linkname, filename))
wp.write("# %s\n# %s\n" % (filename, time.ctime()))
return wp
except IOError:
sys.stderr.write("Key file creation or link failed.\n")
raise SystemExit(1)
if __name__ == '__main__':
try:
(options, arguments) = getopt.getopt(sys.argv[1:], "hM:", ["help"])
except getopt.GetoptError as e:
print(e)
raise SystemExit(1)
for (switch, val) in options:
if switch == '-M':
# dummy MD5 option for backwards compatibility
pass
elif switch in ("-h", "--help"):
print("usage: ntpkeygen [-M]")
raise SystemExit(0)
randomizer = random.SystemRandom(time.time() + os.getpid())
gen_md5("md5", socket.gethostname())
raise SystemExit(0)
#end
/*
* Program to generate cryptographic keys for ntp clients and servers
*
* All file names are like "ntpkey_<type>_<hostname>.<filestamp>", where
* <type> is the file type, <hostname> the generating host name and
* <filestamp> the generation time in NTP seconds. The NTP programs
* expect generic names such as "ntpkey_<type>_whimsy.udel.edu" with the
* association maintained by soft links. Following is a list of file
* types.
*
* ntpkey_MD5key_<hostname>.<filestamp>
* MD5 (128-bit) keys used to compute message digests in symmetric
* key cryptography
*
* The OpenSSL library used by this program expects a random seed file.
* As described in the OpenSSL documentation, the file name defaults to
* first the RANDFILE environment variable in the user's home directory
* and then .rnd in the user's home directory.
*/
#include <config.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include "ntp.h"
#include "ntp_stdlib.h"
#include "ntp_assert.h"
#include "ntp_calendar.h"
#ifdef HAVE_OPENSSL
#include "openssl/bn.h"
#include "openssl/evp.h"
#include "openssl/err.h"
#include "openssl/rand.h"
#include "openssl/pem.h"
#include "openssl/x509v3.h"
#include <openssl/objects.h>
#endif /* HAVE_OPENSSL */
#include <sodium.h>
/*
* Cryptodefines
*/
#define MD5KEYS 10 /* number of keys generated of each type */
#define MD5SIZE 20 /* maximum key size */
/*
* Prototypes
*/
FILE *fheader (const char *, const char *, const char *);
bool gen_md5 (const char *);
/*
* Program variables
*/
extern char *optarg; /* command line argument */
char *progname;
time_t epoch; /* Unix epoch (seconds) since 1970 */
u_int fstamp; /* NTP filestamp */
char hostbuf[MAXHOSTNAME + 1];
char *hostname = NULL; /* host, used in cert filenames */
char *groupname = NULL; /* group name */
char filename[MAXFILENAME + 1]; /* file name */
#define ALL_OPTIONS "Mh"
static const struct option longoptions[] = {
{ "md5key", 0, 0, 'M' },
{ "help", 0, 0, 'h' },
{ NULL, 0, 0, '\0'},
};
/*
* Main program
*/
int
main(
int argc, /* command line options */
char **argv
)
{
struct timespec ts; /* initialization vector */
int op;
progname = argv[0];
init_lib();
#ifdef HAVE_OPENSSL
ssl_check_version();
#endif /* HAVE_OPENSSL */
sodium_init();
/*
* Process options, initialize host name and timestamp.
* gethostname() won't null-terminate if hostname is exactly the
* length provided for the buffer.
*/
gethostname(hostbuf, sizeof(hostbuf) - 1);
hostbuf[COUNTOF(hostbuf) - 1] = '\0';
hostname = hostbuf;
groupname = hostbuf;
clock_gettime(CLOCK_REALTIME, &ts);
epoch = ts.tv_sec;
fstamp = (u_int)(epoch + JAN_1970);
while ((op = ntp_getopt_long(argc, argv,
ALL_OPTIONS, longoptions, NULL)) != -1) {
switch (op) {
case 'M':
/* dummy MD5 option for backwards compatibility */
break;
case 'h':
fprintf(stderr, "usage: ntpkeygen [-M]\n" );
exit(0);
default:
fprintf(stderr, "usage: ntpkeygen [-M]\n" );
exit(1);
}
}
argc -= optind;
argv += optind;
#ifdef HAVE_OPENSSL
if (SSLeay() == SSLEAY_VERSION_NUMBER)
fprintf(stderr, "Using OpenSSL version %s\n",
SSLeay_version(SSLEAY_VERSION));
else
fprintf(stderr, "Built against OpenSSL %s, using version %s\n",
OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
#endif /* HAVE_OPENSSL */
gen_md5("md5");
exit(0);
}
/*
* Generate semi-random MD5 keys compatible with NTPv3 and NTPv4. Also,
* if OpenSSL is around, generate random SHA1 keys compatible with
* symmetric key cryptography.
*/
bool
gen_md5(
const char *id /* file name id */
)
{
uint8_t md5key[MD5SIZE + 1]; /* MD5 key */
FILE *str;
int i, j;
#ifdef HAVE_OPENSSL
uint8_t keystr[MD5SIZE];
uint8_t hexstr[2 * MD5SIZE + 1];
uint8_t hex[] = "0123456789abcdef";
#endif /* HAVE_OPENSSL */
str = fheader("MD5key", id, groupname);
for (i = 1; i <= MD5KEYS; i++) {
for (j = 0; j < MD5SIZE; j++) {
uint8_t temp;
while (1) {
randombytes_buf(
&temp, sizeof(temp));
if (temp == '#')
continue;
if (temp > 0x20 && temp < 0x7f)
break;
}
md5key[j] = temp;
}
md5key[j] = '\0';
fprintf(str, "%2d MD5 %s # MD5 key\n", i,
md5key);
}
#ifdef HAVE_OPENSSL
for (i = 1; i <= MD5KEYS; i++) {
RAND_bytes(keystr, sizeof(keystr));
for (j = 0; j < MD5SIZE; j++) {
hexstr[2 * j] = hex[keystr[j] >> 4];
hexstr[2 * j + 1] = hex[keystr[j] & 0xf];
}
hexstr[2 * MD5SIZE] = '\0';
fprintf(str, "%2d SHA1 %s # SHA1 key\n", i + MD5KEYS,
hexstr);
}
#endif /* HAVE_OPENSSL */
fclose(str);
return true;
}
/*
* Generate file header and link
*/
FILE *
fheader (
const char *file, /* file name id */
const char *ulink, /* linkname */
const char *owner /* owner name */
)
{
FILE *str; /* file handle */
char linkname[MAXFILENAME]; /* link name */
int temp;
mode_t orig_umask;
char ascbuf[BUFSIZ];
snprintf(filename, sizeof(filename), "ntpkey_%s_%s.%u", file,
owner, fstamp);
orig_umask = umask( S_IWGRP | S_IRWXO );
str = fopen(filename, "w");
(void) umask(orig_umask);
if (str == NULL) {
perror("Write");
exit (-1);
}
/* NAMECHANGE */
strlcpy(linkname,"ntp.keys",sizeof(linkname));
(void)remove(linkname); /* The symlink() line below matters */
temp = symlink(filename, linkname);
if (temp < 0)
perror(file);
fprintf(stderr, "Generating new %s file and link\n", ulink);
fprintf(stderr, "%s->%s\n", linkname, filename);
fprintf(str, "# %s\n# %s\n", filename, ctime_r(&epoch, ascbuf));
return (str);
}
from waflib import Utils
def build(ctx):
srcnode = ctx.srcnode.abspath()
bldnode = ctx.bldnode.abspath()
ntp_keygen_source = [
"ntpkeygen.c",
]
ctx(
target = "ntpkeygen",
features = "c cprogram bld_include src_include libisc_include",
source = ntp_keygen_source,
includes = [
"%s/ntpkeygen/" % bldnode,
"%s/libsodium/include/" % srcnode
],
# clock_gettime needs -lrt for glibc versions before 2.17
use = "ntp isc sodium RT M CRYPTO",
install_path= "${PREFIX}/bin/"
)
ctx.manpage(8, "ntpkeygen-man.txt")
......@@ -148,6 +148,15 @@ def linkmaker(ctx):
if ctx.cmd in ('install', 'build'):
os.system("ln -sf %s/libntp/ntpc.so %s/pylib/ntpc.so " % (bldnode, bldnode))
python_scripts = [
"ntpq/ntpq",
"ntpstats/ntpviz",
"ntptrace/ntptrace",
"ntpwait/ntpwait",
"ntpsweep/ntpsweep",
"ntpkeygen/ntpkeygen",
]
def build(ctx):
ctx.load('waf', tooldir='wafhelpers/')
ctx.load('bison')
......@@ -182,20 +191,12 @@ def build(ctx):
ctx.recurse("libsodium")
ctx.recurse("ntpd")
ctx.recurse("ntpfrob")
ctx.recurse("ntpkeygen")
ctx.recurse("ntptime")
ctx.recurse("pylib")
ctx.recurse("attic")
ctx.recurse("tests")
scripts = [
"ntpleapfetch/ntpleapfetch",
"ntpq/ntpq",
"ntpstats/ntpviz",
"ntptrace/ntptrace",
"ntpwait/ntpwait",
"ntpsweep/ntpsweep",
]
scripts = ["ntpleapfetch/ntpleapfetch"] + python_scripts
ctx(
features = "subst",
......@@ -212,6 +213,7 @@ def build(ctx):
ctx.manpage(1, "ntpstats/ntpviz-man.txt")
ctx.manpage(8, "ntpwait/ntpwait-man.txt")
ctx.manpage(1, "ntpsweep/ntpsweep-man.txt")
ctx.manpage(8, "ntpkeygen/ntpkeygen-man.txt")
# Skip running unit tests on a cross compile build
if not ctx.env.ENABLE_CROSS:
......@@ -251,6 +253,10 @@ def loccount(ctx):
"Report the SLOC count of the source tree."
ctx.exec_command("loccount -x=build .")
def cxfreeze(ctx):
"Create standalone binaries from Python scripts."
ctx.exec_command("for prog in " + " ".join(python_scripts) + "; do cxfreeze $prog; done")
# The following sets edit modes for GNU EMACS
# Local Variables:
# mode:python
......