diff --git a/Distribution/Scripts/Installer/postinstall b/Distribution/Scripts/Installer/postinstall index d31dab61..76ac4843 100755 --- a/Distribution/Scripts/Installer/postinstall +++ b/Distribution/Scripts/Installer/postinstall @@ -1,35 +1,65 @@ #! /bin/bash -TMP=/tmp +# Define targets DAEMON=iscsid TOOL=iscsictl KEXT=iSCSIInitiator.kext -MAN1=iscsictl.8 -MAN2=iscsid.8 +FRAMEWORK=iSCSI.framework +DAEMON_PLIST=com.github.iscsi-osx.iscsid.plist +DAEMON_PLIST_NOEXT=com.github.iscsi-osx.iscsid +MAN_TOOL=iscsictl.8 +MAN_DAEMON=iscsid.8 + +# Define install path +DAEMON_DST=/usr/local/libexec +DAEMON_PLIST_DST=/Library/LaunchDaemons +FRAMEWORK_DST=/Library/Frameworks +TOOL_DST=/usr/local/bin +MAN_DST=/usr/share/man/man8 + +TMP=/tmp + +# Get minor version of the OS +OSX_MINOR_VER=$(sw_vers -productVersion | awk -F '.' '{print $2}') + +# Minor version of OS X Mavericks +OSX_MAVERICKS_MINOR_VER="9" + +if [ "$OSX_MINOR_VER" -ge "$OSX_MAVERICKS_MINOR_VER" ]; then + KEXT_DST=/Library/Extensions +else + KEXT_DST=/System/Library/Extensions +fi # Copy kernel extensions & load it -sudo cp -R $TMP/$KEXT /Library/Extensions/$KEXT -sudo chmod -R 755 /Library/Extensions/$KEXT -sudo chown -R root:wheel /Library/Extensions/$KEXT +sudo cp -R $TMP/$KEXT $KEXT_DST/$KEXT +sudo chmod -R 755 $KEXT_DST/$KEXT +sudo chown -R root:wheel $KEXT_DST/$KEXT + +# Copy framework +sudo cp -R $TMP/$FRAMEWORK $FRAMEWORK_DST/$FRAMEWORK +sudo chown -R root:wheel $FRAMEWORK_DST/$FRAMEWORK +sudo chmod -R 755 $FRAMEWORK_DST/$FRAMEWORK # Copy daemon & set permissions -sudo cp $TMP/$DAEMON /Library/PrivilegedHelperTools/$DAEMON -sudo cp $TMP/com.github.iscsi-osx.iscsid.plist /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo chmod -R 744 /usr/local/$DAEMON -sudo chmod 644 /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo chown root:wheel /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist +sudo mkdir -p $DAEMON_DST +sudo cp $TMP/$DAEMON $DAEMON_DST/$DAEMON +sudo cp $TMP/$DAEMON_PLIST $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo chmod -R 744 $DAEMON_DST/$DAEMON +sudo chmod 644 $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo chown root:wheel $DAEMON_PLIST_DST/$DAEMON_PLIST # Copy user tool -sudo cp $TMP/$TOOL /usr/local/bin/$TOOL -sudo chmod +x /usr/local/bin/$TOOL +sudo cp $TMP/$TOOL $TOOL_DST/$TOOL +sudo chmod +x $TOOL_DST/$TOOL # Copy man pages -sudo cp $TMP/$MAN1 /usr/share/man/man8 -sudo cp $TMP/$MAN2 /usr/share/man/man8 +sudo cp $TMP/$MAN_TOOL $MAN_DST +sudo cp $TMP/$MAN_DAEMON $MAN_DST # Load kernel extension -sudo kextload /Library/Extensions/$KEXT +sudo kextload $KEXT_DST/$KEXT # Start daemon -sudo launchctl load /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo launchctl start com.github.iscsi-osx.iscsid \ No newline at end of file +sudo launchctl load $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo launchctl start $DAEMON_PLIST_NOEXT diff --git a/Distribution/Scripts/Installer/preinstall b/Distribution/Scripts/Installer/preinstall index 487b483f..e102ec1e 100755 --- a/Distribution/Scripts/Installer/preinstall +++ b/Distribution/Scripts/Installer/preinstall @@ -4,22 +4,63 @@ DAEMON=iscsid TOOL=iscsictl KEXT=iSCSIInitiator.kext +FRAMEWORK=iSCSI.framework +DAEMON_PLIST=com.github.iscsi-osx.iscsid.plist +DAEMON_PLIST_NOEXT=com.github.iscsi-osx.iscsid.plist +MAN_TOOL=iscsictl.8 +MAN_DAEMON=iscsid.8 + +# Define install path +DAEMON_DST=/usr/local/libexec +DAEMON_PLIST_DST=/Library/LaunchDaemons +FRAMEWORK_DST=/Library/Frameworks +TOOL_DST=/usr/local/bin +MAN_DST=/usr/share/man/man8 + +# Get minor version of the OS +OSX_MINOR_VER=$(sw_vers -productVersion | awk -F '.' '{print $2}') + +# Minor version of OS X Mavericks +OSX_MAVERICKS_MINOR_VER="9" + +if [ "$OSX_MINOR_VER" -ge "$OSX_MAVERICKS_MINOR_VER" ]; then + KEXT_DST=/Library/Extensions +else + KEXT_DST=/System/Library/Extensions +fi # Stop, unload and remove launch daemon -sudo launchctl stop /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid -sudo launchctl unload /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo rm -f /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist +sudo launchctl stop $DAEMON_PLIST_NOEXT + +if [ -f $DAEMON_PLIST_DST/$DAEMON_PLIST ]; then + sudo launchctl unload $DAEMON_PLIST_DST/$DAEMON_PLIST +fi + +sudo rm -f $DAEMON_PLIST_DST/$DAEMON_PLIST sudo rm -f /usr/sbin/$DAEMON # Old location -sudo rm -f /Library/PrivilegedHelperTools/$DAEMON +sudo rm -f /System/Library/LaunchDaemons/$DAEMON_PLIST # Old location +sudo rm -f $DAEMON_DST/$DAEMON # Unload & remove kernel extension -sudo kextunload /Library/Extensions/$KEXT -sudo rm -f -R /Library/Extensions/$KEXT +if [ -f $KEXT_DST/$KEXT ]; then + sudo kextunload $KEXT_DST/$KEXT +fi + +sudo rm -f -R $KEXT_DST/$KEXT # Remove user tools sudo rm -f /usr/bin/$TOOL # Old location -sudo rm -f /usr/local/bin/$TOOL +sudo rm -f $TOOL_DST/$TOOL # Remove man pages -sudo rm -f /usr/share/man/man8/iscsictl.8 -sudo rm -f /usr/share/man/man8/iscsid.8 \ No newline at end of file +sudo rm -f $MAN_DST/$MAN_TOOL +sudo rm -f $MAN_DST/$MAN_DAEMON + +# Remove framework +sudo rm -f -R $FRAMEWORK_DST/$FRAMEWORK + +PKG_RSP="$(pkgutil --pkgs=com.github.iscsi-osx.iSCSIInitiator)" + +if [ "$PKG_RSP" == "com.github.iscsi-osx.iSCSIInitiator" ]; then + sudo pkgutil --forget com.github.iscsi-osx.iSCSIInitiator +fi \ No newline at end of file diff --git a/Distribution/Scripts/Uninstaller/postinstall b/Distribution/Scripts/Uninstaller/postinstall index d9bd964f..e102ec1e 100755 --- a/Distribution/Scripts/Uninstaller/postinstall +++ b/Distribution/Scripts/Uninstaller/postinstall @@ -4,24 +4,63 @@ DAEMON=iscsid TOOL=iscsictl KEXT=iSCSIInitiator.kext +FRAMEWORK=iSCSI.framework +DAEMON_PLIST=com.github.iscsi-osx.iscsid.plist +DAEMON_PLIST_NOEXT=com.github.iscsi-osx.iscsid.plist +MAN_TOOL=iscsictl.8 +MAN_DAEMON=iscsid.8 + +# Define install path +DAEMON_DST=/usr/local/libexec +DAEMON_PLIST_DST=/Library/LaunchDaemons +FRAMEWORK_DST=/Library/Frameworks +TOOL_DST=/usr/local/bin +MAN_DST=/usr/share/man/man8 + +# Get minor version of the OS +OSX_MINOR_VER=$(sw_vers -productVersion | awk -F '.' '{print $2}') + +# Minor version of OS X Mavericks +OSX_MAVERICKS_MINOR_VER="9" + +if [ "$OSX_MINOR_VER" -ge "$OSX_MAVERICKS_MINOR_VER" ]; then + KEXT_DST=/Library/Extensions +else + KEXT_DST=/System/Library/Extensions +fi # Stop, unload and remove launch daemon -sudo launchctl stop /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid -sudo launchctl unload /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo rm -f /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist +sudo launchctl stop $DAEMON_PLIST_NOEXT + +if [ -f $DAEMON_PLIST_DST/$DAEMON_PLIST ]; then + sudo launchctl unload $DAEMON_PLIST_DST/$DAEMON_PLIST +fi + +sudo rm -f $DAEMON_PLIST_DST/$DAEMON_PLIST sudo rm -f /usr/sbin/$DAEMON # Old location -sudo rm -f /Library/PrivilegedHelperTools/$DAEMON +sudo rm -f /System/Library/LaunchDaemons/$DAEMON_PLIST # Old location +sudo rm -f $DAEMON_DST/$DAEMON # Unload & remove kernel extension -sudo kextunload /Library/Extensions/$KEXT -sudo rm -f -R /Library/Extensions/$KEXT +if [ -f $KEXT_DST/$KEXT ]; then + sudo kextunload $KEXT_DST/$KEXT +fi + +sudo rm -f -R $KEXT_DST/$KEXT # Remove user tools sudo rm -f /usr/bin/$TOOL # Old location -sudo rm -f /usr/local/bin/$TOOL +sudo rm -f $TOOL_DST/$TOOL # Remove man pages -sudo rm -f /usr/share/man/man8/iscsictl.8 -sudo rm -f /usr/share/man/man8/iscsid.8 +sudo rm -f $MAN_DST/$MAN_TOOL +sudo rm -f $MAN_DST/$MAN_DAEMON + +# Remove framework +sudo rm -f -R $FRAMEWORK_DST/$FRAMEWORK + +PKG_RSP="$(pkgutil --pkgs=com.github.iscsi-osx.iSCSIInitiator)" -pkgutil --forget com.github.iscsi-osx.iSCSIInitiator \ No newline at end of file +if [ "$PKG_RSP" == "com.github.iscsi-osx.iSCSIInitiator" ]; then + sudo pkgutil --forget com.github.iscsi-osx.iSCSIInitiator +fi \ No newline at end of file diff --git a/Distribution/package.sh b/Distribution/package.sh index 0fee9adf..8d988a7f 100755 --- a/Distribution/package.sh +++ b/Distribution/package.sh @@ -1,7 +1,7 @@ # Package parameters NAME="iSCSI Initiator for OS X" BUNDLE_ID="com.github.iscsi-osx.iSCSIInitiator" -VERSION=$(cd ../ ; agvtool what-version -terse) +VERSION="1.0.0-beta2" # Output of final DMG RELEASE="../Release" @@ -43,7 +43,7 @@ REQUIREMENTS_PATH="Resources/Requirements.plist" # Relelase build of all three components xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace \ - -scheme iSCSIInitiator -configuration release BUILD_DIR=$XCODE_RELEASE_BUILD_DIR + -scheme iSCSI.kext -configuration release BUILD_DIR=$XCODE_RELEASE_BUILD_DIR xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace \ -scheme iscsid -configuration release BUILD_DIR=$XCODE_RELEASE_BUILD_DIR xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace \ @@ -68,16 +68,17 @@ pkgbuild --nopayload \ --version $VERSION \ $UNINSTALLER_PATH.tmp + # Put packages inside a product archive productbuild --distribution $INSTALLER_DIST_XML \ - --package-path $TMP_PACKAGE_DIR \ - --product $REQUIREMENTS_PATH \ - $INSTALLER_PATH +--package-path $TMP_PACKAGE_DIR \ +--product $REQUIREMENTS_PATH \ +$INSTALLER_PATH productbuild --distribution $UNINSTALLER_DIST_XML \ - --package-path $TMP_PACKAGE_DIR \ - --product $REQUIREMENTS_PATH \ - $UNINSTALLER_PATH +--package-path $TMP_PACKAGE_DIR \ +--product $REQUIREMENTS_PATH \ +$UNINSTALLER_PATH # Cleanup temporary packages, leaving final pacakges for DMG rm $INSTALLER_PATH.tmp @@ -85,11 +86,11 @@ rm $UNINSTALLER_PATH.tmp # Build the DMG hdiutil create -srcfolder $TMP_PACKAGE_DIR -volname "$NAME" -fs HFS+ \ - -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${DMG_SIZE}k $TMP_ROOT/$DMG_BASE_NAME.dmg +-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${DMG_SIZE}k $TMP_ROOT/$DMG_BASE_NAME.dmg # Load the DMG device=$(hdiutil attach -readwrite -noverify -noautoopen $TMP_ROOT/$DMG_BASE_NAME.dmg | \ - egrep '^/dev/' | sed 1q | awk '{print $1}') +egrep '^/dev/' | sed 1q | awk '{print $1}') sleep 2 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..ee66facc --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,23 @@ +Copyright (c) 2016, Nareg Sinenian +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Scripts/build.sh b/Scripts/build.sh index 99359f1b..41dd83fe 100755 --- a/Scripts/build.sh +++ b/Scripts/build.sh @@ -1,3 +1,3 @@ xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace -scheme iscsid build xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace -scheme iscsictl build -xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace -scheme iSCSIInitiator build +xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace -scheme iSCSI.kext build diff --git a/Scripts/install.sh b/Scripts/install.sh index 59068378..9359e379 100755 --- a/Scripts/install.sh +++ b/Scripts/install.sh @@ -4,6 +4,29 @@ DAEMON=iscsid TOOL=iscsictl KEXT=iSCSIInitiator.kext +FRAMEWORK=iSCSI.framework +DAEMON_PLIST=com.github.iscsi-osx.iscsid.plist +MAN_TOOL=iscsictl.8 +MAN_DAEMON=iscsid.8 + +# Define install path +DAEMON_DST=/usr/local/libexec +DAEMON_PLIST_DST=/Library/LaunchDaemons +FRAMEWORK_DST=/Library/Frameworks +TOOL_DST=/usr/local/bin +MAN_DST=/usr/share/man/man8 + +# Get minor version of the OS +OSX_MINOR_VER=$(sw_vers -productVersion | awk -F '.' '{print $2}') + +# Minor version of OS X Mavericks +OSX_MAVERICKS_MINOR_VER="9" + +if [ "$OSX_MINOR_VER" -ge "$OSX_MAVERICKS_MINOR_VER" ]; then + KEXT_DST=/Library/Extensions +else + KEXT_DST=/System/Library/Extensions +fi # Look for build products in places Xcode might place them. for BUILD_PATH in \ @@ -23,30 +46,37 @@ if [ X"" == X"${SOURCE_PATH}" ]; then fi # Copy kernel extension & load it -sudo cp -R $SOURCE_PATH/$KEXT /Library/Extensions/$KEXT -sudo chmod -R 755 /Library/Extensions/$KEXT -sudo chown -R root:wheel /Library/Extensions/$KEXT +sudo cp -R $SOURCE_PATH/$KEXT $KEXT_DST/$KEXT +sudo chmod -R 755 $KEXT_DST/$KEXT +sudo chown -R root:wheel $KEXT_DST/$KEXT + +# Copy framework +sudo cp -R $SOURCE_PATH/$FRAMEWORK $FRAMEWORK_DST/$FRAMEWORK +sudo chown -R root:wheel $FRAMEWORK_DST/$FRAMEWORK +sudo chmod -R 755 $FRAMEWORK_DST/$FRAMEWORK + # Copy daemon & set permissions sudo rm -f /var/logs/iscsid.log -sudo cp $SOURCE_PATH/$DAEMON /Library/PrivilegedHelperTools/$DAEMON -sudo cp $SOURCE_PATH/com.github.iscsi-osx.iscsid.plist /System/Library/LaunchDaemons -sudo chmod -R 744 /Library/PrivilegedHelperTools/$DAEMON -sudo chown -R root:wheel /Library/PrivilegedHelperTools/$DAEMON -sudo chmod 644 /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo chown root:wheel /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist +sudo mkdir -p $DAEMON_DST +sudo cp $SOURCE_PATH/$DAEMON $DAEMON_DST/$DAEMON +sudo cp $SOURCE_PATH/$DAEMON_PLIST $DAEMON_PLIST_DST +sudo chmod -R 744 $DAEMON_DST/$DAEMON +sudo chown -R root:wheel $DAEMON_DST/$DAEMON +sudo chmod 644 $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo chown root:wheel $DAEMON_PLIST_DST/$DAEMON_PLIST # Copy user tool -sudo cp $SOURCE_PATH/$TOOL /usr/local/bin/$TOOL -sudo chmod +x /usr/local/bin/$TOOL +sudo cp $SOURCE_PATH/$TOOL $TOOL_DST/$TOOL +sudo chmod +x $TOOL_DST/$TOOL # Copy man page -sudo cp $SOURCE_PATH/iscsictl.8 /usr/share/man/man8 -sudo cp $SOURCE_PATH/iscsid.8 /usr/share/man/man8 +sudo cp $SOURCE_PATH/$MAN_TOOL $MAN_DST +sudo cp $SOURCE_PATH/$MAN_DAEMON $MAN_DST # Load kernel extension -sudo kextload /Library/Extensions/$KEXT +sudo kextload $KEXT_DST/$KEXT # Start daemon -sudo launchctl load /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo launchctl start com.github.iscsi-osx.iscsid +sudo launchctl load $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo launchctl start $DAEMON_PLIST diff --git a/Scripts/uninstall.sh b/Scripts/uninstall.sh index 487b483f..7c144a35 100755 --- a/Scripts/uninstall.sh +++ b/Scripts/uninstall.sh @@ -4,22 +4,49 @@ DAEMON=iscsid TOOL=iscsictl KEXT=iSCSIInitiator.kext +FRAMEWORK=iSCSI.framework +DAEMON_PLIST=com.github.iscsi-osx.iscsid.plist +MAN_TOOL=iscsictl.8 +MAN_DAEMON=iscsid.8 + +# Define install path +DAEMON_DST=/usr/local/libexec +DAEMON_PLIST_DST=/Library/LaunchDaemons +FRAMEWORK_DST=/Library/Frameworks +TOOL_DST=/usr/local/bin +MAN_DST=/usr/share/man/man8 + +# Get minor version of the OS +OSX_MINOR_VER=$(sw_vers -productVersion | awk -F '.' '{print $2}') + +# Minor version of OS X Mavericks +OSX_MAVERICKS_MINOR_VER="9" + +if [ "$OSX_MINOR_VER" -ge "$OSX_MAVERICKS_MINOR_VER" ]; then + KEXT_DST=/Library/Extensions +else + KEXT_DST=/System/Library/Extensions +fi # Stop, unload and remove launch daemon -sudo launchctl stop /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid -sudo launchctl unload /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist -sudo rm -f /System/Library/LaunchDaemons/com.github.iscsi-osx.iscsid.plist +sudo launchctl stop $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo launchctl unload $DAEMON_PLIST_DST/$DAEMON_PLIST +sudo rm -f $DAEMON_PLIST_DST/$DAEMON_PLIST sudo rm -f /usr/sbin/$DAEMON # Old location -sudo rm -f /Library/PrivilegedHelperTools/$DAEMON +sudo rm -f /System/Library/LaunchDaemons/$DAEMON_PLIST # Old location +sudo rm -f $DAEMON_DST/$DAEMON # Unload & remove kernel extension -sudo kextunload /Library/Extensions/$KEXT -sudo rm -f -R /Library/Extensions/$KEXT +sudo kextunload $KEXT_DST/$KEXT +sudo rm -f -R $KEXT_DST/$KEXT # Remove user tools sudo rm -f /usr/bin/$TOOL # Old location -sudo rm -f /usr/local/bin/$TOOL +sudo rm -f $TOOL_DST/$TOOL + +# Remove framework +sudo rm -R $FRAMEWORK_DST/$FRAMEWORK # Remove man pages -sudo rm -f /usr/share/man/man8/iscsictl.8 -sudo rm -f /usr/share/man/man8/iscsid.8 \ No newline at end of file +sudo rm -f $MAN_DST/$MAN_DAEMON +sudo rm -f $MAN_DST/$MAN_TOOL \ No newline at end of file diff --git a/Source/Kernel/Info.plist b/Source/Kernel/Info.plist index b6a761e0..4a560c89 100644 --- a/Source/Kernel/Info.plist +++ b/Source/Kernel/Info.plist @@ -46,9 +46,9 @@ IOMaximumSegmentCountWrite 512 IOMaximumSegmentByteCountRead - 8192 + 2048 IOMaximumSegmentByteCountWrite - 8192 + 2048 CFBundleIdentifier ${NAME_PREFIX_D}.${PRODUCT_NAME} IOClass @@ -77,7 +77,7 @@ com.apple.kpi.libkern 12.5 com.apple.kpi.mach - 13.2 + 12.6 diff --git a/Source/Kernel/iSCSIIOEventSource.cpp b/Source/Kernel/iSCSIIOEventSource.cpp index 05108c1c..16d8925f 100644 --- a/Source/Kernel/iSCSIIOEventSource.cpp +++ b/Source/Kernel/iSCSIIOEventSource.cpp @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIIOEventSource.cpp - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/Source/Kernel/iSCSIIOEventSource.h b/Source/Kernel/iSCSIIOEventSource.h index d990933c..e2a1c410 100644 --- a/Source/Kernel/iSCSIIOEventSource.h +++ b/Source/Kernel/iSCSIIOEventSource.h @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIIOEventSource.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_IO_EVENT_SOURCE_H__ diff --git a/Source/Kernel/iSCSIInitiator.cpp b/Source/Kernel/iSCSIInitiator.cpp index 20575d4e..7fc120b5 100644 --- a/Source/Kernel/iSCSIInitiator.cpp +++ b/Source/Kernel/iSCSIInitiator.cpp @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIInitiator.cpp - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include diff --git a/Source/Kernel/iSCSIInitiator.h b/Source/Kernel/iSCSIInitiator.h index b7d392be..e196a801 100644 --- a/Source/Kernel/iSCSIInitiator.h +++ b/Source/Kernel/iSCSIInitiator.h @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIInitiator.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_INITIATOR_H__ diff --git a/Source/Kernel/iSCSIInitiatorClient.cpp b/Source/Kernel/iSCSIInitiatorClient.cpp index 681847aa..0e3767b4 100644 --- a/Source/Kernel/iSCSIInitiatorClient.cpp +++ b/Source/Kernel/iSCSIInitiatorClient.cpp @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIInitiatorClient.cpp - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIVirtualHBA.h" @@ -198,8 +219,8 @@ const IOExternalMethodDispatch iSCSIInitiatorClient::methods[kiSCSIInitiatorNumM (IOExternalMethodAction) &iSCSIInitiatorClient::GetPortalAddressForConnectionId, 2, // Session ID, connection ID 0, - 0, // Returned connection count - kIOUCVariableStructureSize // connection address structures + 0, + kIOUCVariableStructureSize // Portal address (C string) }, { (IOExternalMethodAction) &iSCSIInitiatorClient::GetPortalPortForConnectionId, @@ -249,6 +270,7 @@ bool iSCSIInitiatorClient::initWithTask(task_t owningTask, this->owningTask = owningTask; this->securityToken = securityToken; this->type = type; + this->accessLock = IOLockAlloc(); // Perform any initialization tasks here return super::initWithTask(owningTask,securityToken,type,properties); @@ -278,6 +300,11 @@ IOReturn iSCSIInitiatorClient::clientClose() // Ensure that the connection has been closed (in case the user calls // IOServiceClose() before calling our close() method close(); + + if(accessLock) { + IOLockFree(accessLock); + accessLock = NULL; + } // Terminate ourselves terminate(); @@ -445,12 +472,16 @@ IOReturn iSCSIInitiatorClient::CreateSession(iSCSIInitiatorClient * target, OSString * hostInterface = OSString::withCString((const char *)params[3]); const sockaddr_storage * portalSockAddr = (struct sockaddr_storage*)params[4]; const sockaddr_storage * hostSockAddr = (struct sockaddr_storage*)params[5]; + + IOLockLock(target->accessLock); // Create a connection errno_t error = target->provider->CreateSession( targetIQN,portalAddress,portalPort,hostInterface,portalSockAddr, hostSockAddr,&sessionId,&connectionId); + IOLockUnlock(target->accessLock); + args->scalarOutput[0] = sessionId; args->scalarOutput[1] = connectionId; args->scalarOutput[2] = error; @@ -470,7 +501,10 @@ IOReturn iSCSIInitiatorClient::ReleaseSession(iSCSIInitiatorClient * target, IOExternalMethodArguments * args) { // Release the session with the specified ID + IOLockLock(target->accessLock); target->provider->ReleaseSession(*args->scalarInput); + IOLockUnlock(target->accessLock); + return kIOReturnSuccess; } @@ -491,60 +525,68 @@ IOReturn iSCSIInitiatorClient::SetSessionOption(iSCSIInitiatorClient * target, // Range-check input if(sessionId >= kiSCSIMaxSessions) return kIOReturnBadArgument; + + IOLockLock(target->accessLock); // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; - if(!session) - return kIOReturnNotFound; + IOReturn retVal = kIOReturnSuccess; - switch(optType) + if(session) { - case kiSCSIKernelSODataPDUInOrder: - session->dataPDUInOrder = optVal; - break; - case kiSCSIKernelSODataSequenceInOrder: - session->dataSequenceInOrder = optVal; - break; - case kiSCSIKernelSODefaultTime2Retain: - session->defaultTime2Retain = optVal; - break; - case kiSCSIKernelSODefaultTime2Wait: - session->defaultTime2Wait = optVal; - break; - case kiSCSIKernelSOErrorRecoveryLevel: - session->errorRecoveryLevel = optVal; - break; - case kiSCSIKernelSOFirstBurstLength: - session->firstBurstLength = (UInt32)optVal; - break; - case kiSCSIKernelSOImmediateData: - session->immediateData = optVal; - break; - case kiSCSIKernelSOMaxConnections: - session->maxConnections = (CID)optVal; - break; - case kiSCSIKernelSOMaxOutstandingR2T: - session->maxOutStandingR2T = optVal; - break; - case kiSCSIKernelSOMaxBurstLength: - session->maxBurstLength = (UInt32)optVal; - break; - case kiSCSIKernelSOInitialR2T: - session->initialR2T = optVal; - break; - case kiSCSIKernelSOTargetPortalGroupTag: - session->targetPortalGroupTag = optVal; - break; - case kiSCSIKernelSOTargetSessionId: - session->targetSessionId = optVal; - break; - - default: - return kIOReturnBadArgument; - }; + switch(optType) + { + case kiSCSIKernelSODataPDUInOrder: + session->dataPDUInOrder = optVal; + break; + case kiSCSIKernelSODataSequenceInOrder: + session->dataSequenceInOrder = optVal; + break; + case kiSCSIKernelSODefaultTime2Retain: + session->defaultTime2Retain = optVal; + break; + case kiSCSIKernelSODefaultTime2Wait: + session->defaultTime2Wait = optVal; + break; + case kiSCSIKernelSOErrorRecoveryLevel: + session->errorRecoveryLevel = optVal; + break; + case kiSCSIKernelSOFirstBurstLength: + session->firstBurstLength = (UInt32)optVal; + break; + case kiSCSIKernelSOImmediateData: + session->immediateData = optVal; + break; + case kiSCSIKernelSOMaxConnections: + session->maxConnections = (CID)optVal; + break; + case kiSCSIKernelSOMaxOutstandingR2T: + session->maxOutStandingR2T = optVal; + break; + case kiSCSIKernelSOMaxBurstLength: + session->maxBurstLength = (UInt32)optVal; + break; + case kiSCSIKernelSOInitialR2T: + session->initialR2T = optVal; + break; + case kiSCSIKernelSOTargetPortalGroupTag: + session->targetPortalGroupTag = optVal; + break; + case kiSCSIKernelSOTargetSessionId: + session->targetSessionId = optVal; + break; + + default: + retVal = kIOReturnBadArgument; + }; + } + else { + retVal = kIOReturnBadArgument; + } - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + return retVal; } IOReturn iSCSIInitiatorClient::GetSessionOption(iSCSIInitiatorClient * target, @@ -564,60 +606,68 @@ IOReturn iSCSIInitiatorClient::GetSessionOption(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; - UInt64 * optVal = args->scalarOutput; + IOReturn retVal = kIOReturnSuccess; - if(!session) - return kIOReturnNotFound; + UInt64 * optVal = args->scalarOutput; - switch(optType) + if(session) { - case kiSCSIKernelSODataPDUInOrder: - *optVal = session->dataPDUInOrder; - break; - case kiSCSIKernelSODataSequenceInOrder: - *optVal = session->dataSequenceInOrder; - break; - case kiSCSIKernelSODefaultTime2Retain: - *optVal = session->defaultTime2Retain; - break; - case kiSCSIKernelSODefaultTime2Wait: - *optVal = session->defaultTime2Wait; - break; - case kiSCSIKernelSOErrorRecoveryLevel: - *optVal = session->errorRecoveryLevel; - break; - case kiSCSIKernelSOFirstBurstLength: - *optVal = session->firstBurstLength; - break; - case kiSCSIKernelSOImmediateData: - *optVal = session->immediateData; - break; - case kiSCSIKernelSOMaxConnections: - *optVal = session->maxConnections; - break; - case kiSCSIKernelSOMaxOutstandingR2T: - *optVal = session->maxOutStandingR2T; - break; - case kiSCSIKernelSOMaxBurstLength: - *optVal = session->maxBurstLength; - break; - case kiSCSIKernelSOInitialR2T: - *optVal = session->initialR2T; - break; - case kiSCSIKernelSOTargetPortalGroupTag: - *optVal = session->targetPortalGroupTag; - break; - case kiSCSIKernelSOTargetSessionId: - *optVal = session->targetSessionId; - break; - default: - return kIOReturnBadArgument; - }; + switch(optType) + { + case kiSCSIKernelSODataPDUInOrder: + *optVal = session->dataPDUInOrder; + break; + case kiSCSIKernelSODataSequenceInOrder: + *optVal = session->dataSequenceInOrder; + break; + case kiSCSIKernelSODefaultTime2Retain: + *optVal = session->defaultTime2Retain; + break; + case kiSCSIKernelSODefaultTime2Wait: + *optVal = session->defaultTime2Wait; + break; + case kiSCSIKernelSOErrorRecoveryLevel: + *optVal = session->errorRecoveryLevel; + break; + case kiSCSIKernelSOFirstBurstLength: + *optVal = session->firstBurstLength; + break; + case kiSCSIKernelSOImmediateData: + *optVal = session->immediateData; + break; + case kiSCSIKernelSOMaxConnections: + *optVal = session->maxConnections; + break; + case kiSCSIKernelSOMaxOutstandingR2T: + *optVal = session->maxOutStandingR2T; + break; + case kiSCSIKernelSOMaxBurstLength: + *optVal = session->maxBurstLength; + break; + case kiSCSIKernelSOInitialR2T: + *optVal = session->initialR2T; + break; + case kiSCSIKernelSOTargetPortalGroupTag: + *optVal = session->targetPortalGroupTag; + break; + case kiSCSIKernelSOTargetSessionId: + *optVal = session->targetSessionId; + break; + default: + retVal = kIOReturnBadArgument; + }; + } + else { + retVal = kIOReturnNotFound; + } - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + return retVal; } /*! Dispatched function invoked from user-space to create new connection. */ @@ -652,12 +702,15 @@ IOReturn iSCSIInitiatorClient::CreateConnection(iSCSIInitiatorClient * target, const sockaddr_storage * portalSockAddr = (struct sockaddr_storage*)params[3]; const sockaddr_storage * hostSockAddr = (struct sockaddr_storage*)params[4]; + IOLockLock(target->accessLock); // Create a connection errno_t error = target->provider->CreateConnection( sessionId,portalAddress,portalPort,hostInterface,portalSockAddr, hostSockAddr,&connectionId); + IOLockUnlock(target->accessLock); + args->scalarOutput[0] = connectionId; args->scalarOutput[1] = error; args->scalarOutputCount = 2; @@ -670,8 +723,11 @@ IOReturn iSCSIInitiatorClient::ReleaseConnection(iSCSIInitiatorClient * target, void * reference, IOExternalMethodArguments * args) { + IOLockLock(target->accessLock); + target->provider->ReleaseConnection((SID)args->scalarInput[0], (CID)args->scalarInput[1]); + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -679,9 +735,12 @@ IOReturn iSCSIInitiatorClient::ActivateConnection(iSCSIInitiatorClient * target, void * reference, IOExternalMethodArguments * args) { + IOLockLock(target->accessLock); + *args->scalarOutput = target->provider->ActivateConnection((SID)args->scalarInput[0], (CID)args->scalarInput[1]); + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -689,8 +748,12 @@ IOReturn iSCSIInitiatorClient::ActivateAllConnections(iSCSIInitiatorClient * tar void * reference, IOExternalMethodArguments * args) { + IOLockLock(target->accessLock); + *args->scalarOutput = target->provider->ActivateAllConnections((SID)args->scalarInput[0]); + + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -698,10 +761,13 @@ IOReturn iSCSIInitiatorClient::DeactivateConnection(iSCSIInitiatorClient * targe void * reference, IOExternalMethodArguments * args) { + IOLockLock(target->accessLock); + *args->scalarOutput = target->provider->DeactivateConnection((SID)args->scalarInput[0], (CID)args->scalarInput[1]); - + + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -709,9 +775,12 @@ IOReturn iSCSIInitiatorClient::DeactivateAllConnections(iSCSIInitiatorClient * t void * reference, IOExternalMethodArguments * args) { + IOLockLock(target->accessLock); + *args->scalarOutput = target->provider->DeactivateAllConnections((SID)args->scalarInput[0]); + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -725,7 +794,9 @@ IOReturn iSCSIInitiatorClient::SendBHS(iSCSIInitiatorClient * target, if(args->structureInputSize != kiSCSIPDUBasicHeaderSegmentSize) return kIOReturnNoSpace; + IOLockLock(target->accessLock); memcpy(&target->bhsBuffer,args->structureInput,kiSCSIPDUBasicHeaderSegmentSize); + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -745,25 +816,31 @@ IOReturn iSCSIInitiatorClient::SendData(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; - - iSCSIConnection * connection = session->connections[connectionId]; - - if(!connection) - return kIOReturnNotFound; + if(session) + connection = session->connections[connectionId]; const void * data = args->structureInput; size_t length = args->structureInputSize; // Send data and return the result - if(hba->SendPDU(session,connection,&(target->bhsBuffer),nullptr,data,length)) - return kIOReturnError; + IOReturn retVal = kIOReturnNotFound; - return kIOReturnSuccess; + if(connection) { + if(hba->SendPDU(session,connection,&(target->bhsBuffer),nullptr,data,length)) + retVal = kIOReturnError; + else + retVal = kIOReturnSuccess; + } + + IOLockUnlock(target->accessLock); + + return retVal; } /*! Dispatched function invoked from user-space to receive data @@ -786,25 +863,30 @@ IOReturn iSCSIInitiatorClient::RecvBHS(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; - - iSCSIConnection * connection = session->connections[connectionId]; + if(session) + connection = session->connections[connectionId]; - if(!connection) - return kIOReturnNotFound; - // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; + iSCSIPDUTargetBHS * bhs = (iSCSIPDUTargetBHS*)args->structureOutput; + + if(connection) { + if(hba->RecvPDUHeader(session,connection,bhs,MSG_WAITALL)) + retVal = kIOReturnIOError; + else + retVal = kIOReturnSuccess; + } - if(hba->RecvPDUHeader(session,connection,bhs,MSG_WAITALL)) - return kIOReturnIOError; - + IOLockUnlock(target->accessLock); - return kIOReturnSuccess; + return retVal; } /*! Dispatched function invoked from user-space to receive data @@ -823,25 +905,29 @@ IOReturn iSCSIInitiatorClient::RecvData(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; - - iSCSIConnection * connection = session->connections[connectionId]; - - if(!connection) - return kIOReturnNotFound; + if(session) + connection = session->connections[connectionId]; // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; + void * data = (void *)args->structureOutput; size_t length = args->structureOutputSize; if(hba->RecvPDUData(session,connection,data,length,MSG_WAITALL)) - return kIOReturnIOError; - - return kIOReturnSuccess; + retVal = kIOReturnIOError; + else + retVal = kIOReturnSuccess; + + IOLockUnlock(target->accessLock); + + return retVal; } // TODO: Only allow user to set options when connection is inactive @@ -864,52 +950,60 @@ IOReturn iSCSIInitiatorClient::SetConnectionOption(iSCSIInitiatorClient * target if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; - - iSCSIConnection * connection = session->connections[connectionId]; - - if(!connection) - return kIOReturnNotFound; + if(session) + connection = session->connections[connectionId]; - switch(optType) + // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; + + if(connection) { - case kiSCSIKernelCOIFMarkInt: - connection->IFMarkInt = optVal; - break; - case kiSCSIKernelCOOFMarkInt: - connection->OFMarkInt = optVal; - break; - case kiSCSIKernelCOUseIFMarker: - connection->useIFMarker = optVal; - break; - case kiSCSIKernelCOUseOFMarker: - connection->useOFMarker = optVal; - break; - case kiSCSIKernelCOUseDataDigest: - connection->useDataDigest = optVal; - break; - case kiSCSIKernelCOUseHeaderDigest: - connection->useHeaderDigest = optVal; - break; - case kiSCSIKernelCOMaxRecvDataSegmentLength: - connection->maxRecvDataSegmentLength = (UInt32)optVal; - break; - case kiSCSIKernelCOMaxSendDataSegmentLength: - connection->maxSendDataSegmentLength = (UInt32)optVal; - break; - case kiSCSIKernelCOInitialExpStatSN: - connection->expStatSN = (UInt32)optVal; - break; - - default: - return kIOReturnBadArgument; - }; + retVal = kIOReturnSuccess; + + switch(optType) + { + case kiSCSIKernelCOIFMarkInt: + connection->IFMarkInt = optVal; + break; + case kiSCSIKernelCOOFMarkInt: + connection->OFMarkInt = optVal; + break; + case kiSCSIKernelCOUseIFMarker: + connection->useIFMarker = optVal; + break; + case kiSCSIKernelCOUseOFMarker: + connection->useOFMarker = optVal; + break; + case kiSCSIKernelCOUseDataDigest: + connection->useDataDigest = optVal; + break; + case kiSCSIKernelCOUseHeaderDigest: + connection->useHeaderDigest = optVal; + break; + case kiSCSIKernelCOMaxRecvDataSegmentLength: + connection->maxRecvDataSegmentLength = (UInt32)optVal; + break; + case kiSCSIKernelCOMaxSendDataSegmentLength: + connection->maxSendDataSegmentLength = (UInt32)optVal; + break; + case kiSCSIKernelCOInitialExpStatSN: + connection->expStatSN = (UInt32)optVal; + break; + + default: + retVal = kIOReturnBadArgument; + }; + } - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + + return retVal; } IOReturn iSCSIInitiatorClient::GetConnectionOption(iSCSIInitiatorClient * target, @@ -930,52 +1024,59 @@ IOReturn iSCSIInitiatorClient::GetConnectionOption(iSCSIInitiatorClient * target if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; + if(session) + connection = session->connections[connectionId]; - iSCSIConnection * connection = session->connections[connectionId]; + // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; + + if(connection) { + retVal = kIOReturnSuccess; - if(!connection) - return kIOReturnNotFound; + switch(optType) + { + case kiSCSIKernelCOIFMarkInt: + *optVal = connection->IFMarkInt; + break; + case kiSCSIKernelCOOFMarkInt: + *optVal = connection->OFMarkInt; + break; + case kiSCSIKernelCOUseIFMarker: + *optVal = connection->useIFMarker; + break; + case kiSCSIKernelCOUseOFMarker: + *optVal = connection->useOFMarker; + break; + case kiSCSIKernelCOUseDataDigest: + *optVal = connection->useDataDigest; + break; + case kiSCSIKernelCOUseHeaderDigest: + *optVal = connection->useHeaderDigest; + break; + case kiSCSIKernelCOMaxRecvDataSegmentLength: + *optVal = connection->maxRecvDataSegmentLength; + break; + case kiSCSIKernelCOMaxSendDataSegmentLength: + *optVal = connection->maxSendDataSegmentLength; + break; + case kiSCSIKernelCOInitialExpStatSN: + *optVal = connection->expStatSN; + break; + + default: + return kIOReturnBadArgument; + }; + } - switch(optType) - { - case kiSCSIKernelCOIFMarkInt: - *optVal = connection->IFMarkInt; - break; - case kiSCSIKernelCOOFMarkInt: - *optVal = connection->OFMarkInt; - break; - case kiSCSIKernelCOUseIFMarker: - *optVal = connection->useIFMarker; - break; - case kiSCSIKernelCOUseOFMarker: - *optVal = connection->useOFMarker; - break; - case kiSCSIKernelCOUseDataDigest: - *optVal = connection->useDataDigest; - break; - case kiSCSIKernelCOUseHeaderDigest: - *optVal = connection->useHeaderDigest; - break; - case kiSCSIKernelCOMaxRecvDataSegmentLength: - *optVal = connection->maxRecvDataSegmentLength; - break; - case kiSCSIKernelCOMaxSendDataSegmentLength: - *optVal = connection->maxSendDataSegmentLength; - break; - case kiSCSIKernelCOInitialExpStatSN: - *optVal = connection->expStatSN; - break; - - default: - return kIOReturnBadArgument; - }; + IOLockUnlock(target->accessLock); - return kIOReturnSuccess; + return retVal; } IOReturn iSCSIInitiatorClient::GetConnection(iSCSIInitiatorClient * target, @@ -990,26 +1091,33 @@ IOReturn iSCSIInitiatorClient::GetConnection(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions) return kIOReturnBadArgument; - // Do nothing if session doesn't exist - iSCSISession * session = hba->sessionList[sessionId]; - - if(!session) - return kIOReturnNotFound; + IOLockLock(target->accessLock); - args->scalarOutputCount = 1; - CID * connectionId = (CID *)args->scalarOutput; + iSCSISession * session = hba->sessionList[sessionId]; + IOReturn retVal = kIOReturnNotFound; - for(CID connectionIdx = 0; connectionIdx < kiSCSIMaxConnectionsPerSession; connectionIdx++) - { - if(session->connections[connectionIdx]) + if(session) { + + retVal = kIOReturnSuccess; + + args->scalarOutputCount = 1; + CID * connectionId = (CID *)args->scalarOutput; + + *connectionId = kiSCSIInvalidConnectionId; + + for(CID connectionIdx = 0; connectionIdx < kiSCSIMaxConnectionsPerSession; connectionIdx++) { - *connectionId = connectionIdx; - return kIOReturnSuccess; + if(session->connections[connectionIdx]) + { + *connectionId = connectionIdx; + break; + } } } - *connectionId = kiSCSIInvalidConnectionId; - return kIOReturnNotFound; + IOLockUnlock(target->accessLock); + + return retVal; } IOReturn iSCSIInitiatorClient::GetNumConnections(iSCSIInitiatorClient * target, @@ -1024,22 +1132,25 @@ IOReturn iSCSIInitiatorClient::GetNumConnections(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions) return kIOReturnBadArgument; - // Do nothing if session doesn't exist - iSCSISession * session = hba->sessionList[sessionId]; - - if(!session) - return kIOReturnNotFound; + IOLockLock(target->accessLock); - // Iterate over list of connections to see how many are valid + iSCSISession * session = hba->sessionList[sessionId]; + IOReturn retVal = kIOReturnNotFound; CID connectionCount = 0; - for(CID connectionId = 0; connectionId < kiSCSIMaxConnectionsPerSession; connectionId++) - if(session->connections[connectionId]) - connectionCount++; + + if(session) { + // Iterate over list of connections to see how many are valid + for(CID connectionId = 0; connectionId < kiSCSIMaxConnectionsPerSession; connectionId++) + if(session->connections[connectionId]) + connectionCount++; + } *args->scalarOutput = connectionCount; args->scalarOutputCount = 1; + + IOLockUnlock(target->accessLock); - return kIOReturnSuccess; + return retVal; } IOReturn iSCSIInitiatorClient::GetSessionIdForTargetIQN(iSCSIInitiatorClient * target, @@ -1050,15 +1161,20 @@ IOReturn iSCSIInitiatorClient::GetSessionIdForTargetIQN(iSCSIInitiatorClient * t const char * targetIQN = (const char *)args->structureInput; + IOLockLock(target->accessLock); OSNumber * identifier = (OSNumber*)(hba->targetList->getObject(targetIQN)); - if(!identifier) - return kIOReturnNotFound; + IOReturn retVal = kIOReturnNotFound; - *args->scalarOutput = identifier->unsigned16BitValue();; - args->scalarOutputCount = 1; + if(identifier) { + retVal = kIOReturnSuccess; + *args->scalarOutput = identifier->unsigned16BitValue();; + args->scalarOutputCount = 1; + } - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + + return retVal; } IOReturn iSCSIInitiatorClient::GetConnectionIdForPortalAddress(iSCSIInitiatorClient * target, @@ -1073,38 +1189,47 @@ IOReturn iSCSIInitiatorClient::GetConnectionIdForPortalAddress(iSCSIInitiatorCli if(sessionId == kiSCSIInvalidSessionId) return kIOReturnBadArgument; - // Do nothing if session doesn't exist - iSCSISession * session = hba->sessionList[sessionId]; - - if(!session) - return kIOReturnNotFound; - - OSString * portalAddress = OSString::withCString((const char *)args->structureInput); + IOLockLock(target->accessLock); - if(!portalAddress) - return kIOReturnBadArgument; + iSCSISession * session = hba->sessionList[sessionId]; + IOReturn retVal = kIOReturnNotFound; - iSCSIConnection * connection = NULL; + if(session) { - // Iterate over connections to find a matching address structure - for(CID connectionId = 0; connectionId < kiSCSIMaxConnectionsPerSession; connectionId++) - { - if(!(connection = session->connections[connectionId])) - continue; + retVal = kIOReturnBadArgument; - if(!connection->portalAddress->isEqualTo(portalAddress)) - continue; + OSString * portalAddress = OSString::withCString((const char *)args->structureInput); - *args->scalarOutput = connectionId; - args->scalarOutputCount = 1; + if(portalAddress) + { + retVal = kIOReturnNotFound; + + iSCSIConnection * connection = NULL; + + *args->scalarOutput = kiSCSIInvalidConnectionId; + args->scalarOutputCount = 1; - return kIOReturnSuccess; + // Iterate over connections to find a matching address structure + for(CID connectionId = 0; connectionId < kiSCSIMaxConnectionsPerSession; connectionId++) + { + if(!(connection = session->connections[connectionId])) + continue; + + if(!connection->portalAddress->isEqualTo(portalAddress)) + continue; + + *args->scalarOutput = connectionId; + args->scalarOutputCount = 1; + + retVal = kIOReturnSuccess; + break; + } + } } - *args->scalarOutput = kiSCSIInvalidConnectionId; - args->scalarOutputCount = 1; + IOLockUnlock(target->accessLock); - return kIOReturnNotFound; + return retVal; } IOReturn iSCSIInitiatorClient::GetSessionIds(iSCSIInitiatorClient * target, @@ -1119,6 +1244,8 @@ IOReturn iSCSIInitiatorClient::GetSessionIds(iSCSIInitiatorClient * target, SID sessionCount = 0; SID * sessionIds = (SID *)args->structureOutput; + IOLockLock(target->accessLock); + for(SID sessionIdx = 0; sessionIdx < kiSCSIMaxSessions; sessionIdx++) { if(hba->sessionList[sessionIdx]) @@ -1130,6 +1257,8 @@ IOReturn iSCSIInitiatorClient::GetSessionIds(iSCSIInitiatorClient * target, args->scalarOutputCount = 1; *args->scalarOutput = sessionCount; + + IOLockUnlock(target->accessLock); return kIOReturnSuccess; } @@ -1149,29 +1278,35 @@ IOReturn iSCSIInitiatorClient::GetConnectionIds(iSCSIInitiatorClient * target, if(sessionId >= kiSCSIMaxSessions) return kIOReturnBadArgument; - // Do nothing if session doesn't exist - iSCSISession * session = hba->sessionList[sessionId]; - - if(!session) - return kIOReturnNotFound; + IOLockLock(target->accessLock); - CID connectionCount = 0; - CID * connectionIds = (CID *)args->structureOutput; + iSCSISession * session = hba->sessionList[sessionId]; + IOReturn retVal = kIOReturnNotFound; - // Find an empty connection slot to use for a new connection - for(CID index = 0; index < kiSCSIMaxConnectionsPerSession; index++) + if(session) { - if(session->connections[index]) + retVal = kIOReturnSuccess; + + CID connectionCount = 0; + CID * connectionIds = (CID *)args->structureOutput; + + // Find an empty connection slot to use for a new connection + for(CID index = 0; index < kiSCSIMaxConnectionsPerSession; index++) { - connectionIds[connectionCount] = index; - connectionCount++; + if(session->connections[index]) + { + connectionIds[connectionCount] = index; + connectionCount++; + } } + + args->scalarOutputCount = 1; + *args->scalarOutput = connectionCount; } - - args->scalarOutputCount = 1; - *args->scalarOutput = connectionCount; - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + + return retVal; } IOReturn iSCSIInitiatorClient::GetTargetIQNForSessionId(iSCSIInitiatorClient * target, @@ -1186,36 +1321,40 @@ IOReturn iSCSIInitiatorClient::GetTargetIQNForSessionId(iSCSIInitiatorClient * t if(sessionId >= kiSCSIMaxSessions) return kIOReturnBadArgument; - // Do nothing if session doesn't exist - iSCSISession * session = hba->sessionList[sessionId]; + IOLockLock(target->accessLock); - if(!session) - return kIOReturnNotFound; + iSCSISession * session = hba->sessionList[sessionId]; + IOReturn retVal = kIOReturnNotFound; // Iterate over list of target name and find a matching session identifier OSCollectionIterator * iterator = OSCollectionIterator::withCollection(hba->targetList); - if(!iterator) - return kIOReturnNotFound; - - OSObject * object; - - while((object = iterator->getNextObject())) + if(session && iterator) { - OSString * targetIQN = OSDynamicCast(OSString,object); - OSNumber * sessionIdNumber = OSDynamicCast(OSNumber,hba->targetList->getObject(targetIQN)); - - if(sessionIdNumber->unsigned16BitValue() == sessionId) + OSObject * object; + + while((object = iterator->getNextObject())) { - // Minimum length (either buffer size or size of - // target name, whichever is shorter) - size_t size = min(targetIQN->getLength(),args->structureOutputSize); - memcpy(args->structureOutput,targetIQN->getCStringNoCopy(),size); - - return kIOReturnSuccess; + OSString * targetIQN = OSDynamicCast(OSString,object); + OSNumber * sessionIdNumber = OSDynamicCast(OSNumber,hba->targetList->getObject(targetIQN)); + + if(sessionIdNumber->unsigned16BitValue() == sessionId) + { + // Minimum length (either buffer size or size of + // target name, whichever is shorter) + size_t size = min(targetIQN->getLength(),args->structureOutputSize); + memcpy(args->structureOutput,targetIQN->getCStringNoCopy(),size); + + retVal = kIOReturnSuccess; + break; + } } } - return kIOReturnNotFound; + + IOLockUnlock(target->accessLock); + + OSSafeRelease(iterator); + return retVal; } IOReturn iSCSIInitiatorClient::GetPortalAddressForConnectionId(iSCSIInitiatorClient * target, @@ -1231,23 +1370,30 @@ IOReturn iSCSIInitiatorClient::GetPortalAddressForConnectionId(iSCSIInitiatorCli if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; + if(session) + connection = session->connections[connectionId]; - iSCSIConnection * connection = session->connections[connectionId]; + // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; - if(!connection) - return kIOReturnNotFound; - - const char * portalAddress = connection->portalAddress->getCStringNoCopy(); - size_t portalAddressLength = connection->portalAddress->getLength(); + if(connection) { + retVal = kIOReturnSuccess; + + const char * portalAddress = connection->portalAddress->getCStringNoCopy(); + size_t portalAddressLength = connection->portalAddress->getLength(); + + memset(args->structureOutput,0,args->structureOutputSize); + memcpy(args->structureOutput,portalAddress,min(args->structureOutputSize,portalAddressLength)); + } - memcpy(args->structureOutput,portalAddress,min(args->structureOutputSize,portalAddressLength+1)); - - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + return retVal; } IOReturn iSCSIInitiatorClient::GetPortalPortForConnectionId(iSCSIInitiatorClient * target, @@ -1263,23 +1409,30 @@ IOReturn iSCSIInitiatorClient::GetPortalPortForConnectionId(iSCSIInitiatorClient if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; - - iSCSIConnection * connection = session->connections[connectionId]; + if(session) + connection = session->connections[connectionId]; - if(!connection) - return kIOReturnNotFound; + // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; - const char * portalPort = connection->portalPort->getCStringNoCopy(); - size_t portalPortLength = connection->portalPort->getLength(); + if(connection) { + retVal = kIOReturnSuccess; + + const char * portalPort = connection->portalPort->getCStringNoCopy(); + size_t portalPortLength = connection->portalPort->getLength(); - memcpy(args->structureOutput,portalPort,min(args->structureOutputSize,portalPortLength+1)); + memset(args->structureOutput,0,args->structureOutputSize); + memcpy(args->structureOutput,portalPort,min(args->structureOutputSize,portalPortLength)); + } - return kIOReturnSuccess; + IOLockUnlock(target->accessLock); + return retVal; } IOReturn iSCSIInitiatorClient::GetHostInterfaceForConnectionId(iSCSIInitiatorClient * target, @@ -1295,23 +1448,30 @@ IOReturn iSCSIInitiatorClient::GetHostInterfaceForConnectionId(iSCSIInitiatorCli if(sessionId >= kiSCSIMaxSessions || connectionId >= kiSCSIMaxConnectionsPerSession) return kIOReturnBadArgument; + IOLockLock(target->accessLock); + // Do nothing if session doesn't exist iSCSISession * session = hba->sessionList[sessionId]; + iSCSIConnection * connection = NULL; - if(!session) - return kIOReturnNotFound; + if(session) + connection = session->connections[connectionId]; - iSCSIConnection * connection = session->connections[connectionId]; + // Receive data and return the result + IOReturn retVal = kIOReturnNotFound; - if(!connection) - return kIOReturnNotFound; + if(connection) { + retVal = kIOReturnSuccess; + + const char * hostInterface = connection->hostInteface->getCStringNoCopy(); + size_t hostInterfaceLength = connection->hostInteface->getLength(); - const char * hostInterface = connection->hostInteface->getCStringNoCopy(); - size_t hostInterfaceLength = connection->hostInteface->getLength(); + memcpy(args->structureOutput,hostInterface,min(args->structureOutputSize,hostInterfaceLength+1)); + } - memcpy(args->structureOutput,hostInterface,min(args->structureOutputSize,hostInterfaceLength+1)); + IOLockUnlock(target->accessLock); - return kIOReturnSuccess; + return retVal; } diff --git a/Source/Kernel/iSCSIInitiatorClient.h b/Source/Kernel/iSCSIInitiatorClient.h index 6b10e167..23acfbe2 100644 --- a/Source/Kernel/iSCSIInitiatorClient.h +++ b/Source/Kernel/iSCSIInitiatorClient.h @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIInitiatorClient.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_INITIATOR_CLIENT_H__ @@ -252,6 +273,9 @@ class iSCSIInitiatorClient : public IOUserClient /*! The notification port associated with a user-space connection. */ mach_port_t notificationPort; + + /*! Access lock for kernel functions. */ + IOLock * accessLock; }; #endif /* defined(__ISCSI_INITIATOR_CLIENT_H__) */ diff --git a/Source/Kernel/iSCSIKernelClasses.h b/Source/Kernel/iSCSIKernelClasses.h index edb03a1b..283f92eb 100644 --- a/Source/Kernel/iSCSIKernelClasses.h +++ b/Source/Kernel/iSCSIKernelClasses.h @@ -1,11 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITypesKernel - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. * - * iSCSI class names (follows the reverse DNS notation per - * Apple standards) + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_KERNEL_CLASSES_H__ diff --git a/Source/Kernel/iSCSIKernelInterfaceShared.h b/Source/Kernel/iSCSIKernelInterfaceShared.h index ee00adc0..6df6cd01 100644 --- a/Source/Kernel/iSCSIKernelInterfaceShared.h +++ b/Source/Kernel/iSCSIKernelInterfaceShared.h @@ -1,13 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIKernelInterfaceShared.h - * @date March 18, 2014 - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief iSCSI kernel extension definitions that are shared between - * kernel and user space. These definitions are used by the - * kernel extension's client in user to access the iSCSI virtual - * host bus adapter (initiator). +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_KERNEL_INTERFACE_SHARED_H__ diff --git a/Source/Kernel/iSCSIPDUKernel.cpp b/Source/Kernel/iSCSIPDUKernel.cpp index adda56ca..c0b84bc4 100644 --- a/Source/Kernel/iSCSIPDUKernel.cpp +++ b/Source/Kernel/iSCSIPDUKernel.cpp @@ -1,13 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIPDUKernel.cpp - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Kernel-space iSCSI PDU functions. These functions cannot be - * used within user-space. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #include "iSCSIPDUKernel.h" namespace iSCSIPDU { diff --git a/Source/Kernel/iSCSIPDUKernel.h b/Source/Kernel/iSCSIPDUKernel.h index 572d31f8..3ee1d02d 100644 --- a/Source/Kernel/iSCSIPDUKernel.h +++ b/Source/Kernel/iSCSIPDUKernel.h @@ -1,13 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIPDUKernel.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Kernel-space iSCSI PDU functions. These functions cannot be - * used within user-space. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #ifndef __ISCSI_PDU_USER_H__ #define __ISCSI_PDU_USER_H__ diff --git a/Source/Kernel/iSCSIPDUShared.h b/Source/Kernel/iSCSIPDUShared.h index 49508ad8..89e5a0e4 100644 --- a/Source/Kernel/iSCSIPDUShared.h +++ b/Source/Kernel/iSCSIPDUShared.h @@ -1,13 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIPDUShared.h - * @date April 8, 2014 - * @version 1.0 - * @copyright (c) 2013-2014 Nareg Sinenian. All rights reserved. - * @brief iSCSI PDU definitions that are shared between kernel and user - * space PDU libraries. They are included by the header files of - * both the kernel and user space PDU libraries and are thus - * available to a user of the PDU library. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_PDU_SHARED_H__ diff --git a/Source/Kernel/iSCSIRFC3720Defaults.h b/Source/Kernel/iSCSIRFC3720Defaults.h index 3b18c031..c3769a78 100644 --- a/Source/Kernel/iSCSIRFC3720Defaults.h +++ b/Source/Kernel/iSCSIRFC3720Defaults.h @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIRFC3720Defaults.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Default values of various parameters as defined in RFC3720 +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_RFC3720_DEFAULTS_H__ diff --git a/Source/Kernel/iSCSITaskQueue.cpp b/Source/Kernel/iSCSITaskQueue.cpp index e240dbd5..4ea40cd8 100644 --- a/Source/Kernel/iSCSITaskQueue.cpp +++ b/Source/Kernel/iSCSITaskQueue.cpp @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITaskQueue.cpp - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSITaskQueue.h" diff --git a/Source/Kernel/iSCSITaskQueue.h b/Source/Kernel/iSCSITaskQueue.h index 879e527d..471dec8b 100644 --- a/Source/Kernel/iSCSITaskQueue.h +++ b/Source/Kernel/iSCSITaskQueue.h @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITaskQueue.h - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_TASK_QUEUE_H__ diff --git a/Source/Kernel/iSCSITypesKernel.h b/Source/Kernel/iSCSITypesKernel.h index 6d9ba0e8..c1420b52 100644 --- a/Source/Kernel/iSCSITypesKernel.h +++ b/Source/Kernel/iSCSITypesKernel.h @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITypesKernel - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. * - * iSCSI data types that are used exclusively by the kernel. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_TYPES_KERNEL_H__ diff --git a/Source/Kernel/iSCSIVirtualHBA.cpp b/Source/Kernel/iSCSIVirtualHBA.cpp index 81c4a0eb..ff15522a 100644 --- a/Source/Kernel/iSCSIVirtualHBA.cpp +++ b/Source/Kernel/iSCSIVirtualHBA.cpp @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIVirtualHBA.cpp - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIVirtualHBA.h" @@ -60,7 +81,7 @@ const UInt32 iSCSIVirtualHBA::kNumBytesPerAvgBW = 1048576; const UInt32 iSCSIVirtualHBA::kiSCSITaskTimeoutMs = 60000; /*! Default TCP timeout for new connections (seconds). */ -const UInt32 iSCSIVirtualHBA::kiSCSITCPTimeoutSec = 10; +const UInt32 iSCSIVirtualHBA::kiSCSITCPTimeoutSec = 1; OSDefineMetaClassAndStructors(iSCSIVirtualHBA,IOSCSIParallelInterfaceController); @@ -589,22 +610,23 @@ void iSCSIVirtualHBA::BeginTaskOnWorkloopThread(iSCSIVirtualHBA * owner, return; } - // At this point we have have a write command, determine whether we need - // to send data at this point or later in response to an R2T + // If there is no unsolicited data to send, simply send the WRITE + // command and return. if(session->initialR2T && !session->immediateData) { bhs.flags |= kiSCSIPDUSCSICmdFlagNoUnsolicitedData; owner->SendPDU(session,connection,(iSCSIPDUInitiatorBHS *)&bhs,NULL,NULL,0); return; } - // Get data associated with this task and send ... + // At this point either immediate data, data-out PDUs or both + // are going to be sent out. IOMemoryDescriptor * dataDesc = owner->GetDataBuffer(parallelTask); UInt32 dataOffset = 0, dataLength = 0; - // First use immediate data to send as data with command PDU... + // First use immediate data to send data with command PDU... if(session->immediateData) { - // Either we send the max allowed data (immediate data length) or + // Either send the max allowed data (immediate data length) or // all of the data if it is lesser than the max allowed limit dataLength = min(connection->immediateDataLength,transferSize); @@ -624,6 +646,11 @@ void iSCSIVirtualHBA::BeginTaskOnWorkloopThread(iSCSIVirtualHBA * owner, IOFree(data,dataLength); } + else { + // No immediate data (but there will be data-out following this) + // just send the WRITE command without immediate data + owner->SendPDU(session,connection,(iSCSIPDUInitiatorBHS *)&bhs,NULL,NULL,0); + } // Follow up with data out PDUs up to the firstBurstLength bytes if... if(!session->initialR2T && // Initial R2T = No @@ -683,6 +710,7 @@ bool iSCSIVirtualHBA::ProcessTaskOnWorkloopThread(iSCSIVirtualHBA * owner, case kiSCSIPDUOpCodeR2T: owner->ProcessR2T(session,connection,(iSCSIPDUR2TBHS*)&bhs); break; + case kiSCSIPDUOpCodeReject: owner->ProcessReject(session,connection,(iSCSIPDURejectBHS*)&bhs); break; @@ -1061,7 +1089,7 @@ void iSCSIVirtualHBA::ProcessAsyncMsg(iSCSISession * session, // No support for proprietary vendor codes; do nothing case kiSCSIPDUAsyncMsgVendorCode: break; - + default: break; }; @@ -1162,7 +1190,7 @@ void iSCSIVirtualHBA::ProcessDataOutForTask(iSCSISession * session, } // Cleanup buffer - IOFree(data,connection->maxRecvDataSegmentLength); + IOFree(data,connection->maxSendDataSegmentLength); } /*! Process an incoming reject PDU. @@ -1386,6 +1414,9 @@ void iSCSIVirtualHBA::ReleaseSession(SID sessionId) ReleaseConnection(sessionId,connectionId); } + // Prevent others from accessing the session + sessionList[sessionId] = NULL; + // Free connection list and session object IOFree(theSession->connections,kMaxConnectionsPerSession*sizeof(iSCSIConnection*)); IOFree(theSession,sizeof(iSCSISession)); @@ -1403,7 +1434,6 @@ void iSCSIVirtualHBA::ReleaseSession(SID sessionId) break; } } - sessionList[sessionId] = NULL; } /*! Allocates a new iSCSI connection associated with the particular session. @@ -1587,6 +1617,9 @@ void iSCSIVirtualHBA::ReleaseConnection(SID sessionId, if(connection->taskQueue->isEnabled()) DeactivateConnection(sessionId,connectionId); + // Prevents other from trying to access this connection... + session->connections[connectionId] = NULL; + sock_close(connection->socket); GetWorkLoop()->removeEventSource(connection->dataRecvEventSource); @@ -1599,7 +1632,6 @@ void iSCSIVirtualHBA::ReleaseConnection(SID sessionId, connection->dataToTransfer = 0; IOFree(connection,sizeof(iSCSIConnection)); - session->connections[connectionId] = NULL; DBLog("iscsi: Released connection (sid: %d, cid: %d)\n",sessionId,connectionId); } diff --git a/Source/Kernel/iSCSIVirtualHBA.h b/Source/Kernel/iSCSIVirtualHBA.h index bd788d08..98fe6a04 100644 --- a/Source/Kernel/iSCSIVirtualHBA.h +++ b/Source/Kernel/iSCSIVirtualHBA.h @@ -1,8 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIVirtualHBA.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_VIRTUAL_HBA_H__ diff --git a/Source/User Tools/iSCSIAuth.h b/Source/User Tools/iSCSIAuth.h deleted file mode 100644 index c52a62d7..00000000 --- a/Source/User Tools/iSCSIAuth.h +++ /dev/null @@ -1,38 +0,0 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIAuth.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI authentication functions. This library - * depends on the user-space iSCSI PDU library and augments the - * session library by providing authentication for the target - * and the initiator. - */ - -#ifndef __ISCSI_AUTHMETHOD_H__ -#define __ISCSI_AUTHMETHOD_H__ - -#include -#include - -#include "iSCSITypes.h" -#include "iSCSIKernelInterfaceShared.h" - -/*! Authentication function defined in the authentication module - * (in the file iSCSIAuth.h). */ -errno_t iSCSIAuthNegotiate(iSCSITargetRef target, - iSCSIAuthRef initiatorAuth, - iSCSIAuthRef targetAuth, - SID sessionId, - CID connectionId, - enum iSCSILoginStatusCode * statusCode); - -/*! Authentication function defined in the authentication module - * (in the file iSCSIAuth.h). */ -errno_t iSCSIAuthInterrogate(iSCSITargetRef target, - SID sessionId, - CID connectionId, - enum iSCSIAuthMethods * authMethod, - enum iSCSILoginStatusCode * statusCode); - -#endif diff --git a/Source/User Tools/iSCSIDiscovery.h b/Source/User Tools/iSCSIDiscovery.h deleted file mode 100644 index 5a035dec..00000000 --- a/Source/User Tools/iSCSIDiscovery.h +++ /dev/null @@ -1,26 +0,0 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDiscovery.h - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. - * @brief Discovery functions for use by iscsid. - */ - - -#ifndef __ISCSI_DISCOVERY_H__ -#define __ISCSI_DISCOVERY_H__ - -#include -#include - -#include "iSCSISession.h" -#include "iSCSITypes.h" -#include "iSCSIPropertyList.h" - - -/*! Scans all iSCSI discovery portals for targets (SendTargets). Updates - * the iSCSI property list with information about targets and portals. */ -void iSCSIDiscoveryRunSendTargets(); - - -#endif /* defined(__ISCSI_DISCOVERY_H__) */ diff --git a/Source/User Tools/iSCSITest.c b/Source/User Tools/iSCSITest.c deleted file mode 100644 index 45b6e9a6..00000000 --- a/Source/User Tools/iSCSITest.c +++ /dev/null @@ -1,41 +0,0 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITest.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI session management functions. This library - * depends on the user-space iSCSI PDU library to login, logout - * and perform discovery functions on iSCSI target nodes. It - * also relies on the kernel layer for access to kext. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include - -#include "iSCSISession.h" -#include "iSCSIKernelInterface.h" -#include "iSCSITypes.h" -#include "iSCSIPropertyList.h" - -int main(int argc, const char * argv[]) { - - - - - return 0; -} diff --git a/Source/User/iSCSI Framework/Info.plist b/Source/User/iSCSI Framework/Info.plist new file mode 100644 index 00000000..d3de8eef --- /dev/null +++ b/Source/User/iSCSI Framework/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Source/User/iSCSI Framework/iSCSI.h b/Source/User/iSCSI Framework/iSCSI.h new file mode 100644 index 00000000..e4f4ad81 --- /dev/null +++ b/Source/User/iSCSI Framework/iSCSI.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +//! Project version number for iSCSI. +FOUNDATION_EXPORT double iSCSIVersionNumber; + +//! Project version string for iSCSI. +FOUNDATION_EXPORT const unsigned char iSCSIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import +#import "iSCSIUtils.h" +#import "iSCSIDA.h" +#import "iSCSIDaemonInterface.h" +#import "iSCSIIORegistry.h" +#import "iSCSIKeychain.h" +#import "iSCSIPreferences.h" +#import "iSCSIRFC3720Keys.h" +#import "iSCSITypes.h" +#import "iSCSITypesShared.h" +#import "iSCSIUtils.h" +#import "iSCSIAuthRIghts.h" \ No newline at end of file diff --git a/Source/User/iSCSI Framework/iSCSIAuthRights.c b/Source/User/iSCSI Framework/iSCSIAuthRights.c new file mode 100644 index 00000000..9b28f824 --- /dev/null +++ b/Source/User/iSCSI Framework/iSCSIAuthRights.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iSCSIAuthRights.h" + + +/*! Authorization right for logging in and out of targets. */ +const char kiSCSIAuthRightLogin[] = "com.github.iscsi-osx.iSCSIInitiator.login-logout"; + +/*! Authorization right for modifying initiator configuration (discovery, targets, etc). */ +const char kiSCSIAuthRightModify[] = "com.github.iscsi-osx.iSCSIInitiator.modify-config"; + +CFStringRef kRightPromptLogin = CFSTR("For logging into and out of iSCSI targets."); + +CFStringRef kRightPromptModify = CFSTR("For modifying initiator, discovery and target settings and adding and removing targets."); + + +/*! Creates all necessary rights if they are missing. + * @param authorization authorization used to create rights. */ +OSStatus iSCSIAuthRightsInitialize(AuthorizationRef authorization) +{ + OSStatus error = noErr; + + // Login and logout right does not exist, create it + if(AuthorizationRightGet(kiSCSIAuthRightLogin,NULL) != noErr) + AuthorizationRightSet(authorization,kiSCSIAuthRightLogin, + CFSTR(kAuthorizationRuleClassAllow),kRightPromptLogin, + NULL,NULL); + + if(AuthorizationRightGet(kiSCSIAuthRightModify,NULL) != noErr) + AuthorizationRightSet(authorization,kiSCSIAuthRightModify, + CFSTR(kAuthorizationRuleClassAllow),kRightPromptModify, + NULL,NULL); + + return error; +} + + +/*! Used to acquire a right. + * @param authorization the authorization to associated with the acquired right. + * @param authRight the right to acquire. + * @return an status code indicating the result of the operation. */ +OSStatus iSCSIAuthRightsAcquire(AuthorizationRef authorization,enum iSCSIAuthRights authRight) +{ + const char * rightName; + + switch(authRight) + { + case kiSCSIAuthLoginRight: + rightName = kiSCSIAuthRightLogin; + break; + case kiSCSIAuthModifyRight: + rightName = kiSCSIAuthRightModify; + break; + default: + return errAuthorizationCanceled; + } + + AuthorizationItem actionRight = { rightName, 0, 0, 0 }; + AuthorizationRights rights = { 1, &actionRight }; + + OSStatus error = AuthorizationCopyRights(authorization,&rights,NULL,kAuthorizationFlagExtendRights|kAuthorizationFlagInteractionAllowed,NULL); + + return error; +} diff --git a/Source/User/iSCSI Framework/iSCSIAuthRights.h b/Source/User/iSCSI Framework/iSCSIAuthRights.h new file mode 100644 index 00000000..53d9c416 --- /dev/null +++ b/Source/User/iSCSI Framework/iSCSIAuthRights.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ISCSI_AUTH_RIGHTS_H__ +#define __ISCSI_AUTH_RIGHTS_H__ + +#include +#include + +#include + +enum iSCSIAuthRights { + + /*! The right to login and logout. */ + kiSCSIAuthLoginRight, + + /*! The right to make modifications to the initiator, including + * modification of settings, addition/removal of targets, etc. */ + kiSCSIAuthModifyRight, + + /*! All authentication rights. */ + kiSCSIAuthAllRights +}; + +/*! Creates all necessary rights if they are missing. + * @param authorization authorization used to create rights. */ +OSStatus iSCSIAuthRightsInitialize(AuthorizationRef authorization); + +/*! Used to acquire a right. + * @param authorization the authorization to associated with the acquired right. + * @param authRight the right to acquire. + * @return an status code indicating the result of the operation. */ +OSStatus iSCSIAuthRightsAcquire(AuthorizationRef authorization,enum iSCSIAuthRights authRight); + + +#endif /* __ISCSI_AUTH_RIGHTS_H__ */ diff --git a/Source/User Tools/iSCSIDA.c b/Source/User/iSCSI Framework/iSCSIDA.c similarity index 78% rename from Source/User Tools/iSCSIDA.c rename to Source/User/iSCSI Framework/iSCSIDA.c index 47977522..aed94365 100644 --- a/Source/User Tools/iSCSIDA.c +++ b/Source/User/iSCSI Framework/iSCSIDA.c @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDA.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space management of iSCSI disks. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIDA.h" diff --git a/Source/User Tools/iSCSIDA.h b/Source/User/iSCSI Framework/iSCSIDA.h similarity index 53% rename from Source/User Tools/iSCSIDA.h rename to Source/User/iSCSI Framework/iSCSIDA.h index 9b042099..1624dff3 100644 --- a/Source/User Tools/iSCSIDA.h +++ b/Source/User/iSCSI Framework/iSCSIDA.h @@ -1,12 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDA.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space management of iSCSI disks. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #ifndef __ISCSI_DA_H__ #define __ISCSI_DA_H__ diff --git a/Source/User Tools/iSCSIDaemonInterface.c b/Source/User/iSCSI Framework/iSCSIDaemonInterface.c similarity index 68% rename from Source/User Tools/iSCSIDaemonInterface.c rename to Source/User/iSCSI Framework/iSCSIDaemonInterface.c index 5d8ef1a0..e3a6a580 100644 --- a/Source/User Tools/iSCSIDaemonInterface.c +++ b/Source/User/iSCSI Framework/iSCSIDaemonInterface.c @@ -1,13 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDaemonInterface.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Defines interface used by client applications to access - * the iSCSIDaemon +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #include "iSCSIDaemonInterface.h" #include "iSCSIDaemonInterfaceShared.h" @@ -69,13 +87,20 @@ const iSCSIDMsgUpdateDiscoveryCmd iSCSIDMsgUpdateDiscoveryCmdInit = { .funcCode = kiSCSIDUpdateDiscovery }; +const iSCSIDMsgPreferencesIOLockAndSyncCmd iSCSIDMsgPreferencesIOLockAndSyncCmdInit = { + .funcCode = kiSCSIDPreferencesIOLockAndSync +}; + +const iSCSIDMsgPreferencesIOUnlockAndSyncCmd iSCSIDMsgPreferencesIOUnlockAndSyncCmdInit = { + .funcCode = kiSCSIDPreferencesIOUnlockAndSync +}; iSCSIDaemonHandle iSCSIDaemonConnect() { iSCSIDaemonHandle handle = socket(PF_LOCAL,SOCK_STREAM,0); struct sockaddr_un address; address.sun_family = AF_LOCAL; - strcpy(address.sun_path,"/var/tmp/iscsid"); + strcpy(address.sun_path,"/var/run/iscsid"); // Do non-blocking connect int flags = 0; @@ -88,7 +113,7 @@ iSCSIDaemonHandle iSCSIDaemonConnect() // Set timeout for connect() struct timeval tv; memset(&tv,0,sizeof(tv)); - tv.tv_usec = kiSCSIDaemonConnectTimeoutMilliSec*1000; + tv.tv_usec = kiSCSIDaemonConnectTimeoutMilliSec*2000; fd_set fdset; FD_ZERO(&fdset); @@ -128,22 +153,25 @@ void iSCSIDaemonDisconnect(iSCSIDaemonHandle handle) * If an argument is supplied for portal, login occurs over the specified * portal. Otherwise, the daemon will attempt to login over all portals. * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyLogin * @param target specifies the target and connection parameters to use. * @param portal specifies the portal to use (use NULL for all portals). * @param statusCode iSCSI response code indicating operation status. * @return an error code indicating whether the operation was successful. */ errno_t iSCSIDaemonLogin(iSCSIDaemonHandle handle, + AuthorizationRef authorization, iSCSITargetRef target, iSCSIPortalRef portal, enum iSCSILoginStatusCode * statusCode) { - if(handle < 0 || !target || !statusCode) + if(handle < 0 || !target || !authorization || !statusCode) return EINVAL; CFDataRef targetData = iSCSITargetCreateData(target); CFDataRef portalData = NULL; iSCSIDMsgLoginCmd cmd = iSCSIDMsgLoginCmdInit; + cmd.authLength = kAuthorizationExternalFormLength; cmd.targetLength = (UInt32)CFDataGetLength(targetData); cmd.portalLength = 0; @@ -151,9 +179,18 @@ errno_t iSCSIDaemonLogin(iSCSIDaemonHandle handle, portalData = iSCSIPortalCreateData(portal); cmd.portalLength = (UInt32)CFDataGetLength(portalData); } + + AuthorizationExternalForm authExtForm; + AuthorizationMakeExternalForm(authorization,&authExtForm); + + CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + (UInt8*)&authExtForm.bytes, + kAuthorizationExternalFormLength, + kCFAllocatorDefault); errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, - targetData,portalData,NULL); + authData,targetData,portalData,NULL); + if(portal) CFRelease(portalData); CFRelease(targetData); @@ -176,23 +213,26 @@ errno_t iSCSIDaemonLogin(iSCSIDaemonHandle handle, } -/*! Logs out of the target or a specific portal, if specified. +/*! Closes the iSCSI connection and frees the session qualifier. * @param handle a handle to a daemon connection. - * @param target the target to logout. - * @param portal the portal to logout. If one is not specified, + * @param authorization an authorization for the right kiSCSIAuthModifyLogin + * @param target specifies the target and connection parameters to use. + * @param portal specifies the portal to use (use NULL for all portals). * @param statusCode iSCSI response code indicating operation status. */ errno_t iSCSIDaemonLogout(iSCSIDaemonHandle handle, + AuthorizationRef authorization, iSCSITargetRef target, iSCSIPortalRef portal, enum iSCSILogoutStatusCode * statusCode) { - if(handle < 0 || !target || !statusCode) + if(handle < 0 || !target || !authorization || !statusCode) return EINVAL; CFDataRef targetData = iSCSITargetCreateData(target); CFDataRef portalData = NULL; iSCSIDMsgLogoutCmd cmd = iSCSIDMsgLogoutCmdInit; + cmd.authLength = kAuthorizationExternalFormLength; cmd.targetLength = (UInt32)CFDataGetLength(targetData); cmd.portalLength = 0; @@ -200,9 +240,18 @@ errno_t iSCSIDaemonLogout(iSCSIDaemonHandle handle, portalData = iSCSIPortalCreateData(portal); cmd.portalLength = (UInt32)CFDataGetLength(portalData); } + + AuthorizationExternalForm authExtForm; + AuthorizationMakeExternalForm(authorization,&authExtForm); + + CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + (UInt8*)&authExtForm.bytes, + kAuthorizationExternalFormLength, + kCFAllocatorDefault); errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, - targetData,portalData,NULL); + authData,targetData,portalData,NULL); + if(portal) CFRelease(portalData); CFRelease(targetData); @@ -551,3 +600,109 @@ errno_t iSCSIDaemonUpdateDiscovery(iSCSIDaemonHandle handle) return 0; } +/*! Semaphore that allows a client exclusive accesss to the property list + * that contains iSCSI configuraiton parameters and targets. Forces the provided + * preferences object to synchronize with property list on the disk. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights + * @param preferences the preferences to be synchronized + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonPreferencesIOLockAndSync(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + iSCSIPreferencesRef preferences) +{ + // Validate inputs + if(handle < 0 || !authorization || !preferences) + return EINVAL; + + // Send in authorization and acquire lock + AuthorizationExternalForm authExtForm; + AuthorizationMakeExternalForm(authorization,&authExtForm); + + CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + (UInt8*)authExtForm.bytes, + kAuthorizationExternalFormLength, + kCFAllocatorDefault); + + iSCSIDMsgPreferencesIOLockAndSyncCmd cmd = iSCSIDMsgPreferencesIOLockAndSyncCmdInit; + cmd.authorizationLength = (UInt32)CFDataGetLength(authData); + + errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd,authData,NULL); + + if(error) + return error; + + iSCSIDMsgPreferencesIOLockAndSyncRsp rsp; + + if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EIO; + + if(rsp.funcCode != kiSCSIDPreferencesIOLockAndSync) + return EIO; + + if(rsp.errorCode == 0) { + // Force preferences to synchronize after obtaining lock + // (this ensures that the client has the most up-to-date preferences data) + iSCSIPreferencesUpdateWithAppValues(preferences); + } + + return rsp.errorCode; +} + +/*! Synchronizes cached preference changes to disk and releases the locked + * semaphore, allowing other clients to make changes. If the prefereneces + * parameter is NULL, then no changes are made to disk and the semaphore is + * unlocked. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights + * @param preferences the preferences to be synchronized + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonPreferencesIOUnlockAndSync(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + iSCSIPreferencesRef preferences) +{ + // Validate inputs + if(handle < 0 || !authorization) + return EINVAL; + + CFDataRef preferencesData = NULL; + + AuthorizationExternalForm authExtForm; + AuthorizationMakeExternalForm(authorization,&authExtForm); + + CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + (UInt8*)&authExtForm.bytes, + kAuthorizationExternalFormLength, + kCFAllocatorDefault); + + iSCSIDMsgPreferencesIOUnlockAndSyncCmd cmd = iSCSIDMsgPreferencesIOUnlockAndSyncCmdInit; + + if(preferences) { + preferencesData = iSCSIPreferencesCreateData(preferences); + cmd.preferencesLength = (UInt32)CFDataGetLength(preferencesData); + } + else + cmd.preferencesLength = 0; + + cmd.authorizationLength = cmd.authorizationLength = (UInt32)CFDataGetLength(authData); + + errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, + authData,preferencesData,NULL); + + if(preferencesData) + CFRelease(preferencesData); + + if(error) + return error; + + iSCSIDMsgPreferencesIOUnlockAndSyncRsp rsp; + + if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EIO; + + if(rsp.funcCode != kiSCSIDPreferencesIOUnlockAndSync) + return EIO; + + return rsp.errorCode; +} + diff --git a/Source/User Tools/iSCSIDaemonInterface.h b/Source/User/iSCSI Framework/iSCSIDaemonInterface.h similarity index 62% rename from Source/User Tools/iSCSIDaemonInterface.h rename to Source/User/iSCSI Framework/iSCSIDaemonInterface.h index 9ab73470..6e805e42 100644 --- a/Source/User Tools/iSCSIDaemonInterface.h +++ b/Source/User/iSCSI Framework/iSCSIDaemonInterface.h @@ -1,13 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDaemonInterface.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Defines interface used by client applications to access - * the iSCSIDaemon +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #ifndef __ISCSI_DAEMON_INTERFACE__ #define __ISCSI_DAEMON_INTERFACE__ @@ -23,6 +41,7 @@ #include #include "iSCSITypes.h" +#include "iSCSIPreferences.h" typedef int iSCSIDaemonHandle; @@ -38,20 +57,25 @@ void iSCSIDaemonDisconnect(iSCSIDaemonHandle handle); * If an argument is supplied for portal, login occurs over the specified * portal. Otherwise, the daemon will attempt to login over all portals. * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyLogin * @param target specifies the target and connection parameters to use. * @param portal specifies the portal to use (use NULL for all portals). * @param statusCode iSCSI response code indicating operation status. * @return an error code indicating whether the operation was successful. */ errno_t iSCSIDaemonLogin(iSCSIDaemonHandle handle, + AuthorizationRef authorization, iSCSITargetRef target, iSCSIPortalRef portal, enum iSCSILoginStatusCode * statusCode); /*! Closes the iSCSI connection and frees the session qualifier. * @param handle a handle to a daemon connection. - * @param sessionId the session to free. + * @param authorization an authorization for the right kiSCSIAuthModifyLogin + * @param target specifies the target and connection parameters to use. + * @param portal specifies the portal to use (use NULL for all portals). * @param statusCode iSCSI response code indicating operation status. */ errno_t iSCSIDaemonLogout(iSCSIDaemonHandle handle, + AuthorizationRef authorization, iSCSITargetRef target, iSCSIPortalRef portal, enum iSCSILogoutStatusCode * statusCode); @@ -119,8 +143,28 @@ CFDictionaryRef iSCSIDaemonCreateCFPropertiesForConnection(iSCSIDaemonHandle han * @return an error code indicating whether the operationg was successful. */ errno_t iSCSIDaemonUpdateDiscovery(iSCSIDaemonHandle handle); - - +/*! Semaphore that allows a client exclusive accesss to the property list + * that contains iSCSI configuraiton parameters and targets. Forces the provided + * preferences object to synchronize with property list on the disk. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights + * @param preferences the preferences to be synchronized + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonPreferencesIOLockAndSync(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + iSCSIPreferencesRef preferences); + +/*! Synchronizes cached preference changes to disk and releases the locked + * semaphore, allowing other clients to make changes. If the prefereneces + * parameter is NULL, then no changes are made to disk and the semaphore is + * unlocked. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights + * @param preferences the preferences to be synchronized + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonPreferencesIOUnlockAndSync(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + iSCSIPreferencesRef preferences); #endif /* defined(__ISCSI_DAEMON_INTERFACE__) */ diff --git a/Source/User Tools/iSCSIDaemonInterfaceShared.h b/Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h similarity index 80% rename from Source/User Tools/iSCSIDaemonInterfaceShared.h rename to Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h index aa6727db..5aa34e2f 100644 --- a/Source/User Tools/iSCSIDaemonInterfaceShared.h +++ b/Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h @@ -1,14 +1,32 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDaemonInterfaceShared.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Defines interface used by client applications to access - * the iSCSIDaemon. These definitions are shared between kernel - * and user space. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * Daemon commands and responses consist of a 24-byte header followed by + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Daemon commands and responses consist of a 24-byte header followed by * data. The first two bytes of the header indicate the command or response * type (these values match for commands and responses for the same function). * The type of data that follows the command or respond header depends on the @@ -102,9 +120,9 @@ typedef struct __iSCSIDMsgLoginCmd { const UInt16 funcCode; UInt16 reserved; - CFLength portalLength; + CFLength authLength; CFLength targetLength; - UInt32 reserved2; + CFLength portalLength; UInt32 reserved3; UInt32 reserved4; @@ -132,9 +150,9 @@ typedef struct __iSCSIDMsgLogoutCmd { const UInt16 funcCode; UInt16 reserved; - CFLength portalLength; + CFLength authLength; CFLength targetLength; - UInt32 reserved3; + CFLength portalLength; UInt32 reserved4; UInt32 reserved5; @@ -395,6 +413,67 @@ typedef struct __iSCSIDMsgUpdateDiscoveryRsp { } __attribute__((packed)) iSCSIDMsgUpdateDiscoveryRsp; +/*! Command IO lock and sync preferences. */ +typedef struct __iSCSIDMsgPreferencesIOLockAndSyncCmd { + + const UInt16 funcCode; + UInt16 reserved; + UInt32 reserved2; + UInt32 reserved3; + UInt32 reserved4; + UInt32 reserved5; + CFLength authorizationLength; + +} __attribute__((packed)) iSCSIDMsgPreferencesIOLockAndSyncCmd; + +/*! Default initialization IO lock and sync preferences command. */ +extern const iSCSIDMsgPreferencesIOLockAndSyncCmd iSCSIDMsgPreferencesIOLockAndSyncCmdInit; + +/*! Response to command IO lock and sync preferences. */ +typedef struct __iSCSIDMsgPreferencesIOLockAndSyncRsp { + + const UInt8 funcCode; + UInt16 reserved; + UInt32 errorCode; + UInt8 reserved2; + UInt32 reserved3; + UInt32 reserved4; + UInt32 reserved5; + UInt32 reserved6; + +} __attribute__((packed)) iSCSIDMsgPreferencesIOLockAndSyncRsp; + + +/*! Command IO unlock and sync preferences. */ +typedef struct __iSCSIDMsgPreferencesIOUnlockAndSyncCmd { + + const UInt16 funcCode; + UInt16 reserved; + UInt32 reserved2; + UInt32 reserved3; + UInt32 reserved4; + CFLength authorizationLength; + CFLength preferencesLength; + +} __attribute__((packed)) iSCSIDMsgPreferencesIOUnlockAndSyncCmd; + +/*! Default initialization IO unlock and sync preferences command. */ +extern const iSCSIDMsgPreferencesIOUnlockAndSyncCmd iSCSIDMsgPreferencesIOUnlockAndSyncCmdInit; + +/*! Response to command IO unlock and sync preferences. */ +typedef struct __iSCSIDMsgPreferencesIOUnlockAndSyncRsp { + + const UInt8 funcCode; + UInt16 reserved; + UInt32 errorCode; + UInt8 reserved2; + UInt32 reserved3; + UInt32 reserved4; + UInt32 reserved5; + UInt32 reserved6; + +} __attribute__((packed)) iSCSIDMsgPreferencesIOUnlockAndSyncRsp; + ////////////////////////////// DAEMON FUNCTIONS //////////////////////////////// enum iSCSIDFunctionCodes { @@ -440,6 +519,12 @@ enum iSCSIDFunctionCodes { /*! Shut down the daemon. */ kiSCSIDShutdownDaemon = 13, + + /*! Lock preferences mutex and synchronize provided preferences object. */ + kiSCSIDPreferencesIOLockAndSync = 14, + + /*! Unlock preferences mutex and update application values using preferences object. */ + kiSCSIDPreferencesIOUnlockAndSync = 15, /*! Invalid daemon command. */ kiSCSIDInvalidFunctionCode diff --git a/Source/User Tools/iSCSIIORegistry.c b/Source/User/iSCSI Framework/iSCSIIORegistry.c similarity index 88% rename from Source/User Tools/iSCSIIORegistry.c rename to Source/User/iSCSI Framework/iSCSIIORegistry.c index 013d488e..6a9f5f0a 100644 --- a/Source/User Tools/iSCSIIORegistry.c +++ b/Source/User/iSCSI Framework/iSCSIIORegistry.c @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIIORegistry.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space management of iSCSI I/O registry entries. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIIORegistry.h" diff --git a/Source/User Tools/iSCSIIORegistry.h b/Source/User/iSCSI Framework/iSCSIIORegistry.h similarity index 74% rename from Source/User Tools/iSCSIIORegistry.h rename to Source/User/iSCSI Framework/iSCSIIORegistry.h index e57e6748..a3f90417 100644 --- a/Source/User Tools/iSCSIIORegistry.h +++ b/Source/User/iSCSI Framework/iSCSIIORegistry.h @@ -1,17 +1,39 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIIORegistry.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space management of iSCSI I/O registry entries. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #ifndef __ISCSI_IOREGISTRY_H__ #define __ISCSI_IOREGISTRY_H__ #include #include +#include +#include +#include #define kIOPropertyiSCSIQualifiedNameKey "iSCSI Qualified Name" diff --git a/Source/User Tools/iSCSIKeychain.c b/Source/User/iSCSI Framework/iSCSIKeychain.c similarity index 82% rename from Source/User Tools/iSCSIKeychain.c rename to Source/User/iSCSI Framework/iSCSIKeychain.c index 3469a200..ddf50651 100644 --- a/Source/User Tools/iSCSIKeychain.c +++ b/Source/User/iSCSI Framework/iSCSIKeychain.c @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIKeychain.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Provides user-space library functions that wrap around the - * security keychain to provide iSCSI key maangement +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIKeychain.h" @@ -81,7 +100,7 @@ OSStatus iSCSIKeychainSetCHAPSecretForNode(CFStringRef nodeIQN, CFArrayRef trustedList; SecTrustedApplicationRef trustedApps[2]; SecTrustedApplicationCreateFromPath("/usr/local/bin/iscsictl",&trustedApps[0]); - SecTrustedApplicationCreateFromPath("/Library/PrivilegedHelperTools/iscsid",&trustedApps[1]); + SecTrustedApplicationCreateFromPath("/usr/local/libexec/iscsid",&trustedApps[1]); trustedList = CFArrayCreate(kCFAllocatorDefault,(const void **)trustedApps,2,&kCFTypeArrayCallBacks); diff --git a/Source/User Tools/iSCSIKeychain.h b/Source/User/iSCSI Framework/iSCSIKeychain.h similarity index 55% rename from Source/User Tools/iSCSIKeychain.h rename to Source/User/iSCSI Framework/iSCSIKeychain.h index 159f5f12..e3d6f3d7 100644 --- a/Source/User Tools/iSCSIKeychain.h +++ b/Source/User/iSCSI Framework/iSCSIKeychain.h @@ -1,13 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIKeychain.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Provides user-space library functions that wrap around the - * security keychain to provide iSCSI key maangement +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #include #include #include diff --git a/Source/User/iSCSI Framework/iSCSIPreferences.c b/Source/User/iSCSI Framework/iSCSIPreferences.c new file mode 100644 index 00000000..d1ed246f --- /dev/null +++ b/Source/User/iSCSI Framework/iSCSIPreferences.c @@ -0,0 +1,1365 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "iSCSIPreferences.h" + +/*! App ID. */ +CFStringRef kiSCSIPKAppId = CFSTR(CF_PREFERENCES_APP_ID); + +/*! Preference key name for iSCSI initiator dictionary. */ +CFStringRef kiSCSIPKInitiator = CFSTR("Initiator Node"); + +/*! Preference key name for iSCSI targets dictionary (holds all targets). */ +CFStringRef kiSCSIPKTargets = CFSTR("Target Nodes"); + +/*! Preference key name for iSCSI discovery dictionary. */ +CFStringRef kiSCSIPKDiscovery = CFSTR("Discovery"); + + + +/*! Preference key name for iSCSI portals dictionary (specific to each target). */ +CFStringRef kiSCSIPKPortals = CFSTR("Portals"); + +/*! Target alias. */ +CFStringRef kiSCSIPKTargetAlias = CFSTR("Alias"); + +/*! Preference key name for target configuration type. */ +CFStringRef kiSCSIPKTargetConfigType = CFSTR("Configuration Type"); + +/*! Preference key value for static target configuration. */ +CFStringRef kiSCSIPVTargetConfigTypeStatic = CFSTR("Static"); + +/*! Preference key value for discovery target configuration. */ +CFStringRef kiSCSIPVTargetConfigTypeDiscovery = CFSTR("SendTargets"); + +/*! Preference key name for auto-login of target. */ +CFStringRef kiSCSIPKAutoLogin = CFSTR("Automatic Login"); + +/*! Preference key name for error recovery level. */ +CFStringRef kiSCSIPKErrorRecoveryLevel = CFSTR("Error Recovery Level"); + +/*! Preference key name for maximum number of connections. */ +CFStringRef kiSCSIPKMaxConnections = CFSTR("Maximum Connections"); + +/*! Preference key name for data digest. */ +CFStringRef kiSCSIPKDataDigest = CFSTR("Data Digest"); + +/*! Preference key name for header digest. */ +CFStringRef kiSCSIPKHeaderDigest = CFSTR("Header Digest"); + +/*! Preference key value for digest. */ +CFStringRef kiSCSIPVDigestNone = CFSTR("None"); + +/*! Preference key value for digest. */ +CFStringRef kiSCSIPVDigestCRC32C = CFSTR("CRC32C"); + +/*! Preference key name for iSCSI authentication. */ +CFStringRef kiSCSIPKAuth = CFSTR("Authentication"); + +/*! Preference key value for no authentication. */ +CFStringRef kiSCSIPVAuthNone = CFSTR("None"); + +/*! Preference key value for CHAP authentication. */ +CFStringRef kiSCSIPVAuthCHAP = CFSTR("CHAP"); + +/*! Preference key name for iSCSI CHAP authentication name. */ +CFStringRef kiSCSIPKAuthCHAPName = CFSTR("CHAP Name"); + +/*! Preference key name for portal host interface key. */ +CFStringRef kiSCSIPKPortalHostInterface = CFSTR("Host Interface"); + +/*! Preference key name for portal host interface key. */ +CFStringRef kiSCSIPKPortalPort = CFSTR("Port"); + +/*! Preference key for array of targets associated with a discovery portal. */ +CFStringRef kiSCSIPKDiscoveryTargetsForPortal = CFSTR("Targets"); + + +/*! Preference key name for iSCSI initiator name. */ +CFStringRef kiSCSIPKInitiatorIQN = CFSTR("Name"); + +/*! Preference key name for iSCSI initiator alias. */ +CFStringRef kiSCSIPKInitiatorAlias = CFSTR("Alias"); + +/*! Default initiator alias to use. */ +CFStringRef kiSCSIPVDefaultInitiatorAlias = CFSTR("localhost"); + +/*! Default initiator IQN to use. */ +CFStringRef kiSCSIPVDefaultInitiatorIQN = CFSTR("iqn.2015-01.com.localhost:initiator"); + + +/*! Preference key name for iSCSI discovery portals key. */ +CFStringRef kiSCSIPKDiscoveryPortals = CFSTR("Portals"); + + +/*! Preference key name for iSCSI discovery enabled/disabled. */ +CFStringRef kiSCSIPKSendTargetsEnabled = CFSTR("SendTargets"); + +/*! Preference key name for iSCSI discovery interval. */ +CFStringRef kiSCSIPKDiscoveryInterval = CFSTR("Interval"); + +/*! Preference key naem for iSCSI discovery portal that manages target. */ +CFStringRef kiSCSIPKSendTargetsPortal = CFSTR("Managing Portal"); + + +/*! Retrieves a mutable dictionary for the specified key. + * @param key the name of the key, which can be either kiSCSIPKTargets, + * kiSCSIPKDiscovery, or kiSCSIPKInitiator. + * @return mutable dictionary with list of properties for the specified key. */ +CFMutableDictionaryRef iSCSIPreferencesCopyPropertyDict(CFStringRef kAppId,CFStringRef key) +{ + // Retrieve the desired property from preferences + CFDictionaryRef preferences = CFPreferencesCopyValue(key,kAppId, + kCFPreferencesAnyUser, + kCFPreferencesCurrentHost); + if(!preferences) + return NULL; + + // Create a deep copy to make the dictionary mutable + CFMutableDictionaryRef mutablePropertyList = (CFMutableDictionaryRef)CFPropertyListCreateDeepCopy( + kCFAllocatorDefault, + preferences, + kCFPropertyListMutableContainersAndLeaves); + + // Release original retrieved property + CFRelease(preferences); + return mutablePropertyList; +} + +/*! Creates a mutable dictionary for the targets key. + * @return a mutable dictionary for the targets key. */ +CFMutableDictionaryRef iSCSIPreferencesCreateTargetsDict() +{ + return CFDictionaryCreateMutable(kCFAllocatorDefault, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); +} + + +/*! Creates a mutable dictionary for the discovery key. + * @return a mutable dictionary for the discovery key. */ +CFMutableDictionaryRef iSCSIPreferencesCreateDiscoveryDict() +{ + CFMutableDictionaryRef discoveryDict = CFDictionaryCreateMutable( + kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + // Default scan interval (0 indicates never) + CFIndex interval = kiSCSIInitiator_DiscoveryInterval; + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberCFIndexType,&interval); + + CFDictionaryAddValue(discoveryDict,kiSCSIPKSendTargetsEnabled,kCFBooleanFalse); + CFDictionaryAddValue(discoveryDict,kiSCSIPKDiscoveryInterval,value); + + CFRelease(value); + + return discoveryDict; +} + +/*! Creates a mutable dictionary for the initiator key. + * @return a mutable dictionary for the initiator key. */ +CFMutableDictionaryRef iSCSIPreferencesCreateInitiatorDict() +{ + CFMutableDictionaryRef initiatorDict = CFDictionaryCreateMutable( + kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionaryAddValue(initiatorDict,kiSCSIPKAuthCHAPName,kiSCSIPVDefaultInitiatorAlias); + CFDictionaryAddValue(initiatorDict,kiSCSIPKAuth,kiSCSIPVAuthNone); + CFDictionaryAddValue(initiatorDict,kiSCSIPKInitiatorAlias,kiSCSIPVDefaultInitiatorAlias); + CFDictionaryAddValue(initiatorDict,kiSCSIPKInitiatorIQN,kiSCSIPVDefaultInitiatorIQN); + + return initiatorDict; +} + +CFMutableDictionaryRef iSCSIPreferencesCreateTargetDict() +{ + CFNumberRef maxConnections = CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&kRFC3720_MaxConnections); + CFNumberRef errorRecoveryLevel = CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&kRFC3720_ErrorRecoveryLevel); + + CFMutableDictionaryRef targetDict = CFDictionaryCreateMutable( + kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionaryAddValue(targetDict,kiSCSIPKAuthCHAPName,(void *)CFSTR("")); + CFDictionaryAddValue(targetDict,kiSCSIPKAuth,kiSCSIPVAuthNone); + CFDictionaryAddValue(targetDict,kiSCSIPKAutoLogin,kCFBooleanFalse); + CFDictionaryAddValue(targetDict,kiSCSIPKMaxConnections,maxConnections); + CFDictionaryAddValue(targetDict,kiSCSIPKErrorRecoveryLevel,errorRecoveryLevel); + CFDictionaryAddValue(targetDict,kiSCSIPKHeaderDigest,kiSCSIPVDigestNone); + CFDictionaryAddValue(targetDict,kiSCSIPKDataDigest,kiSCSIPVDigestNone); + + CFRelease(maxConnections); + CFRelease(errorRecoveryLevel); + + return targetDict; +} + +CFMutableDictionaryRef iSCSIPreferencesGetInitiatorDict(iSCSIPreferencesRef preferences,Boolean createIfMissing) +{ + CFMutableDictionaryRef initiatorDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKInitiator); + + if(createIfMissing && !initiatorDict) { + initiatorDict = iSCSIPreferencesCreateInitiatorDict(); + CFDictionarySetValue(preferences,kiSCSIPKInitiator,initiatorDict); + } + + return initiatorDict; +} + +CFMutableDictionaryRef iSCSIPreferencesGetDiscoveryDict(iSCSIPreferencesRef preferences,Boolean createIfMissing) +{ + CFMutableDictionaryRef discoveryDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKDiscovery); + + if(createIfMissing && !discoveryDict) { + discoveryDict = iSCSIPreferencesCreateDiscoveryDict(); + CFDictionarySetValue(preferences,kiSCSIPKDiscovery,discoveryDict); + } + + return discoveryDict; +} + +/*! Helper function. Retrieves the iSCSI discovery portals dictionary. */ +CFMutableDictionaryRef iSCSIPreferencesGetSendTargetsDiscoveryPortals(iSCSIPreferencesRef preferences,Boolean createIfMissing) +{ + // Get discovery dictionary + CFMutableDictionaryRef discoveryDict = iSCSIPreferencesGetDiscoveryDict(preferences,createIfMissing); + + if(discoveryDict) + { + if(createIfMissing && + CFDictionaryGetCountOfKey(discoveryDict,kiSCSIPKDiscoveryPortals) == 0) + { + CFMutableDictionaryRef discoveryPortalsDict = CFDictionaryCreateMutable( + kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue(discoveryDict, + kiSCSIPKDiscoveryPortals, + discoveryPortalsDict); + CFRelease(discoveryPortalsDict); + } + return (CFMutableDictionaryRef)CFDictionaryGetValue(discoveryDict,kiSCSIPKDiscoveryPortals); + } + return NULL; +} + +CFArrayRef iSCSIPreferencesGetDynamicTargetsForSendTargets(iSCSIPreferencesRef preferences, + CFStringRef portalAddress, + Boolean createIfMissing) +{ + CFArrayRef targetsList = NULL; + CFMutableDictionaryRef discoveryPortals = iSCSIPreferencesGetSendTargetsDiscoveryPortals(preferences,false); + + if(discoveryPortals && portalAddress) { + + CFMutableDictionaryRef portalDict = NULL; + if(CFDictionaryGetValueIfPresent(discoveryPortals,portalAddress,(void*)&portalDict)) { + if(!CFDictionaryGetValueIfPresent(portalDict,kiSCSIPKDiscoveryTargetsForPortal,(void*)&targetsList)) { + targetsList = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); + CFDictionarySetValue(portalDict,kiSCSIPKDiscoveryTargetsForPortal,targetsList); + CFRelease(targetsList); + } + } + } + return targetsList; +} + +CFMutableDictionaryRef iSCSIPreferencesGetTargets(iSCSIPreferencesRef preferences,Boolean createIfMissing) +{ + CFMutableDictionaryRef targetsDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKTargets); + + if(createIfMissing && !targetsDict) { + targetsDict = iSCSIPreferencesCreateTargetsDict(); + CFDictionarySetValue(preferences,kiSCSIPKTargets,targetsDict); + } + + return targetsDict; +} + + + +CFMutableDictionaryRef iSCSIPreferencesGetTargetDict(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + Boolean createIfMissing) +{ + // Get list of targets + CFMutableDictionaryRef targetsList = iSCSIPreferencesGetTargets(preferences,createIfMissing); + + if(targetsList) + { + if(createIfMissing && CFDictionaryGetCountOfKey(targetsList,targetIQN) == 0) + { + CFMutableDictionaryRef targetDict = iSCSIPreferencesCreateTargetDict(); + CFDictionarySetValue(targetsList,targetIQN,targetDict); + CFRelease(targetDict); + } + + return (CFMutableDictionaryRef)CFDictionaryGetValue(targetsList,targetIQN); + } + return NULL; +} + +CFMutableDictionaryRef iSCSIPreferencesGetPortalsList(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + Boolean createIfMissing) +{ + // Get the target information dictionary + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,createIfMissing); + + + if(targetDict) + { + if(createIfMissing && CFDictionaryGetCountOfKey(targetDict,kiSCSIPKPortals) == 0) + { + CFMutableDictionaryRef portalsList = CFDictionaryCreateMutable( + kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue(targetDict,kiSCSIPKPortals,portalsList); + CFRelease(portalsList); + } + return (CFMutableDictionaryRef)CFDictionaryGetValue(targetDict,kiSCSIPKPortals); + } + return NULL; +} + +/*! Sets the maximum number of connections for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param maxConnections the maximum number of connections. */ +void iSCSIPreferencesSetMaxConnectionsForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + UInt32 maxConnections) +{ + // Get the target information dictionary + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&maxConnections); + CFDictionarySetValue(targetDict,kiSCSIPKMaxConnections,value); +} + +/*! Sets the error recovery level to use for the target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param level the error recovery level. */ +void iSCSIPreferencesSetErrorRecoveryLevelForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSIErrorRecoveryLevels level) +{ + // Get the target information dictionary + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&level); + CFDictionarySetValue(targetDict,kiSCSIPKErrorRecoveryLevel,value); +} + +/*! Gets the maximum number of connections for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the maximum number of connections for the target. */ +UInt32 iSCSIPreferencesGetMaxConnectionsForTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + // Get the target information dictionary + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + CFNumberRef value = CFDictionaryGetValue(targetDict,kiSCSIPKMaxConnections); + + UInt32 maxConnections = kRFC3720_MaxConnections; + CFNumberGetValue(value,kCFNumberIntType,&maxConnections); + return maxConnections; +} + +/*! Gets the error recovery level to use for the target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the error recovery level. */ +enum iSCSIErrorRecoveryLevels iSCSIPreferencesGetErrorRecoveryLevelForTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + // Get the target information dictionary + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + CFNumberRef value = CFDictionaryGetValue(targetDict,kiSCSIPKErrorRecoveryLevel); + + enum iSCSIErrorRecoveryLevels errorRecoveryLevel = kRFC3720_ErrorRecoveryLevel; + CFNumberGetValue(value,kCFNumberIntType,&errorRecoveryLevel); + return errorRecoveryLevel; +} + +iSCSIPortalRef iSCSIPreferencesCopyPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef portalAddress) +{ + // Get list of portals for this target + CFMutableDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,false); + + iSCSIPortalRef portal = NULL; + + if(portalsList) { + CFMutableDictionaryRef portalDict = + (CFMutableDictionaryRef)CFDictionaryGetValue(portalsList, + portalAddress); + if(portalDict) + portal = iSCSIPortalCreateWithDictionary(portalDict); + } + return portal; +} + +iSCSITargetRef iSCSIPreferencesCopyTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + iSCSIMutableTargetRef target = NULL; + + if(iSCSIUtilsValidateIQN(targetIQN)) { + + CFMutableDictionaryRef targetsDict = iSCSIPreferencesGetTargets(preferences,false); + + if(targetsDict) { + if(CFDictionaryContainsKey(targetsDict,targetIQN)) { + target = iSCSITargetCreateMutable(); + iSCSITargetSetIQN(target,targetIQN); + } + } + } + + return target; +} + +enum iSCSIDigestTypes iSCSIPreferencesGetDataDigestForTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + // Get the dictionary containing information about the target + CFDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + enum iSCSIDigestTypes digestType = kiSCSIDigestInvalid; + + if(targetDict) { + CFStringRef digest = CFDictionaryGetValue(targetDict,kiSCSIPKDataDigest); + + if(digest) { + + if(CFStringCompare(digest,kiSCSIPVDigestNone,0) == kCFCompareEqualTo) + digestType = kiSCSIDigestNone; + else if(CFStringCompare(digest,kiSCSIPVDigestCRC32C,0) == kCFCompareEqualTo) + digestType = kiSCSIDigestCRC32C; + } + } + return digestType; +} + +void iSCSIPreferencesSetDataDigestForTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN,enum iSCSIDigestTypes digestType) +{ + // Get the dictionary containing information about the target + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + if(targetDict) + { + CFStringRef digest = NULL; + + switch(digestType) + { + case kiSCSIDigestNone: digest = kiSCSIPVDigestNone; break; + case kiSCSIDigestCRC32C: digest = kiSCSIPVDigestCRC32C; break; + case kiSCSIDigestInvalid: break; + }; + + if(digest) { + CFDictionarySetValue(targetDict,kiSCSIPKDataDigest,digest); + } + } +} + +enum iSCSIDigestTypes iSCSIPreferencesGetHeaderDigestForTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + // Get the dictionary containing information about the target + CFDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + enum iSCSIDigestTypes digestType = kiSCSIDigestInvalid; + + if(targetDict) { + CFStringRef digest = CFDictionaryGetValue(targetDict,kiSCSIPKHeaderDigest); + + if(digest) { + + if(CFStringCompare(digest,kiSCSIPVDigestNone,0) == kCFCompareEqualTo) + digestType = kiSCSIDigestNone; + else if(CFStringCompare(digest,kiSCSIPVDigestCRC32C,0) == kCFCompareEqualTo) + digestType = kiSCSIDigestCRC32C; + } + } + return digestType; +} + +void iSCSIPreferencesSetHeaderDigestForTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN,enum iSCSIDigestTypes digestType) +{ + // Get the dictionary containing information about the target + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + if(targetDict) + { + CFStringRef digest = NULL; + + switch(digestType) + { + case kiSCSIDigestNone: digest = kiSCSIPVDigestNone; break; + case kiSCSIDigestCRC32C: digest = kiSCSIPVDigestCRC32C; break; + case kiSCSIDigestInvalid: break; + }; + + if(digest) { + CFDictionarySetValue(targetDict,kiSCSIPKHeaderDigest,digest); + } + } +} + +/*! Sets authentication method to be used by initiator. */ +void iSCSIPreferencesSetInitiatorAuthenticationMethod(iSCSIPreferencesRef preferences,enum iSCSIAuthMethods authMethod) +{ + CFMutableDictionaryRef initiatorDict = iSCSIPreferencesGetInitiatorDict(preferences,true); + + if(authMethod == kiSCSIAuthMethodNone) + CFDictionarySetValue(initiatorDict,kiSCSIPKAuth,kiSCSIPVAuthNone); + else if(authMethod == kiSCSIAuthMethodCHAP) + CFDictionarySetValue(initiatorDict,kiSCSIPKAuth,kiSCSIPVAuthCHAP); +} + +/*! Gets the current authentication method used by the initiator. */ +enum iSCSIAuthMethods iSCSIPreferencesGetInitiatorAuthenticationMethod(iSCSIPreferencesRef preferences) +{ + CFMutableDictionaryRef initiatorDict = iSCSIPreferencesGetInitiatorDict(preferences,true); + CFStringRef auth = CFDictionaryGetValue(initiatorDict,kiSCSIPKAuth); + enum iSCSIAuthMethods authMethod = kiSCSIAuthMethodInvalid; + + if(CFStringCompare(auth,kiSCSIPVAuthNone,0) == kCFCompareEqualTo) + authMethod = kiSCSIAuthMethodNone; + else if(CFStringCompare(auth,kiSCSIPVAuthCHAP,0) == kCFCompareEqualTo) + authMethod = kiSCSIAuthMethodCHAP; + + return authMethod; +} + +/*! Sets the CHAP name associated with the initiator. */ +void iSCSIPreferencesSetInitiatorCHAPName(iSCSIPreferencesRef preferences,CFStringRef name) +{ + CFMutableDictionaryRef initiatorDict = iSCSIPreferencesGetInitiatorDict(preferences,true); + + // Change CHAP name in preferences + CFDictionarySetValue(initiatorDict,kiSCSIPKAuthCHAPName,name); +} + +/*! Copies the CHAP name associated with the initiator. */ +CFStringRef iSCSIPreferencesCopyInitiatorCHAPName(iSCSIPreferencesRef preferences) +{ + CFMutableDictionaryRef initiatorDict = iSCSIPreferencesGetInitiatorDict(preferences,true); + CFStringRef name = CFDictionaryGetValue(initiatorDict,kiSCSIPKAuthCHAPName); + return CFStringCreateCopy(kCFAllocatorDefault,name); +} + +/*! Sets the CHAP secret associated with the initiator. + * @return status indicating the result of the operation. */ +OSStatus iSCSIPreferencesSetInitiatorCHAPSecret(iSCSIPreferencesRef preferences,CFStringRef secret) +{ + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + + OSStatus status = iSCSIKeychainSetCHAPSecretForNode(initiatorIQN,secret); + CFRelease(initiatorIQN); + + return status; +} + +/*! Copies the CHAP secret associated with the initiator. */ +CFStringRef iSCSIPreferencesCopyInitiatorCHAPSecret(iSCSIPreferencesRef preferences) +{ + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + + CFStringRef secret = iSCSIKeychainCopyCHAPSecretForNode(initiatorIQN); + CFRelease(initiatorIQN); + return secret; +} + +/*! Gets whether a CHAP secret exists for the initiator. + * @return true if a CHAP secret exists for the initiator. */ +Boolean iSCSIPreferencesExistsInitiatorCHAPSecret(iSCSIPreferencesRef preferences) +{ + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + Boolean exists = iSCSIKeychainContainsCHAPSecretForNode(initiatorIQN); + CFRelease(initiatorIQN); + return exists; +} + +void iSCSIPreferencesSetPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + iSCSIPortalRef portal) +{ + // Get list of portals for this target (only if it exists, otherwise NULL) + CFMutableDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,false); + + if(portal && portalsList) { + CFDictionaryRef portalDict = iSCSIPortalCreateDictionary(portal); + CFStringRef portalAddress = iSCSIPortalGetAddress(portal); + CFDictionarySetValue(portalsList,portalAddress,portalDict); + CFRelease(portalDict); + } +} + +void iSCSIPreferencesRemovePortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef portalAddress) +{ + CFMutableDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,false); + + // Remove target if only one portal is left... + if(portalsList) { + if(CFDictionaryGetCount(portalsList) == 1) + iSCSIPreferencesRemoveTarget(preferences,targetIQN); + else { + CFDictionaryRemoveValue(portalsList,portalAddress); + } + } +} + +/*! Sets whether the target should be logged in during startup. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param autoLogin true to auto login, false otherwise. */ +void iSCSIPreferencesSetAutoLoginForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + Boolean autoLogin) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + + if(targetDict) { + if(autoLogin) + CFDictionarySetValue(targetDict,kiSCSIPKAutoLogin,kCFBooleanTrue); + else + CFDictionarySetValue(targetDict,kiSCSIPKAutoLogin,kCFBooleanFalse); + } +} + +/*! Gets whether the target should be logged in during startup. + * @param targetIQN the target iSCSI qualified name (IQN). */ +Boolean iSCSIPreferencesGetAutoLoginForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + Boolean autoLogin = false; + + if(targetDict) { + if(CFDictionaryGetValue(targetDict,kiSCSIPKAutoLogin) == kCFBooleanTrue) + autoLogin = true; + } + + return autoLogin; +} + +/*! Adds a target object with a specified portal. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portal the portal object to set. */ +void iSCSIPreferencesAddStaticTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + iSCSIPortalRef portal) +{ + // Only proceed if the target does not exist; otherwise do nothing + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { + + // Create list of target portals for a specific target (since the target + // does not exist it is created) + CFMutableDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,true); + + // Add portal to newly create list of portals for this target + CFDictionaryRef portalDict = iSCSIPortalCreateDictionary(portal); + CFStringRef portalAddress = iSCSIPortalGetAddress(portal); + CFDictionarySetValue(portalsList,portalAddress,portalDict); + CFRelease(portalDict); + + // Set target config + iSCSIPreferencesSetTargetConfigType(preferences,targetIQN,kiSCSITargetConfigStatic); + } +} + +/*! Adds a target object with a specified portal, and associates it with + * a particular SendTargets portal that manages the target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portal the portal object to set. + * @param sendTargetsPortal the discovery portal address with which to + * associate the managed target. */ +void iSCSIPreferencesAddDynamicTargetForSendTargets(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + iSCSIPortalRef portal, + CFStringRef sendTargetsPortal) +{ + // Only proceed if the target does not exist; otherwise do nothing + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { + + // Get target dictionary (since the target does not exist it is created) + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + CFDictionarySetValue(targetDict,kiSCSIPKSendTargetsPortal,sendTargetsPortal); + + // Create list of target portals for a specific target (since the target + // does not exist it is created) + CFMutableDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,true); + + // Add portal to newly create list of portals for this target + CFDictionaryRef portalDict = iSCSIPortalCreateDictionary(portal); + CFStringRef portalAddress = iSCSIPortalGetAddress(portal); + CFDictionarySetValue(portalsList,portalAddress,portalDict); + CFRelease(portalDict); + + // Set target config + iSCSIPreferencesSetTargetConfigType(preferences,targetIQN,kiSCSITargetConfigDynamicSendTargets); + } + + // Ensure target is associated with the specified iSCSI discovery portal + CFMutableArrayRef targetList = (CFMutableArrayRef)iSCSIPreferencesGetDynamicTargetsForSendTargets(preferences,sendTargetsPortal,true); + + CFIndex idx = 0, targetCount = CFArrayGetCount(targetList); + for(idx = 0; idx < targetCount; idx++) { + if(CFStringCompare(targetIQN,CFArrayGetValueAtIndex(targetList,idx),0) == kCFCompareEqualTo) + break; + } + + // Target was not associated with the discovery portal, add it + if(idx == targetCount) { + CFArrayAppendValue(targetList,targetIQN); + } +} + +void iSCSIPreferencesRemoveTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN) +{ + CFMutableDictionaryRef targetsList = iSCSIPreferencesGetTargets(preferences,false); + + if(targetsList) { + CFDictionaryRemoveValue(targetsList,targetIQN); + } + + // Remove CHAP secret if one exists + iSCSIKeychainDeleteCHAPSecretForNode(targetIQN); +} + +/*! Copies the initiator name from iSCSI preferences to a CFString object. + * @return the initiator name. */ +CFStringRef iSCSIPreferencesCopyInitiatorIQN(iSCSIPreferencesRef preferences) +{ + CFMutableDictionaryRef initiatorDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKInitiator); + + if(!initiatorDict) { + initiatorDict = iSCSIPreferencesCreateInitiatorDict(); + } + + // Lookup and copy the initiator name from the dictionary + CFStringRef initiatorIQN = CFStringCreateCopy( + kCFAllocatorDefault,CFDictionaryGetValue(initiatorDict,kiSCSIPKInitiatorIQN)); + + return initiatorIQN; +} + +/*! Sets the initiator name in iSCSI preferences. + * @param initiatorIQN the initiator name to set. */ +void iSCSIPreferencesSetInitiatorIQN(iSCSIPreferencesRef preferences,CFStringRef initiatorIQN) +{ + CFMutableDictionaryRef initiatorDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKInitiator); + + if(!initiatorDict) { + initiatorDict = iSCSIPreferencesCreateInitiatorDict(); + } + + // Update keychain if necessary + CFStringRef existingIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + + CFStringRef secret = iSCSIKeychainCopyCHAPSecretForNode(existingIQN); + + if(secret) { + iSCSIKeychainSetCHAPSecretForNode(initiatorIQN,secret); + CFRelease(secret); + iSCSIKeychainDeleteCHAPSecretForNode(existingIQN); + } + + // Update initiator name + CFDictionarySetValue(initiatorDict,kiSCSIPKInitiatorIQN,initiatorIQN); + CFRelease(existingIQN); +} + +/*! Copies the initiator alias from iSCSI preferences to a CFString object. + * @return the initiator alias. */ +CFStringRef iSCSIPreferencesCopyInitiatorAlias(iSCSIPreferencesRef preferences) +{ + CFMutableDictionaryRef initiatorDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKInitiator); + + if(!initiatorDict) { + initiatorDict = iSCSIPreferencesCreateInitiatorDict(); + } + + // Lookup and copy the initiator alias from the dictionary + CFStringRef initiatorAlias = CFStringCreateCopy( + kCFAllocatorDefault,CFDictionaryGetValue(initiatorDict,kiSCSIPKInitiatorAlias)); + + return initiatorAlias; +} + +/*! Sets the initiator alias in iSCSI preferences. + * @param initiatorAlias the initiator alias to set. */ +void iSCSIPreferencesSetInitiatorAlias(iSCSIPreferencesRef preferences,CFStringRef initiatorAlias) +{ + CFMutableDictionaryRef initiatorDict = (CFMutableDictionaryRef)CFDictionaryGetValue(preferences,kiSCSIPKInitiator); + + if(!initiatorDict) { + initiatorDict = iSCSIPreferencesCreateInitiatorDict(); + } + + // Update initiator alias + CFDictionarySetValue(initiatorDict,kiSCSIPKInitiatorAlias,initiatorAlias); +} + +/*! Gets whether a target is defined in preferences. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return true if the target exists, false otherwise. */ +Boolean iSCSIPreferencesContainsTarget(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + CFDictionaryRef targetsList = iSCSIPreferencesGetTargets(preferences,true); + return CFDictionaryContainsKey(targetsList,targetIQN); +} + +/*! Gets whether a portal is defined in preferences. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portalAddress the name of the portal. + * @return true if the portal exists, false otherwise. */ +Boolean iSCSIPreferencesContainsPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef portalAddress) +{ + CFDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,false); + return (portalsList && CFDictionaryContainsKey(portalsList,portalAddress)); +} + +/*! Gets whether a SendTargets discovery portal is defined in preferences. + * @param portalAddress the discovery portal address. + * @return true if the portal exists, false otherwise. */ +Boolean iSCSIPreferencesContainsPortalForSendTargetsDiscovery(iSCSIPreferencesRef preferences, + CFStringRef portalAddress) +{ + Boolean exists = false; + CFDictionaryRef discoveryPortals = iSCSIPreferencesGetSendTargetsDiscoveryPortals(preferences,false); + + if(discoveryPortals) + exists = CFDictionaryContainsKey(discoveryPortals,portalAddress); + + return exists; +} + +/*! Creates an array of target iSCSI qualified name (IQN)s + * defined in preferences. + * @return an array of target iSCSI qualified name (IQN)s. */ +CFArrayRef iSCSIPreferencesCreateArrayOfTargets(iSCSIPreferencesRef preferences) +{ + CFDictionaryRef targetsList = iSCSIPreferencesGetTargets(preferences,false); + + if(!targetsList) + return NULL; + + const CFIndex keyCount = CFDictionaryGetCount(targetsList); + + if(keyCount == 0) + return NULL; + + const void * keys[keyCount]; + CFDictionaryGetKeysAndValues(targetsList,keys,NULL); + + return CFArrayCreate(kCFAllocatorDefault,keys,keyCount,&kCFTypeArrayCallBacks); +} + +/*! Creates an array of iSCSI targets (IQNs) that were dynamically configured + * using SendTargets over a specific discovery portal. + * @param portalAddress the address of the discovery portal that corresponds + * to the dynamically configured discovery targets. + * @return an array of iSCSI targets (IQNs) that were discovered using + * SendTargets over the specified portal. */ +CFArrayRef iSCSIPreferencesCreateArrayOfDynamicTargetsForSendTargets(iSCSIPreferencesRef preferences,CFStringRef portalAddress) +{ + CFArrayRef targetsList = iSCSIPreferencesGetDynamicTargetsForSendTargets(preferences,portalAddress,false); + + // Create a copy to return + if(targetsList) + targetsList = CFArrayCreateCopy(kCFAllocatorDefault,targetsList); + + return targetsList; +} + +/*! Creates an array of portal names for a given target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return an array of portal names for the specified target. */ +CFArrayRef iSCSIPreferencesCreateArrayOfPortalsForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN) +{ + CFMutableDictionaryRef portalsList = iSCSIPreferencesGetPortalsList(preferences,targetIQN,false); + + if(!portalsList) + return NULL; + + const CFIndex keyCount = CFDictionaryGetCount(portalsList); + + if(keyCount == 0) + return NULL; + + const void * keys[keyCount]; + CFDictionaryGetKeysAndValues(portalsList,keys,NULL); + + return CFArrayCreate(kCFAllocatorDefault,keys,keyCount,&kCFTypeArrayCallBacks); +} + + +/*! Modifies the target IQN for the specified target. + * @param existingIQN the IQN of the existing target to modify. + * @param newIQN the new IQN to assign to the target. */ +void iSCSIPreferencesSetTargetIQN(iSCSIPreferencesRef preferences, + CFStringRef existingIQN, + CFStringRef newIQN) +{ + CFMutableDictionaryRef targetNodes = iSCSIPreferencesGetTargets(preferences,false); + CFMutableDictionaryRef target = iSCSIPreferencesGetTargetDict(preferences,existingIQN,false); + + if(target && targetNodes) + { + CFDictionarySetValue(targetNodes,newIQN,target); + CFDictionaryRemoveValue(targetNodes,existingIQN); + + // Rename keychain if required + if(iSCSIKeychainContainsCHAPSecretForNode(existingIQN)) { + CFStringRef secret = iSCSIKeychainCopyCHAPSecretForNode(existingIQN); + iSCSIKeychainSetCHAPSecretForNode(newIQN,secret); + CFRelease(secret); + + iSCSIKeychainDeleteCHAPSecretForNode(existingIQN); + } + } +} + +/*! Sets the alias for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param alias the alias to associate with the specified target. */ +void iSCSIPreferencesSetTargetAlias(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef alias) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + if(targetDict) + CFDictionarySetValue(targetDict,kiSCSIPKTargetAlias,alias); +} + +/*! Gets the alias for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the alias associated with the specified target. */ +CFStringRef iSCSIPreferencesGetTargetAlias(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + if(targetDict) + return CFDictionaryGetValue(targetDict,kiSCSIPKTargetAlias); + + return kiSCSIUnspecifiedTargetAlias; +} + +/*! Sets authentication method to be used by target. */ +void iSCSIPreferencesSetTargetAuthenticationMethod(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSIAuthMethods authMethod) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + + if(authMethod == kiSCSIAuthMethodNone) + CFDictionarySetValue(targetDict,kiSCSIPKAuth,kiSCSIPVAuthNone); + else if(authMethod == kiSCSIAuthMethodCHAP) + CFDictionarySetValue(targetDict,kiSCSIPKAuth,kiSCSIPVAuthCHAP); +} + +/*! Gets the current authentication method used by the target. */ +enum iSCSIAuthMethods iSCSIPreferencesGetTargetAuthenticationMethod(iSCSIPreferencesRef preferences, + CFStringRef targetIQN) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + CFStringRef auth = CFDictionaryGetValue(targetDict,kiSCSIPKAuth); + enum iSCSIAuthMethods authMethod = kiSCSIAuthMethodInvalid; + + if(CFStringCompare(auth,kiSCSIPVAuthNone,0) == kCFCompareEqualTo) + authMethod = kiSCSIAuthMethodNone; + else if(CFStringCompare(auth,kiSCSIPVAuthCHAP,0) == kCFCompareEqualTo) + authMethod = kiSCSIAuthMethodCHAP; + + return authMethod; +} + +/*! Sets target configuration type. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param configType the target configuration type. */ +void iSCSIPreferencesSetTargetConfigType(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSITargetConfigTypes configType) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + CFStringRef configTypeString = NULL; + + switch(configType) { + + case kiSCSITargetConfigStatic: + configTypeString = kiSCSIPVTargetConfigTypeStatic; break; + case kiSCSITargetConfigDynamicSendTargets: + configTypeString = kiSCSIPVTargetConfigTypeDiscovery; break; + case kiSCSITargetConfigInvalid: break; + }; + + if(configTypeString) { + // Change CHAP name in iSCSI preferences + CFDictionarySetValue(targetDict,kiSCSIPKTargetConfigType,configTypeString); + } +} + +/*! Gets target configuration type. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the target configuration type. */ +enum iSCSITargetConfigTypes iSCSIPreferencesGetTargetConfigType(iSCSIPreferencesRef preferences, + CFStringRef targetIQN) +{ + enum iSCSITargetConfigTypes configType = kiSCSITargetConfigInvalid; + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + if(targetDict) { + CFStringRef configTypeString = CFDictionaryGetValue(targetDict,kiSCSIPKTargetConfigType); + + // If target exists but configuration string doesn't, assume it is + // a static target and repair preferences + if(configTypeString == NULL) { + configType = kiSCSITargetConfigStatic; + CFDictionarySetValue(targetDict,kiSCSIPKTargetConfigType,kiSCSIPVTargetConfigTypeStatic); + } + else { + if(CFStringCompare(configTypeString,kiSCSIPVTargetConfigTypeStatic,0) == kCFCompareEqualTo) + configType = kiSCSITargetConfigStatic; + else if(CFStringCompare(configTypeString,kiSCSIPVTargetConfigTypeDiscovery,0) == kCFCompareEqualTo) + configType = kiSCSITargetConfigDynamicSendTargets; + } + } + return configType; +} + +/*! Gets the SendTargets discovery portal associated with the dynamic target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return address of the discovery portal that manages the target. */ +CFStringRef iSCSIPreferencesGetDiscoveryPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN) +{ + CFStringRef discoveryPortal = NULL; + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,false); + + if(targetDict) + discoveryPortal = CFDictionaryGetValue(targetDict,kiSCSIPKSendTargetsPortal); + + return discoveryPortal; +} + +/*! Sets the CHAP name associated with the target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param name the CHAP name associated with the target. */ +void iSCSIPreferencesSetTargetCHAPName(iSCSIPreferencesRef preferences,CFStringRef targetIQN,CFStringRef name) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + + // Change CHAP name in iSCSI preferences + CFDictionarySetValue(targetDict,kiSCSIPKAuthCHAPName,name); +} + +/*! Copies the CHAP name associated with the target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the CHAP name associated with the target. */ +CFStringRef iSCSIPreferencesCopyTargetCHAPName(iSCSIPreferencesRef preferences,CFStringRef targetIQN) +{ + CFMutableDictionaryRef targetDict = iSCSIPreferencesGetTargetDict(preferences,targetIQN,true); + CFStringRef name = CFDictionaryGetValue(targetDict,kiSCSIPKAuthCHAPName); + return CFStringCreateCopy(kCFAllocatorDefault,name); +} + +/*! Adds an iSCSI discovery portal to the list of discovery portals. + * @param portal the discovery portal to add. */ +void iSCSIPreferencesAddSendTargetsDiscoveryPortal(iSCSIPreferencesRef preferences,iSCSIPortalRef portal) +{ + CFMutableDictionaryRef discoveryPortals = iSCSIPreferencesGetSendTargetsDiscoveryPortals(preferences,true); + + if(portal && discoveryPortals) { + + CFStringRef portalAddress = iSCSIPortalGetAddress(portal); + + // Add portal if it doesn't exist + if(!CFDictionaryContainsKey(discoveryPortals,portalAddress)) { + + CFStringRef port = iSCSIPortalGetPort(portal); + CFStringRef interface = iSCSIPortalGetHostInterface(portal); + + CFMutableDictionaryRef portalDict = CFDictionaryCreateMutable( + kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionarySetValue(portalDict,kiSCSIPKPortalPort,port); + CFDictionarySetValue(portalDict,kiSCSIPKPortalHostInterface,interface); + + // Create an array to hold targets associated with this portal + CFMutableArrayRef targets = CFArrayCreateMutable( + kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); + + CFDictionarySetValue(portalDict,kiSCSIPKDiscoveryTargetsForPortal,targets); + + CFDictionarySetValue(discoveryPortals,portalAddress,portalDict); + CFRelease(targets); + CFRelease(portalDict); + } + } +} + +/*! Removes the specified iSCSI discovery portal. + * @param portal the discovery portal to remove. */ +void iSCSIPreferencesRemoveSendTargetsDiscoveryPortal(iSCSIPreferencesRef preferences,iSCSIPortalRef portal) +{ + CFMutableDictionaryRef discoveryPortals = iSCSIPreferencesGetSendTargetsDiscoveryPortals(preferences,false); + + if(discoveryPortals && portal) { + + CFStringRef portalAddress = iSCSIPortalGetAddress(portal); + + if(CFDictionaryContainsKey(discoveryPortals,portalAddress)) { + + // Remove all dynamic targets associated with this portal, if any... + CFArrayRef targetsList = iSCSIPreferencesGetDynamicTargetsForSendTargets(preferences,portalAddress,false); + + if(targetsList) { + CFIndex count = CFArrayGetCount(targetsList); + + for(CFIndex idx = 0; idx < count; idx++) + { + CFStringRef targetIQN = CFArrayGetValueAtIndex(targetsList,idx); + iSCSIPreferencesRemoveTarget(preferences,targetIQN); + } + } + + // Remove discovery portal from SendTargets dictionary + CFDictionaryRemoveValue(discoveryPortals,portalAddress); + } + } +} + +/*! Copies a portal object for the specified discovery portal. + * @param poralAddress the portal name (IPv4, IPv6 or DNS name). + * @return portal the portal object to set. */ +iSCSIPortalRef iSCSIPreferencesCopySendTargetsDiscoveryPortal(iSCSIPreferencesRef preferences,CFStringRef portalAddress) +{ + iSCSIMutablePortalRef portal = NULL; + + CFMutableDictionaryRef discoveryPortals = iSCSIPreferencesGetSendTargetsDiscoveryPortals(preferences,false); + + if(discoveryPortals) { + // The portal dictionary consists of portal information and associated + // targets; we want to extract portal information only + CFMutableDictionaryRef portalDict = NULL; + + if(CFDictionaryGetValueIfPresent(discoveryPortals,portalAddress,(void*)&portalDict)) + { + portal = iSCSIPortalCreateMutable(); + iSCSIPortalSetAddress(portal,portalAddress); + + CFStringRef port = kiSCSIDefaultPort; + CFStringRef interface = kiSCSIDefaultHostInterface; + + CFDictionaryGetValueIfPresent(portalDict,kiSCSIPKPortalPort,(void*)&port); + CFDictionaryGetValueIfPresent(portalDict,kiSCSIPKPortalHostInterface,(void*)&interface); + + // Set portal port and host interface + iSCSIPortalSetPort(portal,port); + iSCSIPortalSetHostInterface(portal,interface); + } + } + return portal; +} + +/*! Creates a list of SendTargets portals. Each element of the array is + * an iSCSI discovery portal address that can be used to retrieve the + * corresponding portal object by calling iSCSIPreferencesCopySendTargetsPortal(). */ +CFArrayRef iSCSIPreferencesCreateArrayOfPortalsForSendTargetsDiscovery(iSCSIPreferencesRef preferences) +{ + CFMutableDictionaryRef discoveryPortals = iSCSIPreferencesGetSendTargetsDiscoveryPortals(preferences,false); + + if(!discoveryPortals) + return NULL; + + const CFIndex keyCount = CFDictionaryGetCount(discoveryPortals); + + if(keyCount == 0) + return NULL; + + const void * keys[keyCount]; + CFDictionaryGetKeysAndValues(discoveryPortals,keys,NULL); + + return CFArrayCreate(kCFAllocatorDefault,keys,keyCount,&kCFTypeArrayCallBacks); +} + +/*! Sets SendTargets discovery to enabled or disabled. + * @param enable True to set send targets discovery enabled, false otherwise. */ +void iSCSIPreferencesSetSendTargetsDiscoveryEnable(iSCSIPreferencesRef preferences,Boolean enable) +{ + CFMutableDictionaryRef discoveryDict = iSCSIPreferencesGetDiscoveryDict(preferences,true); + + if(enable) + CFDictionarySetValue(discoveryDict,kiSCSIPKSendTargetsEnabled,kCFBooleanTrue); + else + CFDictionarySetValue(discoveryDict,kiSCSIPKSendTargetsEnabled,kCFBooleanFalse); +} + +/*! Gets whether SendTargets discovery is set ot disabled or enabled. + * @return True if send targets discovery is set to enabled, false otherwise. */ +Boolean iSCSIPreferencesGetSendTargetsDiscoveryEnable(iSCSIPreferencesRef preferences) +{ + CFMutableDictionaryRef discoveryDict = iSCSIPreferencesGetDiscoveryDict(preferences,true); + return CFBooleanGetValue(CFDictionaryGetValue(discoveryDict,kiSCSIPKSendTargetsEnabled)); +} + +/*! Sets SendTargets discovery interval. + * @param interval the discovery interval, in seconds. */ +void iSCSIPreferencesSetSendTargetsDiscoveryInterval(iSCSIPreferencesRef preferences,CFIndex interval) +{ + CFMutableDictionaryRef discoveryDict = iSCSIPreferencesGetDiscoveryDict(preferences,true); + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberCFIndexType,&interval); + CFDictionarySetValue(discoveryDict,kiSCSIPKDiscoveryInterval,value); +} + +/*! Gets SendTargets disocvery interval. + * @return the discovery interval, in seconds. */ +CFIndex iSCSIPreferencesGetSendTargetsDiscoveryInterval(iSCSIPreferencesRef preferences) +{ + CFIndex interval = 0; + CFMutableDictionaryRef discoveryDict = iSCSIPreferencesGetDiscoveryDict(preferences,true); + CFNumberRef value = CFDictionaryGetValue(discoveryDict,kiSCSIPKDiscoveryInterval); + CFNumberGetValue(value,kCFNumberCFIndexType,&interval); + return interval; +} + +/*! Resets iSCSI preferences, removing all defined targets and + * configuration parameters. */ +void iSCSIPreferencesReset(iSCSIPreferencesRef preferences) +{ + CFDictionaryRemoveAllValues(preferences); +} + +/*! Create a dictionary representation of the preferences object. + * @param preferences the iSCSI preferences object. + * @return a dictionary representation containing key-value pairs of preferences values. */ +CFDictionaryRef iSCSIPreferencesCreateDictionary(iSCSIPreferencesRef preferences) +{ + return (CFDictionaryRef)preferences; +} + +/*! Creates a binary representation of an iSCSI preferences object. + * @param data the data used to create the preferences object. + * @return a binary data representation of a preferences object. */ +CFDataRef iSCSIPreferencesCreateData(iSCSIPreferencesRef preferences) +{ + return CFPropertyListCreateData(kCFAllocatorDefault, + preferences, + kCFPropertyListBinaryFormat_v1_0,0,NULL); +} + +/*! Creates a new iSCSI preferences object. + * @return a new (empty) preferences object. */ +iSCSIPreferencesRef iSCSIPreferencesCreate() +{ + iSCSIPreferencesRef preferences = CFDictionaryCreateMutable(kCFAllocatorDefault,0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + return preferences; +} + +/*! Creates a new iSCSI preferences object from using values stored in system preferences. + * @param kAppId the application identification string. + * @return a new preferences object containing stored iSCSI preferences. */ +iSCSIPreferencesRef iSCSIPreferencesCreateFromAppValues() +{ + iSCSIPreferencesRef preferences = iSCSIPreferencesCreate(); + iSCSIPreferencesUpdateWithAppValues(preferences); + return preferences; +} + +/*! Creates a new iSCSI preferences object from a dictionary object from a dictionary representation. + * @param dict a dictionary used to construct an iSCSI preferences object. + * @return an iSCSI preferences object or NULL if object creation failed. */ +iSCSIPreferencesRef iSCSIPreferencesCreateWithDictionary(CFDictionaryRef dict) +{ + if(!dict) + return NULL; + + // Create a deep copy to make the dictionary mutable + CFMutableDictionaryRef mutablePropertyList = (CFMutableDictionaryRef)CFPropertyListCreateDeepCopy( + kCFAllocatorDefault,dict,kCFPropertyListMutableContainersAndLeaves); + + return mutablePropertyList; +} + +/*! Creates a new iSCSI preferences object from binary data. + * @param data the data used to create the preferences object. + * @return a new preferences object containing stored iSCSI preferences. */ +iSCSIPreferencesRef iSCSIPreferencesCreateWithData(CFDataRef data) +{ + CFPropertyListFormat format; + + iSCSIPreferencesRef preferences = CFPropertyListCreateWithData(kCFAllocatorDefault,data,0,&format,NULL); + + if(format == kCFPropertyListBinaryFormat_v1_0) + return preferences; + + CFRelease(preferences); + return NULL; +} + +/*! Updates the contents of the iSCSI preferences with application values. + * @param preferences an iSCSI preferences object. */ +void iSCSIPreferencesUpdateWithAppValues(iSCSIPreferencesRef preferences) +{ + // Refresh from preferences + CFDictionarySetValue(preferences,kiSCSIPKInitiator,iSCSIPreferencesCopyPropertyDict(kiSCSIPKAppId,kiSCSIPKInitiator)); + CFDictionarySetValue(preferences,kiSCSIPKTargets,iSCSIPreferencesCopyPropertyDict(kiSCSIPKAppId,kiSCSIPKTargets)); + CFDictionarySetValue(preferences,kiSCSIPKDiscovery,iSCSIPreferencesCopyPropertyDict(kiSCSIPKAppId,kiSCSIPKDiscovery)); +} + +/*! Synchronizes application values with those in the preferences object. + * @param preferences an iSCSI preferences object. + * @return true if application values were successfully updated. */ +Boolean iSCSIPreferencesSynchronzeAppValues(iSCSIPreferencesRef preferences) +{ + CFPreferencesSetMultiple((CFDictionaryRef)preferences,0,kiSCSIPKAppId,kCFPreferencesAnyUser,kCFPreferencesCurrentHost); + return CFPreferencesSynchronize(kiSCSIPKAppId,kCFPreferencesAnyUser,kCFPreferencesCurrentHost); +} + + + +/*! Releasese an iSCSI preferences object. + * @param preferences the preferences object to release. */ +void iSCSIPreferencesRelease(iSCSIPreferencesRef preferences) +{ + CFRelease(preferences); +} diff --git a/Source/User/iSCSI Framework/iSCSIPreferences.h b/Source/User/iSCSI Framework/iSCSIPreferences.h new file mode 100644 index 00000000..6ffaa26e --- /dev/null +++ b/Source/User/iSCSI Framework/iSCSIPreferences.h @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ISCSI_PREFERENCES_H__ +#define __ISCSI_PREFERENCES_H__ + +#include +#include +#include + +#include "iSCSIKeychain.h" +#include "iSCSITypes.h" +#include "iSCSIUtils.h" + +typedef CFMutableDictionaryRef iSCSIPreferencesRef; + + +/*! Copies the initiator name from preferences into a CFString object. + * @param preferences an iSCSI preferences object. + * @return the initiator name. */ +CFStringRef iSCSIPreferencesCopyInitiatorIQN(iSCSIPreferencesRef preferences); + +/*! Sets the initiator name in preferences. + * @param preferences an iSCSI preferences object. + * @param initiatorIQN the initiator name to set. */ +void iSCSIPreferencesSetInitiatorIQN(iSCSIPreferencesRef preferences, + CFStringRef initiatorIQN); + +/*! Copies the initiator alias from preferences into a CFString object. + * @param preferences an iSCSI preferences object. + * @return the initiator alias. */ +CFStringRef iSCSIPreferencesCopyInitiatorAlias(iSCSIPreferencesRef preferences); + +/*! Sets the initiator alias in preferences. + * @param preferences an iSCSI preferences object. + * @param initiatorAlias the initiator alias to set. */ +void iSCSIPreferencesSetInitiatorAlias(iSCSIPreferencesRef preferences, + CFStringRef initiatorAlias); + +/*! Sets authentication method to be used by initiator. + * @param preferences an iSCSI preferences object. */ +void iSCSIPreferencesSetInitiatorAuthenticationMethod(iSCSIPreferencesRef preferences, + enum iSCSIAuthMethods authMethod); + +/*! Gets the current authentication method used by the initiator. + * @param preferences an iSCSI preferences object. */ +enum iSCSIAuthMethods iSCSIPreferencesGetInitiatorAuthenticationMethod(iSCSIPreferencesRef preferences); + +/*! Sets the CHAP name associated with the initiator. + * @param preferences an iSCSI preferences object. */ +void iSCSIPreferencesSetInitiatorCHAPName(iSCSIPreferencesRef preferences, + CFStringRef name); + +/*! Copies the CHAP name associated with the initiator. + * @param preferences an iSCSI preferences object. */ +CFStringRef iSCSIPreferencesCopyInitiatorCHAPName(iSCSIPreferencesRef preferences); + +/*! Copies a target object for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return target the target object to copy. */ +iSCSITargetRef iSCSIPreferencesCopyTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Adds a target object with a specified portal. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portal the portal object to set. */ +void iSCSIPreferencesAddStaticTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + iSCSIPortalRef portal); + +/*! Adds a target object with a specified portal, and associates it with + * a particular SendTargets portal that manages the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portal the portal object to set. + * @param sendTargetsPortal the discovery portal address with which to + * associate the managed target. */ +void iSCSIPreferencesAddDynamicTargetForSendTargets(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + iSCSIPortalRef portal, + CFStringRef sendTargetsPortal); + +/*! Removes a target object. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). */ +void iSCSIPreferencesRemoveTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Copies a portal object for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param poralAddress the portal name (IPv4, IPv6 or DNS name). + * @return portal the portal object to set. */ +iSCSIPortalRef iSCSIPreferencesCopyPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef portalAddress); + +/*! Sets a portal object for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portal the portal object to set. */ +void iSCSIPreferencesSetPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + iSCSIPortalRef portal); + +/*! Removes a portal object for a particular target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portalAddress the portal name to remove. */ +void iSCSIPreferencesRemovePortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef portalAddress); + +/*! Sets whether the target should be logged in during startup. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param autoLogin true to auto login, false otherwise. */ +void iSCSIPreferencesSetAutoLoginForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + Boolean autoLogin); + +/*! Gets whether the target should be logged in during startup. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). */ +Boolean iSCSIPreferencesGetAutoLoginForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets the maximum number of connections for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param maxConnections the maximum number of connections. */ +void iSCSIPreferencesSetMaxConnectionsForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + UInt32 maxConnections); + +/*! Gets the maximum number of connections for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the maximum number of connections for the target. */ +UInt32 iSCSIPreferencesGetMaxConnectionsForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets the error recovery level to use for the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param level the error recovery level. */ +void iSCSIPreferencesSetErrorRecoveryLevelForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSIErrorRecoveryLevels level); + +/*! Gets the error recovery level to use for the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the error recovery level. */ +enum iSCSIErrorRecoveryLevels iSCSIPreferencesGetErrorRecoveryLevelForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Gets the data digest for the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the digest type. */ +enum iSCSIDigestTypes iSCSIPreferencesGetDataDigestForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets the data digest for the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param digestType the digest type. */ +void iSCSIPreferencesSetDataDigestForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSIDigestTypes digestType); + +/*! Gets the header digest for the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the digest type. */ +enum iSCSIDigestTypes iSCSIPreferencesGetHeaderDigestForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets the header digest for the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param digestType the digest type. */ +void iSCSIPreferencesSetHeaderDigestForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSIDigestTypes digestType); + +/*! Modifies the target IQN for the specified target. + * @param preferences an iSCSI preferences object. + * @param existingIQN the IQN of the existing target to modify. + * @param newIQN the new IQN to assign to the target. */ +void iSCSIPreferencesSetTargetIQN(iSCSIPreferencesRef preferences, + CFStringRef existingIQN, + CFStringRef newIQN); + +/*! Sets the alias for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param alias the alias to associate with the specified target. */ +void iSCSIPreferencesSetTargetAlias(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef alias); + +/*! Gets the alias for the specified target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the alias associated with the specified target. */ +CFStringRef iSCSIPreferencesGetTargetAlias(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets authentication method to be used by target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param authMethod the authentication method to use. */ +void iSCSIPreferencesSetTargetAuthenticationMethod(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSIAuthMethods authMethod); + +/*! Gets the current authentication method used by the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the iSCSI authentication method for the target. */ +enum iSCSIAuthMethods iSCSIPreferencesGetTargetAuthenticationMethod(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets target configuration type. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param configType the target configuration type. */ +void iSCSIPreferencesSetTargetConfigType(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + enum iSCSITargetConfigTypes configType); + +/*! Gets target configuration type. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the target configuration type. */ +enum iSCSITargetConfigTypes iSCSIPreferencesGetTargetConfigType(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Gets the SendTargets discovery portal associated with the dynamic target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return address of the discovery portal that manages the target. */ +CFStringRef iSCSIPreferencesGetDiscoveryPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Sets the CHAP name associated with the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param name the CHAP name associated with the target. */ +void iSCSIPreferencesSetTargetCHAPName(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef name); + +/*! Copies the CHAP name associated with the target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the CHAP name associated with the target. */ +CFStringRef iSCSIPreferencesCopyTargetCHAPName(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Gets whether a target is defined in preferences. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return true if the target exists, false otherwise. */ +Boolean iSCSIPreferencesContainsTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Gets whether a portal is defined in preferences. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param portalAddress the name of the portal. + * @return true if the portal exists, false otherwise. */ +Boolean iSCSIPreferencesContainsPortalForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, + CFStringRef portalAddress); + +/*! Gets whether a SendTargets discovery portal is defined in preferences. + * @param preferences an iSCSI preferences object. + * @param portalAddress the discovery portal address. + * @return true if the portal exists, false otherwise. */ +Boolean iSCSIPreferencesContainsPortalForSendTargetsDiscovery(iSCSIPreferencesRef preferences, + CFStringRef portalAddress); + +/*! Creates an array of target iSCSI qualified name (IQN)s defined in preferences. + * @param preferences an iSCSI preferences object. + * @return an array of target iSCSI qualified name (IQN)s. */ +CFArrayRef iSCSIPreferencesCreateArrayOfTargets(iSCSIPreferencesRef preferences); + +/*! Creates an array of iSCSI targets (IQNs) that were dynamically configured + * using SendTargets over a specific discovery portal. + * @param preferences an iSCSI preferences object. + * @param portalAddress the address of the discovery portal that corresponds + * to the dynamically configured discovery targets. + * @return an array of iSCSI targets (IQNs) that were discovered using + * SendTargets over the specified portal. */ +CFArrayRef iSCSIPreferencesCreateArrayOfDynamicTargetsForSendTargets(iSCSIPreferencesRef preferences, + CFStringRef portalAddress); + +/*! Creates an array of portal names (addresses) for a given target. + * @param preferences an iSCSI preferences object. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return an array of portal names for the specified target. */ +CFArrayRef iSCSIPreferencesCreateArrayOfPortalsForTarget(iSCSIPreferencesRef preferences, + CFStringRef targetIQN); + +/*! Adds an iSCSI discovery portal to the list of discovery portals. + * @param preferences an iSCSI preferences object. + * @param portal the discovery portal to add. */ +void iSCSIPreferencesAddSendTargetsDiscoveryPortal(iSCSIPreferencesRef preferences, + iSCSIPortalRef portal); + +/*! Removes the specified iSCSI discovery portal. + * @param preferences an iSCSI preferences object. + * @param portal the discovery portal to remove. */ +void iSCSIPreferencesRemoveSendTargetsDiscoveryPortal(iSCSIPreferencesRef preferences, + iSCSIPortalRef portal); + +/*! Copies a portal object for the specified discovery portal. + * @param preferences an iSCSI preferences object. + * @param portalAddress the portal name (IPv4, IPv6 or DNS name). + * @return portal the portal object to set. */ +iSCSIPortalRef iSCSIPreferencesCopySendTargetsDiscoveryPortal(iSCSIPreferencesRef preferences, + CFStringRef portalAddress); + +/*! Creates a list of SendTargets portals. Each element of the array is + * an iSCSI discovery portal address that can be used to retrieve the + * corresponding portal object by calling iSCSIPreferencesCopySendTargetsPortal(). + * @param preferences an iSCSI preferences object. */ +CFArrayRef iSCSIPreferencesCreateArrayOfPortalsForSendTargetsDiscovery(iSCSIPreferencesRef preferences); + +/*! Sets SendTargets discovery to enabled or disabled. + * @param preferences an iSCSI preferences object. + * @param enable True to set send targets discovery enabled, false otherwise. */ +void iSCSIPreferencesSetSendTargetsDiscoveryEnable(iSCSIPreferencesRef preferences, + Boolean enable); + +/*! Gets whether SendTargets discovery is set ot disabled or enabled. + * @param preferences an iSCSI preferences object. + * @return True if send targets discovery is set to enabled, false otherwise. */ +Boolean iSCSIPreferencesGetSendTargetsDiscoveryEnable(iSCSIPreferencesRef preferences); + +/*! Sets SendTargets discovery interval. + * @param preferences an iSCSI preferences object. + * @param interval the discovery interval, in seconds. */ +void iSCSIPreferencesSetSendTargetsDiscoveryInterval(iSCSIPreferencesRef preferences, + CFIndex interval); + +/*! Gets SendTargets disocvery interval. + * @param preferences an iSCSI preferences object. + * @return the discovery interval, in seconds. */ +CFIndex iSCSIPreferencesGetSendTargetsDiscoveryInterval(iSCSIPreferencesRef preferences); + +/*! Resets iSCSI preferences, removing all defined targets and + * configuration parameters. + * @param preferences an iSCSI preferences object. */ +void iSCSIPreferencesReset(iSCSIPreferencesRef preferences); + +/*! Create a dictionary representation of the preferences object. + * @param preferences an iSCSI preferences object. + * @return a dictionary representation containing key-value pairs of preferences values. */ +CFDictionaryRef iSCSIPreferencesCreateDictionary(iSCSIPreferencesRef preferences); + +/*! Creates a binary representation of an iSCSI preferences object. + * @param preferences an iSCSI preferences object. + * @return a binary data representation of a preferences object. */ +CFDataRef iSCSIPreferencesCreateData(iSCSIPreferencesRef preferences); + +/*! Creates a new iSCSI preferences object. + * @return a new (empty) preferences object. */ +iSCSIPreferencesRef iSCSIPreferencesCreate(); + +/*! Creates a new iSCSI preferences object from using values stored in system preferences. + * @param kAppId the application identification string. + * @return a new preferences object containing stored iSCSI preferences. */ +iSCSIPreferencesRef iSCSIPreferencesCreateFromAppValues(); + +/*! Creates a new iSCSI preferences object from a dictionary object from a dictionary representation. + * @param dict a dictionary used to construct an iSCSI preferences object. + * @return an iSCSI preferences object or NULL if object creation failed. */ +iSCSIPreferencesRef iSCSIPreferencesCreateWithDictionary(CFDictionaryRef dict); + +/*! Creates a new iSCSI preferences object from binary data. + * @param data the data used to create the preferences object. + * @return a new preferences object containing stored iSCSI preferences. */ +iSCSIPreferencesRef iSCSIPreferencesCreateWithData(CFDataRef data); + +/*! Updates the contents of the iSCSI preferences with application values. + * @param preferences an iSCSI preferences object. */ +void iSCSIPreferencesUpdateWithAppValues(iSCSIPreferencesRef preferences); + +/*! Synchronizes application values with those in the preferences object. + * @param preferences an iSCSI preferences object. + * @return true if application values were successfully updated. */ +Boolean iSCSIPreferencesSynchronzeAppValues(iSCSIPreferencesRef preferences); + + +/*! Releasese an iSCSI preferences object. + * @param preferences an iSCSI preferences object. */ +void iSCSIPreferencesRelease(iSCSIPreferencesRef preferences); + + +#endif diff --git a/Source/User Tools/iSCSIPropertyList.c b/Source/User/iSCSI Framework/iSCSIPropertyList.c similarity index 95% rename from Source/User Tools/iSCSIPropertyList.c rename to Source/User/iSCSI Framework/iSCSIPropertyList.c index 82c0fede..4c1831aa 100644 --- a/Source/User Tools/iSCSIPropertyList.c +++ b/Source/User/iSCSI Framework/iSCSIPropertyList.c @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIPropertyList.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Provides user-space library functions to read and write - * daemon configuration property list +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIPropertyList.h" @@ -47,6 +66,9 @@ CFStringRef kiSCSIPKDiscovery = CFSTR("Discovery"); /*! Preference key name for iSCSI portals dictionary (specific to each target). */ CFStringRef kiSCSIPKPortals = CFSTR("Portals"); +/*! Target alias. */ +CFStringRef kiSCSIPKTargetAlias = CFSTR("Alias"); + /*! Preference key name for target configuration type. */ CFStringRef kiSCSIPKTargetConfigType = CFSTR("Configuration Type"); @@ -286,7 +308,6 @@ CFArrayRef iSCSIPLGetDynamicTargetsForSendTargets(CFStringRef portalAddress, return targetsList; } - CFMutableDictionaryRef iSCSIPLGetTargets(Boolean createIfMissing) { if(createIfMissing && !targetsCache) @@ -755,7 +776,7 @@ CFStringRef iSCSIPLCopyInitiatorIQN() { if(!initiatorCache) { initiatorCache = iSCSIPLCreateInitiatorDict(); - initiatorNodeCacheModified = true; +// initiatorNodeCacheModified = true; } // Lookup and copy the initiator name from the dictionary @@ -796,7 +817,7 @@ CFStringRef iSCSIPLCopyInitiatorAlias() { if(!initiatorCache) { initiatorCache = iSCSIPLCreateInitiatorDict(); - initiatorNodeCacheModified = true; +// initiatorNodeCacheModified = true; } // Lookup and copy the initiator alias from the dictionary @@ -946,6 +967,30 @@ void iSCSIPLSetTargetIQN(CFStringRef existingIQN,CFStringRef newIQN) } } +/*! Sets the alias for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param alias the alias to associate with the specified target. */ +void iSCSIPLSetTargetAlias(CFStringRef targetIQN,CFStringRef alias) +{ + CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,false); + + if(targetDict) + CFDictionarySetValue(targetDict,kiSCSIPKTargetAlias,alias); +} + +/*! Gets the alias for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the alias associated with the specified target. */ +CFStringRef iSCSIPLGetTargetAlias(CFStringRef targetIQN) +{ + CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,false); + + if(targetDict) + return CFDictionaryGetValue(targetDict,kiSCSIPKTargetAlias); + + return kiSCSIUnspecifiedTargetAlias; +} + /*! Sets authentication method to be used by target. */ void iSCSIPLSetTargetAuthenticationMethod(CFStringRef targetIQN, enum iSCSIAuthMethods authMethod) diff --git a/Source/User Tools/iSCSIPropertyList.h b/Source/User/iSCSI Framework/iSCSIPropertyList.h similarity index 87% rename from Source/User Tools/iSCSIPropertyList.h rename to Source/User/iSCSI Framework/iSCSIPropertyList.h index 0ca1cc86..918fe02a 100644 --- a/Source/User Tools/iSCSIPropertyList.h +++ b/Source/User/iSCSI Framework/iSCSIPropertyList.h @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIPropertyList.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Provides user-space library functions to read and write - * daemon configuration property list +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_PROPERTY_LIST_H__ @@ -155,6 +174,16 @@ void iSCSIPLSetHeaderDigestForTarget(CFStringRef targetIQN, * @param newIQN the new IQN to assign to the target. */ void iSCSIPLSetTargetIQN(CFStringRef existingIQN,CFStringRef newIQN); +/*! Sets the alias for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @param alias the alias to associate with the specified target. */ +void iSCSIPLSetTargetAlias(CFStringRef targetIQN,CFStringRef alias); + +/*! Gets the alias for the specified target. + * @param targetIQN the target iSCSI qualified name (IQN). + * @return the alias associated with the specified target. */ +CFStringRef iSCSIPLGetTargetAlias(CFStringRef targetIQN); + /*! Sets authentication method to be used by target. * @param targetIQN the target iSCSI qualified name (IQN). * @param authMethod the authentication method to use. */ diff --git a/Source/User Tools/iSCSIRFC3720Keys.h b/Source/User/iSCSI Framework/iSCSIRFC3720Keys.h similarity index 75% rename from Source/User Tools/iSCSIRFC3720Keys.h rename to Source/User/iSCSI Framework/iSCSIRFC3720Keys.h index 5052a3b4..203db8ed 100644 --- a/Source/User Tools/iSCSIRFC3720Keys.h +++ b/Source/User/iSCSI Framework/iSCSIRFC3720Keys.h @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIRFC3720Keys.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Keys and values defined in RFC3720 +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_RFC3720_KEYS_H__ diff --git a/Source/User Tools/iSCSITypes.c b/Source/User/iSCSI Framework/iSCSITypes.c similarity index 91% rename from Source/User Tools/iSCSITypes.c rename to Source/User/iSCSI Framework/iSCSITypes.c index b7cfbf77..9cd445d8 100644 --- a/Source/User Tools/iSCSITypes.c +++ b/Source/User/iSCSI Framework/iSCSITypes.c @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITypes.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief iSCSI data types used in user space. All of the data types - * defined here are based on Core Foundation (CF) data types. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSITypes.h" @@ -129,6 +148,7 @@ iSCSISessionConfigRef iSCSITargetCreateWithData(CFDataRef data) /*! iSCSI target records are dictionaries with keys with string values * that specify the target name and other parameters. */ CFStringRef kiSCSITargetIQNKey = CFSTR("Target Name"); +CFStringRef kiSCSITargetAliasKey = CFSTR("Target Alias"); /*! Convenience function. Creates a new iSCSITargetRef with the above keys. */ iSCSIMutableTargetRef iSCSITargetCreateMutable() @@ -136,9 +156,18 @@ iSCSIMutableTargetRef iSCSITargetCreateMutable() iSCSIMutableTargetRef target = CFDictionaryCreateMutable(kCFAllocatorDefault,5,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(target,kiSCSITargetIQNKey,kiSCSIUnspecifiedTargetIQN); + CFDictionarySetValue(target,kiSCSITargetAliasKey,kiSCSIUnspecifiedTargetAlias); return target; } +/*! Createa a new mutable iSCSITarget object. + * @param target an exsiting target object. + * @param a mutable target object. */ +iSCSIMutableTargetRef iSCSITargetCreateMutableCopy(iSCSITargetRef target) +{ + return CFDictionaryCreateMutableCopy(kCFAllocatorDefault,0,(CFDictionaryRef)target); +} + /*! Gets the name associated with the iSCSI target. */ CFStringRef iSCSITargetGetIQN(iSCSITargetRef target) { @@ -146,13 +175,29 @@ CFStringRef iSCSITargetGetIQN(iSCSITargetRef target) } /*! Sets the name associated with the iSCSI target. */ -void iSCSITargetSetIQN(iSCSIMutableTargetRef target,CFStringRef name) +void iSCSITargetSetIQN(iSCSIMutableTargetRef target,CFStringRef IQN) +{ + // Ignore blanks + if(CFStringCompare(IQN,CFSTR(""),0) == kCFCompareEqualTo) + return; + + CFDictionarySetValue(target,kiSCSITargetIQNKey,IQN); +} + +/*! Gets the alias associated with the iSCSI target. */ +CFStringRef iSCSITargetGetAlias(iSCSIMutableTargetRef target) +{ + return CFDictionaryGetValue(target,kiSCSITargetAliasKey); +} + +/*! Sets the alias associated with the iSCSI target. */ +void iSCSITargetSetAlias(iSCSIMutableTargetRef target,CFStringRef alias) { // Ignore blanks - if(CFStringCompare(name,CFSTR(""),0) == kCFCompareEqualTo) + if(CFStringCompare(alias,CFSTR(""),0) == kCFCompareEqualTo) return; - CFDictionarySetValue(target,kiSCSITargetIQNKey,name); + CFDictionarySetValue(target,kiSCSITargetAliasKey,alias); } /*! Releases memory associated with iSCSI targets. */ @@ -540,7 +585,7 @@ iSCSIMutableSessionConfigRef iSCSISessionConfigCreateMutable() } /*! Creates a mutable session configuration object from an existing one. */ -iSCSIMutableSessionConfigRef iSCSISessionConfigCreateMutableWithExisting(iSCSISessionConfigRef config) +iSCSIMutableSessionConfigRef iSCSISessionConfigCreateMutableCopy(iSCSISessionConfigRef config) { return (iSCSIMutableSessionConfigRef)CFPropertyListCreateDeepCopy( kCFAllocatorDefault,config,kCFPropertyListMutableContainersAndLeaves); @@ -673,7 +718,7 @@ iSCSIMutableConnectionConfigRef iSCSIConnectionConfigCreateMutable() } /*! Creates a mutable connection configuration object from an existing one. */ -iSCSIMutableConnectionConfigRef iSCSIConnectionConfigCreateMutableWithExisting(iSCSIConnectionConfigRef config) +iSCSIMutableConnectionConfigRef iSCSIConnectionConfigCreateMutableCopy(iSCSIConnectionConfigRef config) { return (iSCSIMutableConnectionConfigRef)CFPropertyListCreateDeepCopy( kCFAllocatorDefault,config,kCFPropertyListMutableContainersAndLeaves); diff --git a/Source/User Tools/iSCSITypes.h b/Source/User/iSCSI Framework/iSCSITypes.h similarity index 89% rename from Source/User Tools/iSCSITypes.h rename to Source/User/iSCSI Framework/iSCSITypes.h index 24015575..8daa0168 100644 --- a/Source/User Tools/iSCSITypes.h +++ b/Source/User/iSCSI Framework/iSCSITypes.h @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITypes.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief iSCSI data types used in user space. All of the data types - * defined here are based on Core Foundation (CF) data types. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_TYPES_H__ @@ -24,6 +43,11 @@ static CFStringRef kiSCSIDefaultPort = CFSTR("3260"); * been specified. */ static CFStringRef kiSCSIUnspecifiedTargetIQN = CFSTR(""); +/*! The value for the target alias in an iSCSITarget when the alias has not + * been specified. */ +static CFStringRef kiSCSIUnspecifiedTargetAlias = CFSTR(""); + + typedef CFMutableDictionaryRef iSCSIMutablePortalRef; typedef CFDictionaryRef iSCSIPortalRef; @@ -38,7 +62,7 @@ typedef CFDictionaryRef iSCSIAuthRef; typedef CFDictionaryRef iSCSITargetAuthRef; typedef CFMutableDictionaryRef iSCSIMutableTargetAuthRef; -/*! Initiator authenticaiton object. */ +/*! Initiator authentication object. */ typedef CFDictionaryRef iSCSIInitiatorAuthRef; typedef CFMutableDictionaryRef iSCSIMutableInitiatorAuthRef; @@ -56,6 +80,10 @@ typedef CFMutableDictionaryRef iSCSIMutableSessionConfigRef; typedef CFDictionaryRef iSCSIConnectionConfigRef; typedef CFMutableDictionaryRef iSCSIMutableConnectionConfigRef; +#define kiSCSITypeArrayCallbacks kCFTypeArrayCallBacks +#define kiSCSITypeDictionaryKeyCallbacks kCFTypeDictionaryKeyCallBacks +#define kiSCSITypeDictionaryValueCallbacks kCFTypeDictionaryValueCallBacks + /*! Error recovery levels. */ enum iSCSIErrorRecoveryLevels { @@ -260,19 +288,20 @@ CFDictionaryRef iSCSIPortalCreateDictionary(iSCSIPortalRef portal); * @return data representing the portal or NULL if the portal is invalid. */ CFDataRef iSCSIPortalCreateData(iSCSIPortalRef portal); - - - - /*! Creates a new target object from an external data representation. - * @param data data used to construct an iSCSI target object. - * @return an iSCSI target object or NULL if object creation failed */ + * @param data data used to construct an iSCSI target object. + * @return an iSCSI target object or NULL if object creation failed */ iSCSITargetRef iSCSITargetCreateWithData(CFDataRef data); /*! Creates a new iSCSITarget object with empty target parameters. * @return an iSCSI target object. */ iSCSIMutableTargetRef iSCSITargetCreateMutable(); +/*! Createa a new mutable iSCSITarget object. + * @param target an exsiting target object. + * @param a mutable target object. */ +iSCSIMutableTargetRef iSCSITargetCreateMutableCopy(iSCSITargetRef target); + /*! Gets the name associated with the iSCSI target. * @param target the iSCSI target object. * @return the target name or kiSCSITargetUnspecified if one was not set. */ @@ -281,13 +310,18 @@ CFStringRef iSCSITargetGetIQN(iSCSITargetRef target); /*! Sets the name associated with the iSCSI target. This function has no * effect if the specified target name is blank. * @param target the target object. - * @param name the name to set. */ -void iSCSITargetSetIQN(iSCSIMutableTargetRef target,CFStringRef name); + * @param IQN the name to set. */ +void iSCSITargetSetIQN(iSCSIMutableTargetRef target,CFStringRef IQN); + +/*! Gets the alias associated with the iSCSI target. + * @param target the target object. + * @return the alias associated with the target. */ +CFStringRef iSCSITargetGetAlias(iSCSIMutableTargetRef target); -/*! Gets the nickname associated with the iSCSI target. +/*! Sets the alias associated with the iSCSI target. * @param target the target object. - * @return the nickname associated with the target. */ -CFStringRef iSCSITargetGetNickName(iSCSIMutableTargetRef target); + * @param alias the alias associated with the target. */ +void iSCSITargetSetAlias(iSCSIMutableTargetRef target,CFStringRef alias); /*! Releases memory associated with an iSCSI target object. * @param target the iSCSI target object. */ @@ -453,7 +487,7 @@ iSCSISessionConfigRef iSCSISessionConfigCreateWithData(CFDataRef data); iSCSIMutableSessionConfigRef iSCSISessionConfigCreateMutable(); /*! Creates a mutable session configuration object from an existing one. */ -iSCSIMutableSessionConfigRef iSCSISessionConfigCreateMutableWithExisting(iSCSISessionConfigRef config); +iSCSIMutableSessionConfigRef iSCSISessionConfigCreateMutableCopy(iSCSISessionConfigRef config); /*! Gets the error recovery level associated with a session. */ enum iSCSIErrorRecoveryLevels iSCSISessionConfigGetErrorRecoveryLevel(iSCSISessionConfigRef config); @@ -513,7 +547,7 @@ iSCSIConnectionConfigRef iSCSIConnectionConfigCreateWithData(CFDataRef data); iSCSIMutableConnectionConfigRef iSCSIConnectionConfigCreateMutable(); /*! Creates a mutable connection configuration object from an existing one. */ -iSCSIMutableConnectionConfigRef iSCSIConnectionConfigCreateMutableWithExisting(iSCSIConnectionConfigRef config); +iSCSIMutableConnectionConfigRef iSCSIConnectionConfigCreateMutableCopy(iSCSIConnectionConfigRef config); /*! Gets whether a header digest is enabled in the config object. * @param config the iSCSI config object. diff --git a/Source/User Tools/iSCSITypesShared.h b/Source/User/iSCSI Framework/iSCSITypesShared.h similarity index 66% rename from Source/User Tools/iSCSITypesShared.h rename to Source/User/iSCSI Framework/iSCSITypesShared.h index 0bfdc66a..dc1ebb5a 100644 --- a/Source/User Tools/iSCSITypesShared.h +++ b/Source/User/iSCSI Framework/iSCSITypesShared.h @@ -1,15 +1,38 @@ -/*! - * @author Nareg Sinenian - * @file iSCSITypesShared.h - * @date January 6, 2015 - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief iSCSI data types shared between user space and kernel space. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_TYPES_SHARED_H__ #define __ISCSI_TYPES_SHARED_H__ +#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_8 +typedef int errno_t; +#endif + /*! Session identifier. */ typedef UInt16 SID; diff --git a/Source/User Tools/iSCSIUtils.c b/Source/User/iSCSI Framework/iSCSIUtils.c similarity index 78% rename from Source/User Tools/iSCSIUtils.c rename to Source/User/iSCSI Framework/iSCSIUtils.c index 7406669e..d132d386 100644 --- a/Source/User Tools/iSCSIUtils.c +++ b/Source/User/iSCSI Framework/iSCSIUtils.c @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIUtils.h - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI utility functions. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIUtils.h" @@ -22,9 +42,9 @@ static int PORT_MAX = (1 << sizeof(in_port_t)*8) -1; Boolean iSCSIUtilsValidateIQN(CFStringRef IQN) { // IEEE regular expression for matching IQN name - const char pattern[] = "^iqn\.[0-9]\{4\}-[0-9]\{2\}\.[[:alnum:]]\{3\}\." - "[-A-Za-z0-9.]\{1,255\}:[-A-Za-z0-9.]\{1,255\}" - "|^eui\.[[:xdigit:]]\{16\}$"; + const char pattern[] = "^iqn[.][0-9]{4}-[0-9]{2}[.][[:alnum:]]{1,}[.]" + "[-A-Za-z0-9.]{1,255}:[-A-Za-z0-9.]{1,255}" + "|^eui[.][[:xdigit:]]{16}$"; Boolean validName = false; regex_t preg; @@ -57,11 +77,11 @@ Boolean iSCSIUtilsValidatePort(CFStringRef port) CFArrayRef iSCSIUtilsCreateArrayByParsingPortalParts(CFStringRef portal) { // Regular expressions to match valid IPv4, IPv6 and DNS portal strings - const char IPv4Pattern[] = "^((((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|([0-9])?[0-9])[.])\{3\}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|([0-9])?[0-9]))(:([0-9]\{1,5\}))?)$"; + const char IPv4Pattern[] = "^((((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|([0-9])?[0-9])[.]){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|([0-9])?[0-9]))(:([0-9]{1,5}))?)$"; - const char IPv6Pattern[] = "^([[]?(([A-Fa-f0-9]\{0,4\}:)\{1,7\}[A-Fa-f0-9]\{0,4\})([\]]:([0-9]\{1,5\})?)?)$"; + const char IPv6Pattern[] = "^([[]?(([A-Fa-f0-9]{0,4}:){1,7}[A-Fa-f0-9]{0,4})([]]:([0-9]{1,5})?)?)$"; - const char DNSPattern[] = "^((([A-Za-z0-9]\{1,63\}[.])\{1,3\}[A-Za-z0-9]\{1,63\})(:([0-9]\{1,5\}))?)$"; + const char DNSPattern[] = "^((([A-Za-z0-9]{1,63}[.]){1,3}[A-Za-z0-9]{1,63})(:([0-9]{1,5}))?)$"; // Array of patterns to iterate, the indices of the matches that // correspond to the hostname, port and the maximum number of matches diff --git a/Source/User Tools/iSCSIUtils.h b/Source/User/iSCSI Framework/iSCSIUtils.h similarity index 54% rename from Source/User Tools/iSCSIUtils.h rename to Source/User/iSCSI Framework/iSCSIUtils.h index 772812cd..2d1ed776 100644 --- a/Source/User Tools/iSCSIUtils.h +++ b/Source/User/iSCSI Framework/iSCSIUtils.h @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIUtils.h - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI utility functions. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_UTILS_H__ diff --git a/Source/User Tools/iSCSICtl.m b/Source/User/iscsictl/iSCSICtl.m similarity index 74% rename from Source/User Tools/iSCSICtl.m rename to Source/User/iscsictl/iSCSICtl.m index f48dc256..2ca90c4a 100644 --- a/Source/User Tools/iSCSICtl.m +++ b/Source/User/iscsictl/iSCSICtl.m @@ -1,9 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSICtl.m - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI management utility. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include @@ -13,11 +33,16 @@ #include "iSCSITypes.h" #include "iSCSIRFC3720Keys.h" -#include "iSCSIPropertyList.h" +#include "iSCSIPreferences.h" #include "iSCSIDaemonInterface.h" #include "iSCSIDA.h" #include "iSCSIIORegistry.h" #include "iSCSIUtils.h" +#include "iSCSIAuthRIghts.h" + +#include +#include + /*! Modes of operation for this utility. */ enum iSCSICtlCmds { @@ -40,12 +65,6 @@ /*! Logout (target). */ kiSCSICtlCmdLogout, - /*! Probe (target). */ - kiSCSICtlCmdProbe, - - /*! Reset. */ - kiSCSICtlCmdReset, - /*! Invalid mode of operation. */ kiSCSICtlCmdInvalid }; @@ -79,7 +98,6 @@ kiSCSICtlSubCmdInvalid }; - /*! Target command-line option. */ CFStringRef kOptKeyTarget = CFSTR("target"); @@ -171,7 +189,6 @@ * particular iSCSI target object in the system's IO registry. */ errno_t displayTargetDeviceTree(io_object_t); - enum iSCSICtlCmds iSCSICtlGetCmdFromArguments(CFArrayRef arguments) { enum iSCSICtlCmds cmd = kiSCSICtlCmdInvalid; @@ -183,8 +200,6 @@ enum iSCSICtlCmds iSCSICtlGetCmdFromArguments(CFArrayRef arguments) CFDictionarySetValue(modesDict,CFSTR("list") ,(const void *)kiSCSICtlCmdList); CFDictionarySetValue(modesDict,CFSTR("login"),(const void *)kiSCSICtlCmdLogin); CFDictionarySetValue(modesDict,CFSTR("logout"),(const void *)kiSCSICtlCmdLogout); - CFDictionarySetValue(modesDict,CFSTR("probe"),(const void *)kiSCSICtlCmdProbe); - CFDictionarySetValue(modesDict,CFSTR("reset"),(const void *)kiSCSICtlCmdReset); // If a mode was supplied (first argument after executable name) if(CFArrayGetCount(arguments) > 1) { @@ -330,11 +345,6 @@ void iSCSICtlDisplayErrorCode(errno_t errorCode) CFRelease(error); } -void iSCSICtlDisplayPermissionsError() -{ - iSCSICtlDisplayError(CFSTR("Permission denied")); -} - void iSCSICtlDisplayUsage() { iSCSICtlDisplayString(CFSTR("Usage: iscsictl add target , [-interface ]\n" @@ -521,32 +531,6 @@ void iSCSICtlDisplayLoginStatus(enum iSCSILoginStatusCode statusCode, } } - -/*! Helper function used to display login status. - * @param statusCode the status code indicating the login result. - * @param target the target - * @param portal the portal used to logon to the target. */ -void iSCSICtlDisplayProbeTargetLoginStatus(enum iSCSILoginStatusCode statusCode, - iSCSITargetRef target, - iSCSIPortalRef portal, - enum iSCSIAuthMethods authMethod) -{ - CFStringRef probeStatus = NULL; - - switch(authMethod) - { - case kiSCSIAuthMethodCHAP: probeStatus = CFSTR("Target requires CHAP authentication\n"); break; - case kiSCSIAuthMethodNone: probeStatus = CFSTR("Target does not require authentication\n"); break; - case kiSCSIAuthMethodInvalid: - default: - probeStatus = CFSTR("Target requires an unsupported authentication method\n"); break; - }; - - iSCSICtlDisplayString(probeStatus); - CFRelease(probeStatus); -} - - CFStringRef iSCSICtlGetStringForLogoutStatus(enum iSCSILogoutStatusCode statusCode) { switch(statusCode) @@ -722,7 +706,7 @@ errno_t iSCSICtlModifyPortalFromOptions(CFDictionaryRef options, return 0; } -errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { if(handle < 0 || !options) return EINVAL; @@ -730,6 +714,7 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) errno_t error = 0; iSCSITargetRef target = NULL; CFStringRef targetIQN = NULL; + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); // Create target object from user input (may be null if user didn't specify) if(!(target = iSCSICtlCreateTargetFromOptions(options))) @@ -737,13 +722,10 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) if(!error) { - // Synchronize the database with the property list on disk - iSCSIPLSynchronize(); - // Verify that the target exists in the property list targetIQN = iSCSITargetGetIQN(target); - if(!iSCSIPLContainsTarget(targetIQN)) { + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { iSCSICtlDisplayString(CFSTR("The specified target does not exist\n")); error = EINVAL; } @@ -778,7 +760,7 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) // Ensure portal was not malformed if((portal = iSCSICtlCreatePortalFromOptions(options))) { - if(iSCSIPLContainsPortalForTarget(targetIQN,iSCSIPortalGetAddress(portal))) + if(iSCSIPreferencesContainsPortalForTarget(preferences,targetIQN,iSCSIPortalGetAddress(portal))) { // The user may have specified only the portal address, so // get the portal from the property list to get port & interface @@ -786,14 +768,14 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) kCFAllocatorDefault,iSCSIPortalGetAddress(portal)); iSCSIPortalRelease(portal); - portal = iSCSIPLCopyPortalForTarget(targetIQN,portalAddress); + portal = iSCSIPreferencesCopyPortalForTarget(preferences,targetIQN,portalAddress); CFRelease(portalAddress); if(iSCSIDaemonIsPortalActive(handle,target,portal)) iSCSICtlDisplayString(CFSTR("The specified target has an active " "session over the specified portal\n")); else { - error = iSCSIDaemonLogin(handle,target,portal,&statusCode); + error = iSCSIDaemonLogin(handle,authorization,target,portal,&statusCode); if(!error) { if(activeConnections == 0) @@ -810,7 +792,7 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) } } else if(!error) { - error = iSCSIDaemonLogin(handle,target,NULL,&statusCode); + error = iSCSIDaemonLogin(handle,authorization,target,NULL,&statusCode); if(!error) iSCSICtlDisplayLoginStatus(statusCode,target,NULL); @@ -818,11 +800,14 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,CFDictionaryRef options) iSCSICtlDisplayErrorCode(error); } - iSCSITargetRelease(target); + if(target) + iSCSITargetRelease(target); + + iSCSIPreferencesRelease(preferences); return error; } -errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { if(handle < 0 || !options) return EINVAL; @@ -859,7 +844,7 @@ errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,CFDictionaryRef options) if(!error) { enum iSCSILogoutStatusCode statusCode; - error = iSCSIDaemonLogout(handle, target, portal, &statusCode); + error = iSCSIDaemonLogout(handle,authorization,target,portal,&statusCode); if(!error) iSCSICtlDisplayLogoutStatus(statusCode,target,NULL); @@ -882,46 +867,65 @@ errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,CFDictionaryRef options) * @param handle a handle to the iSCSI daemon. * @param options the command-line options. * @return an error code indicating the result of the operation. */ -errno_t iSCSICtlAddTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlAddTarget(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { - errno_t error = EINVAL; // default error result - if (handle && options) { - iSCSITargetRef target = iSCSICtlCreateTargetFromOptions(options); - iSCSIPortalRef portal = NULL; + if(handle < 0 || !authorization || !options) + return EINVAL; + + errno_t error = 0; + iSCSITargetRef target = NULL; + iSCSIPortalRef portal = NULL; + iSCSIPreferencesRef preferences = NULL; + + if(!(target = iSCSICtlCreateTargetFromOptions(options))) + error = EINVAL; + + if(!error && !(portal = iSCSICtlCreatePortalFromOptions(options))) + error = EINVAL; + + + preferences = iSCSIPreferencesCreateFromAppValues(); + + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + + if (!error) { - if(target) - portal = iSCSICtlCreatePortalFromOptions(options); + // If portal and target both exist then do nothing, otherwise + // add target and or portal with user-specified options + CFStringRef targetIQN = iSCSITargetGetIQN(target); - if (target && portal) { - // Synchronize the database with the property list on disk - iSCSIPLSynchronize(); - - // If portal and target both exist then do nothing, otherwise - // add target and or portal with user-specified options - CFStringRef targetIQN = iSCSITargetGetIQN(target); - - if(!iSCSIPLContainsTarget(targetIQN)) { - iSCSIPLAddStaticTarget(targetIQN,portal); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("The specified target has been added\n")); - } - else if(!iSCSIPLContainsPortalForTarget(targetIQN,iSCSIPortalGetAddress(portal))) { - iSCSIPLSetPortalForTarget(targetIQN,portal); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("The specified portal has been added\n")); - } - else { - iSCSICtlDisplayString(CFSTR("The specified target and portal already exist\n")); - } - iSCSIPortalRelease(portal); + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); + iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { + iSCSIPreferencesAddStaticTarget(preferences,targetIQN,portal); + iSCSICtlDisplayString(CFSTR("The specified target has been added\n")); + } + else if(!iSCSIPreferencesContainsPortalForTarget(preferences,targetIQN,iSCSIPortalGetAddress(portal))) { + iSCSIPreferencesSetPortalForTarget(preferences,targetIQN,portal); + iSCSICtlDisplayString(CFSTR("The specified portal has been added\n")); + } + else { + iSCSICtlDisplayString(CFSTR("The specified target and portal already exist\n")); + error = EEXIST; } - if(target) - iSCSITargetRelease(target); } + + if(!error) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + + + if(target) + iSCSITargetRelease(target); + + if(portal) + iSCSIPortalRelease(portal); + return error; } @@ -930,102 +934,113 @@ errno_t iSCSICtlAddTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) * specific portal is specific then that portal is removed. * @param handle handle to the iSCSI daemon. * @param options the command-line options dictionary. */ -errno_t iSCSICtlRemoveTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlRemoveTarget(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { if(handle < 0 || !options) return EINVAL; + errno_t error = 0; iSCSITargetRef target = NULL; iSCSIPortalRef portal = NULL; - errno_t error = 0; + iSCSIPreferencesRef preferences = NULL; + CFStringRef targetIQN = NULL; if(!(target = iSCSICtlCreateTargetFromOptions(options))) - return EINVAL; - - CFStringRef targetIQN = iSCSITargetGetIQN(target); + error = EINVAL; + else + targetIQN = iSCSITargetGetIQN(target); - // Synchronize the database with the property list on disk - iSCSIPLSynchronize(); + if(!error && iSCSICtlIsPortalSpecified(options)) + if(!(portal = iSCSICtlCreatePortalFromOptions(options))) + error = EINVAL; - // Verify that the target exists in the property list - if(!iSCSIPLContainsTarget(targetIQN)) { - iSCSICtlDisplayString(CFSTR("The specified target does not exist\n")); - error = EINVAL; - } - - // Verify that the target is not a dynamic target managed by iSCSI - // discovery - if(iSCSIPLGetTargetConfigType(targetIQN) == kiSCSITargetConfigDynamicSendTargets) { - iSCSICtlDisplayString(CFSTR("The target is configured using iSCSI discovery. " - "Remove the discovery portal to remove the target\n")); - error = EINVAL; - } - - // If a portal was specified, verify that it is valid. - if(!error && iSCSICtlIsPortalSpecified(options)) { - if(!(portal = iSCSICtlCreatePortalFromOptions(options))) { + preferences = iSCSIPreferencesCreateFromAppValues(); + + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + + if(!error) { + + // Verify that the target exists in the property list + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { + iSCSICtlDisplayString(CFSTR("The specified target does not exist\n")); + error = EINVAL; + } + + // Verify that the target is not a dynamic target managed by iSCSI + // discovery + if(!error && iSCSIPreferencesGetTargetConfigType(preferences,targetIQN) == kiSCSITargetConfigDynamicSendTargets) { + iSCSICtlDisplayString(CFSTR("The target is configured using iSCSI discovery. " + "Remove the discovery portal to remove the target\n")); error = EINVAL; } - } - // Verify that portal exists in property list - if(!error && portal && !iSCSIPLContainsPortalForTarget(targetIQN,iSCSIPortalGetAddress(portal))) { - iSCSICtlDisplayString(CFSTR("The specified portal does not exist\n")); - error = EINVAL; - } - - // Check for active sessions or connections before allowing removal - if(!error) { - if(portal) - if(iSCSIDaemonIsPortalActive(handle,target,portal)) - iSCSICtlDisplayString(CFSTR("The specified portal is connected and cannot be removed\n")); - else { - iSCSIPLRemovePortalForTarget(targetIQN,iSCSIPortalGetAddress(portal)); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else + // Verify that portal exists in property list + if(!error && portal && !iSCSIPreferencesContainsPortalForTarget(preferences,targetIQN,iSCSIPortalGetAddress(portal))) { + iSCSICtlDisplayString(CFSTR("The specified portal does not exist\n")); + error = EINVAL; + } + + // Check for active sessions or connections before allowing removal + if(!error) { + if(portal) + if(iSCSIDaemonIsPortalActive(handle,target,portal)) + iSCSICtlDisplayString(CFSTR("The specified portal is connected and cannot be removed\n")); + else { + iSCSIPreferencesRemovePortalForTarget(preferences,targetIQN,iSCSIPortalGetAddress(portal)); iSCSICtlDisplayString(CFSTR("The specified portal has been removed\n")); - } - else - if(iSCSIDaemonIsTargetActive(handle,target)) - iSCSICtlDisplayString(CFSTR("The specified target has an active session and cannot be removed\n")); - else { - iSCSIPLRemoveTarget(targetIQN); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("The specified target has been removed\n")); - } + } + else { + if(iSCSIDaemonIsTargetActive(handle,target)) + iSCSICtlDisplayString(CFSTR("The specified target has an active session and cannot be removed\n")); + else { + iSCSIPreferencesRemoveTarget(preferences,targetIQN); + iSCSICtlDisplayString(CFSTR("The specified target has been removed\n")); + } + } + } } + + if(!error) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + if(portal) iSCSIPortalRelease(portal); if(target) iSCSITargetRelease(target); - + return 0; } -errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { CFStringRef value = NULL; - - iSCSIPLSynchronize(); errno_t error = 0; - + + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); + + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + // Check for CHAP user name - if(CFDictionaryGetValueIfPresent(options,kOptKeyCHAPName,(const void **)&value)) + if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyCHAPName,(const void **)&value)) { if(CFStringCompare(value,kOptValueEmpty,0) != kCFCompareEqualTo) - iSCSIPLSetInitiatorCHAPName(value); + iSCSIPreferencesSetInitiatorCHAPName(preferences,value); } - +/* // Check for CHAP shared secret if(CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) { CFStringRef secret = iSCSICtlCreateSecretFromInput(MAX_SECRET_RETRY_ATTEMPTS); if(secret != NULL) { - if(iSCSIPLSetInitiatorCHAPSecret(secret) != 0) { + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + if(iSCSIKeychainSetCHAPSecretForNode(initiatorIQN,secret) != 0) { iSCSICtlDisplayPermissionsError(); error = EAUTH; } @@ -1034,14 +1049,14 @@ errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,CFDictionaryRef options else error = EINVAL; } - +*/ // Check for authentication method if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyAutMethod,(const void**)&value)) { if(CFStringCompare(value,kOptValueAuthMethodNone,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetInitiatorAuthenticationMethod(kiSCSIAuthMethodNone); + iSCSIPreferencesSetInitiatorAuthenticationMethod(preferences,kiSCSIAuthMethodNone); else if(CFStringCompare(value,kOptValueAuthMethodCHAP,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetInitiatorAuthenticationMethod(kiSCSIAuthMethodCHAP); + iSCSIPreferencesSetInitiatorAuthenticationMethod(preferences,kiSCSIAuthMethodCHAP); else { iSCSICtlDisplayError(CFSTR("The specified authentication method is invalid")); error = EINVAL; @@ -1050,14 +1065,14 @@ errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,CFDictionaryRef options // Check for initiator alias if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyNodeAlias,(const void**)&value)) - iSCSIPLSetInitiatorAlias(value); + iSCSIPreferencesSetInitiatorAlias(preferences,value); // Check for initiator IQN if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyNodeName,(const void **)&value)) { // Validate the chosen initiator IQN if(iSCSIUtilsValidateIQN(value)) - iSCSIPLSetInitiatorIQN(value); + iSCSIPreferencesSetInitiatorIQN(preferences,value); else { iSCSICtlDisplayError(CFSTR("The specified name is not a valid IQN or EUI-64 identifier")); error = EINVAL; @@ -1065,30 +1080,32 @@ errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,CFDictionaryRef options } if(!error) { - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("Initiator settings have been updated\n")); + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + iSCSICtlDisplayString(CFSTR("Initiator settings have been updated\n")); } - + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + return 0; } -errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, +errno_t iSCSICtlModifyTargetFromOptions(iSCSIPreferencesRef preferences, + CFDictionaryRef options, iSCSITargetRef target, iSCSIPortalRef portal) { CFStringRef targetIQN = iSCSITargetGetIQN(target); CFStringRef value = NULL; - iSCSIPLSynchronize(); errno_t error = 0; // Check for CHAP user name, ensure it is not blank if(CFDictionaryGetValueIfPresent(options,kOptKeyCHAPName,(const void **)&value)) { if(CFStringCompare(value,kOptValueEmpty,0) != kCFCompareEqualTo) - iSCSIPLSetTargetCHAPName(targetIQN,value); + iSCSIPreferencesSetTargetCHAPName(preferences,targetIQN,value); } // Check for CHAP shared secret @@ -1096,7 +1113,7 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, CFStringRef secret = iSCSICtlCreateSecretFromInput(MAX_SECRET_RETRY_ATTEMPTS); if(secret != NULL) { - iSCSIPLSetTargetCHAPSecret(targetIQN,secret); + iSCSIKeychainSetCHAPSecretForNode(targetIQN,secret); CFRelease(secret); } else { @@ -1111,12 +1128,12 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, { if(CFStringCompare(value,kOptValueAuthMethodNone,kCFCompareCaseInsensitive) == kCFCompareEqualTo) { authMethod = kiSCSIAuthMethodNone; - iSCSIPLSetTargetAuthenticationMethod(targetIQN,authMethod); + iSCSIPreferencesSetTargetAuthenticationMethod(preferences,targetIQN,authMethod); } else if(CFStringCompare(value,kOptValueAuthMethodCHAP,kCFCompareCaseInsensitive) == kCFCompareEqualTo) { authMethod = kiSCSIAuthMethodCHAP; - iSCSIPLSetTargetAuthenticationMethod(targetIQN,authMethod); + iSCSIPreferencesSetTargetAuthenticationMethod(preferences,targetIQN,authMethod); } else { iSCSICtlDisplayError(CFSTR("The specified authentication method is invalid")); @@ -1129,7 +1146,7 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, { // Validate the chosen target IQN if(iSCSIUtilsValidateIQN(value)) - iSCSIPLSetTargetIQN(targetIQN,value); + iSCSIPreferencesSetTargetIQN(preferences,targetIQN,value); else { iSCSICtlDisplayError(CFSTR("The specified name is not a valid IQN or EUI-64 identifier")); error = EINVAL; @@ -1141,9 +1158,9 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, { if(CFStringCompare(value,kOptValueAutoLoginEnable,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetAutoLoginForTarget(targetIQN,true); + iSCSIPreferencesSetAutoLoginForTarget(preferences,targetIQN,true); else if(CFStringCompare(value,kOptValueAutoLoginDisable,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetAutoLoginForTarget(targetIQN,false); + iSCSIPreferencesSetAutoLoginForTarget(preferences,targetIQN,false); else { CFStringRef errorString = CFStringCreateWithFormat( kCFAllocatorDefault,0,CFSTR("Invalid argument for %@"),kOptKeyAutoLogin); @@ -1166,7 +1183,7 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, error = EINVAL; } else - iSCSIPLSetMaxConnectionsForTarget(targetIQN,maxConnections); + iSCSIPreferencesSetMaxConnectionsForTarget(preferences,targetIQN,maxConnections); } // Check for error recovery level @@ -1179,7 +1196,7 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, error = EINVAL; } else { - iSCSIPLSetErrorRecoveryLevelForTarget(targetIQN,level); + iSCSIPreferencesSetErrorRecoveryLevelForTarget(preferences,targetIQN,level); } } @@ -1187,9 +1204,9 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyHeaderDigest,(const void **)&value)) { if(CFStringCompare(value,kOptValueDigestNone,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetHeaderDigestForTarget(targetIQN,kiSCSIDigestNone); + iSCSIPreferencesSetHeaderDigestForTarget(preferences,targetIQN,kiSCSIDigestNone); else if(CFStringCompare(value,kOptValueDigestCRC32C,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetHeaderDigestForTarget(targetIQN,kiSCSIDigestCRC32C); + iSCSIPreferencesSetHeaderDigestForTarget(preferences,targetIQN,kiSCSIDigestCRC32C); else { iSCSICtlDisplayError(CFSTR("The specified digest type is invalid")); error = EINVAL; @@ -1200,19 +1217,19 @@ errno_t iSCSICtlModifyTargetFromOptions(CFDictionaryRef options, if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyDataDigest,(const void **)&value)) { if(CFStringCompare(value,kOptValueDigestNone,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetDataDigestForTarget(targetIQN,kiSCSIDigestNone); + iSCSIPreferencesSetDataDigestForTarget(preferences,targetIQN,kiSCSIDigestNone); else if(CFStringCompare(value,kOptValueDigestCRC32C,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - iSCSIPLSetDataDigestForTarget(targetIQN,kiSCSIDigestCRC32C); + iSCSIPreferencesSetDataDigestForTarget(preferences,targetIQN,kiSCSIDigestCRC32C); else { iSCSICtlDisplayError(CFSTR("The specified digest type is invalid")); error = EINVAL; } } - return 0; + return error; } -errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { // First check if the target exists in the property list. Then check to // see if it has an active session. If it does, target properties cannot @@ -1223,66 +1240,71 @@ errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) if(handle < 0 || !options) return EINVAL; - iSCSIMutableTargetRef target = NULL; - iSCSIMutablePortalRef portal = NULL; errno_t error = 0; - + iSCSITargetRef target = NULL; + iSCSIMutablePortalRef portal = NULL; + iSCSIPreferencesRef preferences = NULL; + CFStringRef targetIQN = NULL; + if(!(target = iSCSICtlCreateTargetFromOptions(options))) - return EINVAL; - - CFStringRef targetIQN = iSCSITargetGetIQN(target); - - // Synchronize the database with the property list on disk - iSCSIPLSynchronize(); - - // Verify that the target exists in the property list - if(!iSCSIPLContainsTarget(targetIQN)) { - iSCSICtlDisplayString(CFSTR("The specified target does not exist\n")); error = EINVAL; - } - - if(!error && iSCSICtlIsPortalSpecified(options)) { - if(!(portal = iSCSICtlCreatePortalFromOptions(options))) { + else + targetIQN = iSCSITargetGetIQN(target); + + if(!error && iSCSICtlIsPortalSpecified(options)) + if(!(portal = iSCSICtlCreatePortalFromOptions(options))) error = EINVAL; - } - } - - // Verify that portal exists in property list - if(!error && portal && !iSCSIPLContainsPortalForTarget(targetIQN,iSCSIPortalGetAddress(portal))) { - iSCSICtlDisplayString(CFSTR("The specified portal does not exist\n")); - error = EINVAL; - } - - // Check for active sessions or connections before allowing modification + + preferences = iSCSIPreferencesCreateFromAppValues(); + + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + if(!error) { - if(portal) { - if(iSCSIDaemonIsPortalActive(handle,target,portal)) - iSCSICtlDisplayString(CFSTR("The specified portal is connected and cannot be modified\n")); - else { - iSCSICtlModifyPortalFromOptions(options,portal); - iSCSIPLSetPortalForTarget(targetIQN,portal); - - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else + + // Verify that the target exists in the property list + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { + iSCSICtlDisplayString(CFSTR("The specified target does not exist\n")); + error = EINVAL; + } + + // Verify that portal exists in property list + if(!error && portal && !iSCSIPreferencesContainsPortalForTarget(preferences,targetIQN,iSCSIPortalGetAddress(portal))) { + iSCSICtlDisplayString(CFSTR("The specified portal does not exist\n")); + error = EINVAL; + } + + // Check for active sessions or connections before allowing modification + if(!error) { + if(portal) { + if(iSCSIDaemonIsPortalActive(handle,target,portal)) + iSCSICtlDisplayString(CFSTR("The specified portal is connected and cannot be modified\n")); + else { + iSCSICtlModifyPortalFromOptions(options,portal); + iSCSIPreferencesSetPortalForTarget(preferences,targetIQN,portal); iSCSICtlDisplayString(CFSTR("Portal settings have been updated\n")); + } + } - - } - // Else we're modifying target parameters - else { - if(iSCSIDaemonIsTargetActive(handle,target)) - iSCSICtlDisplayString(CFSTR("The specified target has an active session and cannot be modified\n")); + // Else we're modifying target parameters else { - iSCSICtlModifyTargetFromOptions(options,target,portal); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else + if(iSCSIDaemonIsTargetActive(handle,target)) + iSCSICtlDisplayString(CFSTR("The specified target has an active session and cannot be modified\n")); + else { + iSCSICtlModifyTargetFromOptions(preferences,options,target,portal); iSCSICtlDisplayString(CFSTR("Target settings have been updated\n")); + } } } } - + + if(!error) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + if(portal) iSCSIPortalRelease(portal); if(target) @@ -1299,8 +1321,9 @@ void displayTargetInfo(iSCSIDaemonHandle handle, CFStringRef targetState = NULL; CFStringRef targetConfig = NULL; CFStringRef targetIQN = iSCSITargetGetIQN(target); - - enum iSCSITargetConfigTypes configType = iSCSIPLGetTargetConfigType(targetIQN); + + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); + enum iSCSITargetConfigTypes configType = iSCSIPreferencesGetTargetConfigType(preferences,targetIQN); switch(configType) { case kiSCSITargetConfigStatic: @@ -1318,12 +1341,10 @@ void displayTargetInfo(iSCSIDaemonHandle handle, targetState = CFSTR("inactive"); CFStringRef status = NULL; - - if(!properties) { status = CFStringCreateWithFormat(kCFAllocatorDefault,0, - CFSTR("%s <%@, %@>\n"), - CFStringGetCStringPtr(targetIQN,kCFStringEncodingASCII), + CFSTR("%@ <%@, %@>\n"), + targetIQN, targetState,targetConfig); } else { @@ -1335,8 +1356,8 @@ void displayTargetInfo(iSCSIDaemonHandle handle, CFNumberGetValue(targetSessionId,kCFNumberSInt16Type,&tsih); status = CFStringCreateWithFormat(kCFAllocatorDefault,0, - CFSTR("%s <%@, %@, sid %@, tpgt %@, tsid %#x>\n"), - CFStringGetCStringPtr(targetIQN,kCFStringEncodingASCII), + CFSTR("%@ <%@, %@, sid %@, tpgt %@, tsid %#x>\n"), + targetIQN, targetState, targetConfig, sessionId, @@ -1348,6 +1369,7 @@ void displayTargetInfo(iSCSIDaemonHandle handle, CFRelease(status); CFRelease(targetState); CFRelease(targetConfig); + iSCSIPreferencesRelease(preferences); } /*! Helper function. Displays information about a portal/connection. */ @@ -1363,9 +1385,9 @@ void displayPortalInfo(iSCSIDaemonHandle handle, if(!properties) { portalStatus = CFStringCreateWithFormat( kCFAllocatorDefault,NULL, - CFSTR("\t%s \n"), - CFStringGetCStringPtr(portalAddress,kCFStringEncodingASCII), - CFStringGetCStringPtr(iSCSIPortalGetPort(portal),kCFStringEncodingASCII), + CFSTR("\t%@ \n"), + portalAddress, + iSCSIPortalGetPort(portal), iSCSIPortalGetHostInterface(portal)); } else { @@ -1374,10 +1396,10 @@ void displayPortalInfo(iSCSIDaemonHandle handle, portalStatus = CFStringCreateWithFormat( kCFAllocatorDefault,NULL, - CFSTR("\t%s \n"), - CFStringGetCStringPtr(portalAddress,kCFStringEncodingASCII), + CFSTR("\t%@ \n"), + portalAddress, connectionId, - CFStringGetCStringPtr(iSCSIPortalGetPort(portal),kCFStringEncodingASCII), + iSCSIPortalGetPort(portal), iSCSIPortalGetHostInterface(portal)); } @@ -1396,13 +1418,10 @@ errno_t iSCSICtlListTargets(iSCSIDaemonHandle handle,CFDictionaryRef options) // various portals and whether they are connected. Targets from the // property list that cannot be matched to an active session are // assumed to be disconnected. - - // Read property list (synchronize) - iSCSIPLSynchronize(); - CFArrayRef targetsList; + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); - if(!(targetsList = iSCSIPLCreateArrayOfTargets())) { + if(!(targetsList = iSCSIPreferencesCreateArrayOfTargets(preferences))) { iSCSICtlDisplayString(CFSTR("No persistent targets are defined\n")); return 0; } @@ -1414,7 +1433,7 @@ errno_t iSCSICtlListTargets(iSCSIDaemonHandle handle,CFDictionaryRef options) CFStringRef targetIQN = CFArrayGetValueAtIndex(targetsList,targetIdx); iSCSITargetRef target = NULL; - if(!(target = iSCSIPLCopyTarget(targetIQN))) + if(!(target = iSCSIPreferencesCopyTarget(preferences,targetIQN))) continue; CFDictionaryRef properties = NULL; @@ -1423,12 +1442,14 @@ errno_t iSCSICtlListTargets(iSCSIDaemonHandle handle,CFDictionaryRef options) displayTargetInfo(handle,target,properties); - CFArrayRef portalsList = iSCSIPLCreateArrayOfPortalsForTarget(targetIQN); + CFArrayRef portalsList = iSCSIPreferencesCreateArrayOfPortalsForTarget(preferences,targetIQN); CFIndex portalCount = CFArrayGetCount(portalsList); for(CFIndex portalIdx = 0; portalIdx < portalCount; portalIdx++) { - iSCSIPortalRef portal = iSCSIPLCopyPortalForTarget(targetIQN,CFArrayGetValueAtIndex(portalsList,portalIdx)); + iSCSIPortalRef portal = iSCSIPreferencesCopyPortalForTarget(preferences, + targetIQN, + CFArrayGetValueAtIndex(portalsList,portalIdx)); if(portal) { CFDictionaryRef properties = NULL; @@ -1446,6 +1467,8 @@ errno_t iSCSICtlListTargets(iSCSIDaemonHandle handle,CFDictionaryRef options) } CFRelease(targetsList); + + iSCSIPreferencesRelease(preferences); return 0; } @@ -1455,17 +1478,19 @@ errno_t iSCSICtlListTargets(iSCSIDaemonHandle handle,CFDictionaryRef options) * @return an error code indicating the result of the operation. */ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) { - iSCSIPLSynchronize(); iSCSITargetRef target = NULL; if(!(target = iSCSICtlCreateTargetFromOptions(options))) return EINVAL; + + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); // Verify that target exists CFStringRef targetIQN = iSCSITargetGetIQN(target); - if(!iSCSIPLContainsTarget(targetIQN)) + if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { iSCSICtlDisplayString(CFSTR("The specified target does not exist\n")); + iSCSIPreferencesRelease(preferences); return EINVAL; } @@ -1475,16 +1500,16 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) // Get information about automatic login CFStringRef autoLogin = CFSTR("disabled"); - if(iSCSIPLGetAutoLoginForTarget(targetIQN)) + if(iSCSIPreferencesGetAutoLoginForTarget(preferences,targetIQN)) autoLogin = CFSTR("enabled"); CFStringRef targetConfig = CFStringCreateWithFormat(kCFAllocatorDefault,0,CFSTR("\t%@: %@\n"),kOptKeyAutoLogin,autoLogin); iSCSICtlDisplayString(targetConfig); CFRelease(targetConfig); - if(iSCSIPLGetTargetConfigType(targetIQN) == kiSCSITargetConfigDynamicSendTargets) + if(iSCSIPreferencesGetTargetConfigType(preferences,targetIQN) == kiSCSITargetConfigDynamicSendTargets) { - CFStringRef discoveryPortal = iSCSIPLGetDiscoveryPortalForTarget(targetIQN); + CFStringRef discoveryPortal = iSCSIPreferencesGetDiscoveryPortalForTarget(preferences,targetIQN); CFStringRef discoveryCfg = CFStringCreateWithFormat(kCFAllocatorDefault,0,CFSTR("\tdiscovery portal: %@\n"),discoveryPortal); iSCSICtlDisplayString(discoveryCfg); CFRelease(discoveryCfg); @@ -1494,10 +1519,10 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) CFStringRef format = NULL; // Get configured parameter values - int maxConnectionsCfg = iSCSIPLGetMaxConnectionsForTarget(targetIQN); - enum iSCSIErrorRecoveryLevels errorRecoveryLevelCfg = iSCSIPLGetErrorRecoveryLevelForTarget(targetIQN); - CFStringRef headerDigestStr = iSCSICtlGetStringForDigestType(iSCSIPLGetHeaderDigestForTarget(targetIQN)); - CFStringRef dataDigestStr = iSCSICtlGetStringForDigestType(iSCSIPLGetDataDigestForTarget(targetIQN)); + int maxConnectionsCfg = iSCSIPreferencesGetMaxConnectionsForTarget(preferences,targetIQN); + enum iSCSIErrorRecoveryLevels errorRecoveryLevelCfg = iSCSIPreferencesGetErrorRecoveryLevelForTarget(preferences,targetIQN); + CFStringRef headerDigestStr = iSCSICtlGetStringForDigestType(iSCSIPreferencesGetHeaderDigestForTarget(preferences,targetIQN)); + CFStringRef dataDigestStr = iSCSICtlGetStringForDigestType(iSCSIPreferencesGetDataDigestForTarget(preferences,targetIQN)); if(properties) { format = CFSTR("\tConfiguration:" @@ -1530,10 +1555,10 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) } // Get authentication information - CFStringRef CHAPName = iSCSIPLCopyTargetCHAPName(targetIQN); + CFStringRef CHAPName = iSCSIPreferencesCopyTargetCHAPName(preferences,targetIQN); CFStringRef authMethod = NULL; - switch(iSCSIPLGetTargetAuthenticationMethod(targetIQN)) { + switch(iSCSIPreferencesGetTargetAuthenticationMethod(preferences,targetIQN)) { case kiSCSIAuthMethodCHAP: authMethod = CFSTR("CHAP"); break; default: @@ -1541,7 +1566,7 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) }; CFStringRef CHAPSecret = CFSTR(""); - if(!iSCSIPLExistsTargetCHAPSecret(targetIQN)) + if(!iSCSIKeychainContainsCHAPSecretForNode(targetIQN)) CHAPSecret = CFSTR(""); format = CFSTR("\n\tAuthentication: %@" @@ -1558,14 +1583,14 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) iSCSICtlDisplayString(targetParams); iSCSICtlDisplayString(targetAuth); - CFArrayRef portals = iSCSIPLCreateArrayOfPortalsForTarget(targetIQN); + CFArrayRef portals = iSCSIPreferencesCreateArrayOfPortalsForTarget(preferences,targetIQN); CFIndex count = CFArrayGetCount(portals); // Iterate over portals for target and display configuration information for(CFIndex idx = 0; idx < count; idx++) { CFStringRef portalConfig = NULL; CFStringRef portalAddress = CFArrayGetValueAtIndex(portals,idx); - iSCSIPortalRef portal = iSCSIPLCopyPortalForTarget(targetIQN,portalAddress); + iSCSIPortalRef portal = iSCSIPreferencesCopyPortalForTarget(preferences,targetIQN,portalAddress); // Get negotiated portal parameters CFDictionaryRef properties = iSCSIDaemonCreateCFPropertiesForConnection(handle,target,portal); @@ -1598,23 +1623,25 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) CFRelease(targetParams); CFRelease(targetAuth); + + iSCSIPreferencesRelease(preferences); return 0; } errno_t iSCSICtlListDiscoveryConfig(iSCSIDaemonHandle handle,CFDictionaryRef optDictionary) { - iSCSIPLSynchronize(); + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); - Boolean enabled = iSCSIPLGetSendTargetsDiscoveryEnable(); - CFIndex interval = iSCSIPLGetSendTargetsDiscoveryInterval(); + Boolean enabled = iSCSIPreferencesGetSendTargetsDiscoveryEnable(preferences); + CFIndex interval = iSCSIPreferencesGetSendTargetsDiscoveryInterval(preferences); CFStringRef enableString = CFSTR("disabled"); if(enabled) enableString = CFSTR("enabled"); CFStringRef format = CFSTR("\%@: %@" - "\n\tinterval: %ld"); + "\n\tinterval: %ld seconds"); CFStringRef discoveryConfig = CFStringCreateWithFormat(kCFAllocatorDefault,0, format, kOptKeySendTargetsEnable, @@ -1624,7 +1651,7 @@ errno_t iSCSICtlListDiscoveryConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt CFRelease(discoveryConfig); // Display a list of discovery (SendTargets) portals - CFArrayRef portals = iSCSIPLCreateArrayOfPortalsForSendTargetsDiscovery(); + CFArrayRef portals = iSCSIPreferencesCreateArrayOfPortalsForSendTargetsDiscovery(preferences); CFIndex portalCount = 0; if(portals) { @@ -1639,31 +1666,37 @@ errno_t iSCSICtlListDiscoveryConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt for(CFIndex idx = 0; idx < portalCount; idx++) { CFStringRef portalAddress = CFArrayGetValueAtIndex(portals,idx); - iSCSIPortalRef portal = iSCSIPLCopySendTargetsDiscoveryPortal(portalAddress); - + iSCSIPortalRef portal = iSCSIPreferencesCopySendTargetsDiscoveryPortal(preferences,portalAddress); + + char portalAddressBuffer[NI_MAXHOST]; + CFStringGetCString(portalAddress,portalAddressBuffer,NI_MAXHOST,kCFStringEncodingASCII); + CFStringRef entry = CFStringCreateWithFormat(kCFAllocatorDefault,0, - CFSTR("\t\t%-15s \n"), - CFStringGetCStringPtr(portalAddress,kCFStringEncodingASCII), - CFStringGetCStringPtr(iSCSIPortalGetPort(portal),kCFStringEncodingASCII), + CFSTR("\t\t%-15s \n"), + portalAddressBuffer, + iSCSIPortalGetPort(portal), iSCSIPortalGetHostInterface(portal)); + iSCSICtlDisplayString(entry); CFRelease(entry); } + iSCSIPreferencesRelease(preferences); + return 0; } errno_t iSCSICtlListInitiatorConfig(iSCSIDaemonHandle handle,CFDictionaryRef optDictionary) { - iSCSIPLSynchronize(); + iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); - CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN(); - CFStringRef alias = iSCSIPLCopyInitiatorAlias(); - CFStringRef CHAPName = iSCSIPLCopyInitiatorCHAPName(); + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + CFStringRef alias = iSCSIPreferencesCopyInitiatorAlias(preferences); + CFStringRef CHAPName = iSCSIPreferencesCopyInitiatorCHAPName(preferences); CFStringRef authMethod = NULL; - switch(iSCSIPLGetInitiatorAuthenticationMethod()) { + switch(iSCSIPreferencesGetInitiatorAuthenticationMethod(preferences)) { case kiSCSIAuthMethodCHAP: authMethod = CFSTR("CHAP"); break; default: @@ -1671,7 +1704,7 @@ errno_t iSCSICtlListInitiatorConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt }; CFStringRef CHAPSecret = CFSTR(""); - if(!iSCSIPLExistsInitiatorCHAPSecret()) + if(!iSCSIKeychainContainsCHAPSecretForNode(initiatorIQN)) CHAPSecret = CFSTR(""); @@ -1697,6 +1730,8 @@ errno_t iSCSICtlListInitiatorConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt iSCSICtlDisplayString(initiatorConfig); CFRelease(initiatorConfig); + iSCSIPreferencesRelease(preferences); + return 0; } @@ -1704,30 +1739,51 @@ errno_t iSCSICtlListInitiatorConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt * @param handle handle to the iSCSI daemon. * @param options the command-line options dictionary. * @return an error code indicating the result of the operation. */ -errno_t iSCSICtlAddDiscoveryPortal(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlAddDiscoveryPortal(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { iSCSIPortalRef portal = NULL; - if((portal = iSCSICtlCreatePortalFromOptions(options))) + iSCSIPreferencesRef preferences = NULL; + errno_t error = 0; + + if(!(portal = iSCSICtlCreatePortalFromOptions(options))) + error = EINVAL; + + preferences = iSCSIPreferencesCreateFromAppValues(); + + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + + if(!error) { - iSCSIPLSynchronize(); CFStringRef portalAddress = iSCSIPortalGetAddress(portal); - if(!iSCSIPLContainsPortalForSendTargetsDiscovery(portalAddress)) { - iSCSIPLAddSendTargetsDiscoveryPortal(portal); + if(!iSCSIPreferencesContainsPortalForSendTargetsDiscovery(preferences,portalAddress)) + { + iSCSIPreferencesAddSendTargetsDiscoveryPortal(preferences,portal); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else { - CFStringRef status = CFStringCreateWithFormat(kCFAllocatorDefault,0, + + CFStringRef status = CFStringCreateWithFormat(kCFAllocatorDefault,0, CFSTR("The discovery portal %@ has been added\n"), iSCSIPortalGetAddress(portal)); - iSCSICtlDisplayString(status); - CFRelease(status); - } + iSCSICtlDisplayString(status); + CFRelease(status); } - else + else { iSCSICtlDisplayString(CFSTR("The specified discovery portal already exists\n")); + error = EEXIST; + } } + + if(!error) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + + if(portal) + iSCSIPortalRelease(portal); + return 0; } @@ -1735,137 +1791,159 @@ errno_t iSCSICtlAddDiscoveryPortal(iSCSIDaemonHandle handle,CFDictionaryRef opti * @param handle handle to the iSCSI daemon. * @param options the command-line options dictionary. * @return an error code indicating the result of the operation. */ -errno_t iSCSICtlModifyDiscovery(iSCSIDaemonHandle handle,CFDictionaryRef optDictionary) +errno_t iSCSICtlModifyDiscovery(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef optDictionary) { - iSCSIPLSynchronize(); - - CFStringRef value = NULL; errno_t error = 0; + CFStringRef value = NULL; + iSCSIPreferencesRef preferences = NULL; + + preferences = iSCSIPreferencesCreateFromAppValues(); + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + // Check if user enabled or disable a discovery method and act accordingly - if(CFDictionaryGetValueIfPresent(optDictionary,kOptKeySendTargetsEnable,(const void **)&value)) + if(!error && CFDictionaryGetValueIfPresent(optDictionary,kOptKeySendTargetsEnable,(const void **)&value)) { if(CFStringCompare(value,kOptValueDiscoveryEnable,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - iSCSIPLSetSendTargetsDiscoveryEnable(true); - - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("SendTargets discovery has been enabled\n")); - } + iSCSIPreferencesSetSendTargetsDiscoveryEnable(preferences,true); else if(CFStringCompare(value,kOptValueDiscoveryDisable,kCFCompareCaseInsensitive) == kCFCompareEqualTo) - { - iSCSIPLSetSendTargetsDiscoveryEnable(false); - - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("SendTargets discovery has been disabled\n")); - - } + iSCSIPreferencesSetSendTargetsDiscoveryEnable(preferences,false); else { CFStringRef errorString = CFStringCreateWithFormat( - kCFAllocatorDefault,0,CFSTR("Invalid argument for %@"),kOptKeySendTargetsEnable); + kCFAllocatorDefault,0,CFSTR("Invalid argument for %@"),kOptKeySendTargetsEnable); iSCSICtlDisplayError(errorString); CFRelease(errorString); error = EINVAL; } } - // Check if user modified the discovery interval if(!error && CFDictionaryGetValueIfPresent(optDictionary,kOptKeyDiscoveryInterval,(const void **)&value)) { int interval = CFStringGetIntValue(value); if(interval < kiSCSIInitiator_DiscoveryInterval_Min || interval > kiSCSIInitiator_DiscoveryInterval_Max) { - - CFStringRef errorString = CFStringCreateWithFormat( - kCFAllocatorDefault,0, - CFSTR("The specified discovery interval is invalid. Specify a value between %d - %d seconds"), - kiSCSIInitiator_DiscoveryInterval_Min,kiSCSIInitiator_DiscoveryInterval_Max); + CFStringRef errorString = CFStringCreateWithFormat(kCFAllocatorDefault,0, + CFSTR("The specified discovery interval is invalid. Specify a value between %d - %d seconds"), + kiSCSIInitiator_DiscoveryInterval_Min,kiSCSIInitiator_DiscoveryInterval_Max); iSCSICtlDisplayError(errorString); CFRelease(errorString); + error = EINVAL; } - else { - iSCSIPLSetSendTargetsDiscoveryInterval(interval); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("The discovery interval has been updated\n")); - } + else + iSCSIPreferencesSetSendTargetsDiscoveryInterval(preferences,interval); } - + + if(!error) { + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + iSCSICtlDisplayString(CFSTR("Discovery settings have been updated\n")); + } + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + if(!error) iSCSIDaemonUpdateDiscovery(handle); return error; } +/*! Helper function. Creates an array of strings of target IQNs + * of active targets associated with the specified discovery portal. */ +CFArrayRef iSCSICtlCreateArrayOfActiveTargetsForDiscoveryPortal(iSCSIDaemonHandle handle, + iSCSIPreferencesRef preferences, + CFStringRef portalAddress) +{ + CFMutableArrayRef activeTargets = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); + CFArrayRef targets = + iSCSIPreferencesCreateArrayOfDynamicTargetsForSendTargets(preferences,portalAddress); + + CFIndex targetsCount = CFArrayGetCount(targets); + for(CFIndex idx = 0; idx < targetsCount; idx++) + { + CFStringRef targetIQN = CFArrayGetValueAtIndex(targets,idx); + iSCSIMutableTargetRef target = iSCSITargetCreateMutable(); + iSCSITargetSetIQN(target,targetIQN); + + if(iSCSIDaemonIsTargetActive(handle,target)) + CFArrayAppendValue(activeTargets,targetIQN); + + iSCSITargetRelease(target); + } + + CFRelease(targets); + return activeTargets; +} + + /*! Removes a discovery portal from SendTargets discovery. * @param handle handle to the iSCSI daemon. * @param options the command-line options dictionary. * @return an error code indicating the result of the operation. */ -errno_t iSCSICtlRemoveDiscoveryPortal(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlRemoveDiscoveryPortal(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) { + if(handle < 0 || !authorization || !options) + return EINVAL; + + errno_t error = 0; iSCSIPortalRef portal = NULL; - if((portal = iSCSICtlCreatePortalFromOptions(options))) + iSCSIPreferencesRef preferences = NULL; + + if(!(portal = iSCSICtlCreatePortalFromOptions(options))) + error = EINVAL; + + preferences = iSCSIPreferencesCreateFromAppValues(); + + if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) + iSCSICtlDisplayError(CFSTR("Permission denied")); + + if (!error) { - iSCSIPLSynchronize(); - CFStringRef status = NULL; CFStringRef portalAddress = iSCSIPortalGetAddress(portal); - if(iSCSIPLContainsPortalForSendTargetsDiscovery(portalAddress)) { - - // If targets associated with this discovery portal are logged in, - // notify user and do nothing - CFMutableArrayRef activeTargets = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); - CFArrayRef targets = iSCISPLCreateArrayOfDynamicTargetsForSendTargets(portalAddress); - - CFIndex targetsCount = CFArrayGetCount(targets); - for(CFIndex idx = 0; idx < targetsCount; idx++) - { - CFStringRef targetIQN = CFArrayGetValueAtIndex(targets,idx); - iSCSIMutableTargetRef target = iSCSITargetCreateMutable(); - iSCSITargetSetIQN(target,targetIQN); - - if(iSCSIDaemonIsTargetActive(handle,target)) - CFArrayAppendValue(activeTargets,targetIQN); - - iSCSITargetRelease(target); - } - + if(!error && !iSCSIPreferencesContainsPortalForSendTargetsDiscovery(preferences,portalAddress)) { + iSCSICtlDisplayString(CFSTR("The specified discovery portal does not exist\n")); + error = EINVAL; + } + + // Check if any targets associated with this portal are active + if(!error) { + + // Get active targets associated with this discovery portal + CFArrayRef activeTargets = iSCSICtlCreateArrayOfActiveTargetsForDiscoveryPortal(handle,preferences,portalAddress); + CFIndex targetsCount = 0; if((targetsCount = CFArrayGetCount(activeTargets)) > 0) { iSCSICtlDisplayString(CFSTR("\nThe following active target(s) are associated with the specified discovery portal:\n\n")); for(CFIndex idx = 0; idx < targetsCount; idx++) { - CFStringRef targetIQN = CFArrayGetValueAtIndex(targets,idx); + CFStringRef targetIQN = CFArrayGetValueAtIndex(activeTargets,idx); CFStringRef targetString = CFStringCreateWithFormat(kCFAllocatorDefault,0,CFSTR("\t%@\n"),targetIQN); iSCSICtlDisplayString(targetString); CFRelease(targetString); } - iSCSICtlDisplayString(CFSTR("\nThe active targets must be logged out before the discovery portal can be removed\n\n")); + iSCSICtlDisplayString(CFSTR("\nThe active target(s) must be logged out before the discovery portal can be removed\n\n")); + error = EBUSY; } - else { - iSCSIPLRemoveSendTargetsDiscoveryPortal(portal); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else { - status = CFStringCreateWithFormat(kCFAllocatorDefault,0, - CFSTR("The discovery portal %@ has been removed\n"), - iSCSIPortalGetAddress(portal)); - iSCSICtlDisplayString(status); - CFRelease(status); - } - } - CFRelease(activeTargets); - CFRelease(targets); } - else - iSCSICtlDisplayString(CFSTR("The specified discovery portal does not exist\n")); } + + if(!error) { + iSCSIPreferencesRemoveSendTargetsDiscoveryPortal(preferences,portal); + CFStringRef status = CFStringCreateWithFormat(kCFAllocatorDefault,0, + CFSTR("The discovery portal %@ has been removed\n"),iSCSIPortalGetAddress(portal)); + iSCSICtlDisplayString(status); + CFRelease(status); + + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + } + else + iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + + iSCSIPreferencesRelease(preferences); + return 0; } @@ -1884,8 +1962,8 @@ void displayTargetProperties(CFDictionaryRef propertiesDict) CFStringRef targetIQN = CFDictionaryGetValue(protocolDict,CFSTR(kIOPropertyiSCSIQualifiedNameKey)); CFStringRef targetStr = CFStringCreateWithFormat(kCFAllocatorDefault,NULL, - CFSTR("%s \n\t%@ %@ %@\n\tSerial Number %@\n"), - CFStringGetCStringPtr(targetIQN,kCFStringEncodingASCII), + CFSTR("%@ \n\t%@ %@ %@\n\tSerial Number %@\n"), + targetIQN, domainId,targetId,targetVendor,targetProduct, targetRevision,serialNumber); iSCSICtlDisplayString(targetStr); @@ -2013,57 +2091,6 @@ errno_t iSCSICtlListLUNs(iSCSIDaemonHandle handle,CFDictionaryRef options) return 0; } -errno_t iSCSICtlProbeTargetForAuthMethod(iSCSIDaemonHandle handle, - CFDictionaryRef options) -{ - if(handle < 0 || !options) - return EINVAL; - - iSCSITargetRef target = NULL; - iSCSIPortalRef portal = NULL; - errno_t error = 0; - - if(!(target = iSCSICtlCreateTargetFromOptions(options))) - return EINVAL; - - if(!(portal = iSCSICtlCreatePortalFromOptions(options))) { - CFRelease(target); - return EINVAL; - } - // Synchronize the database with the property list on disk - iSCSIPLSynchronize(); - - enum iSCSILoginStatusCode statusCode = kiSCSILoginInvalidStatusCode; - enum iSCSIAuthMethods authMethod; - - error = iSCSIDaemonQueryTargetForAuthMethod(handle,portal, - iSCSITargetGetIQN(target), - &authMethod, - &statusCode); - - if(statusCode != kiSCSILoginInvalidStatusCode) - iSCSICtlDisplayProbeTargetLoginStatus(statusCode,target,portal,authMethod); - else { - CFStringRef errorString = CFStringCreateWithCString(kCFAllocatorDefault,strerror(error),kCFStringEncodingASCII); - iSCSICtlDisplayError(errorString); - CFRelease(errorString); - } - - return error; -} - -errno_t iSCSICtlReset(iSCSIDaemonHandle handle,CFDictionaryRef options) -{ - iSCSIPLReset(); - if(!iSCSIPLSynchronize()) - iSCSICtlDisplayPermissionsError(); - else - iSCSICtlDisplayString(CFSTR("iSCSI settings have been reset\n")); - - return 0; -} - - /*! Entry point. Parses command line arguments, establishes a connection to the * iSCSI deamon and executes requested iSCSI tasks. */ int main(int argc, char * argv[]) @@ -2072,9 +2099,6 @@ int main(int argc, char * argv[]) @autoreleasepool { - // Connect to the daemon - iSCSIDaemonHandle handle = iSCSIDaemonConnect(); - // Setup a stream for writing to stdout CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/dev/stdout"), @@ -2107,34 +2131,41 @@ int main(int argc, char * argv[]) // Get the mode of operation (e.g., add, modify, remove, etc.). enum iSCSICtlCmds cmd = iSCSICtlGetCmdFromArguments(arguments); enum iSCSICtlSubCmds subCmd = iSCSICtlGetSubCmdFromArguments(arguments); + + // Prepare authorization object (necessary for some operations) + AuthorizationRef authorization; + AuthorizationCreate(NULL,NULL,0,&authorization); + + // Connect to the daemon + iSCSIDaemonHandle handle = iSCSIDaemonConnect(); switch(cmd) { case kiSCSICtlCmdAdd: if(subCmd == kiSCSICtlSubCmdTarget) - error = iSCSICtlAddTarget(handle,optDictionary); + error = iSCSICtlAddTarget(handle,authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryPortal) - error = iSCSICtlAddDiscoveryPortal(handle,optDictionary); + error = iSCSICtlAddDiscoveryPortal(handle,authorization,optDictionary); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for add")); break; case kiSCSICtlCmdModify: if(subCmd == kiSCSICtlSubCmdTargetConfig) - error = iSCSICtlModifyTarget(handle,optDictionary); + error = iSCSICtlModifyTarget(handle,authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdInitiatorConfig) - error = iSCSICtlModifyInitiator(handle,optDictionary); + error = iSCSICtlModifyInitiator(handle,authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryConfig) - error = iSCSICtlModifyDiscovery(handle,optDictionary); + error = iSCSICtlModifyDiscovery(handle,authorization,optDictionary); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for modify")); break; case kiSCSICtlCmdRemove: if(subCmd == kiSCSICtlSubCmdTarget) - error = iSCSICtlRemoveTarget(handle,optDictionary); + error = iSCSICtlRemoveTarget(handle,authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryPortal) - error = iSCSICtlRemoveDiscoveryPortal(handle,optDictionary); + error = iSCSICtlRemoveDiscoveryPortal(handle,authorization,optDictionary); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for remove")); break; @@ -2155,13 +2186,9 @@ int main(int argc, char * argv[]) break; case kiSCSICtlCmdLogin: - error = iSCSICtlLogin(handle,optDictionary); break; + error = iSCSICtlLogin(handle,authorization,optDictionary); break; case kiSCSICtlCmdLogout: - error = iSCSICtlLogout(handle,optDictionary); break; - case kiSCSICtlCmdProbe: - error = iSCSICtlProbeTargetForAuthMethod(handle,optDictionary); break; - case kiSCSICtlCmdReset: - error = iSCSICtlReset(handle,optDictionary); break; + error = iSCSICtlLogout(handle,authorization,optDictionary); break; case kiSCSICtlCmdInvalid: iSCSICtlDisplayUsage(); @@ -2170,7 +2197,10 @@ int main(int argc, char * argv[]) iSCSIDaemonDisconnect(handle); CFWriteStreamClose(stdoutStream); + +// AuthorizationFree(<#AuthorizationRef _Nonnull authorization#>, <#AuthorizationFlags flags#>) } - + + return error; } \ No newline at end of file diff --git a/Source/User Tools/iscsictl.8 b/Source/User/iscsictl/iscsictl.8 similarity index 100% rename from Source/User Tools/iscsictl.8 rename to Source/User/iscsictl/iscsictl.8 diff --git a/Source/User Tools/com.github.iscsi-osx.iscsid.plist b/Source/User/iscsid/com.github.iscsi-osx.iscsid.plist similarity index 83% rename from Source/User Tools/com.github.iscsi-osx.iscsid.plist rename to Source/User/iscsid/com.github.iscsi-osx.iscsid.plist index b6587ec7..bafbd1aa 100644 --- a/Source/User Tools/com.github.iscsi-osx.iscsid.plist +++ b/Source/User/iscsid/com.github.iscsi-osx.iscsid.plist @@ -11,11 +11,11 @@ iscsid SockPathName - /var/tmp/iscsid + /var/run/iscsid Program - /Library/PrivilegedHelperTools/iscsid + /usr/local/libexec/iscsid Label com.github.iscsi-osx.iscsid diff --git a/Source/User Tools/iSCSIAuth.c b/Source/User/iscsid/iSCSIAuth.c similarity index 91% rename from Source/User Tools/iSCSIAuth.c rename to Source/User/iscsid/iSCSIAuth.c index 38c5bcce..36e7d028 100644 --- a/Source/User Tools/iSCSIAuth.c +++ b/Source/User/iscsid/iSCSIAuth.c @@ -1,12 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIAuth.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI authentication functions. This library - * depends on the user-space iSCSI PDU library and augments the - * session library by providing authentication for the target - * and the initiator. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIAuth.h" @@ -171,7 +188,7 @@ CFStringRef iSCSIAuthNegotiateCHAPCreateId() /*! Helper function for iSCSIConnectionSecurityNegotiate. Once it has been * determined that a CHAP session is to be used, this function will perform * the CHAP authentication. */ -errno_t iSCSIAuthNegotiateCHAP(iSCSITargetRef target, +errno_t iSCSIAuthNegotiateCHAP(iSCSIMutableTargetRef target, iSCSIAuthRef initiatorAuth, iSCSIAuthRef targetAuth, SID sessionId, @@ -296,6 +313,12 @@ errno_t iSCSIAuthNegotiateCHAP(iSCSITargetRef target, } } + // If no error and the target returned an alias save it... + CFStringRef targetAlias; + if(!error && CFDictionaryGetValueIfPresent(authRsp,kRFC3720_Key_TargetAlias,(const void **)&targetAlias)) { + iSCSITargetSetAlias(target,targetAlias); + } + CFRelease(authCmd); CFRelease(authRsp); @@ -359,7 +382,7 @@ void iSCSIAuthNegotiateBuildDict(iSCSITargetRef target, * begin authentication between the initiator and a selected target. If the * target name is set to blank (e.g., by a call to iSCSITargetSetIQN()) or * never set at all, a discovery session is assumed for authentication. */ -errno_t iSCSIAuthNegotiate(iSCSITargetRef target, +errno_t iSCSIAuthNegotiate(iSCSIMutableTargetRef target, iSCSIAuthRef initiatorAuth, iSCSIAuthRef targetAuth, SID sessionId, @@ -496,6 +519,12 @@ errno_t iSCSIAuthNegotiate(iSCSITargetRef target, goto ERROR_AUTHENTICATE_CHAP; } + // If no error and the target returned an alias save it... + CFStringRef targetAlias; + if(!error && CFDictionaryGetValueIfPresent(authRsp,kRFC3720_Key_TargetAlias,(const void**)&targetAlias)) { + iSCSITargetSetAlias(target,targetAlias); + } + CFRelease(authCmd); CFRelease(authRsp); diff --git a/Source/User/iscsid/iSCSIAuth.h b/Source/User/iscsid/iSCSIAuth.h new file mode 100644 index 00000000..58257e4f --- /dev/null +++ b/Source/User/iscsid/iSCSIAuth.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ISCSI_AUTHMETHOD_H__ +#define __ISCSI_AUTHMETHOD_H__ + +#include +#include + +#include "iSCSITypes.h" +#include "iSCSIKernelInterfaceShared.h" + +/*! Authentication function defined in the authentication module + * (in the file iSCSIAuth.h). */ +errno_t iSCSIAuthNegotiate(iSCSIMutableTargetRef target, + iSCSIAuthRef initiatorAuth, + iSCSIAuthRef targetAuth, + SID sessionId, + CID connectionId, + enum iSCSILoginStatusCode * statusCode); + +/*! Authentication function defined in the authentication module + * (in the file iSCSIAuth.h). */ +errno_t iSCSIAuthInterrogate(iSCSITargetRef target, + SID sessionId, + CID connectionId, + enum iSCSIAuthMethods * authMethod, + enum iSCSILoginStatusCode * statusCode); + +#endif diff --git a/Source/User Tools/iSCSIDaemon.c b/Source/User/iscsid/iSCSIDaemon.c similarity index 76% rename from Source/User Tools/iSCSIDaemon.c rename to Source/User/iscsid/iSCSIDaemon.c index 819e7ac0..2cf07b50 100644 --- a/Source/User Tools/iSCSIDaemon.c +++ b/Source/User/iscsid/iSCSIDaemon.c @@ -1,12 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDaemon.c - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. - * @brief iSCSI user-space daemon +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - // BSD includes #include #include @@ -43,8 +62,9 @@ #include "iSCSISession.h" #include "iSCSIDiscovery.h" #include "iSCSIDaemonInterfaceShared.h" -#include "iSCSIPropertyList.h" +#include "iSCSIPreferences.h" #include "iSCSIDA.h" +#include "iSCSIAuthRights.h" // Used to notify daemon of power state changes @@ -65,6 +85,12 @@ static const int kiSCSIDaemonTimeoutMilliSec = 250; * were active when the system goes to sleep. */ CFMutableDictionaryRef activeTargets = NULL; +// Mutex lock used when preferences are being synchronized +pthread_mutex_t preferencesMutex = PTHREAD_MUTEX_INITIALIZER; + +/*! Preferences object used to syncrhonize iSCSI preferences. */ +iSCSIPreferencesRef preferences = NULL; + struct iSCSIDIncomingRequestInfo { CFSocketRef socket; @@ -131,6 +157,16 @@ const iSCSIDMsgUpdateDiscoveryRsp iSCSIDMsgUpdateDiscoveryRspInit = { .errorCode = 0, }; +const iSCSIDMsgPreferencesIOLockAndSyncRsp iSCSIDMsgPreferencesIOLockAndSyncRspInit = { + .funcCode = kiSCSIDPreferencesIOLockAndSync, + .errorCode = 0, +}; + +const iSCSIDMsgPreferencesIOUnlockAndSyncRsp iSCSIDMsgPreferencesIOUnlockAndSyncRspInit = { + .funcCode = kiSCSIDPreferencesIOUnlockAndSync, + .errorCode = 0, +}; + /*! Used for the logout process. */ typedef struct iSCSIDLogoutContext { int fd; @@ -141,12 +177,21 @@ typedef struct iSCSIDLogoutContext { } iSCSIDLogoutContext; +/*! Helper function. Updates the preferences object using application values. */ +void iSCSIDUpdatePreferencesFromAppValues() +{ + if(preferences != NULL) + iSCSIPreferencesRelease(preferences); + + preferences = iSCSIPreferencesCreateFromAppValues(CFSTR(CF_PREFERENCES_APP_ID)); +} + iSCSISessionConfigRef iSCSIDCreateSessionConfig(CFStringRef targetIQN) { iSCSIMutableSessionConfigRef config = iSCSISessionConfigCreateMutable(); - iSCSISessionConfigSetErrorRecoveryLevel(config,iSCSIPLGetErrorRecoveryLevelForTarget(targetIQN)); - iSCSISessionConfigSetMaxConnections(config,iSCSIPLGetMaxConnectionsForTarget(targetIQN)); + iSCSISessionConfigSetErrorRecoveryLevel(config,iSCSIPreferencesGetErrorRecoveryLevelForTarget(preferences,targetIQN)); + iSCSISessionConfigSetMaxConnections(config,iSCSIPreferencesGetMaxConnectionsForTarget(preferences,targetIQN)); return config; } @@ -158,19 +203,19 @@ iSCSIConnectionConfigRef iSCSIDCreateConnectionConfig(CFStringRef targetIQN, enum iSCSIDigestTypes digestType; - digestType = iSCSIPLGetDataDigestForTarget(targetIQN); + digestType = iSCSIPreferencesGetDataDigestForTarget(preferences,targetIQN); if(digestType == kiSCSIDigestInvalid) digestType = kiSCSIDigestNone; iSCSIConnectionConfigSetDataDigest(config,digestType); - digestType = iSCSIPLGetHeaderDigestForTarget(targetIQN); + digestType = iSCSIPreferencesGetHeaderDigestForTarget(preferences,targetIQN); if(digestType == kiSCSIDigestInvalid) digestType = kiSCSIDigestNone; - iSCSIConnectionConfigSetHeaderDigest(config,iSCSIPLGetHeaderDigestForTarget(targetIQN)); + iSCSIConnectionConfigSetHeaderDigest(config,iSCSIPreferencesGetHeaderDigestForTarget(preferences,targetIQN)); return config; } @@ -178,19 +223,19 @@ iSCSIConnectionConfigRef iSCSIDCreateConnectionConfig(CFStringRef targetIQN, iSCSIAuthRef iSCSIDCreateAuthenticationForTarget(CFStringRef targetIQN) { iSCSIAuthRef auth; - enum iSCSIAuthMethods authMethod = iSCSIPLGetTargetAuthenticationMethod(targetIQN); + enum iSCSIAuthMethods authMethod = iSCSIPreferencesGetTargetAuthenticationMethod(preferences,targetIQN); if(authMethod == kiSCSIAuthMethodCHAP) { - CFStringRef name = iSCSIPLCopyTargetCHAPName(targetIQN); - CFStringRef sharedSecret = iSCSIPLCopyTargetCHAPSecret(targetIQN); + CFStringRef name = iSCSIPreferencesCopyTargetCHAPName(preferences,targetIQN); + CFStringRef sharedSecret = iSCSIKeychainCopyCHAPSecretForNode(targetIQN); if(!name) { - asl_log(NULL,NULL,ASL_LEVEL_WARNING,"CHAP name for target has not been set, reverting to no authentication"); + asl_log(NULL,NULL,ASL_LEVEL_WARNING,"target CHAP name for target has not been set, reverting to no authentication"); auth = iSCSIAuthCreateNone(); } else if(!sharedSecret) { - asl_log(NULL,NULL,ASL_LEVEL_WARNING,"CHAP secret is missing or insufficient privileges to system keychain, reverting to no authentication"); + asl_log(NULL,NULL,ASL_LEVEL_WARNING,"target CHAP secret is missing or insufficient privileges to system keychain, reverting to no authentication"); auth = iSCSIAuthCreateNone(); } else { @@ -212,19 +257,21 @@ iSCSIAuthRef iSCSIDCreateAuthenticationForTarget(CFStringRef targetIQN) iSCSIAuthRef iSCSIDCreateAuthenticationForInitiator() { iSCSIAuthRef auth; - enum iSCSIAuthMethods authMethod = iSCSIPLGetInitiatorAuthenticationMethod(); + enum iSCSIAuthMethods authMethod = iSCSIPreferencesGetInitiatorAuthenticationMethod(preferences); if(authMethod == kiSCSIAuthMethodCHAP) { - CFStringRef name = iSCSIPLCopyInitiatorCHAPName(); - CFStringRef sharedSecret = iSCSIPLCopyInitiatorCHAPSecret(); + CFStringRef name = iSCSIPreferencesCopyInitiatorCHAPName(preferences); + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); + CFStringRef sharedSecret = iSCSIKeychainCopyCHAPSecretForNode(initiatorIQN); + CFRelease(initiatorIQN); if(!name) { - asl_log(NULL,NULL,ASL_LEVEL_WARNING,"CHAP name for target has not been set, reverting to no authentication."); + asl_log(NULL,NULL,ASL_LEVEL_WARNING,"initiator CHAP name for target has not been set, reverting to no authentication."); auth = iSCSIAuthCreateNone(); } else if(!sharedSecret) { - asl_log(NULL,NULL,ASL_LEVEL_WARNING,"CHAP secret is missing or insufficient privileges to system keychain, reverting to no authentication."); + asl_log(NULL,NULL,ASL_LEVEL_WARNING,"initiator CHAP secret is missing or insufficient privileges to system keychain, reverting to no authentication."); auth = iSCSIAuthCreateNone(); } else { @@ -243,7 +290,7 @@ iSCSIAuthRef iSCSIDCreateAuthenticationForInitiator() } errno_t iSCSIDLoginCommon(SID sessionId, - iSCSITargetRef target, + iSCSIMutableTargetRef target, iSCSIPortalRef portal, enum iSCSILoginStatusCode * statusCode) { @@ -298,7 +345,7 @@ errno_t iSCSIDLoginCommon(SID sessionId, } -errno_t iSCSIDLoginAllPortals(iSCSITargetRef target, +errno_t iSCSIDLoginAllPortals(iSCSIMutableTargetRef target, enum iSCSILoginStatusCode * statusCode) { CFIndex activeConnections = 0; @@ -338,7 +385,7 @@ errno_t iSCSIDLoginAllPortals(iSCSITargetRef target, // Add portals to the session until we've run out of portals to add or // reached the maximum connection limit CFStringRef portalAddress = NULL; - CFArrayRef portals = iSCSIPLCreateArrayOfPortalsForTarget(targetIQN); + CFArrayRef portals = iSCSIPreferencesCreateArrayOfPortalsForTarget(preferences,targetIQN); CFIndex portalIdx = 0; CFIndex portalCount = CFArrayGetCount(portals); @@ -347,7 +394,7 @@ errno_t iSCSIDLoginAllPortals(iSCSITargetRef target, portalAddress = CFArrayGetValueAtIndex(portals,portalIdx); // Get portal object and login - iSCSIPortalRef portal = iSCSIPLCopyPortalForTarget(targetIQN,portalAddress); + iSCSIPortalRef portal = iSCSIPreferencesCopyPortalForTarget(preferences,targetIQN,portalAddress); errorCode = iSCSIDLoginCommon(sessionId,target,portal,statusCode); iSCSIPortalRelease(portal); @@ -378,7 +425,7 @@ errno_t iSCSIDLoginAllPortals(iSCSITargetRef target, } -errno_t iSCSIDLoginWithPortal(iSCSITargetRef target, +errno_t iSCSIDLoginWithPortal(iSCSIMutableTargetRef target, iSCSIPortalRef portal, enum iSCSILoginStatusCode * statusCode) { @@ -432,12 +479,15 @@ errno_t iSCSIDLoginWithPortal(iSCSITargetRef target, errno_t iSCSIDLogin(int fd,iSCSIDMsgLoginCmd * cmd) { - CFDataRef targetData = NULL, portalData = NULL; - iSCSIDaemonRecvMsg(fd,0,&targetData,cmd->targetLength,&portalData,cmd->portalLength,NULL); - iSCSITargetRef target = NULL; + CFDataRef targetData = NULL, portalData = NULL, authorizationData = NULL; + iSCSIDaemonRecvMsg(fd,0,&authorizationData,cmd->authLength,&targetData,cmd->targetLength,&portalData,cmd->portalLength,NULL); + iSCSIMutableTargetRef target = NULL; + errno_t errorCode = 0; if(targetData) { - target = iSCSITargetCreateWithData(targetData); + iSCSITargetRef targetTemp = iSCSITargetCreateWithData(targetData); + target = iSCSITargetCreateMutableCopy(targetTemp); + iSCSITargetRelease(targetTemp); CFRelease(targetData); } @@ -448,21 +498,44 @@ errno_t iSCSIDLogin(int fd,iSCSIDMsgLoginCmd * cmd) CFRelease(portalData); } + AuthorizationRef authorization = NULL; + + // If authorization data is valid, create authorization object + if(authorizationData) { + AuthorizationExternalForm authorizationExtForm; + + CFDataGetBytes(authorizationData, + CFRangeMake(0,kAuthorizationExternalFormLength), + (UInt8 *)&authorizationExtForm.bytes); + + AuthorizationCreateFromExternalForm(&authorizationExtForm,&authorization); + CFRelease(authorizationData); + } + + // If authorization object is valid, get the necessary rights + if(authorization) { + if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthLoginRight) != errAuthorizationSuccess) + errorCode = EAUTH; + } + else + errorCode = EINVAL; + // If portal and target are valid, login with portal. Otherwise login to // target using all defined portals. - errno_t errorCode = 0; enum iSCSILoginStatusCode statusCode = kiSCSILoginInvalidStatusCode; // Synchronize property list - iSCSIPLSynchronize(); - - if(target && portal) - errorCode = iSCSIDLoginWithPortal(target,portal,&statusCode); - else if(target) - errorCode = iSCSIDLoginAllPortals(target,&statusCode); - else - errorCode = EINVAL; + iSCSIDUpdatePreferencesFromAppValues(); + if(!errorCode) { + if(target && portal) + errorCode = iSCSIDLoginWithPortal(target,portal,&statusCode); + else if(target) + errorCode = iSCSIDLoginAllPortals(target,&statusCode); + else + errorCode = EINVAL; + } + // Compose a response to send back to the client iSCSIDMsgLoginRsp rsp = iSCSIDMsgLoginRspInit; rsp.errorCode = errorCode; @@ -490,7 +563,9 @@ void iSCSIDLogoutComplete(iSCSITargetRef target,enum iSCSIDAOperationResult resu int fd = ctx->fd; errno_t errorCode = ctx->errorCode; iSCSIPortalRef portal = ctx->portal; - CFRelease(ctx->diskSession); + + if(ctx->diskSession) + CFRelease(ctx->diskSession); free(ctx); enum iSCSILogoutStatusCode statusCode = kiSCSILogoutInvalidStatusCode; @@ -552,8 +627,8 @@ void iSCSIDLogoutComplete(iSCSITargetRef target,enum iSCSIDAOperationResult resu errno_t iSCSIDLogout(int fd,iSCSIDMsgLogoutCmd * cmd) { - CFDataRef targetData = NULL, portalData = NULL; - iSCSIDaemonRecvMsg(fd,0,&targetData,cmd->targetLength,&portalData,cmd->portalLength,NULL); + CFDataRef targetData = NULL, portalData = NULL, authorizationData = NULL; + iSCSIDaemonRecvMsg(fd,0,&authorizationData,cmd->authLength,&targetData,cmd->targetLength,&portalData,cmd->portalLength,NULL); errno_t errorCode = 0; iSCSITargetRef target = NULL; @@ -569,11 +644,34 @@ errno_t iSCSIDLogout(int fd,iSCSIDMsgLogoutCmd * cmd) portal = iSCSIPortalCreateWithData(portalData); CFRelease(portalData); } + + AuthorizationRef authorization = NULL; + + // If authorization data is valid, create authorization object + if(authorizationData) { + AuthorizationExternalForm authorizationExtForm; + + CFDataGetBytes(authorizationData, + CFRangeMake(0,kAuthorizationExternalFormLength), + (UInt8 *)&authorizationExtForm.bytes); + + AuthorizationCreateFromExternalForm(&authorizationExtForm,&authorization); + CFRelease(authorizationData); + } + + // If authorization object is valid, get the necessary rights + if(authorization) { + if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthLoginRight) != errAuthorizationSuccess) + errorCode = EAUTH; + } + else + errorCode = EINVAL; + // See if there exists an active session for this target SID sessionId = iSCSIGetSessionIdForTarget(iSCSITargetGetIQN(target)); - if(sessionId == kiSCSIInvalidSessionId) + if(!errorCode && sessionId == kiSCSIInvalidSessionId) { CFStringRef errorString = CFStringCreateWithFormat( kCFAllocatorDefault,0, @@ -613,21 +711,24 @@ errno_t iSCSIDLogout(int fd,iSCSIDMsgLogoutCmd * cmd) // Unmount volumes if portal not specified (session logout) // or if portal is specified and is only connection... - iSCSIDLogoutContext * context = (iSCSIDLogoutContext*)malloc(sizeof(iSCSIDLogoutContext)); + iSCSIDLogoutContext * context; + context = (iSCSIDLogoutContext*)malloc(sizeof(iSCSIDLogoutContext)); context->fd = fd; - context->diskSession = DASessionCreate(kCFAllocatorDefault); context->portal = portal; context->errorCode = errorCode; + context->diskSession = NULL; - if(!errorCode) { - if(!portal || connectionCount == 1) { - DASessionScheduleWithRunLoop(context->diskSession,CFRunLoopGetMain(),kCFRunLoopDefaultMode); - iSCSIDAUnmountForTarget(context->diskSession,kDADiskUnmountOptionWhole,target,&iSCSIDLogoutComplete,context); - } - else { - iSCSIDLogoutComplete(target,kiSCSIDAOperationSuccess,context); - } + // Unmount and session logout + if(!errorCode && (!portal || connectionCount == 1)) + { + context->diskSession = DASessionCreate(kCFAllocatorDefault); + + DASessionScheduleWithRunLoop(context->diskSession,CFRunLoopGetMain(),kCFRunLoopDefaultMode); + iSCSIDAUnmountForTarget(context->diskSession,kDADiskUnmountOptionWhole,target,&iSCSIDLogoutComplete,context); } + // Portal logout only (or no logout and just a response to client if error) + else + iSCSIDLogoutComplete(target,kiSCSIDAOperationSuccess,context); return 0; } @@ -903,7 +1004,28 @@ errno_t iSCSIDCreateCFPropertiesForConnection(int fd, void * iSCSIDRunDiscovery(void * context) { - iSCSIDiscoveryRunSendTargets(); + CFDictionaryRef discoveryRecords = iSCSIDiscoveryCreateRecordsWithSendTargets(preferences); + + // Process discovery results if any + if(discoveryRecords) { + + pthread_mutex_lock(&preferencesMutex); + iSCSIDUpdatePreferencesFromAppValues(); + + const CFIndex count = CFDictionaryGetCount(discoveryRecords); + const void * keys[count]; + const void * values[count]; + CFDictionaryGetKeysAndValues(discoveryRecords,keys,values); + + for(CFIndex i = 0; i < count; i++) + iSCSIDiscoveryUpdatePreferencesWithDiscoveredTargets(preferences,keys[i],values[i]); + + iSCSIPreferencesSynchronzeAppValues(preferences); + pthread_mutex_unlock(&preferencesMutex); + + CFRelease(discoveryRecords); + } + pthread_mutex_unlock(&discoveryMutex); return NULL; @@ -950,11 +1072,11 @@ errno_t iSCSIDUpdateDiscovery(int fd, iSCSIDMsgUpdateDiscoveryCmd * cmd) { errno_t error = 0; - iSCSIPLSynchronize(); + iSCSIDUpdatePreferencesFromAppValues(); // Check whether SendTargets discovery is enabled, and get interval (sec) - Boolean discoveryEnabled = iSCSIPLGetSendTargetsDiscoveryEnable(); - CFTimeInterval interval = iSCSIPLGetSendTargetsDiscoveryInterval(); + Boolean discoveryEnabled = iSCSIPreferencesGetSendTargetsDiscoveryEnable(preferences); + CFTimeInterval interval = iSCSIPreferencesGetSendTargetsDiscoveryInterval(preferences); CFRunLoopTimerCallBack callout = &iSCSIDLaunchDiscoveryThread; // Remove existing timer if one exists @@ -979,7 +1101,6 @@ errno_t iSCSIDUpdateDiscovery(int fd, // Send back response iSCSIDMsgUpdateDiscoveryRsp rsp = iSCSIDMsgUpdateDiscoveryRspInit; rsp.errorCode = 0; - iSCSIPLSynchronize(); if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) error = EAGAIN; @@ -987,17 +1108,108 @@ errno_t iSCSIDUpdateDiscovery(int fd, return error; } +errno_t iSCSIDPreferencesIOLockAndSync(int fd,iSCSIDMsgPreferencesIOLockAndSyncCmd * cmd) +{ + // Verify that the client is authorized for the operation + CFDataRef authorizationData = NULL; + errno_t error = iSCSIDaemonRecvMsg(fd,0,&authorizationData,cmd->authorizationLength,NULL); + + AuthorizationRef authorization = NULL; + + // If authorization data is valid, create authorization object + if(authorizationData) { + AuthorizationExternalForm authorizationExtForm; + + CFDataGetBytes(authorizationData, + CFRangeMake(0,kAuthorizationExternalFormLength), + (UInt8 *)&authorizationExtForm.bytes); + + AuthorizationCreateFromExternalForm(&authorizationExtForm,&authorization); + CFRelease(authorizationData); + } + + // If authorization object is valid, get the necessary rights + if(authorization) { + if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthModifyRight) != errAuthorizationSuccess) + error = EAUTH; + } + else + error = EINVAL; + + // If we have the necessary rights, lock + if(!error) { + pthread_mutex_lock(&preferencesMutex); + } + + // Compose a response to send back to the client + iSCSIDMsgPreferencesIOLockAndSyncRsp rsp = iSCSIDMsgPreferencesIOLockAndSyncRspInit; + rsp.errorCode = error; + + if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EAGAIN; + + return 0; +} + + +errno_t iSCSIDPreferencesIOUnlockAndSync(int fd,iSCSIDMsgPreferencesIOUnlockAndSyncCmd * cmd) +{ + // Verify that the client is authorized for the operation + CFDataRef authorizationData = NULL, preferencesData = NULL; + errno_t error = iSCSIDaemonRecvMsg(fd,0,&authorizationData,cmd->authorizationLength,&preferencesData,cmd->preferencesLength,NULL); + + AuthorizationRef authorization = NULL; + + if(authorizationData) { + AuthorizationExternalForm authorizationExtForm; + + CFDataGetBytes(authorizationData, + CFRangeMake(0,kAuthorizationExternalFormLength), + (UInt8 *)&authorizationExtForm.bytes); + + AuthorizationCreateFromExternalForm(&authorizationExtForm,&authorization); + CFRelease(authorizationData); + } + + iSCSIPreferencesRef preferencesToSync = NULL; + + if(preferencesData) { + preferencesToSync = iSCSIPreferencesCreateWithData(preferencesData); + CFRelease(preferencesData); + } + + // If no errors and the daemon was previously locked out for sync + if(!error && preferencesToSync && pthread_mutex_trylock(&preferencesMutex)) + { + iSCSIPreferencesSynchronzeAppValues(preferencesToSync); + iSCSIPreferencesUpdateWithAppValues(preferences); + } + pthread_mutex_unlock(&preferencesMutex); + + if(preferencesToSync) + iSCSIPreferencesRelease(preferencesToSync); + + // Compose a response to send back to the client + iSCSIDMsgPreferencesIOUnlockAndSyncRsp rsp = iSCSIDMsgPreferencesIOUnlockAndSyncRspInit; + rsp.errorCode = error; + + if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EAGAIN; + + return 0; +} + /*! Automatically logs in to targets that were specified for auto-login. * Used during startup of the daemon to log in to either static * dynamic targets for which the auto-login option is enabled. */ void iSCSIDAutoLogin() { // Iterate over all targets and auto-login as required - iSCSIPLSynchronize(); + iSCSIDUpdatePreferencesFromAppValues(); CFArrayRef targets = NULL; - if(!(targets = iSCSIPLCreateArrayOfTargets())) + if(!(targets = iSCSIPreferencesCreateArrayOfTargets(preferences))) return; CFIndex targetsCount = CFArrayGetCount(targets); @@ -1006,8 +1218,10 @@ void iSCSIDAutoLogin() { CFStringRef targetIQN = CFArrayGetValueAtIndex(targets,idx); - if(iSCSIPLGetAutoLoginForTarget(targetIQN)) { - iSCSITargetRef target = iSCSIPLCopyTarget(targetIQN); + if(iSCSIPreferencesGetAutoLoginForTarget(preferences,targetIQN)) { + iSCSITargetRef targetTemp = iSCSIPreferencesCopyTarget(preferences,targetIQN); + iSCSIMutableTargetRef target = iSCSITargetCreateMutableCopy(targetTemp); + iSCSITargetRelease(targetTemp); enum iSCSILoginStatusCode statusCode; iSCSIDLoginAllPortals(target,&statusCode); iSCSITargetRelease(target); @@ -1113,7 +1327,7 @@ void iSCSIDPrepareForSystemSleep() DASessionScheduleWithRunLoop(diskSession,CFRunLoopGetMain(),kCFRunLoopDefaultMode); iSCSIDAUnmountForTarget(diskSession,kDADiskUnmountOptionWhole,target,&iSCSIDPrepareForSystemSleepComplete,(void*)sessionId); - iSCSITargetRelease(target); +// iSCSITargetRelease(target); } CFRetain(diskSession); @@ -1182,7 +1396,6 @@ void iSCSIDProcessIncomingRequest(void * info) int fd = reqInfo->fd; if(fd != 0 && recv(fd,&cmd,sizeof(cmd),MSG_WAITALL) == sizeof(cmd)) { - errno_t error = 0; switch(cmd.funcCode) { @@ -1206,9 +1419,14 @@ void iSCSIDProcessIncomingRequest(void * info) error = iSCSIDCreateCFPropertiesForConnection(fd,(iSCSIDMsgCreateCFPropertiesForConnectionCmd*)&cmd); break; case kiSCSIDUpdateDiscovery: error = iSCSIDUpdateDiscovery(fd,(iSCSIDMsgUpdateDiscoveryCmd*)&cmd); break; - default: + case kiSCSIDPreferencesIOLockAndSync: + error = iSCSIDPreferencesIOLockAndSync(fd,(iSCSIDMsgPreferencesIOLockAndSyncCmd*)&cmd); break; + case kiSCSIDPreferencesIOUnlockAndSync: + error = iSCSIDPreferencesIOUnlockAndSync(fd,(iSCSIDMsgPreferencesIOUnlockAndSyncCmd*)&cmd); break; + default: CFSocketInvalidate(reqInfo->socket); reqInfo->fd = 0; + pthread_mutex_unlock(&preferencesMutex); }; } @@ -1252,18 +1470,17 @@ void iSCSIDAcceptConnection(CFSocketRef socket, iSCSIDProcessIncomingRequest(info); } - /*! iSCSI daemon entry point. */ int main(void) { // Initialize logging - asl_object_t log = asl_open(NULL,NULL,ASL_OPT_STDERR); + aslclient log = asl_open(NULL,NULL,ASL_OPT_STDERR); // Read configuration parameters from the iSCSI property list - iSCSIPLSynchronize(); - + iSCSIDUpdatePreferencesFromAppValues(); + // Update initiator name and alias internally - CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN(); + CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); if(initiatorIQN) { iSCSISetInitiatorName(initiatorIQN); @@ -1273,7 +1490,7 @@ int main(void) asl_log(NULL,NULL,ASL_LEVEL_WARNING,"initiator IQN not set, reverting to internal default"); } - CFStringRef initiatorAlias = iSCSIPLCopyInitiatorAlias(); + CFStringRef initiatorAlias = iSCSIPreferencesCopyInitiatorAlias(preferences); if(initiatorAlias) { iSCSISetInitiatorAlias(initiatorAlias); @@ -1363,6 +1580,12 @@ int main(void) // functions and receive notifications from the kernel). iSCSIInitialize(CFRunLoopGetMain()); + // Setup authorization rights if none exist + AuthorizationRef authorization; + AuthorizationCreate(NULL,NULL,0,&authorization); + iSCSIAuthRightsInitialize(authorization); + AuthorizationFree(authorization,kAuthorizationFlagDefaults); + // Sync discovery parameters upon startup iSCSIDUpdateDiscovery(0,NULL); diff --git a/Source/User Tools/iSCSIDiscovery.c b/Source/User/iscsid/iSCSIDiscovery.c similarity index 56% rename from Source/User Tools/iSCSIDiscovery.c rename to Source/User/iscsid/iSCSIDiscovery.c index 7db17484..bb69e6a4 100644 --- a/Source/User Tools/iSCSIDiscovery.c +++ b/Source/User/iscsid/iSCSIDiscovery.c @@ -1,14 +1,35 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIDiscovery.c - * @version 1.0 - * @copyright (c) 2014-2015 Nareg Sinenian. All rights reserved. - * @brief Discovery functions for use by iscsid. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIDiscovery.h" -errno_t iSCSIDiscoveryAddTargetForSendTargets(CFStringRef targetIQN, +errno_t iSCSIDiscoveryAddTargetForSendTargets(iSCSIPreferencesRef preferences, + CFStringRef targetIQN, iSCSIDiscoveryRecRef discoveryRec, CFStringRef discoveryPortal) { @@ -31,18 +52,25 @@ errno_t iSCSIDiscoveryAddTargetForSendTargets(CFStringRef targetIQN, continue; // Add portal to target, or add target as necessary - if(iSCSIPLContainsTarget(targetIQN)) - iSCSIPLSetPortalForTarget(targetIQN,portal); + if(iSCSIPreferencesContainsTarget(preferences,targetIQN)) + iSCSIPreferencesSetPortalForTarget(preferences,targetIQN,portal); else - iSCSIPLAddDynamicTargetForSendTargets(targetIQN,portal,discoveryPortal); + iSCSIPreferencesAddDynamicTargetForSendTargets(preferences,targetIQN,portal,discoveryPortal); } } return 0; } -errno_t iSCSIDiscoveryProcessSendTargetsResults(CFStringRef discoveryPortal, - iSCSIDiscoveryRecRef discoveryRec) +/*! Updates an iSCSI preference sobject with information about targets as + * contained in the provided discovery record. + * @param preferences an iSCSI preferences object. + * @param discoveryPortal the portal (address) that was used to perform discovery. + * @param discoveryRec the discovery record resulting from the discovery operation. + * @return an error code indicating the result of the operation. */ +errno_t iSCSIDiscoveryUpdatePreferencesWithDiscoveredTargets(iSCSIPreferencesRef preferences, + CFStringRef discoveryPortal, + iSCSIDiscoveryRecRef discoveryRec) { CFArrayRef targets = iSCSIDiscoveryRecCreateArrayOfTargets(discoveryRec); @@ -60,8 +88,8 @@ errno_t iSCSIDiscoveryProcessSendTargetsResults(CFStringRef discoveryPortal, // Target exists with static (or other configuration). In // this case we do nothing, log a message and move on. - if(iSCSIPLContainsTarget(targetIQN) && - iSCSIPLGetTargetConfigType(targetIQN) != kiSCSITargetConfigDynamicSendTargets) + if(iSCSIPreferencesContainsTarget(preferences,targetIQN) && + iSCSIPreferencesGetTargetConfigType(preferences,targetIQN) != kiSCSITargetConfigDynamicSendTargets) { CFStringRef statusString = CFStringCreateWithFormat( kCFAllocatorDefault,0, @@ -75,7 +103,7 @@ errno_t iSCSIDiscoveryProcessSendTargetsResults(CFStringRef discoveryPortal, // Target doesn't exist, or target exists with SendTargets // configuration (add or update as necessary) else { - iSCSIDiscoveryAddTargetForSendTargets(targetIQN,discoveryRec,discoveryPortal); + iSCSIDiscoveryAddTargetForSendTargets(preferences,targetIQN,discoveryRec,discoveryPortal); CFStringRef statusString = CFStringCreateWithFormat( kCFAllocatorDefault,0, CFSTR("discovered target %@ over discovery portal %@."), @@ -94,7 +122,7 @@ errno_t iSCSIDiscoveryProcessSendTargetsResults(CFStringRef discoveryPortal, // Are there any targets that must be removed? Cross-check existing // list against the list we just built... - CFArrayRef existingTargets = iSCISPLCreateArrayOfDynamicTargetsForSendTargets(discoveryPortal); + CFArrayRef existingTargets = iSCSIPreferencesCreateArrayOfDynamicTargetsForSendTargets(preferences,discoveryPortal); targetCount = CFArrayGetCount(existingTargets); for(CFIndex targetIdx = 0; targetIdx < targetCount; targetIdx++) @@ -111,33 +139,44 @@ errno_t iSCSIDiscoveryProcessSendTargetsResults(CFStringRef discoveryPortal, if(sessionId != kiSCSIInvalidSessionId) iSCSILogoutSession(sessionId,&statusCode); - iSCSIPLRemoveTarget(targetIQN); + iSCSIPreferencesRemoveTarget(preferences,targetIQN); } } CFRelease(discTargets); CFRelease(existingTargets); - - iSCSIPLSynchronize(); + return 0; } -void iSCSIDiscoveryRunSendTargets() +/*! Scans all iSCSI discovery portals found in iSCSI preferences + * for targets (SendTargets). Returns a dictionary of key-value pairs + * with discovery record objects as values and discovery portal names + * as keys. + * @param preferences an iSCSI preferences object. + * @return a dictionary key-value pairs of dicovery portal names (addresses) + * and the discovery records associated with the result of SendTargets + * discovery of those portals. */ +CFDictionaryRef iSCSIDiscoveryCreateRecordsWithSendTargets(iSCSIPreferencesRef preferences) { - // Obtain a list of SendTargets portals from the property list - iSCSIPLSynchronize(); - - CFArrayRef portals = iSCSIPLCreateArrayOfPortalsForSendTargetsDiscovery(); + if(!preferences) + return NULL; + + CFArrayRef portals = iSCSIPreferencesCreateArrayOfPortalsForSendTargetsDiscovery(preferences); // Quit if no discovery portals are defined if(!portals) - return; + return NULL; CFIndex portalCount = CFArrayGetCount(portals); CFStringRef discoveryPortal = NULL; iSCSIPortalRef portal = NULL; + CFMutableDictionaryRef discoveryRecords = CFDictionaryCreateMutable(kCFAllocatorDefault,0, + &kiSCSITypeDictionaryKeyCallbacks, + &kiSCSITypeDictionaryValueCallbacks); + for(CFIndex idx = 0; idx < portalCount; idx++) { discoveryPortal = CFArrayGetValueAtIndex(portals,idx); @@ -145,7 +184,7 @@ void iSCSIDiscoveryRunSendTargets() if(!discoveryPortal) continue; - portal = iSCSIPLCopySendTargetsDiscoveryPortal(discoveryPortal); + portal = iSCSIPreferencesCopySendTargetsDiscoveryPortal(preferences,discoveryPortal); if(!portal) continue; @@ -175,13 +214,16 @@ void iSCSIDiscoveryRunSendTargets() CFRelease(errorString); } else { - // Now parse discovery results, add new targets and remove stale targets + // Queue discovery record so that it can be processes later if(discoveryRec) { - iSCSIDiscoveryProcessSendTargetsResults(discoveryPortal,discoveryRec); + CFDictionarySetValue(discoveryRecords,discoveryPortal,discoveryRec); iSCSIDiscoveryRecRelease(discoveryRec); } } } - - iSCSIPLSynchronize(); + + // Release the array of discovery portals + CFRelease(portals); + + return discoveryRecords; } diff --git a/Source/User/iscsid/iSCSIDiscovery.h b/Source/User/iscsid/iSCSIDiscovery.h new file mode 100644 index 00000000..3af95fe8 --- /dev/null +++ b/Source/User/iscsid/iSCSIDiscovery.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ISCSI_DISCOVERY_H__ +#define __ISCSI_DISCOVERY_H__ + +#include +#include + +#include "iSCSISession.h" +#include "iSCSITypes.h" +#include "iSCSIPreferences.h" + + +/*! Scans all iSCSI discovery portals found in iSCSI preferences + * for targets (SendTargets). Returns a dictionary of key-value pairs + * with discovery record objects as values and discovery portal names + * as keys. + * @param preferences an iSCSI preferences object. + * @return a dictionary key-value pairs of dicovery portal names (addresses) + * and the discovery records associated with the result of SendTargets + * discovery of those portals. */ +CFDictionaryRef iSCSIDiscoveryCreateRecordsWithSendTargets(iSCSIPreferencesRef preferences); + +/*! Updates an iSCSI preference sobject with information about targets as + * contained in the provided discovery record. + * @param preferences an iSCSI preferences object. + * @param discoveryPortal the portal (address) that was used to perform discovery. + * @param discoveryRec the discovery record resulting from the discovery operation. + * @return an error code indicating the result of the operation. */ +errno_t iSCSIDiscoveryUpdatePreferencesWithDiscoveredTargets(iSCSIPreferencesRef preferences, + CFStringRef discoveryPortal, + iSCSIDiscoveryRecRef discoveryRec); + +#endif /* defined(__ISCSI_DISCOVERY_H__) */ diff --git a/Source/User Tools/iSCSIKernelInterface.c b/Source/User/iscsid/iSCSIKernelInterface.c similarity index 91% rename from Source/User Tools/iSCSIKernelInterface.c rename to Source/User/iscsid/iSCSIKernelInterface.c index 7dde5829..149e0c3d 100644 --- a/Source/User Tools/iSCSIKernelInterface.c +++ b/Source/User/iscsid/iSCSIKernelInterface.c @@ -1,12 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIKernelInterface.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Interface to the iSCSI kernel extension. Do not include this - * file directly or call these functions. They are used internally - * by the session layer to process login, logout, and other iSCSI - * requests. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIKernelInterface.h" @@ -69,6 +86,7 @@ CFRunLoopSourceRef iSCSIKernelCreateRunLoopSource() { if(notificationPort) return CFMachPortCreateRunLoopSource(kCFAllocatorDefault,notificationPort,0); + return NULL; } @@ -161,13 +179,6 @@ errno_t iSCSIKernelCreateSession(CFStringRef targetIQN, void * params[kNumParams]; size_t paramSize[kNumParams]; - params[0] = (void*)CFStringGetCStringPtr(targetIQN,kCFStringEncodingASCII); - params[1] = (void*)CFStringGetCStringPtr(portalAddress,kCFStringEncodingASCII); - params[2] = (void*)CFStringGetCStringPtr(portalPort,kCFStringEncodingASCII); - params[3] = (void*)CFStringGetCStringPtr(hostInterface,kCFStringEncodingASCII); - params[4] = (void*)portalSockAddr; - params[5] = (void*)hostSockAddr; - // Add one for string lengths to copy the NULL character (CFGetStringLength // does not include the length of the NULL terminator) paramSize[0] = CFStringGetLength(targetIQN) + 1; @@ -177,6 +188,19 @@ errno_t iSCSIKernelCreateSession(CFStringRef targetIQN, paramSize[4] = sizeof(struct sockaddr_storage); paramSize[5] = sizeof(struct sockaddr_storage); + // Populate parameters + params[0] = malloc(paramSize[0]); + params[1] = malloc(paramSize[1]); + params[2] = malloc(paramSize[2]); + params[3] = malloc(paramSize[3]); + params[4] = (void*)portalSockAddr; + params[5] = (void*)hostSockAddr; + + CFStringGetCString(targetIQN,params[0],paramSize[0],kCFStringEncodingASCII); + CFStringGetCString(portalAddress,params[1],paramSize[1],kCFStringEncodingASCII); + CFStringGetCString(portalPort,params[2],paramSize[2],kCFStringEncodingASCII); + CFStringGetCString(hostInterface,params[3],paramSize[3],kCFStringEncodingASCII); + // The input buffer will first have eight bytes to denote the length of // the portion that follows. So for each of the six input parameters, // we'll have six UInt64 blocks that indicate the size up front. @@ -214,6 +238,12 @@ errno_t iSCSIKernelCreateSession(CFStringRef targetIQN, IOConnectCallMethod(connection,kiSCSICreateSession,inputs,inputCnt, inputStruct,inputStructSize,output,&outputCnt,0,0); + // Free allocated memory + free(params[0]); + free(params[1]); + free(params[2]); + free(params[3]); + if(result == kIOReturnSuccess && outputCnt == expOutputCnt) { *sessionId = (UInt16)output[0]; *connectionId = (UInt32)output[1]; @@ -324,12 +354,6 @@ errno_t iSCSIKernelCreateConnection(SID sessionId, void * params[kNumParams]; size_t paramSize[kNumParams]; - params[0] = (void*)CFStringGetCStringPtr(portalAddress,kCFStringEncodingASCII); - params[1] = (void*)CFStringGetCStringPtr(portalPort,kCFStringEncodingASCII); - params[2] = (void*)CFStringGetCStringPtr(hostInterface,kCFStringEncodingASCII); - params[3] = (void*)portalSockAddr; - params[4] = (void*)hostSockAddr; - // Add one for string lengths to copy the NULL character (CFGetStringLength // does not include the length of the NULL terminator) paramSize[0] = CFStringGetLength(portalAddress) + 1; @@ -338,6 +362,16 @@ errno_t iSCSIKernelCreateConnection(SID sessionId, paramSize[3] = sizeof(struct sockaddr_storage); paramSize[4] = sizeof(struct sockaddr_storage); + params[0] = malloc(paramSize[0]); + params[1] = malloc(paramSize[1]); + params[2] = malloc(paramSize[2]); + params[3] = (void*)portalSockAddr; + params[4] = (void*)hostSockAddr; + + CFStringGetCString(portalAddress,params[0],paramSize[0],kCFStringEncodingASCII); + CFStringGetCString(portalPort,params[1],paramSize[1],kCFStringEncodingASCII); + CFStringGetCString(hostInterface,params[2],paramSize[2],kCFStringEncodingASCII); + // The input buffer will first have eight bytes to denote the length of // the portion that follows. So for each of the six input parameters, // we'll have six UInt64 blocks that indicate the size up front. @@ -375,6 +409,11 @@ errno_t iSCSIKernelCreateConnection(SID sessionId, IOConnectCallMethod(connection,kiSCSICreateConnection,inputs,inputCnt,inputStruct, inputStructSize,output,&outputCnt,0,0); + // Free memory + free(params[0]); + free(params[1]); + free(params[2]); + if(result == kIOReturnSuccess && outputCnt == expOutputCnt) { *connectionId = (UInt32)output[0]; errno_t error = (errno_t)output[1]; @@ -681,14 +720,24 @@ SID iSCSIKernelGetSessionIdForTargetIQN(CFStringRef targetIQN) const UInt32 expOutputCnt = 1; UInt64 output[expOutputCnt]; UInt32 outputCnt = expOutputCnt; + + const int targetIQNBufferSize = (int)CFStringGetLength(targetIQN)+1; + char * targetIQNBuffer = (char *)malloc(targetIQNBufferSize); + if(!CFStringGetCString(targetIQN,targetIQNBuffer,targetIQNBufferSize,kCFStringEncodingASCII)) + { + free(targetIQNBuffer); + return kiSCSIInvalidSessionId; + } kern_return_t result = IOConnectCallMethod( connection, kiSCSIGetSessionIdForTargetIQN,0,0, - (const void*)CFStringGetCStringPtr(targetIQN,kCFStringEncodingASCII), - CFStringGetLength(targetIQN)+1, + targetIQNBuffer, + targetIQNBufferSize, output,&outputCnt,0,0); + free(targetIQNBuffer); + if(result == kIOReturnSuccess && outputCnt == expOutputCnt) return (SID)output[0]; @@ -713,13 +762,23 @@ CID iSCSIKernelGetConnectionIdForPortalAddress(SID sessionId, UInt64 output[expOutputCnt]; UInt32 outputCnt = expOutputCnt; + const int portalAddressBufferSize = (int)CFStringGetLength(portalAddress)+1; + char * portalAddressBuffer = (char*)malloc(portalAddressBufferSize); + if(!CFStringGetCString(portalAddress,portalAddressBuffer,portalAddressBufferSize,kCFStringEncodingASCII)) + { + free(portalAddressBuffer); + return EINVAL; + } + kern_return_t result = IOConnectCallMethod(connection,kiSCSIGetConnectionIdForPortalAddress, &input,inputCnt, - CFStringGetCStringPtr(portalAddress,kCFStringEncodingASCII), - CFStringGetLength(portalAddress)+1, + portalAddressBuffer, + portalAddressBufferSize, output,&outputCnt,0,0); + free(portalAddressBuffer); + if(result != kIOReturnSuccess || outputCnt != expOutputCnt) return kiSCSIInvalidConnectionId; diff --git a/Source/User Tools/iSCSIKernelInterface.h b/Source/User/iscsid/iSCSIKernelInterface.h similarity index 90% rename from Source/User Tools/iSCSIKernelInterface.h rename to Source/User/iscsid/iSCSIKernelInterface.h index cd07430c..a5410d3e 100644 --- a/Source/User Tools/iSCSIKernelInterface.h +++ b/Source/User/iscsid/iSCSIKernelInterface.h @@ -1,12 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIKernelInterface.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief Interface to the iSCSI kernel extension. Do not include this - * file directly or call these functions. They are used internally - * by the session layer to process login, logout, and other iSCSI - * requests. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_KERNEL_INTERFACE_H__ diff --git a/Source/User Tools/iSCSIPDUUser.c b/Source/User/iscsid/iSCSIPDUUser.c similarity index 86% rename from Source/User Tools/iSCSIPDUUser.c rename to Source/User/iscsid/iSCSIPDUUser.c index c2d7ec91..29b2a85f 100644 --- a/Source/User Tools/iSCSIPDUUser.c +++ b/Source/User/iscsid/iSCSIPDUUser.c @@ -1,14 +1,29 @@ - /*! - * @author Nareg Sinenian - * @file iSCSIPDUUser.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI PDU functions. These functions cannot be used - * within the kernel and are intended for use within a daemon on - * Mac OS. They make extensive use of Core Foundation and allow - * for allocation, deallocation, transmission and reception of - * iSCSI PDU components, including definitions of basic header - * segments for various PDUs and data segments. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSIPDUUser.h" @@ -227,6 +242,9 @@ void iSCSIPDUPopulateWithTextCommand(const void * key, const void * value, void * posTracker) { + const int MAX_KEY_SIZE = 100; + const int MAX_VAL_SIZE = 100; + // Ensure pointer to data segment is valid if(posTracker) { @@ -234,13 +252,14 @@ void iSCSIPDUPopulateWithTextCommand(const void * key, CFIndex valueByteSize = CFStringGetLength((CFStringRef)value); CFStringEncoding stringEncoding = kCFStringEncodingUTF8; - const char * keyCString = - CFStringGetCStringPtr((CFStringRef)key,stringEncoding); - const char * valueCString = - CFStringGetCStringPtr((CFStringRef)value,stringEncoding); + char keyCString[MAX_KEY_SIZE]; + char valueCString[MAX_VAL_SIZE]; + + Boolean validKeyCString = CFStringGetCString(key,keyCString,MAX_KEY_SIZE,stringEncoding); + Boolean validValueCString = CFStringGetCString(value,valueCString,MAX_VAL_SIZE,stringEncoding); // If both strings are valid C-strings, copy them into the PDU - if(keyCString && valueCString) + if(validKeyCString && validValueCString) { iSCSIPDUDataSegmentTracker * position = (iSCSIPDUDataSegmentTracker*)posTracker; diff --git a/Source/User Tools/iSCSIPDUUser.h b/Source/User/iscsid/iSCSIPDUUser.h similarity index 88% rename from Source/User Tools/iSCSIPDUUser.h rename to Source/User/iscsid/iSCSIPDUUser.h index 15f08c1c..6f2eaf74 100644 --- a/Source/User Tools/iSCSIPDUUser.h +++ b/Source/User/iscsid/iSCSIPDUUser.h @@ -1,14 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIPDUUser.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI PDU functions. These functions cannot be used - * within the kernel and are intended for use within a daemon on - * Mac OS. They make extensive use of Core Foundation and allow - * for allocation, deallocation, transmission and reception of - * iSCSI PDU components, including definitions of basic header - * segments for various PDUs and data segments. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_PDU_USER_H__ diff --git a/Source/User Tools/iSCSIQueryTarget.c b/Source/User/iscsid/iSCSIQueryTarget.c similarity index 85% rename from Source/User Tools/iSCSIQueryTarget.c rename to Source/User/iscsid/iSCSIQueryTarget.c index 593b8d4b..da1d6ebd 100644 --- a/Source/User Tools/iSCSIQueryTarget.c +++ b/Source/User/iscsid/iSCSIQueryTarget.c @@ -1,13 +1,31 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIQueryTarget.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI query function. Used throughout the login - * process to perform parameter negotiation and login. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ - #include "iSCSIQueryTarget.h" #include "iSCSIKernelInterface.h" diff --git a/Source/User Tools/iSCSIQueryTarget.h b/Source/User/iscsid/iSCSIQueryTarget.h similarity index 72% rename from Source/User Tools/iSCSIQueryTarget.h rename to Source/User/iscsid/iSCSIQueryTarget.h index c8741101..443aad84 100644 --- a/Source/User Tools/iSCSIQueryTarget.h +++ b/Source/User/iscsid/iSCSIQueryTarget.h @@ -1,10 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSIQueryTarget.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI query function. Used throughout the login - * process to perform parameter negotiation and login. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_QUERY_TARGET_H__ diff --git a/Source/User Tools/iSCSISession.c b/Source/User/iscsid/iSCSISession.c similarity index 96% rename from Source/User Tools/iSCSISession.c rename to Source/User/iscsid/iSCSISession.c index 5cc31cfd..5cf1e7f3 100644 --- a/Source/User Tools/iSCSISession.c +++ b/Source/User/iscsid/iSCSISession.c @@ -1,12 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSISession.c - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI session management functions. This library - * depends on the user-space iSCSI PDU library to login, logout - * and perform discovery functions on iSCSI target nodes. It - * also relies on the kernel layer for access to kext. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "iSCSISession.h" @@ -124,7 +141,7 @@ void iSCSINegotiateBuildSWDictNormal(iSCSISessionConfigRef sessCfg, CFDictionaryAddValue(sessCmd,kRFC3720_Key_MaxConnections,value); CFRelease(value); - CFDictionaryAddValue(sessCmd,kRFC3720_Key_InitialR2T,kRFC3720_Value_No); + CFDictionaryAddValue(sessCmd,kRFC3720_Key_InitialR2T,kRFC3720_Value_Yes); CFDictionaryAddValue(sessCmd,kRFC3720_Key_ImmediateData,kRFC3720_Value_Yes); value = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("%u"),kRFC3720_MaxBurstLength); @@ -458,7 +475,7 @@ errno_t iSCSINegotiateParseCWDict(SID sessionId, return 0; } -errno_t iSCSINegotiateSession(iSCSITargetRef target, +errno_t iSCSINegotiateSession(iSCSIMutableTargetRef target, SID sessionId, CID connectionId, iSCSISessionConfigRef sessCfg, @@ -521,6 +538,12 @@ errno_t iSCSINegotiateSession(iSCSITargetRef target, error = iSCSINegotiateParseCWDict(sessionId,connectionId,sessCmd,sessRsp); } + // If no error and the target returned an alias save it... + CFStringRef targetAlias; + if(!error && CFDictionaryGetValueIfPresent(sessRsp,kRFC3720_Key_TargetAlias,(const void **)&targetAlias)) { + iSCSITargetSetAlias(target,targetAlias); + } + CFRelease(sessCmd); CFRelease(sessRsp); return error; @@ -768,7 +791,9 @@ errno_t iSCSILoginConnection(SID sessionId, if(error || *connectionId == kiSCSIInvalidConnectionId) return EAGAIN; - iSCSITargetRef target = iSCSICreateTargetForSessionId(sessionId); + iSCSITargetRef targetTemp = iSCSICreateTargetForSessionId(sessionId); + iSCSIMutableTargetRef target = iSCSITargetCreateMutableCopy(targetTemp); + iSCSITargetRelease(targetTemp); // If no error, authenticate (negotiate security parameters) if(!error && *statusCode == kiSCSILoginSuccess) @@ -826,7 +851,7 @@ errno_t iSCSILogoutConnection(SID sessionId, * @param connectionId the new connection identifier. * @param statusCode iSCSI response code indicating operation status. * @return an error code indicating whether the operation was successful. */ -errno_t iSCSILoginSession(iSCSITargetRef target, +errno_t iSCSILoginSession(iSCSIMutableTargetRef target, iSCSIPortalRef portal, iSCSIAuthRef initiatorAuth, iSCSIAuthRef targetAuth, @@ -1545,10 +1570,17 @@ void iSCSISessionHandleKernelNotifications(enum iSCSIKernelNotificationTypes typ errno_t iSCSIInitialize(CFRunLoopRef rl) { errno_t error = iSCSIKernelInitialize(&iSCSISessionHandleKernelNotifications); - - CFRunLoopSourceRef source = iSCSIKernelCreateRunLoopSource(); - CFRunLoopAddSource(rl,source,kCFRunLoopDefaultMode); + if(!error) { + CFRunLoopSourceRef source; + + // Create a run loop source tied to the kernel notification system; + // if fail then kext may not be loaded, try again later + if((source = iSCSIKernelCreateRunLoopSource())) + CFRunLoopAddSource(rl,source,kCFRunLoopDefaultMode); + else + error = EAGAIN; + } return error; } diff --git a/Source/User Tools/iSCSISession.h b/Source/User/iscsid/iSCSISession.h similarity index 86% rename from Source/User Tools/iSCSISession.h rename to Source/User/iscsid/iSCSISession.h index 8b718558..dd7c235a 100644 --- a/Source/User Tools/iSCSISession.h +++ b/Source/User/iscsid/iSCSISession.h @@ -1,12 +1,29 @@ -/*! - * @author Nareg Sinenian - * @file iSCSISession.h - * @version 1.0 - * @copyright (c) 2013-2015 Nareg Sinenian. All rights reserved. - * @brief User-space iSCSI session management functions. This library - * depends on the user-space iSCSI PDU library to login, logout - * and perform discovery functions on iSCSI target nodes. It - * also relies on the kernel layer for access to kext. +/* + * Copyright (c) 2016, Nareg Sinenian + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ISCSI_SESSION_H__ @@ -45,7 +62,7 @@ errno_t iSCSICleanup(); * @param connectionId the new connection identifier. * @param statusCode iSCSI response code indicating operation status. * @return an error code indicating whether the operation was successful. */ -errno_t iSCSILoginSession(iSCSITargetRef target, +errno_t iSCSILoginSession(iSCSIMutableTargetRef target, iSCSIPortalRef portal, iSCSIAuthRef initiatorAuth, iSCSIAuthRef targetAuth, diff --git a/Source/User Tools/iscsid.8 b/Source/User/iscsid/iscsid.8 similarity index 100% rename from Source/User Tools/iscsid.8 rename to Source/User/iscsid/iscsid.8 diff --git a/iSCSIInitiator.xcodeproj/project.pbxproj b/iSCSIInitiator.xcodeproj/project.pbxproj index bc07a28d..4216027b 100644 --- a/iSCSIInitiator.xcodeproj/project.pbxproj +++ b/iSCSIInitiator.xcodeproj/project.pbxproj @@ -11,39 +11,51 @@ 2B4A60371A3E6F690006AFCC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5935C21810DF7100FFC3D3 /* IOKit.framework */; }; 2B4A60381A3E6F830006AFCC /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B9CAB9A185527EC00F3A9C6 /* CoreFoundation.framework */; }; 2B56ACED1C4A48C800930E79 /* Distribution in Resources */ = {isa = PBXBuildFile; fileRef = 2B56ACEC1C4A48C800930E79 /* Distribution */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C501C493B2D00440116 /* iSCSICtl.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C2E1C493B2D00440116 /* iSCSICtl.m */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C511C493B2D00440116 /* iSCSIDA.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C301C493B2D00440116 /* iSCSIDA.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C521C493B2D00440116 /* iSCSIDA.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C301C493B2D00440116 /* iSCSIDA.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C531C493B2D00440116 /* iSCSIDaemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C321C493B2D00440116 /* iSCSIDaemon.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C561C493B2D00440116 /* iSCSIDaemonInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C331C493B2D00440116 /* iSCSIDaemonInterface.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C571C493B2D00440116 /* iSCSIDiscovery.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C361C493B2D00440116 /* iSCSIDiscovery.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C591C493B2D00440116 /* iSCSIIORegistry.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C381C493B2D00440116 /* iSCSIIORegistry.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C5A1C493B2D00440116 /* iSCSIIORegistry.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C381C493B2D00440116 /* iSCSIIORegistry.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C5B1C493B2D00440116 /* iSCSIKernelInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C3A1C493B2D00440116 /* iSCSIKernelInterface.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C5D1C493B2D00440116 /* iSCSIKeychain.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C3C1C493B2D00440116 /* iSCSIKeychain.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C5E1C493B2D00440116 /* iSCSIKeychain.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C3C1C493B2D00440116 /* iSCSIKeychain.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C5F1C493B2D00440116 /* iSCSIPDUUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C3E1C493B2D00440116 /* iSCSIPDUUser.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C611C493B2D00440116 /* iSCSIPropertyList.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C401C493B2D00440116 /* iSCSIPropertyList.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C621C493B2D00440116 /* iSCSIPropertyList.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C401C493B2D00440116 /* iSCSIPropertyList.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C631C493B2D00440116 /* iSCSIQueryTarget.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C421C493B2D00440116 /* iSCSIQueryTarget.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C651C493B2D00440116 /* iSCSISession.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C451C493B2D00440116 /* iSCSISession.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C691C493B2D00440116 /* iSCSITypes.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C481C493B2D00440116 /* iSCSITypes.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C6A1C493B2D00440116 /* iSCSITypes.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C481C493B2D00440116 /* iSCSITypes.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C6B1C493B2D00440116 /* iSCSIUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C4B1C493B2D00440116 /* iSCSIUtils.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3C6C1C493B2D00440116 /* iSCSIUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C4B1C493B2D00440116 /* iSCSIUtils.c */; settings = {ASSET_TAGS = (); }; }; + 2B5C213B1C70871600ED8791 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B5935C21810DF7100FFC3D3 /* IOKit.framework */; }; + 2B5C213C1C70871A00ED8791 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BC4CBB11AA55046003611F7 /* DiskArbitration.framework */; }; + 2B5C213D1C70872400ED8791 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B459D541B7B8192008F656F /* Security.framework */; }; + 2B5C213E1C70872E00ED8791 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B9CAB9A185527EC00F3A9C6 /* CoreFoundation.framework */; }; 2B9E3C941C493BAA00440116 /* iSCSIInitiator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C711C493B9C00440116 /* iSCSIInitiator.cpp */; settings = {COMPILER_FLAGS = "-Wno-inconsistent-missing-override"; }; }; 2B9E3C961C493BAA00440116 /* iSCSIInitiatorClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C731C493B9C00440116 /* iSCSIInitiatorClient.cpp */; settings = {COMPILER_FLAGS = "-Wno-inconsistent-missing-override"; }; }; 2B9E3C981C493BAA00440116 /* iSCSIIOEventSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C751C493B9C00440116 /* iSCSIIOEventSource.cpp */; settings = {COMPILER_FLAGS = "-Wno-inconsistent-missing-override"; }; }; 2B9E3C9C1C493BAA00440116 /* iSCSIPDUKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C791C493B9C00440116 /* iSCSIPDUKernel.cpp */; settings = {COMPILER_FLAGS = "-Wno-inconsistent-missing-override"; }; }; 2B9E3CA01C493BAA00440116 /* iSCSITaskQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C7D1C493B9C00440116 /* iSCSITaskQueue.cpp */; settings = {COMPILER_FLAGS = "-Wno-inconsistent-missing-override"; }; }; 2B9E3CA31C493BAA00440116 /* iSCSIVirtualHBA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C801C493B9C00440116 /* iSCSIVirtualHBA.cpp */; settings = {COMPILER_FLAGS = "-Wno-inconsistent-missing-override"; }; }; - 2B9E3CA71C493CDF00440116 /* iSCSIAuth.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C2B1C493B2D00440116 /* iSCSIAuth.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3CA81C493DC400440116 /* iSCSITest.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3C471C493B2D00440116 /* iSCSITest.c */; settings = {ASSET_TAGS = (); }; }; - 2B9E3CA91C49570100440116 /* iscsid.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2B9E3C2F1C493B2D00440116 /* iscsid.8 */; }; - 2B9E3CAA1C49570F00440116 /* iscsictl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2B9E3C2D1C493B2D00440116 /* iscsictl.8 */; }; - 2B9E3CAB1C49571600440116 /* com.github.iscsi-osx.iscsid.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2B9E3C2A1C493B2D00440116 /* com.github.iscsi-osx.iscsid.plist */; }; 2B9E3CBE1C49ED0000440116 /* crc32c.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3CBA1C49ECF900440116 /* crc32c.c */; settings = {ASSET_TAGS = (); }; }; 2BC4CBB21AA55046003611F7 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BC4CBB11AA55046003611F7 /* DiskArbitration.framework */; }; + 2BDE5E281C8B0274004BDB5F /* iscsictl.8 in Resources */ = {isa = PBXBuildFile; fileRef = 2BDE5E261C8B0274004BDB5F /* iscsictl.8 */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E6E1C8B0292004BDB5F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2BDE5E481C8B028B004BDB5F /* Info.plist */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E6F1C8B0292004BDB5F /* iSCSI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E491C8B028B004BDB5F /* iSCSI.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E701C8B0292004BDB5F /* iSCSIDA.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E4A1C8B028B004BDB5F /* iSCSIDA.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E711C8B0292004BDB5F /* iSCSIDA.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E4B1C8B028B004BDB5F /* iSCSIDA.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E721C8B0292004BDB5F /* iSCSIDaemonInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E4C1C8B028B004BDB5F /* iSCSIDaemonInterface.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E731C8B0292004BDB5F /* iSCSIDaemonInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E4D1C8B028B004BDB5F /* iSCSIDaemonInterface.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E741C8B0292004BDB5F /* iSCSIDaemonInterfaceShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E4E1C8B028B004BDB5F /* iSCSIDaemonInterfaceShared.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E751C8B0292004BDB5F /* iSCSIIORegistry.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E4F1C8B028B004BDB5F /* iSCSIIORegistry.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E761C8B0292004BDB5F /* iSCSIIORegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E501C8B028B004BDB5F /* iSCSIIORegistry.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E771C8B0292004BDB5F /* iSCSIKeychain.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E511C8B028B004BDB5F /* iSCSIKeychain.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E781C8B0292004BDB5F /* iSCSIKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E521C8B028B004BDB5F /* iSCSIKeychain.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E791C8B0292004BDB5F /* iSCSIPropertyList.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E531C8B028B004BDB5F /* iSCSIPropertyList.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E7A1C8B0292004BDB5F /* iSCSIPropertyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E541C8B028B004BDB5F /* iSCSIPropertyList.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E7B1C8B0292004BDB5F /* iSCSIRFC3720Keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E551C8B028B004BDB5F /* iSCSIRFC3720Keys.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E7C1C8B0292004BDB5F /* iSCSITypes.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E561C8B028B004BDB5F /* iSCSITypes.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E7D1C8B0292004BDB5F /* iSCSITypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E571C8B028B004BDB5F /* iSCSITypes.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E7E1C8B0292004BDB5F /* iSCSITypesShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E581C8B028B004BDB5F /* iSCSITypesShared.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E7F1C8B0292004BDB5F /* iSCSIUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E591C8B028B004BDB5F /* iSCSIUtils.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E801C8B0292004BDB5F /* iSCSIUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E5A1C8B028B004BDB5F /* iSCSIUtils.h */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E881C8B3E7D004BDB5F /* iSCSIAuth.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E2B1C8B0281004BDB5F /* iSCSIAuth.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E891C8B3E7D004BDB5F /* iSCSIDaemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E2E1C8B0281004BDB5F /* iSCSIDaemon.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E8A1C8B3E7D004BDB5F /* iSCSIDiscovery.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E2F1C8B0281004BDB5F /* iSCSIDiscovery.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E8B1C8B3E7D004BDB5F /* iSCSIKernelInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E311C8B0281004BDB5F /* iSCSIKernelInterface.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E8C1C8B3E7D004BDB5F /* iSCSIPDUUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E331C8B0281004BDB5F /* iSCSIPDUUser.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E8D1C8B3E7D004BDB5F /* iSCSIQueryTarget.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E351C8B0281004BDB5F /* iSCSIQueryTarget.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E8E1C8B3E7D004BDB5F /* iSCSISession.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E371C8B0281004BDB5F /* iSCSISession.c */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E8F1C8B3E96004BDB5F /* iSCSICtl.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E271C8B0274004BDB5F /* iSCSICtl.m */; settings = {ASSET_TAGS = (); }; }; + 2BDE5E901C8B3ED0004BDB5F /* iSCSI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */; }; + 2BDE5E911C8B3EE7004BDB5F /* iSCSI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */; }; + 2BDE5E921C8BD1C5004BDB5F /* iscsictl.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2BDE5E261C8B0274004BDB5F /* iscsictl.8 */; }; + 2BDE5E931C8BD1DC004BDB5F /* iscsid.8 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2BDE5E2D1C8B0281004BDB5F /* iscsid.8 */; }; + 2BDE5E941C8C7AF1004BDB5F /* com.github.iscsi-osx.iscsid.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2BDE5E2A1C8B0281004BDB5F /* com.github.iscsi-osx.iscsid.plist */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -53,7 +65,7 @@ dstPath = ""; dstSubfolderSpec = 16; files = ( - 2B9E3CAA1C49570F00440116 /* iscsictl.8 in CopyFiles */, + 2BDE5E921C8BD1C5004BDB5F /* iscsictl.8 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -63,20 +75,11 @@ dstPath = ""; dstSubfolderSpec = 16; files = ( - 2B9E3CAB1C49571600440116 /* com.github.iscsi-osx.iscsid.plist in CopyFiles */, - 2B9E3CA91C49570100440116 /* iscsid.8 in CopyFiles */, + 2BDE5E941C8C7AF1004BDB5F /* com.github.iscsi-osx.iscsid.plist in CopyFiles */, + 2BDE5E931C8BD1DC004BDB5F /* iscsid.8 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; - 2BB83CD51A3D493B0017212D /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -91,43 +94,9 @@ 2B59357F1810D3C800FFC3D3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 2B5935801810D3C800FFC3D3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 2B5935C21810DF7100FFC3D3 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = iSCSI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2B84883C1BEBCE0E0038DC53 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 2B9CAB9A185527EC00F3A9C6 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - 2B9E3C2A1C493B2D00440116 /* com.github.iscsi-osx.iscsid.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "com.github.iscsi-osx.iscsid.plist"; path = "Source/User Tools/com.github.iscsi-osx.iscsid.plist"; sourceTree = ""; }; - 2B9E3C2B1C493B2D00440116 /* iSCSIAuth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIAuth.c; path = "Source/User Tools/iSCSIAuth.c"; sourceTree = ""; }; - 2B9E3C2C1C493B2D00440116 /* iSCSIAuth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIAuth.h; path = "Source/User Tools/iSCSIAuth.h"; sourceTree = ""; }; - 2B9E3C2D1C493B2D00440116 /* iscsictl.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = iscsictl.8; path = "Source/User Tools/iscsictl.8"; sourceTree = ""; }; - 2B9E3C2E1C493B2D00440116 /* iSCSICtl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iSCSICtl.m; path = "Source/User Tools/iSCSICtl.m"; sourceTree = ""; }; - 2B9E3C2F1C493B2D00440116 /* iscsid.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = iscsid.8; path = "Source/User Tools/iscsid.8"; sourceTree = ""; }; - 2B9E3C301C493B2D00440116 /* iSCSIDA.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDA.c; path = "Source/User Tools/iSCSIDA.c"; sourceTree = ""; }; - 2B9E3C311C493B2D00440116 /* iSCSIDA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDA.h; path = "Source/User Tools/iSCSIDA.h"; sourceTree = ""; }; - 2B9E3C321C493B2D00440116 /* iSCSIDaemon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDaemon.c; path = "Source/User Tools/iSCSIDaemon.c"; sourceTree = ""; }; - 2B9E3C331C493B2D00440116 /* iSCSIDaemonInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDaemonInterface.c; path = "Source/User Tools/iSCSIDaemonInterface.c"; sourceTree = ""; }; - 2B9E3C341C493B2D00440116 /* iSCSIDaemonInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDaemonInterface.h; path = "Source/User Tools/iSCSIDaemonInterface.h"; sourceTree = ""; }; - 2B9E3C351C493B2D00440116 /* iSCSIDaemonInterfaceShared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDaemonInterfaceShared.h; path = "Source/User Tools/iSCSIDaemonInterfaceShared.h"; sourceTree = ""; }; - 2B9E3C361C493B2D00440116 /* iSCSIDiscovery.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDiscovery.c; path = "Source/User Tools/iSCSIDiscovery.c"; sourceTree = ""; }; - 2B9E3C371C493B2D00440116 /* iSCSIDiscovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDiscovery.h; path = "Source/User Tools/iSCSIDiscovery.h"; sourceTree = ""; }; - 2B9E3C381C493B2D00440116 /* iSCSIIORegistry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIIORegistry.c; path = "Source/User Tools/iSCSIIORegistry.c"; sourceTree = ""; }; - 2B9E3C391C493B2D00440116 /* iSCSIIORegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIIORegistry.h; path = "Source/User Tools/iSCSIIORegistry.h"; sourceTree = ""; }; - 2B9E3C3A1C493B2D00440116 /* iSCSIKernelInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIKernelInterface.c; path = "Source/User Tools/iSCSIKernelInterface.c"; sourceTree = ""; }; - 2B9E3C3B1C493B2D00440116 /* iSCSIKernelInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIKernelInterface.h; path = "Source/User Tools/iSCSIKernelInterface.h"; sourceTree = ""; }; - 2B9E3C3C1C493B2D00440116 /* iSCSIKeychain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIKeychain.c; path = "Source/User Tools/iSCSIKeychain.c"; sourceTree = ""; }; - 2B9E3C3D1C493B2D00440116 /* iSCSIKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIKeychain.h; path = "Source/User Tools/iSCSIKeychain.h"; sourceTree = ""; }; - 2B9E3C3E1C493B2D00440116 /* iSCSIPDUUser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIPDUUser.c; path = "Source/User Tools/iSCSIPDUUser.c"; sourceTree = ""; }; - 2B9E3C3F1C493B2D00440116 /* iSCSIPDUUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIPDUUser.h; path = "Source/User Tools/iSCSIPDUUser.h"; sourceTree = ""; }; - 2B9E3C401C493B2D00440116 /* iSCSIPropertyList.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIPropertyList.c; path = "Source/User Tools/iSCSIPropertyList.c"; sourceTree = ""; }; - 2B9E3C411C493B2D00440116 /* iSCSIPropertyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIPropertyList.h; path = "Source/User Tools/iSCSIPropertyList.h"; sourceTree = ""; }; - 2B9E3C421C493B2D00440116 /* iSCSIQueryTarget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIQueryTarget.c; path = "Source/User Tools/iSCSIQueryTarget.c"; sourceTree = ""; }; - 2B9E3C431C493B2D00440116 /* iSCSIQueryTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIQueryTarget.h; path = "Source/User Tools/iSCSIQueryTarget.h"; sourceTree = ""; }; - 2B9E3C441C493B2D00440116 /* iSCSIRFC3720Keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIRFC3720Keys.h; path = "Source/User Tools/iSCSIRFC3720Keys.h"; sourceTree = ""; }; - 2B9E3C451C493B2D00440116 /* iSCSISession.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSISession.c; path = "Source/User Tools/iSCSISession.c"; sourceTree = ""; }; - 2B9E3C461C493B2D00440116 /* iSCSISession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSISession.h; path = "Source/User Tools/iSCSISession.h"; sourceTree = ""; }; - 2B9E3C471C493B2D00440116 /* iSCSITest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSITest.c; path = "Source/User Tools/iSCSITest.c"; sourceTree = ""; }; - 2B9E3C481C493B2D00440116 /* iSCSITypes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSITypes.c; path = "Source/User Tools/iSCSITypes.c"; sourceTree = ""; }; - 2B9E3C491C493B2D00440116 /* iSCSITypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSITypes.h; path = "Source/User Tools/iSCSITypes.h"; sourceTree = ""; }; - 2B9E3C4A1C493B2D00440116 /* iSCSITypesShared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSITypesShared.h; path = "Source/User Tools/iSCSITypesShared.h"; sourceTree = ""; }; - 2B9E3C4B1C493B2D00440116 /* iSCSIUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIUtils.c; path = "Source/User Tools/iSCSIUtils.c"; sourceTree = ""; }; - 2B9E3C4C1C493B2D00440116 /* iSCSIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIUtils.h; path = "Source/User Tools/iSCSIUtils.h"; sourceTree = ""; }; 2B9E3C701C493B9C00440116 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Source/Kernel/Info.plist; sourceTree = ""; }; 2B9E3C711C493B9C00440116 /* iSCSIInitiator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = iSCSIInitiator.cpp; path = Source/Kernel/iSCSIInitiator.cpp; sourceTree = ""; }; 2B9E3C721C493B9C00440116 /* iSCSIInitiator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIInitiator.h; path = Source/Kernel/iSCSIInitiator.h; sourceTree = ""; }; @@ -150,10 +119,45 @@ 2B9E3CBA1C49ECF900440116 /* crc32c.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = crc32c.c; path = Source/Kernel/crc32c.c; sourceTree = ""; }; 2B9E3CBB1C49ECF900440116 /* crc32c.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; name = crc32c.h; path = Source/Kernel/crc32c.h; sourceTree = ""; }; 2BC4CBB11AA55046003611F7 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = System/Library/Frameworks/DiskArbitration.framework; sourceTree = SDKROOT; }; + 2BDE5E261C8B0274004BDB5F /* iscsictl.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = iscsictl.8; path = Source/User/iscsictl/iscsictl.8; sourceTree = ""; }; + 2BDE5E271C8B0274004BDB5F /* iSCSICtl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iSCSICtl.m; path = Source/User/iscsictl/iSCSICtl.m; sourceTree = ""; }; + 2BDE5E2A1C8B0281004BDB5F /* com.github.iscsi-osx.iscsid.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "com.github.iscsi-osx.iscsid.plist"; path = "Source/User/iscsid/com.github.iscsi-osx.iscsid.plist"; sourceTree = ""; }; + 2BDE5E2B1C8B0281004BDB5F /* iSCSIAuth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIAuth.c; path = Source/User/iscsid/iSCSIAuth.c; sourceTree = ""; }; + 2BDE5E2C1C8B0281004BDB5F /* iSCSIAuth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIAuth.h; path = Source/User/iscsid/iSCSIAuth.h; sourceTree = ""; }; + 2BDE5E2D1C8B0281004BDB5F /* iscsid.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = iscsid.8; path = Source/User/iscsid/iscsid.8; sourceTree = ""; }; + 2BDE5E2E1C8B0281004BDB5F /* iSCSIDaemon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDaemon.c; path = Source/User/iscsid/iSCSIDaemon.c; sourceTree = ""; }; + 2BDE5E2F1C8B0281004BDB5F /* iSCSIDiscovery.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDiscovery.c; path = Source/User/iscsid/iSCSIDiscovery.c; sourceTree = ""; }; + 2BDE5E301C8B0281004BDB5F /* iSCSIDiscovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDiscovery.h; path = Source/User/iscsid/iSCSIDiscovery.h; sourceTree = ""; }; + 2BDE5E311C8B0281004BDB5F /* iSCSIKernelInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIKernelInterface.c; path = Source/User/iscsid/iSCSIKernelInterface.c; sourceTree = ""; }; + 2BDE5E321C8B0281004BDB5F /* iSCSIKernelInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIKernelInterface.h; path = Source/User/iscsid/iSCSIKernelInterface.h; sourceTree = ""; }; + 2BDE5E331C8B0281004BDB5F /* iSCSIPDUUser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIPDUUser.c; path = Source/User/iscsid/iSCSIPDUUser.c; sourceTree = ""; }; + 2BDE5E341C8B0281004BDB5F /* iSCSIPDUUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIPDUUser.h; path = Source/User/iscsid/iSCSIPDUUser.h; sourceTree = ""; }; + 2BDE5E351C8B0281004BDB5F /* iSCSIQueryTarget.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIQueryTarget.c; path = Source/User/iscsid/iSCSIQueryTarget.c; sourceTree = ""; }; + 2BDE5E361C8B0281004BDB5F /* iSCSIQueryTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIQueryTarget.h; path = Source/User/iscsid/iSCSIQueryTarget.h; sourceTree = ""; }; + 2BDE5E371C8B0281004BDB5F /* iSCSISession.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSISession.c; path = Source/User/iscsid/iSCSISession.c; sourceTree = ""; }; + 2BDE5E381C8B0281004BDB5F /* iSCSISession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSISession.h; path = Source/User/iscsid/iSCSISession.h; sourceTree = ""; }; + 2BDE5E481C8B028B004BDB5F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "Source/User/iSCSI Framework/Info.plist"; sourceTree = ""; }; + 2BDE5E491C8B028B004BDB5F /* iSCSI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSI.h; path = "Source/User/iSCSI Framework/iSCSI.h"; sourceTree = ""; }; + 2BDE5E4A1C8B028B004BDB5F /* iSCSIDA.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDA.c; path = "Source/User/iSCSI Framework/iSCSIDA.c"; sourceTree = ""; }; + 2BDE5E4B1C8B028B004BDB5F /* iSCSIDA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDA.h; path = "Source/User/iSCSI Framework/iSCSIDA.h"; sourceTree = ""; }; + 2BDE5E4C1C8B028B004BDB5F /* iSCSIDaemonInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIDaemonInterface.c; path = "Source/User/iSCSI Framework/iSCSIDaemonInterface.c"; sourceTree = ""; }; + 2BDE5E4D1C8B028B004BDB5F /* iSCSIDaemonInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDaemonInterface.h; path = "Source/User/iSCSI Framework/iSCSIDaemonInterface.h"; sourceTree = ""; }; + 2BDE5E4E1C8B028B004BDB5F /* iSCSIDaemonInterfaceShared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIDaemonInterfaceShared.h; path = "Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h"; sourceTree = ""; }; + 2BDE5E4F1C8B028B004BDB5F /* iSCSIIORegistry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIIORegistry.c; path = "Source/User/iSCSI Framework/iSCSIIORegistry.c"; sourceTree = ""; }; + 2BDE5E501C8B028B004BDB5F /* iSCSIIORegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIIORegistry.h; path = "Source/User/iSCSI Framework/iSCSIIORegistry.h"; sourceTree = ""; }; + 2BDE5E511C8B028B004BDB5F /* iSCSIKeychain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIKeychain.c; path = "Source/User/iSCSI Framework/iSCSIKeychain.c"; sourceTree = ""; }; + 2BDE5E521C8B028B004BDB5F /* iSCSIKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIKeychain.h; path = "Source/User/iSCSI Framework/iSCSIKeychain.h"; sourceTree = ""; }; + 2BDE5E531C8B028B004BDB5F /* iSCSIPropertyList.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIPropertyList.c; path = "Source/User/iSCSI Framework/iSCSIPropertyList.c"; sourceTree = ""; }; + 2BDE5E541C8B028B004BDB5F /* iSCSIPropertyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIPropertyList.h; path = "Source/User/iSCSI Framework/iSCSIPropertyList.h"; sourceTree = ""; }; + 2BDE5E551C8B028B004BDB5F /* iSCSIRFC3720Keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIRFC3720Keys.h; path = "Source/User/iSCSI Framework/iSCSIRFC3720Keys.h"; sourceTree = ""; }; + 2BDE5E561C8B028B004BDB5F /* iSCSITypes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSITypes.c; path = "Source/User/iSCSI Framework/iSCSITypes.c"; sourceTree = ""; }; + 2BDE5E571C8B028B004BDB5F /* iSCSITypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSITypes.h; path = "Source/User/iSCSI Framework/iSCSITypes.h"; sourceTree = ""; }; + 2BDE5E581C8B028B004BDB5F /* iSCSITypesShared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSITypesShared.h; path = "Source/User/iSCSI Framework/iSCSITypesShared.h"; sourceTree = ""; }; + 2BDE5E591C8B028B004BDB5F /* iSCSIUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIUtils.c; path = "Source/User/iSCSI Framework/iSCSIUtils.c"; sourceTree = ""; }; + 2BDE5E5A1C8B028B004BDB5F /* iSCSIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIUtils.h; path = "Source/User/iSCSI Framework/iSCSIUtils.h"; sourceTree = ""; }; 2BDEA9401A715C7B00D5B48B /* iSCSIInitiator.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iSCSIInitiator.kext; sourceTree = BUILT_PRODUCTS_DIR; }; 2BDEA9411A715C7B00D5B48B /* iscsid */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = iscsid; sourceTree = BUILT_PRODUCTS_DIR; }; 2BDEA9421A715C7B00D5B48B /* iscsictl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = iscsictl; sourceTree = BUILT_PRODUCTS_DIR; }; - 2BDEA9431A715C7B00D5B48B /* iscsitest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = iscsitest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -161,31 +165,37 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2BDE5E911C8B3EE7004BDB5F /* iSCSI.framework in Frameworks */, + 2B5C213E1C70872E00ED8791 /* CoreFoundation.framework in Frameworks */, + 2B5C213D1C70872400ED8791 /* Security.framework in Frameworks */, + 2B5C213C1C70871A00ED8791 /* DiskArbitration.framework in Frameworks */, + 2B5C213B1C70871600ED8791 /* IOKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 2B9519821810F852006CE7E5 /* Frameworks */ = { + 2B7A0B701C8AEC47008290E9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 2BA96D9018D4F60200F135E3 /* Frameworks */ = { + 2B9519821810F852006CE7E5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2B459D551B7B8192008F656F /* Security.framework in Frameworks */, - 2BC4CBB21AA55046003611F7 /* DiskArbitration.framework in Frameworks */, - 2B4A60381A3E6F830006AFCC /* CoreFoundation.framework in Frameworks */, - 2B4A60371A3E6F690006AFCC /* IOKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 2BB83CD41A3D493B0017212D /* Frameworks */ = { + 2BA96D9018D4F60200F135E3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2BDE5E901C8B3ED0004BDB5F /* iSCSI.framework in Frameworks */, + 2B459D551B7B8192008F656F /* Security.framework in Frameworks */, + 2BC4CBB21AA55046003611F7 /* DiskArbitration.framework in Frameworks */, + 2B4A60381A3E6F830006AFCC /* CoreFoundation.framework in Frameworks */, + 2B4A60371A3E6F690006AFCC /* IOKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -195,7 +205,7 @@ 2B5935541810CE6800FFC3D3 = { isa = PBXGroup; children = ( - 2B9E3BD51C493AAD00440116 /* User Tools */, + 2BDE5E1A1C8B020A004BDB5F /* User */, 2B9E3BD41C493AA400440116 /* Kernel */, 2B1B972A1C4937B400DA5281 /* Scripts */, 2B56ACEC1C4A48C800930E79 /* Distribution */, @@ -204,7 +214,7 @@ 2BDEA9401A715C7B00D5B48B /* iSCSIInitiator.kext */, 2BDEA9411A715C7B00D5B48B /* iscsid */, 2BDEA9421A715C7B00D5B48B /* iscsictl */, - 2BDEA9431A715C7B00D5B48B /* iscsitest */, + 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */, ); sourceTree = ""; }; @@ -261,48 +271,6 @@ name = Kernel; sourceTree = ""; }; - 2B9E3BD51C493AAD00440116 /* User Tools */ = { - isa = PBXGroup; - children = ( - 2B9E3C2A1C493B2D00440116 /* com.github.iscsi-osx.iscsid.plist */, - 2B9E3C2B1C493B2D00440116 /* iSCSIAuth.c */, - 2B9E3C2C1C493B2D00440116 /* iSCSIAuth.h */, - 2B9E3C2D1C493B2D00440116 /* iscsictl.8 */, - 2B9E3C2E1C493B2D00440116 /* iSCSICtl.m */, - 2B9E3C2F1C493B2D00440116 /* iscsid.8 */, - 2B9E3C301C493B2D00440116 /* iSCSIDA.c */, - 2B9E3C311C493B2D00440116 /* iSCSIDA.h */, - 2B9E3C321C493B2D00440116 /* iSCSIDaemon.c */, - 2B9E3C331C493B2D00440116 /* iSCSIDaemonInterface.c */, - 2B9E3C341C493B2D00440116 /* iSCSIDaemonInterface.h */, - 2B9E3C351C493B2D00440116 /* iSCSIDaemonInterfaceShared.h */, - 2B9E3C361C493B2D00440116 /* iSCSIDiscovery.c */, - 2B9E3C371C493B2D00440116 /* iSCSIDiscovery.h */, - 2B9E3C381C493B2D00440116 /* iSCSIIORegistry.c */, - 2B9E3C391C493B2D00440116 /* iSCSIIORegistry.h */, - 2B9E3C3A1C493B2D00440116 /* iSCSIKernelInterface.c */, - 2B9E3C3B1C493B2D00440116 /* iSCSIKernelInterface.h */, - 2B9E3C3C1C493B2D00440116 /* iSCSIKeychain.c */, - 2B9E3C3D1C493B2D00440116 /* iSCSIKeychain.h */, - 2B9E3C3E1C493B2D00440116 /* iSCSIPDUUser.c */, - 2B9E3C3F1C493B2D00440116 /* iSCSIPDUUser.h */, - 2B9E3C401C493B2D00440116 /* iSCSIPropertyList.c */, - 2B9E3C411C493B2D00440116 /* iSCSIPropertyList.h */, - 2B9E3C421C493B2D00440116 /* iSCSIQueryTarget.c */, - 2B9E3C431C493B2D00440116 /* iSCSIQueryTarget.h */, - 2B9E3C441C493B2D00440116 /* iSCSIRFC3720Keys.h */, - 2B9E3C451C493B2D00440116 /* iSCSISession.c */, - 2B9E3C461C493B2D00440116 /* iSCSISession.h */, - 2B9E3C471C493B2D00440116 /* iSCSITest.c */, - 2B9E3C481C493B2D00440116 /* iSCSITypes.c */, - 2B9E3C491C493B2D00440116 /* iSCSITypes.h */, - 2B9E3C4A1C493B2D00440116 /* iSCSITypesShared.h */, - 2B9E3C4B1C493B2D00440116 /* iSCSIUtils.c */, - 2B9E3C4C1C493B2D00440116 /* iSCSIUtils.h */, - ); - name = "User Tools"; - sourceTree = ""; - }; 2B9E3CB91C49739600440116 /* Supporting Files */ = { isa = PBXGroup; children = ( @@ -312,9 +280,94 @@ name = "Supporting Files"; sourceTree = ""; }; + 2BDE5E1A1C8B020A004BDB5F /* User */ = { + isa = PBXGroup; + children = ( + 2BDE5E231C8B0255004BDB5F /* iscsictl */, + 2BDE5E221C8B024A004BDB5F /* iscsid */, + 2BDE5E211C8B0241004BDB5F /* iSCSI.Framwork */, + ); + name = User; + sourceTree = ""; + }; + 2BDE5E211C8B0241004BDB5F /* iSCSI.Framwork */ = { + isa = PBXGroup; + children = ( + 2BDE5E481C8B028B004BDB5F /* Info.plist */, + 2BDE5E491C8B028B004BDB5F /* iSCSI.h */, + 2BDE5E4A1C8B028B004BDB5F /* iSCSIDA.c */, + 2BDE5E4B1C8B028B004BDB5F /* iSCSIDA.h */, + 2BDE5E4C1C8B028B004BDB5F /* iSCSIDaemonInterface.c */, + 2BDE5E4D1C8B028B004BDB5F /* iSCSIDaemonInterface.h */, + 2BDE5E4E1C8B028B004BDB5F /* iSCSIDaemonInterfaceShared.h */, + 2BDE5E4F1C8B028B004BDB5F /* iSCSIIORegistry.c */, + 2BDE5E501C8B028B004BDB5F /* iSCSIIORegistry.h */, + 2BDE5E511C8B028B004BDB5F /* iSCSIKeychain.c */, + 2BDE5E521C8B028B004BDB5F /* iSCSIKeychain.h */, + 2BDE5E531C8B028B004BDB5F /* iSCSIPropertyList.c */, + 2BDE5E541C8B028B004BDB5F /* iSCSIPropertyList.h */, + 2BDE5E551C8B028B004BDB5F /* iSCSIRFC3720Keys.h */, + 2BDE5E561C8B028B004BDB5F /* iSCSITypes.c */, + 2BDE5E571C8B028B004BDB5F /* iSCSITypes.h */, + 2BDE5E581C8B028B004BDB5F /* iSCSITypesShared.h */, + 2BDE5E591C8B028B004BDB5F /* iSCSIUtils.c */, + 2BDE5E5A1C8B028B004BDB5F /* iSCSIUtils.h */, + ); + name = iSCSI.Framwork; + sourceTree = ""; + }; + 2BDE5E221C8B024A004BDB5F /* iscsid */ = { + isa = PBXGroup; + children = ( + 2BDE5E2A1C8B0281004BDB5F /* com.github.iscsi-osx.iscsid.plist */, + 2BDE5E2B1C8B0281004BDB5F /* iSCSIAuth.c */, + 2BDE5E2C1C8B0281004BDB5F /* iSCSIAuth.h */, + 2BDE5E2D1C8B0281004BDB5F /* iscsid.8 */, + 2BDE5E2E1C8B0281004BDB5F /* iSCSIDaemon.c */, + 2BDE5E2F1C8B0281004BDB5F /* iSCSIDiscovery.c */, + 2BDE5E301C8B0281004BDB5F /* iSCSIDiscovery.h */, + 2BDE5E311C8B0281004BDB5F /* iSCSIKernelInterface.c */, + 2BDE5E321C8B0281004BDB5F /* iSCSIKernelInterface.h */, + 2BDE5E331C8B0281004BDB5F /* iSCSIPDUUser.c */, + 2BDE5E341C8B0281004BDB5F /* iSCSIPDUUser.h */, + 2BDE5E351C8B0281004BDB5F /* iSCSIQueryTarget.c */, + 2BDE5E361C8B0281004BDB5F /* iSCSIQueryTarget.h */, + 2BDE5E371C8B0281004BDB5F /* iSCSISession.c */, + 2BDE5E381C8B0281004BDB5F /* iSCSISession.h */, + ); + name = iscsid; + sourceTree = ""; + }; + 2BDE5E231C8B0255004BDB5F /* iscsictl */ = { + isa = PBXGroup; + children = ( + 2BDE5E261C8B0274004BDB5F /* iscsictl.8 */, + 2BDE5E271C8B0274004BDB5F /* iSCSICtl.m */, + ); + name = iscsictl; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 2B7A0B711C8AEC47008290E9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BDE5E801C8B0292004BDB5F /* iSCSIUtils.h in Headers */, + 2BDE5E7D1C8B0292004BDB5F /* iSCSITypes.h in Headers */, + 2BDE5E761C8B0292004BDB5F /* iSCSIIORegistry.h in Headers */, + 2BDE5E731C8B0292004BDB5F /* iSCSIDaemonInterface.h in Headers */, + 2BDE5E741C8B0292004BDB5F /* iSCSIDaemonInterfaceShared.h in Headers */, + 2BDE5E7A1C8B0292004BDB5F /* iSCSIPropertyList.h in Headers */, + 2BDE5E6F1C8B0292004BDB5F /* iSCSI.h in Headers */, + 2BDE5E781C8B0292004BDB5F /* iSCSIKeychain.h in Headers */, + 2BDE5E7E1C8B0292004BDB5F /* iSCSITypesShared.h in Headers */, + 2BDE5E7B1C8B0292004BDB5F /* iSCSIRFC3720Keys.h in Headers */, + 2BDE5E711C8B0292004BDB5F /* iSCSIDA.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 2B9519831810F852006CE7E5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -342,6 +395,24 @@ productReference = 2BDEA9421A715C7B00D5B48B /* iscsictl */; productType = "com.apple.product-type.tool"; }; + 2B7A0B731C8AEC47008290E9 /* iSCSI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2B7A0B891C8AEC47008290E9 /* Build configuration list for PBXNativeTarget "iSCSI" */; + buildPhases = ( + 2B7A0B6F1C8AEC47008290E9 /* Sources */, + 2B7A0B701C8AEC47008290E9 /* Frameworks */, + 2B7A0B711C8AEC47008290E9 /* Headers */, + 2B7A0B721C8AEC47008290E9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iSCSI; + productName = iSCSI; + productReference = 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */; + productType = "com.apple.product-type.framework"; + }; 2B9519861810F852006CE7E5 /* iSCSIInitiator */ = { isa = PBXNativeTarget; buildConfigurationList = 2B9519921810F852006CE7E5 /* Build configuration list for PBXNativeTarget "iSCSIInitiator" */; @@ -378,23 +449,6 @@ productReference = 2BDEA9411A715C7B00D5B48B /* iscsid */; productType = "com.apple.product-type.tool"; }; - 2BB83CD61A3D493B0017212D /* iscsitest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2BB83CDD1A3D493C0017212D /* Build configuration list for PBXNativeTarget "iscsitest" */; - buildPhases = ( - 2BB83CD31A3D493B0017212D /* Sources */, - 2BB83CD41A3D493B0017212D /* Frameworks */, - 2BB83CD51A3D493B0017212D /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = iscsitest; - productName = iSCSITest; - productReference = 2BDEA9431A715C7B00D5B48B /* iscsitest */; - productType = "com.apple.product-type.tool"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -403,8 +457,8 @@ attributes = { LastUpgradeCheck = 0700; TargetAttributes = { - 2BB83CD61A3D493B0017212D = { - CreatedOnToolsVersion = 6.1.1; + 2B7A0B731C8AEC47008290E9 = { + CreatedOnToolsVersion = 7.0.1; }; }; }; @@ -424,16 +478,25 @@ 2B9519861810F852006CE7E5 /* iSCSIInitiator */, 2BA96D8818D4F60200F135E3 /* iscsid */, 2B16EEC8196085A40061E7FA /* iscsictl */, - 2BB83CD61A3D493B0017212D /* iscsitest */, + 2B7A0B731C8AEC47008290E9 /* iSCSI */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 2B7A0B721C8AEC47008290E9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BDE5E6E1C8B0292004BDB5F /* Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 2B9519841810F852006CE7E5 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2BDE5E281C8B0274004BDB5F /* iscsictl.8 in Resources */, 2B56ACED1C4A48C800930E79 /* Distribution in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -455,14 +518,21 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2B9E3C521C493B2D00440116 /* iSCSIDA.c in Sources */, - 2B9E3C5E1C493B2D00440116 /* iSCSIKeychain.c in Sources */, - 2B9E3C5A1C493B2D00440116 /* iSCSIIORegistry.c in Sources */, - 2B9E3C6C1C493B2D00440116 /* iSCSIUtils.c in Sources */, - 2B9E3C561C493B2D00440116 /* iSCSIDaemonInterface.c in Sources */, - 2B9E3C6A1C493B2D00440116 /* iSCSITypes.c in Sources */, - 2B9E3C621C493B2D00440116 /* iSCSIPropertyList.c in Sources */, - 2B9E3C501C493B2D00440116 /* iSCSICtl.m in Sources */, + 2BDE5E8F1C8B3E96004BDB5F /* iSCSICtl.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2B7A0B6F1C8AEC47008290E9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2BDE5E701C8B0292004BDB5F /* iSCSIDA.c in Sources */, + 2BDE5E721C8B0292004BDB5F /* iSCSIDaemonInterface.c in Sources */, + 2BDE5E791C8B0292004BDB5F /* iSCSIPropertyList.c in Sources */, + 2BDE5E751C8B0292004BDB5F /* iSCSIIORegistry.c in Sources */, + 2BDE5E771C8B0292004BDB5F /* iSCSIKeychain.c in Sources */, + 2BDE5E7F1C8B0292004BDB5F /* iSCSIUtils.c in Sources */, + 2BDE5E7C1C8B0292004BDB5F /* iSCSITypes.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -484,27 +554,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2B9E3C511C493B2D00440116 /* iSCSIDA.c in Sources */, - 2B9E3C5D1C493B2D00440116 /* iSCSIKeychain.c in Sources */, - 2B9E3C651C493B2D00440116 /* iSCSISession.c in Sources */, - 2B9E3C531C493B2D00440116 /* iSCSIDaemon.c in Sources */, - 2B9E3C571C493B2D00440116 /* iSCSIDiscovery.c in Sources */, - 2B9E3C5F1C493B2D00440116 /* iSCSIPDUUser.c in Sources */, - 2B9E3C591C493B2D00440116 /* iSCSIIORegistry.c in Sources */, - 2B9E3C5B1C493B2D00440116 /* iSCSIKernelInterface.c in Sources */, - 2B9E3CA71C493CDF00440116 /* iSCSIAuth.c in Sources */, - 2B9E3C6B1C493B2D00440116 /* iSCSIUtils.c in Sources */, - 2B9E3C691C493B2D00440116 /* iSCSITypes.c in Sources */, - 2B9E3C611C493B2D00440116 /* iSCSIPropertyList.c in Sources */, - 2B9E3C631C493B2D00440116 /* iSCSIQueryTarget.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2BB83CD31A3D493B0017212D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2B9E3CA81C493DC400440116 /* iSCSITest.c in Sources */, + 2BDE5E8E1C8B3E7D004BDB5F /* iSCSISession.c in Sources */, + 2BDE5E8B1C8B3E7D004BDB5F /* iSCSIKernelInterface.c in Sources */, + 2BDE5E881C8B3E7D004BDB5F /* iSCSIAuth.c in Sources */, + 2BDE5E891C8B3E7D004BDB5F /* iSCSIDaemon.c in Sources */, + 2BDE5E8A1C8B3E7D004BDB5F /* iSCSIDiscovery.c in Sources */, + 2BDE5E8C1C8B3E7D004BDB5F /* iSCSIPDUUser.c in Sources */, + 2BDE5E8D1C8B3E7D004BDB5F /* iSCSIQueryTarget.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -529,7 +585,8 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; + DYLIB_CURRENT_VERSION = "1.0.0-beta"; + GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -570,8 +627,9 @@ CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_CURRENT_VERSION = "1.0.0-beta"; ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -629,12 +687,13 @@ }; name = Release; }; - 2B9519931810F852006CE7E5 /* Debug */ = { + 2B7A0B851C8AEC47008290E9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -643,50 +702,51 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = ""; + DYLIB_CURRENT_VERSION = 1.0.0; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Source/Kernel/Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Source/Kernel/Info.plist; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/usr/lib/system", - ); + INFOPLIST_FILE = "Source/User/iSCSI Framework/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.7; - MODULE_NAME = "$(NAME_PREFIX_D).$(PRODUCT_NAME)"; - MODULE_VERSION = 1.0.0d1; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "${NAME_PREFIX_D}.${PRODUCT_NAME}"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "iscsi-osx.iSCSI"; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - VALID_ARCHS = "x86_64 i386"; - WRAPPER_EXTENSION = kext; + SKIP_INSTALL = YES; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 2B9519941810F852006CE7E5 /* Release */ = { + 2B7A0B861C8AEC47008290E9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -695,45 +755,44 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = ""; + DYLIB_CURRENT_VERSION = 1.0.0; + DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = A; GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = Source/Kernel/Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = "NAME_PREFIX_U=$(NAME_PREFIX_U)"; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Source/Kernel/Info.plist; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/usr/lib/system", - ); + INFOPLIST_FILE = "Source/User/iSCSI Framework/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.7; - MODULE_NAME = "$(NAME_PREFIX_D).$(PRODUCT_NAME)"; - MODULE_VERSION = 1.0.0d1; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "${NAME_PREFIX_D}.${PRODUCT_NAME}"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "iscsi-osx.iSCSI"; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - WRAPPER_EXTENSION = kext; + SKIP_INSTALL = YES; + VERSION_INFO_PREFIX = ""; }; name = Release; }; - 2BA96D9618D4F60200F135E3 /* Debug */ = { + 2B9519931810F852006CE7E5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - APPLY_RULES_IN_COPY_FILES = NO; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -744,11 +803,16 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = c11; + DYLIB_CURRENT_VERSION = "1.0.0-beta"; + GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Source/Kernel/Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -760,21 +824,28 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INSTALL_PATH = /Library/PrivilegedHelperTools; + INFOPLIST_FILE = Source/Kernel/Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/lib/system", + ); MACOSX_DEPLOYMENT_TARGET = 10.7; + MODULE_NAME = "$(NAME_PREFIX_D).$(PRODUCT_NAME)"; + MODULE_VERSION = 1.0.0d1; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = ""; - PRODUCT_NAME = iscsid; + PRODUCT_BUNDLE_IDENTIFIER = "${NAME_PREFIX_D}.${PRODUCT_NAME}"; + PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + VALID_ARCHS = "x86_64 i386"; + WRAPPER_EXTENSION = kext; }; name = Debug; }; - 2BA96D9718D4F60200F135E3 /* Release */ = { + 2B9519941810F852006CE7E5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - APPLY_RULES_IN_COPY_FILES = NO; - CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -785,33 +856,46 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_CURRENT_VERSION = "1.0.0-beta"; ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = c11; + GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = Source/Kernel/Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = "NAME_PREFIX_U=$(NAME_PREFIX_U)"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INSTALL_PATH = /Library/PrivilegedHelperTools; + INFOPLIST_FILE = Source/Kernel/Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/lib/system", + ); MACOSX_DEPLOYMENT_TARGET = 10.7; + MODULE_NAME = "$(NAME_PREFIX_D).$(PRODUCT_NAME)"; + MODULE_VERSION = 1.0.0d1; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = ""; - PRODUCT_NAME = iscsid; + PRODUCT_BUNDLE_IDENTIFIER = "${NAME_PREFIX_D}.${PRODUCT_NAME}"; + PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + WRAPPER_EXTENSION = kext; }; name = Release; }; - 2BB83CDB1A3D493C0017212D /* Debug */ = { + 2BA96D9618D4F60200F135E3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + APPLY_RULES_IN_COPY_FILES = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -820,12 +904,12 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + DYLIB_CURRENT_VERSION = "1.0.0-beta"; + GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -835,23 +919,25 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; + INSTALL_PATH = /Library/PrivilegedHelperTools; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = ""; + PRODUCT_NAME = iscsid; SDKROOT = macosx; }; name = Debug; }; - 2BB83CDC1A3D493C0017212D /* Release */ = { + 2BA96D9718D4F60200F135E3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + APPLY_RULES_IN_COPY_FILES = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -860,22 +946,24 @@ CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_CURRENT_VERSION = "1.0.0-beta"; ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_C_LANGUAGE_STANDARD = "compiler-default"; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = "$(TARGET_NAME)"; + INSTALL_PATH = /Library/PrivilegedHelperTools; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = ""; + PRODUCT_NAME = iscsid; SDKROOT = macosx; }; name = Release; @@ -901,29 +989,29 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2B9519921810F852006CE7E5 /* Build configuration list for PBXNativeTarget "iSCSIInitiator" */ = { + 2B7A0B891C8AEC47008290E9 /* Build configuration list for PBXNativeTarget "iSCSI" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2B9519931810F852006CE7E5 /* Debug */, - 2B9519941810F852006CE7E5 /* Release */, + 2B7A0B851C8AEC47008290E9 /* Debug */, + 2B7A0B861C8AEC47008290E9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2BA96D9518D4F60200F135E3 /* Build configuration list for PBXNativeTarget "iscsid" */ = { + 2B9519921810F852006CE7E5 /* Build configuration list for PBXNativeTarget "iSCSIInitiator" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2BA96D9618D4F60200F135E3 /* Debug */, - 2BA96D9718D4F60200F135E3 /* Release */, + 2B9519931810F852006CE7E5 /* Debug */, + 2B9519941810F852006CE7E5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2BB83CDD1A3D493C0017212D /* Build configuration list for PBXNativeTarget "iscsitest" */ = { + 2BA96D9518D4F60200F135E3 /* Build configuration list for PBXNativeTarget "iscsid" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2BB83CDB1A3D493C0017212D /* Debug */, - 2BB83CDC1A3D493C0017212D /* Release */, + 2BA96D9618D4F60200F135E3 /* Debug */, + 2BA96D9718D4F60200F135E3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSITest.xcscheme b/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSITest.xcscheme deleted file mode 100644 index b47a6e96..00000000 --- a/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSITest.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -