1 /* $NetBSD: example_client.c,v 1.3 2011/02/11 23:44:43 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.3 2011/02/11 23:44:43 christos Exp $"); 39 #include <stdio.h> 40 #include <saslc.h> 41 #include <err.h> 42 #include <unistd.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <limits.h> 46 47 static void 48 print_help(void) 49 { 50 51 printf("usage: [-hl] {-m mech_name}\n"); 52 printf("-h - help\n"); 53 printf("-l - mechanisms list\n"); 54 printf("-m - use mech_name mechanism\n"); 55 } 56 57 static void 58 list_mechanisms(void) 59 { 60 61 printf("available mechanisms:\n"); 62 printf("ANONYMOUS, CRAM-MD5, DIGEST-MD5, GSSAPI, EXTERNAL, LOGIN, " 63 "PLAIN\n"); 64 } 65 66 static char * 67 nextline(char *buf, size_t len, FILE *fp) 68 { 69 char *p; 70 71 if (fgets(buf, len, fp) == NULL) 72 return NULL; 73 74 if ((p = strchr(buf, '\n')) != NULL) 75 *p = '\0'; 76 77 return buf; 78 } 79 80 int 81 main(int argc, char **argv) 82 { 83 int opt, n, cont; 84 char *mechanism = NULL; 85 saslc_t *ctx; 86 saslc_sess_t *sess; 87 char input[LINE_MAX]; 88 char *option, *var; 89 char *output; 90 static char empty[] = ""; 91 size_t input_len, output_len; 92 93 while ((opt = getopt(argc, argv, "hm:l")) != -1) { 94 switch (opt) { 95 case 'm': 96 /* mechanism */ 97 mechanism = optarg; 98 break; 99 case 'l': 100 /* list mechanisms */ 101 list_mechanisms(); 102 return EXIT_SUCCESS; 103 case 'h': 104 default: 105 /* ??? */ 106 print_help(); 107 return EXIT_FAILURE; 108 } 109 } 110 111 if (mechanism == NULL) { 112 printf("mechanism: "); 113 if (nextline(input, sizeof(input), stdin) == NULL) 114 goto eof; 115 mechanism = input; 116 } 117 118 ctx = saslc_alloc(); 119 120 if (saslc_init(ctx, NULL, NULL) < 0) 121 goto error; 122 123 if ((sess = saslc_sess_init(ctx, mechanism, NULL)) == NULL) 124 goto error; 125 126 /* reading properties */ 127 if (nextline(input, sizeof(input), stdin) == NULL) 128 goto eof; 129 n = atoi(input); 130 131 while (n--) { 132 if (nextline(input, sizeof(input), stdin) == NULL) 133 goto eof; 134 var = strchr(input, ' '); 135 if (var != NULL) 136 *var++ = '\0'; 137 else 138 var = empty; 139 option = input; 140 if (saslc_sess_setprop(sess, option, var) < 0) 141 goto error; 142 } 143 144 printf("session:\n"); 145 146 for (;;) { 147 if (nextline(input, sizeof(input), stdin) == NULL) 148 break; 149 input_len = strlen(input); 150 cont = saslc_sess_cont(sess, input, input_len, (void **)&output, 151 &output_len); 152 if (cont < 0) 153 goto error_sess; 154 printf("%s\n", output == NULL ? "empty line" : output); 155 if (cont == 0) 156 break; 157 } 158 159 saslc_sess_end(sess); 160 if (saslc_end(ctx, true) < 0) 161 goto error; 162 163 return 0; 164 eof: 165 err(EXIT_FAILURE, "Unexpected EOF"); 166 error: 167 errx(EXIT_FAILURE, "%s", saslc_strerror(ctx)); 168 error_sess: 169 errx(EXIT_FAILURE, "%s", saslc_sess_strerror(sess)); 170 } 171