1 /* CVS Kerberos4 client stuff. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; either version 2, or (at your option) 6 any later version. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. */ 12 #include <sys/cdefs.h> 13 __RCSID("$NetBSD: kerberos4-client.c,v 1.2 2016/05/17 14:00:09 christos Exp $"); 14 15 #include <config.h> 16 17 #include "cvs.h" 18 19 #include "buffer.h" 20 #include "socket-client.h" 21 22 # include <krb.h> 23 24 extern char *krb_realmofhost (); 25 # ifndef HAVE_KRB_GET_ERR_TEXT 26 # define krb_get_err_text(status) krb_err_txt[status] 27 # endif /* HAVE_KRB_GET_ERR_TEXT */ 28 29 /* Information we need if we are going to use Kerberos encryption. */ 30 static C_Block kblock; 31 static Key_schedule sched; 32 33 34 /* This function has not been changed to deal with NO_SOCKET_TO_FD 35 (i.e., systems on which sockets cannot be converted to file 36 descriptors). The first person to try building a kerberos client 37 on such a system (OS/2, Windows 95, and maybe others) will have to 38 take care of this. */ 39 void 40 start_kerberos4_server (cvsroot_t *root, struct buffer **to_server_p, 41 struct buffer **from_server_p) 42 { 43 int s; 44 int port; 45 struct hostent *hp; 46 struct sockaddr_in sin; 47 char *hname; 48 49 s = socket (AF_INET, SOCK_STREAM, 0); 50 if (s < 0) 51 error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); 52 53 port = get_cvs_port_number (root); 54 55 hp = init_sockaddr (&sin, root->hostname, port); 56 57 hname = xstrdup (hp->h_name); 58 59 TRACE (TRACE_FUNCTION, "Connecting to %s(%s):%d", 60 root->hostname, 61 inet_ntoa (sin.sin_addr), 62 port); 63 64 if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0) 65 error (1, 0, "connect to %s(%s):%d failed: %s", 66 root->hostname, 67 inet_ntoa (sin.sin_addr), 68 port, SOCK_STRERROR (SOCK_ERRNO)); 69 70 { 71 const char *realm; 72 struct sockaddr_in laddr; 73 int laddrlen; 74 KTEXT_ST ticket; 75 MSG_DAT msg_data; 76 CREDENTIALS cred; 77 int status; 78 79 realm = krb_realmofhost (hname); 80 81 laddrlen = sizeof (laddr); 82 if (getsockname (s, (struct sockaddr *) &laddr, &laddrlen) < 0) 83 error (1, 0, "getsockname failed: %s", SOCK_STRERROR (SOCK_ERRNO)); 84 85 /* We don't care about the checksum, and pass it as zero. */ 86 status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd", 87 hname, realm, (unsigned long) 0, &msg_data, 88 &cred, sched, &laddr, &sin, "KCVSV1.0"); 89 if (status != KSUCCESS) 90 error (1, 0, "kerberos authentication failed: %s", 91 krb_get_err_text (status)); 92 memcpy (kblock, cred.session, sizeof (C_Block)); 93 } 94 95 close_on_exec (s); 96 97 free (hname); 98 99 /* Give caller the values it wants. */ 100 make_bufs_from_fds (s, s, 0, root, to_server_p, from_server_p, 1); 101 } 102 103 void 104 initialize_kerberos4_encryption_buffers( struct buffer **to_server_p, 105 struct buffer **from_server_p ) 106 { 107 *to_server_p = krb_encrypt_buffer_initialize (*to_server_p, 0, sched, 108 kblock, NULL); 109 *from_server_p = krb_encrypt_buffer_initialize (*from_server_p, 1, 110 sched, kblock, NULL); 111 } 112 113