1*beea8b97Schristos /* $NetBSD: example_client.c,v 1.4 2011/02/12 23:21:33 christos Exp $ */
2231558cbSagc
3231558cbSagc /* Copyright (c) 2010 The NetBSD Foundation, Inc.
4231558cbSagc * All rights reserved.
5231558cbSagc *
6231558cbSagc * This code is derived from software contributed to The NetBSD Foundation
7231558cbSagc * by Mateusz Kocielski.
8231558cbSagc *
9231558cbSagc * Redistribution and use in source and binary forms, with or without
10231558cbSagc * modification, are permitted provided that the following conditions
11231558cbSagc * are met:
12231558cbSagc * 1. Redistributions of source code must retain the above copyright
13231558cbSagc * notice, this list of conditions and the following disclaimer.
14231558cbSagc * 2. Redistributions in binary form must reproduce the above copyright
15231558cbSagc * notice, this list of conditions and the following disclaimer in the
16231558cbSagc * documentation and/or other materials provided with the distribution.
17231558cbSagc * 3. All advertising materials mentioning features or use of this software
18231558cbSagc * must display the following acknowledgement:
19231558cbSagc * This product includes software developed by the NetBSD
20231558cbSagc * Foundation, Inc. and its contributors.
21231558cbSagc * 4. Neither the name of The NetBSD Foundation nor the names of its
22231558cbSagc * contributors may be used to endorse or promote products derived
23231558cbSagc * from this software without specific prior written permission.
24231558cbSagc *
25231558cbSagc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26231558cbSagc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27231558cbSagc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28231558cbSagc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29231558cbSagc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30231558cbSagc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31231558cbSagc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32231558cbSagc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33231558cbSagc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34231558cbSagc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35231558cbSagc * POSSIBILITY OF SUCH DAMAGE.
36231558cbSagc */
3719c14409Schristos #include <sys/cdefs.h>
38*beea8b97Schristos __RCSID("$NetBSD: example_client.c,v 1.4 2011/02/12 23:21:33 christos Exp $");
39*beea8b97Schristos
40231558cbSagc #include <err.h>
41*beea8b97Schristos #include <limits.h>
42*beea8b97Schristos #include <saslc.h>
43*beea8b97Schristos #include <stdio.h>
44231558cbSagc #include <stdlib.h>
45231558cbSagc #include <string.h>
46*beea8b97Schristos #include <unistd.h>
47231558cbSagc
48231558cbSagc static void
print_help(void)49231558cbSagc print_help(void)
50231558cbSagc {
5119c14409Schristos
52231558cbSagc printf("usage: [-hl] {-m mech_name}\n");
53231558cbSagc printf("-h - help\n");
54231558cbSagc printf("-l - mechanisms list\n");
55231558cbSagc printf("-m - use mech_name mechanism\n");
56231558cbSagc }
57231558cbSagc
58231558cbSagc static void
list_mechanisms(void)59231558cbSagc list_mechanisms(void)
60231558cbSagc {
6119c14409Schristos
62231558cbSagc printf("available mechanisms:\n");
63231558cbSagc printf("ANONYMOUS, CRAM-MD5, DIGEST-MD5, GSSAPI, EXTERNAL, LOGIN, "
64231558cbSagc "PLAIN\n");
65231558cbSagc }
66231558cbSagc
67231558cbSagc static char *
nextline(char * buf,size_t len,FILE * fp)68231558cbSagc nextline(char *buf, size_t len, FILE *fp)
69231558cbSagc {
70231558cbSagc char *p;
71231558cbSagc
72231558cbSagc if (fgets(buf, len, fp) == NULL)
73231558cbSagc return NULL;
74231558cbSagc
75231558cbSagc if ((p = strchr(buf, '\n')) != NULL)
76231558cbSagc *p = '\0';
77231558cbSagc
78231558cbSagc return buf;
79231558cbSagc }
80231558cbSagc
81231558cbSagc int
main(int argc,char ** argv)82231558cbSagc main(int argc, char **argv)
83231558cbSagc {
84231558cbSagc int opt, n, cont;
85231558cbSagc char *mechanism = NULL;
86231558cbSagc saslc_t *ctx;
87231558cbSagc saslc_sess_t *sess;
886b638291Sagc char input[LINE_MAX];
89231558cbSagc char *option, *var;
90231558cbSagc char *output;
91231558cbSagc static char empty[] = "";
92231558cbSagc size_t input_len, output_len;
93231558cbSagc
94231558cbSagc while ((opt = getopt(argc, argv, "hm:l")) != -1) {
95231558cbSagc switch (opt) {
96231558cbSagc case 'm':
97231558cbSagc /* mechanism */
98231558cbSagc mechanism = optarg;
99231558cbSagc break;
100231558cbSagc case 'l':
101231558cbSagc /* list mechanisms */
102231558cbSagc list_mechanisms();
103231558cbSagc return EXIT_SUCCESS;
104231558cbSagc case 'h':
105231558cbSagc default:
106231558cbSagc /* ??? */
107231558cbSagc print_help();
108231558cbSagc return EXIT_FAILURE;
109231558cbSagc }
110231558cbSagc }
111231558cbSagc
112231558cbSagc if (mechanism == NULL) {
113231558cbSagc printf("mechanism: ");
114231558cbSagc if (nextline(input, sizeof(input), stdin) == NULL)
115231558cbSagc goto eof;
116231558cbSagc mechanism = input;
117231558cbSagc }
118231558cbSagc
119231558cbSagc ctx = saslc_alloc();
120231558cbSagc
12119c14409Schristos if (saslc_init(ctx, NULL, NULL) < 0)
122231558cbSagc goto error;
123231558cbSagc
12419c14409Schristos if ((sess = saslc_sess_init(ctx, mechanism, NULL)) == NULL)
125231558cbSagc goto error;
126231558cbSagc
127231558cbSagc /* reading properties */
128231558cbSagc if (nextline(input, sizeof(input), stdin) == NULL)
129231558cbSagc goto eof;
130231558cbSagc n = atoi(input);
131231558cbSagc
132231558cbSagc while (n--) {
133231558cbSagc if (nextline(input, sizeof(input), stdin) == NULL)
134231558cbSagc goto eof;
135231558cbSagc var = strchr(input, ' ');
136231558cbSagc if (var != NULL)
137231558cbSagc *var++ = '\0';
138231558cbSagc else
139231558cbSagc var = empty;
140231558cbSagc option = input;
141231558cbSagc if (saslc_sess_setprop(sess, option, var) < 0)
142231558cbSagc goto error;
143231558cbSagc }
144231558cbSagc
145231558cbSagc printf("session:\n");
146231558cbSagc
147231558cbSagc for (;;) {
148231558cbSagc if (nextline(input, sizeof(input), stdin) == NULL)
149231558cbSagc break;
150231558cbSagc input_len = strlen(input);
151231558cbSagc cont = saslc_sess_cont(sess, input, input_len, (void **)&output,
152231558cbSagc &output_len);
153231558cbSagc if (cont < 0)
154231558cbSagc goto error_sess;
1556b638291Sagc printf("%s\n", output == NULL ? "empty line" : output);
156231558cbSagc if (cont == 0)
157231558cbSagc break;
158231558cbSagc }
159231558cbSagc
160231558cbSagc saslc_sess_end(sess);
161*beea8b97Schristos if (saslc_end(ctx) < 0)
162231558cbSagc goto error;
163231558cbSagc
164231558cbSagc return 0;
165231558cbSagc eof:
166231558cbSagc err(EXIT_FAILURE, "Unexpected EOF");
167231558cbSagc error:
168231558cbSagc errx(EXIT_FAILURE, "%s", saslc_strerror(ctx));
169231558cbSagc error_sess:
170231558cbSagc errx(EXIT_FAILURE, "%s", saslc_sess_strerror(sess));
171231558cbSagc }
172