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