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
48 static void
print_help(void)49 print_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
58 static void
list_mechanisms(void)59 list_mechanisms(void)
60 {
61
62 printf("available mechanisms:\n");
63 printf("ANONYMOUS, CRAM-MD5, DIGEST-MD5, GSSAPI, EXTERNAL, LOGIN, "
64 "PLAIN\n");
65 }
66
67 static char *
nextline(char * buf,size_t len,FILE * fp)68 nextline(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
81 int
main(int argc,char ** argv)82 main(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