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
start_kerberos4_server(cvsroot_t * root,struct buffer ** to_server_p,struct buffer ** from_server_p)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
initialize_kerberos4_encryption_buffers(struct buffer ** to_server_p,struct buffer ** from_server_p)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