155682Smarkm/*
2233294Sstas * Copyright (c) 1997 - 2000, 2007 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
555682Smarkm *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
955682Smarkm *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
18233294Sstas *    may be used to endorse or promote products derived from this software
19233294Sstas *    without specific prior written permission.
2055682Smarkm *
21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31233294Sstas * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "test_locl.h"
35233294SstasRCSID("$Id$");
3655682Smarkm
3755682Smarkmkrb5_context context;
3855682Smarkm
3955682Smarkmstatic int
4055682Smarkmproto (int sock, const char *service)
4155682Smarkm{
4255682Smarkm    struct sockaddr_in remote, local;
4372445Sassar    socklen_t addrlen;
4455682Smarkm    krb5_address remote_addr, local_addr;
4555682Smarkm    krb5_ccache ccache;
4655682Smarkm    krb5_auth_context auth_context;
4755682Smarkm    krb5_error_code status;
4855682Smarkm    krb5_data packet;
4955682Smarkm    krb5_data data;
5055682Smarkm    krb5_data client_name;
5155682Smarkm    krb5_creds in_creds, *out_creds;
5255682Smarkm
5355682Smarkm    addrlen = sizeof(local);
5455682Smarkm    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
5555682Smarkm	|| addrlen != sizeof(local))
5655682Smarkm	err (1, "getsockname)");
5755682Smarkm
5855682Smarkm    addrlen = sizeof(remote);
5955682Smarkm    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
6055682Smarkm	|| addrlen != sizeof(remote))
6155682Smarkm	err (1, "getpeername");
6255682Smarkm
6355682Smarkm    status = krb5_auth_con_init (context, &auth_context);
6455682Smarkm    if (status)
65233294Sstas	krb5_err(context, 1, status, "krb5_auth_con_init");
6655682Smarkm
6755682Smarkm    local_addr.addr_type = AF_INET;
6855682Smarkm    local_addr.address.length = sizeof(local.sin_addr);
6955682Smarkm    local_addr.address.data   = &local.sin_addr;
7055682Smarkm
7155682Smarkm    remote_addr.addr_type = AF_INET;
7255682Smarkm    remote_addr.address.length = sizeof(remote.sin_addr);
7355682Smarkm    remote_addr.address.data   = &remote.sin_addr;
7455682Smarkm
7555682Smarkm    status = krb5_auth_con_setaddrs (context,
7655682Smarkm				     auth_context,
7755682Smarkm				     &local_addr,
7855682Smarkm				     &remote_addr);
7955682Smarkm    if (status)
80233294Sstas	krb5_err(context, 1, status, "krb5_auth_con_setaddr");
8155682Smarkm
8255682Smarkm    status = krb5_read_message(context, &sock, &client_name);
8355682Smarkm    if(status)
8455682Smarkm	krb5_err(context, 1, status, "krb5_read_message");
85233294Sstas
8655682Smarkm    memset(&in_creds, 0, sizeof(in_creds));
8755682Smarkm    status = krb5_cc_default(context, &ccache);
88233294Sstas    if(status)
89233294Sstas	krb5_err(context, 1, status, "krb5_cc_default");
9055682Smarkm    status = krb5_cc_get_principal(context, ccache, &in_creds.client);
91233294Sstas    if(status)
92233294Sstas	krb5_err(context, 1, status, "krb5_cc_get_principal");
9355682Smarkm
9455682Smarkm    status = krb5_read_message(context, &sock, &in_creds.second_ticket);
9555682Smarkm    if(status)
9655682Smarkm	krb5_err(context, 1, status, "krb5_read_message");
9755682Smarkm
9855682Smarkm    status = krb5_parse_name(context, client_name.data, &in_creds.server);
9955682Smarkm    if(status)
10055682Smarkm	krb5_err(context, 1, status, "krb5_parse_name");
101233294Sstas
102233294Sstas    status = krb5_get_credentials(context, KRB5_GC_USER_USER, ccache,
10355682Smarkm				  &in_creds, &out_creds);
10455682Smarkm    if(status)
10555682Smarkm	krb5_err(context, 1, status, "krb5_get_credentials");
10655682Smarkm
10755682Smarkm    status = krb5_cc_default(context, &ccache);
108233294Sstas    if(status)
109233294Sstas	krb5_err(context, 1, status, "krb5_cc_default");
11055682Smarkm
111233294Sstas    status = krb5_sendauth(context,
11255682Smarkm			   &auth_context,
113233294Sstas			   &sock,
114233294Sstas			   VERSION,
11555682Smarkm			   in_creds.client,
11655682Smarkm			   in_creds.server,
11755682Smarkm			   AP_OPTS_USE_SESSION_KEY,
11855682Smarkm			   NULL,
11955682Smarkm			   out_creds,
12055682Smarkm			   ccache,
12155682Smarkm			   NULL,
12255682Smarkm			   NULL,
12355682Smarkm			   NULL);
124233294Sstas
12555682Smarkm    if (status)
12655682Smarkm	krb5_err(context, 1, status, "krb5_sendauth");
127233294Sstas
128178825Sdfr    {
129178825Sdfr	char *str;
130178825Sdfr	krb5_unparse_name(context, in_creds.server, &str);
131178825Sdfr	printf ("User is `%s'\n", str);
132178825Sdfr	free(str);
133178825Sdfr	krb5_unparse_name(context, in_creds.client, &str);
134178825Sdfr	printf ("Server is `%s'\n", str);
135178825Sdfr	free(str);
136178825Sdfr    }
13755682Smarkm
13855682Smarkm    krb5_data_zero (&data);
13955682Smarkm    krb5_data_zero (&packet);
14055682Smarkm
14155682Smarkm    status = krb5_read_message(context, &sock, &packet);
14255682Smarkm    if(status)
14355682Smarkm	krb5_err(context, 1, status, "krb5_read_message");
144233294Sstas
14555682Smarkm    status = krb5_rd_safe (context,
14655682Smarkm			   auth_context,
14755682Smarkm			   &packet,
14855682Smarkm			   &data,
14955682Smarkm			   NULL);
15055682Smarkm    if (status)
151233294Sstas	krb5_err(context, 1, status, "krb5_rd_safe");
15255682Smarkm
153178825Sdfr    printf ("safe packet: %.*s\n", (int)data.length,
15455682Smarkm	    (char *)data.data);
15555682Smarkm
15655682Smarkm    status = krb5_read_message(context, &sock, &packet);
15755682Smarkm    if(status)
15855682Smarkm	krb5_err(context, 1, status, "krb5_read_message");
159233294Sstas
16055682Smarkm    status = krb5_rd_priv (context,
16155682Smarkm			   auth_context,
16255682Smarkm			   &packet,
16355682Smarkm			   &data,
16455682Smarkm			   NULL);
16555682Smarkm    if (status)
166233294Sstas	krb5_err(context, 1, status, "krb5_rd_priv");
16755682Smarkm
168178825Sdfr    printf ("priv packet: %.*s\n", (int)data.length,
16955682Smarkm	    (char *)data.data);
17055682Smarkm
17155682Smarkm    return 0;
17255682Smarkm}
17355682Smarkm
17455682Smarkmstatic int
17555682Smarkmdoit (int port, const char *service)
17655682Smarkm{
17755682Smarkm    int sock, sock2;
17855682Smarkm    struct sockaddr_in my_addr;
17955682Smarkm    int one = 1;
18055682Smarkm
18155682Smarkm    sock = socket (AF_INET, SOCK_STREAM, 0);
18255682Smarkm    if (sock < 0)
18355682Smarkm	err (1, "socket");
18455682Smarkm
18555682Smarkm    memset (&my_addr, 0, sizeof(my_addr));
18655682Smarkm    my_addr.sin_family      = AF_INET;
18755682Smarkm    my_addr.sin_port        = port;
18855682Smarkm    my_addr.sin_addr.s_addr = INADDR_ANY;
18955682Smarkm
190233294Sstas    if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
19155682Smarkm		    (void *)&one, sizeof(one)) < 0)
19255682Smarkm	warn ("setsockopt SO_REUSEADDR");
19355682Smarkm
19455682Smarkm    if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
19555682Smarkm	err (1, "bind");
19655682Smarkm
19755682Smarkm    if (listen (sock, 1) < 0)
19855682Smarkm	err (1, "listen");
19955682Smarkm
20055682Smarkm    sock2 = accept (sock, NULL, NULL);
20155682Smarkm    if (sock2 < 0)
20255682Smarkm	err (1, "accept");
20355682Smarkm
20455682Smarkm    return proto (sock2, service);
20555682Smarkm}
20655682Smarkm
20755682Smarkmint
20855682Smarkmmain(int argc, char **argv)
20955682Smarkm{
21055682Smarkm    int port = server_setup(&context, argc, argv);
21155682Smarkm    return doit (port, service);
21255682Smarkm}
213