diff options
-rw-r--r-- | CHANGES.txt | 6 | ||||
-rw-r--r-- | backend/ipp.c | 40 | ||||
-rw-r--r-- | cgi-bin/Dependencies | 3 | ||||
-rw-r--r-- | cups/Dependencies | 17 | ||||
-rw-r--r-- | cups/Makefile | 1 | ||||
-rw-r--r-- | cups/cups.h | 3 | ||||
-rw-r--r-- | cups/hash.c | 250 | ||||
-rw-r--r-- | cups/ppd-cache.c | 31 | ||||
-rw-r--r-- | cups/versioning.h | 4 | ||||
-rw-r--r-- | xcode/CUPS.xcodeproj/project.pbxproj | 8 |
10 files changed, 354 insertions, 9 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 05722be21..3e3edb78b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -CHANGES.txt - 2.2b1 - 2015-10-19 +CHANGES.txt - 2.2b1 - 2015-11-18 -------------------------------- CHANGES IN CUPS V2.2b1 @@ -6,4 +6,6 @@ CHANGES IN CUPS V2.2b1 - The cupsd domain socket is no longer world-accessible on OS X (<rdar://problem/7542560>) - Interface scripts are no longer supported for security reasons - (<rdar://problem/23135640>)
\ No newline at end of file + (<rdar://problem/23135640>) + - Added a new cupsHashData API and support for hashed job passwords + (<rdar://problem/20221502>) diff --git a/backend/ipp.c b/backend/ipp.c index 2376da4e7..5d0fc662d 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -108,6 +108,7 @@ static const char * const pattrs[] = /* Printer attributes we want */ "copies-supported", "cups-version", "document-format-supported", + "job-password-encryption-supported", "marker-colors", "marker-high-levels", "marker-levels", @@ -249,6 +250,7 @@ main(int argc, /* I - Number of command-line args */ #endif /* HAVE_LIBZ */ ipp_attribute_t *copies_sup; /* copies-supported */ ipp_attribute_t *cups_version; /* cups-version */ + ipp_attribute_t *encryption_sup; /* job-password-encryption-supported */ ipp_attribute_t *format_sup; /* document-format-supported */ ipp_attribute_t *job_auth; /* job-authorization-uri */ ipp_attribute_t *media_col_sup; /* media-col-supported */ @@ -880,6 +882,7 @@ main(int argc, /* I - Number of command-line args */ #endif /* HAVE_LIBZ */ copies_sup = NULL; cups_version = NULL; + encryption_sup = NULL; format_sup = NULL; media_col_sup = NULL; supported = NULL; @@ -1125,6 +1128,8 @@ main(int argc, /* I - Number of command-line args */ cups_version = ippFindAttribute(supported, "cups-version", IPP_TAG_TEXT); + encryption_sup = ippFindAttribute(supported, "job-password-encryption-supported", IPP_TAG_KEYWORD); + if ((format_sup = ippFindAttribute(supported, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) { @@ -1309,6 +1314,41 @@ main(int argc, /* I - Number of command-line args */ if ((mandatory = ppdFindAttr(ppd, "cupsMandatory", NULL)) != NULL) strlcpy(mandatory_attrs, mandatory->value, sizeof(mandatory_attrs)); } + + /* + * Validate job-password/-encryption... + */ + + if (cupsGetOption("job-password", num_options, options)) + { + const char *keyword; /* job-password-encryption value */ + static const char * const hashes[] = + { /* List of supported hash algorithms, in order of preference */ + "sha-512", + "sha-384", + "sha-512_256", + "sha-512-224", + "sha-256", + "sha-224", + "sha", + "none" + }; + + if ((keyword = cupsGetOption("job-password-encryption", num_options, options)) == NULL || !ippContainsString(encryption_sup, keyword)) + { + /* + * Either no job-password-encryption or the value isn't supported by + * the printer... + */ + + for (i = 0; i < (int)(sizeof(hashes) / sizeof(hashes[0])); i ++) + if (ippContainsString(encryption_sup, hashes[i])) + break; + + if (i < (int)(sizeof(hashes) / sizeof(hashes[0]))) + num_options = cupsAddOption("job-password-encryption", hashes[i], num_options, &options); + } + } } else num_options = 0; diff --git a/cgi-bin/Dependencies b/cgi-bin/Dependencies index 66ffa01e1..9dda29c78 100644 --- a/cgi-bin/Dependencies +++ b/cgi-bin/Dependencies @@ -35,7 +35,8 @@ admin.o: admin.c cgi-private.h cgi.h ../cups/cups.h ../cups/file.h \ ../cups/language.h ../cups/pwg.h help-index.h ../cups/debug-private.h \ ../cups/language-private.h ../cups/transcode.h \ ../cups/string-private.h ../config.h ../cups/ipp-private.h \ - ../cups/adminutil.h ../cups/ppd.h + ../cups/http-private.h ../cups/md5-private.h ../cups/ppd-private.h \ + ../cups/ppd.h ../cups/pwg-private.h ../cups/adminutil.h classes.o: classes.c cgi-private.h cgi.h ../cups/cups.h ../cups/file.h \ ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h \ ../cups/language.h ../cups/pwg.h help-index.h ../cups/debug-private.h \ diff --git a/cups/Dependencies b/cups/Dependencies index 64a0d19d1..e667d3920 100644 --- a/cups/Dependencies +++ b/cups/Dependencies @@ -110,6 +110,12 @@ globals.o: globals.c cups-private.h string-private.h ../config.h \ md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ ../cups/cups.h file.h pwg.h ppd-private.h ../cups/ppd.h \ thread-private.h +hash.o: hash.c cups-private.h string-private.h ../config.h \ + debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ + ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ + md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ + ../cups/cups.h file.h pwg.h ppd-private.h ../cups/ppd.h \ + thread-private.h http.o: http.c cups-private.h string-private.h ../config.h \ debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ @@ -269,6 +275,11 @@ testadmin.o: testadmin.c adminutil.h cups.h file.h versioning.h ipp.h \ http.h array.h language.h pwg.h string-private.h ../config.h testarray.o: testarray.c string-private.h ../config.h debug-private.h \ ../cups/versioning.h array-private.h ../cups/array.h dir.h +testcache.o: testcache.c ppd-private.h ../cups/cups.h file.h versioning.h \ + ipp.h http.h array.h language.h pwg.h ../cups/ppd.h pwg-private.h \ + file-private.h cups-private.h string-private.h ../config.h \ + debug-private.h array-private.h ipp-private.h http-private.h \ + md5-private.h language-private.h ../cups/transcode.h thread-private.h testconflicts.o: testconflicts.c cups.h file.h versioning.h ipp.h http.h \ array.h language.h pwg.h ppd.h string-private.h ../config.h testcups.o: testcups.c string-private.h ../config.h cups.h file.h \ @@ -316,3 +327,9 @@ testsnmp.o: testsnmp.c cups-private.h string-private.h ../config.h \ md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ ../cups/cups.h file.h pwg.h ppd-private.h ../cups/ppd.h \ thread-private.h snmp-private.h +tlscheck.o: tlscheck.c cups-private.h string-private.h ../config.h \ + debug-private.h ../cups/versioning.h array-private.h ../cups/array.h \ + ipp-private.h ../cups/ipp.h http.h http-private.h ../cups/language.h \ + md5-private.h language-private.h ../cups/transcode.h pwg-private.h \ + ../cups/cups.h file.h pwg.h ppd-private.h ../cups/ppd.h \ + thread-private.h diff --git a/cups/Makefile b/cups/Makefile index 60df442a2..dc6859b8c 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -51,6 +51,7 @@ LIBOBJS = \ getifaddrs.o \ getputfile.o \ globals.o \ + hash.o \ http.o \ http-addr.o \ http-addrlist.o \ diff --git a/cups/cups.h b/cups/cups.h index 0fc6c9b23..fbcc332a8 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -629,6 +629,9 @@ extern const char *cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest, cups_d extern int cupsMakeServerCredentials(const char *path, const char *common_name, int num_alt_names, const char **alt_names, time_t expiration_date) _CUPS_API_2_0; extern int cupsSetServerCredentials(const char *path, const char *common_name, int auto_create) _CUPS_API_2_0; +/* New in CUPS 2.2 */ +extern ssize_t cupsHashData(const char *algorithm, const void *data, size_t datalen, unsigned char *hash, size_t hashsize) _CUPS_API_2_2; + # ifdef __cplusplus } # endif /* __cplusplus */ diff --git a/cups/hash.c b/cups/hash.c new file mode 100644 index 000000000..1d7b0dbad --- /dev/null +++ b/cups/hash.c @@ -0,0 +1,250 @@ +/* + * "$Id$" + * + * Hashing function for CUPS. + * + * Copyright 2015 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * which should have been included with this file. If this file is + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +/* + * Include necessary headers... + */ + +#include "cups-private.h" +#ifdef __APPLE__ +# include <CommonCrypto/CommonDigest.h> +#endif /* __APPLE__ */ + + +/* + * 'cupsHashData()' - Perform a hash function on the given data. + * + * The "algorithm" argument can be any of the registered, non-deprecated IPP + * hash algorithms for the "job-password-encryption" attribute, including + * "sha" for SHA-1, "sha-256" for SHA2-256, etc. + * + * The "hash" argument points to a buffer of "hashsize" bytes and should be at + * least 64 bytes in length for all of the supported algorithms. + * + * The returned hash is binary data. + * + * @since CUPS 2.2@ + */ + +ssize_t /* O - Size of hash or -1 on error */ +cupsHashData(const char *algorithm, /* I - Algorithm name */ + const void *data, /* I - Data to hash */ + size_t datalen, /* I - Length of data to hash */ + unsigned char *hash, /* I - Hash buffer */ + size_t hashsize) /* I - Size of hash buffer */ +{ + if (!algorithm || !data || datalen == 0 || !hash || hashsize == 0) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad arguments to function"), 1); + return (-1); + } + +#ifdef __APPLE__ + if (strcmp(algorithm, "sha")) + { + /* + * SHA-1... + */ + + CC_SHA1_CTX ctx; /* SHA-1 context */ + + if (hashsize < CC_SHA1_DIGEST_LENGTH) + goto too_small; + + CC_SHA1_Init(&ctx); + CC_SHA1_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA1_Final(hash, &ctx); + + return (CC_SHA1_DIGEST_LENGTH); + } + else if (strcmp(algorithm, "sha2-224")) + { + CC_SHA256_CTX ctx; /* SHA-224 context */ + + if (hashsize < CC_SHA224_DIGEST_LENGTH) + goto too_small; + + CC_SHA224_Init(&ctx); + CC_SHA224_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA224_Final(hash, &ctx); + + return (CC_SHA224_DIGEST_LENGTH); + } + else if (strcmp(algorithm, "sha2-256")) + { + CC_SHA256_CTX ctx; /* SHA-256 context */ + + if (hashsize < CC_SHA256_DIGEST_LENGTH) + goto too_small; + + CC_SHA256_Init(&ctx); + CC_SHA256_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA256_Final(hash, &ctx); + + return (CC_SHA256_DIGEST_LENGTH); + } + else if (strcmp(algorithm, "sha2-384")) + { + CC_SHA512_CTX ctx; /* SHA-384 context */ + + if (hashsize < CC_SHA384_DIGEST_LENGTH) + goto too_small; + + CC_SHA384_Init(&ctx); + CC_SHA384_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA384_Final(hash, &ctx); + + return (CC_SHA384_DIGEST_LENGTH); + } + else if (strcmp(algorithm, "sha2-512")) + { + CC_SHA512_CTX ctx; /* SHA-512 context */ + + if (hashsize < CC_SHA512_DIGEST_LENGTH) + goto too_small; + + CC_SHA512_Init(&ctx); + CC_SHA512_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA512_Final(hash, &ctx); + + return (CC_SHA512_DIGEST_LENGTH); + } + else if (strcmp(algorithm, "sha2-512_224")) + { + CC_SHA512_CTX ctx; /* SHA-512 context */ + unsigned char temp[CC_SHA512_DIGEST_LENGTH]; + /* SHA-512 hash */ + + /* + * SHA2-512 truncated to 224 bits (28 bytes)... + */ + + if (hashsize < CC_SHA224_DIGEST_LENGTH) + goto too_small; + + CC_SHA512_Init(&ctx); + CC_SHA512_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA512_Final(temp, &ctx); + + memcpy(hash, temp, CC_SHA224_DIGEST_LENGTH); + + return (CC_SHA224_DIGEST_LENGTH); + } + else if (strcmp(algorithm, "sha2-512_256")) + { + CC_SHA512_CTX ctx; /* SHA-512 context */ + unsigned char temp[CC_SHA512_DIGEST_LENGTH]; + /* SHA-512 hash */ + + /* + * SHA2-512 truncated to 256 bits (32 bytes)... + */ + + if (hashsize < CC_SHA256_DIGEST_LENGTH) + goto too_small; + + CC_SHA512_Init(&ctx); + CC_SHA512_Update(&ctx, data, (CC_LONG)datalen); + CC_SHA512_Final(temp, &ctx); + + memcpy(hash, temp, CC_SHA256_DIGEST_LENGTH); + + return (CC_SHA256_DIGEST_LENGTH); + } + +#elif defined(HAVE_GNUTLS) + gnutls_digest_algorithm_t alg = GNUTLS_DIG_UNKNOWN; + /* Algorithm */ + unsigned char temp[64]; /* Temporary hash buffer */ + size_t tempsize = 0; /* Truncate to this size? */ + + if (strcmp(algorithm, "sha")) + alg = GNUTLS_DIG_SHA1; + else if (strcmp(algorithm, "sha2-224")) + alg = GNUTLS_DIG_SHA224; + else if (strcmp(algorithm, "sha2-256")) + alg = GNUTLS_DIG_SHA256; + else if (strcmp(algorithm, "sha2-384")) + alg = GNUTLS_DIG_SHA384; + else if (strcmp(algorithm, "sha2-512")) + alg = GNUTLS_DIG_SHA512; + else if (strcmp(algorithm, "sha2-512_224")) + { + alg = GNUTLS_DIG_SHA512; + tempsize = 28; + } + else if (strcmp(algorithm, "sha2-512_256")) + { + alg = GNUTLS_DIG_SHA512; + tempsize = 32; + } + + if (alg != GNUTLS_DIG_UNKNOWN) + { + if (tempsize > 0) + { + /* + * Truncate result to tempsize bytes... + */ + + if (hashsize < tempsize) + goto too_small; + + gnutls_hash_fast(alg, data, datalen, temp); + memcpy(hash, temp, tempsize); + + return (tempsize); + } + + if (hashsize < gnutls_hash_get_len(alg)) + goto too_small; + + gnutls_hash_fast(alg, data, datalen, hash); + + return (gnutls_hash_get_len(alg)); + } + +#else + /* + * No hash support without CommonCrypto or GNU TLS... + */ + + if (hashsize < 64) + goto too_small; +#endif /* __APPLE__ */ + + /* + * Unknown hash algorithm... + */ + + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown hash algorithm."), 1); + + return (-1); + + /* + * We get here if the buffer is too small. + */ + + too_small: + + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1); + return (-1); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index c6fe05f5d..e02129106 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -67,7 +67,8 @@ _cupsConvertOptions(ipp_t *request, /* I - IPP request */ cups_option_t *options) /* I - Options */ { int i; /* Looping var */ - const char *keyword; /* PWG keyword */ + const char *keyword, /* PWG keyword */ + *password; /* Password string */ pwg_size_t *size; /* PWG media size */ ipp_t *media_col, /* media-col value */ *media_size; /* media-size value */ @@ -85,14 +86,36 @@ _cupsConvertOptions(ipp_t *request, /* I - IPP request */ * Send standard IPP attributes... */ - if (pc->password && (keyword = cupsGetOption("job-password", num_options, options)) != NULL && ippGetOperation(request) != IPP_OP_VALIDATE_JOB) + if (pc->password && (password = cupsGetOption("job-password", num_options, options)) != NULL && ippGetOperation(request) != IPP_OP_VALIDATE_JOB) { - ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", keyword, (int)strlen(keyword)); + ipp_attribute_t *attr = NULL; /* job-password attribute */ if ((keyword = cupsGetOption("job-password-encryption", num_options, options)) == NULL) keyword = "none"; - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "job-password-encryption", NULL, keyword); + if (!strcmp(keyword, "none")) + { + /* + * Add plain-text job-password... + */ + + attr = ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", password, (int)strlen(password)); + } + else + { + /* + * Add hashed job-password... + */ + + unsigned char hash[64]; /* Hash of password */ + ssize_t hashlen; /* Length of hash */ + + if ((hashlen = cupsHashData(keyword, password, strlen(password), hash, sizeof(hash))) > 0) + attr = ippAddOctetString(request, IPP_TAG_OPERATION, "job-password", hash, (int)hashlen); + } + + if (attr) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "job-password-encryption", NULL, keyword); } if (pc->account_id) diff --git a/cups/versioning.h b/cups/versioning.h index 26e9a0193..ff52d6088 100644 --- a/cups/versioning.h +++ b/cups/versioning.h @@ -3,7 +3,7 @@ * * API versioning definitions for CUPS. * - * Copyright 2007-2013 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -66,6 +66,7 @@ # define _CUPS_API_1_6 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER # define _CUPS_API_1_7 AVAILABLE_MAC_OS_X_VERSION_10_9_AND_LATER # define _CUPS_API_2_0 AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER +# define _CUPS_API_2_2 # else # define _CUPS_API_1_1_19 # define _CUPS_API_1_1_20 @@ -77,6 +78,7 @@ # define _CUPS_API_1_6 # define _CUPS_API_1_7 # define _CUPS_API_2_0 +# define _CUPS_API_2_2 # endif /* __APPLE__ && !_CUPS_SOURCE */ /* diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj index 6f85ea915..5575db341 100644 --- a/xcode/CUPS.xcodeproj/project.pbxproj +++ b/xcode/CUPS.xcodeproj/project.pbxproj @@ -383,6 +383,8 @@ 7271883D1374AB14001A2036 /* mime-private.h in Headers */ = {isa = PBXBuildFile; fileRef = 7271883C1374AB14001A2036 /* mime-private.h */; }; 727AD5B719100A58009F6862 /* tls.c in Sources */ = {isa = PBXBuildFile; fileRef = 727AD5B619100A58009F6862 /* tls.c */; }; 727AD5B819100A58009F6862 /* tls.c in Sources */ = {isa = PBXBuildFile; fileRef = 727AD5B619100A58009F6862 /* tls.c */; }; + 7284F9F01BFCCDB10026F886 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 7284F9EF1BFCCD940026F886 /* hash.c */; }; + 7284F9F11BFCCDB20026F886 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 7284F9EF1BFCCD940026F886 /* hash.c */; }; 728FB7E91536161C005426E1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E5136B64AF00836530 /* CoreFoundation.framework */; }; 728FB7EA1536161C005426E1 /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E6136B64B000836530 /* Kerberos.framework */; }; 728FB7EB1536161C005426E1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E7136B64B000836530 /* Security.framework */; }; @@ -1586,6 +1588,7 @@ 727EF04D192E3602001EF690 /* testlpd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testlpd.c; path = ../scheduler/testlpd.c; sourceTree = "<group>"; }; 727EF04E192E3602001EF690 /* testspeed.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testspeed.c; path = ../scheduler/testspeed.c; sourceTree = "<group>"; }; 727EF04F192E3602001EF690 /* testsub.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testsub.c; path = ../scheduler/testsub.c; sourceTree = "<group>"; }; + 7284F9EF1BFCCD940026F886 /* hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../cups/hash.c; sourceTree = "<group>"; }; 728FB7EC1536161C005426E1 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; }; 728FB7EF1536167A005426E1 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = /usr/lib/libiconv.dylib; sourceTree = "<absolute>"; }; 728FB7F01536167A005426E1 /* libresolv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libresolv.dylib; path = /usr/lib/libresolv.dylib; sourceTree = "<absolute>"; }; @@ -2220,6 +2223,7 @@ 72220EDB133305BB00FCA411 /* getifaddrs.c */, 72220EDC133305BB00FCA411 /* getputfile.c */, 72220EDD133305BB00FCA411 /* globals.c */, + 7284F9EF1BFCCD940026F886 /* hash.c */, 72220EE2133305BB00FCA411 /* http.c */, 72220EDE133305BB00FCA411 /* http-addr.c */, 72220EDF133305BB00FCA411 /* http-addrlist.c */, @@ -3343,7 +3347,7 @@ 72BF96371333042100B1EAD7 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastUpgradeCheck = 0710; ORGANIZATIONNAME = "Apple Inc."; TargetAttributes = { 27A0347A1A8BDB1200650675 = { @@ -3541,6 +3545,7 @@ 274FF6A61333B1C400317ECB /* mark.c in Sources */, 274FF6A71333B1C400317ECB /* md5.c in Sources */, 274FF6A81333B1C400317ECB /* md5passwd.c in Sources */, + 7284F9F11BFCCDB20026F886 /* hash.c in Sources */, 274FF6A91333B1C400317ECB /* notify.c in Sources */, 274FF6AA1333B1C400317ECB /* options.c in Sources */, 727AD5B819100A58009F6862 /* tls.c in Sources */, @@ -3695,6 +3700,7 @@ 72220F26133305BB00FCA411 /* localize.c in Sources */, 72220F27133305BB00FCA411 /* mark.c in Sources */, 72220F29133305BB00FCA411 /* md5.c in Sources */, + 7284F9F01BFCCDB10026F886 /* hash.c in Sources */, 72220F2A133305BB00FCA411 /* md5passwd.c in Sources */, 72220F2B133305BB00FCA411 /* notify.c in Sources */, 72220F2C133305BB00FCA411 /* options.c in Sources */, |