Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / appl / sample / simple_client.c
1 /*
2  *
3  * Copyright 1989 by the Massachusetts Institute of Technology.
4  *
5  * For copying and distribution information, please see the file
6  * <mit-copyright.h>.
7  *
8  * Simple UDP-based sample client program.  For demonstration.
9  * This program performs no useful function.
10  */
11
12 #include "sample.h"
13 RCSID("$Id: simple_client.c,v 1.15 1999/11/13 06:29:01 assar Exp $");
14
15 #define MSG "hi, Jennifer!"             /* message text */
16
17 static int
18 talkto(char *hostname, char *service, int port)
19 {
20   int flags = 0;                        /* flags for sendto() */
21   long len;
22   u_long cksum = 0L;            /* cksum not used */
23   char c_realm[REALM_SZ];               /* local Kerberos realm */
24   char *s_realm;                        /* server's Kerberos realm */
25
26   KTEXT_ST k;                   /* Kerberos data */
27   KTEXT ktxt = &k;
28
29   int sock, i;
30   struct hostent *host;
31   struct sockaddr_in s_sock;    /* server address */
32   char myhostname[MaxHostNameLen]; /* local hostname */
33
34   /* for krb_mk_safe/priv */
35   struct sockaddr_in c_sock;    /* client address */
36   CREDENTIALS c;                        /* ticket & session key */
37   CREDENTIALS *cred = &c;
38
39   /* for krb_mk_priv */
40   des_key_schedule sched;               /* session key schedule */
41
42   /* Look up server host */
43   if ((host = gethostbyname(hostname)) == NULL) {
44     fprintf(stderr, "%s: unknown host \n", hostname);
45     return 1;
46   }
47
48   /* Set server's address */
49   memset(&s_sock, 0, sizeof(s_sock));
50   memcpy(&s_sock.sin_addr, host->h_addr, sizeof(s_sock.sin_addr));
51   s_sock.sin_family = AF_INET;
52   if (port)
53     s_sock.sin_port = port;
54   else
55     s_sock.sin_port = k_getportbyname (service, "tcp", htons(SAMPLE_PORT));
56
57   if (gethostname(myhostname, sizeof(myhostname)) < 0) {
58     warn("gethostname");
59     return 1;
60   }
61
62   if ((host = gethostbyname(myhostname)) == NULL) {
63     fprintf(stderr, "%s: unknown host\n", myhostname);
64     return 1;
65   }
66
67   /* Open a socket */
68   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
69     warn("socket SOCK_DGRAM");
70     return 1;
71   }
72
73   memset(&c_sock, 0, sizeof(c_sock));
74   memcpy(&c_sock.sin_addr, host->h_addr, sizeof(c_sock.sin_addr));
75   c_sock.sin_family = AF_INET;
76
77   /* Bind it to set the address; kernel will fill in port # */
78   if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) {
79     warn("bind");
80     return 1;
81   }
82         
83   /* Get local realm, not needed, just an example */
84   if ((i = krb_get_lrealm(c_realm, 1)) != KSUCCESS) {
85     fprintf(stderr, "can't find local Kerberos realm\n");
86     return 1;
87   }
88   printf("Local Kerberos realm is %s\n", c_realm);
89
90   /* Get Kerberos realm of host */
91   s_realm = krb_realmofhost(hostname);
92
93   /* PREPARE KRB_MK_REQ MESSAGE */
94
95   /* Get credentials for server, create krb_mk_req message */
96   if ((i = krb_mk_req(ktxt, service, hostname, s_realm, cksum))
97       != KSUCCESS) {
98     fprintf(stderr, "%s\n", krb_get_err_text(i));
99     return 1;
100   }
101   printf("Got credentials for %s.\n", service);
102
103   /* Send authentication info to server */
104   i = sendto(sock, (char *)ktxt->dat, ktxt->length, flags,
105              (struct sockaddr *)&s_sock, sizeof(s_sock));
106   if (i < 0)
107     warn("sending datagram message");
108   printf("Sent authentication data: %d bytes\n", i);
109
110   /* PREPARE KRB_MK_SAFE MESSAGE */
111
112   /* Get my address */
113   memset(&c_sock, 0, sizeof(c_sock));
114   i = sizeof(c_sock);
115   if (getsockname(sock, (struct sockaddr *)&c_sock, &i) < 0) {
116     warn("getsockname");
117     return 1;
118   }
119
120   /* Get session key */
121   i = krb_get_cred(service, hostname, s_realm, cred);
122   if (i != KSUCCESS)
123     return 1;
124
125   /* Make the safe message */
126   len = krb_mk_safe(MSG, ktxt->dat, strlen(MSG)+1,
127                     &cred->session, &c_sock, &s_sock);
128
129   /* Send it */
130   i = sendto(sock, (char *)ktxt->dat, (int) len, flags,
131              (struct sockaddr *)&s_sock, sizeof(s_sock));
132   if (i < 0)
133     warn("sending safe message");
134   printf("Sent checksummed message: %d bytes\n", i);
135
136   /* PREPARE KRB_MK_PRIV MESSAGE */
137
138 #ifdef NOENCRYPTION
139   memset(sched, 0, sizeof(sched));
140 #else
141   /* Get key schedule for session key */
142   des_key_sched(&cred->session, sched);
143 #endif
144
145   /* Make the encrypted message */
146   len = krb_mk_priv(MSG, ktxt->dat, strlen(MSG)+1,
147                     sched, &cred->session, &c_sock, &s_sock);
148
149   /* Send it */
150   i = sendto(sock, (char *)ktxt->dat, (int) len, flags,
151              (struct sockaddr *)&s_sock, sizeof(s_sock));
152   if (i < 0)
153     warn("sending encrypted message");
154   printf("Sent encrypted message: %d bytes\n", i);
155   return 0;
156 }
157
158 static void
159 usage (void)
160 {
161   fprintf (stderr, "Usage: %s [-s service] [-p port] hostname\n",
162            __progname);
163   exit (1);
164 }
165
166 int
167 main(int argc, char **argv)
168 {
169   int ret = 0;
170   int port = 0;
171   char service[SNAME_SZ];
172   struct servent *serv;
173   int c;
174
175   set_progname (argv[0]);
176
177   strlcpy (service, SAMPLE_SERVICE, sizeof(service));
178
179   while ((c = getopt(argc, argv, "s:p:")) != -1)
180     switch(c) {
181     case 's' :
182       strlcpy (service, optarg, sizeof(service));
183       break;
184     case 'p' :
185       serv = getservbyname (optarg, "tcp");
186       if (serv)
187         port = serv->s_port;
188       else
189         port = htons(atoi(optarg));
190       break;
191     case '?' :
192     default :
193       usage();
194     }
195
196   argc -= optind;
197   argv += optind;
198
199   while (argc-- > 0)
200     ret &= talkto (*argv++, service, port);
201   return ret;
202 }