--- /dev/null
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * Sample Kerberos v5 client.
+ *
+ * Usage: sample_client hostname
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_sclient_c [] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+#include <krb5/krb5.h>
+#include <krb5/krb5_err.h>
+#include <krb5/ext-proto.h>
+#include <errno.h>
+#include <stdio.h>
+#include <krb5/libos-proto.h>
+
+#include <ctype.h>
+#include <com_err.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <signal.h>
+
+#include "sample.h"
+
+void
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ struct servent *sp;
+ struct hostent *hp;
+ struct sockaddr_in sin, lsin;
+ char *remote_host;
+ register char *cp;
+ int sock, namelen;
+ krb5_data send_data;
+ krb5_checksum send_cksum;
+ krb5_error_code retval;
+ krb5_ccache ccdef;
+ krb5_principal server;
+ char **hrealms;
+ short xmitlen;
+ char sbuf[512];
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <hostname>\n",argv[0]);
+ exit(1);
+ }
+
+ krb5_init_ets();
+
+ (void) signal(SIGPIPE, SIG_IGN);
+ if (!valid_cksumtype(CKSUMTYPE_CRC32)) {
+ com_err(argv[0], KRB5_PROG_SUMTYPE_NOSUPP, "while using CRC-32");
+ exit(1);
+ }
+
+ /* clear out the structure first */
+ (void) bzero((char *)&sin, sizeof(sin));
+
+ /* find the port number for knetd */
+ sp = getservbyname(SAMPLE_SERVICE, "tcp");
+ if (!sp) {
+ fprintf(stderr,
+ "unknown service %s/tcp; check /etc/services\n",
+ SAMPLE_SERVICE);
+ exit(1);
+ }
+ /* copy the port number */
+ sin.sin_port = sp->s_port;
+ sin.sin_family = AF_INET;
+
+ /* look up the server host */
+ hp = gethostbyname(argv[1]);
+ if (!hp) {
+ fprintf(stderr, "unknown host %s\n",argv[1]);
+ exit(1);
+ }
+
+ if (retval = krb5_get_host_realm(hp->h_name, &hrealms)) {
+ com_err(argv[0], retval, "while determining realm(s) of %s",
+ hp->h_name);
+ exit(1);
+ }
+ if (strlen(hp->h_name)+strlen(SAMPLE_SERVICE)+strlen(hrealms[0])+3 >
+ sizeof(sbuf)) {
+ fprintf(stderr, "hostname too long!\n");
+ exit(1);
+ }
+
+ /* copy the hostname into non-volatile storage */
+ remote_host = malloc(strlen(hp->h_name) + 1);
+ (void) strcpy(remote_host, hp->h_name);
+
+ /* lower-case to get name for "instance" part of service name */
+ for (cp = remote_host; *cp; cp++)
+ if (isupper(*cp))
+ *cp = tolower(*cp);
+
+ bzero(sbuf, sizeof(sbuf));
+ strcpy(sbuf, SAMPLE_SERVICE);
+ strcat(sbuf, "/");
+ strcat(sbuf, remote_host);
+ strcat(sbuf, "@");
+ strcat(sbuf, hrealms[0]);
+ (void) krb5_free_host_realm(hrealms);
+ if (retval = krb5_parse_name(sbuf, &server)) {
+ com_err(argv[0], retval, "while parsing service name %s", sbuf);
+ exit(1);
+ }
+
+ /* set up the address of the foreign socket for connect() */
+ sin.sin_family = hp->h_addrtype;
+ (void) bcopy((char *)hp->h_addr,
+ (char *)&sin.sin_addr,
+ sizeof(hp->h_addr));
+
+ /* open a TCP socket */
+ sock = socket(PF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ /* connect to the server */
+ if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ perror("connect");
+ close(sock);
+ exit(1);
+ }
+
+ /* find out who I am, now that we are connected and therefore bound */
+ namelen = sizeof(lsin);
+ if (getsockname(sock, (struct sockaddr *) &lsin, &namelen) < 0) {
+ perror("getsockname");
+ close(sock);
+ exit(1);
+ }
+
+ /* compute checksum, using CRC-32 */
+ if (!(send_cksum.contents = (krb5_octet *)
+ malloc(krb5_cksumarray[CKSUMTYPE_CRC32]->checksum_length))) {
+ com_err(argv[0], ENOMEM, "while allocating checksum");
+ exit(1);
+ }
+ /* choose some random stuff to compute checksum from */
+ if (retval = (*krb5_cksumarray[CKSUMTYPE_CRC32]->
+ sum_func)(remote_host,
+ strlen(remote_host),
+ 0,
+ 0, /* if length is 0, crc-32 doesn't
+ use the seed */
+ &send_cksum)) {
+ com_err(argv[0], retval, "while computing checksum");
+ exit(1);
+ }
+
+ ccdef = krb5_cc_default();
+
+ if (retval = krb5_mk_req(server, 0, &send_cksum, ccdef, &send_data)) {
+ com_err(argv[0], retval, "while preparing AP_REQ");
+ exit(1);
+ }
+ xmitlen = htons(send_data.length);
+
+ if ((retval = krb5_net_write(sock, (char *)&xmitlen,
+ sizeof(xmitlen))) < 0) {
+ com_err(argv[0], errno, "while writing len to server");
+ exit(1);
+ }
+ if ((retval = krb5_net_write(sock, (char *)send_data.data,
+ send_data.length)) < 0) {
+ com_err(argv[0], errno, "while writing data to server");
+ exit(1);
+ }
+ xfree(send_data.data);
+ if ((retval = krb5_net_read(sock, (char *)&xmitlen,
+ sizeof(xmitlen))) <= 0) {
+ if (retval == 0)
+ errno = ECONNRESET; /* XXX */
+ com_err(argv[0], errno, "while reading data from server");
+ exit(1);
+ }
+ send_data.length = ntohs(xmitlen);
+ if (!(send_data.data = (char *)malloc(send_data.length + 1))) {
+ com_err(argv[0], ENOMEM, "while allocating buffer to read from server");
+ exit(1);
+ }
+ if ((retval = krb5_net_read(sock, (char *)send_data.data,
+ send_data.length)) <= 0) {
+ if (retval == 0)
+ errno = ECONNRESET; /* XXX */
+ com_err(argv[0], errno, "while reading data from server");
+ exit(1);
+ }
+ send_data.data[send_data.length] = '\0';
+ printf("reply len %d, contents:\n%s\n",send_data.length,send_data.data);
+ exit(0);
+}
--- /dev/null
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * Sample Kerberos v5 server.
+ *
+ * sample_server:
+ * A sample Kerberos server, which reads an AP_REQ from a TCP socket,
+ * decodes it, and writes back the results (in ASCII) to the client.
+ *
+ * Usage:
+ * sample_server servername [keytabname]
+ *
+ * file descriptor 0 (zero) should be a socket connected to the requesting
+ * client (this will be correct if this server is started by inetd).
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_sserver_c [] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+#include <krb5/krb5.h>
+#include <krb5/krb5_err.h>
+#include <krb5/ext-proto.h>
+#include <stdio.h>
+#include <krb5/libos-proto.h>
+
+#include <errno.h>
+
+#include <ctype.h>
+#include <com_err.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <syslog.h>
+
+#include "sample.h"
+
+#define RCSAMPLE "dfl:sserver_rcache"
+
+extern krb5_deltat krb5_clockskew;
+
+void
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ struct sockaddr_in peername;
+ krb5_address peeraddr;
+ int namelen = sizeof(peername);
+ krb5_data recv_data;
+ short xmitlen;
+ krb5_error_code retval;
+ krb5_rcache rcsample;
+ krb5_tkt_authent authd;
+ krb5_pointer keyfile = 0;
+ krb5_principal server;
+ char repbuf[BUFSIZ];
+ char *cname;
+
+ krb5_init_ets();
+ /* open a log connection */
+
+ openlog("sserver", 0, LOG_DAEMON);
+
+ if (retval = krb5_parse_name(argv[1], &server)) {
+ syslog(LOG_ERR, "parse server name %s: %s", argv[1],
+ error_message(retval));
+ exit(1);
+ }
+
+ if (argc > 2)
+ keyfile = (krb5_pointer) argv[2];
+
+#ifdef DEBUG
+{
+ int sock, acc;
+ struct sockaddr_in sin;
+
+ if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ syslog(LOG_ERR, "socket: %m");
+ exit(3);
+ }
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = 0;
+ sin.sin_port = htons(5555);
+ if (bind(sock, &sin, sizeof(sin))) {
+ syslog(LOG_ERR, "bind: %m");
+ exit(3);
+ }
+ if (listen(sock, 1) == -1) {
+ syslog(LOG_ERR, "listen: %m");
+ exit(3);
+ }
+ if ((acc = accept(sock, &peername, &namelen)) == -1) {
+ syslog(LOG_ERR, "accept: %m");
+ exit(3);
+ }
+ dup2(acc, 0);
+ close(sock);
+}
+#else
+ /*
+ * To verify authenticity, we need to know the address of the
+ * client.
+ */
+ if (getpeername(0, (struct sockaddr *)&peername, &namelen) < 0) {
+ syslog(LOG_ERR, "getpeername: %m");
+ exit(1);
+ }
+#endif
+ peeraddr.addrtype = peername.sin_family;
+ peeraddr.length = sizeof(peername.sin_addr);
+ if (!(peeraddr.contents = (krb5_octet *)malloc(peeraddr.length))) {
+ syslog(LOG_ERR, "no memory allocating addr");
+ exit(1);
+ }
+ bcopy((char *)&peername.sin_addr, (char *)peeraddr.contents,
+ peeraddr.length);
+
+ if (retval = krb5_rc_resolve_full(&rcsample, RCSAMPLE)) {
+ syslog(LOG_ERR, "%s while resolving replay cache '%s'",
+ error_message(retval), RCSAMPLE);
+ exit(1);
+ }
+
+ if ((retval = krb5_rc_recover(rcsample)) &&
+ (retval = krb5_rc_initialize(rcsample, krb5_clockskew))) {
+ syslog(LOG_ERR, "%s while initializing replay cache '%s:%s'",
+ error_message(retval),
+ rcsample->ops->type,
+ krb5_rc_get_name(rcsample));
+ exit(1);
+ }
+ if ((retval = krb5_net_read(0, (char *)&xmitlen, sizeof(xmitlen))) <= 0) {
+ if (retval == 0)
+ errno = ECONNRESET; /* XXX */
+ syslog(LOG_ERR, "read size: %m");
+ exit(1);
+ }
+ recv_data.length = ntohs(xmitlen);
+ if (!(recv_data.data = (char *) malloc(recv_data.length))) {
+ syslog(LOG_ERR, "no memory allocating packet");
+ exit(1);
+ }
+ if ((retval = krb5_net_read(0, (char *)recv_data.data,
+ recv_data.length)) <= 0) {
+ if (retval == 0)
+ errno = ECONNRESET; /* XXX */
+ syslog(LOG_ERR, "read contents: %m");
+ exit(1);
+ }
+ if (retval = krb5_rd_req(&recv_data, server, &peeraddr, keyfile, 0, 0,
+ rcsample, &authd)) {
+ syslog(LOG_ERR, "rd_req failed: %s", error_message(retval));
+ sprintf(repbuf, "RD_REQ failed: %s\n", error_message(retval));
+ goto sendreply;
+ }
+ xfree(recv_data.data);
+
+ if (retval = krb5_unparse_name(authd.ticket->enc_part2->client, &cname)) {
+ syslog(LOG_ERR, "unparse failed: %s", error_message(retval));
+ cname = "<unparse error>";
+ }
+ sprintf(repbuf, "You are %s\n", cname);
+ if (!retval)
+ free(cname);
+ sendreply:
+ xmitlen = htons(strlen(repbuf));
+ recv_data.length = strlen(repbuf);
+ recv_data.data = repbuf;
+ if ((retval = krb5_net_write(0, (char *)&xmitlen,
+ sizeof(xmitlen))) < 0) {
+ syslog(LOG_ERR, "%m: while writing len to client");
+ exit(1);
+ }
+ if ((retval = krb5_net_write(0, (char *)recv_data.data,
+ recv_data.length)) < 0) {
+ syslog(LOG_ERR, "%m: while writing data to client");
+ exit(1);
+ }
+ exit(0);
+}