diff --git a/.gitignore b/.gitignore index 86d52cc5d7..313d6d34bc 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ cups/testadmin cups/testarray cups/testcache cups/testconflicts +cups/testcreds cups/testcups cups/testdest cups/testfile diff --git a/cups/Makefile b/cups/Makefile index f41269c24a..ba9bbed4bb 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -85,6 +85,7 @@ TESTOBJS = \ testarray.o \ testcache.o \ testconflicts.o \ + testcreds.o \ testcups.o \ testdest.o \ testfile.o \ @@ -153,6 +154,7 @@ UNITTARGETS = \ testarray \ testcache \ testconflicts \ + testcreds \ testcups \ testdest \ testfile \ @@ -417,6 +419,16 @@ testconflicts: testconflicts.o $(LIBCUPSSTATIC) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) +# +# testcreds (dependency on static CUPS library is intentional) +# + +testcreds: testcreds.o $(LIBCUPSSTATIC) + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcreds.o $(LIBCUPSSTATIC) \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + # # testcups (dependency on static CUPS library is intentional) # diff --git a/cups/testcreds.c b/cups/testcreds.c new file mode 100644 index 0000000000..8e3c878a15 --- /dev/null +++ b/cups/testcreds.c @@ -0,0 +1,124 @@ +/* + * HTTP credentials test program for CUPS. + * + * Copyright 2007-2016 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * 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" + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + http_t *http; /* HTTP connection */ + char scheme[HTTP_MAX_URI], /* Scheme from URI */ + hostname[HTTP_MAX_URI], /* Hostname from URI */ + username[HTTP_MAX_URI], /* Username:password from URI */ + resource[HTTP_MAX_URI]; /* Resource from URI */ + int port; /* Port number from URI */ + http_trust_t trust; /* Trust evaluation for connection */ + cups_array_t *hcreds, /* Credentials from connection */ + *tcreds; /* Credentials from trust store */ + char hinfo[1024], /* String for connection credentials */ + tinfo[1024]; /* String for trust store credentials */ + static const char *trusts[] = /* Trust strings */ + { "OK", "Invalid", "Changed", "Expired", "Renewed", "Unknown" }; + + + /* + * Check command-line... + */ + + if (argc != 2) + { + puts("Usage: ./testcreds hostname"); + puts(" ./testcreds https://hostname[:port]"); + return (1); + } + + if (!strncmp(argv[1], "https://", 8)) + { + /* + * Connect to the host and validate credentials... + */ + + if (httpSeparateURI(HTTP_URI_CODING_MOST, argv[1], scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK) + { + printf("ERROR: Bad URI \"%s\".\n", argv[1]); + return (1); + } + + if ((http = httpConnect2(hostname, port, NULL, AF_UNSPEC, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL)) == NULL) + { + printf("ERROR: Unable to connect to \"%s\" on port %d: %s\n", hostname, port, cupsLastErrorString()); + return (1); + } + + puts("HTTP Credentials:"); + if (!httpCopyCredentials(http, &hcreds)) + { + trust = httpCredentialsGetTrust(hcreds, hostname); + + httpCredentialsString(hcreds, hinfo, sizeof(hinfo)); + + printf(" Certificate Count: %d\n", cupsArrayCount(hcreds)); + if (trust == HTTP_TRUST_OK) + puts(" Trust: OK"); + else + printf(" Trust: %s (%s)\n", trusts[trust], cupsLastErrorString()); + printf(" Expiration: %s\n", httpGetDateString(httpCredentialsGetExpiration(hcreds))); + printf(" IsValidName: %d\n", httpCredentialsAreValidForName(hcreds, hostname)); + printf(" String: \"%s\"\n", hinfo); + + httpFreeCredentials(hcreds); + } + else + puts(" Not present (error)."); + + puts(""); + } + else + { + /* + * Load stored credentials... + */ + + strlcpy(hostname, argv[1], sizeof(hostname)); + } + + printf("Trust Store for \"%s\":\n", hostname); + + if (!httpLoadCredentials(NULL, &tcreds, hostname)) + { + httpCredentialsString(tcreds, tinfo, sizeof(tinfo)); + + printf(" Certificate Count: %d\n", cupsArrayCount(tcreds)); + printf(" Expiration: %s\n", httpGetDateString(httpCredentialsGetExpiration(tcreds))); + printf(" IsValidName: %d\n", httpCredentialsAreValidForName(tcreds, hostname)); + printf(" String: \"%s\"\n", tinfo); + + httpFreeCredentials(tcreds); + } + else + puts(" Not present."); + + return (0); +} diff --git a/xcode/CUPS.xcodeproj/project.pbxproj b/xcode/CUPS.xcodeproj/project.pbxproj index 1d8af90120..28a97bf52f 100644 --- a/xcode/CUPS.xcodeproj/project.pbxproj +++ b/xcode/CUPS.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ buildPhases = ( ); dependencies = ( + 270D02281D707E5100EA9403 /* PBXTargetDependency */, 271287361CC1411000E517C7 /* PBXTargetDependency */, 2712871C1CC13FFA00E517C7 /* PBXTargetDependency */, 271286DC1CC13EF400E517C7 /* PBXTargetDependency */, @@ -194,6 +195,14 @@ 270696561CADF3E200FFE5FB /* versioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 72220F0A133305BB00FCA411 /* versioning.h */; settings = {ATTRIBUTES = (); }; }; 2706965B1CAE1A9A00FFE5FB /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 72220F09133305BB00FCA411 /* util.c */; }; 270CCDBC135E3D3E00007BE2 /* testmime.c in Sources */ = {isa = PBXBuildFile; fileRef = 270CCDBB135E3D3E00007BE2 /* testmime.c */; }; + 270D02191D707E0200EA9403 /* libcups_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72A4332F155844CF002E172D /* libcups_static.a */; }; + 270D021A1D707E0200EA9403 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E5136B64AF00836530 /* CoreFoundation.framework */; }; + 270D021B1D707E0200EA9403 /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E6136B64B000836530 /* Kerberos.framework */; }; + 270D021C1D707E0200EA9403 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 728FB7EF1536167A005426E1 /* libiconv.dylib */; }; + 270D021D1D707E0200EA9403 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 728FB7F01536167A005426E1 /* libresolv.dylib */; }; + 270D021E1D707E0200EA9403 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 728FB7EC1536161C005426E1 /* libz.dylib */; }; + 270D021F1D707E0200EA9403 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E7136B64B000836530 /* Security.framework */; }; + 270D02261D707E3700EA9403 /* testcreds.c in Sources */ = {isa = PBXBuildFile; fileRef = 270D02251D707E3700EA9403 /* testcreds.c */; }; 271284D21CC1231300E517C7 /* snmp-supplies.c in Sources */ = {isa = PBXBuildFile; fileRef = 7243790C1333E4E3009631B9 /* snmp-supplies.c */; }; 271284D71CC124D700E517C7 /* libcupscgi_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 724FA76B1CC03AF60092477B /* libcupscgi_static.a */; }; 271284D81CC124E300E517C7 /* libcupscgi_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 724FA76B1CC03AF60092477B /* libcupscgi_static.a */; }; @@ -901,6 +910,20 @@ remoteGlobalIDString = 274FF6891333B1C400317ECB; remoteInfo = libcups_static; }; + 270D02151D707E0200EA9403 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 72BF96371333042100B1EAD7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 274FF6891333B1C400317ECB; + remoteInfo = libcups_static; + }; + 270D02271D707E5100EA9403 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 72BF96371333042100B1EAD7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 270D02131D707E0200EA9403; + remoteInfo = testcreds; + }; 271284901CC11FA500E517C7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 72BF96371333042100B1EAD7 /* Project object */; @@ -2341,6 +2364,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 270D02201D707E0200EA9403 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; 271284E81CC1261900E517C7 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -3115,6 +3147,8 @@ 270B268117F5C5D600C8A3A9 /* tls-sspi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-sspi.c"; path = "../cups/tls-sspi.c"; sourceTree = ""; }; 270CCDA7135E3C9E00007BE2 /* testmime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testmime; sourceTree = BUILT_PRODUCTS_DIR; }; 270CCDBB135E3D3E00007BE2 /* testmime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testmime.c; path = ../scheduler/testmime.c; sourceTree = ""; }; + 270D02241D707E0200EA9403 /* testcreds */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testcreds; sourceTree = BUILT_PRODUCTS_DIR; }; + 270D02251D707E3700EA9403 /* testcreds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testcreds.c; path = ../cups/testcreds.c; sourceTree = ""; }; 271284DD1CC125FC00E517C7 /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpc.c; path = ../berkeley/lpc.c; sourceTree = ""; }; 271284DE1CC125FC00E517C7 /* lpq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpq.c; path = ../berkeley/lpq.c; sourceTree = ""; }; 271284DF1CC125FC00E517C7 /* lpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lpr.c; path = ../berkeley/lpr.c; sourceTree = ""; }; @@ -3585,6 +3619,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 270D02181D707E0200EA9403 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 270D02191D707E0200EA9403 /* libcups_static.a in Frameworks */, + 270D021A1D707E0200EA9403 /* CoreFoundation.framework in Frameworks */, + 270D021B1D707E0200EA9403 /* Kerberos.framework in Frameworks */, + 270D021C1D707E0200EA9403 /* libiconv.dylib in Frameworks */, + 270D021D1D707E0200EA9403 /* libresolv.dylib in Frameworks */, + 270D021E1D707E0200EA9403 /* libz.dylib in Frameworks */, + 270D021F1D707E0200EA9403 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 271284E61CC1261900E517C7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -4601,6 +4649,7 @@ 273BF6B81333B4A90022CAAB /* tests */ = { isa = PBXGroup; children = ( + 270D02251D707E3700EA9403 /* testcreds.c */, 2712866A1CC130FF00E517C7 /* rasterbench.c */, 724FA65B1CC0389F0092477B /* test1284.c */, 727EF041192E3544001EF690 /* testadmin.c */, @@ -4815,6 +4864,7 @@ 271287031CC13F3F00E517C7 /* rss */, 271287181CC13FAB00E517C7 /* mantohtml */, 2712872C1CC140BE00E517C7 /* genstrings */, + 270D02241D707E0200EA9403 /* testcreds */, ); name = Products; sourceTree = ""; @@ -5428,6 +5478,24 @@ productReference = 270CCDA7135E3C9E00007BE2 /* testmime */; productType = "com.apple.product-type.tool"; }; + 270D02131D707E0200EA9403 /* testcreds */ = { + isa = PBXNativeTarget; + buildConfigurationList = 270D02211D707E0200EA9403 /* Build configuration list for PBXNativeTarget "testcreds" */; + buildPhases = ( + 270D02161D707E0200EA9403 /* Sources */, + 270D02181D707E0200EA9403 /* Frameworks */, + 270D02201D707E0200EA9403 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 270D02141D707E0200EA9403 /* PBXTargetDependency */, + ); + name = testcreds; + productName = testhttp; + productReference = 270D02241D707E0200EA9403 /* testcreds */; + productType = "com.apple.product-type.tool"; + }; 271284E11CC1261900E517C7 /* cancel */ = { isa = PBXNativeTarget; buildConfigurationList = 271284E91CC1261900E517C7 /* Build configuration list for PBXNativeTarget "cancel" */; @@ -7257,6 +7325,7 @@ 724FA6ED1CC03A210092477B /* testcatalog */, 724FA6991CC039200092477B /* testcgi */, 724FA55D1CC037670092477B /* testconflicts */, + 270D02131D707E0200EA9403 /* testcreds */, 273BF6BC1333B5000022CAAB /* testcups */, 2767FC4619266A0D000F61D3 /* testdest */, 724FA5701CC037810092477B /* testfile */, @@ -7334,6 +7403,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 270D02161D707E0200EA9403 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 270D02261D707E3700EA9403 /* testcreds.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 271284E41CC1261900E517C7 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -8304,6 +8381,16 @@ target = 274FF6891333B1C400317ECB /* libcups_static */; targetProxy = 270CCDB7135E3CFD00007BE2 /* PBXContainerItemProxy */; }; + 270D02141D707E0200EA9403 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 274FF6891333B1C400317ECB /* libcups_static */; + targetProxy = 270D02151D707E0200EA9403 /* PBXContainerItemProxy */; + }; + 270D02281D707E5100EA9403 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 270D02131D707E0200EA9403 /* testcreds */; + targetProxy = 270D02271D707E5100EA9403 /* PBXContainerItemProxy */; + }; 271284911CC11FA500E517C7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 274FF6891333B1C400317ECB /* libcups_static */; @@ -9379,6 +9466,20 @@ }; name = Release; }; + 270D02221D707E0200EA9403 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 270D02231D707E0200EA9403 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 271284EA1CC1261900E517C7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -11079,6 +11180,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 270D02211D707E0200EA9403 /* Build configuration list for PBXNativeTarget "testcreds" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 270D02221D707E0200EA9403 /* Debug */, + 270D02231D707E0200EA9403 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 271284E91CC1261900E517C7 /* Build configuration list for PBXNativeTarget "cancel" */ = { isa = XCConfigurationList; buildConfigurations = (