1/* $NetBSD: example_client.c,v 1.4 2011/02/12 23:21:33 christos Exp $ */
2
3/* Copyright (c) 2010 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Mateusz Kocielski.
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 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *        This product includes software developed by the NetBSD
20 *        Foundation, Inc. and its contributors.
21 * 4. Neither the name of The NetBSD Foundation nor the names of its
22 *    contributors may be used to endorse or promote products derived
23 *    from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37#include <sys/cdefs.h>
38__RCSID("$NetBSD: example_client.c,v 1.4 2011/02/12 23:21:33 christos Exp $");
39
40#include <err.h>
41#include <limits.h>
42#include <saslc.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47
48static void
49print_help(void)
50{
51
52	printf("usage: [-hl] {-m mech_name}\n");
53	printf("-h - help\n");
54	printf("-l - mechanisms list\n");
55	printf("-m - use mech_name mechanism\n");
56}
57
58static void
59list_mechanisms(void)
60{
61
62	printf("available mechanisms:\n");
63	printf("ANONYMOUS, CRAM-MD5, DIGEST-MD5, GSSAPI, EXTERNAL, LOGIN, "
64	    "PLAIN\n");
65}
66
67static char *
68nextline(char *buf, size_t len, FILE *fp)
69{
70	char *p;
71
72	if (fgets(buf, len, fp) == NULL)
73		return NULL;
74
75	if ((p = strchr(buf, '\n')) != NULL)
76		*p = '\0';
77
78	return buf;
79}
80
81int
82main(int argc, char **argv)
83{
84	int opt, n, cont;
85	char *mechanism = NULL;
86	saslc_t *ctx;
87	saslc_sess_t *sess;
88	char input[LINE_MAX];
89	char *option, *var;
90	char *output;
91	static char empty[] = "";
92	size_t input_len, output_len;
93
94	while ((opt = getopt(argc, argv, "hm:l")) != -1) {
95		switch (opt) {
96		case 'm':
97			/* mechanism */
98			mechanism = optarg;
99			break;
100		case 'l':
101			/* list mechanisms */
102			list_mechanisms();
103			return EXIT_SUCCESS;
104		case 'h':
105		default:
106			/* ??? */
107			print_help();
108			return EXIT_FAILURE;
109		}
110	}
111
112	if (mechanism == NULL) {
113		printf("mechanism: ");
114		if (nextline(input, sizeof(input), stdin) == NULL)
115			goto eof;
116		mechanism = input;
117	}
118
119	ctx = saslc_alloc();
120
121	if (saslc_init(ctx, NULL, NULL) < 0)
122		goto error;
123
124	if ((sess = saslc_sess_init(ctx, mechanism, NULL)) == NULL)
125		goto error;
126
127	/* reading properties */
128	if (nextline(input, sizeof(input), stdin) == NULL)
129		goto eof;
130	n = atoi(input);
131
132	while (n--) {
133		if (nextline(input, sizeof(input), stdin) == NULL)
134			goto eof;
135		var = strchr(input, ' ');
136		if (var != NULL)
137			*var++ = '\0';
138		else
139			var = empty;
140		option = input;
141		if (saslc_sess_setprop(sess, option, var) < 0)
142			goto error;
143	}
144
145	printf("session:\n");
146
147	for (;;) {
148		if (nextline(input, sizeof(input), stdin) == NULL)
149			break;
150		input_len = strlen(input);
151		cont = saslc_sess_cont(sess, input, input_len, (void **)&output,
152		    &output_len);
153		if (cont < 0)
154			goto error_sess;
155		printf("%s\n", output == NULL ? "empty line" : output);
156		if (cont == 0)
157			break;
158	}
159
160	saslc_sess_end(sess);
161	if (saslc_end(ctx) < 0)
162		goto error;
163
164	return 0;
165 eof:
166	err(EXIT_FAILURE, "Unexpected EOF");
167 error:
168	errx(EXIT_FAILURE, "%s", saslc_strerror(ctx));
169 error_sess:
170	errx(EXIT_FAILURE, "%s", saslc_sess_strerror(sess));
171}
172