1/*
2 * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "test_locl.h"
35RCSID("$Id$");
36
37krb5_context context;
38
39static int
40proto (int sock, const char *hostname, const char *service)
41{
42    struct sockaddr_in remote, local;
43    socklen_t addrlen;
44    krb5_address remote_addr, local_addr;
45    krb5_context context;
46    krb5_ccache ccache;
47    krb5_auth_context auth_context;
48    krb5_error_code status;
49    krb5_principal client;
50    krb5_data data;
51    krb5_data packet;
52    krb5_creds mcred, cred;
53    krb5_ticket *ticket;
54
55    addrlen = sizeof(local);
56    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
57	|| addrlen != sizeof(local))
58	err (1, "getsockname(%s)", hostname);
59
60    addrlen = sizeof(remote);
61    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
62	|| addrlen != sizeof(remote))
63	err (1, "getpeername(%s)", hostname);
64
65    status = krb5_init_context(&context);
66    if (status)
67	errx(1, "krb5_init_context failed: %d", status);
68
69    status = krb5_cc_default (context, &ccache);
70    if (status)
71	krb5_err(context, 1, status, "krb5_cc_default");
72
73    status = krb5_auth_con_init (context, &auth_context);
74    if (status)
75	krb5_err(context, 1, status, "krb5_auth_con_init");
76
77    local_addr.addr_type = AF_INET;
78    local_addr.address.length = sizeof(local.sin_addr);
79    local_addr.address.data   = &local.sin_addr;
80
81    remote_addr.addr_type = AF_INET;
82    remote_addr.address.length = sizeof(remote.sin_addr);
83    remote_addr.address.data   = &remote.sin_addr;
84
85    status = krb5_auth_con_setaddrs (context,
86				     auth_context,
87				     &local_addr,
88				     &remote_addr);
89    if (status)
90	krb5_err(context, 1, status, "krb5_auth_con_setaddr");
91
92    krb5_cc_clear_mcred(&mcred);
93
94    status = krb5_cc_get_principal(context, ccache, &client);
95    if(status)
96	krb5_err(context, 1, status, "krb5_cc_get_principal");
97    status = krb5_make_principal(context, &mcred.server,
98				 krb5_principal_get_realm(context, client),
99				 "krbtgt",
100				 krb5_principal_get_realm(context, client),
101				 NULL);
102    if(status)
103	krb5_err(context, 1, status, "krb5_make_principal");
104    mcred.client = client;
105
106    status = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
107    if(status)
108	krb5_err(context, 1, status, "krb5_cc_retrieve_cred");
109
110    {
111	char *client_name;
112	krb5_data data;
113	status = krb5_unparse_name(context, cred.client, &client_name);
114	if(status)
115	    krb5_err(context, 1, status, "krb5_unparse_name");
116	data.data = client_name;
117	data.length = strlen(client_name) + 1;
118	status = krb5_write_message(context, &sock, &data);
119	if(status)
120	    krb5_err(context, 1, status, "krb5_write_message");
121	free(client_name);
122    }
123
124    status = krb5_write_message(context, &sock, &cred.ticket);
125    if(status)
126	krb5_err(context, 1, status, "krb5_write_message");
127
128    status = krb5_auth_con_setuserkey(context, auth_context, &cred.session);
129    if(status)
130	krb5_err(context, 1, status, "krb5_auth_con_setuserkey");
131
132    status = krb5_recvauth(context, &auth_context, &sock,
133			   VERSION, client, 0, NULL, &ticket);
134
135    if (status)
136	krb5_err(context, 1, status, "krb5_recvauth");
137
138    if (ticket->ticket.authorization_data) {
139	AuthorizationData *authz;
140	int i;
141
142	printf("Authorization data:\n");
143
144	authz = ticket->ticket.authorization_data;
145	for (i = 0; i < authz->len; i++) {
146	    printf("\ttype %d, length %lu\n",
147		   authz->val[i].ad_type,
148		   (unsigned long)authz->val[i].ad_data.length);
149	}
150    }
151
152    data.data   = "hej";
153    data.length = 3;
154
155    krb5_data_zero (&packet);
156
157    status = krb5_mk_safe (context,
158			   auth_context,
159			   &data,
160			   &packet,
161			   NULL);
162    if (status)
163	krb5_err(context, 1, status, "krb5_mk_safe");
164
165    status = krb5_write_message(context, &sock, &packet);
166    if(status)
167	krb5_err(context, 1, status, "krb5_write_message");
168
169    data.data   = "hemligt";
170    data.length = 7;
171
172    krb5_data_free (&packet);
173
174    status = krb5_mk_priv (context,
175			   auth_context,
176			   &data,
177			   &packet,
178			   NULL);
179    if (status)
180	krb5_err(context, 1, status, "krb5_mk_priv");
181
182    status = krb5_write_message(context, &sock, &packet);
183    if(status)
184	krb5_err(context, 1, status, "krb5_write_message");
185    return 0;
186}
187
188int
189main(int argc, char **argv)
190{
191    int port = client_setup(&context, &argc, argv);
192    return client_doit (argv[argc], port, service_str, proto);
193}
194