1 /* SASL Config file API
2 * Rob Siemborski
3 * Tim Martin (originally in Cyrus distribution)
4 */
5 /*
6 * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The name "Carnegie Mellon University" must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission. For permission or any other legal
23 * details, please contact
24 * Carnegie Mellon University
25 * Center for Technology Transfer and Enterprise Creation
26 * 4615 Forbes Avenue
27 * Suite 302
28 * Pittsburgh, PA 15213
29 * (412) 268-7393, fax: (412) 268-7395
30 * innovation@andrew.cmu.edu
31 *
32 * 4. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by Computing Services
35 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36 *
37 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <ctype.h>
49
50 #include "sasl.h"
51 #include "saslint.h"
52
53 struct configlist {
54 char *key;
55 char *value;
56 };
57
58 static struct configlist *configlist = NULL;
59 static int nconfiglist = 0;
60
61 #define CONFIGLISTGROWSIZE 100
62
sasl_config_init(const char * filename)63 int sasl_config_init(const char *filename)
64 {
65 FILE *infile;
66 int lineno = 0;
67 int alloced = 0;
68 char buf[4096];
69 char *p, *key;
70 char *tail;
71 int result;
72
73 nconfiglist=0;
74
75 infile = fopen(filename, "r");
76 if (!infile) {
77 return SASL_CONTINUE;
78 }
79
80 while (fgets(buf, sizeof(buf), infile)) {
81 lineno++;
82
83 if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
84 for (p = buf; *p && isspace((int) *p); p++);
85 if (!*p || *p == '#') continue;
86
87 key = p;
88 while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) {
89 if (isupper((int) *p)) *p = (char) tolower(*p);
90 p++;
91 }
92 if (*p != ':') {
93 fclose(infile);
94 return SASL_CONFIGERR;
95 }
96 *p++ = '\0';
97
98 while (*p && isspace((int) *p)) p++;
99
100 if (!*p) {
101 fclose(infile);
102 return SASL_CONFIGERR;
103 }
104
105 /* Now strip trailing spaces, if any */
106 tail = p + strlen(p) - 1;
107 while (tail > p && isspace((int) *tail)) {
108 *tail = '\0';
109 tail--;
110 }
111
112 if (nconfiglist == alloced) {
113 alloced += CONFIGLISTGROWSIZE;
114 configlist=sasl_REALLOC((char *)configlist,
115 alloced * sizeof(struct configlist));
116 if (configlist == NULL) {
117 fclose(infile);
118 return SASL_NOMEM;
119 }
120 }
121
122 result = _sasl_strdup(key,
123 &(configlist[nconfiglist].key),
124 NULL);
125 if (result != SASL_OK) {
126 fclose(infile);
127 return result;
128 }
129 result = _sasl_strdup(p,
130 &(configlist[nconfiglist].value),
131 NULL);
132 if (result != SASL_OK) {
133 fclose(infile);
134 return result;
135 }
136
137 nconfiglist++;
138 }
139 fclose(infile);
140
141 return SASL_OK;
142 }
143
sasl_config_getstring(const char * key,const char * def)144 const char *sasl_config_getstring(const char *key,const char *def)
145 {
146 int opt;
147
148 for (opt = 0; opt < nconfiglist; opt++) {
149 if (*key == configlist[opt].key[0] &&
150 !strcmp(key, configlist[opt].key))
151 return configlist[opt].value;
152 }
153 return def;
154 }
155
sasl_config_done(void)156 void sasl_config_done(void)
157 {
158 int opt;
159
160 for (opt = 0; opt < nconfiglist; opt++) {
161 if (configlist[opt].key) sasl_FREE(configlist[opt].key);
162 if (configlist[opt].value) sasl_FREE(configlist[opt].value);
163 }
164
165 sasl_FREE(configlist);
166 configlist = NULL;
167 nconfiglist = 0;
168 }
169