diff options
-rw-r--r-- | src/appl/simple/client/ChangeLog | 11 | ||||
-rw-r--r-- | src/appl/simple/client/configure.in | 3 | ||||
-rw-r--r-- | src/appl/simple/client/sim_client.c | 179 |
3 files changed, 140 insertions, 53 deletions
diff --git a/src/appl/simple/client/ChangeLog b/src/appl/simple/client/ChangeLog index 321938a22..d13e231c7 100644 --- a/src/appl/simple/client/ChangeLog +++ b/src/appl/simple/client/ChangeLog @@ -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. diff --git a/src/appl/simple/client/configure.in b/src/appl/simple/client/configure.in index 657e99f36..a94236849 100644 --- a/src/appl/simple/client/configure.in +++ b/src/appl/simple/client/configure.in @@ -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 diff --git a/src/appl/simple/client/sim_client.c b/src/appl/simple/client/sim_client.c index 3a15d833d..15644ee7e 100644 --- a/src/appl/simple/client/sim_client.c +++ b/src/appl/simple/client/sim_client.c @@ -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); |