xref: /freebsd/crypto/krb5/src/appl/user_user/server.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
1 
2 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 /* appl/user_user/server.c - One end of user-user client-server pair */
4 /*
5  * Copyright 1991 by the Massachusetts Institute of Technology.
6  * All Rights Reserved.
7  *
8  * Export of this software from the United States of America may
9  *   require a specific license from the United States Government.
10  *   It is the responsibility of any person or organization contemplating
11  *   export to obtain such a license before exporting.
12  *
13  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
14  * distribute this software and its documentation for any purpose and
15  * without fee is hereby granted, provided that the above copyright
16  * notice appear in all copies and that both that copyright notice and
17  * this permission notice appear in supporting documentation, and that
18  * the name of M.I.T. not be used in advertising or publicity pertaining
19  * to distribution of the software without specific, written prior
20  * permission.  Furthermore if you modify this software you must label
21  * your software as modified software and not distribute it in such a
22  * fashion that it might be confused with the original M.I.T. software.
23  * M.I.T. makes no representations about the suitability of
24  * this software for any purpose.  It is provided "as is" without express
25  * or implied warranty.
26  */
27 
28 #include "k5-int.h"
29 #include "port-sockets.h"
30 #include "com_err.h"
31 
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <netdb.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 
40 /* fd 0 is a tcp socket used to talk to the client */
41 
42 int
main(int argc,char * argv[])43 main(int argc, char *argv[])
44 {
45     krb5_data pname_data, tkt_data;
46     int sock = 0;
47     socklen_t l;
48     int retval;
49     struct sockaddr_in l_inaddr, f_inaddr;        /* local, foreign address */
50     krb5_creds creds, *new_creds;
51     krb5_ccache cc;
52     krb5_data msgtext, msg;
53     krb5_context context;
54     krb5_auth_context auth_context = NULL;
55 
56 #ifndef DEBUG
57     freopen("/tmp/uu-server.log", "w", stderr);
58 #endif
59 
60     retval = krb5_init_context(&context);
61     if (retval) {
62         com_err(argv[0], retval, "while initializing krb5");
63         exit(1);
64     }
65 
66 #ifdef DEBUG
67     {
68         int one = 1;
69         int acc;
70         struct servent *sp;
71         socklen_t namelen = sizeof(f_inaddr);
72 
73         if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
74             com_err("uu-server", errno, "creating socket");
75             exit(3);
76         }
77 
78         l_inaddr.sin_family = AF_INET;
79         l_inaddr.sin_addr.s_addr = 0;
80         if (argc == 2) {
81             l_inaddr.sin_port = htons(atoi(argv[1]));
82         } else  {
83             if (!(sp = getservbyname("uu-sample", "tcp"))) {
84                 com_err("uu-server", 0, "can't find uu-sample/tcp service");
85                 exit(3);
86             }
87             l_inaddr.sin_port = sp->s_port;
88         }
89 
90         (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (one));
91         if (bind(sock, (struct sockaddr *)&l_inaddr, sizeof(l_inaddr))) {
92             com_err("uu-server", errno, "binding socket");
93             exit(3);
94         }
95         if (listen(sock, 1) == -1) {
96             com_err("uu-server", errno, "listening");
97             exit(3);
98         }
99 
100         printf("Server started\n");
101         fflush(stdout);
102 
103         if ((acc = accept(sock, (struct sockaddr *)&f_inaddr, &namelen)) == -1) {
104             com_err("uu-server", errno, "accepting");
105             exit(3);
106         }
107         dup2(acc, 0);
108         close(sock);
109         sock = 0;
110     }
111 #endif
112 
113     /* principal name must be sent null-terminated. */
114     retval = krb5_read_message(context, (krb5_pointer) &sock, &pname_data);
115     if (retval || pname_data.length == 0 ||
116         pname_data.data[pname_data.length - 1] != '\0') {
117         com_err ("uu-server", retval, "reading pname");
118         return 2;
119     }
120 
121     retval = krb5_read_message(context, (krb5_pointer) &sock, &tkt_data);
122     if (retval) {
123         com_err ("uu-server", retval, "reading ticket data");
124         return 2;
125     }
126 
127     retval = krb5_cc_default(context, &cc);
128     if (retval) {
129         com_err("uu-server", retval, "getting credentials cache");
130         return 4;
131     }
132 
133     memset (&creds, 0, sizeof(creds));
134     retval = krb5_cc_get_principal(context, cc, &creds.client);
135     if (retval) {
136         com_err("uu-client", retval, "getting principal name");
137         return 6;
138     }
139 
140     /* client sends it already null-terminated. */
141     printf ("uu-server: client principal is \"%s\".\n", pname_data.data);
142 
143     retval = krb5_parse_name(context, pname_data.data, &creds.server);
144     if (retval) {
145         com_err("uu-server", retval, "parsing client name");
146         return 3;
147     }
148 
149     creds.second_ticket = tkt_data;
150     printf ("uu-server: client ticket is %d bytes.\n",
151             creds.second_ticket.length);
152 
153     retval = krb5_get_credentials(context, KRB5_GC_USER_USER, cc,
154                                   &creds, &new_creds);
155     if (retval) {
156         com_err("uu-server", retval, "getting user-user ticket");
157         return 5;
158     }
159 
160 #ifndef DEBUG
161     l = sizeof(f_inaddr);
162     if (getpeername(0, (struct sockaddr *)&f_inaddr, &l) == -1)
163     {
164         com_err("uu-server", errno, "getting client address");
165         return 6;
166     }
167 #endif
168     l = sizeof(l_inaddr);
169     if (getsockname(0, (struct sockaddr *)&l_inaddr, &l) == -1)
170     {
171         com_err("uu-server", errno, "getting local address");
172         return 6;
173     }
174 
175     /* send a ticket/authenticator to the other side, so it can get the key
176        we're using for the krb_safe below. */
177 
178     retval = krb5_auth_con_init(context, &auth_context);
179     if (retval) {
180         com_err("uu-server", retval, "making auth_context");
181         return 8;
182     }
183 
184     retval = krb5_auth_con_setflags(context, auth_context,
185                                     KRB5_AUTH_CONTEXT_DO_SEQUENCE);
186     if (retval) {
187         com_err("uu-server", retval, "initializing the auth_context flags");
188         return 8;
189     }
190 
191     retval =
192         krb5_auth_con_genaddrs(context, auth_context, sock,
193                                KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR |
194                                KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
195     if (retval) {
196         com_err("uu-server", retval, "generating addrs for auth_context");
197         return 9;
198     }
199 
200 #if 1
201     retval = krb5_mk_req_extended(context, &auth_context,
202                                   AP_OPTS_USE_SESSION_KEY,
203                                   NULL, new_creds, &msg);
204     if (retval) {
205         com_err("uu-server", retval, "making AP_REQ");
206         return 8;
207     }
208     retval = krb5_write_message(context, (krb5_pointer) &sock, &msg);
209 #else
210     retval = krb5_sendauth(context, &auth_context, (krb5_pointer)&sock, "???",
211                            0, 0,
212                            AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SESSION_KEY,
213                            NULL, &creds, cc, NULL, NULL, NULL);
214 #endif
215     if (retval)
216         goto cl_short_wrt;
217 
218     free(msg.data);
219 
220     msgtext.length = 32;
221     msgtext.data = "Hello, other end of connection.";
222 
223     retval = krb5_mk_safe(context, auth_context, &msgtext, &msg, NULL);
224     if (retval) {
225         com_err("uu-server", retval, "encoding message to client");
226         return 6;
227     }
228 
229     retval = krb5_write_message(context, (krb5_pointer) &sock, &msg);
230     if (retval) {
231     cl_short_wrt:
232         com_err("uu-server", retval, "writing message to client");
233         return 7;
234     }
235 
236 
237     krb5_free_data_contents(context, &msg);
238     krb5_free_data_contents(context, &pname_data);
239     /* tkt_data freed with creds */
240     krb5_free_cred_contents(context, &creds);
241     krb5_free_creds(context, new_creds);
242     krb5_cc_close(context, cc);
243     krb5_auth_con_free(context, auth_context);
244     krb5_free_context(context);
245     return 0;
246 }
247