1 /* 2 * Copyright (c) 1997 - 2000, 2007 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" 35 RCSID("$Id$"); 36 37 krb5_context context; 38 39 static int 40 proto (int sock, const char *service) 41 { 42 struct sockaddr_in remote, local; 43 socklen_t addrlen; 44 krb5_address remote_addr, local_addr; 45 krb5_ccache ccache; 46 krb5_auth_context auth_context; 47 krb5_error_code status; 48 krb5_data packet; 49 krb5_data data; 50 krb5_data client_name; 51 krb5_creds in_creds, *out_creds; 52 53 addrlen = sizeof(local); 54 if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 55 || addrlen != sizeof(local)) 56 err (1, "getsockname)"); 57 58 addrlen = sizeof(remote); 59 if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 60 || addrlen != sizeof(remote)) 61 err (1, "getpeername"); 62 63 status = krb5_auth_con_init (context, &auth_context); 64 if (status) 65 krb5_err(context, 1, status, "krb5_auth_con_init"); 66 67 local_addr.addr_type = AF_INET; 68 local_addr.address.length = sizeof(local.sin_addr); 69 local_addr.address.data = &local.sin_addr; 70 71 remote_addr.addr_type = AF_INET; 72 remote_addr.address.length = sizeof(remote.sin_addr); 73 remote_addr.address.data = &remote.sin_addr; 74 75 status = krb5_auth_con_setaddrs (context, 76 auth_context, 77 &local_addr, 78 &remote_addr); 79 if (status) 80 krb5_err(context, 1, status, "krb5_auth_con_setaddr"); 81 82 status = krb5_read_message(context, &sock, &client_name); 83 if(status) 84 krb5_err(context, 1, status, "krb5_read_message"); 85 86 memset(&in_creds, 0, sizeof(in_creds)); 87 status = krb5_cc_default(context, &ccache); 88 if(status) 89 krb5_err(context, 1, status, "krb5_cc_default"); 90 status = krb5_cc_get_principal(context, ccache, &in_creds.client); 91 if(status) 92 krb5_err(context, 1, status, "krb5_cc_get_principal"); 93 94 status = krb5_read_message(context, &sock, &in_creds.second_ticket); 95 if(status) 96 krb5_err(context, 1, status, "krb5_read_message"); 97 98 status = krb5_parse_name(context, client_name.data, &in_creds.server); 99 if(status) 100 krb5_err(context, 1, status, "krb5_parse_name"); 101 102 status = krb5_get_credentials(context, KRB5_GC_USER_USER, ccache, 103 &in_creds, &out_creds); 104 if(status) 105 krb5_err(context, 1, status, "krb5_get_credentials"); 106 107 status = krb5_cc_default(context, &ccache); 108 if(status) 109 krb5_err(context, 1, status, "krb5_cc_default"); 110 111 status = krb5_sendauth(context, 112 &auth_context, 113 &sock, 114 VERSION, 115 in_creds.client, 116 in_creds.server, 117 AP_OPTS_USE_SESSION_KEY, 118 NULL, 119 out_creds, 120 ccache, 121 NULL, 122 NULL, 123 NULL); 124 125 if (status) 126 krb5_err(context, 1, status, "krb5_sendauth"); 127 128 { 129 char *str; 130 krb5_unparse_name(context, in_creds.server, &str); 131 printf ("User is `%s'\n", str); 132 free(str); 133 krb5_unparse_name(context, in_creds.client, &str); 134 printf ("Server is `%s'\n", str); 135 free(str); 136 } 137 138 krb5_data_zero (&data); 139 krb5_data_zero (&packet); 140 141 status = krb5_read_message(context, &sock, &packet); 142 if(status) 143 krb5_err(context, 1, status, "krb5_read_message"); 144 145 status = krb5_rd_safe (context, 146 auth_context, 147 &packet, 148 &data, 149 NULL); 150 if (status) 151 krb5_err(context, 1, status, "krb5_rd_safe"); 152 153 printf ("safe packet: %.*s\n", (int)data.length, 154 (char *)data.data); 155 156 status = krb5_read_message(context, &sock, &packet); 157 if(status) 158 krb5_err(context, 1, status, "krb5_read_message"); 159 160 status = krb5_rd_priv (context, 161 auth_context, 162 &packet, 163 &data, 164 NULL); 165 if (status) 166 krb5_err(context, 1, status, "krb5_rd_priv"); 167 168 printf ("priv packet: %.*s\n", (int)data.length, 169 (char *)data.data); 170 171 return 0; 172 } 173 174 static int 175 doit (int port, const char *service) 176 { 177 int sock, sock2; 178 struct sockaddr_in my_addr; 179 int one = 1; 180 181 sock = socket (AF_INET, SOCK_STREAM, 0); 182 if (sock < 0) 183 err (1, "socket"); 184 185 memset (&my_addr, 0, sizeof(my_addr)); 186 my_addr.sin_family = AF_INET; 187 my_addr.sin_port = port; 188 my_addr.sin_addr.s_addr = INADDR_ANY; 189 190 if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 191 (void *)&one, sizeof(one)) < 0) 192 warn ("setsockopt SO_REUSEADDR"); 193 194 if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) 195 err (1, "bind"); 196 197 if (listen (sock, 1) < 0) 198 err (1, "listen"); 199 200 sock2 = accept (sock, NULL, NULL); 201 if (sock2 < 0) 202 err (1, "accept"); 203 204 return proto (sock2, service); 205 } 206 207 int 208 main(int argc, char **argv) 209 { 210 int port = server_setup(&context, argc, argv); 211 return doit (port, service); 212 } 213