summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/appl/sample/sample_client.c
blob: d0ec1c56674901981b50afac07959332258620b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
 *
 * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information,
 * please see the file <mit-copyright.h>.
 *
 * sample_client:
 * A sample Kerberos client, which connects to a server on a remote host,
 * at port "sample" (be sure to define it in /etc/services)
 * and authenticates itself to the server. The server then writes back
 * (in ASCII) the authenticated name.
 *
 * Usage:
 * sample_client <hostname> <checksum>
 *
 * <hostname> is the name of the foreign host to contact.
 *
 * <checksum> is an integer checksum to be used for the call to krb_mk_req()
 *	and mutual authentication
 *
 */

#include "sample.h"

RCSID("$Id: sample_client.c,v 1.21 1999/11/13 06:27:01 assar Exp $");

static void
usage (void)
{
  fprintf (stderr, "Usage: %s [-s service] [-p port] hostname checksum\n",
	   __progname);
  exit (1);
}

int
main(int argc, char **argv)
{
    struct hostent *hp;
    struct sockaddr_in sin, lsin;
    char *remote_host;
    int status;
    int namelen;
    int sock = -1;
    KTEXT_ST ticket;
    char buf[512];
    long authopts;
    MSG_DAT msg_data;
    CREDENTIALS cred;
    des_key_schedule sched;
    u_int32_t cksum;
    int c;
    char service[SNAME_SZ];
    u_int16_t port;
    struct servent *serv;
    char **h_addr_list;

    set_progname (argv[0]);
    strlcpy (service, SAMPLE_SERVICE, sizeof(service));
    port = 0;

    while ((c = getopt(argc, argv, "s:p:")) != -1)
	switch(c) {
	case 's' :
	    strlcpy (service, optarg, sizeof(service));
	    break;
	case 'p' :
	    serv = getservbyname (optarg, "tcp");
	    if (serv)
		port = serv->s_port;
	    else
		port = htons(atoi(optarg));
	    break;
	case '?' :
	default :
	    usage();
	}

    argc -= optind;
    argv += optind;

    if (argc != 2)
	usage ();
    
    /* convert cksum to internal rep */
    cksum = atoi(argv[1]);

    printf("Setting checksum to %ld\n", (long)cksum);

    /* clear out the structure first */
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    if (port)
	sin.sin_port = port;
    else
	sin.sin_port = k_getportbyname (service, "tcp", htons(SAMPLE_PORT));

    /* look up the server host */
    hp = gethostbyname(argv[0]);
    if (hp == NULL)
	errx (1, "gethostbyname(%s): %s", argv[0],
	      hstrerror(h_errno));

    /* copy the hostname into non-volatile storage */
    remote_host = strdup(hp->h_name);
    if (remote_host == NULL)
	errx (1, "strdup: out of memory");

    /* set up the address of the foreign socket for connect() */
    sin.sin_family = hp->h_addrtype;

    for (h_addr_list = hp->h_addr_list;
	 *h_addr_list;
	 ++h_addr_list) {
	memcpy(&sin.sin_addr, *h_addr_list, sizeof(sin.sin_addr));
	fprintf (stderr, "Trying %s...\n", inet_ntoa(sin.sin_addr));

	/* open a TCP socket */
	sock = socket(PF_INET, SOCK_STREAM, 0);
	if (sock < 0)
	    err (1, "socket");

	/* connect to the server */
	if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
	    break;
	close (sock);
    }

    if (*h_addr_list == NULL)
	err (1, "connect");

    /* find out who I am, now that we are connected and therefore bound */
    namelen = sizeof(lsin);
    if (getsockname(sock, (struct sockaddr *) &lsin, &namelen) < 0) {
	close (sock);
	err (1, "getsockname");
    }

    /* call Kerberos library routine to obtain an authenticator,
       pass it over the socket to the server, and obtain mutual
       authentication. */

    authopts = KOPT_DO_MUTUAL;
    status = krb_sendauth(authopts, sock, &ticket,
			  service, remote_host,
			  NULL, cksum, &msg_data, &cred,
			  sched, &lsin, &sin, SAMPLE_VERSION);
    if (status != KSUCCESS)
	errx (1, "cannot authenticate to server: %s",
	      krb_get_err_text(status));

    /* After we send the authenticator to the server, it will write
       back the name we authenticated to. Read what it has to say. */
    status = read(sock, buf, sizeof(buf));
    if (status < 0)
	errx(1, "read");

    /* make sure it's null terminated before printing */
    if (status < sizeof(buf))
	buf[status] = '\0';
    else
	buf[sizeof(buf) - 1] = '\0';

    printf("The server says:\n%s\n", buf);

    close(sock);
    return 0;
}
OpenPOWER on IntegriCloud