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]
21 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
31 #include <libxml/tree.h>
32 #include <libxml/parser.h>
38 /* Supporting structures and global variables for getopt_av(). */
39 typedef struct av_opts_s
{
40 int shortnm
; /* short name character */
41 char *longnm
; /* long name string, NOT terminated */
42 int longnm_len
; /* length of long name string */
43 boolean_t has_arg
; /* takes optional argument */
46 static av_opts
*opts_av
= NULL
;
47 static const char *_save_optstr
= NULL
;
48 static int _save_numopts
= 0;
50 char *optarg_av
= NULL
;
53 free_policy_list(POLICY_LIST
*plist
)
55 POLICY_LIST
*n
= plist
, *old
;
62 kmf_free_policy_record(&n
->plc
);
70 load_policies(char *file
, POLICY_LIST
**policy_list
)
73 KMF_RETURN kmfrv
= KMF_OK
;
74 POLICY_LIST
*newitem
, *plist
= NULL
;
75 xmlParserCtxtPtr ctxt
;
79 /* Create a parser context */
80 ctxt
= xmlNewParserCtxt();
82 return (KMF_ERR_POLICY_DB_FORMAT
);
84 /* Read the policy DB and verify it against the schema. */
85 doc
= xmlCtxtReadFile(ctxt
, file
, NULL
,
86 XML_PARSE_DTDVALID
| XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
);
87 if (doc
== NULL
|| ctxt
->valid
== 0) {
88 kmfrv
= KMF_ERR_POLICY_DB_FORMAT
;
92 cur
= xmlDocGetRootElement(doc
);
94 kmfrv
= KMF_ERR_POLICY_DB_FORMAT
;
98 node
= cur
->xmlChildrenNode
;
99 while (node
!= NULL
) {
102 * Search for the policy that matches the given name.
104 if (!xmlStrcmp((const xmlChar
*)node
->name
,
105 (const xmlChar
*)KMF_POLICY_ELEMENT
)) {
106 /* Check the name attribute */
107 c
= (char *)xmlGetProp(node
,
108 (const xmlChar
*)KMF_POLICY_NAME_ATTR
);
110 /* If a match, parse the rest of the data */
113 newitem
= malloc(sizeof (POLICY_LIST
));
114 if (newitem
!= NULL
) {
115 (void) memset(newitem
, 0,
116 sizeof (POLICY_LIST
));
117 kmfrv
= parsePolicyElement(node
,
120 kmfrv
= KMF_ERR_MEMORY
;
123 /* add to linked list */
127 POLICY_LIST
*n
= plist
;
128 while (n
->next
!= NULL
)
132 newitem
->next
= NULL
;
141 xmlFreeParserCtxt(ctxt
);
146 if (kmfrv
!= KMF_OK
) {
147 free_policy_list(plist
);
150 *policy_list
= plist
;
157 * Return 0 if there is any error in the input string.
160 parseKUlist(char *kustring
)
166 p
= strtok(kustring
, ",");
168 cur_bit
= kmf_string_to_ku(p
);
174 p
= strtok(NULL
, ",");
181 addToEKUList(KMF_EKU_POLICY
*ekus
, KMF_OID
*newoid
)
183 if (newoid
!= NULL
&& ekus
!= NULL
) {
185 ekus
->ekulist
= reallocarray(ekus
->ekulist
, ekus
->eku_count
,
187 if (ekus
->ekulist
!= NULL
) {
188 ekus
->ekulist
[ekus
->eku_count
-1] = *newoid
;
194 parseEKUNames(char *ekulist
, KMF_POLICY_RECORD
*plc
)
199 KMF_EKU_POLICY
*ekus
= &plc
->eku_set
;
201 if (ekulist
== NULL
|| !strlen(ekulist
))
205 * The list should be comma separated list of EKU Names.
207 p
= strtok(ekulist
, ",");
209 /* If no tokens found, then maybe its just a single EKU value */
211 newoid
= kmf_ekuname_to_oid(ekulist
);
212 if (newoid
!= NULL
) {
213 addToEKUList(ekus
, newoid
);
221 newoid
= kmf_ekuname_to_oid(p
);
222 if (newoid
!= NULL
) {
223 addToEKUList(ekus
, newoid
);
229 p
= strtok(NULL
, ",");
233 kmf_free_eku_policy(ekus
);
239 parseEKUOIDs(char *ekulist
, KMF_POLICY_RECORD
*plc
)
243 KMF_OID newoid
= { 0, NULL
};
244 KMF_EKU_POLICY
*ekus
= &plc
->eku_set
;
246 if (ekulist
== NULL
|| !strlen(ekulist
))
250 * The list should be comma separated list of EKU Names.
252 p
= strtok(ekulist
, ",");
254 if (kmf_string_to_oid(ekulist
, &newoid
) == KMF_OK
) {
255 addToEKUList(ekus
, &newoid
);
261 while (p
!= NULL
&& rv
== 0) {
262 if (kmf_string_to_oid(p
, &newoid
) == KMF_OK
) {
263 addToEKUList(ekus
, &newoid
);
268 p
= strtok(NULL
, ",");
272 kmf_free_eku_policy(ekus
);
278 get_boolean(char *arg
)
282 if (strcasecmp(arg
, "true") == 0)
284 if (strcasecmp(arg
, "false") == 0)
290 * This function processes the input string. It removes the beginning
291 * and ending blank's first, makes a copy of the resulting string and
294 * This function returns NULL, if there is an error in the
295 * input string or when the system is out of memory. The output
296 * "err_flag" argument will record the error code, if it is not NULL.
299 get_string(char *str
, int *err_flag
)
306 if (err_flag
!= NULL
)
307 *err_flag
= KC_ERR_USAGE
;
311 /* Remove beginning whitespace */
313 while (p
!= NULL
&& isspace(*p
))
317 if (err_flag
!= NULL
)
318 *err_flag
= KC_ERR_USAGE
;
322 /* Remove the trailing blanks */
324 while (len
> 0 && isspace(p
[len
-1]))
328 if (err_flag
!= NULL
)
329 *err_flag
= KC_ERR_USAGE
;
333 /* Check if there is any non-printable character */
339 if (err_flag
!= NULL
)
340 *err_flag
= KC_ERR_USAGE
;
345 /* Make a copy of the string and return it */
346 retstr
= malloc(len
+ 1);
347 if (retstr
== NULL
) {
348 if (err_flag
!= NULL
)
349 *err_flag
= KC_ERR_MEMORY
;
353 if (err_flag
!= NULL
)
356 (void) strncpy(retstr
, p
, len
);
362 * Breaks out the getopt-style option string into a structure that can be
363 * traversed later for calls to getopt_av(). Option string is NOT altered,
364 * but the struct fields point to locations within option string.
367 populate_opts(char *optstring
)
373 if (optstring
== NULL
|| *optstring
== '\0')
377 * This tries to imitate getopt(3c) Each option must conform to:
378 * <short name char> [ ':' ] [ '(' <long name string> ')' ]
379 * If long name is missing, the short name is used for long name.
381 for (i
= 0; *optstring
!= '\0'; i
++) {
382 if ((temp
= (av_opts
*)((i
== 0) ? malloc(sizeof (av_opts
)) :
383 reallocarray(opts_av
, i
+ 1, sizeof (av_opts
)))) == NULL
) {
388 opts_av
= (av_opts
*)temp
;
390 marker
= optstring
; /* may need optstring later */
392 opts_av
[i
].shortnm
= *marker
++; /* set short name */
394 if (*marker
== ':') { /* check for opt arg */
396 opts_av
[i
].has_arg
= B_TRUE
;
399 if (*marker
== '(') { /* check and set long name */
401 opts_av
[i
].longnm
= marker
;
402 opts_av
[i
].longnm_len
= strcspn(marker
, ")");
403 optstring
= marker
+ opts_av
[i
].longnm_len
+ 1;
405 /* use short name option character */
406 opts_av
[i
].longnm
= optstring
;
407 opts_av
[i
].longnm_len
= 1;
416 * getopt_av() is very similar to getopt(3c) in that the takes an option
417 * string, compares command line arguments for matches, and returns a single
418 * letter option when a match is found. However, getopt_av() differs from
419 * getopt(3c) by allowing both longname options and values be found
420 * on the command line.
423 getopt_av(int argc
, char * const *argv
, const char *optstring
)
428 if (optind_av
>= argc
)
431 /* First time or when optstring changes from previous one */
432 if (_save_optstr
!= optstring
) {
435 _save_optstr
= optstring
;
436 _save_numopts
= populate_opts((char *)optstring
);
439 for (i
= 0; i
< _save_numopts
; i
++) {
440 if (strcmp(argv
[optind_av
], "--") == 0) {
445 len
= strcspn(argv
[optind_av
], "=");
447 if (len
== opts_av
[i
].longnm_len
&& strncmp(argv
[optind_av
],
448 opts_av
[i
].longnm
, opts_av
[i
].longnm_len
) == 0) {
450 if (!opts_av
[i
].has_arg
) {
452 return (opts_av
[i
].shortnm
);
456 if (argv
[optind_av
][len
] == '=') {
457 optarg_av
= &(argv
[optind_av
][len
+1]);
459 return (opts_av
[i
].shortnm
);
472 print_sanity_error(KMF_RETURN ret
)
475 case KMF_ERR_POLICY_NAME
:
476 (void) fprintf(stderr
, gettext("Error in the policy name\n"));
478 case KMF_ERR_TA_POLICY
:
479 (void) fprintf(stderr
,
480 gettext("Error in trust anchor attributes\n"));
482 case KMF_ERR_OCSP_POLICY
:
483 (void) fprintf(stderr
,
484 gettext("Error in OCSP policy attributes\n"));
493 get_keystore_entry(char *kstore_name
)
495 conf_entrylist_t
*phead
= NULL
;
496 conf_entrylist_t
*ptr
;
497 conf_entry_t
*rtn_entry
= NULL
;
499 if (kstore_name
== NULL
)
502 if (get_entrylist(&phead
) != KMF_OK
)
506 while (ptr
!= NULL
) {
507 if (strcmp(ptr
->entry
->keystore
, kstore_name
) == 0)
512 if (ptr
!= NULL
) /* found the entry */
513 rtn_entry
= dup_entry(ptr
->entry
);
515 free_entrylist(phead
);