gssapi_server.c revision 57419
155682Smarkm/* 257419Smarkm * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "test_locl.h" 3555682Smarkm#include <gssapi.h> 3655682Smarkm#include "gss_common.h" 3757419SmarkmRCSID("$Id: gssapi_server.c,v 1.12 2000/02/12 21:34:11 assar Exp $"); 3855682Smarkm 3955682Smarkmstatic int 4057419Smarkmprocess_it(int sock, 4157419Smarkm gss_ctx_id_t context_hdl, 4257419Smarkm gss_name_t client_name 4357419Smarkm ) 4457419Smarkm{ 4557419Smarkm OM_uint32 maj_stat, min_stat; 4657419Smarkm gss_buffer_desc name_token; 4757419Smarkm gss_buffer_desc real_input_token, real_output_token; 4857419Smarkm gss_buffer_t input_token = &real_input_token, 4957419Smarkm output_token = &real_output_token; 5057419Smarkm 5157419Smarkm maj_stat = gss_display_name (&min_stat, 5257419Smarkm client_name, 5357419Smarkm &name_token, 5457419Smarkm NULL); 5557419Smarkm if (GSS_ERROR(maj_stat)) 5657419Smarkm gss_err (1, min_stat, "gss_display_name"); 5757419Smarkm 5857419Smarkm fprintf (stderr, "User is `%.*s'\n", (int)name_token.length, 5957419Smarkm (char *)name_token.value); 6057419Smarkm 6157419Smarkm gss_release_buffer (&min_stat, &name_token); 6257419Smarkm 6357419Smarkm /* gss_verify_mic */ 6457419Smarkm 6557419Smarkm read_token (sock, input_token); 6657419Smarkm read_token (sock, output_token); 6757419Smarkm 6857419Smarkm maj_stat = gss_verify_mic (&min_stat, 6957419Smarkm context_hdl, 7057419Smarkm input_token, 7157419Smarkm output_token, 7257419Smarkm NULL); 7357419Smarkm if (GSS_ERROR(maj_stat)) 7457419Smarkm gss_err (1, min_stat, "gss_verify_mic"); 7557419Smarkm 7657419Smarkm fprintf (stderr, "gss_verify_mic: %.*s\n", (int)input_token->length, 7757419Smarkm (char *)input_token->value); 7857419Smarkm 7957419Smarkm gss_release_buffer (&min_stat, input_token); 8057419Smarkm gss_release_buffer (&min_stat, output_token); 8157419Smarkm 8257419Smarkm /* gss_unwrap */ 8357419Smarkm 8457419Smarkm read_token (sock, input_token); 8557419Smarkm 8657419Smarkm maj_stat = gss_unwrap (&min_stat, 8757419Smarkm context_hdl, 8857419Smarkm input_token, 8957419Smarkm output_token, 9057419Smarkm NULL, 9157419Smarkm NULL); 9257419Smarkm if(GSS_ERROR(maj_stat)) 9357419Smarkm gss_err (1, min_stat, "gss_unwrap"); 9457419Smarkm 9557419Smarkm fprintf (stderr, "gss_unwrap: %.*s\n", (int)output_token->length, 9657419Smarkm (char *)output_token->value); 9757419Smarkm 9857419Smarkm gss_release_buffer (&min_stat, input_token); 9957419Smarkm gss_release_buffer (&min_stat, output_token); 10057419Smarkm 10157419Smarkm return 0; 10257419Smarkm} 10357419Smarkm 10457419Smarkmstatic int 10555682Smarkmproto (int sock, const char *service) 10655682Smarkm{ 10755682Smarkm struct sockaddr_in remote, local; 10855682Smarkm int addrlen; 10955682Smarkm gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT; 11055682Smarkm gss_buffer_desc real_input_token, real_output_token; 11157419Smarkm gss_buffer_t input_token = &real_input_token, 11257419Smarkm output_token = &real_output_token; 11355682Smarkm OM_uint32 maj_stat, min_stat; 11455682Smarkm gss_name_t client_name; 11555682Smarkm 11655682Smarkm addrlen = sizeof(local); 11755682Smarkm if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0 11855682Smarkm || addrlen != sizeof(local)) 11955682Smarkm err (1, "getsockname)"); 12055682Smarkm 12155682Smarkm addrlen = sizeof(remote); 12255682Smarkm if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0 12355682Smarkm || addrlen != sizeof(remote)) 12455682Smarkm err (1, "getpeername"); 12555682Smarkm 12655682Smarkm do { 12755682Smarkm read_token (sock, input_token); 12855682Smarkm maj_stat = 12955682Smarkm gss_accept_sec_context (&min_stat, 13055682Smarkm &context_hdl, 13155682Smarkm GSS_C_NO_CREDENTIAL, 13255682Smarkm input_token, 13355682Smarkm GSS_C_NO_CHANNEL_BINDINGS, 13455682Smarkm &client_name, 13555682Smarkm NULL, 13655682Smarkm output_token, 13755682Smarkm NULL, 13855682Smarkm NULL, 13955682Smarkm NULL); 14055682Smarkm if(GSS_ERROR(maj_stat)) 14155682Smarkm gss_err (1, min_stat, "gss_accept_sec_context"); 14255682Smarkm if (output_token->length != 0) 14355682Smarkm write_token (sock, output_token); 14455682Smarkm if (GSS_ERROR(maj_stat)) { 14555682Smarkm if (context_hdl != GSS_C_NO_CONTEXT) 14655682Smarkm gss_delete_sec_context (&min_stat, 14755682Smarkm &context_hdl, 14855682Smarkm GSS_C_NO_BUFFER); 14955682Smarkm break; 15055682Smarkm } 15155682Smarkm } while(maj_stat & GSS_S_CONTINUE_NEEDED); 15255682Smarkm 15357419Smarkm if (fork_flag) { 15457419Smarkm pid_t pid; 15557419Smarkm int pipefd[2]; 15655682Smarkm 15757419Smarkm if (pipe (pipefd) < 0) 15857419Smarkm err (1, "pipe"); 15955682Smarkm 16057419Smarkm pid = fork (); 16157419Smarkm if (pid < 0) 16257419Smarkm err (1, "fork"); 16357419Smarkm if (pid != 0) { 16457419Smarkm gss_buffer_desc buf; 16555682Smarkm 16657419Smarkm maj_stat = gss_export_sec_context (&min_stat, 16757419Smarkm &context_hdl, 16857419Smarkm &buf); 16957419Smarkm if (GSS_ERROR(maj_stat)) 17057419Smarkm gss_err (1, min_stat, "gss_export_sec_context"); 17157419Smarkm write_token (pipefd[1], &buf); 17257419Smarkm exit (0); 17357419Smarkm } else { 17457419Smarkm gss_ctx_id_t context_hdl; 17557419Smarkm gss_buffer_desc buf; 17655682Smarkm 17757419Smarkm close (pipefd[1]); 17857419Smarkm read_token (pipefd[0], &buf); 17957419Smarkm close (pipefd[0]); 18057419Smarkm maj_stat = gss_import_sec_context (&min_stat, &buf, &context_hdl); 18157419Smarkm if (GSS_ERROR(maj_stat)) 18257419Smarkm gss_err (1, min_stat, "gss_import_sec_context"); 18357419Smarkm gss_release_buffer (&min_stat, &buf); 18457419Smarkm return process_it (sock, context_hdl, client_name); 18557419Smarkm } 18657419Smarkm } else { 18757419Smarkm return process_it (sock, context_hdl, client_name); 18857419Smarkm } 18955682Smarkm} 19055682Smarkm 19155682Smarkmstatic int 19255682Smarkmdoit (int port, const char *service) 19355682Smarkm{ 19455682Smarkm int sock, sock2; 19555682Smarkm struct sockaddr_in my_addr; 19655682Smarkm int one = 1; 19755682Smarkm 19855682Smarkm sock = socket (AF_INET, SOCK_STREAM, 0); 19955682Smarkm if (sock < 0) 20055682Smarkm err (1, "socket"); 20155682Smarkm 20255682Smarkm memset (&my_addr, 0, sizeof(my_addr)); 20355682Smarkm my_addr.sin_family = AF_INET; 20455682Smarkm my_addr.sin_port = port; 20555682Smarkm my_addr.sin_addr.s_addr = INADDR_ANY; 20655682Smarkm 20755682Smarkm if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 20855682Smarkm (void *)&one, sizeof(one)) < 0) 20955682Smarkm warn ("setsockopt SO_REUSEADDR"); 21055682Smarkm 21155682Smarkm if (bind (sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) 21255682Smarkm err (1, "bind"); 21355682Smarkm 21455682Smarkm if (listen (sock, 1) < 0) 21555682Smarkm err (1, "listen"); 21655682Smarkm 21755682Smarkm sock2 = accept (sock, NULL, NULL); 21855682Smarkm if (sock2 < 0) 21955682Smarkm err (1, "accept"); 22055682Smarkm 22155682Smarkm return proto (sock2, service); 22255682Smarkm} 22355682Smarkm 22455682Smarkmint 22555682Smarkmmain(int argc, char **argv) 22655682Smarkm{ 22755682Smarkm krb5_context context = NULL; /* XXX */ 22855682Smarkm int port = server_setup(&context, argc, argv); 22955682Smarkm return doit (port, service); 23055682Smarkm} 231