xref: /plan9/sys/src/cmd/gs/src/iutil2.c (revision ff8c3af2f44d95267f67219afa20ba82ff6cf7e4)
1 /* Copyright (C) 1993, 1994, 1998 Aladdin Enterprises.  All rights reserved.
2 
3   This file is part of AFPL Ghostscript.
4 
5   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
6   distributor accepts any responsibility for the consequences of using it, or
7   for whether it serves any particular purpose or works at all, unless he or
8   she says so in writing.  Refer to the Aladdin Free Public License (the
9   "License") for full details.
10 
11   Every copy of AFPL Ghostscript must include a copy of the License, normally
12   in a plain ASCII text file named PUBLIC.  The License grants you the right
13   to copy, modify and redistribute AFPL Ghostscript, but only under certain
14   conditions described in the License.  Among other things, the License
15   requires that the copyright notice and this notice be preserved on all
16   copies.
17 */
18 
19 /*$Id: iutil2.c,v 1.2.6.1 2002/01/25 06:33:09 rayjj Exp $ */
20 /* Level 2 utilities for Ghostscript interpreter */
21 #include "memory_.h"
22 #include "string_.h"
23 #include "ghost.h"
24 #include "errors.h"
25 #include "opcheck.h"
26 #include "gsparam.h"
27 #include "gsutil.h"		/* bytes_compare prototype */
28 #include "idict.h"
29 #include "imemory.h"		/* for iutil.h */
30 #include "iutil.h"
31 #include "iutil2.h"
32 
33 /* ------ Password utilities ------ */
34 
35 /* Read a password from a parameter list. */
36 /* Return 0 if present, 1 if absent, or an error code. */
37 int
38 param_read_password(gs_param_list * plist, const char *kstr, password * ppass)
39 {
40     gs_param_string ps;
41     long ipass;
42     int code;
43 
44     ps.data = (const byte *)ppass->data, ps.size = ppass->size,
45 	ps.persistent = false;
46     code = param_read_string(plist, kstr, &ps);
47     switch (code) {
48 	case 0:		/* OK */
49 	    if (ps.size > MAX_PASSWORD)
50 		return_error(e_limitcheck);
51 	    /* Copy the data back. */
52 	    memcpy(ppass->data, ps.data, ps.size);
53 	    ppass->size = ps.size;
54 	    return 0;
55 	case 1:		/* key is missing */
56 	    return 1;
57     }
58     /* We might have gotten a typecheck because */
59     /* the supplied password was an integer. */
60     if (code != e_typecheck)
61 	return code;
62     code = param_read_long(plist, kstr, &ipass);
63     if (code != 0)		/* error or missing */
64 	return code;
65     sprintf((char *)ppass->data, "%ld", ipass);
66     ppass->size = strlen((char *)ppass->data);
67     return 0;
68 }
69 /* Write a password to a parameter list. */
70 int
71 param_write_password(gs_param_list * plist, const char *kstr,
72 		     const password * ppass)
73 {
74     gs_param_string ps;
75 
76     ps.data = (const byte *)ppass->data, ps.size = ppass->size,
77 	ps.persistent = false;
78     if (ps.size > MAX_PASSWORD)
79 	return_error(e_limitcheck);
80     return param_write_string(plist, kstr, &ps);
81 }
82 
83 /* Check a password from a parameter list. */
84 /* Return 0 if OK, 1 if not OK, or an error code. */
85 int
86 param_check_password(gs_param_list * plist, const password * ppass)
87 {
88     if (ppass->size != 0) {
89 	password pass;
90 	int code = param_read_password(plist, "Password", &pass);
91 
92 	if (code)
93 	    return code;
94 	if (pass.size != ppass->size ||
95 	    bytes_compare(&pass.data[0], pass.size,
96 			  &ppass->data[0],
97 			  ppass->size) != 0
98 	    )
99 	    return 1;
100     }
101     return 0;
102 }
103 
104 /* Read a password from, or write a password into, a dictionary */
105 /* (presumably systemdict). */
106 private int
107 dict_find_password(ref ** ppvalue, const ref * pdref, const char *kstr)
108 {
109     ref *pvalue;
110 
111     if (dict_find_string(pdref, kstr, &pvalue) <= 0)
112 	return_error(e_undefined);
113     if (!r_has_type(pvalue, t_string) ||
114 	r_has_attrs(pvalue, a_read) ||
115 	pvalue->value.const_bytes[0] >= r_size(pvalue)
116 	)
117 	return_error(e_rangecheck);
118     *ppvalue = pvalue;
119     return 0;
120 }
121 int
122 dict_read_password(password * ppass, const ref * pdref, const char *pkey)
123 {
124     ref *pvalue;
125     int code = dict_find_password(&pvalue, pdref, pkey);
126 
127     if (code < 0)
128 	return code;
129     if (pvalue->value.const_bytes[0] > MAX_PASSWORD)
130 	return_error(e_rangecheck);	/* limitcheck? */
131     memcpy(ppass->data, pvalue->value.const_bytes + 1,
132 	   (ppass->size = pvalue->value.const_bytes[0]));
133     return 0;
134 }
135 int
136 dict_write_password(const password * ppass, ref * pdref, const char *pkey,
137 			bool change_allowed)
138 {
139     ref *pvalue;
140     int code = dict_find_password(&pvalue, pdref, pkey);
141 
142     if (code < 0)
143 	return code;
144     if (ppass->size >= r_size(pvalue))
145 	return_error(e_rangecheck);
146     if (!change_allowed &&
147     	bytes_compare(pvalue->value.bytes + 1, pvalue->value.bytes[0],
148 	    ppass->data, ppass->size) != 0)
149 	return_error(e_invalidaccess);
150     memcpy(pvalue->value.bytes + 1, ppass->data,
151 	   (pvalue->value.bytes[0] = ppass->size));
152     return 0;
153 }
154