Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/appl/simple/client/sim_client.c
34914 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* appl/simple/client/sim_client.c */
3
/*
4
* Copyright 1989,1991 by the Massachusetts Institute of Technology.
5
* All Rights Reserved.
6
*
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
11
*
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
25
*/
26
27
/*
28
* Simple UDP-based sample client program. For demonstration.
29
* This program performs no useful function.
30
*/
31
32
#include <krb5.h>
33
#include "com_err.h"
34
35
#include <sys/types.h>
36
#include <sys/socket.h>
37
#include <netinet/in.h>
38
#include <stdio.h>
39
#include <string.h>
40
#include <errno.h>
41
#include <netdb.h>
42
#include <unistd.h>
43
44
#include "simple.h"
45
46
/* for old Unixes and friends ... */
47
#ifndef MAXHOSTNAMELEN
48
#define MAXHOSTNAMELEN 64
49
#endif
50
51
#define MSG "hi there!" /* message text */
52
53
void usage (char *);
54
55
void
56
usage(char *name)
57
{
58
fprintf(stderr, "usage: %s [-p port] [-h host] [-m message] [-s service] [host]\n", name);
59
}
60
61
int
62
main(int argc, char *argv[])
63
{
64
int sock, i;
65
socklen_t len;
66
int flags = 0; /* flags for sendto() */
67
struct servent *serv;
68
struct hostent *host;
69
#ifdef BROKEN_STREAMS_SOCKETS
70
char my_hostname[MAXHOSTNAMELEN];
71
#endif
72
struct sockaddr_in s_sock; /* server address */
73
struct sockaddr_in c_sock; /* client address */
74
extern int opterr, optind;
75
extern char * optarg;
76
int ch;
77
78
short port = 0;
79
char *message = MSG;
80
char *hostname = 0;
81
char *service = SIMPLE_SERVICE;
82
char *progname = 0;
83
84
krb5_error_code retval;
85
krb5_data packet, inbuf;
86
krb5_ccache ccdef;
87
krb5_address addr;
88
89
krb5_context context;
90
krb5_auth_context auth_context = NULL;
91
92
retval = krb5_init_context(&context);
93
if (retval) {
94
com_err(argv[0], retval, "while initializing krb5");
95
exit(1);
96
}
97
98
progname = argv[0];
99
100
/*
101
* Parse command line arguments
102
*
103
*/
104
opterr = 0;
105
while ((ch = getopt(argc, argv, "p:m:h:s:")) != -1)
106
switch (ch) {
107
case 'p':
108
port = atoi(optarg);
109
break;
110
case 'm':
111
message = optarg;
112
break;
113
case 'h':
114
hostname = optarg;
115
break;
116
case 's':
117
service = optarg;
118
break;
119
case '?':
120
default:
121
usage(progname);
122
exit(1);
123
break;
124
}
125
argc -= optind;
126
argv += optind;
127
if (argc > 0) {
128
if (hostname)
129
usage(progname);
130
hostname = argv[0];
131
}
132
133
if (hostname == 0) {
134
fprintf(stderr, "You must specify a hostname to contact.\n\n");
135
usage(progname);
136
exit(1);
137
}
138
139
/* Look up server host */
140
if ((host = gethostbyname(hostname)) == (struct hostent *) 0) {
141
fprintf(stderr, "%s: unknown host\n", hostname);
142
exit(1);
143
}
144
145
/* Set server's address */
146
(void) memset(&s_sock, 0, sizeof(s_sock));
147
148
memcpy(&s_sock.sin_addr, host->h_addr, sizeof(s_sock.sin_addr));
149
#ifdef DEBUG
150
printf("s_sock.sin_addr is %s\n", inet_ntoa(s_sock.sin_addr));
151
#endif
152
s_sock.sin_family = AF_INET;
153
154
if (port == 0) {
155
/* Look up service */
156
if ((serv = getservbyname(SIMPLE_PORT, "udp")) == NULL) {
157
fprintf(stderr, "service unknown: %s/udp\n", SIMPLE_PORT);
158
exit(1);
159
}
160
s_sock.sin_port = serv->s_port;
161
} else {
162
s_sock.sin_port = htons(port);
163
}
164
165
/* Open a socket */
166
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
167
com_err(progname, errno, "opening datagram socket");
168
exit(1);
169
}
170
171
memset(&c_sock, 0, sizeof(c_sock));
172
c_sock.sin_family = AF_INET;
173
#ifdef BROKEN_STREAMS_SOCKETS
174
if (gethostname(my_hostname, sizeof(my_hostname)) < 0) {
175
perror("gethostname");
176
exit(1);
177
}
178
179
if ((host = gethostbyname(my_hostname)) == (struct hostent *)0) {
180
fprintf(stderr, "%s: unknown host\n", hostname);
181
exit(1);
182
}
183
memcpy(&c_sock.sin_addr, host->h_addr, sizeof(c_sock.sin_addr));
184
#endif
185
186
187
/* Bind it to set the address; kernel will fill in port # */
188
if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) {
189
com_err(progname, errno, "while binding datagram socket");
190
exit(1);
191
}
192
193
/* PREPARE KRB_AP_REQ MESSAGE */
194
195
inbuf.data = hostname;
196
inbuf.length = strlen(hostname);
197
198
/* Get credentials for server */
199
if ((retval = krb5_cc_default(context, &ccdef))) {
200
com_err(progname, retval, "while getting default ccache");
201
exit(1);
202
}
203
204
retval = krb5_mk_req(context, &auth_context, AP_OPTS_USE_SUBKEY, service,
205
hostname, &inbuf, ccdef, &packet);
206
if (retval) {
207
com_err(progname, retval, "while preparing AP_REQ");
208
exit(1);
209
}
210
printf("Got credentials for %s.\n", service);
211
212
/* "connect" the datagram socket; this is necessary to get a local address
213
properly bound for getsockname() below. */
214
215
if (connect(sock, (struct sockaddr *)&s_sock, sizeof(s_sock)) == -1) {
216
com_err(progname, errno, "while connecting to server");
217
exit(1);
218
}
219
/* Send authentication info to server */
220
if ((i = send(sock, (char *)packet.data, (unsigned) packet.length,
221
flags)) < 0)
222
com_err(progname, errno, "while sending KRB_AP_REQ message");
223
printf("Sent authentication data: %d bytes\n", i);
224
krb5_free_data_contents(context, &packet);
225
226
/* PREPARE KRB_SAFE MESSAGE */
227
228
/* Get my address */
229
memset(&c_sock, 0, sizeof(c_sock));
230
len = sizeof(c_sock);
231
if (getsockname(sock, (struct sockaddr *)&c_sock, &len) < 0) {
232
com_err(progname, errno, "while getting socket name");
233
exit(1);
234
}
235
236
addr.addrtype = ADDRTYPE_IPPORT;
237
addr.length = sizeof(c_sock.sin_port);
238
addr.contents = (krb5_octet *)&c_sock.sin_port;
239
if ((retval = krb5_auth_con_setports(context, auth_context,
240
&addr, NULL))) {
241
com_err(progname, retval, "while setting local port\n");
242
exit(1);
243
}
244
245
addr.addrtype = ADDRTYPE_INET;
246
addr.length = sizeof(c_sock.sin_addr);
247
addr.contents = (krb5_octet *)&c_sock.sin_addr;
248
if ((retval = krb5_auth_con_setaddrs(context, auth_context,
249
&addr, NULL))) {
250
com_err(progname, retval, "while setting local addr\n");
251
exit(1);
252
}
253
254
/* Make the safe message */
255
inbuf.data = message;
256
inbuf.length = strlen(message);
257
258
if ((retval = krb5_mk_safe(context, auth_context, &inbuf, &packet, NULL))){
259
com_err(progname, retval, "while making KRB_SAFE message");
260
exit(1);
261
}
262
263
/* Send it */
264
if ((i = send(sock, (char *)packet.data, (unsigned) packet.length,
265
flags)) < 0)
266
com_err(progname, errno, "while sending SAFE message");
267
printf("Sent checksummed message: %d bytes\n", i);
268
krb5_free_data_contents(context, &packet);
269
270
/* PREPARE KRB_PRIV MESSAGE */
271
272
/* Make the encrypted message */
273
if ((retval = krb5_mk_priv(context, auth_context, &inbuf,
274
&packet, NULL))) {
275
com_err(progname, retval, "while making KRB_PRIV message");
276
exit(1);
277
}
278
279
/* Send it */
280
if ((i = send(sock, (char *)packet.data, (unsigned) packet.length,
281
flags)) < 0)
282
com_err(progname, errno, "while sending PRIV message");
283
printf("Sent encrypted message: %d bytes\n", i);
284
krb5_free_data_contents(context, &packet);
285
286
krb5_auth_con_free(context, auth_context);
287
krb5_free_context(context);
288
289
exit(0);
290
}
291
292