dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / cryptoadm / adm_util.c
blobf816a02870bac214699bdd1d3b4f85f932a6b0e3
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <ctype.h>
27 #include <strings.h>
28 #include <libintl.h>
29 #include <stdio.h>
30 #include <sys/stat.h>
31 #include "cryptoadm.h"
32 #include <cryptoutil.h>
35 * Create one item of type mechlist_t with the mechanism name. A null is
36 * returned to indicate that the storage space available is insufficient.
38 mechlist_t *
39 create_mech(char *name)
41 mechlist_t *pres = NULL;
42 char *first, *last;
44 if (name == NULL) {
45 return (NULL);
48 pres = malloc(sizeof (mechlist_t));
49 if (pres == NULL) {
50 cryptodebug("out of memory.");
51 return (NULL);
54 first = name;
55 while (isspace(*first)) /* nuke leading whitespace */
56 first++;
57 (void) strlcpy(pres->name, first, sizeof (pres->name));
59 last = strrchr(pres->name, '\0');
60 last--;
61 while (isspace(*last)) /* nuke trailing whitespace */
62 *last-- = '\0';
64 pres->next = NULL;
66 return (pres);
71 void
72 free_mechlist(mechlist_t *plist)
74 mechlist_t *pnext;
76 while (plist != NULL) {
77 pnext = plist->next;
78 free(plist);
79 plist = pnext;
86 * Check if the mechanism is in the mechanism list.
88 boolean_t
89 is_in_list(char *mechname, mechlist_t *plist)
91 boolean_t found = B_FALSE;
93 if (mechname == NULL) {
94 return (B_FALSE);
97 while (plist != NULL) {
98 if (strcmp(plist->name, mechname) == 0) {
99 found = B_TRUE;
100 break;
102 plist = plist->next;
105 return (found);
109 update_conf(char *conf_file, char *entry)
112 boolean_t found;
113 boolean_t fips_entry = B_FALSE;
114 FILE *pfile;
115 FILE *pfile_tmp;
116 char tmpfile_name[MAXPATHLEN];
117 char *ptr;
118 char *name;
119 char buffer[BUFSIZ];
120 char buffer2[BUFSIZ];
121 int found_count;
122 int rc = SUCCESS;
123 int err;
125 if ((pfile = fopen(conf_file, "r+")) == NULL) {
126 err = errno;
127 cryptoerror(LOG_STDERR,
128 gettext("failed to update the configuration - %s"),
129 strerror(err));
130 cryptodebug("failed to open %s for write.", conf_file);
131 return (FAILURE);
134 if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
135 err = errno;
136 cryptoerror(LOG_STDERR,
137 gettext("failed to lock the configuration - %s"),
138 strerror(err));
139 (void) fclose(pfile);
140 return (FAILURE);
144 * Create a temporary file in the /etc/crypto directory.
146 (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
147 if (mkstemp(tmpfile_name) == -1) {
148 err = errno;
149 cryptoerror(LOG_STDERR,
150 gettext("failed to create a temporary file - %s"),
151 strerror(err));
152 (void) fclose(pfile);
153 return (FAILURE);
156 if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
157 err = errno;
158 cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
159 tmpfile_name, strerror(err));
160 (void) fclose(pfile);
161 return (FAILURE);
166 * Loop thru the config file. If the provider was reserved within a
167 * package bracket, just uncomment it. Otherwise, append it at
168 * the end. The resulting file will be saved in the temp file first.
170 found_count = 0;
171 rc = SUCCESS;
173 while (fgets(buffer, BUFSIZ, pfile) != NULL) {
174 found = B_FALSE;
175 if (strcmp(conf_file, _PATH_PKCS11_CONF) == 0) {
176 if (buffer[0] == '#') {
177 ptr = buffer;
178 ptr++;
179 if (strcmp(entry, ptr) == 0) {
180 found = B_TRUE;
181 found_count++;
183 } else {
184 (void) strlcpy(buffer2, buffer, BUFSIZ);
185 ptr = buffer2;
186 if ((name = strtok(ptr, SEP_COLON)) == NULL) {
187 rc = FAILURE;
188 break;
189 } else if (strcmp(FIPS_KEYWORD, name) == 0) {
190 found = B_TRUE;
191 found_count++;
192 fips_entry = B_TRUE;
195 } else { /* _PATH_KCF_CONF */
196 if (buffer[0] == '#') {
197 (void) strlcpy(buffer2, buffer, BUFSIZ);
198 ptr = buffer2;
199 ptr++; /* skip # */
200 if ((name = strtok(ptr, SEP_COLON)) == NULL) {
201 rc = FAILURE;
202 break;
204 } else {
205 (void) strlcpy(buffer2, buffer, BUFSIZ);
206 ptr = buffer2;
207 if ((name = strtok(ptr, SEP_COLON)) == NULL) {
208 rc = FAILURE;
209 break;
214 if (found == B_FALSE) {
215 if (fputs(buffer, pfile_tmp) == EOF) {
216 rc = FAILURE;
218 } else {
219 if (found_count == 1) {
220 if (strcmp(conf_file, _PATH_PKCS11_CONF) == 0) {
221 if (fips_entry == B_TRUE) {
222 if (fputs(entry, pfile_tmp) ==
223 EOF) {
224 rc = FAILURE;
226 fips_entry = B_FALSE;
227 } else {
228 if (fputs(ptr, pfile_tmp) ==
229 EOF) {
230 rc = FAILURE;
233 } else {
234 if (fputs(entry, pfile_tmp) == EOF) {
235 rc = FAILURE;
238 } else {
240 * Found a second entry with same tag name.
241 * Should not happen. The config file
242 * is corrupted. Give a warning and skip
243 * this entry.
245 cryptoerror(LOG_STDERR, gettext(
246 "(Warning) Found an additional reserved "
247 "entry for %s."), entry);
251 if (rc == FAILURE) {
252 break;
256 (void) fclose(pfile);
258 if (rc == FAILURE) {
259 cryptoerror(LOG_STDERR, gettext("write error."));
260 (void) fclose(pfile_tmp);
261 if (unlink(tmpfile_name) != 0) {
262 err = errno;
263 cryptoerror(LOG_STDERR, gettext(
264 "(Warning) failed to remove %s: %s"), tmpfile_name,
265 strerror(err));
267 return (FAILURE);
270 if (found_count == 0) {
272 * The entry was not in config file before, append it to the
273 * end of the temp file.
275 if (fputs(entry, pfile_tmp) == EOF) {
276 cryptoerror(LOG_STDERR, gettext(
277 "failed to write to %s: %s"), tmpfile_name,
278 strerror(errno));
279 (void) fclose(pfile_tmp);
280 if (unlink(tmpfile_name) != 0) {
281 err = errno;
282 cryptoerror(LOG_STDERR, gettext(
283 "(Warning) failed to remove %s: %s"),
284 tmpfile_name, strerror(err));
286 return (FAILURE);
290 if (fclose(pfile_tmp) != 0) {
291 err = errno;
292 cryptoerror(LOG_STDERR,
293 gettext("failed to close %s: %s"), tmpfile_name,
294 strerror(err));
295 return (FAILURE);
298 if (rename(tmpfile_name, conf_file) == -1) {
299 err = errno;
300 cryptoerror(LOG_STDERR,
301 gettext("failed to update the configuration - %s"),
302 strerror(err));
303 cryptodebug("failed to rename %s to %s: %s", tmpfile_name,
304 conf_file, strerror(err));
305 rc = FAILURE;
306 } else if (chmod(conf_file,
307 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
308 err = errno;
309 cryptoerror(LOG_STDERR,
310 gettext("failed to update the configuration - %s"),
311 strerror(err));
312 cryptodebug("failed to chmod to %s: %s", conf_file,
313 strerror(err));
314 rc = FAILURE;
315 } else {
316 rc = SUCCESS;
319 if (rc == FAILURE) {
320 if (unlink(tmpfile_name) != 0) {
321 err = errno;
322 cryptoerror(LOG_STDERR, gettext(
323 "(Warning) failed to remove %s: %s"),
324 tmpfile_name, strerror(err));
328 return (rc);