[Git][NTPsec/ntpsec][master] 2 commits: Adding attic/samba/*, debugging hacks for MS-SNTP

Hal Murray (@hal.murray) gitlab at mg.gitlab.com
Mon Nov 13 07:42:23 UTC 2023



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
f2b39a15 by Hal Murray at 2023-11-12T23:42:02-08:00
Adding attic/samba/*, debugging hacks for MS-SNTP

- - - - -
42deba21 by Hal Murray at 2023-11-12T23:42:02-08:00
Update HOWTO-OpenSSL to OpenSSL 3.2.0

- - - - -


7 changed files:

- HOWTO-OpenSSL
- + attic/samba/Makefile
- + attic/samba/README
- + attic/samba/fake-ntp-client.c
- + attic/samba/fake-ntp-server.c
- + attic/samba/fake-samba.c
- + attic/samba/fake.h


Changes:

=====================================
HOWTO-OpenSSL
=====================================
@@ -2,8 +2,8 @@ NTS needs TLS 1.3 or newer.
 That was first supported in OpenSSL 1.1.1
   (1.1.1a is broken)
 Some OSes/Distros don't support a new enough version of OpenSSL
-This file contains notes on how to download, build, and install 1.1.1m
-It also works for testing 3.0.1
+This file contains notes on how to download, build, and install 3.2.0
+It it should be close for other 3.x.y versions
 
 It's rough.  Don't be surprised by bugs/oversights.
 Corrections, clarifications and feedback encouraged.
@@ -11,15 +11,12 @@ Corrections, clarifications and feedback encouraged.
 FreeBSD 13.0 has OpenSSL 3.0.2 available as a package.
 You can just install it and ignore the rest of this note.
   sudo pkg update
-  sudo pkg install openssl-devel-3.0.2
-openssl-devel-3.0.2            TLSv1.3 capable SSL and crypto library
-
-
+  sudo pkg install openssl-devel-3.0.8
+openssl-devel-3.0.8            TLSv1.3 capable SSL and crypto library
 
 
 Download OpenSSL source from here:
   https://www.openssl.org/source/
-  https://www.openssl.org/source/old/1.1.1/
 
 You should be able to cut/paste many of these lines.
 But check for the latest versions first.
@@ -27,14 +24,10 @@ But check for the latest versions first.
 cd xxx
 mkdir OpenSSL
 cd OpenSSL
-for OpenSSL 1.1.1m
-  wget https://www.openssl.org/source/openssl-1.1.1m.tar.gz
-  tar -xzf openssl-1.1.1m.tar.gz
-  cd openssl-1.1.1m
-for OpenSSL 3.0.1
-  wget https://www.openssl.org/source/openssl-3.0.1.tar.gz
-  tar -xzf openssl-3.0.1.tar.gz
-  cd openssl-3.0.1
+for OpenSSL 3.2.0
+  wget https://www.openssl.org/source/openssl-3.2.0.tar.gz
+  tar -xzf openssl-3.2.0.tar.gz
+  cd openssl-3.2.0
 
 # Check NOTES.PERL
 #   for CentOS, you need
@@ -50,6 +43,17 @@ for OpenSSL 3.0.1
 # On FreeBSD for 3.0.1
   sudo pkg install perl5
 
+By default, this recipe will install
+  libcrypto.so.3 and libsso.so.3
+  in /usr/local/ssh/lib64/
+and they will be used by all software, not just ntpd.
+
+If you don't want that, edit VERSION.dat and change SHLIB_VERSION
+to something like 6.  That will install the libraries as
+  libcrypto.so.6 and libsso.so.6
+and waf will setup ntpd to use them.
+openssl-3.2-beta breaks sudo on Fedora, so this is a good idea.   <======
+
 On Linux
   openssl version -d
   OPENSSLDIR=`openssl version -d | sed "s/OPENSSLDIR: //"`
@@ -63,28 +67,27 @@ On Linux
 ***                                                                ***
 ***       perl configdata.pm --dump                                ***
 
-time make -j4
+time make -j4         |& tee make.log
   # Check that we got it right.  These should match.
   openssl version -d
-  util/shlib_wrap.sh ./apps/openssl version -d
+  ./util/shlib_wrap.sh ./apps/openssl version -d
   # ./apps/openssl without the wrapper will use the installed libraries
-time make test
-time make build_docs  # doesn't work on 1.1.1
-sudo make install
+The above check is broken for openssl-3.2.0-beta1 on Fedora
+It works on Ubuntu and FreeBSD.
+
+time make test        |& tee test.log
+time make build_docs  |& tee docs.log
+sudo make install     |& tee install.log
 
 sudo su
   cd /etc/ld.so.conf.d
-  echo "/usr/local/ssl/lib" > openssl-1.1.1m.conf
-  echo "/usr/local/ssl/lib" > openssl-3.0.1.conf    # 32 bit systems
-  echo "/usr/local/ssl/lib64" > openssl-3.0.1.conf  # 64 bit systems
+  echo "/usr/local/ssl/lib" > openssl-3.2.0.conf    # 32 bit systems
+  echo "/usr/local/ssl/lib64" > openssl-3.2.0.conf  # 64 bit systems
   # running ldconfig before install doesn't work
   ldconfig
 
-On FreeBSD, I couldn't figure out how it is supposed to work.
-  Probably, I just need the magic to ldconfig.
-  echo "/usr/local/ssl/lib" >> /etc/ld-elf.so.conf
-  reboot
-or something close to that.
+On FreeBSD:
+  ldconfig -m /usr/local/ssl/lib/
 
 NetBSD:
   echo "/usr/local/ssl/lib" >> /etc/ld.so.conf
@@ -97,10 +100,3 @@ NetBSD:
 # match where wscript looks for your OS.
 # The above works for CentOS 7
 
-----------
-
-On earlier versions of the Configure step (above)
-Fedora and CentOS 7 needed this if you use real certificates:
-  nts ca /etc/pki/tls/certs/ca-bundle.trust.crt
-It works correctly now.
-


=====================================
attic/samba/Makefile
=====================================
@@ -0,0 +1,24 @@
+# Hi
+
+
+PROGS = fake-samba fake-ntp-server fake-ntp-client
+
+# Compiler flags
+CFLAGS = -O1 -Wall -Wstrict-prototypes -Wmissing-prototypes
+
+all: \
+	$(PROGS)
+
+clean:
+	rm $(PROGS)
+
+fake-samba: fake.h fake-samba.c
+	cc $(CFLAGS) -g -o fake-samba fake-samba.c
+
+fake-ntp-server: fake.h fake-ntp-server.c
+	cc $(CFLAGS) -g -o fake-ntp-server fake-ntp-server.c
+
+fake-ntp-client: fake.h fake-ntp-client.c
+	cc $(CFLAGS) -g -o fake-ntp-client fake-ntp-client.c
+
+


=====================================
attic/samba/README
=====================================
@@ -0,0 +1,41 @@
+This is a set of hacks for use when debugging ntpd's MS-SNTP option.
+
+The default is off.
+Use --enable-mssntp with ./waf configure to build a system with that option.
+
+make in .../attic/samba should build them.
+make clean will clean things up.
+
+fake-samba acts like a Samba server.  It will sign packets with a constant.
+That's not real authentication, but it goes through all protocol actions.
+It prints a line for each packet it processes.
+
+fake-ntp-server generates traffic for fake-samba.  It's much simpler/faster
+than using ntpd to generate traffic.
+
+fake-ntp-client generates MS-SNTP traffic for an NTP server.  If you setup
+ntpd connected to fake-samba, this will generate traffic that should get
+all the way to/through fake-samba and back.
+
+fake-ntp-client needs a command line parameter: the name of the ntp server.
+Optional extra paramters are the number of packets to send (default 1) and
+the time to wait between packets in microseconds (default 1000).
+
+This can also be used to generate buggy traffic to Samba.  The keyid
+is unlikely to be anything Samba knows about.
+
+It doesn't work with IPv6.
+
+fake.h has "murray" wired in as part of the name of the UNIX socket
+connecting ntpd and (fake-)samba.  "tmp" didn't work on Fedora.  Systemd
+gives ntpd its own tmp directory.
+
+Your ntp.conf will need something like this:
+  ntpsigndsocket  /home/murray/fake-samba-socket
+  restrict 192.168.1.2 mssntp
+
+Note that ntpd adds "/socket" to the name from the config file.
+
+
+These are simple hacks.  Look at the code and fix it to do what you want.
+


=====================================
attic/samba/fake-ntp-client.c
=====================================
@@ -0,0 +1,119 @@
+/*  Last modified on Sat Jan  6 00:11:51 PST 2001 by murray  */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include "fake.h"
+
+char* host = "time.example.com";// First arg
+int packets = 1;		// Second arg
+int delay = 1000;		// Third arg, microseconds after each packet
+
+int sock;
+struct ntp_packet ntp_send, ntp_recv;
+
+void bailout(char *msg);
+
+void bailout(char *msg)
+{
+  int saverrr = errno;
+  char timetxt[100];
+  time_t nowbin;
+  struct tm nowstruct;
+  time(&nowbin);
+  localtime_r(&nowbin, &nowstruct);
+  strftime(timetxt, sizeof(timetxt), "%Y-%b-%d %H:%M", &nowstruct);
+  printf("** %s %s: errno = %d, %s\n",
+    timetxt, msg, saverrr, strerror(saverrr));
+  exit(1);
+};
+
+int main (int argc, char *argv[])
+{
+  struct hostent *target;
+  struct sockaddr_in server, client;
+  float timeout = 5.0;
+  struct timeval tv;
+  int addr;
+  int i, ec, len;
+
+  if (argc > 3) delay = atoi(argv[3]);
+  if (delay < 0) bailout("Bad delay");
+  if (argc > 2) packets = atoi(argv[2]);
+  if (packets <= 0) bailout("Bad packet count");
+
+  if (argc <= 1) bailout("Need host name");
+  host = argv[1];
+  target = gethostbyname(host);
+  if (target == NULL)
+    bailout("usage: xx <name-addr> [count [delay]]");
+
+  bcopy((char *)target->h_addr, (char *)&addr, sizeof(addr));
+  addr = ntohl(addr);
+  printf("Connecting to %s=>%d.%d.%d.%d\n",
+    host,
+    (addr >> 24) & 0xff,
+    (addr >> 16) & 0xff,
+    (addr >> 8) & 0xff,
+    (addr >> 0) & 0xff);
+
+  if (0) printf("Sending: len = %ld, header=%8x\n",
+    sizeof(ntp_send), ntp_send.header); 
+
+  bzero((char *)&server, sizeof(server));
+  bcopy((char *)target->h_addr, (char *)&server.sin_addr, target->h_length);
+  server.sin_family = target->h_addrtype;
+  server.sin_port = htons(123);
+
+  sock = socket(PF_INET, SOCK_DGRAM, 0);
+  if (sock < 0) bailout("socket");
+
+  bzero((char *)&client, sizeof(client));
+  client.sin_family = AF_INET;
+  client.sin_addr.s_addr = htonl(INADDR_ANY);
+  client.sin_port = htons(0);
+  
+  ec = bind(sock, (struct sockaddr *)&client, sizeof(client) );
+  if (ec) bailout("bind");
+  
+  ec = connect(sock, (struct sockaddr *)&server, sizeof(server) );
+  if (ec) bailout("connect");
+
+  tv.tv_sec = timeout;
+  tv.tv_usec = (timeout-tv.tv_sec)*1E6;
+  setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
+
+  ntp_send.header = htonl(0x23000000);
+  ntp_send.keyid = 56578;  
+
+  for (i = 0; i < packets; i++) {
+    struct timespec start, stop;
+    double elapsed;
+    ntp_send.t3.seconds = htonl(i);
+    ntp_send.t3.fraction = 0;
+    clock_gettime(CLOCK_MONOTONIC, &start);
+    len = send(sock, &ntp_send, sizeof(ntp_send), 0);
+    if (len != sizeof(ntp_send)) bailout("send");
+    len = recv(sock, &ntp_recv, sizeof(ntp_recv), 0);
+    if (len != sizeof(ntp_recv)) bailout("recv");
+    clock_gettime(CLOCK_MONOTONIC, &stop);
+    elapsed = (double)(stop.tv_sec-start.tv_sec);
+    elapsed += (double)(stop.tv_nsec-start.tv_nsec)/1E9;
+    printf("Signing took %.1f us\n", elapsed*1E6);
+    usleep(delay);
+  }
+  close(sock);
+  
+  return 0;
+}


=====================================
attic/samba/fake-ntp-server.c
=====================================
@@ -0,0 +1,114 @@
+/* fake-ntp-server.c
+ * fake NTP server to exersize fake-samba
+ * it won't work with real samba since we don't know any key-IDs
+ * so all it is good for is debugging fake-samba
+ */
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "fake.h"
+
+char *name = FAKE_SAMBA_SOCKET;
+
+int main(int argc, char *argv[]) {
+	struct timespec start, stop;
+	double elapsed;
+	int server;
+	struct sockaddr_un addr;
+	struct to_samba request;
+	struct from_samba reply;
+	int len;
+	uint32_t length, net_length, op;
+
+        clock_gettime(CLOCK_MONOTONIC, &start);
+
+	server = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (server == -1) {
+	  printf("## socket() failed: %s\n", strerror(errno));
+	  return 1;
+	}
+
+	bzero(&addr, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	strncpy(addr.sun_path, name, sizeof(addr.sun_path));
+
+	if (connect(server, (struct sockaddr *)&addr,
+		strlen(addr.sun_path) + sizeof(addr.sun_family)) <0) {
+	  printf("## connect() failed: %s\n", strerror(errno));
+	  return 2;
+	}
+
+	printf("Got connected...\n");
+
+	length = sizeof(request);
+	net_length = htonl(length);
+	len = write(server, &net_length, sizeof(net_length));
+	if (len != sizeof(net_length)) {
+	  printf("## write() length failed, len=%d: %s\n", len, strerror(errno));
+	  return 2;
+	}
+
+	/* Fill in request */
+	request.version = 0;
+	request.op = 0;
+	request.packet_id = HACK_PACKET_ID;
+	request.key_id = HACK_KEY_ID;
+	for (int i=0; i<LEN_PKT_NOMAC; i++) {
+	  request.pkt[i] = i;
+	}
+
+	len = write(server, &request, sizeof(request));
+	if (len != sizeof(request)) {
+	  printf("## write() body failed, len=%d: %s\n", len, strerror(errno));
+	  return 2;
+	}
+
+	len = read(server, &net_length, sizeof(net_length));
+	length = ntohl(net_length);
+	if (len != sizeof(net_length)) {
+	  printf("## read() length failed, len=%d: %s\n", len, strerror(errno));
+	  return 2;
+	}
+	len = read(server, &reply, sizeof(reply));
+	if (len != sizeof(reply)) {
+	  printf("## read() body failed, len=%d: %s\n", len, strerror(errno));
+	  return 2;
+	}
+
+	/* check stuff */
+	if (length != sizeof(reply)) {
+	  printf("** Wrong length word: %d\n", length);
+	}
+	op = ntohl(reply.op);
+	if (op != 3) {
+	  printf("** Wrong op field: %d\n", op);
+	}
+	if (reply.packet_id != HACK_PACKET_ID) {
+	  printf("** Wrong packet_id field: %d\n", reply.packet_id);
+	}
+	if (reply.key_id != HACK_KEY_ID) {
+	  printf("** Wrong key_id field: %d\n", reply.key_id);
+	}
+
+	if (memcmp(reply.pkt, request.pkt, sizeof(reply.pkt))) {
+	  printf("** pkt body mismatch\n");
+	  /* FIXME: print it out */
+	}
+
+        clock_gettime(CLOCK_MONOTONIC, &stop);
+	elapsed = (double)(stop.tv_sec-start.tv_sec);
+	elapsed += (double)(stop.tv_nsec-start.tv_nsec)/1E9;
+
+	printf("Signing took %.1f us\n", elapsed*1E6);
+	return 0;
+}
+


=====================================
attic/samba/fake-samba.c
=====================================
@@ -0,0 +1,146 @@
+/*
+ * fake-samba.c -- fake samba server to exercise MS-SNTP option.
+ */
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <sys/stat.h>
+
+
+#include "fake.h"
+
+char *name = FAKE_SAMBA_SOCKET;
+
+int main(int argc, char *argv[]) {
+	int listener;
+	struct sockaddr_un addr;
+	uint32_t length, net_length;
+
+	unlink(name);  /* Don't care if it fails. */
+
+	listener = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (listener == -1) {
+	  printf("## socket() failed: %s\n", strerror(errno));
+	  return 1;
+	}
+	
+	bzero(&addr, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	strncpy(addr.sun_path, name, sizeof(addr.sun_path));
+
+	if (bind(listener, (struct sockaddr *)&addr,
+		strlen(addr.sun_path) + sizeof(addr.sun_family)) <0) {
+	  printf("## bind() failed: %s\n", strerror(errno));
+	  return 2;
+	}
+	/* change mode so ntpd as user NTP can write to it */
+	if (chmod(name, 0777) < 0) {
+	  printf("## chmod() failed: %s\n", strerror(errno));
+	  return 3;
+	}
+
+
+	if (listen(listener, 6) < 0) {
+	  printf("## listen() failed: %s\n", strerror(errno));
+	  return 4;
+	}
+
+	for (int i=0; ; i++) {
+	  struct sockaddr_un who;
+	  socklen_t len = sizeof(who);
+	  int client;
+	  char buffer[100];
+	  struct to_samba request;
+	  struct from_samba reply;
+	  printf("## Waiting for a connection...\n");
+	  client = accept(listener, (struct sockaddr *)&who, &len);
+	  if (client < 0) {
+	    printf("## accept() failed: %s\n", strerror(errno));
+	    return 5;
+	  }
+	  printf("## Got one...  len=%d\n", len);
+
+	  len = read(client, &net_length, sizeof(net_length));
+	  if (len <0) {
+	    printf("## read() length failed: len=%d, %s\n", len, strerror(errno));
+	    return 6;
+	  }
+	  if (len != sizeof(net_length)) {
+	    printf("** Wrong length body read(), len=%d\n", len);
+	    close(client);
+	    printf("\n");
+	    continue;
+	  } else {
+	    printf("## read %d bytes\n", len);
+	    length = ntohl(net_length);
+	  }
+	  if (length != sizeof(request)) {
+	    printf("** Wrong length word: %d\n", length);
+	  }
+	  len = read(client, buffer, sizeof(buffer));
+	  if (len <0) {
+	    printf("## read() body failed: len=%d, %s\n", len, strerror(errno));
+	    return 6;
+	  }
+	  if (len != sizeof(request)) {
+	    printf("** Wrong length body read(), len=%d\n", len);
+	    close(client);
+	    printf("\n");
+	    continue;
+	  } else {
+	    printf("## read %d bytes\n", len);
+	    memcpy(&request, buffer, sizeof(request));
+	  }
+	  if (request.op != 0) {
+	    printf("** Wrong op field: %d\n", request.op);
+	  }
+
+	  /* construct reply */
+	  reply.version = request.version;
+	  reply.op = htonl(3);
+	  reply.packet_id = request.packet_id;
+	  memcpy(reply.pkt, request.pkt, sizeof(reply.pkt));
+	  reply.key_id = request.key_id;
+	  memcpy(reply.mac, HACK_KEY, sizeof(reply.mac));
+
+	  length = sizeof(reply);
+	  net_length = htonl(length);
+	  len = write(client, &net_length, sizeof(net_length));
+	  if (len <0) {
+	    printf("## write() length failed: len=%d, %s\n", len, strerror(errno));
+	    return 7;
+	  }
+	  if (len != sizeof(net_length)) {
+	    printf("## Wrong length write(),  len=%d\n", len);
+	  } else {
+	    printf("## wrote %d bytes\n", len);
+          }
+
+	  len = write(client, &reply, sizeof(reply));
+	  if (len <0) {
+	    printf("## write() body failed: len=%d, %s\n", len, strerror(errno));
+	    return 7;
+	  }
+	  if (len != sizeof(reply)) {
+	    printf("## Wrong length write(),  len=%d\n", len);
+	  } else {
+	    printf("## wrote %d bytes\n", len);
+          }
+	  close(client);
+	  printf("packet_id: %d, key_id: %d\n",
+	    request.packet_id, request.key_id);
+	  printf("\n");
+	}
+
+	printf("Working so far...\n");
+	return 0;
+}
+


=====================================
attic/samba/fake.h
=====================================
@@ -0,0 +1,50 @@
+#include <stdint.h>
+
+#define LEN_PKT_NOMAC 48
+#define LEN_MAC 16
+
+#define FAKE_SAMBA_SOCKET "/home/murray/fake-samba-socket/socket"
+
+#define HACK_PACKET_ID 123
+#define HACK_KEY_ID 3211
+#define HACK_KEY "ABCDEFGHIJKLMNOP"
+
+/* Microsoft says the key_id is little-endian
+ * We don't care.  We just pass it around.
+ */
+
+/* each of these is preceeded by a length word, network byte order */
+struct to_samba {
+  uint32_t version;
+  uint32_t op;
+  uint32_t packet_id;
+  uint32_t key_id;
+  char pkt[LEN_PKT_NOMAC];
+};
+
+struct from_samba {
+  uint32_t version;
+  uint32_t op; 
+  uint32_t packet_id;
+  char pkt[LEN_PKT_NOMAC];
+  uint32_t key_id;
+  char mac[LEN_MAC];
+};
+
+
+
+struct ntp_time {
+  uint32_t seconds;
+  uint32_t fraction;
+};
+
+struct ntp_packet {
+  uint32_t header;
+  uint32_t root_delay;
+  uint32_t root_dispersion;
+  uint32_t ref_id;
+  struct ntp_time t0, t1, t2, t3;
+  uint32_t keyid;
+  char auth[16];
+};
+



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/89c1a8e5abec2aa10a794061b49a0637aee6c37d...42deba21dd9f7b87ed4badc7633efe027273f951

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/89c1a8e5abec2aa10a794061b49a0637aee6c37d...42deba21dd9f7b87ed4badc7633efe027273f951
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20231113/d43a46c0/attachment-0001.htm>


More information about the vc mailing list