More documentation.
[heimdal.git] / appl / popper / pop_debug.c
blob14a290c89ddf7ff672bc7e4bebaa298dce810723
1 /*
2 * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 /* Tiny program to help debug popper */
36 #include "popper.h"
37 RCSID("$Id$");
39 static void
40 loop(int s)
42 char cmd[1024];
43 char buf[1024];
44 fd_set fds;
45 while(1){
46 FD_ZERO(&fds);
47 FD_SET(0, &fds);
48 FD_SET(s, &fds);
49 if(select(s+1, &fds, 0, 0, 0) < 0)
50 err(1, "select");
51 if(FD_ISSET(0, &fds)){
52 fgets(cmd, sizeof(cmd), stdin);
53 cmd[strlen(cmd) - 1] = '\0';
54 strlcat (cmd, "\r\n", sizeof(cmd));
55 write(s, cmd, strlen(cmd));
57 if(FD_ISSET(s, &fds)){
58 int n = read(s, buf, sizeof(buf));
59 if(n == 0)
60 exit(0);
61 fwrite(buf, n, 1, stdout);
66 static int
67 get_socket (const char *hostname, int port)
69 int ret;
70 struct addrinfo *ai, *a;
71 struct addrinfo hints;
72 char portstr[NI_MAXSERV];
74 memset (&hints, 0, sizeof(hints));
75 hints.ai_socktype = SOCK_STREAM;
76 snprintf (portstr, sizeof(portstr), "%d", ntohs(port));
77 ret = getaddrinfo (hostname, portstr, &hints, &ai);
78 if (ret)
79 errx (1, "getaddrinfo %s: %s", hostname, gai_strerror (ret));
81 for (a = ai; a != NULL; a = a->ai_next) {
82 int s;
84 s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
85 if (s < 0)
86 continue;
87 if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
88 close (s);
89 continue;
91 freeaddrinfo (ai);
92 return s;
94 err (1, "failed to connect to %s", hostname);
97 #ifdef KRB4
98 static int
99 doit_v4 (char *host, int port)
101 KTEXT_ST ticket;
102 MSG_DAT msg_data;
103 CREDENTIALS cred;
104 des_key_schedule sched;
105 int ret;
106 int s = get_socket (host, port);
108 ret = krb_sendauth(0,
110 &ticket,
111 "pop",
112 host,
113 krb_realmofhost(host),
114 getpid(),
115 &msg_data,
116 &cred,
117 sched,
118 NULL,
119 NULL,
120 "KPOPV0.1");
121 if(ret) {
122 warnx("krb_sendauth: %s", krb_get_err_text(ret));
123 return 1;
125 loop(s);
126 return 0;
128 #endif
130 #ifdef KRB5
131 static int
132 doit_v5 (char *host, int port)
134 krb5_error_code ret;
135 krb5_context context;
136 krb5_auth_context auth_context = NULL;
137 krb5_principal server;
138 int s = get_socket (host, port);
140 ret = krb5_init_context (&context);
141 if (ret)
142 errx (1, "krb5_init_context failed: %d", ret);
144 ret = krb5_sname_to_principal (context,
145 host,
146 "pop",
147 KRB5_NT_SRV_HST,
148 &server);
149 if (ret) {
150 warnx ("krb5_sname_to_principal: %s",
151 krb5_get_err_text (context, ret));
152 return 1;
154 ret = krb5_sendauth (context,
155 &auth_context,
157 "KPOPV1.0",
158 NULL,
159 server,
161 NULL,
162 NULL,
163 NULL,
164 NULL,
165 NULL,
166 NULL);
167 if (ret) {
168 warnx ("krb5_sendauth: %s",
169 krb5_get_err_text (context, ret));
170 return 1;
172 loop (s);
173 return 0;
175 #endif
178 #ifdef KRB4
179 static int use_v4 = -1;
180 #endif
181 #ifdef KRB5
182 static int use_v5 = -1;
183 #endif
184 static char *port_str;
185 static int do_version;
186 static int do_help;
188 struct getargs args[] = {
189 #ifdef KRB4
190 { "krb4", '4', arg_flag, &use_v4, "Use Kerberos V4",
191 NULL },
192 #endif
193 #ifdef KRB5
194 { "krb5", '5', arg_flag, &use_v5, "Use Kerberos V5",
195 NULL },
196 #endif
197 { "port", 'p', arg_string, &port_str, "Use this port",
198 "number-or-service" },
199 { "version", 0, arg_flag, &do_version, "Print version",
200 NULL },
201 { "help", 0, arg_flag, &do_help, NULL,
202 NULL }
205 static void
206 usage (int ret)
208 arg_printusage (args,
209 sizeof(args) / sizeof(args[0]),
210 NULL,
211 "hostname");
212 exit (ret);
216 main(int argc, char **argv)
218 int port = 0;
219 int ret = 1;
220 int optind = 0;
222 setprogname(argv[0]);
224 if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
225 &optind))
226 usage (1);
228 argc -= optind;
229 argv += optind;
231 if (do_help)
232 usage (0);
234 if (do_version) {
235 print_version (NULL);
236 return 0;
239 if (argc < 1)
240 usage (1);
242 if (port_str) {
243 struct servent *s = roken_getservbyname (port_str, "tcp");
245 if (s)
246 port = s->s_port;
247 else {
248 char *ptr;
250 port = strtol (port_str, &ptr, 10);
251 if (port == 0 && ptr == port_str)
252 errx (1, "Bad port `%s'", port_str);
253 port = htons(port);
256 if (port == 0) {
257 #ifdef KRB5
258 port = krb5_getportbyname (NULL, "kpop", "tcp", 1109);
259 #elif defined(KRB4)
260 port = k_getportbyname ("kpop", "tcp", 1109);
261 #else
262 #error must define KRB4 or KRB5
263 #endif
266 #if defined(KRB4) && defined(KRB5)
267 if(use_v4 == -1 && use_v5 == 1)
268 use_v4 = 0;
269 if(use_v5 == -1 && use_v4 == 1)
270 use_v5 = 0;
271 #endif
273 #ifdef KRB5
274 if (ret && use_v5) {
275 ret = doit_v5 (argv[0], port);
277 #endif
278 #ifdef KRB4
279 if (ret && use_v4) {
280 ret = doit_v4 (argv[0], port);
282 #endif
283 return ret;