1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* appl/simple/server/sim_server.c */
4 * Copyright 1989,1991 by the Massachusetts Institute of Technology.
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.
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.
29 * sample_server servername
31 * Simple UDP-based server application. For demonstration.
32 * This program performs no useful function.
36 #include "port-sockets.h"
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
45 #include <arpa/inet.h>
51 /* for old Unixes and friends ... */
52 #ifndef MAXHOSTNAMELEN
53 #define MAXHOSTNAMELEN 64
56 #define PROGNAME argv[0]
61 fprintf(stderr, "usage: %s [-p port] [-s service] [-S keytab]\n", name);
65 main(int argc, char *argv[])
69 int flags = 0; /* for recvfrom() */
72 struct sockaddr_in s_sock; /* server's address */
73 struct sockaddr_in c_sock; /* client's address */
78 short port = 0; /* If user specifies port */
79 krb5_keytab keytab = NULL; /* Allow specification on command line */
80 char *service = SIMPLE_SERVICE;
82 krb5_error_code retval;
83 krb5_data packet, message;
84 unsigned char pktbuf[BUFSIZ];
85 krb5_principal sprinc;
87 krb5_auth_context auth_context = NULL;
89 krb5_ticket *ticket = NULL;
91 retval = krb5_init_context(&context);
93 com_err(argv[0], retval, "while initializing krb5");
98 * Parse command line arguments
101 while ((ch = getopt(argc, argv, "p:s:S:")) != -1) {
110 if ((retval = krb5_kt_resolve(context, optarg, &keytab))) {
111 com_err(PROGNAME, retval,
112 "while resolving keytab file %s", optarg);
125 if ((retval = krb5_sname_to_principal(context, NULL, service,
126 KRB5_NT_SRV_HST, &sprinc))) {
127 com_err(PROGNAME, retval, "while generating service name %s", service);
131 /* Set up server address */
132 memset(&s_sock, 0, sizeof(s_sock));
133 s_sock.sin_family = AF_INET;
134 s_sock.sin_addr.s_addr = INADDR_ANY;
137 /* Look up service */
138 if ((serv = getservbyname(SIMPLE_PORT, "udp")) == NULL) {
139 fprintf(stderr, "service unknown: %s/udp\n", SIMPLE_PORT);
142 s_sock.sin_port = serv->s_port;
144 s_sock.sin_port = htons(port);
148 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
149 perror("opening datagram socket");
153 /* Let the socket be reused right away */
154 (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
157 /* Bind the socket */
158 if (bind(sock, (struct sockaddr *)&s_sock, sizeof(s_sock))) {
159 perror("binding datagram socket");
163 printf("starting...\n");
167 printf("socket has port # %d\n", ntohs(s_sock.sin_port));
170 /* GET KRB_AP_REQ MESSAGE */
172 /* use "recvfrom" so we know client's address */
173 len = sizeof(struct sockaddr_in);
174 if ((i = recvfrom(sock, (char *)pktbuf, sizeof(pktbuf), flags,
175 (struct sockaddr *)&c_sock, &len)) < 0) {
176 perror("receiving datagram");
180 printf("Received %d bytes\n", i);
182 packet.data = (krb5_pointer) pktbuf;
184 /* Check authentication info */
185 if ((retval = krb5_rd_req(context, &auth_context, &packet,
186 sprinc, keytab, NULL, &ticket))) {
187 com_err(PROGNAME, retval, "while reading request");
190 if ((retval = krb5_unparse_name(context, ticket->enc_part2->client,
192 com_err(PROGNAME, retval, "while unparsing client name");
195 printf("Got authentication info from %s\n", cp);
198 /* Set foreign_addr for rd_safe() and rd_priv() */
199 addr.addrtype = ADDRTYPE_INET;
200 addr.length = sizeof(c_sock.sin_addr);
201 addr.contents = (krb5_octet *)&c_sock.sin_addr;
202 if ((retval = krb5_auth_con_setaddrs(context, auth_context,
204 com_err(PROGNAME, retval, "while setting foreign addr");
208 addr.addrtype = ADDRTYPE_IPPORT;
209 addr.length = sizeof(c_sock.sin_port);
210 addr.contents = (krb5_octet *)&c_sock.sin_port;
211 if ((retval = krb5_auth_con_setports(context, auth_context,
213 com_err(PROGNAME, retval, "while setting foreign port");
217 /* GET KRB_MK_SAFE MESSAGE */
219 /* use "recvfrom" so we know client's address */
220 len = sizeof(struct sockaddr_in);
221 if ((i = recvfrom(sock, (char *)pktbuf, sizeof(pktbuf), flags,
222 (struct sockaddr *)&c_sock, &len)) < 0) {
223 perror("receiving datagram");
227 printf("&c_sock.sin_addr is %s\n", inet_ntoa(c_sock.sin_addr));
229 printf("Received %d bytes\n", i);
232 packet.data = (krb5_pointer) pktbuf;
234 if ((retval = krb5_rd_safe(context, auth_context, &packet,
236 com_err(PROGNAME, retval, "while verifying SAFE message");
239 printf("Safe message is: '%.*s'\n", (int) message.length, message.data);
241 krb5_free_data_contents(context, &message);
243 /* NOW GET ENCRYPTED MESSAGE */
245 /* use "recvfrom" so we know client's address */
246 len = sizeof(struct sockaddr_in);
247 if ((i = recvfrom(sock, (char *)pktbuf, sizeof(pktbuf), flags,
248 (struct sockaddr *)&c_sock, &len)) < 0) {
249 perror("receiving datagram");
252 printf("Received %d bytes\n", i);
255 packet.data = (krb5_pointer) pktbuf;
257 if ((retval = krb5_rd_priv(context, auth_context, &packet,
259 com_err(PROGNAME, retval, "while verifying PRIV message");
262 printf("Decrypted message is: '%.*s'\n", (int) message.length,
265 krb5_auth_con_free(context, auth_context);
266 krb5_free_context(context);