155682Smarkm/* 2178825Sdfr * Copyright (c) 1997-2007 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 "krb5_locl.h" 3555682Smarkm 36178825SdfrRCSID("$Id: recvauth.c 20306 2007-04-11 11:15:55Z lha $"); 3755682Smarkm 3855682Smarkm/* 3955682Smarkm * See `sendauth.c' for the format. 4055682Smarkm */ 4155682Smarkm 4255682Smarkmstatic krb5_boolean 43102644Snectarmatch_exact(const void *data, const char *appl_version) 4455682Smarkm{ 4555682Smarkm return strcmp(data, appl_version) == 0; 4655682Smarkm} 4755682Smarkm 48178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 4955682Smarkmkrb5_recvauth(krb5_context context, 5055682Smarkm krb5_auth_context *auth_context, 5155682Smarkm krb5_pointer p_fd, 52102644Snectar const char *appl_version, 5355682Smarkm krb5_principal server, 5455682Smarkm int32_t flags, 5555682Smarkm krb5_keytab keytab, 5655682Smarkm krb5_ticket **ticket) 5755682Smarkm{ 5855682Smarkm return krb5_recvauth_match_version(context, auth_context, p_fd, 5955682Smarkm match_exact, appl_version, 6055682Smarkm server, flags, 6155682Smarkm keytab, ticket); 6255682Smarkm} 6355682Smarkm 64178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 6555682Smarkmkrb5_recvauth_match_version(krb5_context context, 6655682Smarkm krb5_auth_context *auth_context, 6755682Smarkm krb5_pointer p_fd, 68102644Snectar krb5_boolean (*match_appl_version)(const void *, 6955682Smarkm const char*), 70102644Snectar const void *match_data, 7155682Smarkm krb5_principal server, 7255682Smarkm int32_t flags, 7355682Smarkm krb5_keytab keytab, 7455682Smarkm krb5_ticket **ticket) 7555682Smarkm{ 76178825Sdfr krb5_error_code ret; 77178825Sdfr const char *version = KRB5_SENDAUTH_VERSION; 78178825Sdfr char her_version[sizeof(KRB5_SENDAUTH_VERSION)]; 79178825Sdfr char *her_appl_version; 80178825Sdfr uint32_t len; 81178825Sdfr u_char repl; 82178825Sdfr krb5_data data; 83178825Sdfr krb5_flags ap_options; 84178825Sdfr ssize_t n; 8555682Smarkm 86178825Sdfr /* 87178825Sdfr * If there are no addresses in auth_context, get them from `fd'. 88178825Sdfr */ 8955682Smarkm 90178825Sdfr if (*auth_context == NULL) { 91178825Sdfr ret = krb5_auth_con_init (context, auth_context); 92178825Sdfr if (ret) 93178825Sdfr return ret; 94178825Sdfr } 9555682Smarkm 96178825Sdfr ret = krb5_auth_con_setaddrs_from_fd (context, 97178825Sdfr *auth_context, 98178825Sdfr p_fd); 99178825Sdfr if (ret) 100178825Sdfr return ret; 10155682Smarkm 102178825Sdfr if(!(flags & KRB5_RECVAUTH_IGNORE_VERSION)) { 103178825Sdfr n = krb5_net_read (context, p_fd, &len, 4); 104178825Sdfr if (n < 0) { 105178825Sdfr ret = errno; 106178825Sdfr krb5_set_error_string (context, "read: %s", strerror(errno)); 107178825Sdfr return ret; 108178825Sdfr } 109178825Sdfr if (n == 0) { 110178825Sdfr krb5_set_error_string (context, "Failed to receive sendauth data"); 111178825Sdfr return KRB5_SENDAUTH_BADAUTHVERS; 112178825Sdfr } 113178825Sdfr len = ntohl(len); 114178825Sdfr if (len != sizeof(her_version) 115178825Sdfr || krb5_net_read (context, p_fd, her_version, len) != len 116178825Sdfr || strncmp (version, her_version, len)) { 117178825Sdfr repl = 1; 118178825Sdfr krb5_net_write (context, p_fd, &repl, 1); 119178825Sdfr krb5_clear_error_string (context); 120178825Sdfr return KRB5_SENDAUTH_BADAUTHVERS; 121178825Sdfr } 122178825Sdfr } 123178825Sdfr 12455682Smarkm n = krb5_net_read (context, p_fd, &len, 4); 12578527Sassar if (n < 0) { 12678527Sassar ret = errno; 12778527Sassar krb5_set_error_string (context, "read: %s", strerror(errno)); 12878527Sassar return ret; 12978527Sassar } 13078527Sassar if (n == 0) { 13178527Sassar krb5_clear_error_string (context); 132178825Sdfr return KRB5_SENDAUTH_BADAPPLVERS; 13378527Sassar } 13455682Smarkm len = ntohl(len); 135178825Sdfr her_appl_version = malloc (len); 136178825Sdfr if (her_appl_version == NULL) { 137178825Sdfr repl = 2; 138178825Sdfr krb5_net_write (context, p_fd, &repl, 1); 139178825Sdfr krb5_set_error_string (context, "malloc: out of memory"); 140178825Sdfr return ENOMEM; 14155682Smarkm } 142178825Sdfr if (krb5_net_read (context, p_fd, her_appl_version, len) != len 143178825Sdfr || !(*match_appl_version)(match_data, her_appl_version)) { 144178825Sdfr repl = 2; 145178825Sdfr krb5_net_write (context, p_fd, &repl, 1); 146178825Sdfr krb5_set_error_string (context, "wrong sendauth version (%s)", 147178825Sdfr her_appl_version); 148178825Sdfr free (her_appl_version); 149178825Sdfr return KRB5_SENDAUTH_BADAPPLVERS; 150178825Sdfr } 15155682Smarkm free (her_appl_version); 15255682Smarkm 153178825Sdfr repl = 0; 154178825Sdfr if (krb5_net_write (context, p_fd, &repl, 1) != 1) { 155178825Sdfr ret = errno; 156178825Sdfr krb5_set_error_string (context, "write: %s", strerror(errno)); 157178825Sdfr return ret; 158178825Sdfr } 15955682Smarkm 160178825Sdfr krb5_data_zero (&data); 161178825Sdfr ret = krb5_read_message (context, p_fd, &data); 162178825Sdfr if (ret) 163178825Sdfr return ret; 16455682Smarkm 165178825Sdfr ret = krb5_rd_req (context, 166178825Sdfr auth_context, 167178825Sdfr &data, 168178825Sdfr server, 169178825Sdfr keytab, 170178825Sdfr &ap_options, 171178825Sdfr ticket); 172178825Sdfr krb5_data_free (&data); 173178825Sdfr if (ret) { 174178825Sdfr krb5_data error_data; 175178825Sdfr krb5_error_code ret2; 17655682Smarkm 177178825Sdfr ret2 = krb5_mk_error (context, 178178825Sdfr ret, 179178825Sdfr NULL, 180178825Sdfr NULL, 181178825Sdfr NULL, 182178825Sdfr server, 183178825Sdfr NULL, 184178825Sdfr NULL, 185178825Sdfr &error_data); 186178825Sdfr if (ret2 == 0) { 187178825Sdfr krb5_write_message (context, p_fd, &error_data); 188178825Sdfr krb5_data_free (&error_data); 189178825Sdfr } 190178825Sdfr return ret; 191178825Sdfr } 19255682Smarkm 193178825Sdfr len = 0; 194178825Sdfr if (krb5_net_write (context, p_fd, &len, 4) != 4) { 195178825Sdfr ret = errno; 196178825Sdfr krb5_set_error_string (context, "write: %s", strerror(errno)); 197178825Sdfr return ret; 198178825Sdfr } 19955682Smarkm 200178825Sdfr if (ap_options & AP_OPTS_MUTUAL_REQUIRED) { 201178825Sdfr ret = krb5_mk_rep (context, *auth_context, &data); 202178825Sdfr if (ret) 203178825Sdfr return ret; 20455682Smarkm 205178825Sdfr ret = krb5_write_message (context, p_fd, &data); 206178825Sdfr if (ret) 207178825Sdfr return ret; 208178825Sdfr krb5_data_free (&data); 209178825Sdfr } 210178825Sdfr return 0; 21155682Smarkm} 212