Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / appl / sample / sample_client.c
1 /*
2  *
3  * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
4  *
5  * For copying and distribution information,
6  * please see the file <mit-copyright.h>.
7  *
8  * sample_client:
9  * A sample Kerberos client, which connects to a server on a remote host,
10  * at port "sample" (be sure to define it in /etc/services)
11  * and authenticates itself to the server. The server then writes back
12  * (in ASCII) the authenticated name.
13  *
14  * Usage:
15  * sample_client <hostname> <checksum>
16  *
17  * <hostname> is the name of the foreign host to contact.
18  *
19  * <checksum> is an integer checksum to be used for the call to krb_mk_req()
20  *      and mutual authentication
21  *
22  */
23
24 #include "sample.h"
25
26 RCSID("$Id: sample_client.c,v 1.21 1999/11/13 06:27:01 assar Exp $");
27
28 static void
29 usage (void)
30 {
31   fprintf (stderr, "Usage: %s [-s service] [-p port] hostname checksum\n",
32            __progname);
33   exit (1);
34 }
35
36 int
37 main(int argc, char **argv)
38 {
39     struct hostent *hp;
40     struct sockaddr_in sin, lsin;
41     char *remote_host;
42     int status;
43     int namelen;
44     int sock = -1;
45     KTEXT_ST ticket;
46     char buf[512];
47     long authopts;
48     MSG_DAT msg_data;
49     CREDENTIALS cred;
50     des_key_schedule sched;
51     u_int32_t cksum;
52     int c;
53     char service[SNAME_SZ];
54     u_int16_t port;
55     struct servent *serv;
56     char **h_addr_list;
57
58     set_progname (argv[0]);
59     strlcpy (service, SAMPLE_SERVICE, sizeof(service));
60     port = 0;
61
62     while ((c = getopt(argc, argv, "s:p:")) != -1)
63         switch(c) {
64         case 's' :
65             strlcpy (service, optarg, sizeof(service));
66             break;
67         case 'p' :
68             serv = getservbyname (optarg, "tcp");
69             if (serv)
70                 port = serv->s_port;
71             else
72                 port = htons(atoi(optarg));
73             break;
74         case '?' :
75         default :
76             usage();
77         }
78
79     argc -= optind;
80     argv += optind;
81
82     if (argc != 2)
83         usage ();
84     
85     /* convert cksum to internal rep */
86     cksum = atoi(argv[1]);
87
88     printf("Setting checksum to %ld\n", (long)cksum);
89
90     /* clear out the structure first */
91     memset(&sin, 0, sizeof(sin));
92     sin.sin_family = AF_INET;
93     if (port)
94         sin.sin_port = port;
95     else
96         sin.sin_port = k_getportbyname (service, "tcp", htons(SAMPLE_PORT));
97
98     /* look up the server host */
99     hp = gethostbyname(argv[0]);
100     if (hp == NULL)
101         errx (1, "gethostbyname(%s): %s", argv[0],
102               hstrerror(h_errno));
103
104     /* copy the hostname into non-volatile storage */
105     remote_host = strdup(hp->h_name);
106     if (remote_host == NULL)
107         errx (1, "strdup: out of memory");
108
109     /* set up the address of the foreign socket for connect() */
110     sin.sin_family = hp->h_addrtype;
111
112     for (h_addr_list = hp->h_addr_list;
113          *h_addr_list;
114          ++h_addr_list) {
115         memcpy(&sin.sin_addr, *h_addr_list, sizeof(sin.sin_addr));
116         fprintf (stderr, "Trying %s...\n", inet_ntoa(sin.sin_addr));
117
118         /* open a TCP socket */
119         sock = socket(PF_INET, SOCK_STREAM, 0);
120         if (sock < 0)
121             err (1, "socket");
122
123         /* connect to the server */
124         if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
125             break;
126         close (sock);
127     }
128
129     if (*h_addr_list == NULL)
130         err (1, "connect");
131
132     /* find out who I am, now that we are connected and therefore bound */
133     namelen = sizeof(lsin);
134     if (getsockname(sock, (struct sockaddr *) &lsin, &namelen) < 0) {
135         close (sock);
136         err (1, "getsockname");
137     }
138
139     /* call Kerberos library routine to obtain an authenticator,
140        pass it over the socket to the server, and obtain mutual
141        authentication. */
142
143     authopts = KOPT_DO_MUTUAL;
144     status = krb_sendauth(authopts, sock, &ticket,
145                           service, remote_host,
146                           NULL, cksum, &msg_data, &cred,
147                           sched, &lsin, &sin, SAMPLE_VERSION);
148     if (status != KSUCCESS)
149         errx (1, "cannot authenticate to server: %s",
150               krb_get_err_text(status));
151
152     /* After we send the authenticator to the server, it will write
153        back the name we authenticated to. Read what it has to say. */
154     status = read(sock, buf, sizeof(buf));
155     if (status < 0)
156         errx(1, "read");
157
158     /* make sure it's null terminated before printing */
159     if (status < sizeof(buf))
160         buf[status] = '\0';
161     else
162         buf[sizeof(buf) - 1] = '\0';
163
164     printf("The server says:\n%s\n", buf);
165
166     close(sock);
167     return 0;
168 }