Index: Doxyfile ================================================================== --- Doxyfile +++ Doxyfile @@ -7,10 +7,11 @@ HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_MEMBERS = YES PREDEFINED = DOXYGEN \ OF_HAVE_BLOCKS \ OF_HAVE_FILES \ + OF_HAVE_SANDBOX \ OF_HAVE_SOCKETS \ OF_HAVE_THREADS \ OF_NO_RETURN \ OF_NO_RETURN_FUNC \ OF_NULLABLE_PROPERTY \ Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -82,10 +82,14 @@ 4B11005C14329B9A003A45D8 /* OFXMLNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B11005A14329B9A003A45D8 /* OFXMLNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B11005D14329B9A003A45D8 /* OFXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B11005B14329B9A003A45D8 /* OFXMLNode.m */; }; 4B141BA415FCDF74000C21A8 /* OFSortedList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B141BA215FCDF74000C21A8 /* OFSortedList.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B141BA515FCDF74000C21A8 /* OFSortedList.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B141BA315FCDF74000C21A8 /* OFSortedList.m */; }; 4B1473CB17E6391900B46BB8 /* OFAutoreleasePool+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */; }; + 4B14EAC71E9A8292005E8BFD /* OFSandboxActivationFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B14EAC81E9A8292005E8BFD /* OFSandboxActivationFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B14EAC91E9A8292005E8BFD /* OFSandboxActivationFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B14EAC61E9A8292005E8BFD /* OFSandboxActivationFailedException.m */; }; + 4B14EACA1E9A8292005E8BFD /* OFSandboxActivationFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B14EAC61E9A8292005E8BFD /* OFSandboxActivationFailedException.m */; }; 4B17FF73133A2A76003E6DCD /* OFException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B17FF71133A28FC003E6DCD /* OFException.m */; }; 4B17FF74133A2AAB003E6DCD /* OFException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF70133A28FC003E6DCD /* OFException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B17FF77133A2B18003E6DCD /* OFNotImplementedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF75133A2B18003E6DCD /* OFNotImplementedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B17FF78133A2B18003E6DCD /* OFNotImplementedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B17FF76133A2B18003E6DCD /* OFNotImplementedException.m */; }; 4B17FF7B133A2C15003E6DCD /* OFOutOfRangeException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B17FF79133A2C14003E6DCD /* OFOutOfRangeException.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -824,10 +828,14 @@ 4B90B7A5133AD87D00BD33CB /* OFConnectionFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90B79B133AD87D00BD33CB /* OFConnectionFailedException.m */; }; 4B90B7A6133AD87D00BD33CB /* OFListenFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90B79C133AD87D00BD33CB /* OFListenFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B90B7A7133AD87D00BD33CB /* OFListenFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90B79D133AD87D00BD33CB /* OFListenFailedException.m */; }; 4B91FD12196B4F5900C5C25E /* OFUnknownXMLEntityException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B91FD10196B4F5900C5C25E /* OFUnknownXMLEntityException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B91FD13196B4F5900C5C25E /* OFUnknownXMLEntityException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B91FD11196B4F5900C5C25E /* OFUnknownXMLEntityException.m */; }; + 4B935D121E9A7DC3001F2957 /* OFSandbox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B935D101E9A7DC3001F2957 /* OFSandbox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B935D131E9A7DC3001F2957 /* OFSandbox.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B935D101E9A7DC3001F2957 /* OFSandbox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B935D141E9A7DC3001F2957 /* OFSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B935D111E9A7DC3001F2957 /* OFSandbox.m */; }; + 4B935D151E9A7DC3001F2957 /* OFSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B935D111E9A7DC3001F2957 /* OFSandbox.m */; }; 4B9361A81511000C00DCD16B /* OFThreadPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9361A61511000C00DCD16B /* OFThreadPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9361A91511000C00DCD16B /* OFThreadPool.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9361A71511000C00DCD16B /* OFThreadPool.m */; }; 4B989C2F13771A3700109A30 /* OFSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B989C2E13771A3700109A30 /* OFSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9BB7BD141CDE2D000AD1CC /* OFArray_adjacentSubarray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9BB7B9141CDE2D000AD1CC /* OFArray_adjacentSubarray.h */; }; 4B9BB7BE141CDE2D000AD1CC /* OFArray_adjacentSubarray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9BB7BA141CDE2D000AD1CC /* OFArray_adjacentSubarray.m */; }; @@ -1145,10 +1153,12 @@ 4B11005A14329B9A003A45D8 /* OFXMLNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFXMLNode.h; path = src/OFXMLNode.h; sourceTree = ""; }; 4B11005B14329B9A003A45D8 /* OFXMLNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFXMLNode.m; path = src/OFXMLNode.m; sourceTree = ""; }; 4B141BA215FCDF74000C21A8 /* OFSortedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSortedList.h; path = src/OFSortedList.h; sourceTree = ""; }; 4B141BA315FCDF74000C21A8 /* OFSortedList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSortedList.m; path = src/OFSortedList.m; sourceTree = ""; }; 4B1473CA17E6391900B46BB8 /* OFAutoreleasePool+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFAutoreleasePool+Private.h"; path = "src/OFAutoreleasePool+Private.h"; sourceTree = ""; }; + 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSandboxActivationFailedException.h; path = src/exceptions/OFSandboxActivationFailedException.h; sourceTree = ""; }; + 4B14EAC61E9A8292005E8BFD /* OFSandboxActivationFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSandboxActivationFailedException.m; path = src/exceptions/OFSandboxActivationFailedException.m; sourceTree = ""; }; 4B175C1D116D130B003C99CB /* OFApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFApplication.h; path = src/OFApplication.h; sourceTree = ""; }; 4B175C1E116D130B003C99CB /* OFApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFApplication.m; path = src/OFApplication.m; sourceTree = ""; }; 4B17FF70133A28FC003E6DCD /* OFException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFException.h; path = src/exceptions/OFException.h; sourceTree = ""; }; 4B17FF71133A28FC003E6DCD /* OFException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFException.m; path = src/exceptions/OFException.m; sourceTree = ""; }; 4B17FF75133A2B18003E6DCD /* OFNotImplementedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFNotImplementedException.h; path = src/exceptions/OFNotImplementedException.h; sourceTree = ""; }; @@ -1479,10 +1489,12 @@ 4B90B79B133AD87D00BD33CB /* OFConnectionFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFConnectionFailedException.m; path = src/exceptions/OFConnectionFailedException.m; sourceTree = ""; }; 4B90B79C133AD87D00BD33CB /* OFListenFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFListenFailedException.h; path = src/exceptions/OFListenFailedException.h; sourceTree = ""; }; 4B90B79D133AD87D00BD33CB /* OFListenFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFListenFailedException.m; path = src/exceptions/OFListenFailedException.m; sourceTree = ""; }; 4B91FD10196B4F5900C5C25E /* OFUnknownXMLEntityException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFUnknownXMLEntityException.h; path = src/exceptions/OFUnknownXMLEntityException.h; sourceTree = ""; }; 4B91FD11196B4F5900C5C25E /* OFUnknownXMLEntityException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFUnknownXMLEntityException.m; path = src/exceptions/OFUnknownXMLEntityException.m; sourceTree = ""; }; + 4B935D101E9A7DC3001F2957 /* OFSandbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSandbox.h; path = src/OFSandbox.h; sourceTree = ""; }; + 4B935D111E9A7DC3001F2957 /* OFSandbox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSandbox.m; path = src/OFSandbox.m; sourceTree = ""; }; 4B9361A61511000C00DCD16B /* OFThreadPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFThreadPool.h; path = src/OFThreadPool.h; sourceTree = ""; }; 4B9361A71511000C00DCD16B /* OFThreadPool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFThreadPool.m; path = src/OFThreadPool.m; sourceTree = ""; }; 4B981CDE116F71DD00294DB7 /* OFSeekableStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSeekableStream.h; path = src/OFSeekableStream.h; sourceTree = ""; }; 4B981CDF116F71DD00294DB7 /* OFSeekableStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSeekableStream.m; path = src/OFSeekableStream.m; sourceTree = ""; }; 4B989C2E13771A3700109A30 /* OFSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSerialization.h; path = src/OFSerialization.h; sourceTree = ""; }; @@ -1781,10 +1793,12 @@ 4B55A10D133AC24500B58A93 /* OFReadFailedException.m */, 4B55A10E133AC24500B58A93 /* OFReadOrWriteFailedException.h */, 4B55A10F133AC24500B58A93 /* OFReadOrWriteFailedException.m */, 4BFF3710177E17C100192782 /* OFRemoveItemFailedException.h */, 4BFF3711177E17C100192782 /* OFRemoveItemFailedException.m */, + 4B14EAC51E9A8292005E8BFD /* OFSandboxActivationFailedException.h */, + 4B14EAC61E9A8292005E8BFD /* OFSandboxActivationFailedException.m */, 4B29BC39133AC4E80004B236 /* OFSeekFailedException.h */, 4B29BC3A133AC4E80004B236 /* OFSeekFailedException.m */, 4B90B78B133AD46700BD33CB /* OFSetOptionFailedException.h */, 4B90B78C133AD46700BD33CB /* OFSetOptionFailedException.m */, 4B72F7DC1AD9311B00CE253C /* OFStatItemFailedException.h */, @@ -2022,12 +2036,10 @@ 4B0EA9141898690E00F573A4 /* OFKernelEventObserver_poll.h */, 4B0EA9151898690E00F573A4 /* OFKernelEventObserver_poll.m */, 4B0EA9161898690E00F573A4 /* OFKernelEventObserver_select.h */, 4B0EA9171898690E00F573A4 /* OFKernelEventObserver_select.m */, 4BC176231D04963000C32718 /* OFKeyValueCoding.h */, - 4BC176241D04963000C32718 /* OFObject+KeyValueCoding.h */, - 4BC176251D04963000C32718 /* OFObject+KeyValueCoding.m */, 4B67996C1099E7C50041064A /* OFList.h */, 4B67996D1099E7C50041064A /* OFList.m */, 4B46E21F1E235EA700121ED6 /* OFLocalization.h */, 4B46E2201E235EA700121ED6 /* OFLocalization.m */, 4B6743F9163C395900EB1E59 /* OFLocking.h */, @@ -2061,10 +2073,12 @@ 4B511B7B139C0A34003764A5 /* OFNull.m */, 4B6799751099E7C50041064A /* OFNumber.h */, 4B6799761099E7C50041064A /* OFNumber.m */, 4B6799771099E7C50041064A /* OFObject.h */, 4B6799781099E7C50041064A /* OFObject.m */, + 4BC176241D04963000C32718 /* OFObject+KeyValueCoding.h */, + 4BC176251D04963000C32718 /* OFObject+KeyValueCoding.m */, 4BB25E82139C388A00F574EA /* OFObject+Serialization.h */, 4BB25E83139C388A00F574EA /* OFObject+Serialization.m */, 4BAFC166182EAA7800BE5E57 /* OFOptionsParser.h */, 4BAFC167182EAA7800BE5E57 /* OFOptionsParser.m */, 4B6799791099E7C50041064A /* OFPlugin.h */, @@ -2076,10 +2090,12 @@ 4BEC83B719B7CB7100E4BB08 /* OFRIPEMD160Hash.h */, 4BEC83B819B7CB7100E4BB08 /* OFRIPEMD160Hash.m */, 4B325ED91605F3A0007836CA /* OFRunLoop.h */, 4B325EDA1605F3A0007836CA /* OFRunLoop.m */, 4B6C8AD117BD5C2E00B194F2 /* OFRunLoop+Private.h */, + 4B935D101E9A7DC3001F2957 /* OFSandbox.h */, + 4B935D111E9A7DC3001F2957 /* OFSandbox.m */, 4B981CDE116F71DD00294DB7 /* OFSeekableStream.h */, 4B981CDF116F71DD00294DB7 /* OFSeekableStream.m */, 4B989C2E13771A3700109A30 /* OFSerialization.h */, 4B39844013D3A24600E6F825 /* OFSet.h */, 4B39844113D3A24600E6F825 /* OFSet.m */, @@ -2416,10 +2432,11 @@ 4B2C220A1DA292BE00735907 /* OFOptionsParser.h in Headers */, 4B5D70671DA2F7B400B3B2D7 /* OFPlugin.h in Headers */, 4B2C220D1DA292BE00735907 /* OFRecursiveMutex.h in Headers */, 4B2C220E1DA292BE00735907 /* OFRIPEMD160Hash.h in Headers */, 4B2C220F1DA292BE00735907 /* OFRunLoop.h in Headers */, + 4B935D131E9A7DC3001F2957 /* OFSandbox.h in Headers */, 4B2C22101DA292BE00735907 /* OFSeekableStream.h in Headers */, 4B2C22111DA292BE00735907 /* OFSerialization.h in Headers */, 4B2C22121DA292BE00735907 /* OFSet.h in Headers */, 4B2C22131DA292BE00735907 /* OFSettings.h in Headers */, 4B2C22141DA292BE00735907 /* OFSHA1Hash.h in Headers */, @@ -2525,10 +2542,11 @@ 4B2C22791DA292BE00735907 /* OFOutOfMemoryException.h in Headers */, 4B2C227A1DA292BE00735907 /* OFOutOfRangeException.h in Headers */, 4B2C227B1DA292BE00735907 /* OFReadFailedException.h in Headers */, 4B2C227C1DA292BE00735907 /* OFReadOrWriteFailedException.h in Headers */, 4B2C227D1DA292BE00735907 /* OFRemoveItemFailedException.h in Headers */, + 4B14EAC81E9A8292005E8BFD /* OFSandboxActivationFailedException.h in Headers */, 4B2C227E1DA292BE00735907 /* OFSeekFailedException.h in Headers */, 4B2C227F1DA292BE00735907 /* OFSetOptionFailedException.h in Headers */, 4B2C22801DA292BE00735907 /* OFStatItemFailedException.h in Headers */, 4B2C22811DA292BE00735907 /* OFStillLockedException.h in Headers */, 4B2C22821DA292BE00735907 /* OFTruncatedDataException.h in Headers */, @@ -2636,10 +2654,11 @@ 4B3D23D21337FCB000DD29B8 /* OFPlugin.h in Headers */, 4BB524C1143D1E4E0085FBCC /* OFProcess.h in Headers */, 4B674405163C395900EB1E59 /* OFRecursiveMutex.h in Headers */, 4BEC83B919B7CB7100E4BB08 /* OFRIPEMD160Hash.h in Headers */, 4B325EDD1605F3A0007836CA /* OFRunLoop.h in Headers */, + 4B935D121E9A7DC3001F2957 /* OFSandbox.h in Headers */, 4B3D23D31337FCB000DD29B8 /* OFSeekableStream.h in Headers */, 4B989C2F13771A3700109A30 /* OFSerialization.h in Headers */, 4B39844213D3A24600E6F825 /* OFSet.h in Headers */, 4B8385181951BF9500D5358A /* OFSettings.h in Headers */, 4B3D23D41337FCB000DD29B8 /* OFSHA1Hash.h in Headers */, @@ -2745,10 +2764,11 @@ 4B17FF83133A2DFB003E6DCD /* OFOutOfMemoryException.h in Headers */, 4B17FF7B133A2C15003E6DCD /* OFOutOfRangeException.h in Headers */, 4B55A112133AC24600B58A93 /* OFReadFailedException.h in Headers */, 4B55A114133AC24600B58A93 /* OFReadOrWriteFailedException.h in Headers */, 4BFF3714177E17C100192782 /* OFRemoveItemFailedException.h in Headers */, + 4B14EAC71E9A8292005E8BFD /* OFSandboxActivationFailedException.h in Headers */, 4B29BC41133AC4E80004B236 /* OFSeekFailedException.h in Headers */, 4B90B791133AD46700BD33CB /* OFSetOptionFailedException.h in Headers */, 4B72F7DE1AD9311B00CE253C /* OFStatItemFailedException.h in Headers */, 4B6743F3163C384A00EB1E59 /* OFStillLockedException.h in Headers */, 4B17FFA9133A34E7003E6DCD /* OFTruncatedDataException.h in Headers */, @@ -3175,10 +3195,11 @@ 4B2C21551DA292BE00735907 /* OFOptionsParser.m in Sources */, 4B5D70681DA2F7B400B3B2D7 /* OFPlugin.m in Sources */, 4B2C21581DA292BE00735907 /* OFRecursiveMutex.m in Sources */, 4B2C21591DA292BE00735907 /* OFRIPEMD160Hash.m in Sources */, 4B2C215A1DA292BE00735907 /* OFRunLoop.m in Sources */, + 4B935D151E9A7DC3001F2957 /* OFSandbox.m in Sources */, 4B2C215B1DA292BE00735907 /* OFSeekableStream.m in Sources */, 4B2C215C1DA292BE00735907 /* OFSet.m in Sources */, 4B2C215D1DA292BE00735907 /* OFSet_hashtable.m in Sources */, 4B2C215E1DA292BE00735907 /* OFSettings.m in Sources */, 4B2C215F1DA292BE00735907 /* OFSettings_INIFile.m in Sources */, @@ -3276,10 +3297,11 @@ 4B2C21BF1DA292BE00735907 /* OFOutOfMemoryException.m in Sources */, 4B2C21C01DA292BE00735907 /* OFOutOfRangeException.m in Sources */, 4B2C21C11DA292BE00735907 /* OFReadFailedException.m in Sources */, 4B2C21C21DA292BE00735907 /* OFReadOrWriteFailedException.m in Sources */, 4B2C21C31DA292BE00735907 /* OFRemoveItemFailedException.m in Sources */, + 4B14EACA1E9A8292005E8BFD /* OFSandboxActivationFailedException.m in Sources */, 4B2C21C41DA292BE00735907 /* OFSeekFailedException.m in Sources */, 4B2C21C51DA292BE00735907 /* OFSetOptionFailedException.m in Sources */, 4B2C21C61DA292BE00735907 /* OFStatItemFailedException.m in Sources */, 4B2C21C71DA292BE00735907 /* OFStillLockedException.m in Sources */, 4B2C21C81DA292BE00735907 /* OFThreadJoinFailedException.m in Sources */, @@ -3372,10 +3394,11 @@ 4B3D23A01337FC0D00DD29B8 /* OFPlugin.m in Sources */, 4BB524C2143D1E4E0085FBCC /* OFProcess.m in Sources */, 4B674406163C395900EB1E59 /* OFRecursiveMutex.m in Sources */, 4BEC83BA19B7CB7100E4BB08 /* OFRIPEMD160Hash.m in Sources */, 4B325EDE1605F3A0007836CA /* OFRunLoop.m in Sources */, + 4B935D141E9A7DC3001F2957 /* OFSandbox.m in Sources */, 4B3D23A11337FC0D00DD29B8 /* OFSeekableStream.m in Sources */, 4B39844313D3A24600E6F825 /* OFSet.m in Sources */, 4BA85BCF140ECCE800E91D51 /* OFSet_hashtable.m in Sources */, 4B8385191951BF9500D5358A /* OFSettings.m in Sources */, 4B8385171951BF9500D5358A /* OFSettings_INIFile.m in Sources */, @@ -3473,10 +3496,11 @@ 4B17FF84133A2DFB003E6DCD /* OFOutOfMemoryException.m in Sources */, 4B17FF7C133A2C15003E6DCD /* OFOutOfRangeException.m in Sources */, 4B55A113133AC24600B58A93 /* OFReadFailedException.m in Sources */, 4B55A115133AC24600B58A93 /* OFReadOrWriteFailedException.m in Sources */, 4BFF3715177E17C100192782 /* OFRemoveItemFailedException.m in Sources */, + 4B14EAC91E9A8292005E8BFD /* OFSandboxActivationFailedException.m in Sources */, 4B29BC42133AC4E80004B236 /* OFSeekFailedException.m in Sources */, 4B90B792133AD46700BD33CB /* OFSetOptionFailedException.m in Sources */, 4B72F7DF1AD9311B00CE253C /* OFStatItemFailedException.m in Sources */, 4B6743F4163C384A00EB1E59 /* OFStillLockedException.m in Sources */, 4B55A100133ABEA900B58A93 /* OFThreadJoinFailedException.m in Sources */, Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1202,10 +1202,14 @@ AC_SUBST(OFPROCESS_M, "OFProcess.m") AC_DEFINE(OF_HAVE_PROCESSES, 1, [Whether we have processes]) ]) AC_CHECK_HEADERS_ONCE([sys/ioctl.h sys/ttycom.h]) + +AC_CHECK_FUNC(pledge, [ + AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()]) +]) AS_IF([test x"$objc_runtime" = x"Apple runtime"], [ AC_CHECK_HEADER(Foundation/NSObject.h, [ AC_SUBST(FOUNDATION_COMPAT_M, "foundation-compat.m") AC_SUBST(BRIDGE, "bridge") Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -43,10 +43,11 @@ OFObject+Serialization.m \ OFOptionsParser.m \ ${OFPROCESS_M} \ OFRIPEMD160Hash.m \ OFRunLoop.m \ + OFSandbox.m \ OFSeekableStream.m \ OFSet.m \ OFSHA1Hash.m \ OFSHA224Hash.m \ OFSHA224Or256Hash.m \ Index: src/OFApplication.h ================================================================== --- src/OFApplication.h +++ src/OFApplication.h @@ -23,17 +23,22 @@ @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); #endif +@class OFSandbox; #define OF_APPLICATION_DELEGATE(cls) \ int \ main(int argc, char *argv[]) \ { \ return of_application_main(&argc, &argv, [cls class]); \ } + +#ifdef OF_HAVE_PLEDGE +# define OF_HAVE_SANDBOX +#endif /*! * @protocol OFApplicationDelegate OFApplication.h ObjFW/OFApplication.h * * @brief A protocol for delegates of OFApplication. @@ -182,10 +187,21 @@ * * @param status The status with which the application will terminate */ + (void)terminateWithStatus: (int)status OF_NO_RETURN; +#ifdef OF_HAVE_SANDBOX +/*! + * @brief Activates the specified sandbox for the application. + * + * This is only available if `OF_HAVE_SANDBOX` is defined. + * + * @param sandbox The sandbox to activate + */ ++ (void)activateSandbox: (OFSandbox*)sandbox; +#endif + /*! * @brief Gets argc and argv. * * @param argc A pointer where a pointer to argc should be stored * @param argv A pointer where a pointer to argv should be stored @@ -216,10 +232,21 @@ * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ - (void)terminateWithStatus: (int)status OF_NO_RETURN; + +#ifdef OF_HAVE_SANDBOX +/*! + * @brief Activates the specified sandbox for the application. + * + * This is only available if `OF_HAVE_SANDBOX` is defined. + * + * @param sandbox The sandbox to activate + */ +- (void)activateSandbox: (OFSandbox*)sandbox; +#endif @end #ifdef __cplusplus extern "C" { #endif Index: src/OFApplication.m ================================================================== --- src/OFApplication.m +++ src/OFApplication.m @@ -18,12 +18,14 @@ #include #include #include +#include #include #include +#include #import "OFApplication.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" @@ -30,13 +32,15 @@ #import "OFLocalization.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFThread.h" #import "OFThread+Private.h" +#import "OFSandbox.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" +#import "OFSandboxActivationFailedException.h" #if defined(OF_MACOS) # include #elif defined(OF_WINDOWS) # include @@ -183,10 +187,17 @@ sceKernelExitGame(); OF_UNREACHABLE #endif } + +#ifdef OF_HAVE_SANDBOX ++ (void)activateSandbox: (OFSandbox*)sandbox +{ + [app activateSandbox: sandbox]; +} +#endif - init { self = [super init]; @@ -501,6 +512,24 @@ { [[self class] terminateWithStatus: status]; OF_UNREACHABLE } + +#ifdef OF_HAVE_SANDBOX +- (void)activateSandbox: (OFSandbox*)sandbox +{ +# ifdef OF_HAVE_PLEDGE + void *pool = objc_autoreleasePoolPush(); + const char *promises = [[sandbox pledgeString] + cStringWithEncoding: [OFLocalization encoding]]; + + if (pledge(promises, NULL) != 0) + @throw [OFSandboxActivationFailedException + exceptionWithSandbox: sandbox + errNo: errno]; + + objc_autoreleasePoolPop(pool); +# endif +} +#endif @end ADDED src/OFSandbox.h Index: src/OFSandbox.h ================================================================== --- /dev/null +++ src/OFSandbox.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFObject.h" + +OF_ASSUME_NONNULL_BEGIN + +#ifndef DOXYGEN +@class OFArray OF_GENERIC(ObjectType); +#endif + +/*! + * @class OFSandbox OFSandbox.h ObjFW/OFSandbox.h + * + * @brief A class which describes a sandbox for the application. + */ +@interface OFSandbox: OFObject +{ + bool _allowsStdIO; + bool _allowsReadingFiles; + bool _allowsWritingFiles; + bool _allowsCreatingFiles; + bool _allowsCreatingSpecialFiles; + bool _allowsTemporaryFiles; + bool _allowsIPSockets; + bool _allowsMulticastSockets; + bool _allowsChangingFileAttributes; + bool _allowsFileOwnerChanges; + bool _allowsFileLocks; + bool _allowsUNIXSockets; + bool _allowsDNS; + bool _allowsUserDatabaseReading; + bool _allowsFileDescriptorSending; + bool _allowsFileDescriptorReceiving; + bool _allowsTape; + bool _allowsTTY; + bool _allowsProcessOperations; + bool _allowsExec; + bool _allowsProtExec; + bool _allowsSetTime; + bool _allowsPS; + bool _allowsVMInfo; + bool _allowsChangingProcessRights; + bool _allowsPF; + bool _allowsAudio; + bool _allowsBPF; +} + +/*! Allows IO operations on previously allocated file descriptors. */ +@property bool allowsStdIO; + +/*! Allows read access to the file system. */ +@property bool allowsReadingFiles; + +/*! Allows write access to the file system. */ +@property bool allowsWritingFiles; + +/*! Allows creating files in the file system. */ +@property bool allowsCreatingFiles; + +/*! Allows creating special files in the file system. */ +@property bool allowsCreatingSpecialFiles; + +/*! Allows creating, reading and writing temporary files in /tmp. */ +@property bool allowsTemporaryFiles; + +/*! Allows using IP sockets. */ +@property bool allowsIPSockets; + +/*! Allows multicast sockets. */ +@property bool allowsMulticastSockets; + +/*! Allows explicit changes to file attributes. */ +@property bool allowsChangingFileAttributes; + +/*! Allows changing ownership of files. */ +@property bool allowsFileOwnerChanges; + +/*! Allows file locks. */ +@property bool allowsFileLocks; + +/*! Allows UNIX sockets. */ +@property bool allowsUNIXSockets; + +/*! Allows syscalls necessary for DNS lookups. */ +@property bool allowsDNS; + +/*! Allows to look up users and groups. */ +@property bool allowsUserDatabaseReading; + +/*! Allows sending file descriptors via sendmsg(). */ +@property bool allowsFileDescriptorSending; + +/*! Allows receiving file descriptors via recvmsg(). */ +@property bool allowsFileDescriptorReceiving; + +/*! Allows MTIOCGET and MTIOCTOP operations on tape devices. */ +@property bool allowsTape; + +/*! Allows read-write operations and ioctls on the TTY. */ +@property bool allowsTTY; + +/*! Allows various process relationshop operations. */ +@property bool allowsProcessOperations; + +/*! Allows execve(). */ +@property bool allowsExec; + +/*! Allows PROT_EXEC for mmap() and mprotect(). */ +@property bool allowsProtExec; + +/*! Allows settime(). */ +@property bool allowsSetTime; + +/*! Allows introspection of processes on the system. */ +@property bool allowsPS; + +/*! Allows introspection of the system's virtual memory. */ +@property bool allowsVMInfo; + +/*! Allows changing the rights of process, for example the UID. */ +@property bool allowsChangingProcessRights; + +/*! Allows certain ioctls on the PF device. */ +@property bool allowsPF; + +/*! Allows certain ioctls on audio devices. */ +@property bool allowsAudio; + +/*! Allows BIOCGSTATS to collect statistics from a BPF device. */ +@property bool allowsBPF; + +/*! + * @brief Create a new, autorelease OFSandbox. + */ ++ (instancetype)sandbox; + +#ifdef OF_HAVE_PLEDGE +/*! + * @brief Returns the string for OpenBSD's pledge() call. + * + * @warning Only available on systems with the pledge() call! + */ +- (OFString*)pledgeString; +#endif +@end + +OF_ASSUME_NONNULL_END ADDED src/OFSandbox.m Index: src/OFSandbox.m ================================================================== --- /dev/null +++ src/OFSandbox.m @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFSandbox.h" +#import "OFString.h" +#import "OFArray.h" + +@implementation OFSandbox +@synthesize allowsStdIO = _allowsStdIO; +@synthesize allowsReadingFiles = _allowsReadingFiles; +@synthesize allowsWritingFiles = _allowsWritingFiles; +@synthesize allowsCreatingFiles = _allowsCreatingFiles; +@synthesize allowsCreatingSpecialFiles = _allowsCreatingSpecialFiles; +@synthesize allowsTemporaryFiles = _allowsTemporaryFiles; +@synthesize allowsIPSockets = _allowsIPSockets; +@synthesize allowsMulticastSockets = _allowsMulticastSockets; +@synthesize allowsChangingFileAttributes = _allowsChangingFileAttributes; +@synthesize allowsFileOwnerChanges = _allowsFileOwnerChanges; +@synthesize allowsFileLocks = _allowsFileLocks; +@synthesize allowsUNIXSockets = _allowsUNIXSockets; +@synthesize allowsDNS = _allowsDNS; +@synthesize allowsUserDatabaseReading = _allowsUserDatabaseReading; +@synthesize allowsFileDescriptorSending = _allowsFileDescriptorSending; +@synthesize allowsFileDescriptorReceiving = _allowsFileDescriptorReceiving; +@synthesize allowsTape = _allowsTape; +@synthesize allowsTTY = _allowsTTY; +@synthesize allowsProcessOperations = _allowsProcessOperations; +@synthesize allowsExec = _allowsExec; +@synthesize allowsProtExec = _allowsProtExec; +@synthesize allowsSetTime = _allowsSetTime; +@synthesize allowsPS = _allowsPS; +@synthesize allowsVMInfo = _allowsVMInfo; +@synthesize allowsChangingProcessRights = _allowsChangingProcessRights; +@synthesize allowsPF = _allowsPF; +@synthesize allowsAudio = _allowsAudio; +@synthesize allowsBPF = _allowsBPF; + ++ (instancetype)sandbox +{ + return [[[self alloc] init] autorelease]; +} + +- copy +{ + OFSandbox *copy = [[OFSandbox alloc] init]; + + copy->_allowsStdIO = _allowsStdIO; + copy->_allowsReadingFiles = _allowsReadingFiles; + copy->_allowsWritingFiles = _allowsWritingFiles; + copy->_allowsCreatingFiles = _allowsCreatingFiles; + copy->_allowsCreatingSpecialFiles = _allowsCreatingSpecialFiles; + copy->_allowsTemporaryFiles = _allowsTemporaryFiles; + copy->_allowsIPSockets = _allowsIPSockets; + copy->_allowsMulticastSockets = _allowsMulticastSockets; + copy->_allowsChangingFileAttributes = _allowsChangingFileAttributes; + copy->_allowsFileOwnerChanges = _allowsFileOwnerChanges; + copy->_allowsFileLocks = _allowsFileLocks; + copy->_allowsUNIXSockets = _allowsUNIXSockets; + copy->_allowsDNS = _allowsDNS; + copy->_allowsUserDatabaseReading = _allowsUserDatabaseReading; + copy->_allowsFileDescriptorSending = _allowsFileDescriptorSending; + copy->_allowsFileDescriptorReceiving = _allowsFileDescriptorReceiving; + copy->_allowsTape = _allowsTape; + copy->_allowsTTY = _allowsTTY; + copy->_allowsProcessOperations = _allowsProcessOperations; + copy->_allowsExec = _allowsExec; + copy->_allowsProtExec = _allowsProtExec; + copy->_allowsSetTime = _allowsSetTime; + copy->_allowsPS = _allowsPS; + copy->_allowsVMInfo = _allowsVMInfo; + copy->_allowsChangingProcessRights = _allowsChangingProcessRights; + copy->_allowsPF = _allowsPF; + copy->_allowsAudio = _allowsAudio; + copy->_allowsBPF = _allowsBPF; + + return copy; +} + +- (bool)isEqual: (id)otherObject +{ + OFSandbox *otherSandbox; + + if (![otherObject isKindOfClass: [OFSandbox class]]) + return false; + + otherSandbox = otherObject; + + if (otherSandbox->_allowsStdIO != _allowsStdIO) + return false; + if (otherSandbox->_allowsReadingFiles != _allowsReadingFiles) + return false; + if (otherSandbox->_allowsWritingFiles != _allowsWritingFiles) + return false; + if (otherSandbox->_allowsCreatingFiles != _allowsCreatingFiles) + return false; + if (otherSandbox->_allowsCreatingSpecialFiles != + _allowsCreatingSpecialFiles) + return false; + if (otherSandbox->_allowsTemporaryFiles != _allowsTemporaryFiles) + return false; + if (otherSandbox->_allowsIPSockets != _allowsIPSockets) + return false; + if (otherSandbox->_allowsMulticastSockets != _allowsMulticastSockets) + return false; + if (otherSandbox->_allowsChangingFileAttributes != + _allowsChangingFileAttributes) + return false; + if (otherSandbox->_allowsFileOwnerChanges != _allowsFileOwnerChanges) + return false; + if (otherSandbox->_allowsFileLocks != _allowsFileLocks) + return false; + if (otherSandbox->_allowsUNIXSockets != _allowsUNIXSockets) + return false; + if (otherSandbox->_allowsDNS != _allowsDNS) + return false; + if (otherSandbox->_allowsUserDatabaseReading != + _allowsUserDatabaseReading) + return false; + if (otherSandbox->_allowsFileDescriptorSending != + _allowsFileDescriptorSending) + return false; + if (otherSandbox->_allowsFileDescriptorReceiving != + _allowsFileDescriptorReceiving) + return false; + if (otherSandbox->_allowsTape != _allowsTape) + return false; + if (otherSandbox->_allowsTTY != _allowsTTY) + return false; + if (otherSandbox->_allowsProcessOperations != _allowsProcessOperations) + return false; + if (otherSandbox->_allowsExec != _allowsExec) + return false; + if (otherSandbox->_allowsProtExec != _allowsProtExec) + return false; + if (otherSandbox->_allowsSetTime != _allowsSetTime) + return false; + if (otherSandbox->_allowsPS != _allowsPS) + return false; + if (otherSandbox->_allowsVMInfo != _allowsVMInfo) + return false; + if (otherSandbox->_allowsChangingProcessRights != + _allowsChangingProcessRights) + return false; + if (otherSandbox->_allowsPF != _allowsPF) + return false; + if (otherSandbox->_allowsAudio != _allowsAudio) + return false; + if (otherSandbox->_allowsBPF != _allowsBPF) + return false; + + return true; +} + +- (uint32_t)hash +{ + uint32_t hash; + + OF_HASH_INIT(hash); + + OF_HASH_ADD(hash, _allowsStdIO); + OF_HASH_ADD(hash, _allowsReadingFiles); + OF_HASH_ADD(hash, _allowsWritingFiles); + OF_HASH_ADD(hash, _allowsCreatingFiles); + OF_HASH_ADD(hash, _allowsCreatingSpecialFiles); + OF_HASH_ADD(hash, _allowsTemporaryFiles); + OF_HASH_ADD(hash, _allowsIPSockets); + OF_HASH_ADD(hash, _allowsMulticastSockets); + OF_HASH_ADD(hash, _allowsChangingFileAttributes); + OF_HASH_ADD(hash, _allowsFileOwnerChanges); + OF_HASH_ADD(hash, _allowsFileLocks); + OF_HASH_ADD(hash, _allowsUNIXSockets); + OF_HASH_ADD(hash, _allowsDNS); + OF_HASH_ADD(hash, _allowsUserDatabaseReading); + OF_HASH_ADD(hash, _allowsFileDescriptorSending); + OF_HASH_ADD(hash, _allowsFileDescriptorReceiving); + OF_HASH_ADD(hash, _allowsTape); + OF_HASH_ADD(hash, _allowsTTY); + OF_HASH_ADD(hash, _allowsProcessOperations); + OF_HASH_ADD(hash, _allowsExec); + OF_HASH_ADD(hash, _allowsProtExec); + OF_HASH_ADD(hash, _allowsSetTime); + OF_HASH_ADD(hash, _allowsPS); + OF_HASH_ADD(hash, _allowsVMInfo); + OF_HASH_ADD(hash, _allowsChangingProcessRights); + OF_HASH_ADD(hash, _allowsPF); + OF_HASH_ADD(hash, _allowsAudio); + OF_HASH_ADD(hash, _allowsBPF); + + OF_HASH_FINALIZE(hash); + + return hash; +} + +#ifdef OF_HAVE_PLEDGE +- (OFString*)pledgeString +{ + void *pool = objc_autoreleasePoolPush(); + OFMutableArray *pledges = [OFMutableArray array]; + OFString *ret; + + if (_allowsStdIO) + [pledges addObject: @"stdio"]; + if (_allowsReadingFiles) + [pledges addObject: @"rpath"]; + if (_allowsWritingFiles) + [pledges addObject: @"wpath"]; + if (_allowsCreatingFiles) + [pledges addObject: @"cpath"]; + if (_allowsCreatingSpecialFiles) + [pledges addObject: @"dpath"]; + if (_allowsTemporaryFiles) + [pledges addObject: @"tmppath"]; + if (_allowsIPSockets) + [pledges addObject: @"inet"]; + if (_allowsMulticastSockets) + [pledges addObject: @"mcast"]; + if (_allowsChangingFileAttributes) + [pledges addObject: @"fattr"]; + if (_allowsFileOwnerChanges) + [pledges addObject: @"chown"]; + if (_allowsFileLocks) + [pledges addObject: @"flock"]; + if (_allowsUNIXSockets) + [pledges addObject: @"unix"]; + if (_allowsDNS) + [pledges addObject: @"dns"]; + if (_allowsUserDatabaseReading) + [pledges addObject: @"getpw"]; + if (_allowsFileDescriptorSending) + [pledges addObject: @"sendfd"]; + if (_allowsFileDescriptorReceiving) + [pledges addObject: @"recvfd"]; + if (_allowsTape) + [pledges addObject: @"tape"]; + if (_allowsTTY) + [pledges addObject: @"tty"]; + if (_allowsProcessOperations) + [pledges addObject: @"proc"]; + if (_allowsExec) + [pledges addObject: @"exec"]; + if (_allowsProtExec) + [pledges addObject: @"prot_exec"]; + if (_allowsSetTime) + [pledges addObject: @"settime"]; + if (_allowsPS) + [pledges addObject: @"ps"]; + if (_allowsVMInfo) + [pledges addObject: @"vminfo"]; + if (_allowsChangingProcessRights) + [pledges addObject: @"id"]; + if (_allowsPF) + [pledges addObject: @"pf"]; + if (_allowsAudio) + [pledges addObject: @"audio"]; + if (_allowsBPF) + [pledges addObject: @"bpf"]; + + ret = [pledges componentsJoinedByString: @" "]; + + [ret retain]; + + objc_autoreleasePoolPop(pool); + + return [ret autorelease]; +} +#endif +@end Index: src/exceptions/Makefile ================================================================== --- src/exceptions/Makefile +++ src/exceptions/Makefile @@ -32,10 +32,11 @@ OFOutOfMemoryException.m \ OFOutOfRangeException.m \ OFReadFailedException.m \ OFReadOrWriteFailedException.m \ OFRemoveItemFailedException.m \ + OFSandboxActivationFailedException.m \ OFSeekFailedException.m \ OFSetOptionFailedException.m \ OFStatItemFailedException.m \ OFStillLockedException.m \ OFTruncatedDataException.m \ ADDED src/exceptions/OFSandboxActivationFailedException.h Index: src/exceptions/OFSandboxActivationFailedException.h ================================================================== --- /dev/null +++ src/exceptions/OFSandboxActivationFailedException.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFException.h" + +@class OFSandbox; + +/*! + * @class OFSandboxActivationFailedException \ + * OFSandboxActivationFailedException.h \ + * ObjFW/OFSandboxActivationFailedException.h + * + * @brief An exception indicating that sandboxing the process failed. + */ +@interface OFSandboxActivationFailedException: OFException +{ + OFSandbox *_sandbox; + int _errNo; +} + +/*! + * The sandbox which could not be activated. + */ +@property (readonly, retain) OFSandbox *sandbox; + +/*! + * The errno of the error that occurred. + */ +@property (readonly) int errNo; + +/*! + * @brief Creates a new, autoreleased sandboxing failed exception. + * + * @param sandbox The sandbox which could not be activated + * @param errNo The errno of the error that occurred + * @return A new, autoreleased sandboxing failed exception + */ ++ (instancetype)exceptionWithSandbox: (OFSandbox*)sandbox + errNo: (int)errNo; + +/*! + * @brief Initializes an already allocated sandboxing failed exception. + * + * @param sandbox The sandbox which could not be activated + * @param errNo The errno of the error that occurred + * @return An initialized sandboxing failed exception + */ +- initWithSandbox: (OFSandbox*)sandbox + errNo: (int)errNo; +@end ADDED src/exceptions/OFSandboxActivationFailedException.m Index: src/exceptions/OFSandboxActivationFailedException.m ================================================================== --- /dev/null +++ src/exceptions/OFSandboxActivationFailedException.m @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFSandboxActivationFailedException.h" +#import "OFString.h" +#import "OFSandbox.h" + +@implementation OFSandboxActivationFailedException +@synthesize sandbox = _sandbox, errNo = _errNo; + ++ (instancetype)exceptionWithSandbox: (OFSandbox*)sandbox + errNo: (int)errNo +{ + return [[[self alloc] initWithSandbox: sandbox + errNo: errNo] autorelease]; +} + +- init +{ + OF_INVALID_INIT_METHOD +} + +- initWithSandbox: (OFSandbox*)sandbox + errNo: (int)errNo +{ + self = [super init]; + + _sandbox = [sandbox retain]; + _errNo = errNo; + + return self; +} + +- (void)dealloc +{ + [_sandbox release]; + + [super dealloc]; +} + +- (OFString*)description +{ + return [OFString stringWithFormat: + @"The sandbox could not be applied: %@", of_strerror(_errNo)]; +} +@end Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -15,10 +15,11 @@ #undef OF_HAVE_MAX_ALIGN_T #undef OF_HAVE_NETINET_IN_H #undef OF_HAVE_OSATOMIC #undef OF_HAVE_OSATOMIC_64 #undef OF_HAVE_PIPE +#undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_PROCESSES #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS #undef OF_HAVE_READLINK Index: utils/ofhash/OFHash.m ================================================================== --- utils/ofhash/OFHash.m +++ utils/ofhash/OFHash.m @@ -26,10 +26,11 @@ #import "OFSHA256Hash.h" #import "OFSHA384Hash.h" #import "OFSHA512Hash.h" #import "OFStdIOStream.h" #import "OFLocalization.h" +#import "OFSandbox.h" #import "OFOpenItemFailedException.h" #import "OFReadFailedException.h" @interface OFHash: OFObject @@ -74,10 +75,22 @@ { OFArray OF_GENERIC(OFString*) *arguments = [OFApplication arguments]; id hash; bool first = true; int exitStatus = 0; + +#ifdef OF_HAVE_SANDBOX + OFSandbox *sandbox = [[OFSandbox alloc] init]; + @try { + [sandbox setAllowsStdIO: true]; + [sandbox setAllowsReadingFiles: true]; + + [OFApplication activateSandbox: sandbox]; + } @finally { + [sandbox release]; + } +#endif [OFLocalization addLanguageDirectory: @LANGUAGE_DIR]; if ([arguments count] < 2) help(); Index: utils/ofhttp/OFHTTP.m ================================================================== --- utils/ofhttp/OFHTTP.m +++ utils/ofhttp/OFHTTP.m @@ -30,10 +30,11 @@ #import "OFSystemInfo.h" #import "OFTCPSocket.h" #import "OFTLSSocket.h" #import "OFURL.h" #import "OFLocalization.h" +#import "OFSandbox.h" #import "OFAddressTranslationFailedException.h" #import "OFConnectionFailedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidFormatException.h" @@ -247,16 +248,33 @@ { 'q', @"quiet", 0, &_quiet, NULL }, { 'v', @"verbose", 0, &_verbose, NULL }, { '\0', @"insecure", 0, &_insecure, NULL }, { '\0', nil, 0, NULL, NULL } }; - OFOptionsParser *optionsParser = [OFOptionsParser - parserWithOptions: options]; + OFOptionsParser *optionsParser; of_unichar_t option; + +#ifdef OF_HAVE_SANDBOX + OFSandbox *sandbox = [[OFSandbox alloc] init]; + @try { + [sandbox setAllowsStdIO: true]; + [sandbox setAllowsReadingFiles: true]; + [sandbox setAllowsWritingFiles: true]; + [sandbox setAllowsCreatingFiles: true]; + [sandbox setAllowsIPSockets: true]; + [sandbox setAllowsDNS: true]; + [sandbox setAllowsTTY: true]; + + [OFApplication activateSandbox: sandbox]; + } @finally { + [sandbox release]; + } +#endif [OFLocalization addLanguageDirectory: @LANGUAGE_DIR]; + optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 'b': [self setBody: [optionsParser argument]]; break; Index: utils/ofzip/OFZIP.m ================================================================== --- utils/ofzip/OFZIP.m +++ utils/ofzip/OFZIP.m @@ -23,10 +23,11 @@ #import "OFFile.h" #import "OFFileManager.h" #import "OFOptionsParser.h" #import "OFStdIOStream.h" #import "OFLocalization.h" +#import "OFSandbox.h" #import "OFZIP.h" #import "GZIPArchive.h" #import "TarArchive.h" #import "ZIPArchive.h" @@ -131,18 +132,33 @@ { 't', @"type", 1, NULL, &type }, { 'v', @"verbose", 0, NULL, NULL }, { 'x', @"extract", 0, NULL, NULL }, { '\0', nil, 0, NULL, NULL } }; - OFOptionsParser *optionsParser = - [OFOptionsParser parserWithOptions: options]; + OFOptionsParser *optionsParser; of_unichar_t option, mode = '\0'; OFArray OF_GENERIC(OFString*) *remainingArguments, *files; id archive; + +#ifdef OF_HAVE_SANDBOX + OFSandbox *sandbox = [[OFSandbox alloc] init]; + @try { + [sandbox setAllowsStdIO: true]; + [sandbox setAllowsReadingFiles: true]; + [sandbox setAllowsWritingFiles: true]; + [sandbox setAllowsCreatingFiles: true]; + [sandbox setAllowsChangingFileAttributes: true]; + + [OFApplication activateSandbox: sandbox]; + } @finally { + [sandbox release]; + } +#endif [OFLocalization addLanguageDirectory: @LANGUAGE_DIR]; + optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 'f': if (_overwrite < 0) mutuallyExclusiveError(