xref: /netbsd-src/crypto/external/bsd/libsaslc/dist/src/saslc.c (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
1 /* $Id: saslc.c,v 1.1.1.1 2010/11/27 21:23:59 agc 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 
38 #include <saslc.h>
39 #include <ctype.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdbool.h>
43 #include "dict.h"
44 #include "parser.h"
45 #include "saslc_private.h"
46 #include "mech.h"
47 #include "error.h"
48 
49 /* local headers */
50 
51 static bool saslc__valid_appname(const char *);
52 
53 /**
54  * @brief checks if application name is legal
55  * @param appname application name
56  * @return true if application name is legal, false otherwise
57  */
58 
59 static bool
60 saslc__valid_appname(const char *appname)
61 {
62 	const char *p;
63 
64 	for (p = appname; *p; p++)
65 		if (!isalnum((unsigned char)*p))
66 			return false;
67 
68 	return true;
69 }
70 
71 
72 /**
73  * @brief allocates new saslc context
74  * @return pointer to the saslc context
75  */
76 
77 saslc_t *
78 saslc_alloc(void)
79 {
80 	return calloc(1, sizeof(saslc_t));
81 }
82 
83 /**
84  * @brief initializes sasl context, basing on application name function
85  * parses configuration files, sets up default peroperties, creates
86  * mechanisms list for the context.
87  * @param ctx sasl context
88  * @param appname application name, NULL could be used for generic aplication
89  * @return 0 on success, -1 otherwise.
90  */
91 
92 int
93 saslc_init(saslc_t *ctx, const char *appname)
94 {
95 
96 	/* reference counter */
97 	ctx->refcnt = 0;
98 	ctx->prop = saslc__dict_create();
99 
100 	/* appname */
101 	if (appname != NULL) {
102 		/* check if appname is valid */
103 		if (saslc__valid_appname(appname) == false) {
104 			saslc__error_set(ERR(ctx), ERROR_BADARG,
105 			    "application name is not permited");
106 			free(ctx->prop);
107 			ctx->prop = NULL;
108 			return -1;
109 		}
110 
111 		if ((ctx->appname = strdup(appname)) == NULL) {
112 			saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
113 			free(ctx->prop);
114 			ctx->prop = NULL;
115 			return -1;
116 		}
117 	} else
118 		ctx->appname = NULL;
119 
120 	/* mechanisms list */
121 	ctx->mechanisms = saslc__mech_list_create(ctx);
122 
123 	if (ctx->mechanisms == NULL)
124 		return -1;
125 
126 	/* @param configuration default properties */
127 	if (saslc__parser_config(ctx) < 0) {
128 		free((void *)(intptr_t)ctx->appname);
129 		ctx->appname = NULL;
130 		saslc__dict_destroy(ctx->prop);
131 		ctx->prop = NULL;
132 		saslc__mech_list_destroy(ctx->mechanisms);
133 		ctx->mechanisms = NULL;
134 		return -1;
135 	}
136 
137 	return 0;
138 }
139 
140 /**
141  * @brief gets string message of the error.
142  * @param ctx context
143  * @return pointer to the error message.
144  */
145 
146 const char *
147 saslc_strerror(saslc_t *ctx)
148 {
149 	return saslc__error_get_strerror(ERR(ctx));
150 }
151 
152 /**
153  * @brief destroys and deallocate resources used by the context.
154  * Context shouldn't have got any sessions assigned to it.
155  * @param ctx context
156  * @return 0 on success, -1 on failure.
157  */
158 
159 int
160 saslc_end(saslc_t *ctx)
161 {
162 	if (ctx->refcnt > 0) {
163 		saslc__error_set(ERR(ctx), ERROR_GENERAL,
164 		    "context has got assigned active sessions");
165 		return -1;
166 	}
167 
168 	/* mechanism list */
169 	if (ctx->mechanisms != NULL)
170 		saslc__mech_list_destroy(ctx->mechanisms);
171 
172 	/* properties */
173 	if (ctx->prop != NULL)
174 		saslc__dict_destroy(ctx->prop);
175 
176 	/* application name */
177 	if (ctx->appname != NULL)
178 		free((void *)(intptr_t)ctx->appname);
179 
180 	/* free context */
181 	free(ctx);
182 
183 	return 0;
184 }
185