diff options
Diffstat (limited to 'crypto/kerberosIV/appl/sample')
-rw-r--r-- | crypto/kerberosIV/appl/sample/Makefile.in | 83 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/sample/sample.h | 81 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/sample/sample_client.c | 168 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/sample/sample_server.c | 153 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/sample/simple.h | 14 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/sample/simple_client.c | 202 | ||||
-rw-r--r-- | crypto/kerberosIV/appl/sample/simple_server.c | 140 |
7 files changed, 841 insertions, 0 deletions
diff --git a/crypto/kerberosIV/appl/sample/Makefile.in b/crypto/kerberosIV/appl/sample/Makefile.in new file mode 100644 index 0000000..d88023a --- /dev/null +++ b/crypto/kerberosIV/appl/sample/Makefile.in @@ -0,0 +1,83 @@ +# $Id: Makefile.in,v 1.18 1999/03/10 19:01:13 joda Exp $ + +SHELL = /bin/sh + +srcdir = @srcdir@ +VPATH = @srcdir@ + +top_builddir = ../.. + +CC = @CC@ +LINK = @LINK@ +AR = ar +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ $(WFLAGS) +WFLAGS = @WFLAGS@ +LD_FLAGS = @LD_FLAGS@ +INSTALL = @INSTALL@ +LIBS = @LIBS@ +MKINSTALLDIRS = @top_srcdir@/mkinstalldirs + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +libexecdir = @libexecdir@ +bindir = @bindir@ +transform=@program_transform_name@ +EXECSUFFIX=@EXECSUFFIX@ + +PROG_BIN = sample_client$(EXECSUFFIX) \ + simple_client$(EXECSUFFIX) +PROG_LIBEXEC = sample_server$(EXECSUFFIX) \ + simple_server$(EXECSUFFIX) +PROGS = $(PROG_BIN) $(PROG_LIBEXEC) + +OBJECTS = sample_client.o sample_server.o simple_client.o simple_server.o +SOURCES = sample_client.c sample_server.c simple_client.c simple_server.c + +all: $(PROGS) + +Wall: + make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__" + +.c.o: + $(CC) -c $(DEFS) -I../../include -I$(srcdir) $(CFLAGS) $(CPPFLAGS) $< + +install: all + +uninstall: + +TAGS: $(SOURCES) + etags $(SOURCES) + +check: + +clean: + rm -f *.a *.o $(PROGS) + +mostlyclean: clean + +distclean: clean + rm -f Makefile *.tab.c *~ + +realclean: distclean + rm -f TAGS + +KLIB=-L../../lib/krb -lkrb -L../../lib/des -ldes +LIBROKEN=-L../../lib/roken -lroken + +sample_client$(EXECSUFFIX): sample_client.o + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ sample_client.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN) + +simple_client$(EXECSUFFIX): simple_client.o + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ simple_client.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN) + +sample_server$(EXECSUFFIX): sample_server.o + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ sample_server.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN) + +simple_server$(EXECSUFFIX): simple_server.o + $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ simple_server.o $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN) + +$(OBJECTS): ../../include/config.h + +.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean diff --git a/crypto/kerberosIV/appl/sample/sample.h b/crypto/kerberosIV/appl/sample/sample.h new file mode 100644 index 0000000..a5880ab --- /dev/null +++ b/crypto/kerberosIV/appl/sample/sample.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: sample.h,v 1.10 1998/06/13 00:06:49 assar Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <stdio.h> +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#include <errno.h> +#ifdef SOCKS +#include <socks.h> +/* This doesn't belong here. */ +struct tm *localtime(const time_t *); +struct hostent *gethostbyname(const char *); +#endif + +#include <err.h> +#include <krb.h> + +#include <roken.h> + +#define SAMPLE_PORT 6354 + +#define SAMPLE_SERVICE "sample" +#define SAMPLE_VERSION "VERSION9" diff --git a/crypto/kerberosIV/appl/sample/sample_client.c b/crypto/kerberosIV/appl/sample/sample_client.c new file mode 100644 index 0000000..8c45ae5 --- /dev/null +++ b/crypto/kerberosIV/appl/sample/sample_client.c @@ -0,0 +1,168 @@ +/* + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, + * please see the file <mit-copyright.h>. + * + * sample_client: + * A sample Kerberos client, which connects to a server on a remote host, + * at port "sample" (be sure to define it in /etc/services) + * and authenticates itself to the server. The server then writes back + * (in ASCII) the authenticated name. + * + * Usage: + * sample_client <hostname> <checksum> + * + * <hostname> is the name of the foreign host to contact. + * + * <checksum> is an integer checksum to be used for the call to krb_mk_req() + * and mutual authentication + * + */ + +#include "sample.h" + +RCSID("$Id: sample_client.c,v 1.19 1999/05/08 02:23:43 assar Exp $"); + +static void +usage (void) +{ + fprintf (stderr, "Usage: %s [-s service] [-p port] hostname checksum\n", + __progname); + exit (1); +} + +int +main(int argc, char **argv) +{ + struct hostent *hp; + struct sockaddr_in sin, lsin; + char *remote_host; + int status; + int namelen; + int sock = -1; + KTEXT_ST ticket; + char buf[512]; + long authopts; + MSG_DAT msg_data; + CREDENTIALS cred; + des_key_schedule sched; + u_int32_t cksum; + int c; + char service[SNAME_SZ]; + u_int16_t port; + struct servent *serv; + char **h_addr_list; + + set_progname (argv[0]); + strcpy_truncate (service, SAMPLE_SERVICE, sizeof(service)); + port = 0; + + while ((c = getopt(argc, argv, "s:p:")) != EOF) + switch(c) { + case 's' : + strcpy_truncate (service, optarg, sizeof(service)); + break; + case 'p' : + serv = getservbyname (optarg, "tcp"); + if (serv) + port = serv->s_port; + else + port = htons(atoi(optarg)); + break; + case '?' : + default : + usage(); + } + + argc -= optind; + argv += optind; + + if (argc != 2) + usage (); + + /* convert cksum to internal rep */ + cksum = atoi(argv[1]); + + printf("Setting checksum to %ld\n", (long)cksum); + + /* clear out the structure first */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + if (port) + sin.sin_port = port; + else + sin.sin_port = k_getportbyname (service, "tcp", htons(SAMPLE_PORT)); + + /* look up the server host */ + hp = gethostbyname(argv[0]); + if (hp == NULL) + errx (1, "gethostbyname(%s): %s", argv[0], + hstrerror(h_errno)); + + /* copy the hostname into non-volatile storage */ + remote_host = strdup(hp->h_name); + if (remote_host == NULL) + errx (1, "strdup: out of memory"); + + /* set up the address of the foreign socket for connect() */ + sin.sin_family = hp->h_addrtype; + + for (h_addr_list = hp->h_addr_list; + *h_addr_list; + ++h_addr_list) { + memcpy(&sin.sin_addr, *h_addr_list, sizeof(sin.sin_addr)); + fprintf (stderr, "Trying %s...\n", inet_ntoa(sin.sin_addr)); + + /* open a TCP socket */ + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) + err (1, "socket"); + + /* connect to the server */ + if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0) + break; + close (sock); + } + + if (*h_addr_list == NULL) + err (1, "connect"); + + /* find out who I am, now that we are connected and therefore bound */ + namelen = sizeof(lsin); + if (getsockname(sock, (struct sockaddr *) &lsin, &namelen) < 0) { + close (sock); + err (1, "getsockname"); + } + + /* call Kerberos library routine to obtain an authenticator, + pass it over the socket to the server, and obtain mutual + authentication. */ + + authopts = KOPT_DO_MUTUAL; + status = krb_sendauth(authopts, sock, &ticket, + service, remote_host, + NULL, cksum, &msg_data, &cred, + sched, &lsin, &sin, SAMPLE_VERSION); + if (status != KSUCCESS) + errx (1, "cannot authenticate to server: %s", + krb_get_err_text(status)); + + /* After we send the authenticator to the server, it will write + back the name we authenticated to. Read what it has to say. */ + status = read(sock, buf, sizeof(buf)); + if (status < 0) + errx(1, "read"); + + /* make sure it's null terminated before printing */ + if (status < sizeof(buf)) + buf[status] = '\0'; + else + buf[sizeof(buf) - 1] = '\0'; + + printf("The server says:\n%s\n", buf); + + close(sock); + return 0; +} diff --git a/crypto/kerberosIV/appl/sample/sample_server.c b/crypto/kerberosIV/appl/sample/sample_server.c new file mode 100644 index 0000000..a1a92d1 --- /dev/null +++ b/crypto/kerberosIV/appl/sample/sample_server.c @@ -0,0 +1,153 @@ +/* + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, + * please see the file <mit-copyright.h>. + * + * sample_server: + * A sample Kerberos server, which reads a ticket from a TCP socket, + * decodes it, and writes back the results (in ASCII) to the client. + * + * Usage: + * sample_server + * + * file descriptor 0 (zero) should be a socket connected to the requesting + * client (this will be correct if this server is started by inetd). + */ + +#include "sample.h" + +RCSID("$Id: sample_server.c,v 1.12 1999/03/10 18:33:53 joda Exp $"); + +static void +usage (void) +{ + fprintf (stderr, "Usage: %s [-i] [-s service] [-t srvtab]\n", + __progname); + exit (1); +} + +int +main(int argc, char **argv) +{ + struct sockaddr_in peername, myname; + int namelen = sizeof(peername); + int status, count, len; + long authopts; + AUTH_DAT auth_data; + KTEXT_ST clt_ticket; + des_key_schedule sched; + char instance[INST_SZ]; + char service[ANAME_SZ]; + char version[KRB_SENDAUTH_VLEN+1]; + char retbuf[512]; + char lname[ANAME_SZ]; + char srvtab[MaxPathLen]; + int c; + int no_inetd = 0; + + /* open a log connection */ + + set_progname (argv[0]); + + roken_openlog(__progname, LOG_ODELAY, LOG_DAEMON); + + strcpy_truncate (service, SAMPLE_SERVICE, sizeof(service)); + *srvtab = '\0'; + + while ((c = getopt (argc, argv, "s:t:i")) != EOF) + switch (c) { + case 's' : + strcpy_truncate (service, optarg, sizeof(service)); + break; + case 't' : + strcpy_truncate (srvtab, optarg, sizeof(srvtab)); + break; + case 'i': + no_inetd = 1; + break; + case '?' : + default : + usage (); + } + + if (no_inetd) + mini_inetd (htons(SAMPLE_PORT)); + + /* + * To verify authenticity, we need to know the address of the + * client. + */ + if (getpeername(STDIN_FILENO, + (struct sockaddr *)&peername, + &namelen) < 0) { + syslog(LOG_ERR, "getpeername: %m"); + return 1; + } + + /* for mutual authentication, we need to know our address */ + namelen = sizeof(myname); + if (getsockname(STDIN_FILENO, (struct sockaddr *)&myname, &namelen) < 0) { + syslog(LOG_ERR, "getsocknamename: %m"); + return 1; + } + + /* read the authenticator and decode it. Using `k_getsockinst' we + * always get the right instance on a multi-homed host. + */ + k_getsockinst (STDIN_FILENO, instance, sizeof(instance)); + + /* we want mutual authentication */ + authopts = KOPT_DO_MUTUAL; + status = krb_recvauth(authopts, STDIN_FILENO, &clt_ticket, + service, instance, &peername, &myname, + &auth_data, srvtab, + sched, version); + if (status != KSUCCESS) { + snprintf(retbuf, sizeof(retbuf), + "Kerberos error: %s\n", + krb_get_err_text(status)); + syslog(LOG_ERR, retbuf); + } else { + /* Check the version string (KRB_SENDAUTH_VLEN chars) */ + if (strncmp(version, SAMPLE_VERSION, KRB_SENDAUTH_VLEN)) { + /* didn't match the expected version */ + /* could do something different, but we just log an error + and continue */ + version[8] = '\0'; /* make sure null term */ + syslog(LOG_ERR, "Version mismatch: '%s' isn't '%s'", + version, SAMPLE_VERSION); + } + /* now that we have decoded the authenticator, translate + the kerberos principal.instance@realm into a local name */ + if (krb_kntoln(&auth_data, lname) != KSUCCESS) + strcpy_truncate(lname, + "*No local name returned by krb_kntoln*", + sizeof(lname)); + /* compose the reply */ + snprintf(retbuf, sizeof(retbuf), + "You are %s.%s@%s (local name %s),\n at address %s, version %s, cksum %ld\n", + auth_data.pname, + auth_data.pinst, + auth_data.prealm, + lname, + inet_ntoa(peername.sin_addr), + version, + (long)auth_data.checksum); + } + + /* write back the response */ + if ((count = write(0, retbuf, (len = strlen(retbuf) + 1))) < 0) { + syslog(LOG_ERR,"write: %m"); + return 1; + } else if (count != len) { + syslog(LOG_ERR, "write count incorrect: %d != %d\n", + count, len); + return 1; + } + + /* close up and exit */ + close(0); + return 0; +} diff --git a/crypto/kerberosIV/appl/sample/simple.h b/crypto/kerberosIV/appl/sample/simple.h new file mode 100644 index 0000000..17315b3 --- /dev/null +++ b/crypto/kerberosIV/appl/sample/simple.h @@ -0,0 +1,14 @@ +/* + * $Id: simple.h,v 1.3 1996/09/27 15:54:23 assar Exp $ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * Common definitions for the simple UDP-based Kerberos-mediated + * server & client applications. + */ + +#define SERVICE "sample" +#define HOST "bach" diff --git a/crypto/kerberosIV/appl/sample/simple_client.c b/crypto/kerberosIV/appl/sample/simple_client.c new file mode 100644 index 0000000..8769725 --- /dev/null +++ b/crypto/kerberosIV/appl/sample/simple_client.c @@ -0,0 +1,202 @@ +/* + * + * Copyright 1989 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * Simple UDP-based sample client program. For demonstration. + * This program performs no useful function. + */ + +#include "sample.h" +RCSID("$Id: simple_client.c,v 1.13 1998/06/09 19:24:39 joda Exp $"); + +#define MSG "hi, Jennifer!" /* message text */ + +static int +talkto(char *hostname, char *service, int port) +{ + int flags = 0; /* flags for sendto() */ + long len; + u_long cksum = 0L; /* cksum not used */ + char c_realm[REALM_SZ]; /* local Kerberos realm */ + char *s_realm; /* server's Kerberos realm */ + + KTEXT_ST k; /* Kerberos data */ + KTEXT ktxt = &k; + + int sock, i; + struct hostent *host; + struct sockaddr_in s_sock; /* server address */ + char myhostname[MaxHostNameLen]; /* local hostname */ + + /* for krb_mk_safe/priv */ + struct sockaddr_in c_sock; /* client address */ + CREDENTIALS c; /* ticket & session key */ + CREDENTIALS *cred = &c; + + /* for krb_mk_priv */ + des_key_schedule sched; /* session key schedule */ + + /* Look up server host */ + if ((host = gethostbyname(hostname)) == NULL) { + fprintf(stderr, "%s: unknown host \n", hostname); + return 1; + } + + /* Set server's address */ + memset(&s_sock, 0, sizeof(s_sock)); + memcpy(&s_sock.sin_addr, host->h_addr, sizeof(s_sock.sin_addr)); + s_sock.sin_family = AF_INET; + if (port) + s_sock.sin_port = port; + else + s_sock.sin_port = k_getportbyname (service, "tcp", htons(SAMPLE_PORT)); + + if (gethostname(myhostname, sizeof(myhostname)) < 0) { + warn("gethostname"); + return 1; + } + + if ((host = gethostbyname(myhostname)) == NULL) { + fprintf(stderr, "%s: unknown host\n", myhostname); + return 1; + } + + /* Open a socket */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + warn("socket SOCK_DGRAM"); + return 1; + } + + memset(&c_sock, 0, sizeof(c_sock)); + memcpy(&c_sock.sin_addr, host->h_addr, sizeof(c_sock.sin_addr)); + c_sock.sin_family = AF_INET; + + /* Bind it to set the address; kernel will fill in port # */ + if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) { + warn("bind"); + return 1; + } + + /* Get local realm, not needed, just an example */ + if ((i = krb_get_lrealm(c_realm, 1)) != KSUCCESS) { + fprintf(stderr, "can't find local Kerberos realm\n"); + return 1; + } + printf("Local Kerberos realm is %s\n", c_realm); + + /* Get Kerberos realm of host */ + s_realm = krb_realmofhost(hostname); + + /* PREPARE KRB_MK_REQ MESSAGE */ + + /* Get credentials for server, create krb_mk_req message */ + if ((i = krb_mk_req(ktxt, service, hostname, s_realm, cksum)) + != KSUCCESS) { + fprintf(stderr, "%s\n", krb_get_err_text(i)); + return 1; + } + printf("Got credentials for %s.\n", service); + + /* Send authentication info to server */ + i = sendto(sock, (char *)ktxt->dat, ktxt->length, flags, + (struct sockaddr *)&s_sock, sizeof(s_sock)); + if (i < 0) + warn("sending datagram message"); + printf("Sent authentication data: %d bytes\n", i); + + /* PREPARE KRB_MK_SAFE MESSAGE */ + + /* Get my address */ + memset(&c_sock, 0, sizeof(c_sock)); + i = sizeof(c_sock); + if (getsockname(sock, (struct sockaddr *)&c_sock, &i) < 0) { + warn("getsockname"); + return 1; + } + + /* Get session key */ + i = krb_get_cred(service, hostname, s_realm, cred); + if (i != KSUCCESS) + return 1; + + /* Make the safe message */ + len = krb_mk_safe(MSG, ktxt->dat, strlen(MSG)+1, + &cred->session, &c_sock, &s_sock); + + /* Send it */ + i = sendto(sock, (char *)ktxt->dat, (int) len, flags, + (struct sockaddr *)&s_sock, sizeof(s_sock)); + if (i < 0) + warn("sending safe message"); + printf("Sent checksummed message: %d bytes\n", i); + + /* PREPARE KRB_MK_PRIV MESSAGE */ + +#ifdef NOENCRYPTION + memset(sched, 0, sizeof(sched)); +#else + /* Get key schedule for session key */ + des_key_sched(&cred->session, sched); +#endif + + /* Make the encrypted message */ + len = krb_mk_priv(MSG, ktxt->dat, strlen(MSG)+1, + sched, &cred->session, &c_sock, &s_sock); + + /* Send it */ + i = sendto(sock, (char *)ktxt->dat, (int) len, flags, + (struct sockaddr *)&s_sock, sizeof(s_sock)); + if (i < 0) + warn("sending encrypted message"); + printf("Sent encrypted message: %d bytes\n", i); + return 0; +} + +static void +usage (void) +{ + fprintf (stderr, "Usage: %s [-s service] [-p port] hostname\n", + __progname); + exit (1); +} + +int +main(int argc, char **argv) +{ + int ret = 0; + int port = 0; + char service[SNAME_SZ]; + struct servent *serv; + int c; + + set_progname (argv[0]); + + strcpy_truncate (service, SAMPLE_SERVICE, sizeof(service)); + + while ((c = getopt(argc, argv, "s:p:")) != EOF) + switch(c) { + case 's' : + strcpy_truncate (service, optarg, sizeof(service)); + break; + case 'p' : + serv = getservbyname (optarg, "tcp"); + if (serv) + port = serv->s_port; + else + port = htons(atoi(optarg)); + break; + case '?' : + default : + usage(); + } + + argc -= optind; + argv += optind; + + while (argc-- > 0) + ret &= talkto (*argv++, service, port); + return ret; +} diff --git a/crypto/kerberosIV/appl/sample/simple_server.c b/crypto/kerberosIV/appl/sample/simple_server.c new file mode 100644 index 0000000..2b950c7 --- /dev/null +++ b/crypto/kerberosIV/appl/sample/simple_server.c @@ -0,0 +1,140 @@ +/* + * + * Copyright 1989 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * <mit-copyright.h>. + * + * Simple UDP-based server application. For demonstration. + * This program performs no useful function. + */ + +#include "sample.h" + +RCSID("$Id: simple_server.c,v 1.9 1998/06/09 19:24:39 joda Exp $"); + +static void +usage (void) +{ + fprintf (stderr, "Usage: %s [-p port] [-s service] [-t srvtab]\n", + __progname); + exit (1); +} + +int +main(int argc, char **argv) +{ + char service[SNAME_SZ]; + char instance[INST_SZ]; + int port; + char srvtab[MaxPathLen]; + struct sockaddr_in addr, otheraddr; + int c; + int sock; + int i; + int len; + KTEXT_ST k; + KTEXT ktxt = &k; + AUTH_DAT ad; + MSG_DAT msg_data; + des_key_schedule sched; + + set_progname (argv[0]); + strcpy_truncate (service, SAMPLE_SERVICE, sizeof(service)); + strcpy_truncate (instance, "*", sizeof(instance)); + *srvtab = '\0'; + port = 0; + + while ((c = getopt (argc, argv, "p:s:t:")) != EOF) + switch (c) { + case 'p' : { + struct servent *sp; + + sp = getservbyname (optarg, "udp"); + if (sp) + port = sp->s_port; + else + port = htons(atoi(optarg)); + break; + } + case 's' : + strcpy_truncate (service, optarg, sizeof(service)); + break; + case 't' : + strcpy_truncate (srvtab, optarg, sizeof(srvtab)); + break; + case '?' : + default : + usage (); + } + + if(port == 0) + port = k_getportbyname (SAMPLE_SERVICE, "udp", htons(SAMPLE_PORT)); + + memset (&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = port; + + sock = socket (AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + err (1, "socket"); + + if (bind (sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + err (1, "bind"); + + /* GET KRB_MK_REQ MESSAGE */ + + i = read(sock, ktxt->dat, MAX_KTXT_LEN); + if (i < 0) + err (1, "read"); + + printf("Received %d bytes\n", i); + ktxt->length = i; + + /* Check authentication info */ + i = krb_rd_req(ktxt, service, instance, 0, &ad, ""); + if (i != KSUCCESS) + errx (1, "krb_rd_req: %s", krb_get_err_text(i)); + printf("Got authentication info from %s%s%s@%s\n", ad.pname, + *ad.pinst ? "." : "", ad.pinst, ad.prealm); + + /* GET KRB_MK_SAFE MESSAGE */ + + /* use "recvfrom" so we know client's address */ + len = sizeof(otheraddr); + i = recvfrom(sock, ktxt->dat, MAX_KTXT_LEN, 0, + (struct sockaddr *)&otheraddr, &len); + if (i < 0) + err (1, "recvfrom"); + printf("Received %d bytes\n", i); + + /* Verify the checksummed message */ + i = krb_rd_safe(ktxt->dat, i, &ad.session, &otheraddr, + &addr, &msg_data); + if (i != KSUCCESS) + errx (1, "krb_rd_safe: %s", krb_get_err_text(i)); + printf("Safe message is: %s\n", msg_data.app_data); + + /* NOW GET ENCRYPTED MESSAGE */ + +#ifdef NOENCRYPTION + memset(sched, 0, sizeof(sched)); +#else + /* need key schedule for session key */ + des_key_sched(&ad.session, sched); +#endif + + /* use "recvfrom" so we know client's address */ + len = sizeof(otheraddr); + i = recvfrom(sock, ktxt->dat, MAX_KTXT_LEN, 0, + (struct sockaddr *)&otheraddr, &len); + if (i < 0) + err (1, "recvfrom"); + printf("Received %d bytes\n", i); + i = krb_rd_priv(ktxt->dat, i, sched, &ad.session, &otheraddr, + &addr, &msg_data); + if (i != KSUCCESS) + errx (1, "krb_rd_priv: %s", krb_get_err_text(i)); + printf("Decrypted message is: %s\n", msg_data.app_data); + return(0); +} |