sim_client.c (main): Added better options parsing for more flexibility
authorTheodore Tso <tytso@mit.edu>
Fri, 15 Sep 1995 09:03:42 +0000 (09:03 +0000)
committerTheodore Tso <tytso@mit.edu>
Fri, 15 Sep 1995 09:03:42 +0000 (09:03 +0000)
in calling this program.  Worked around breakage in the Solaris
Streams Sockets emulation where getsockname() can not be used to find
out the address of a network interface.

configure.in: If we are including both -lsocket and -lnsl, #define
BROKEN_STREAMS_SOCKETS.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6791 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/simple/client/ChangeLog
src/appl/simple/client/configure.in
src/appl/simple/client/sim_client.c

index 321938a22d7ba6557d5585a1fead7ae757d2b8c1..d13e231c71fcbd214cbe81d81fdbd7669c432625 100644 (file)
@@ -1,3 +1,14 @@
+Fri Sep 15 04:59:30 1995  Theodore Y. Ts'o  <tytso@dcl>
+
+       * sim_client.c (main): Added better options parsing for more
+               flexibility in calling this program.  Worked around
+               breakage in the Solaris Streams Sockets emulation where
+               getsockname() can not be used to find out the address of
+               a network interface.
+
+       * configure.in: If we are including both -lsocket and -lnsl,
+               #define BROKEN_STREAMS_SOCKETS.
+       
 
 Fri Jul 7 15:48:14 EDT 1995    Paul Park       (pjpark@mit.edu)
        * Makefile.in - Remove all explicit library handling and LDFLAGS.
index 657e99f367df51433423464b1e2a9be000873296..a942368495f5e89050a26c77d27c892c241e8fea 100644 (file)
@@ -2,6 +2,9 @@ AC_INIT(sim_client.c)
 CONFIG_RULES
 AC_PROG_INSTALL
 AC_CHECK_HEADERS(stdlib.h)
+if test "$ac_cv_lib_socket" = "yes" -a "$ac_cv_lib_nsl" = "yes"; then
+       AC_DEFINE(BROKEN_STREAMS_SOCKETS)
+fi
 KRB5_LIBRARIES
 V5_USE_SHARED_LIB
 V5_AC_OUTPUT_MAKEFILE
index 3a15d833dce81192cbfb1490669daa1c119e5a47..15644ee7ebdd1c757c784cf2eb9117a84f09878e 100644 (file)
@@ -51,8 +51,12 @@ extern char *malloc();
 
 #define MSG "hi there!"                        /* message text */
 
-#define PROGNAME argv[0]
-#define HOST argv[1]
+void
+usage(name)
+    char *name;
+{
+       fprintf(stderr, "usage: %s [-p port] [-h host] [-m message] [-s service] [host]\n", name);
+}      
 
 int
 main(argc, argv)
@@ -65,8 +69,20 @@ main(argc, argv)
     struct hostent *host;
     char *cp;
     char full_hname[MAXHOSTNAMELEN];
+#ifdef BROKEN_STREAMS_SOCKETS
+    char my_hostname[MAXHOSTNAMELEN];
+#endif
     struct sockaddr_in s_sock;         /* server address */
     struct sockaddr_in c_sock;         /* client address */
+    extern int opterr, optind;
+    extern char * optarg;
+    int        ch;
+    
+    short port = 0;
+    char *message = MSG;
+    char *hostname = 0;
+    char *service = SIMPLE_SERVICE;
+    char *progname = 0;
 
     krb5_error_code retval;
     krb5_data packet, inbuf;
@@ -79,28 +95,58 @@ main(argc, argv)
     krb5_auth_context    auth_context = NULL;
     krb5_replay_data     replaydata;
 
-    if (argc != 2 && argc != 3) {
-       fprintf(stderr, "usage: %s <hostname> [message]\n",PROGNAME);
-       exit(1);
-    }
-    
     krb5_init_context(&context);
     krb5_init_ets(context);
 
-    if (!valid_cksumtype(CKSUMTYPE_CRC32)) {
-       com_err(PROGNAME, KRB5_PROG_SUMTYPE_NOSUPP, "while using CRC-32");
+    progname = argv[0];
+
+    /*
+     * Parse command line arguments
+     *  
+     */
+    opterr = 0;
+    while ((ch = getopt(argc, argv, "p:m:h:s:")) != EOF)
+    switch (ch) {
+    case 'p':
+       port = atoi(optarg);
+       break;
+    case 'm':
+       message = optarg;
+       break;
+    case 'h':
+       hostname = optarg;
+       break;
+    case 's':
+       service = optarg;
+       break;
+    case '?':
+    default:
+       usage(progname);
        exit(1);
+       break;
+    }
+    argc -= optind;
+    argv += optind;
+    if (argc > 1) {
+       if (hostname)
+           usage();
+       hostname = argv[1];
     }
 
-    /* Look up service */
-    if ((serv = getservbyname(SERVICE, "udp")) == NULL) {
-       fprintf(stderr, "service unknown: %s/udp\n", SERVICE);
+    if (hostname == 0) {
+       fprintf(stderr, "You must specify a hostname to contact.\n\n");
+       usage(progname);
+       exit(1);
+    }
+
+    if (!valid_cksumtype(CKSUMTYPE_CRC32)) {
+       com_err(progname, KRB5_PROG_SUMTYPE_NOSUPP, "while using CRC-32");
        exit(1);
     }
 
     /* Look up server host */
-    if ((host = gethostbyname(HOST)) == (struct hostent *) 0) {
-       fprintf(stderr, "%s: unknown host\n", HOST);
+    if ((host = gethostbyname(hostname)) == (struct hostent *) 0) {
+       fprintf(stderr, "%s: unknown host\n", hostname);
        exit(1);
     }
     strncpy(full_hname, host->h_name, sizeof(full_hname)-1);
@@ -119,51 +165,74 @@ main(argc, argv)
     printf("s_sock.sin_addr is %s\n", inet_ntoa(s_sock.sin_addr));
 #endif
     s_sock.sin_family = AF_INET;
-    s_sock.sin_port = serv->s_port;
+
+    if (port == 0) {
+       /* Look up service */
+       if ((serv = getservbyname(SIMPLE_PORT, "udp")) == NULL) {
+           fprintf(stderr, "service unknown: %s/udp\n", SIMPLE_PORT);
+           exit(1);
+       }
+       s_sock.sin_port = serv->s_port;
+    } else {
+       s_sock.sin_port = htons(port);
+    }
 
     /* Open a socket */
     if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-       com_err(PROGNAME, errno, "opening datagram socket");
+       com_err(progname, errno, "opening datagram socket");
        exit(1);
     }
 
     memset((char *)&c_sock, 0, sizeof(c_sock));
     c_sock.sin_family = AF_INET;
+#ifdef BROKEN_STREAMS_SOCKETS
+    if (gethostname(my_hostname, sizeof(my_hostname)) < 0) {
+       perror("gethostname");
+       exit(1);
+    }
+
+    if ((host = gethostbyname(my_hostname)) == (struct hostent *)0) {
+       fprintf(stderr, "%s: unknown host\n", hostname);
+       exit(1);
+    }
+    memcpy((char *)&c_sock.sin_addr, host->h_addr, host->h_length);
+#endif
+    
 
     /* Bind it to set the address; kernel will fill in port # */
     if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) {
-       com_err(PROGNAME, errno, "while binding datagram socket");
+       com_err(progname, errno, "while binding datagram socket");
        exit(1);
     }
        
     /* PREPARE KRB_AP_REQ MESSAGE */
 
-    inbuf.data = HOST;
-    inbuf.length = strlen(HOST);
+    inbuf.data = hostname;
+    inbuf.length = strlen(hostname);
 
     /* Get credentials for server */
-    if (retval = krb5_cc_default(context, &ccdef)) {
-       com_err(PROGNAME, retval, "while getting default ccache");
+    if ((retval = krb5_cc_default(context, &ccdef))) {
+       com_err(progname, retval, "while getting default ccache");
        exit(1);
     }
 
-    if (retval = krb5_mk_req(context, &auth_context, 0, SERVICE, full_hname,
-                            &inbuf, ccdef, &packet)) {
-       com_err(PROGNAME, retval, "while preparing AP_REQ");
+    if ((retval = krb5_mk_req(context, &auth_context, 0, service, full_hname,
+                             &inbuf, ccdef, &packet))) {
+       com_err(progname, retval, "while preparing AP_REQ");
        exit(1);
     }
-    printf("Got credentials for %s.\n", SERVICE);
+    printf("Got credentials for %s.\n", service);
 
     /* "connect" the datagram socket; this is necessary to get a local address
        properly bound for getsockname() below. */
 
     if (connect(sock, (struct sockaddr *)&s_sock, sizeof(s_sock)) == -1) {
-       com_err(PROGNAME, errno, "while connecting to server");
+       com_err(progname, errno, "while connecting to server");
        exit(1);
     }
     /* Send authentication info to server */
     if ((i = send(sock, (char *)packet.data, packet.length, flags)) < 0) 
-       com_err(PROGNAME, errno, "while sending KRB_AP_REQ message");
+       com_err(progname, errno, "while sending KRB_AP_REQ message");
     printf("Sent authentication data: %d bytes\n", i);
     krb5_xfree(packet.data);
 
@@ -173,56 +242,59 @@ main(argc, argv)
     memset((char *) &c_sock, 0, sizeof(c_sock));
     i = sizeof(c_sock);
     if (getsockname(sock, (struct sockaddr *)&c_sock, &i) < 0) {
-       com_err(PROGNAME, errno, "while getting socket name");
+       com_err(progname, errno, "while getting socket name");
        exit(1);
     }
 
     addr.addrtype = ADDRTYPE_IPPORT;
     addr.length = sizeof(c_sock.sin_port);
     addr.contents = (krb5_octet *)&c_sock.sin_port;
-    if (retval = krb5_auth_con_setports(context, auth_context, &addr, NULL)) {
-       com_err(PROGNAME, retval, "while setting local port\n");
+    if ((retval = krb5_auth_con_setports(context, auth_context,
+                                        &addr, NULL))) {
+       com_err(progname, retval, "while setting local port\n");
        exit(1);
     }
 
     addr.addrtype = ADDRTYPE_INET;
     addr.length = sizeof(c_sock.sin_addr);
     addr.contents = (krb5_octet *)&c_sock.sin_addr;
-    if (retval = krb5_auth_con_setaddrs(context, auth_context, &addr, NULL)) {
-       com_err(PROGNAME, retval, "while setting local addr\n");
+    if ((retval = krb5_auth_con_setaddrs(context, auth_context,
+                                        &addr, NULL))) {
+       com_err(progname, retval, "while setting local addr\n");
        exit(1);
     }
 
     /* THIS IS UGLY */
-    if (retval = krb5_gen_portaddr(context, &addr,
-                                  (krb5_pointer) &c_sock.sin_port,
-                                  &portlocal_addr)) {
-       com_err(PROGNAME, retval, "while generating port address");
+    if ((retval = krb5_gen_portaddr(context, &addr,
+                                   (krb5_pointer) &c_sock.sin_port,
+                                   &portlocal_addr))) {
+       com_err(progname, retval, "while generating port address");
        exit(1);
     }
     
-    if (retval = krb5_gen_replay_name(context,portlocal_addr,"_sim_clt",&cp)) {
-       com_err(PROGNAME, retval, "while generating replay cache name");
+    if ((retval = krb5_gen_replay_name(context,portlocal_addr,
+                                      "_sim_clt",&cp))) {
+       com_err(progname, retval, "while generating replay cache name");
        exit(1);
     }
     if (!(rcache = (krb5_rcache)malloc(sizeof(*rcache)))) {
-       com_err(PROGNAME, ENOMEM, "while allocating replay cache");
+       com_err(progname, ENOMEM, "while allocating replay cache");
        exit(1);
     }
-    if (retval = krb5_rc_resolve_type(context, &rcache, 
-                                     krb5_rc_default_type(context))) {
+    if ((retval = krb5_rc_resolve_type(context, &rcache, 
+                                      krb5_rc_default_type(context)))) {
        krb5_xfree(rcache);
-       com_err(PROGNAME, retval, "while resolving replay cache type");
+       com_err(progname, retval, "while resolving replay cache type");
        exit(1);
     }
-    if (retval = krb5_rc_resolve(context, rcache, cp)) {
+    if ((retval = krb5_rc_resolve(context, rcache, cp))) {
        krb5_xfree(rcache);
-       com_err(PROGNAME, retval, "while resolving replay cache type");
+       com_err(progname, retval, "while resolving replay cache type");
        exit(1);
     }
     if ((retval = krb5_rc_recover(context, rcache)) &&
        (retval = krb5_rc_initialize(context, rcache, krb5_clockskew))) {
-       com_err(PROGNAME, retval, "while initializing replay cache '%s:%s'",
+       com_err(progname, retval, "while initializing replay cache '%s:%s'",
                rcache->ops->type,
                krb5_rc_get_name(context, rcache));
        exit(1);
@@ -232,31 +304,32 @@ main(argc, argv)
     krb5_auth_con_setrcache(context, auth_context, rcache);
 
     /* Make the safe message */
-    inbuf.data = argc == 3 ? argv[2] : MSG;
-    inbuf.length = strlen (inbuf.data);
+    inbuf.data = message;
+    inbuf.length = strlen(message);
 
-    if (retval = krb5_mk_safe(context, auth_context, &inbuf, &packet, NULL)){
-       com_err(PROGNAME, retval, "while making KRB_SAFE message");
+    if ((retval = krb5_mk_safe(context, auth_context, &inbuf, &packet, NULL))){
+       com_err(progname, retval, "while making KRB_SAFE message");
        exit(1);
     }
 
     /* Send it */
     if ((i = send(sock, (char *)packet.data, packet.length, flags)) < 0)
-       com_err(PROGNAME, errno, "while sending SAFE message");
+       com_err(progname, errno, "while sending SAFE message");
     printf("Sent checksummed message: %d bytes\n", i);
     krb5_xfree(packet.data);
 
     /* PREPARE KRB_PRIV MESSAGE */
 
     /* Make the encrypted message */
-    if (retval = krb5_mk_priv(context, auth_context, &inbuf, &packet, NULL)) {
-       com_err(PROGNAME, retval, "while making KRB_PRIV message");
+    if ((retval = krb5_mk_priv(context, auth_context, &inbuf,
+                              &packet, NULL))) {
+       com_err(progname, retval, "while making KRB_PRIV message");
        exit(1);
     }
 
     /* Send it */
     if ((i = send(sock, (char *)packet.data, packet.length, flags)) < 0)
-       com_err(PROGNAME, errno, "while sending PRIV message");
+       com_err(progname, errno, "while sending PRIV message");
     printf("Sent encrypted message: %d bytes\n", i);
     krb5_xfree(packet.data);
     exit(0);