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