xref: /plan9/sys/src/cmd/gs/src/iutil2.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1993, 1994, 1998 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: iutil2.c,v 1.6 2003/09/03 03:22:59 giles Exp $ */
187dd7cddfSDavid du Colombier /* Level 2 utilities for Ghostscript interpreter */
197dd7cddfSDavid du Colombier #include "memory_.h"
207dd7cddfSDavid du Colombier #include "string_.h"
217dd7cddfSDavid du Colombier #include "ghost.h"
22*593dc095SDavid du Colombier #include "ierrors.h"
237dd7cddfSDavid du Colombier #include "opcheck.h"
247dd7cddfSDavid du Colombier #include "gsparam.h"
257dd7cddfSDavid du Colombier #include "gsutil.h"		/* bytes_compare prototype */
267dd7cddfSDavid du Colombier #include "idict.h"
277dd7cddfSDavid du Colombier #include "imemory.h"		/* for iutil.h */
287dd7cddfSDavid du Colombier #include "iutil.h"
297dd7cddfSDavid du Colombier #include "iutil2.h"
307dd7cddfSDavid du Colombier 
317dd7cddfSDavid du Colombier /* ------ Password utilities ------ */
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier /* Read a password from a parameter list. */
347dd7cddfSDavid du Colombier /* Return 0 if present, 1 if absent, or an error code. */
357dd7cddfSDavid du Colombier int
param_read_password(gs_param_list * plist,const char * kstr,password * ppass)367dd7cddfSDavid du Colombier param_read_password(gs_param_list * plist, const char *kstr, password * ppass)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier     gs_param_string ps;
397dd7cddfSDavid du Colombier     long ipass;
407dd7cddfSDavid du Colombier     int code;
417dd7cddfSDavid du Colombier 
427dd7cddfSDavid du Colombier     ps.data = (const byte *)ppass->data, ps.size = ppass->size,
437dd7cddfSDavid du Colombier 	ps.persistent = false;
447dd7cddfSDavid du Colombier     code = param_read_string(plist, kstr, &ps);
457dd7cddfSDavid du Colombier     switch (code) {
467dd7cddfSDavid du Colombier 	case 0:		/* OK */
477dd7cddfSDavid du Colombier 	    if (ps.size > MAX_PASSWORD)
487dd7cddfSDavid du Colombier 		return_error(e_limitcheck);
497dd7cddfSDavid du Colombier 	    /* Copy the data back. */
507dd7cddfSDavid du Colombier 	    memcpy(ppass->data, ps.data, ps.size);
517dd7cddfSDavid du Colombier 	    ppass->size = ps.size;
527dd7cddfSDavid du Colombier 	    return 0;
537dd7cddfSDavid du Colombier 	case 1:		/* key is missing */
547dd7cddfSDavid du Colombier 	    return 1;
557dd7cddfSDavid du Colombier     }
567dd7cddfSDavid du Colombier     /* We might have gotten a typecheck because */
577dd7cddfSDavid du Colombier     /* the supplied password was an integer. */
587dd7cddfSDavid du Colombier     if (code != e_typecheck)
597dd7cddfSDavid du Colombier 	return code;
607dd7cddfSDavid du Colombier     code = param_read_long(plist, kstr, &ipass);
617dd7cddfSDavid du Colombier     if (code != 0)		/* error or missing */
627dd7cddfSDavid du Colombier 	return code;
637dd7cddfSDavid du Colombier     sprintf((char *)ppass->data, "%ld", ipass);
647dd7cddfSDavid du Colombier     ppass->size = strlen((char *)ppass->data);
657dd7cddfSDavid du Colombier     return 0;
667dd7cddfSDavid du Colombier }
677dd7cddfSDavid du Colombier /* Write a password to a parameter list. */
687dd7cddfSDavid du Colombier int
param_write_password(gs_param_list * plist,const char * kstr,const password * ppass)697dd7cddfSDavid du Colombier param_write_password(gs_param_list * plist, const char *kstr,
707dd7cddfSDavid du Colombier 		     const password * ppass)
717dd7cddfSDavid du Colombier {
727dd7cddfSDavid du Colombier     gs_param_string ps;
737dd7cddfSDavid du Colombier 
747dd7cddfSDavid du Colombier     ps.data = (const byte *)ppass->data, ps.size = ppass->size,
757dd7cddfSDavid du Colombier 	ps.persistent = false;
767dd7cddfSDavid du Colombier     if (ps.size > MAX_PASSWORD)
777dd7cddfSDavid du Colombier 	return_error(e_limitcheck);
787dd7cddfSDavid du Colombier     return param_write_string(plist, kstr, &ps);
797dd7cddfSDavid du Colombier }
807dd7cddfSDavid du Colombier 
817dd7cddfSDavid du Colombier /* Check a password from a parameter list. */
827dd7cddfSDavid du Colombier /* Return 0 if OK, 1 if not OK, or an error code. */
837dd7cddfSDavid du Colombier int
param_check_password(gs_param_list * plist,const password * ppass)847dd7cddfSDavid du Colombier param_check_password(gs_param_list * plist, const password * ppass)
857dd7cddfSDavid du Colombier {
867dd7cddfSDavid du Colombier     if (ppass->size != 0) {
877dd7cddfSDavid du Colombier 	password pass;
887dd7cddfSDavid du Colombier 	int code = param_read_password(plist, "Password", &pass);
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier 	if (code)
917dd7cddfSDavid du Colombier 	    return code;
927dd7cddfSDavid du Colombier 	if (pass.size != ppass->size ||
937dd7cddfSDavid du Colombier 	    bytes_compare(&pass.data[0], pass.size,
947dd7cddfSDavid du Colombier 			  &ppass->data[0],
957dd7cddfSDavid du Colombier 			  ppass->size) != 0
967dd7cddfSDavid du Colombier 	    )
977dd7cddfSDavid du Colombier 	    return 1;
987dd7cddfSDavid du Colombier     }
997dd7cddfSDavid du Colombier     return 0;
1007dd7cddfSDavid du Colombier }
1017dd7cddfSDavid du Colombier 
1027dd7cddfSDavid du Colombier /* Read a password from, or write a password into, a dictionary */
1037dd7cddfSDavid du Colombier /* (presumably systemdict). */
1047dd7cddfSDavid du Colombier private int
dict_find_password(ref ** ppvalue,const ref * pdref,const char * kstr)1057dd7cddfSDavid du Colombier dict_find_password(ref ** ppvalue, const ref * pdref, const char *kstr)
1067dd7cddfSDavid du Colombier {
1077dd7cddfSDavid du Colombier     ref *pvalue;
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier     if (dict_find_string(pdref, kstr, &pvalue) <= 0)
1107dd7cddfSDavid du Colombier 	return_error(e_undefined);
1117dd7cddfSDavid du Colombier     if (!r_has_type(pvalue, t_string) ||
1127dd7cddfSDavid du Colombier 	r_has_attrs(pvalue, a_read) ||
1137dd7cddfSDavid du Colombier 	pvalue->value.const_bytes[0] >= r_size(pvalue)
1147dd7cddfSDavid du Colombier 	)
1157dd7cddfSDavid du Colombier 	return_error(e_rangecheck);
1167dd7cddfSDavid du Colombier     *ppvalue = pvalue;
1177dd7cddfSDavid du Colombier     return 0;
1187dd7cddfSDavid du Colombier }
1197dd7cddfSDavid du Colombier int
dict_read_password(password * ppass,const ref * pdref,const char * pkey)1207dd7cddfSDavid du Colombier dict_read_password(password * ppass, const ref * pdref, const char *pkey)
1217dd7cddfSDavid du Colombier {
1227dd7cddfSDavid du Colombier     ref *pvalue;
1237dd7cddfSDavid du Colombier     int code = dict_find_password(&pvalue, pdref, pkey);
1247dd7cddfSDavid du Colombier 
1257dd7cddfSDavid du Colombier     if (code < 0)
1267dd7cddfSDavid du Colombier 	return code;
1277dd7cddfSDavid du Colombier     if (pvalue->value.const_bytes[0] > MAX_PASSWORD)
1287dd7cddfSDavid du Colombier 	return_error(e_rangecheck);	/* limitcheck? */
1297dd7cddfSDavid du Colombier     memcpy(ppass->data, pvalue->value.const_bytes + 1,
1307dd7cddfSDavid du Colombier 	   (ppass->size = pvalue->value.const_bytes[0]));
1317dd7cddfSDavid du Colombier     return 0;
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier int
dict_write_password(const password * ppass,ref * pdref,const char * pkey,bool change_allowed)1343ff48bf5SDavid du Colombier dict_write_password(const password * ppass, ref * pdref, const char *pkey,
1353ff48bf5SDavid du Colombier 			bool change_allowed)
1367dd7cddfSDavid du Colombier {
1377dd7cddfSDavid du Colombier     ref *pvalue;
1387dd7cddfSDavid du Colombier     int code = dict_find_password(&pvalue, pdref, pkey);
1397dd7cddfSDavid du Colombier 
1407dd7cddfSDavid du Colombier     if (code < 0)
1417dd7cddfSDavid du Colombier 	return code;
1427dd7cddfSDavid du Colombier     if (ppass->size >= r_size(pvalue))
1437dd7cddfSDavid du Colombier 	return_error(e_rangecheck);
1443ff48bf5SDavid du Colombier     if (!change_allowed &&
1453ff48bf5SDavid du Colombier     	bytes_compare(pvalue->value.bytes + 1, pvalue->value.bytes[0],
1463ff48bf5SDavid du Colombier 	    ppass->data, ppass->size) != 0)
1473ff48bf5SDavid du Colombier 	return_error(e_invalidaccess);
1487dd7cddfSDavid du Colombier     memcpy(pvalue->value.bytes + 1, ppass->data,
1497dd7cddfSDavid du Colombier 	   (pvalue->value.bytes[0] = ppass->size));
1507dd7cddfSDavid du Colombier     return 0;
1517dd7cddfSDavid du Colombier }
152