Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / crypto / kerberosIV / appl / kip / kipd.c
1 /* $FreeBSD: src/crypto/kerberosIV/appl/kip/kipd.c,v 1.1.1.3.2.2 2001/03/04 12:52:43 markm Exp $ */
2 /* $DragonFly: src/crypto/kerberosIV/appl/kip/Attic/kipd.c,v 1.2 2003/06/17 04:24:36 dillon Exp $ */
3
4 /*
5  * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
6  * (Royal Institute of Technology, Stockholm, Sweden).
7  * All rights reserved.
8  * 
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 
20  * 3. Neither the name of the Institute nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  * 
24  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #include "kip.h"
38
39 RCSID("$Id: kipd.c,v 1.16.2.3 2000/10/18 20:46:45 assar Exp $");
40
41 static int
42 recv_conn (int sock, des_cblock *key, des_key_schedule schedule,
43            struct sockaddr_in *retaddr, char *user, size_t len)
44 {
45      int status;
46      KTEXT_ST ticket;
47      AUTH_DAT auth;
48      char instance[INST_SZ];
49      struct sockaddr_in thisaddr, thataddr;
50      int addrlen;
51      char version[KRB_SENDAUTH_VLEN + 1];
52      u_char ok = 0;
53      struct passwd *passwd;
54
55      addrlen = sizeof(thisaddr);
56      if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
57          addrlen != sizeof(thisaddr)) {
58           return 1;
59      }
60      addrlen = sizeof(thataddr);
61      if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
62          addrlen != sizeof(thataddr)) {
63           return 1;
64      }
65
66      k_getsockinst (sock, instance, sizeof(instance));
67      status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance,
68                             &thataddr, &thisaddr, &auth, "", schedule,
69                             version);
70      if (status != KSUCCESS ||
71          strncmp(version, KIP_VERSION, KRB_SENDAUTH_VLEN) != 0) {
72           return 1;
73      }
74      passwd = k_getpwnam ("root");
75      if (passwd == NULL) {
76           fatal (sock, "Cannot find root", schedule, &auth.session);
77           return 1;
78      }
79      if (kuserok(&auth, "root") != 0) {
80           fatal (sock, "Permission denied", schedule, &auth.session);
81           return 1;
82      }
83      if (write (sock, &ok, sizeof(ok)) != sizeof(ok))
84           return 1;
85
86      snprintf (user, len, "%s%s%s@%s", auth.pname, 
87                auth.pinst[0] != '\0' ? "." : "",
88                auth.pinst, auth.prealm);
89
90      memcpy(key, &auth.session, sizeof(des_cblock));
91      *retaddr = thataddr;
92      return 0;
93 }
94
95 static int
96 doit(int sock)
97 {
98      char msg[1024];
99      char cmd[MAXPATHLEN];
100      char tun_if_name[64];
101      char user[MAX_K_NAME_SZ];
102      struct sockaddr_in thataddr;
103      des_key_schedule schedule;
104      des_cblock key;
105      int this, ret, ret2;
106
107      isserver = 1;
108
109      if (recv_conn (sock, &key, schedule, &thataddr, user, sizeof(user)))
110           return 1;
111      this = tunnel_open (tun_if_name, sizeof(tun_if_name));
112      if (this < 0)
113           fatal (sock, "Cannot open " _PATH_DEV TUNDEV, schedule, &key);
114
115      strlcpy(cmd, LIBEXECDIR "/kipd-control", sizeof(cmd));
116
117      ret = kip_exec (cmd, msg, sizeof(msg), "kipd-control",
118                      "up", tun_if_name, inet_ntoa(thataddr.sin_addr), user,
119                      NULL);
120      if (ret) {
121          fatal (sock, msg, schedule, &key);
122          return -1;
123      }
124
125      ret = copy_packets (this, sock, TUNMTU, &key, schedule);
126      
127      ret2 = kip_exec (cmd,  msg, sizeof(msg), "kipd-control",
128                       "down", tun_if_name, user, NULL);
129      if (ret2)
130          syslog(LOG_ERR, "%s", msg);
131      return ret;
132 }
133
134 static char *port_str           = NULL;
135 static int inetd_flag           = 1;
136 static int version_flag         = 0;
137 static int help_flag            = 0;
138
139 struct getargs args[] = {
140     { "inetd",          'i',    arg_negative_flag,      &inetd_flag,
141       "Not started from inetd" },
142     { "port",           'p',    arg_string,     &port_str,      "Use this port",
143       "port" },
144     { "version",        0,      arg_flag,               &version_flag },
145     { "help",           0,      arg_flag,               &help_flag }
146 };
147
148 static void
149 usage(int ret)
150 {
151     arg_printusage (args,
152                     sizeof(args) / sizeof(args[0]),
153                     NULL,
154                     "");
155     exit (ret);
156 }
157
158 /*
159  * kipd - receive forwarded IP
160  */
161
162 int
163 main (int argc, char **argv)
164 {
165     int port;
166     int optind = 0;
167
168     set_progname (argv[0]);
169     roken_openlog(__progname, LOG_PID|LOG_CONS, LOG_DAEMON);
170
171     if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
172                 &optind))
173         usage (1);
174
175     if (help_flag)
176         usage (0);
177
178     if (version_flag) {
179         print_version (NULL);
180         return 0;
181     }
182
183     if(port_str) {
184         struct servent *s = roken_getservbyname (port_str, "tcp");
185
186         if (s)
187             port = s->s_port;
188         else {
189             char *ptr;
190
191             port = strtol (port_str, &ptr, 10);
192             if (port == 0 && ptr == port_str)
193                 errx (1, "bad port `%s'", port_str);
194             port = htons(port);
195         }
196     } else {
197         port = k_getportbyname ("kip", "tcp", htons(KIPPORT));
198     }
199
200     if (!inetd_flag)
201         mini_inetd (port);
202
203     signal (SIGCHLD, childhandler);
204     return doit(STDIN_FILENO);
205 }