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 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