155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2000 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "test_locl.h" 3555682Smarkm 36233294SstasRCSID("$Id$"); 3755682Smarkm 3855682Smarkmstatic int help_flag; 3955682Smarkmstatic int version_flag; 4055682Smarkmstatic char *port_str; 4172445Sassarstatic char *keytab_str; 4272445Sassarkrb5_keytab keytab; 4355682Smarkmchar *service = SERVICE; 44178825Sdfrchar *mech = "krb5"; 4557419Smarkmint fork_flag; 46233294Sstaschar *password = NULL; 4755682Smarkm 4855682Smarkmstatic struct getargs args[] = { 4955682Smarkm { "port", 'p', arg_string, &port_str, "port to listen to", "port" }, 5055682Smarkm { "service", 's', arg_string, &service, "service to use", "service" }, 5172445Sassar { "keytab", 'k', arg_string, &keytab_str, "keytab to use", "keytab" }, 52178825Sdfr { "mech", 'm', arg_string, &mech, "gssapi mech to use", "mech" }, 53233294Sstas { "password", 'P', arg_string, &password, "password to use", "password" }, 5457419Smarkm { "fork", 'f', arg_flag, &fork_flag, "do fork" }, 5555682Smarkm { "help", 'h', arg_flag, &help_flag }, 5655682Smarkm { "version", 0, arg_flag, &version_flag } 5755682Smarkm}; 5855682Smarkm 5955682Smarkmstatic int num_args = sizeof(args) / sizeof(args[0]); 6055682Smarkm 6155682Smarkmstatic void 6255682Smarkmserver_usage(int code, struct getargs *args, int num_args) 6355682Smarkm{ 6455682Smarkm arg_printusage(args, num_args, NULL, ""); 6555682Smarkm exit(code); 6655682Smarkm} 6755682Smarkm 6855682Smarkmstatic void 6955682Smarkmclient_usage(int code, struct getargs *args, int num_args) 7055682Smarkm{ 7155682Smarkm arg_printusage(args, num_args, NULL, "host"); 7255682Smarkm exit(code); 7355682Smarkm} 7455682Smarkm 7555682Smarkm 7655682Smarkmstatic int 77233294Sstascommon_setup(krb5_context *context, int *argc, char **argv, 7855682Smarkm void (*usage)(int, struct getargs*, int)) 7955682Smarkm{ 8055682Smarkm int port = 0; 8155682Smarkm *argc = krb5_program_setup(context, *argc, argv, args, num_args, usage); 8255682Smarkm 8355682Smarkm if(help_flag) 8455682Smarkm (*usage)(0, args, num_args); 8555682Smarkm if(version_flag) { 8655682Smarkm print_version(NULL); 8755682Smarkm exit(0); 8855682Smarkm } 89233294Sstas 9055682Smarkm if(port_str){ 9155682Smarkm struct servent *s = roken_getservbyname(port_str, "tcp"); 9255682Smarkm if(s) 9355682Smarkm port = s->s_port; 9455682Smarkm else { 9555682Smarkm char *ptr; 9655682Smarkm 9755682Smarkm port = strtol (port_str, &ptr, 10); 9855682Smarkm if (port == 0 && ptr == port_str) 9955682Smarkm errx (1, "Bad port `%s'", port_str); 10055682Smarkm port = htons(port); 10155682Smarkm } 10255682Smarkm } 10355682Smarkm 10455682Smarkm if (port == 0) 10555682Smarkm port = krb5_getportbyname (*context, PORT, "tcp", 4711); 106233294Sstas 10755682Smarkm return port; 10855682Smarkm} 10955682Smarkm 11055682Smarkmint 11155682Smarkmserver_setup(krb5_context *context, int argc, char **argv) 11255682Smarkm{ 11355682Smarkm int port = common_setup(context, &argc, argv, server_usage); 11472445Sassar krb5_error_code ret; 11572445Sassar 11655682Smarkm if(argv[argc] != NULL) 11755682Smarkm server_usage(1, args, num_args); 11872445Sassar if (keytab_str != NULL) 11972445Sassar ret = krb5_kt_resolve (*context, keytab_str, &keytab); 12072445Sassar else 12172445Sassar ret = krb5_kt_default (*context, &keytab); 12272445Sassar if (ret) 12372445Sassar krb5_err (*context, 1, ret, "krb5_kt_resolve/default"); 12455682Smarkm return port; 12555682Smarkm} 12655682Smarkm 12755682Smarkmint 12855682Smarkmclient_setup(krb5_context *context, int *argc, char **argv) 12955682Smarkm{ 13055682Smarkm int optind = *argc; 13155682Smarkm int port = common_setup(context, &optind, argv, client_usage); 13255682Smarkm if(*argc - optind != 1) 13355682Smarkm client_usage(1, args, num_args); 13455682Smarkm *argc = optind; 13555682Smarkm return port; 13655682Smarkm} 13755682Smarkm 13855682Smarkmint 13955682Smarkmclient_doit (const char *hostname, int port, const char *service, 14055682Smarkm int (*func)(int, const char *hostname, const char *service)) 14155682Smarkm{ 14255682Smarkm struct addrinfo *ai, *a; 14355682Smarkm struct addrinfo hints; 14455682Smarkm int error; 14555682Smarkm char portstr[NI_MAXSERV]; 14655682Smarkm 14755682Smarkm memset (&hints, 0, sizeof(hints)); 14855682Smarkm hints.ai_socktype = SOCK_STREAM; 14955682Smarkm hints.ai_protocol = IPPROTO_TCP; 15055682Smarkm 15155682Smarkm snprintf (portstr, sizeof(portstr), "%u", ntohs(port)); 15255682Smarkm 15355682Smarkm error = getaddrinfo (hostname, portstr, &hints, &ai); 15455682Smarkm if (error) { 15555682Smarkm errx (1, "%s: %s", hostname, gai_strerror(error)); 15655682Smarkm return -1; 15755682Smarkm } 15855682Smarkm 15955682Smarkm for (a = ai; a != NULL; a = a->ai_next) { 16055682Smarkm int s; 16155682Smarkm 16255682Smarkm s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); 16355682Smarkm if (s < 0) 16455682Smarkm continue; 16555682Smarkm if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { 16655682Smarkm warn ("connect(%s)", hostname); 16755682Smarkm close (s); 16855682Smarkm continue; 16955682Smarkm } 17055682Smarkm freeaddrinfo (ai); 17155682Smarkm return (*func) (s, hostname, service); 17255682Smarkm } 17355682Smarkm warnx ("failed to contact %s", hostname); 17455682Smarkm freeaddrinfo (ai); 17555682Smarkm return 1; 17655682Smarkm} 177