Initial revision
authorTheodore Tso <tytso@mit.edu>
Mon, 6 May 1991 11:28:05 +0000 (11:28 +0000)
committerTheodore Tso <tytso@mit.edu>
Mon, 6 May 1991 11:28:05 +0000 (11:28 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@2092 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/user_user/client.c [new file with mode: 0644]
src/appl/user_user/server.c [new file with mode: 0644]

diff --git a/src/appl/user_user/client.c b/src/appl/user_user/client.c
new file mode 100644 (file)
index 0000000..56e34a5
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * Other end of user-user client/server pair.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_client_c[] =
+"$Id$";
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include <krb5/los-proto.h>
+#include <com_err.h>
+
+extern char *strdup(const char *);
+
+krb5_error_code
+tgt_keyproc(DECLARG(krb5_pointer, keyprocarg),
+           DECLARG(krb5_principal, principal),
+           DECLARG(krb5_kvno, vno),
+           DECLARG(krb5_keyblock **, key))
+OLDDECLARG(krb5_pointer, keyprocarg)
+OLDDECLARG(krb5_principal, principal)
+OLDDECLARG(krb5_kvno, vno)
+OLDDECLARG(krb5_keyblock **, key)
+{
+    krb5_creds *creds = (krb5_creds *)keyprocarg;
+    
+    return krb5_copy_keyblock(&creds->keyblock, key);
+}
+
+int main (argc, argv)
+int argc;
+char *argv[];
+{
+  int s;
+  register int retval, i;
+  char *hname;         /* full name of server */
+  char **srealms;      /* realm(s) of server */
+  char *princ;         /* principal in credentials cache */
+  struct servent *serv;
+  struct hostent *host;
+  struct sockaddr_in serv_net_addr, cli_net_addr;
+  krb5_address serv_addr, cli_addr;
+  krb5_ccache cc;
+  krb5_creds creds;
+  krb5_principal sprinc;               /* principal of server */
+  krb5_data reply, msg, princ_data;
+  krb5_tkt_authent *authdat;
+
+  if (argc < 2 || argc > 3)
+    {
+      fputs ("usage: uu-client <hostname> [message]\n", stderr);
+      return 1;
+    }
+
+  krb5_init_ets();
+
+  if ((serv = getservbyname ("uu-sample", "tcp")) == NULL)
+    {
+      fputs ("uu-client: unknown service \"uu-sample/tcp\"\n", stderr);
+      return 2;
+    }
+
+  if ((host = gethostbyname (argv[1])) == NULL)
+    {
+      extern int h_errno;
+
+      if (h_errno == HOST_NOT_FOUND)
+       fprintf (stderr, "uu-client: unknown host \"%s\".\n", argv[1]);
+      else
+       fprintf (stderr, "uu-client: can't get address of host \"%s\".\n", argv[1]);
+      return 3;
+    }
+
+  if (host->h_addrtype != AF_INET)
+    {
+      fprintf (stderr, "uu-client: bad address type %d for \"%s\".\n",
+              host->h_addrtype, argv[1]);
+      return 3;
+    }
+
+  hname = strdup (host->h_name);
+
+#ifndef USE_STDOUT
+  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    {
+      com_err ("uu-client", errno, "creating socket");
+      return 4;
+    } else {
+      cli_net_addr.sin_family = AF_INET;
+      cli_net_addr.sin_port = 0;
+      cli_net_addr.sin_addr.s_addr = 0;
+      if (bind (s, (struct sockaddr *)&cli_net_addr, sizeof (cli_net_addr)) < 0)
+       {
+         com_err ("uu-client", errno, "binding socket");
+         return 4;
+       }
+    }
+
+  serv_net_addr.sin_family = AF_INET;
+  serv_net_addr.sin_port = serv->s_port;
+
+  i = 0;
+  while (1)
+    {
+      if (host->h_addr_list[i] == 0)
+       {
+         fprintf (stderr, "uu-client: unable to connect to \"%s\"\n", hname);
+         return 5;
+       }
+      memcpy ((char *)&serv_net_addr.sin_addr, host->h_addr_list[i++], host->h_length);
+      if (connect(s, (struct sockaddr *)&serv_net_addr, sizeof (serv_net_addr)) == 0)
+       break;
+      com_err ("uu-client", errno, "connecting to \"%s\" (%s).",
+              hname, inet_ntoa(serv_net_addr.sin_addr.s_addr));
+    }
+#else
+  s = 1;
+#endif
+
+  if (retval = krb5_cc_default(&cc))
+    {
+      com_err("uu-client", retval, "getting credentials cache");
+      return 6;
+    }
+
+  memset ((char*)&creds, 0, sizeof(creds));
+  if (retval = krb5_cc_get_principal(cc, &creds.client))
+    {
+      com_err("uu-client", retval, "getting principal name");
+      return 6;
+    }
+
+  if (retval = krb5_unparse_name(creds.client, &princ))
+    com_err("uu-client", retval, "printing principal name");
+  else
+    fprintf(stderr, "uu-client: client principal is \"%s\".\n", princ);
+
+  if (retval = krb5_get_host_realm(hname, &srealms))
+    {
+      com_err("uu-client", retval, "getting realms for \"%s\"", hname);
+      return 7;
+    }
+
+  if (retval = krb5_build_principal_ext(&sprinc,
+                                       krb5_princ_realm(creds.client)->length,
+                                       krb5_princ_realm(creds.client)->data,
+                                       6, "krbtgt",
+                                       krb5_princ_realm(creds.client)->length,
+                                       krb5_princ_realm(creds.client)->data,
+                                       0))
+    {
+      com_err("uu-client", retval, "setting up tgt server name");
+      return 7;
+    }
+
+  creds.server = sprinc;
+
+  /* Get TGT from credentials cache */
+  if (retval = krb5_get_credentials(KRB5_GC_CACHED, cc, &creds))
+    {
+      com_err("uu-client", retval, "getting TGT");
+      return 6;
+    }
+  krb5_free_principal(sprinc);         /* creds.server is replaced
+                                          upon retrieval */
+
+  i = strlen(princ) + 1;
+
+  fprintf(stderr, "uu-client: sending %d bytes\n", creds.ticket.length + i);
+  princ_data.data = princ;
+  princ_data.length = i;               /* include null terminator for
+                                          server's convenience */
+  retval = krb5_write_message((krb5_pointer) &s, &princ_data);
+  if (retval)
+    {
+      com_err("uu-client", retval, "sending principal name to server");
+      return 8;
+    }
+  free(princ);
+  retval = krb5_write_message((krb5_pointer) &s, &creds.ticket);
+  if (retval)
+    {
+      com_err("uu-client", retval, "sending ticket to server");
+      return 8;
+    }
+
+  retval = krb5_read_message((krb5_pointer) &s, &reply);
+  if (retval)
+    {
+       com_err("uu-client", retval, "reading reply from server");
+      return 9;
+    }
+  serv_addr.addrtype = ADDRTYPE_INET;
+  serv_addr.length = sizeof (serv_net_addr.sin_addr);
+  serv_addr.contents = (krb5_octet *)&serv_net_addr.sin_addr;
+
+  cli_addr.addrtype = ADDRTYPE_INET;
+  cli_addr.length = sizeof(cli_net_addr.sin_addr);
+  cli_addr.contents = (krb5_octet *)&cli_net_addr.sin_addr;
+
+#if 1
+  /* read the ap_req to get the session key */
+  retval = krb5_rd_req(&reply,
+                      0,               /* don't know server's name... */
+                      &serv_addr,
+                      0,               /* no fetchfrom */
+                      tgt_keyproc,
+                      (krb5_pointer)&creds, /* credentials as arg to
+                                               keyproc */
+                      0,               /* no rcache for the moment XXX */
+                      &authdat);
+  free(reply.data);
+#else
+  retval = krb5_recvauth((krb5_pointer)&s, "???",
+                        0, /* server */
+                        &serv_addr, 0, tgt_keyproc, (krb5_pointer)&creds,
+                        0, 0);
+#endif
+  if (retval) {
+      com_err("uu-client", retval, "reading AP_REQ from server");
+      return 9;
+  }
+  if (retval = krb5_unparse_name(authdat->ticket->enc_part2->client, &princ))
+      com_err("uu-client", retval, "while unparsing client name");
+  else {
+      printf("server is named \"%s\"\n", princ);
+      free(princ);
+  }
+  retval = krb5_read_message((krb5_pointer) &s, &reply);
+  if (retval)
+    {
+      com_err("uu-client", retval, "reading reply from server");
+      return 9;
+    }
+
+
+  if (retval = krb5_rd_safe(&reply, authdat->ticket->enc_part2->session,
+                           &serv_addr, &cli_addr,
+                           authdat->authenticator->seq_number,
+                           KRB5_SAFE_NOTIME|KRB5_SAFE_DOSEQUENCE, 0, &msg))
+    {
+      com_err("uu-client", retval, "decoding reply from server");
+      return 10;
+    }
+  printf ("uu-client: server says \"%s\".\n", msg.data);
+  return 0;
+}
+
diff --git a/src/appl/user_user/server.c b/src/appl/user_user/server.c
new file mode 100644 (file)
index 0000000..bde0bd0
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1991 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * One end of the user-user client-server pair.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_server_c[] =
+"$Id$";
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include <krb5/los-proto.h>
+#include <com_err.h>
+
+extern krb5_flags krb5_kdc_default_options;
+
+/* fd 0 is a tcp socket used to talk to the client */
+
+int main(argc, argv)
+int argc;
+char *argv[];
+{
+  krb5_data pname_data, tkt_data;
+  int l, sock = 0;
+  int retval;
+  struct sockaddr_in l_inaddr, f_inaddr;       /* local, foreign address */
+  krb5_address laddr, faddr;
+  krb5_creds creds;
+  krb5_ccache cc;
+  krb5_data msgtext, msg;
+  krb5_int32 seqno;
+
+#ifndef DEBUG
+  freopen("/tmp/uu-server.log", "w", stderr);
+#endif
+
+  krb5_init_ets();
+
+#ifdef DEBUG
+    {
+       int acc;
+       struct servent *sp;
+       int namelen = sizeof(f_inaddr);
+
+       if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+           com_err("uu-server", errno, "creating socket");
+           exit(3);
+       }
+
+       l_inaddr.sin_family = AF_INET;
+       l_inaddr.sin_addr.s_addr = 0;
+       if (!(sp = getservbyname("uu-sample", "tcp"))) {
+           com_err("uu-server", 0, "can't find uu-sample/tcp");
+           exit(3);
+       }
+       l_inaddr.sin_port = sp->s_port;
+       if (bind(sock, &l_inaddr, sizeof(l_inaddr))) {
+           com_err("uu-server", errno, "binding socket");
+           exit(3);
+       }
+       if (listen(sock, 1) == -1) {
+           com_err("uu-server", errno, "listening");
+           exit(3);
+       }
+       if ((acc = accept(sock, (struct sockaddr *)&f_inaddr, &namelen)) == -1) {
+           com_err("uu-server", errno, "accepting");
+           exit(3);
+       }
+       dup2(acc, 0);
+       close(sock);
+       sock = 0;
+    }
+#endif
+  if (retval = krb5_read_message((krb5_pointer) &sock, &pname_data)) {
+      com_err ("uu-server", retval, "reading pname");
+      return 2;
+  }
+  if (retval = krb5_read_message((krb5_pointer) &sock, &tkt_data)) {
+      com_err ("uu-server", retval, "reading ticket data");
+      return 2;
+  }
+
+  if (retval = krb5_cc_default(&cc))
+    {
+      com_err("uu-server", retval, "getting credentials cache");
+      return 4;
+    }
+
+  memset ((char*)&creds, 0, sizeof(creds));
+  if (retval = krb5_cc_get_principal(cc, &creds.client))
+    {
+      com_err("uu-client", retval, "getting principal name");
+      return 6;
+    }
+
+  /* client sends it already null-terminated. */
+  printf ("uu-server: client principal is \"%s\".\n", pname_data.data);
+
+  if (retval = krb5_parse_name(pname_data.data, &creds.server))
+    {
+      com_err("uu-server", retval, "parsing client name");
+      return 3;
+    }
+  creds.second_ticket = tkt_data;
+  printf ("uu-server: client ticket is %d bytes.\n",
+         creds.second_ticket.length);
+
+  if (retval = krb5_get_credentials(KRB5_GC_USER_USER, cc, &creds))
+    {
+      com_err("uu-server", retval, "getting user-user ticket");
+      return 5;
+    }
+
+#ifndef DEBUG
+  l = sizeof(f_inaddr);
+  if (getpeername(0, (struct sockaddr *)&f_inaddr, &l) == -1)
+    {
+      com_err("uu-server", errno, "getting client address");
+      return 6;
+    }
+#endif
+  faddr.addrtype = ADDRTYPE_INET;
+  faddr.length = sizeof (f_inaddr.sin_addr);
+  faddr.contents = (krb5_octet *)&f_inaddr.sin_addr;
+
+  l = sizeof(l_inaddr);
+  if (getsockname(0, (caddr_t)&l_inaddr, &l) == -1)
+    {
+      com_err("uu-server", errno, "getting local address");
+      return 6;
+    }
+
+  laddr.addrtype = ADDRTYPE_INET;
+  laddr.length = sizeof (l_inaddr.sin_addr);
+  laddr.contents = (krb5_octet *)&l_inaddr.sin_addr;
+
+  /* send a ticket/authenticator to the other side, so it can get the key
+     we're using for the krb_safe below. */
+
+  if (retval = krb5_generate_seq_number(&creds.keyblock, &seqno)) {
+      com_err("uu-server", retval, "generating sequence number");
+      return 8;
+  }
+#if 1
+  if (retval = krb5_mk_req_extended(AP_OPTS_USE_SESSION_KEY,
+                              0,       /* no application checksum here */
+                              &creds.times,
+                              krb5_kdc_default_options,
+                              seqno,
+                              0,       /* no need for subkey */
+                              cc,
+                              &creds,
+                              0,       /* don't need authenticator copy */
+                              &msg)) {
+      com_err("uu-server", retval, "making AP_REQ");
+      return 8;
+  }
+  retval = krb5_write_message((krb5_pointer) &sock, &msg);
+#else
+  retval = krb5_sendauth((krb5_pointer)&sock, "???", 0, 0,
+                        AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SESSION_KEY,
+                        0, /* no checksum*/
+                        &creds, cc,
+                        0, 0,  /* no sequence number or subsession key */
+                        0, 0);
+#endif
+  if (retval)
+      goto cl_short_wrt;
+
+  free(msg.data);
+
+  msgtext.length = 32;
+  msgtext.data = "Hello, other end of connection.";
+
+  if (retval = krb5_mk_safe(&msgtext, CKSUMTYPE_RSA_MD4_DES, &creds.keyblock,
+                           &laddr, &faddr, seqno,
+                           KRB5_SAFE_NOTIME|KRB5_SAFE_DOSEQUENCE, 0, &msg))
+    {
+      com_err("uu-server", retval, "encoding message to client");
+      return 6;
+    }
+
+  retval = krb5_write_message((krb5_pointer) &sock, &msg);
+  if (retval)
+    {
+    cl_short_wrt:
+       com_err("uu-server", retval, "writing message to client");
+      return 7;
+    }
+
+  return 0;
+}