diff --git a/Distribution/Scripts/Installer/postinstall b/Distribution/Scripts/Installer/postinstall index 76ac4843..ced935c9 100755 --- a/Distribution/Scripts/Installer/postinstall +++ b/Distribution/Scripts/Installer/postinstall @@ -25,18 +25,20 @@ 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 +if [ "$OSX_MINOR_VER" -gt "$OSX_MAVERICKS_MINOR_VER" ]; then KEXT_DST=/Library/Extensions else KEXT_DST=/System/Library/Extensions fi # Copy kernel extensions & load it +sudo mkdir -p $KEXT_DST 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 mkdir -p $FRAMEWORK_DST sudo cp -R $TMP/$FRAMEWORK $FRAMEWORK_DST/$FRAMEWORK sudo chown -R root:wheel $FRAMEWORK_DST/$FRAMEWORK sudo chmod -R 755 $FRAMEWORK_DST/$FRAMEWORK @@ -50,10 +52,12 @@ sudo chmod 644 $DAEMON_PLIST_DST/$DAEMON_PLIST sudo chown root:wheel $DAEMON_PLIST_DST/$DAEMON_PLIST # Copy user tool +sudo mkdir -p $TOOL_DST sudo cp $TMP/$TOOL $TOOL_DST/$TOOL sudo chmod +x $TOOL_DST/$TOOL # Copy man pages +sudo mkdir -p $MAN_DST sudo cp $TMP/$MAN_TOOL $MAN_DST sudo cp $TMP/$MAN_DAEMON $MAN_DST diff --git a/Distribution/Scripts/Installer/preinstall b/Distribution/Scripts/Installer/preinstall index e102ec1e..985318db 100755 --- a/Distribution/Scripts/Installer/preinstall +++ b/Distribution/Scripts/Installer/preinstall @@ -23,7 +23,7 @@ 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 +if [ "$OSX_MINOR_VER" -gt "$OSX_MAVERICKS_MINOR_VER" ]; then KEXT_DST=/Library/Extensions else KEXT_DST=/System/Library/Extensions diff --git a/Distribution/Scripts/Uninstaller/postinstall b/Distribution/Scripts/Uninstaller/postinstall index e102ec1e..985318db 100755 --- a/Distribution/Scripts/Uninstaller/postinstall +++ b/Distribution/Scripts/Uninstaller/postinstall @@ -23,7 +23,7 @@ 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 +if [ "$OSX_MINOR_VER" -gt "$OSX_MAVERICKS_MINOR_VER" ]; then KEXT_DST=/Library/Extensions else KEXT_DST=/System/Library/Extensions diff --git a/Distribution/package.sh b/Distribution/package.sh index 8d988a7f..ab498fb7 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="1.0.0-beta2" +VERSION="1.0.0-beta3" # Output of final DMG RELEASE="../Release" @@ -42,6 +42,8 @@ UNINSTALLER_DIST_XML="Resources/Uninstaller.xml" REQUIREMENTS_PATH="Resources/Requirements.plist" # Relelase build of all three components +xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace \ + -scheme iSCSI.framework -configuration release BUILD_DIR=$XCODE_RELEASE_BUILD_DIR xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace \ -scheme iSCSI.kext -configuration release BUILD_DIR=$XCODE_RELEASE_BUILD_DIR xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace \ diff --git a/Scripts/build.sh b/Scripts/build.sh index 41dd83fe..ae908b5a 100755 --- a/Scripts/build.sh +++ b/Scripts/build.sh @@ -1,3 +1,4 @@ +xcodebuild -workspace ../iSCSIInitiator.xcodeproj/project.xcworkspace -scheme iSCSI.framework 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 iSCSI.kext build diff --git a/Scripts/install.sh b/Scripts/install.sh index 9359e379..ae76e03b 100755 --- a/Scripts/install.sh +++ b/Scripts/install.sh @@ -22,7 +22,7 @@ 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 +if [ "$OSX_MINOR_VER" -gt "$OSX_MAVERICKS_MINOR_VER" ]; then KEXT_DST=/Library/Extensions else KEXT_DST=/System/Library/Extensions @@ -46,16 +46,17 @@ if [ X"" == X"${SOURCE_PATH}" ]; then fi # Copy kernel extension & load it +sudo mkdir -p $KEXT_DST 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 mkdir -p $FRAMEWORK_DST 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 mkdir -p $DAEMON_DST @@ -67,10 +68,12 @@ sudo chmod 644 $DAEMON_PLIST_DST/$DAEMON_PLIST sudo chown root:wheel $DAEMON_PLIST_DST/$DAEMON_PLIST # Copy user tool +sudo mkdir -p $TOOL_DST sudo cp $SOURCE_PATH/$TOOL $TOOL_DST/$TOOL sudo chmod +x $TOOL_DST/$TOOL # Copy man page +sudo mkdir -p $MAN_DST sudo cp $SOURCE_PATH/$MAN_TOOL $MAN_DST sudo cp $SOURCE_PATH/$MAN_DAEMON $MAN_DST diff --git a/Scripts/uninstall.sh b/Scripts/uninstall.sh index 7c144a35..dffc45f6 100755 --- a/Scripts/uninstall.sh +++ b/Scripts/uninstall.sh @@ -22,7 +22,7 @@ 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 +if [ "$OSX_MINOR_VER" -gt "$OSX_MAVERICKS_MINOR_VER" ]; then KEXT_DST=/Library/Extensions else KEXT_DST=/System/Library/Extensions diff --git a/Source/Kernel/iSCSITypesKernel.h b/Source/Kernel/iSCSITypesKernel.h index c1420b52..104824a1 100644 --- a/Source/Kernel/iSCSITypesKernel.h +++ b/Source/Kernel/iSCSITypesKernel.h @@ -105,6 +105,9 @@ typedef struct iSCSIConnection { /*! Keeps track of the index in the above array should be populated next. */ UInt8 bytesPerSecHistoryIdx; + /*! Keeps track of the connection latency (ms). */ + UInt32 latency_ms; + //////////////////// Configured Connection Parameters ///////////////////// /*! Flag that indicates if this connection uses header digests. */ diff --git a/Source/Kernel/iSCSIVirtualHBA.cpp b/Source/Kernel/iSCSIVirtualHBA.cpp index ff15522a..3e1f0919 100644 --- a/Source/Kernel/iSCSIVirtualHBA.cpp +++ b/Source/Kernel/iSCSIVirtualHBA.cpp @@ -862,10 +862,10 @@ void iSCSIVirtualHBA::ProcessNOPIn(iSCSISession * session, // Grab current system uptime clock_get_system_microtime(&secs,&usecs); - UInt32 latency_ms = (secs - secs_stamp)*1e3 + (usecs - usecs_stamp)/1e3; + connection->latency_ms = (secs - secs_stamp)*1e3 + (usecs - usecs_stamp)/1e3; DBLog("iscsi: Connection latency: %d ms (sid: %d, cid: %d)\n", - latency_ms,session->sessionId,connection->cid); + connection->latency_ms,session->sessionId,connection->cid); // Remove latency measurement task from queue connection->taskQueue->completeCurrentTask(); diff --git a/Source/User/iSCSI Framework/iSCSIDA.c b/Source/User/iSCSI Framework/iSCSIDA.c index aed94365..be1f8873 100644 --- a/Source/User/iSCSI Framework/iSCSIDA.c +++ b/Source/User/iSCSI Framework/iSCSIDA.c @@ -97,6 +97,7 @@ void iSCSIDAUnmountApplierFunc(io_object_t entry, void * context) DADiskRef disk = DADiskCreateFromIOMedia(kCFAllocatorDefault,opContext->session,entry); DADiskUnmount(disk,opContext->options,iSCSIDADiskUnmountComplete,context); + CFRelease(disk); } @@ -137,6 +138,7 @@ void iSCSIDAMountApplierFunc(io_object_t entry, void * context) DADiskRef disk = DADiskCreateFromIOMedia(kCFAllocatorDefault,opContext->session,entry); DADiskMount(disk,NULL,opContext->options,iSCSIDADiskMountComplete,context); + CFRelease(disk); } /*! Mounts all IOMedia associated with a particular iSCSI session, and diff --git a/Source/User/iSCSI Framework/iSCSIDaemonInterface.c b/Source/User/iSCSI Framework/iSCSIDaemonInterface.c index e3a6a580..aeef8120 100644 --- a/Source/User/iSCSI Framework/iSCSIDaemonInterface.c +++ b/Source/User/iSCSI Framework/iSCSIDaemonInterface.c @@ -35,7 +35,7 @@ static const int kiSCSIDaemonConnectTimeoutMilliSec = 100; /*! Timeout to use for normal communication with daemon. This is the time * that the client will have to wait for the deamon to perform the desired * operation (potentially over the network). */ -static const int kiSCSIDaemonDefaultTimeoutSec = 30; +static const int kiSCSIDaemonDefaultTimeoutSec = 10; const iSCSIDMsgLoginCmd iSCSIDMsgLoginCmdInit = { @@ -95,6 +95,14 @@ const iSCSIDMsgPreferencesIOUnlockAndSyncCmd iSCSIDMsgPreferencesIOUnlockAndSync .funcCode = kiSCSIDPreferencesIOUnlockAndSync }; +const iSCSIDMsgSetSharedSecretCmd iSCSIDMsgSetSharedSecretCmdInit = { + .funcCode = kiSCSIDSetSharedSecret +}; + +const iSCSIDMsgRemoveSharedSecretCmd iSCSIDMsgRemoveSharedSecretCmdInit = { + .funcCode = kiSCSIDRemoveSharedSecret +}; + iSCSIDaemonHandle iSCSIDaemonConnect() { iSCSIDaemonHandle handle = socket(PF_LOCAL,SOCK_STREAM,0); @@ -654,27 +662,17 @@ errno_t iSCSIDaemonPreferencesIOLockAndSync(iSCSIDaemonHandle handle, * 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) + if(handle < 0) return EINVAL; CFDataRef preferencesData = NULL; - AuthorizationExternalForm authExtForm; - AuthorizationMakeExternalForm(authorization,&authExtForm); - - CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - (UInt8*)&authExtForm.bytes, - kAuthorizationExternalFormLength, - kCFAllocatorDefault); - iSCSIDMsgPreferencesIOUnlockAndSyncCmd cmd = iSCSIDMsgPreferencesIOUnlockAndSyncCmdInit; if(preferences) { @@ -684,10 +682,7 @@ errno_t iSCSIDaemonPreferencesIOUnlockAndSync(iSCSIDaemonHandle handle, else cmd.preferencesLength = 0; - cmd.authorizationLength = cmd.authorizationLength = (UInt32)CFDataGetLength(authData); - - errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, - authData,preferencesData,NULL); + errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd,preferencesData,NULL); if(preferencesData) CFRelease(preferencesData); @@ -706,3 +701,106 @@ errno_t iSCSIDaemonPreferencesIOUnlockAndSync(iSCSIDaemonHandle handle, return rsp.errorCode; } +/*! Sets or updates a shared secret. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights. + * @param nodeIQN the node iSCSI qualified name. + * @param sharedSecret the secret to set. + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonSetSharedSecret(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + CFStringRef nodeIQN, + CFStringRef sharedSecret) +{ + // Validate inputs + if(handle < 0 || !authorization || !nodeIQN || !sharedSecret) + return EINVAL; + + AuthorizationExternalForm authExtForm; + AuthorizationMakeExternalForm(authorization,&authExtForm); + + CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + (UInt8*)&authExtForm.bytes, + kAuthorizationExternalFormLength, + kCFAllocatorDefault); + + CFDataRef nodeIQNData = CFStringCreateExternalRepresentation(kCFAllocatorDefault,nodeIQN,kCFStringEncodingASCII,NULL); + CFDataRef sharedSecretData = CFStringCreateExternalRepresentation(kCFAllocatorDefault,sharedSecret,kCFStringEncodingASCII,NULL); + + iSCSIDMsgSetSharedSecretCmd cmd = iSCSIDMsgSetSharedSecretCmdInit; + cmd.authorizationLength = (UInt32)CFDataGetLength(authData); + cmd.nodeIQNLength = CFDataGetLength(nodeIQNData); + cmd.secretLength = CFDataGetLength(sharedSecretData); + + errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, + authData,nodeIQNData,sharedSecretData,NULL); + + if(nodeIQNData) + CFRelease(nodeIQNData); + + if(sharedSecretData) + CFRelease(sharedSecretData); + + if(error) + return error; + + iSCSIDMsgSetSharedSecretRsp rsp; + + if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EIO; + + if(rsp.funcCode != kiSCSIDSetSharedSecret) + return EIO; + + return rsp.errorCode; +} + +/*! Sets or updates a shared secret. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights. + * @param nodeIQN the node iSCSI qualified name. + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonRemoveSharedSecret(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + CFStringRef nodeIQN) +{ + // Validate inputs + if(handle < 0 || !authorization || !nodeIQN) + return EINVAL; + + AuthorizationExternalForm authExtForm; + AuthorizationMakeExternalForm(authorization,&authExtForm); + + CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + (UInt8*)&authExtForm.bytes, + kAuthorizationExternalFormLength, + kCFAllocatorDefault); + + CFDataRef nodeIQNData = CFStringCreateExternalRepresentation(kCFAllocatorDefault,nodeIQN,kCFStringEncodingASCII,'0'); + + iSCSIDMsgRemoveSharedSecretCmd cmd = iSCSIDMsgRemoveSharedSecretCmdInit; + cmd.authorizationLength = (UInt32)CFDataGetLength(authData); + cmd.nodeIQNLength = CFDataGetLength(nodeIQNData); + + errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, + authData,nodeIQNData,NULL); + + if(nodeIQNData) + CFRelease(nodeIQNData); + + if(error) + return error; + + iSCSIDMsgRemoveSharedSecretRsp rsp; + + if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EIO; + + if(rsp.funcCode != kiSCSIDRemoveSharedSecret) + return EIO; + + + return rsp.errorCode; +} + + diff --git a/Source/User/iSCSI Framework/iSCSIDaemonInterface.h b/Source/User/iSCSI Framework/iSCSIDaemonInterface.h index 6e805e42..202d36ae 100644 --- a/Source/User/iSCSI Framework/iSCSIDaemonInterface.h +++ b/Source/User/iSCSI Framework/iSCSIDaemonInterface.h @@ -159,12 +159,29 @@ errno_t iSCSIDaemonPreferencesIOLockAndSync(iSCSIDaemonHandle handle, * 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); + iSCSIPreferencesRef preferences); + +/*! Sets or updates a shared secret. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights. + * @param nodeIQN the node iSCSI qualified name. + * @param sharedSecret the secret to set. + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonSetSharedSecret(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + CFStringRef nodeIQN, + CFStringRef sharedSecret); +/*! Sets or updates a shared secret. + * @param handle a handle to a daemon connection. + * @param authorization an authorization for the right kiSCSIAuthModifyRights. + * @param nodeIQN the node iSCSI qualified name. + * @return an error code indicating whether the operating was successful. */ +errno_t iSCSIDaemonRemoveSharedSecret(iSCSIDaemonHandle handle, + AuthorizationRef authorization, + CFStringRef nodeIQN); #endif /* defined(__ISCSI_DAEMON_INTERFACE__) */ diff --git a/Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h b/Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h index 5aa34e2f..691475be 100644 --- a/Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h +++ b/Source/User/iSCSI Framework/iSCSIDaemonInterfaceShared.h @@ -120,9 +120,9 @@ typedef struct __iSCSIDMsgLoginCmd { const UInt16 funcCode; UInt16 reserved; - CFLength authLength; - CFLength targetLength; - CFLength portalLength; + UInt32 authLength; + UInt32 targetLength; + UInt32 portalLength; UInt32 reserved3; UInt32 reserved4; @@ -141,7 +141,7 @@ typedef struct __iSCSIDMsgLoginRsp { UInt32 reserved2; UInt32 reserved3; UInt32 reserved4; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgLoginRsp; @@ -150,9 +150,9 @@ typedef struct __iSCSIDMsgLogoutCmd { const UInt16 funcCode; UInt16 reserved; - CFLength authLength; - CFLength targetLength; - CFLength portalLength; + UInt32 authLength; + UInt32 targetLength; + UInt32 portalLength; UInt32 reserved4; UInt32 reserved5; @@ -171,7 +171,7 @@ typedef struct __iSCSIDMsgLogoutRsp { UInt32 reserved2; UInt32 reserved3; UInt32 reserved4; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgLogoutRsp; @@ -200,7 +200,7 @@ typedef struct __iSCSIDMsgCreateArrayOfActiveTargetsRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgCreateArrayOfActiveTargetsRsp; @@ -229,7 +229,7 @@ typedef struct __iSCSIDMsgCreateArrayOfActivePortalsForTargetRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgCreateArrayOfActivePortalsForTargetRsp; @@ -238,7 +238,7 @@ typedef struct __iSCSIDMsgIsTargetActiveCmd { const UInt16 funcCode; UInt16 reserved; - CFLength targetLength; + UInt32 targetLength; UInt32 reserved2; UInt32 reserved3; UInt32 reserved4; @@ -258,7 +258,7 @@ typedef struct __iSCSIDMsgIsTargetActiveRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgIsTargetActiveRsp; @@ -267,8 +267,8 @@ typedef struct __iSCSIDMsgIsPortalActiveCmd { const UInt16 funcCode; UInt16 reserved; - CFLength portalLength; - CFLength targetLength; + UInt32 portalLength; + UInt32 targetLength; UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; @@ -287,7 +287,7 @@ typedef struct __iSCSIDMsgIsPortalActiveRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgIsPortalActiveRsp; @@ -299,8 +299,8 @@ typedef struct __iSCSIDMsgQueryTargetForAuthMethodCmd { UInt16 reserved; UInt32 reserved2; UInt32 reserved3; - CFLength portalLength; - CFLength targetLength; + UInt32 portalLength; + UInt32 targetLength; UInt32 reserved4; } __attribute__((packed)) iSCSIDMsgQueryTargetForAuthMethodCmd; @@ -317,7 +317,7 @@ typedef struct __iSCSIDMsgQueryTargetForAuthMethodRsp { UInt32 reserved2; UInt32 reserved3; UInt32 authMethod; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgQueryTargetForAuthMethodRsp; @@ -326,7 +326,7 @@ typedef struct __iSCSIDMsgCreateCFPropertiesForSessionCmd { const UInt16 funcCode; UInt16 reserved; - CFLength targetLength; + UInt32 targetLength; UInt32 reserved2; UInt32 reserved3; UInt32 reserved4; @@ -347,7 +347,7 @@ typedef struct __iSCSIDMsgCreateCFPropertiesForSessionRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgCreateCFPropertiesForSessionRsp; @@ -356,8 +356,8 @@ typedef struct __iSCSIDMsgCreateCFPropertiesForConnectionCmd { const UInt16 funcCode; UInt16 reserved; - CFLength targetLength; - CFLength portalLength; + UInt32 targetLength; + UInt32 portalLength; UInt32 reserved2; UInt32 reserved3; UInt32 reserved4; @@ -377,7 +377,7 @@ typedef struct __iSCSIDMsgCreateCFPropertiesForConnectionRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgCreateCFPropertiesForConnectionRsp; @@ -408,7 +408,7 @@ typedef struct __iSCSIDMsgUpdateDiscoveryRsp { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength dataLength; + UInt32 dataLength; } __attribute__((packed)) iSCSIDMsgUpdateDiscoveryRsp; @@ -422,7 +422,7 @@ typedef struct __iSCSIDMsgPreferencesIOLockAndSyncCmd { UInt32 reserved3; UInt32 reserved4; UInt32 reserved5; - CFLength authorizationLength; + UInt32 authorizationLength; } __attribute__((packed)) iSCSIDMsgPreferencesIOLockAndSyncCmd; @@ -452,8 +452,8 @@ typedef struct __iSCSIDMsgPreferencesIOUnlockAndSyncCmd { UInt32 reserved2; UInt32 reserved3; UInt32 reserved4; - CFLength authorizationLength; - CFLength preferencesLength; + UInt32 reserved5; + UInt32 preferencesLength; } __attribute__((packed)) iSCSIDMsgPreferencesIOUnlockAndSyncCmd; @@ -474,6 +474,68 @@ typedef struct __iSCSIDMsgPreferencesIOUnlockAndSyncRsp { } __attribute__((packed)) iSCSIDMsgPreferencesIOUnlockAndSyncRsp; + +/*! Command to set shared a shared secret. */ +typedef struct __iSCSIDMsgSetSharedSecretCmd { + + const UInt16 funcCode; + UInt16 reserved; + UInt32 reserved2; + UInt32 reserved3; + UInt32 authorizationLength; + UInt32 nodeIQNLength; + UInt32 secretLength; + +} __attribute__((packed)) iSCSIDMsgSetSharedSecretCmd; + +/*! Default initialization for command to set a shared secret. */ +extern const iSCSIDMsgSetSharedSecretCmd iSCSIDMsgSetSharedSecretCmdInit; + +/*! Response to command to set a shared secret. */ +typedef struct __iSCSIDMsgSetSharedSecretRsp { + + const UInt8 funcCode; + UInt16 reserved; + UInt32 errorCode; + UInt8 reserved2; + UInt32 reserved3; + UInt32 reserved4; + UInt32 reserved5; + UInt32 reserved6; + +} __attribute__((packed)) iSCSIDMsgSetSharedSecretRsp; + + +/*! Command to set shared a shared secret. */ +typedef struct __iSCSIDMsgRemoveSharedSecretCmd { + + const UInt16 funcCode; + UInt16 reserved; + UInt32 reserved2; + UInt32 reserved3; + UInt32 reserved4; + UInt32 authorizationLength; + UInt32 nodeIQNLength; + +} __attribute__((packed)) iSCSIDMsgRemoveSharedSecretCmd; + +/*! Default initialization for command to set a shared secret. */ +extern const iSCSIDMsgRemoveSharedSecretCmd kiSCSIDMsgRemoveSharedSecretCmdInit; + +/*! Response to command to set a shared secret. */ +typedef struct __iSCSIDMsgRemoveSharedSecretRsp { + + const UInt8 funcCode; + UInt16 reserved; + UInt32 errorCode; + UInt8 reserved2; + UInt32 reserved3; + UInt32 reserved4; + UInt32 reserved5; + UInt32 reserved6; + +} __attribute__((packed)) iSCSIDMsgRemoveSharedSecretRsp; + ////////////////////////////// DAEMON FUNCTIONS //////////////////////////////// enum iSCSIDFunctionCodes { @@ -525,6 +587,12 @@ enum iSCSIDFunctionCodes { /*! Unlock preferences mutex and update application values using preferences object. */ kiSCSIDPreferencesIOUnlockAndSync = 15, + + /*! Set or update a SCSI shared secret. */ + kiSCSIDSetSharedSecret = 16, + + /*! Remove a SCSI shared secret. */ + kiSCSIDRemoveSharedSecret = 17, /*! Invalid daemon command. */ kiSCSIDInvalidFunctionCode diff --git a/Source/User/iSCSI Framework/iSCSIKeychain.c b/Source/User/iSCSI Framework/iSCSIKeychain.c index ddf50651..8d741313 100644 --- a/Source/User/iSCSI Framework/iSCSIKeychain.c +++ b/Source/User/iSCSI Framework/iSCSIKeychain.c @@ -27,6 +27,7 @@ */ #include "iSCSIKeychain.h" +#include /*! Copies a shared secret associated with a particular * iSCSI node (either initiator or target) to the system keychain. @@ -44,12 +45,17 @@ CFStringRef iSCSIKeychainCopyCHAPSecretForNode(CFStringRef nodeIQN) UInt32 sharedSecretLength = 0; void * sharedSecretData = NULL; + + UInt32 nodeIQNLength = (UInt32)CFStringGetLength(nodeIQN) + 1; + char nodeIQNBuffer[nodeIQNLength]; + + CFStringGetCString(nodeIQN,nodeIQNBuffer,nodeIQNLength,kCFStringEncodingASCII); status = SecKeychainFindGenericPassword(NULL, - (UInt32)CFStringGetLength(nodeIQN), - CFStringGetCStringPtr(nodeIQN,kCFStringEncodingASCII), - (UInt32)CFStringGetLength(nodeIQN), - CFStringGetCStringPtr(nodeIQN,kCFStringEncodingASCII), + nodeIQNLength, + nodeIQNBuffer, + nodeIQNLength, + nodeIQNBuffer, &sharedSecretLength, &sharedSecretData,&item); @@ -74,67 +80,77 @@ OSStatus iSCSIKeychainSetCHAPSecretForNode(CFStringRef nodeIQN, CFStringRef sharedSecret) { SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); + SecKeychainSetUserInteractionAllowed(true); SecKeychainUnlock(NULL,0,NULL,false); OSStatus status; SecKeychainItemRef itemRef = NULL; + + // Allow for a null terminator (C string) - hence the + 1 + const UInt32 nodeIQNLength = (UInt32)CFStringGetLength(nodeIQN) + 1; + char nodeIQNBuffer[nodeIQNLength]; + CFStringGetCString(nodeIQN,nodeIQNBuffer,nodeIQNLength,kCFStringEncodingASCII); + + const int secretLength = (int)CFStringGetLength(sharedSecret) + 1; + char secretBuffer[secretLength]; + CFStringGetCString(sharedSecret,secretBuffer,secretLength,kCFStringEncodingASCII); SecKeychainFindGenericPassword(NULL, - (UInt32)CFStringGetLength(nodeIQN), - CFStringGetCStringPtr(nodeIQN,kCFStringEncodingASCII), - (UInt32)CFStringGetLength(nodeIQN), - CFStringGetCStringPtr(nodeIQN,kCFStringEncodingASCII), + nodeIQNLength, + nodeIQNBuffer, + nodeIQNLength, + nodeIQNBuffer, 0,0,&itemRef); + // Create attribute list for later use + const char secItemDesc[] = "iSCSI CHAP Shared Secret"; + const int secItemDescLength = sizeof(secItemDesc)/sizeof(secItemDesc[0]); + + SecKeychainAttribute attrs[] = { + { kSecLabelItemAttr, nodeIQNLength, nodeIQNBuffer }, + { kSecDescriptionItemAttr, secItemDescLength, (void*)secItemDesc }, + { kSecAccountItemAttr, nodeIQNLength, nodeIQNBuffer }, + { kSecServiceItemAttr, nodeIQNLength, nodeIQNBuffer } + }; + + SecKeychainAttributeList attrList = { sizeof(attrs)/sizeof(attrs[0]), attrs }; + // Update the secret if it exists; else create a new entry if(itemRef) { - status = SecKeychainItemModifyContent(itemRef,0, - (UInt32)CFStringGetLength(sharedSecret), - CFStringGetCStringPtr(sharedSecret,kCFStringEncodingASCII)); - + status = SecKeychainItemModifyContent(itemRef,&attrList,secretLength,secretBuffer); CFRelease(itemRef); } // Create a new item else { SecAccessRef accessRef; - CFArrayRef trustedList; - SecTrustedApplicationRef trustedApps[2]; - SecTrustedApplicationCreateFromPath("/usr/local/bin/iscsictl",&trustedApps[0]); - SecTrustedApplicationCreateFromPath("/usr/local/libexec/iscsid",&trustedApps[1]); - - trustedList = CFArrayCreate(kCFAllocatorDefault,(const void **)trustedApps,2,&kCFTypeArrayCallBacks); - - - status = SecAccessCreate(CFSTR("Description"),trustedList,&accessRef); - - // Get the system keychain and unlock it (prompts user if required) - SecKeychainRef keychain; - status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem,&keychain); - - CFStringRef secItemLabel = nodeIQN; - CFStringRef secItemDesc = CFSTR("iSCSI CHAP Shared Secret"); - CFStringRef secItemAcct = nodeIQN; - CFStringRef secItemService = nodeIQN; - + SecACLRef aclRef; - SecKeychainAttribute attrs[] = { - { kSecLabelItemAttr, (UInt32)CFStringGetLength(secItemLabel),(char *)CFStringGetCStringPtr(secItemLabel,kCFStringEncodingUTF8) }, - { kSecDescriptionItemAttr, (UInt32)CFStringGetLength(secItemDesc),(char *)CFStringGetCStringPtr(secItemDesc,kCFStringEncodingUTF8) }, - { kSecAccountItemAttr, (UInt32)CFStringGetLength(secItemAcct),(char *)CFStringGetCStringPtr(secItemAcct,kCFStringEncodingUTF8) }, - { kSecServiceItemAttr, (UInt32)CFStringGetLength(secItemService),(char *)CFStringGetCStringPtr(secItemService,kCFStringEncodingUTF8) } - }; - - SecKeychainAttributeList attrList = { sizeof(attrs)/sizeof(attrs[0]), attrs }; + CFStringRef description = CFSTR("Description"); + + // Create new security access + status = SecAccessCreate(description,NULL,&accessRef); - SecKeychainItemRef itemRef; - status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, - &attrList, - (UInt32)CFStringGetLength(sharedSecret), - CFStringGetCStringPtr(sharedSecret,kCFStringEncodingASCII), - keychain,accessRef,&itemRef); + if(status == errSecSuccess) + status = SecACLCreateWithSimpleContents(accessRef,NULL,description,kSecKeychainPromptRequirePassphase,&aclRef); + + if(status == errSecSuccess) { - if(keychain) - CFRelease(keychain); + // Get the system keychain and unlock it (prompts user if required) + SecKeychainRef keychain; + status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem,&keychain); + + SecKeychainItemRef itemRef; + status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, + &attrList, + secretLength, + secretBuffer, + keychain,accessRef,&itemRef); + if(keychain) + CFRelease(keychain); + + if(itemRef) + CFRelease(itemRef); + } } return status; @@ -148,21 +164,28 @@ OSStatus iSCSIKeychainDeleteCHAPSecretForNode(CFStringRef nodeIQN) { SecKeychainRef sysKeychain = NULL; OSStatus status; - SecKeychainItemRef item = NULL; - + SecKeychainItemRef itemRef = NULL; + // Get the system keychain and unlock it (prompts user if required) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); + SecKeychainSetUserInteractionAllowed(true); + SecKeychainUnlock(NULL,0,NULL,false); + + UInt32 nodeIQNLength = (UInt32)CFStringGetLength(nodeIQN) + 1; + char nodeIQNBuffer[nodeIQNLength]; + + CFStringGetCString(nodeIQN,nodeIQNBuffer,nodeIQNLength,kCFStringEncodingASCII); status = SecKeychainFindGenericPassword(NULL, - (UInt32)CFStringGetLength(nodeIQN), - CFStringGetCStringPtr(nodeIQN,kCFStringEncodingASCII), - (UInt32)CFStringGetLength(nodeIQN), - CFStringGetCStringPtr(nodeIQN,kCFStringEncodingASCII), - 0,0,&item); + nodeIQNLength, + nodeIQNBuffer, + nodeIQNLength, + nodeIQNBuffer, + 0,0,&itemRef); // Remove item from keychain if(status == errSecSuccess) { - SecKeychainItemDelete(item); + SecKeychainItemDelete(itemRef); } if(sysKeychain) @@ -176,30 +199,26 @@ OSStatus iSCSIKeychainDeleteCHAPSecretForNode(CFStringRef nodeIQN) * @return true if a CHAP secret exists for the specified node. */ Boolean iSCSIKeychainContainsCHAPSecretForNode(CFStringRef nodeIQN) { + OSStatus status; + SecKeychainItemRef itemRef = NULL; + // Get the system keychain and unlock it (prompts user if required) SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem); - - SecKeychainItemRef item = NULL; - - CFStringRef keys[] = { - kSecClass, - kSecAttrAccount - - }; - - CFStringRef values[] = { - kSecClassGenericPassword, - nodeIQN, - }; - - CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, - (void*)keys,(void*)values, - sizeof(keys)/sizeof(void*), - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - SecItemCopyMatching(query,(CFTypeRef *)&item); - - return (item != NULL); + + UInt32 nodeIQNLength = (UInt32)CFStringGetLength(nodeIQN) + 1; + char nodeIQNBuffer[nodeIQNLength]; + + CFStringGetCString(nodeIQN,nodeIQNBuffer,nodeIQNLength,kCFStringEncodingASCII); + + status = SecKeychainFindGenericPassword(NULL, + nodeIQNLength, + nodeIQNBuffer, + nodeIQNLength, + nodeIQNBuffer, + 0,0,&itemRef); + if(itemRef) + CFRelease(itemRef); + + return status == errSecSuccess; } diff --git a/Source/User/iSCSI Framework/iSCSIPreferences.c b/Source/User/iSCSI Framework/iSCSIPreferences.c index d1ed246f..c681309b 100644 --- a/Source/User/iSCSI Framework/iSCSIPreferences.c +++ b/Source/User/iSCSI Framework/iSCSIPreferences.c @@ -1327,7 +1327,7 @@ iSCSIPreferencesRef iSCSIPreferencesCreateWithData(CFDataRef data) { CFPropertyListFormat format; - iSCSIPreferencesRef preferences = CFPropertyListCreateWithData(kCFAllocatorDefault,data,0,&format,NULL); + iSCSIPreferencesRef preferences = (iSCSIPreferencesRef)CFPropertyListCreateWithData(kCFAllocatorDefault,data,0,&format,NULL); if(format == kCFPropertyListBinaryFormat_v1_0) return preferences; @@ -1341,9 +1341,31 @@ iSCSIPreferencesRef iSCSIPreferencesCreateWithData(CFDataRef data) 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)); + CFDictionaryRef dict = NULL; + + dict = iSCSIPreferencesCopyPropertyDict(kiSCSIPKAppId,kiSCSIPKInitiator); + + if(dict) { + CFDictionarySetValue(preferences,kiSCSIPKInitiator,dict); + CFRelease(dict); + dict = NULL; + } + + dict = iSCSIPreferencesCopyPropertyDict(kiSCSIPKAppId,kiSCSIPKTargets); + + if(dict) { + CFDictionarySetValue(preferences,kiSCSIPKTargets,dict); + CFRelease(dict); + dict = NULL; + } + + dict = iSCSIPreferencesCopyPropertyDict(kiSCSIPKAppId,kiSCSIPKDiscovery); + + if(dict) { + CFDictionarySetValue(preferences,kiSCSIPKDiscovery,dict); + CFRelease(dict); + dict = NULL; + } } /*! Synchronizes application values with those in the preferences object. diff --git a/Source/User/iSCSI Framework/iSCSIPropertyList.c b/Source/User/iSCSI Framework/iSCSIPropertyList.c deleted file mode 100644 index 4c1831aa..00000000 --- a/Source/User/iSCSI Framework/iSCSIPropertyList.c +++ /dev/null @@ -1,1387 +0,0 @@ -/* - * 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" -#include -#include -#include - -/*! A cached version of the targets dictionary. */ -CFMutableDictionaryRef targetsCache = NULL; - -/*! Flag that indicates whether the targets cache was modified. */ -Boolean targetNodesCacheModified = false; - -/*! A cached version of the discovery dictionary. */ -CFMutableDictionaryRef discoveryCache = NULL; - -/*! Flag that indicates whether the discovery cache was modified. */ -Boolean discoveryCacheModified = false; - -/*! A cached version of the initiator dictionary. */ -CFMutableDictionaryRef initiatorCache = NULL; - -/*! Flag that indicates whether the initiator cache was modified. */ -Boolean initiatorNodeCacheModified = false; - -/*! 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 iSCSIPLCopyPropertyDict(CFStringRef key) -{ - // Retrieve the desired property from the property list - CFDictionaryRef propertyList = CFPreferencesCopyValue(key,kiSCSIPKAppId, - kCFPreferencesAnyUser, - kCFPreferencesCurrentHost); - if(!propertyList) - return NULL; - - // Create a deep copy to make the dictionary mutable - CFMutableDictionaryRef mutablePropertyList = (CFMutableDictionaryRef)CFPropertyListCreateDeepCopy( - kCFAllocatorDefault, - propertyList, - kCFPropertyListMutableContainersAndLeaves); - - // Release original retrieved property - CFRelease(propertyList); - return mutablePropertyList; -} - -/*! Creates a mutable dictionary for the targets key. - * @return a mutable dictionary for the targets key. */ -CFMutableDictionaryRef iSCSIPLCreateTargetsDict() -{ - return CFDictionaryCreateMutable(kCFAllocatorDefault, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); -} - - -/*! Creates a mutable dictionary for the discovery key. - * @return a mutable dictionary for the discovery key. */ -CFMutableDictionaryRef iSCSIPLCreateDiscoveryDict() -{ - 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 iSCSIPLCreateInitiatorDict() -{ - 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 iSCSIPLCreateTargetDict() -{ - 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 iSCSIPLGetInitiatorDict(Boolean createIfMissing) -{ - if(createIfMissing && !initiatorCache) - initiatorCache = iSCSIPLCreateInitiatorDict(); - - return initiatorCache; -} - -CFMutableDictionaryRef iSCSIPLGetDiscoveryDict(Boolean createIfMissing) -{ - if(createIfMissing && !discoveryCache) - discoveryCache = iSCSIPLCreateDiscoveryDict(); - - return discoveryCache; -} - -/*! Helper function. Retrieves the iSCSI discovery portals dictionary. */ -CFMutableDictionaryRef iSCSIPLGetSendTargetsDiscoveryPortals(Boolean createIfMissing) -{ - // Get discovery dictionary - CFMutableDictionaryRef discoveryDict = iSCSIPLGetDiscoveryDict(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 iSCSIPLGetDynamicTargetsForSendTargets(CFStringRef portalAddress, - Boolean createIfMissing) -{ - CFArrayRef targetsList = NULL; - CFMutableDictionaryRef discoveryPortals = iSCSIPLGetSendTargetsDiscoveryPortals(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 iSCSIPLGetTargets(Boolean createIfMissing) -{ - if(createIfMissing && !targetsCache) - targetsCache = iSCSIPLCreateTargetsDict(); - - return targetsCache; -} - -CFMutableDictionaryRef iSCSIPLGetTargetDict(CFStringRef targetIQN, - Boolean createIfMissing) -{ - // Get list of targets - CFMutableDictionaryRef targetsList = iSCSIPLGetTargets(createIfMissing); - - if(targetsList) - { - if(createIfMissing && CFDictionaryGetCountOfKey(targetsList,targetIQN) == 0) - { - CFMutableDictionaryRef targetDict = iSCSIPLCreateTargetDict(); - CFDictionarySetValue(targetsList,targetIQN,targetDict); - CFRelease(targetDict); - } - - return (CFMutableDictionaryRef)CFDictionaryGetValue(targetsList,targetIQN); - } - return NULL; -} - -CFMutableDictionaryRef iSCSIPLGetPortalsList(CFStringRef targetIQN, - Boolean createIfMissing) -{ - // Get the target information dictionary - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLSetMaxConnectionsForTarget(CFStringRef targetIQN, - UInt32 maxConnections) -{ - // Get the target information dictionary - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,false); - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&maxConnections); - CFDictionarySetValue(targetDict,kiSCSIPKMaxConnections,value); - - targetNodesCacheModified = true; -} - -/*! 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 iSCSIPLSetErrorRecoveryLevelForTarget(CFStringRef targetIQN, - enum iSCSIErrorRecoveryLevels level) -{ - // Get the target information dictionary - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,false); - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberIntType,&level); - CFDictionarySetValue(targetDict,kiSCSIPKErrorRecoveryLevel,value); - - targetNodesCacheModified = true; -} - -/*! 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 iSCSIPLGetMaxConnectionsForTarget(CFStringRef targetIQN) -{ - // Get the target information dictionary - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLGetErrorRecoveryLevelForTarget(CFStringRef targetIQN) -{ - // Get the target information dictionary - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,false); - CFNumberRef value = CFDictionaryGetValue(targetDict,kiSCSIPKErrorRecoveryLevel); - - enum iSCSIErrorRecoveryLevels errorRecoveryLevel = kRFC3720_ErrorRecoveryLevel; - CFNumberGetValue(value,kCFNumberIntType,&errorRecoveryLevel); - return errorRecoveryLevel; -} - -iSCSIPortalRef iSCSIPLCopyPortalForTarget(CFStringRef targetIQN, - CFStringRef portalAddress) -{ - // Get list of portals for this target - CFMutableDictionaryRef portalsList = iSCSIPLGetPortalsList(targetIQN,false); - - iSCSIPortalRef portal = NULL; - - if(portalsList) { - CFMutableDictionaryRef portalDict = - (CFMutableDictionaryRef)CFDictionaryGetValue(portalsList, - portalAddress); - if(portalDict) - portal = iSCSIPortalCreateWithDictionary(portalDict); - } - return portal; -} - -iSCSITargetRef iSCSIPLCopyTarget(CFStringRef targetIQN) -{ - iSCSIMutableTargetRef target = NULL; - - if(iSCSIUtilsValidateIQN(targetIQN)) { - - CFMutableDictionaryRef targetsDict = iSCSIPLGetTargets(false); - - if(targetsDict) { - if(CFDictionaryContainsKey(targetsDict,targetIQN)) { - target = iSCSITargetCreateMutable(); - iSCSITargetSetIQN(target,targetIQN); - } - } - } - - return target; -} - -enum iSCSIDigestTypes iSCSIPLGetDataDigestForTarget(CFStringRef targetIQN) -{ - // Get the dictionary containing information about the target - CFDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLSetDataDigestForTarget(CFStringRef targetIQN,enum iSCSIDigestTypes digestType) -{ - // Get the dictionary containing information about the target - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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); - targetNodesCacheModified = true; - } - } -} - -enum iSCSIDigestTypes iSCSIPLGetHeaderDigestForTarget(CFStringRef targetIQN) -{ - // Get the dictionary containing information about the target - CFDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLSetHeaderDigestForTarget(CFStringRef targetIQN,enum iSCSIDigestTypes digestType) -{ - // Get the dictionary containing information about the target - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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); - targetNodesCacheModified = true; - } - } -} - -/*! Sets authentication method to be used by initiator. */ -void iSCSIPLSetInitiatorAuthenticationMethod(enum iSCSIAuthMethods authMethod) -{ - CFMutableDictionaryRef initiatorDict = iSCSIPLGetInitiatorDict(true); - - if(authMethod == kiSCSIAuthMethodNone) - CFDictionarySetValue(initiatorDict,kiSCSIPKAuth,kiSCSIPVAuthNone); - else if(authMethod == kiSCSIAuthMethodCHAP) - CFDictionarySetValue(initiatorDict,kiSCSIPKAuth,kiSCSIPVAuthCHAP); - - initiatorNodeCacheModified = true; -} - -/*! Gets the current authentication method used by the initiator. */ -enum iSCSIAuthMethods iSCSIPLGetInitiatorAuthenticationMethod() -{ - CFMutableDictionaryRef initiatorDict = iSCSIPLGetInitiatorDict(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 iSCSIPLSetInitiatorCHAPName(CFStringRef name) -{ - CFMutableDictionaryRef initiatorDict = iSCSIPLGetInitiatorDict(true); - - // Change CHAP name in property list - CFDictionarySetValue(initiatorDict,kiSCSIPKAuthCHAPName,name); - - initiatorNodeCacheModified = true; -} - -/*! Copies the CHAP name associated with the initiator. */ -CFStringRef iSCSIPLCopyInitiatorCHAPName() -{ - CFMutableDictionaryRef initiatorDict = iSCSIPLGetInitiatorDict(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 iSCSIPLSetInitiatorCHAPSecret(CFStringRef secret) -{ - CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN(); - - OSStatus status = iSCSIKeychainSetCHAPSecretForNode(initiatorIQN,secret); - CFRelease(initiatorIQN); - - return status; -} - -/*! Copies the CHAP secret associated with the initiator. */ -CFStringRef iSCSIPLCopyInitiatorCHAPSecret() -{ - CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN(); - - 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 iSCSIPLExistsInitiatorCHAPSecret() -{ - CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN(); - Boolean exists = iSCSIKeychainContainsCHAPSecretForNode(initiatorIQN); - CFRelease(initiatorIQN); - return exists; -} - -void iSCSIPLSetPortalForTarget(CFStringRef targetIQN, - iSCSIPortalRef portal) -{ - // Get list of portals for this target (only if it exists, otherwise NULL) - CFMutableDictionaryRef portalsList = iSCSIPLGetPortalsList(targetIQN,false); - - if(portal && portalsList) { - CFDictionaryRef portalDict = iSCSIPortalCreateDictionary(portal); - CFStringRef portalAddress = iSCSIPortalGetAddress(portal); - CFDictionarySetValue(portalsList,portalAddress,portalDict); - CFRelease(portalDict); - - targetNodesCacheModified = true; - } -} - -void iSCSIPLRemovePortalForTarget(CFStringRef targetIQN, - CFStringRef portalAddress) -{ - CFMutableDictionaryRef portalsList = iSCSIPLGetPortalsList(targetIQN,false); - - // Remove target if only one portal is left... - if(portalsList) { - if(CFDictionaryGetCount(portalsList) == 1) - iSCSIPLRemoveTarget(targetIQN); - else { - CFDictionaryRemoveValue(portalsList,portalAddress); - targetNodesCacheModified = true; - } - } -} - -/*! 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 iSCSIPLSetAutoLoginForTarget(CFStringRef targetIQN,Boolean autoLogin) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,true); - - if(targetDict) { - if(autoLogin) - CFDictionarySetValue(targetDict,kiSCSIPKAutoLogin,kCFBooleanTrue); - else - CFDictionarySetValue(targetDict,kiSCSIPKAutoLogin,kCFBooleanFalse); - - targetNodesCacheModified = true; - } -} - -/*! Gets whether the target should be logged in during startup. - * @param targetIQN the target iSCSI qualified name (IQN). */ -Boolean iSCSIPLGetAutoLoginForTarget(CFStringRef targetIQN) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLAddStaticTarget(CFStringRef targetIQN,iSCSIPortalRef portal) -{ - // Only proceed if the target does not exist; otherwise do nothing - if(!iSCSIPLContainsTarget(targetIQN)) { - - // Create list of target portals for a specific target (since the target - // does not exist it is created) - CFMutableDictionaryRef portalsList = iSCSIPLGetPortalsList(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 - iSCSIPLSetTargetConfigType(targetIQN,kiSCSITargetConfigStatic); - - targetNodesCacheModified = true; - } -} - -/*! 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 iSCSIPLAddDynamicTargetForSendTargets(CFStringRef targetIQN, - iSCSIPortalRef portal, - CFStringRef sendTargetsPortal) -{ - // Only proceed if the target does not exist; otherwise do nothing - if(!iSCSIPLContainsTarget(targetIQN)) { - - // Get target dictionary (since the target does not exist it is created) - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 = iSCSIPLGetPortalsList(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 - iSCSIPLSetTargetConfigType(targetIQN,kiSCSITargetConfigDynamicSendTargets); - targetNodesCacheModified = true; - } - - // Ensure target is associated with the specified iSCSI discovery portal - CFMutableArrayRef targetList = (CFMutableArrayRef)iSCSIPLGetDynamicTargetsForSendTargets(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); - discoveryCacheModified = true; - } -} - -void iSCSIPLRemoveTarget(CFStringRef targetIQN) -{ - CFMutableDictionaryRef targetsList = iSCSIPLGetTargets(false); - - if(targetsList) { - CFDictionaryRemoveValue(targetsList,targetIQN); - targetNodesCacheModified = true; - } - - // Remove CHAP secret if one exists - iSCSIKeychainDeleteCHAPSecretForNode(targetIQN); -} - -/*! Copies the initiator name from the iSCSI property list to a CFString object. - * @return the initiator name. */ -CFStringRef iSCSIPLCopyInitiatorIQN() -{ - if(!initiatorCache) { - initiatorCache = iSCSIPLCreateInitiatorDict(); -// initiatorNodeCacheModified = true; - } - - // Lookup and copy the initiator name from the dictionary - CFStringRef initiatorIQN = CFStringCreateCopy( - kCFAllocatorDefault,CFDictionaryGetValue(initiatorCache,kiSCSIPKInitiatorIQN)); - - return initiatorIQN; -} - -/*! Sets the initiator name in the iSCSI property list. - * @param initiatorIQN the initiator name to set. */ -void iSCSIPLSetInitiatorIQN(CFStringRef initiatorIQN) -{ - if(!initiatorCache) - initiatorCache = iSCSIPLCreateInitiatorDict(); - - // Update keychain if necessary - CFStringRef existingIQN = iSCSIPLCopyInitiatorIQN(); - - CFStringRef secret = iSCSIKeychainCopyCHAPSecretForNode(existingIQN); - - if(secret) { - iSCSIKeychainSetCHAPSecretForNode(initiatorIQN,secret); - CFRelease(secret); - iSCSIKeychainDeleteCHAPSecretForNode(existingIQN); - } - - // Update initiator name - CFDictionarySetValue(initiatorCache,kiSCSIPKInitiatorIQN,initiatorIQN); - CFRelease(existingIQN); - - initiatorNodeCacheModified = true; -} - -/*! Copies the initiator alias from the iSCSI property list to a CFString object. - * @return the initiator alias. */ -CFStringRef iSCSIPLCopyInitiatorAlias() -{ - if(!initiatorCache) { - initiatorCache = iSCSIPLCreateInitiatorDict(); -// initiatorNodeCacheModified = true; - } - - // Lookup and copy the initiator alias from the dictionary - CFStringRef initiatorAlias = CFStringCreateCopy( - kCFAllocatorDefault,CFDictionaryGetValue(initiatorCache,kiSCSIPKInitiatorAlias)); - - return initiatorAlias; -} - -/*! Sets the initiator alias in the iSCSI property list. - * @param initiatorAlias the initiator alias to set. */ -void iSCSIPLSetInitiatorAlias(CFStringRef initiatorAlias) -{ - if(!initiatorCache) - initiatorCache = iSCSIPLCreateInitiatorDict(); - - // Update initiator alias - CFDictionarySetValue(initiatorCache,kiSCSIPKInitiatorAlias,initiatorAlias); - - initiatorNodeCacheModified = true; -} - -/*! Gets whether a target is defined in the property list. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return true if the target exists, false otherwise. */ -Boolean iSCSIPLContainsTarget(CFStringRef targetIQN) -{ - CFDictionaryRef targetsList = iSCSIPLGetTargets(true); - return CFDictionaryContainsKey(targetsList,targetIQN); -} - -/*! Gets whether a portal is defined in the property list. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param portalAddress the name of the portal. - * @return true if the portal exists, false otherwise. */ -Boolean iSCSIPLContainsPortalForTarget(CFStringRef targetIQN, - CFStringRef portalAddress) -{ - CFDictionaryRef portalsList = iSCSIPLGetPortalsList(targetIQN,false); - return (portalsList && CFDictionaryContainsKey(portalsList,portalAddress)); -} - -/*! Gets whether a SendTargets discovery portal is defined in the property list. - * @param portalAddress the discovery portal address. - * @return true if the portal exists, false otherwise. */ -Boolean iSCSIPLContainsPortalForSendTargetsDiscovery(CFStringRef portalAddress) -{ - Boolean exists = false; - CFDictionaryRef discoveryPortals = iSCSIPLGetSendTargetsDiscoveryPortals(false); - - if(discoveryPortals) - exists = CFDictionaryContainsKey(discoveryPortals,portalAddress); - - return exists; -} - -/*! Creates an array of target iSCSI qualified name (IQN)s - * defined in the property list. - * @return an array of target iSCSI qualified name (IQN)s. */ -CFArrayRef iSCSIPLCreateArrayOfTargets() -{ - CFDictionaryRef targetsList = iSCSIPLGetTargets(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 statically configured iSCSI targets (IQNs). - * @return an array of statically configured iSCSI targets (IQNs). */ -CFArrayRef iSCSIPLCreateArrayOfStaticTargets() -{ - return NULL; -} - -/*! 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 iSCISPLCreateArrayOfDynamicTargetsForSendTargets(CFStringRef portalAddress) -{ - CFArrayRef targetsList = iSCSIPLGetDynamicTargetsForSendTargets(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 iSCSIPLCreateArrayOfPortalsForTarget(CFStringRef targetIQN) -{ - CFMutableDictionaryRef portalsList = iSCSIPLGetPortalsList(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 iSCSIPLSetTargetIQN(CFStringRef existingIQN,CFStringRef newIQN) -{ - CFMutableDictionaryRef targetNodes = iSCSIPLGetTargets(false); - CFMutableDictionaryRef target = iSCSIPLGetTargetDict(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); - } - - targetNodesCacheModified = true; - } -} - -/*! 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) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,true); - - if(authMethod == kiSCSIAuthMethodNone) - CFDictionarySetValue(targetDict,kiSCSIPKAuth,kiSCSIPVAuthNone); - else if(authMethod == kiSCSIAuthMethodCHAP) - CFDictionarySetValue(targetDict,kiSCSIPKAuth,kiSCSIPVAuthCHAP); - - targetNodesCacheModified = true; -} - -/*! Gets the current authentication method used by the target. */ -enum iSCSIAuthMethods iSCSIPLGetTargetAuthenticationMethod(CFStringRef targetIQN) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLSetTargetConfigType(CFStringRef targetIQN, - enum iSCSITargetConfigTypes configType) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 property list - CFDictionarySetValue(targetDict,kiSCSIPKTargetConfigType,configTypeString); - targetNodesCacheModified = true; - } -} - -/*! Gets target configuration type. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the target configuration type. */ -enum iSCSITargetConfigTypes iSCSIPLGetTargetConfigType(CFStringRef targetIQN) -{ - enum iSCSITargetConfigTypes configType = kiSCSITargetConfigInvalid; - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 the property list - 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 iSCSIPLGetDiscoveryPortalForTarget(CFStringRef targetIQN) -{ - CFStringRef discoveryPortal = NULL; - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(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 iSCSIPLSetTargetCHAPName(CFStringRef targetIQN,CFStringRef name) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,true); - - // Change CHAP name in property list - CFDictionarySetValue(targetDict,kiSCSIPKAuthCHAPName,name); - - targetNodesCacheModified = true; -} - -/*! 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 iSCSIPLCopyTargetCHAPName(CFStringRef targetIQN) -{ - CFMutableDictionaryRef targetDict = iSCSIPLGetTargetDict(targetIQN,true); - CFStringRef name = CFDictionaryGetValue(targetDict,kiSCSIPKAuthCHAPName); - return CFStringCreateCopy(kCFAllocatorDefault,name); -} - -/*! Sets the CHAP secret associated with the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param secret the CHAP shared secret associated with the target. - * @return status indicating the result of the operation. */ -OSStatus iSCSIPLSetTargetCHAPSecret(CFStringRef targetIQN,CFStringRef secret) -{ - return iSCSIKeychainSetCHAPSecretForNode(targetIQN,secret); -} - -/*! Copies the CHAP secret associated with the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the CHAP shared secret associated with the target. */ -CFStringRef iSCSIPLCopyTargetCHAPSecret(CFStringRef targetIQN) -{ - return iSCSIKeychainCopyCHAPSecretForNode(targetIQN); -} - -/*! Gets whether a CHAP secret exists for the specified target. - * @return true if a CHAP secret exists for the target. */ -Boolean iSCSIPLExistsTargetCHAPSecret(CFStringRef nodeIQN) -{ - return iSCSIKeychainContainsCHAPSecretForNode(nodeIQN); -} - -/*! Adds an iSCSI discovery portal to the list of discovery portals. - * @param portal the discovery portal to add. */ -void iSCSIPLAddSendTargetsDiscoveryPortal(iSCSIPortalRef portal) -{ - CFMutableDictionaryRef discoveryPortals = iSCSIPLGetSendTargetsDiscoveryPortals(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); - - discoveryCacheModified = true; - } - } -} - -/*! Removes the specified iSCSI discovery portal. - * @param portal the discovery portal to remove. */ -void iSCSIPLRemoveSendTargetsDiscoveryPortal(iSCSIPortalRef portal) -{ - CFMutableDictionaryRef discoveryPortals = iSCSIPLGetSendTargetsDiscoveryPortals(false); - - if(discoveryPortals && portal) { - - CFStringRef portalAddress = iSCSIPortalGetAddress(portal); - - if(CFDictionaryContainsKey(discoveryPortals,portalAddress)) { - - // Remove all dynamic targets associated with this portal, if any... - CFArrayRef targetsList = iSCSIPLGetDynamicTargetsForSendTargets(portalAddress,false); - - if(targetsList) { - CFIndex count = CFArrayGetCount(targetsList); - - for(CFIndex idx = 0; idx < count; idx++) - { - CFStringRef targetIQN = CFArrayGetValueAtIndex(targetsList,idx); - iSCSIPLRemoveTarget(targetIQN); - } - - targetNodesCacheModified = true; - } - - // Remove discovery portal from SendTargets dictionary - CFDictionaryRemoveValue(discoveryPortals,portalAddress); - discoveryCacheModified = true; - } - } -} - -/*! 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 iSCSIPLCopySendTargetsDiscoveryPortal(CFStringRef portalAddress) -{ - iSCSIMutablePortalRef portal = NULL; - - CFMutableDictionaryRef discoveryPortals = iSCSIPLGetSendTargetsDiscoveryPortals(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 iSCSIPLCopySendTargetsPortal(). */ -CFArrayRef iSCSIPLCreateArrayOfPortalsForSendTargetsDiscovery() -{ - CFMutableDictionaryRef discoveryPortals = iSCSIPLGetSendTargetsDiscoveryPortals(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 iSCSIPLSetSendTargetsDiscoveryEnable(Boolean enable) -{ - CFMutableDictionaryRef discoveryDict = iSCSIPLGetDiscoveryDict(true); - - if(enable) - CFDictionarySetValue(discoveryDict,kiSCSIPKSendTargetsEnabled,kCFBooleanTrue); - else - CFDictionarySetValue(discoveryDict,kiSCSIPKSendTargetsEnabled,kCFBooleanFalse); - - discoveryCacheModified = true; -} - -/*! Gets whether SendTargets discovery is set ot disabled or enabled. - * @return True if send targets discovery is set to enabled, false otherwise. */ -Boolean iSCSIPLGetSendTargetsDiscoveryEnable() -{ - CFMutableDictionaryRef discoveryDict = iSCSIPLGetDiscoveryDict(true); - return CFBooleanGetValue(CFDictionaryGetValue(discoveryDict,kiSCSIPKSendTargetsEnabled)); -} - -/*! Sets SendTargets discovery interval. - * @param interval the discovery interval, in seconds. */ -void iSCSIPLSetSendTargetsDiscoveryInterval(CFIndex interval) -{ - CFMutableDictionaryRef discoveryDict = iSCSIPLGetDiscoveryDict(true); - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,kCFNumberCFIndexType,&interval); - CFDictionarySetValue(discoveryDict,kiSCSIPKDiscoveryInterval,value); - - discoveryCacheModified = true; -} - -/*! Gets SendTargets disocvery interval. - * @return the discovery interval, in seconds. */ -CFIndex iSCSIPLGetSendTargetsDiscoveryInterval() -{ - CFIndex interval = 0; - CFMutableDictionaryRef discoveryDict = iSCSIPLGetDiscoveryDict(true); - CFNumberRef value = CFDictionaryGetValue(discoveryDict,kiSCSIPKDiscoveryInterval); - CFNumberGetValue(value,kCFNumberCFIndexType,&interval); - return interval; -} - -/*! Resets the iSCSI property list, removing all defined targets and - * configuration parameters. */ -void iSCSIPLReset() -{ - initiatorNodeCacheModified = true; - targetNodesCacheModified = true; - discoveryCacheModified = true; - - if(initiatorCache) - CFRelease(initiatorCache); - initiatorCache = iSCSIPLCreateInitiatorDict(); - - if(targetsCache) - CFRelease(targetsCache); - targetsCache = iSCSIPLCreateTargetsDict(); - - if(discoveryCache) - CFRelease(discoveryCache); - discoveryCache = iSCSIPLCreateDiscoveryDict(); -} - - -/*! Synchronizes the intitiator and target settings cache with the property - * list on the disk. */ -Boolean iSCSIPLSynchronize() -{ - // If we have modified our targets dictionary, we write changes back and - // otherwise we'll read in the latest. - if(targetNodesCacheModified) - CFPreferencesSetValue(kiSCSIPKTargets,targetsCache,kiSCSIPKAppId, - kCFPreferencesAnyUser,kCFPreferencesCurrentHost); - - if(initiatorNodeCacheModified) - CFPreferencesSetValue(kiSCSIPKInitiator,initiatorCache,kiSCSIPKAppId, - kCFPreferencesAnyUser,kCFPreferencesCurrentHost); - - if(discoveryCacheModified) - CFPreferencesSetValue(kiSCSIPKDiscovery,discoveryCache,kiSCSIPKAppId, - kCFPreferencesAnyUser,kCFPreferencesCurrentHost); - - // If sychronization failed for a write... - if(!CFPreferencesSynchronize(kiSCSIPKAppId,kCFPreferencesAnyUser,kCFPreferencesCurrentHost)) - { - if(targetNodesCacheModified || initiatorNodeCacheModified || discoveryCacheModified) - return false; - } - - if(!targetNodesCacheModified) - { - // Free old cache if present - if(targetsCache) - CFRelease(targetsCache); - - // Refresh cache from preferences - targetsCache = iSCSIPLCopyPropertyDict(kiSCSIPKTargets); - } - - if(!initiatorNodeCacheModified) - { - // Free old cache if present - if(initiatorCache) - CFRelease(initiatorCache); - - // Refresh cache from preferences - initiatorCache = iSCSIPLCopyPropertyDict(kiSCSIPKInitiator); - } - - if(!discoveryCacheModified) - { - // Free old cache if present - if(discoveryCache) - CFRelease(discoveryCache); - - // Refresh cache from preferences - discoveryCache = iSCSIPLCopyPropertyDict(kiSCSIPKDiscovery); - } - - initiatorNodeCacheModified = targetNodesCacheModified = discoveryCacheModified = false; - - return true; -} diff --git a/Source/User/iSCSI Framework/iSCSIPropertyList.h b/Source/User/iSCSI Framework/iSCSIPropertyList.h deleted file mode 100644 index 918fe02a..00000000 --- a/Source/User/iSCSI Framework/iSCSIPropertyList.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - * 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__ -#define __ISCSI_PROPERTY_LIST_H__ - -#include - -#include "iSCSIKeychain.h" -#include "iSCSITypes.h" -#include "iSCSIUtils.h" - -/*! Copies the initiator name from the property list into a CFString object. - * @return the initiator name. */ -CFStringRef iSCSIPLCopyInitiatorIQN(); - -/*! Sets the initiator name in the property list. - * @param initiatorIQN the initiator name to set. */ -void iSCSIPLSetInitiatorIQN(CFStringRef initiatorIQN); - -/*! Copies the initiator alias from the property list into a CFString object. - * @return the initiator alias. */ -CFStringRef iSCSIPLCopyInitiatorAlias(); - -/*! Sets the initiator alias in the property list. - * @param initiatorAlias the initiator alias to set. */ -void iSCSIPLSetInitiatorAlias(CFStringRef initiatorAlias); - -/*! Sets authentication method to be used by initiator. */ -void iSCSIPLSetInitiatorAuthenticationMethod(enum iSCSIAuthMethods authMethod); - -/*! Gets the current authentication method used by the initiator. */ -enum iSCSIAuthMethods iSCSIPLGetInitiatorAuthenticationMethod(); - -/*! Sets the CHAP name associated with the initiator. */ -void iSCSIPLSetInitiatorCHAPName(CFStringRef name); - -/*! Copies the CHAP name associated with the initiator. */ -CFStringRef iSCSIPLCopyInitiatorCHAPName(); - -/*! Sets the CHAP secret associated with the initiator. - * @return status indicating the result of the operation. */ -OSStatus iSCSIPLSetInitiatorCHAPSecret(CFStringRef secret); - -/*! Copies the CHAP secret associated with the initiator. */ -CFStringRef iSCSIPLCopyInitiatorCHAPSecret(); - -/*! Gets whether a CHAP secret exists for the initiator. - * @return true if a CHAP secret exists for the initiator. */ -Boolean iSCSIPLExistsInitiatorCHAPSecret(); - -/*! Copies a target object for the specified target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return target the target object to copy. */ -iSCSITargetRef iSCSIPLCopyTarget(CFStringRef targetIQN); - -/*! Adds a target object with a specified portal. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param portal the portal object to set. */ -void iSCSIPLAddStaticTarget(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 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 iSCSIPLAddDynamicTargetForSendTargets(CFStringRef targetIQN, - iSCSIPortalRef portal, - CFStringRef sendTargetsPortal); - -/*! Removes a target object. - * @param targetIQN the target iSCSI qualified name (IQN). */ -void iSCSIPLRemoveTarget(CFStringRef targetIQN); - -/*! Copies a portal object for the specified target. - * @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 iSCSIPLCopyPortalForTarget(CFStringRef targetIQN, - CFStringRef portalAddress); - -/*! Sets a portal object for the specified target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param portal the portal object to set. */ -void iSCSIPLSetPortalForTarget(CFStringRef targetIQN,iSCSIPortalRef portal); - -/*! Removes a portal object for a particular target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param portalAddress the portal name to remove. */ -void iSCSIPLRemovePortalForTarget(CFStringRef targetIQN, - CFStringRef 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 iSCSIPLSetAutoLoginForTarget(CFStringRef targetIQN,Boolean autoLogin); - -/*! Gets whether the target should be logged in during startup. - * @param targetIQN the target iSCSI qualified name (IQN). */ -Boolean iSCSIPLGetAutoLoginForTarget(CFStringRef targetIQN); - -/*! 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 iSCSIPLSetMaxConnectionsForTarget(CFStringRef targetIQN, - UInt32 maxConnections); - -/*! 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 iSCSIPLGetMaxConnectionsForTarget(CFStringRef targetIQN); - -/*! 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 iSCSIPLSetErrorRecoveryLevelForTarget(CFStringRef targetIQN, - enum iSCSIErrorRecoveryLevels level); - -/*! 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 iSCSIPLGetErrorRecoveryLevelForTarget(CFStringRef targetIQN); - -/*! Gets the data digest for the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the digest type. */ -enum iSCSIDigestTypes iSCSIPLGetDataDigestForTarget(CFStringRef targetIQN); - -/*! Sets the data digest for the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param digestType the digest type. */ -void iSCSIPLSetDataDigestForTarget(CFStringRef targetIQN, - enum iSCSIDigestTypes digestType); - -/*! Gets the header digest for the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the digest type. */ -enum iSCSIDigestTypes iSCSIPLGetHeaderDigestForTarget(CFStringRef targetIQN); - -/*! Sets the header digest for the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param digestType the digest type. */ -void iSCSIPLSetHeaderDigestForTarget(CFStringRef targetIQN, - enum iSCSIDigestTypes digestType); - -/*! 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 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. */ -void iSCSIPLSetTargetAuthenticationMethod(CFStringRef targetIQN, - enum iSCSIAuthMethods authMethod); - -/*! Gets the current authentication method used by the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the iSCSI authentication method for the target. */ -enum iSCSIAuthMethods iSCSIPLGetTargetAuthenticationMethod(CFStringRef targetIQN); - -/*! Sets target configuration type. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param configType the target configuration type. */ -void iSCSIPLSetTargetConfigType(CFStringRef targetIQN, - enum iSCSITargetConfigTypes configType); - -/*! Gets target configuration type. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the target configuration type. */ -enum iSCSITargetConfigTypes iSCSIPLGetTargetConfigType(CFStringRef targetIQN); - -/*! 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 iSCSIPLGetDiscoveryPortalForTarget(CFStringRef targetIQN); - -/*! 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 iSCSIPLSetTargetCHAPName(CFStringRef targetIQN,CFStringRef 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 iSCSIPLCopyTargetCHAPName(CFStringRef targetIQN); - -/*! Sets the CHAP secret associated with the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param secret the CHAP shared secret associated with the target. - * @return status indicating the result of the operation. */ -OSStatus iSCSIPLSetTargetCHAPSecret(CFStringRef targetIQN,CFStringRef secret); - -/*! Copies the CHAP secret associated with the target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return the CHAP shared secret associated with the target. */ -CFStringRef iSCSIPLCopyTargetCHAPSecret(CFStringRef targetIQN); - -/*! Gets whether a CHAP secret exists for the specified target. - * @return true if a CHAP secret exists for the target. */ -Boolean iSCSIPLExistsTargetCHAPSecret(CFStringRef nodeIQN); - -/*! Gets whether a target is defined in the property list. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return true if the target exists, false otherwise. */ -Boolean iSCSIPLContainsTarget(CFStringRef targetIQN); - -/*! Gets whether a portal is defined in the property list. - * @param targetIQN the target iSCSI qualified name (IQN). - * @param portalAddress the name of the portal. - * @return true if the portal exists, false otherwise. */ -Boolean iSCSIPLContainsPortalForTarget(CFStringRef targetIQN, - CFStringRef portalAddress); - -/*! Gets whether a SendTargets discovery portal is defined in the property list. - * @param portalAddress the discovery portal address. - * @return true if the portal exists, false otherwise. */ -Boolean iSCSIPLContainsPortalForSendTargetsDiscovery(CFStringRef portalAddress); - -/*! Creates an array of target iSCSI qualified name (IQN)s - * defined in the property list. - * @return an array of target iSCSI qualified name (IQN)s. */ -CFArrayRef iSCSIPLCreateArrayOfTargets(); - -/*! Creates an array of statically configured iSCSI targets (IQNs). - * @return an array of statically configured iSCSI targets (IQNs). */ -CFArrayRef iSCSIPLCreateArrayOfStaticTargets(); - -/*! 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 iSCISPLCreateArrayOfDynamicTargetsForSendTargets(CFStringRef portalAddress); - -/*! Creates an array of portal names (addresses) for a given target. - * @param targetIQN the target iSCSI qualified name (IQN). - * @return an array of portal names for the specified target. */ -CFArrayRef iSCSIPLCreateArrayOfPortalsForTarget(CFStringRef targetIQN); - -/*! Adds an iSCSI discovery portal to the list of discovery portals. - * @param portal the discovery portal to add. */ -void iSCSIPLAddSendTargetsDiscoveryPortal(iSCSIPortalRef portal); - -/*! Removes the specified iSCSI discovery portal. - * @param portal the discovery portal to remove. */ -void iSCSIPLRemoveSendTargetsDiscoveryPortal(iSCSIPortalRef portal); - -/*! Copies a portal object for the specified discovery portal. - * @param portalAddress the portal name (IPv4, IPv6 or DNS name). - * @return portal the portal object to set. */ -iSCSIPortalRef iSCSIPLCopySendTargetsDiscoveryPortal(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 iSCSIPLCopySendTargetsPortal(). */ -CFArrayRef iSCSIPLCreateArrayOfPortalsForSendTargetsDiscovery(); - -/*! Sets SendTargets discovery to enabled or disabled. - * @param enable True to set send targets discovery enabled, false otherwise. */ -void iSCSIPLSetSendTargetsDiscoveryEnable(Boolean enable); - -/*! Gets whether SendTargets discovery is set ot disabled or enabled. - * @return True if send targets discovery is set to enabled, false otherwise. */ -Boolean iSCSIPLGetSendTargetsDiscoveryEnable(); - -/*! Sets SendTargets discovery interval. - * @param interval the discovery interval, in seconds. */ -void iSCSIPLSetSendTargetsDiscoveryInterval(CFIndex interval); - -/*! Gets SendTargets disocvery interval. - * @return the discovery interval, in seconds. */ -CFIndex iSCSIPLGetSendTargetsDiscoveryInterval(); - -/*! Resets the iSCSI property list, removing all defined targets and - * configuration parameters. */ -void iSCSIPLReset(); - -/*! Synchronizes the intitiator and target settings cache with the property - * list on the disk. */ -Boolean iSCSIPLSynchronize(); - - -#endif diff --git a/Source/User/iSCSI Framework/iSCSITypes.c b/Source/User/iSCSI Framework/iSCSITypes.c index 9cd445d8..c8ec5b03 100644 --- a/Source/User/iSCSI Framework/iSCSITypes.c +++ b/Source/User/iSCSI Framework/iSCSITypes.c @@ -401,6 +401,8 @@ void iSCSIDiscoveryRecAddPortal(iSCSIMutableDiscoveryRecRef discoveryRec, return; CFMutableDictionaryRef targetDict; + bool targetDictCreated = false; + bool portalsArrayCreated = false; // If target doesn't exist add it if(!CFDictionaryGetValueIfPresent(discoveryRec,targetIQN,(void *)&targetDict)) @@ -408,6 +410,7 @@ void iSCSIDiscoveryRecAddPortal(iSCSIMutableDiscoveryRecRef discoveryRec, targetDict = CFDictionaryCreateMutable(kCFAllocatorDefault,0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + targetDictCreated = true; } // If the group tag doesn't exist add it @@ -417,7 +420,7 @@ void iSCSIDiscoveryRecAddPortal(iSCSIMutableDiscoveryRecRef discoveryRec, { portalsArray = CFArrayCreateMutable(kCFAllocatorDefault,0, &kCFTypeArrayCallBacks); - + portalsArrayCreated = true; } CFDictionaryRef portalDict = iSCSIPortalCreateDictionary(portal); @@ -428,6 +431,12 @@ void iSCSIDiscoveryRecAddPortal(iSCSIMutableDiscoveryRecRef discoveryRec, CFDictionarySetValue(discoveryRec,targetIQN,targetDict); CFRelease(portalDict); + + if(targetDictCreated) + CFRelease(targetDict); + + if(portalsArrayCreated) + CFRelease(portalsArray); } @@ -442,6 +451,7 @@ void iSCSIDiscoveryRecAddTarget(iSCSIMutableDiscoveryRecRef discoveryRec, return; CFMutableDictionaryRef targetDict; + bool targetDictCreated = false; // If target doesn't exist add it if(!CFDictionaryGetValueIfPresent(discoveryRec,targetIQN,(void *)&targetDict)) @@ -449,10 +459,15 @@ void iSCSIDiscoveryRecAddTarget(iSCSIMutableDiscoveryRecRef discoveryRec, targetDict = CFDictionaryCreateMutable(kCFAllocatorDefault,0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + targetDictCreated = true; } + // Add target to discovery record CFDictionarySetValue(discoveryRec,targetIQN,targetDict); + + if(targetDictCreated) + CFRelease(targetDict); } /*! Creates a CFArray object containing CFString objects with names of diff --git a/Source/User/iSCSI Framework/iSCSIUtils.c b/Source/User/iSCSI Framework/iSCSIUtils.c index d132d386..5e2bc868 100644 --- a/Source/User/iSCSI Framework/iSCSIUtils.c +++ b/Source/User/iSCSI Framework/iSCSIUtils.c @@ -147,7 +147,6 @@ CFArrayRef iSCSIUtilsCreateArrayByParsingPortalParts(CFStringRef portal) * @param peripheralDeviceType the single byte peripheral device descriptor * as outlined in the SPC-4 r36d. * @return a string describing the device (guaranteed to be a valid string). */ - CFStringRef iSCSIUtilsGetSCSIPeripheralDeviceDescription(UInt8 peripheralDeviceType) { switch(peripheralDeviceType) @@ -192,4 +191,76 @@ CFStringRef iSCSIUtilsGetSCSIPeripheralDeviceDescription(UInt8 peripheralDeviceT default: return CFSTR("Unknown or no device"); }; +} + +/*! Gets a string describing the iSCSI login status. + * @param statusCode the login status code. + * @return a string describing the login status (guaranteed to be a valid string). */ +CFStringRef iSCSIUtilsGetStringForLoginStatus(enum iSCSILoginStatusCode statusCode) +{ + switch(statusCode) + { + case kiSCSILoginSuccess: + return CFSTR("Login successful"); + case kiSCSILoginAccessDenied: + return CFSTR("The target has denied access"); + case kiSCSILoginAuthFail: + return CFSTR("Authentication failure"); + case kiSCSILoginCantIncludeInSeession: + return CFSTR("Can't include the portal in the session"); + case kiSCSILoginInitiatorError: + return CFSTR("An initiator error has occurred"); + case kiSCSILoginInvalidReqDuringLogin: + return CFSTR("The initiator made an invalid request"); + case kiSCSILoginMissingParam: + return CFSTR("Missing login parameters"); + case kiSCSILoginNotFound: + return CFSTR("Target was not found"); + case kiSCSILoginOutOfResources: + return CFSTR("Target is out of resources"); + case kiSCSILoginServiceUnavailable: + return CFSTR("Target services unavailable"); + case kiSCSILoginSessionDoesntExist: + return CFSTR("Session doesn't exist"); + case kiSCSILoginSessionTypeUnsupported: + return CFSTR("Target doesn't support login"); + case kiSCSILoginTargetHWorSWError: + return CFSTR("Target software or hardware error has occured"); + case kiSCSILoginTargetMovedPerm: + return CFSTR("Target has permanently moved"); + case kiSCSILoginTargetMovedTemp: + return CFSTR("Target has temporarily moved"); + case kiSCSILoginTargetRemoved: + return CFSTR("Target has been removed"); + case kiSCSILoginTooManyConnections: + return CFSTR("The session cannot support additional connections"); + case kiSCSILoginUnsupportedVer: + return CFSTR("Target is incompatible with the initiator"); + case kiSCSILoginInvalidStatusCode: + default: + return CFSTR("Unknown error occurred"); + }; + return CFSTR(""); +} + +/*! Gets a string describing the iSCSI logout status. + * @param statusCode the logout status code. + * @return a string describing the login status (guaranteed to be a valid string). */ +CFStringRef iSCSIUtilsGetStringForLogoutStatus(enum iSCSILogoutStatusCode statusCode) +{ + switch(statusCode) + { + case kiSCSILogoutSuccess: + return CFSTR("Logout successful"); + case kiSCSILogoutCIDNotFound: + return CFSTR("The connection was not found"); + case kiSCSILogoutCleanupFailed: + return CFSTR("Target cleanup of connection failed"); + case kiSCSILogoutRecoveryNotSupported: + return CFSTR("Could not recover the connection"); + case kiSCSILogoutInvalidStatusCode: + default: + return CFSTR(""); + }; + return CFSTR(""); } \ No newline at end of file diff --git a/Source/User/iSCSI Framework/iSCSIUtils.h b/Source/User/iSCSI Framework/iSCSIUtils.h index 2d1ed776..013a0c96 100644 --- a/Source/User/iSCSI Framework/iSCSIUtils.h +++ b/Source/User/iSCSI Framework/iSCSIUtils.h @@ -33,6 +33,8 @@ #include #include +#include "iSCSITypes.h" + /*! Verifies whether specified iSCSI qualified name (IQN) is valid per RFC3720. * This function also validates 64-bit EUI names expressed as strings that * start with the "eui" prefix. @@ -61,5 +63,14 @@ CFArrayRef iSCSIUtilsCreateArrayByParsingPortalParts(CFStringRef portal); * @return a string describing the device (guaranteed to be a valid string). */ CFStringRef iSCSIUtilsGetSCSIPeripheralDeviceDescription(UInt8 peripheralDeviceType); +/*! Gets a string describing the iSCSI login status. + * @param statusCode the login status code. + * @return a string describing the login status (guaranteed to be a valid string). */ +CFStringRef iSCSIUtilsGetStringForLoginStatus(enum iSCSILoginStatusCode statusCode); + +/*! Gets a string describing the iSCSI logout status. + * @param statusCode the logout status code. + * @return a string describing the login status (guaranteed to be a valid string). */ +CFStringRef iSCSIUtilsGetStringForLogoutStatus(enum iSCSILogoutStatusCode statusCode); #endif /* defined(__ISCSI_UTILS_H__) */ diff --git a/Source/User/iscsictl/iSCSICtl.m b/Source/User/iscsictl/iSCSICtl.m index 2ca90c4a..23734940 100644 --- a/Source/User/iscsictl/iSCSICtl.m +++ b/Source/User/iscsictl/iSCSICtl.m @@ -42,7 +42,7 @@ #include #include - +#include /*! Modes of operation for this utility. */ enum iSCSICtlCmds { @@ -185,6 +185,9 @@ /*! The standard out stream, used by various functions to write. */ CFWriteStreamRef stdoutStream = NULL; +/*! Error string to display when a persmissions error occurs. */ +CFStringRef kPermissionsErrorString = CFSTR("Permission denied"); + /*! Used to display the device tree (luns and target information) for a * particular iSCSI target object in the system's IO registry. */ errno_t displayTargetDeviceTree(io_object_t); @@ -372,10 +375,10 @@ CFStringRef iSCSICtlCreateSecretFromInput(CFIndex retries) { CFStringRef secret = NULL; - const int MAX_SECRET_LENGTH = 256; + const int MAX_SECRET_LENGTH = 128; //256 char buffer[MAX_SECRET_LENGTH]; char verify[MAX_SECRET_LENGTH]; - + // Retry as required... for(CFIndex idx = 0; idx < retries; idx++) { @@ -405,9 +408,9 @@ CFStringRef iSCSICtlCreateSecretFromInput(CFIndex retries) } } - if(!secret) { + if(!secret) iSCSICtlDisplayString(CFSTR("Exceeded the maximum number of attempts\n")); - } + return secret; } @@ -422,75 +425,10 @@ CFStringRef iSCSICtlGetStringForDigestType(enum iSCSIDigestTypes digestType) }; } -CFStringRef iSCSICtlGetStringForLoginStatus(enum iSCSILoginStatusCode statusCode) -{ - switch(statusCode) - { - case kiSCSILoginSuccess: - break; - case kiSCSILoginAccessDenied: - return CFSTR("The target has denied access"); - - case kiSCSILoginAuthFail: - return CFSTR("Authentication failure"); - - case kiSCSILoginCantIncludeInSeession: - return CFSTR("Can't include the portal in the session"); - - case kiSCSILoginInitiatorError: - return CFSTR("An initiator error has occurred"); - - case kiSCSILoginInvalidReqDuringLogin: - return CFSTR("The initiator made an invalid request"); - - case kiSCSILoginMissingParam: - return CFSTR("Missing login parameters"); - - case kiSCSILoginNotFound: - return CFSTR("Target was not found"); - - case kiSCSILoginOutOfResources: - return CFSTR("Target is out of resources"); - - case kiSCSILoginServiceUnavailable: - return CFSTR("Target services unavailable"); - - case kiSCSILoginSessionDoesntExist: - return CFSTR("Session doesn't exist"); - - case kiSCSILoginSessionTypeUnsupported: - return CFSTR("Target doesn't support login"); - - case kiSCSILoginTargetHWorSWError: - return CFSTR("Target software or hardware error has occured"); - - case kiSCSILoginTargetMovedPerm: - return CFSTR("Target has permanently moved"); - - case kiSCSILoginTargetMovedTemp: - return CFSTR("Target has temporarily moved"); - - case kiSCSILoginTargetRemoved: - return CFSTR("Target has been removed"); - - case kiSCSILoginTooManyConnections: - return CFSTR("The session cannot support additional connections"); - - case kiSCSILoginUnsupportedVer: - return CFSTR("Target is incompatible with the initiator"); - - case kiSCSILoginInvalidStatusCode: - default: - return CFSTR("Unknown error occurred"); - }; - return CFSTR(""); -} - - void iSCSICtlDisplayiSCSILoginError(enum iSCSILoginStatusCode statusCode) { CFStringRef error = CFStringCreateWithFormat( - kCFAllocatorDefault,NULL,CFSTR("%s: %@\n"),executableName,iSCSICtlGetStringForLoginStatus(statusCode)); + kCFAllocatorDefault,NULL,CFSTR("%s: %@\n"),executableName,iSCSIUtilsGetStringForLoginStatus(statusCode)); iSCSICtlDisplayString(error); CFRelease(error); @@ -531,33 +469,10 @@ void iSCSICtlDisplayLoginStatus(enum iSCSILoginStatusCode statusCode, } } -CFStringRef iSCSICtlGetStringForLogoutStatus(enum iSCSILogoutStatusCode statusCode) -{ - switch(statusCode) - { - case kiSCSILogoutSuccess: - break; - - case kiSCSILogoutCIDNotFound: - return CFSTR("The connection was not found"); - - case kiSCSILogoutCleanupFailed: - return CFSTR("Target cleanup of connection failed"); - - case kiSCSILogoutRecoveryNotSupported: - return CFSTR("Could not recover the connection"); - - case kiSCSILogoutInvalidStatusCode: - default: - return CFSTR(""); - }; - return CFSTR(""); -} - void iSCSICtlDisplayiSCSILogoutError(enum iSCSILogoutStatusCode statusCode) { CFStringRef error = CFStringCreateWithFormat( - kCFAllocatorDefault,NULL,CFSTR("%s: %@\n"),executableName,iSCSICtlGetStringForLogoutStatus(statusCode)); + kCFAllocatorDefault,NULL,CFSTR("%s: %@\n"),executableName,iSCSIUtilsGetStringForLogoutStatus(statusCode)); iSCSICtlDisplayString(error); CFRelease(error); @@ -695,33 +610,63 @@ errno_t iSCSICtlModifyPortalFromOptions(CFDictionaryRef options, { iSCSIPortalRef portalUpdates = iSCSICtlCreatePortalFromOptions(options); - // If a port was explicity specified, update it - if(CFDictionaryContainsKey(options,kOptKeyPort)) - iSCSIPortalSetPort(portal,iSCSIPortalGetPort(portalUpdates)); + if(portalUpdates) { + + // If a port was explicity specified, update it + if(CFDictionaryContainsKey(options,kOptKeyPort)) + iSCSIPortalSetPort(portal,iSCSIPortalGetPort(portalUpdates)); + + // If the interface was explicitly specified, update it + if(CFDictionaryContainsKey(options,kOptKeyInterface)) + iSCSIPortalSetHostInterface(portal,iSCSIPortalGetHostInterface(portalUpdates)); + + iSCSIPortalRelease(portalUpdates); + } - // If the interface was explicitly specified, update it - if(CFDictionaryContainsKey(options,kOptKeyInterface)) - iSCSIPortalSetHostInterface(portal,iSCSIPortalGetHostInterface(portalUpdates)); + return 0; +} +errno_t iSCSICtlConnectToDaemon(iSCSIDaemonHandle * handle) +{ + if(!handle) + return EIO; + + *handle = iSCSIDaemonConnect(); + + if(*handle < 0) { + iSCSICtlDisplayError(CFSTR("Could not connect to iscsid.\n")); + return EIO; + } return 0; } -errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) +void iSCSICtlDisconnectFromDaemon(iSCSIDaemonHandle handle) { - if(handle < 0 || !options) + if(handle < 0) + return; + + iSCSIDaemonDisconnect(handle); +} + +errno_t iSCSICtlLogin(AuthorizationRef authorization,CFDictionaryRef options) +{ + if(!authorization || !options) return EINVAL; - errno_t error = 0; + iSCSIDaemonHandle handle; iSCSITargetRef target = NULL; CFStringRef targetIQN = NULL; - iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); + iSCSIPreferencesRef preferences = NULL; + errno_t error = 0; // Create target object from user input (may be null if user didn't specify) - if(!(target = iSCSICtlCreateTargetFromOptions(options))) + if(!error && !(target = iSCSICtlCreateTargetFromOptions(options))) error = EINVAL; + + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); if(!error) { - // Verify that the target exists in the property list targetIQN = iSCSITargetGetIQN(target); @@ -730,6 +675,9 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,AuthorizationRef authorization,CF error = EINVAL; } } + + if(!error) + error = iSCSICtlConnectToDaemon(&handle); // Check if the number of connections is maxed out for this session UInt32 maxConnections = 0, activeConnections = 0; @@ -802,26 +750,31 @@ errno_t iSCSICtlLogin(iSCSIDaemonHandle handle,AuthorizationRef authorization,CF if(target) iSCSITargetRelease(target); + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); - iSCSIPreferencesRelease(preferences); return error; } -errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlLogout(AuthorizationRef authorization,CFDictionaryRef options) { - if(handle < 0 || !options) + if(!authorization || !options) return EINVAL; + iSCSIDaemonHandle handle; iSCSITargetRef target = NULL; iSCSIPortalRef portal = NULL; - - if(!(target = iSCSICtlCreateTargetFromOptions(options))) - return EINVAL; - errno_t error = 0; + if(!error && !(target = iSCSICtlCreateTargetFromOptions(options))) + error = EINVAL; + + if(!error) + error = iSCSICtlConnectToDaemon(&handle); + // See if there exists an active session for this target - if(!iSCSIDaemonIsTargetActive(handle,target)) + if(!error && !iSCSIDaemonIsTargetActive(handle,target)) { iSCSICtlDisplayString(CFSTR("The specified target has no active session\n")); error = EINVAL; @@ -854,7 +807,10 @@ errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,AuthorizationRef authorization,C if(portal) iSCSIPortalRelease(portal); - iSCSITargetRelease(target); + if(target) + iSCSITargetRelease(target); + + iSCSICtlDisconnectFromDaemon(handle); return error; } @@ -867,37 +823,44 @@ errno_t iSCSICtlLogout(iSCSIDaemonHandle handle,AuthorizationRef authorization,C * @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,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlAddTarget(AuthorizationRef authorization,CFDictionaryRef options) { - if(handle < 0 || !authorization || !options) + if(!authorization || !options) return EINVAL; - errno_t error = 0; + iSCSIDaemonHandle handle; iSCSITargetRef target = NULL; iSCSIPortalRef portal = NULL; iSCSIPreferencesRef preferences = NULL; + bool lockAndSync = false; + errno_t error = 0; - if(!(target = iSCSICtlCreateTargetFromOptions(options))) + if(!error && !(target = iSCSICtlCreateTargetFromOptions(options))) error = EINVAL; if(!error && !(portal = iSCSICtlCreatePortalFromOptions(options))) error = EINVAL; + if(!error) + error = iSCSICtlConnectToDaemon(&handle); - preferences = iSCSIPreferencesCreateFromAppValues(); + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } if (!error) { - // If portal and target both exist then do nothing, otherwise // add target and or portal with user-specified options CFStringRef targetIQN = iSCSITargetGetIQN(target); - iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); - iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); - if(!iSCSIPreferencesContainsTarget(preferences,targetIQN)) { iSCSIPreferencesAddStaticTarget(preferences,targetIQN,portal); iSCSICtlDisplayString(CFSTR("The specified target has been added\n")); @@ -913,18 +876,17 @@ errno_t iSCSICtlAddTarget(iSCSIDaemonHandle handle,AuthorizationRef authorizatio } if(!error) - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); - - iSCSIPreferencesRelease(preferences); - + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); if(target) iSCSITargetRelease(target); - if(portal) iSCSIPortalRelease(portal); + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); return error; } @@ -934,18 +896,20 @@ errno_t iSCSICtlAddTarget(iSCSIDaemonHandle handle,AuthorizationRef authorizatio * 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,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlRemoveTarget(AuthorizationRef authorization,CFDictionaryRef options) { - if(handle < 0 || !options) + if(!authorization || !options) return EINVAL; - errno_t error = 0; + iSCSIDaemonHandle handle; iSCSITargetRef target = NULL; iSCSIPortalRef portal = NULL; iSCSIPreferencesRef preferences = NULL; CFStringRef targetIQN = NULL; + bool lockAndSync = false; + errno_t error = 0; - if(!(target = iSCSICtlCreateTargetFromOptions(options))) + if(!error && !(target = iSCSICtlCreateTargetFromOptions(options))) error = EINVAL; else targetIQN = iSCSITargetGetIQN(target); @@ -954,10 +918,20 @@ errno_t iSCSICtlRemoveTarget(iSCSIDaemonHandle handle,AuthorizationRef authoriza if(!(portal = iSCSICtlCreatePortalFromOptions(options))) error = EINVAL; - preferences = iSCSIPreferencesCreateFromAppValues(); + if(!error) + error = iSCSICtlConnectToDaemon(&handle); + + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } if(!error) { @@ -1002,54 +976,72 @@ errno_t iSCSICtlRemoveTarget(iSCSIDaemonHandle handle,AuthorizationRef authoriza } if(!error) - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); - - iSCSIPreferencesRelease(preferences); - + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); if(portal) iSCSIPortalRelease(portal); if(target) iSCSITargetRelease(target); + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); return 0; } -errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlModifyInitiator(AuthorizationRef authorization,CFDictionaryRef options) { + if(!authorization || !options) + return EINVAL; + + iSCSIDaemonHandle handle; CFStringRef value = NULL; + bool lockAndSync = false; + iSCSIPreferencesRef preferences = NULL; errno_t error = 0; - iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); + // Check for CHAP shared secret + CFStringRef secret = NULL; + if(CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) + secret = iSCSICtlCreateSecretFromInput(MAX_SECRET_RETRY_ATTEMPTS); - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); + error = iSCSICtlConnectToDaemon(&handle); - // Check for CHAP user name - if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyCHAPName,(const void **)&value)) - { - if(CFStringCompare(value,kOptValueEmpty,0) != kCFCompareEqualTo) - iSCSIPreferencesSetInitiatorCHAPName(preferences,value); - } -/* - // Check for CHAP shared secret - if(CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) { - CFStringRef secret = iSCSICtlCreateSecretFromInput(MAX_SECRET_RETRY_ATTEMPTS); - + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); + + if(!error && CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) { if(secret != NULL) { CFStringRef initiatorIQN = iSCSIPreferencesCopyInitiatorIQN(preferences); - if(iSCSIKeychainSetCHAPSecretForNode(initiatorIQN,secret) != 0) { - iSCSICtlDisplayPermissionsError(); + if(iSCSIDaemonSetSharedSecret(handle,authorization,initiatorIQN,secret)) { + iSCSICtlDisplayError(kPermissionsErrorString); error = EAUTH; } + CFRelease(initiatorIQN); CFRelease(secret); } else error = EINVAL; } -*/ + + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } + + // Check for CHAP user name + if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyCHAPName,(const void **)&value)) + { + if(CFStringCompare(value,kOptValueEmpty,0) != kCFCompareEqualTo) + iSCSIPreferencesSetInitiatorCHAPName(preferences,value); + } + // Check for authentication method if(!error && CFDictionaryGetValueIfPresent(options,kOptKeyAutMethod,(const void**)&value)) { @@ -1080,25 +1072,27 @@ errno_t iSCSICtlModifyInitiator(iSCSIDaemonHandle handle,AuthorizationRef author } if(!error) { - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); iSCSICtlDisplayString(CFSTR("Initiator settings have been updated\n")); } - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); - iSCSIPreferencesRelease(preferences); + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); return 0; } -errno_t iSCSICtlModifyTargetFromOptions(iSCSIPreferencesRef preferences, +errno_t iSCSICtlModifyTargetFromOptions(AuthorizationRef authorization, + iSCSIPreferencesRef preferences, CFDictionaryRef options, iSCSITargetRef target, iSCSIPortalRef portal) { CFStringRef targetIQN = iSCSITargetGetIQN(target); CFStringRef value = NULL; - errno_t error = 0; // Check for CHAP user name, ensure it is not blank @@ -1108,19 +1102,6 @@ errno_t iSCSICtlModifyTargetFromOptions(iSCSIPreferencesRef preferences, iSCSIPreferencesSetTargetCHAPName(preferences,targetIQN,value); } - // Check for CHAP shared secret - if(CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) { - CFStringRef secret = iSCSICtlCreateSecretFromInput(MAX_SECRET_RETRY_ATTEMPTS); - - if(secret != NULL) { - iSCSIKeychainSetCHAPSecretForNode(targetIQN,secret); - CFRelease(secret); - } - else { - error = EINVAL; - } - } - // Check for authentication method enum iSCSIAuthMethods authMethod = kiSCSIAuthMethodInvalid; @@ -1229,24 +1210,25 @@ errno_t iSCSICtlModifyTargetFromOptions(iSCSIPreferencesRef preferences, return error; } -errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlModifyTarget(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 // be modified. Do the same for portal (to change connection properties, // but this is optional and a portal may not have been specified by the // user). - - if(handle < 0 || !options) + if(!authorization || !options) return EINVAL; - errno_t error = 0; + iSCSIDaemonHandle handle; + bool lockAndSync = false; iSCSITargetRef target = NULL; iSCSIMutablePortalRef portal = NULL; iSCSIPreferencesRef preferences = NULL; CFStringRef targetIQN = NULL; + errno_t error = 0; - if(!(target = iSCSICtlCreateTargetFromOptions(options))) + if(!error && !(target = iSCSICtlCreateTargetFromOptions(options))) error = EINVAL; else targetIQN = iSCSITargetGetIQN(target); @@ -1255,10 +1237,37 @@ errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,AuthorizationRef authoriza if(!(portal = iSCSICtlCreatePortalFromOptions(options))) error = EINVAL; - preferences = iSCSIPreferencesCreateFromAppValues(); + // Check for CHAP shared secret + CFStringRef secret = NULL; + if(CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) + secret = iSCSICtlCreateSecretFromInput(MAX_SECRET_RETRY_ATTEMPTS); + + if(!error) + error = iSCSICtlConnectToDaemon(&handle); + + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); + + if(!error && CFDictionaryContainsKey(options,kOptKeyCHAPSecret)) { + if(secret != NULL) { + if(iSCSIDaemonSetSharedSecret(handle,authorization,targetIQN,secret)) { + iSCSICtlDisplayError(kPermissionsErrorString); + error = EAUTH; + } + CFRelease(secret); + } + else + error = EINVAL; + } - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } if(!error) { @@ -1284,14 +1293,13 @@ errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,AuthorizationRef authoriza 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 { - iSCSICtlModifyTargetFromOptions(preferences,options,target,portal); + iSCSICtlModifyTargetFromOptions(authorization,preferences,options,target,portal); iSCSICtlDisplayString(CFSTR("Target settings have been updated\n")); } } @@ -1299,23 +1307,23 @@ errno_t iSCSICtlModifyTarget(iSCSIDaemonHandle handle,AuthorizationRef authoriza } if(!error) - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); - - iSCSIPreferencesRelease(preferences); + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); if(portal) iSCSIPortalRelease(portal); if(target) iSCSITargetRelease(target); - + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); + return error; } /*! Helper function. Displays information about a target/session. */ -void displayTargetInfo(iSCSIDaemonHandle handle, - iSCSITargetRef target, +void displayTargetInfo(iSCSITargetRef target, CFDictionaryRef properties) { CFStringRef targetState = NULL; @@ -1373,8 +1381,7 @@ void displayTargetInfo(iSCSIDaemonHandle handle, } /*! Helper function. Displays information about a portal/connection. */ -void displayPortalInfo(iSCSIDaemonHandle handle, - iSCSITargetRef target, +void displayPortalInfo(iSCSITargetRef target, iSCSIPortalRef portal, CFDictionaryRef properties) { @@ -1411,72 +1418,82 @@ void displayPortalInfo(iSCSIDaemonHandle handle, * @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 iSCSICtlListTargets(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlListTargets(CFDictionaryRef options) { // We want to list all defined targets and information about any sessions // that may be associated with those targets, including information about // 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. + iSCSIDaemonHandle handle = 0; CFArrayRef targetsList; + errno_t error = 0; iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); - + if(!(targetsList = iSCSIPreferencesCreateArrayOfTargets(preferences))) { iSCSICtlDisplayString(CFSTR("No persistent targets are defined\n")); - return 0; } - - CFIndex targetCount = CFArrayGetCount(targetsList); - - for(CFIndex targetIdx = 0; targetIdx < targetCount; targetIdx++) - { - CFStringRef targetIQN = CFArrayGetValueAtIndex(targetsList,targetIdx); - - iSCSITargetRef target = NULL; - if(!(target = iSCSIPreferencesCopyTarget(preferences,targetIQN))) - continue; - - CFDictionaryRef properties = NULL; - if(!(handle < 0)) - properties = iSCSIDaemonCreateCFPropertiesForSession(handle,target); - - displayTargetInfo(handle,target,properties); + else + error = iSCSICtlConnectToDaemon(&handle); + + // If we connected to the daemon and we have defined targets + if(targetsList) { - CFArrayRef portalsList = iSCSIPreferencesCreateArrayOfPortalsForTarget(preferences,targetIQN); - CFIndex portalCount = CFArrayGetCount(portalsList); + CFIndex targetCount = CFArrayGetCount(targetsList); - for(CFIndex portalIdx = 0; portalIdx < portalCount; portalIdx++) + for(CFIndex targetIdx = 0; targetIdx < targetCount; targetIdx++) { - iSCSIPortalRef portal = iSCSIPreferencesCopyPortalForTarget(preferences, - targetIQN, - CFArrayGetValueAtIndex(portalsList,portalIdx)); - - if(portal) { - CFDictionaryRef properties = NULL; + CFStringRef targetIQN = CFArrayGetValueAtIndex(targetsList,targetIdx); - if(!(handle < 0)) - properties = iSCSIDaemonCreateCFPropertiesForConnection(handle,target,portal); + iSCSITargetRef target = NULL; + if(!(target = iSCSIPreferencesCopyTarget(preferences,targetIQN))) + continue; - displayPortalInfo(handle,target,portal,properties); - iSCSIPortalRelease(portal); + // If we connected to the daemon get status of any active sessions + CFDictionaryRef properties = NULL; + if(!error) + properties = iSCSIDaemonCreateCFPropertiesForSession(handle,target); + + displayTargetInfo(target,properties); + + CFArrayRef portalsList = iSCSIPreferencesCreateArrayOfPortalsForTarget(preferences,targetIQN); + CFIndex portalCount = CFArrayGetCount(portalsList); + + for(CFIndex portalIdx = 0; portalIdx < portalCount; portalIdx++) + { + iSCSIPortalRef portal = iSCSIPreferencesCopyPortalForTarget(preferences, + targetIQN, + CFArrayGetValueAtIndex(portalsList,portalIdx)); + if(portal) { + CFDictionaryRef properties = NULL; + + // If we connected to the the daemon get status of active portals + if(!error) + properties = iSCSIDaemonCreateCFPropertiesForConnection(handle,target,portal); + + displayPortalInfo(target,portal,properties); + iSCSIPortalRelease(portal); + } } + + iSCSITargetRelease(target); + CFRelease(portalsList); } - - iSCSITargetRelease(target); - CFRelease(portalsList); } - CFRelease(targetsList); + if(targetsList) + CFRelease(targetsList); iSCSIPreferencesRelease(preferences); - return 0; + iSCSICtlDisconnectFromDaemon(handle); + return error; } /*! Lists information about a specific target. * @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 iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlListTarget(CFDictionaryRef options) { iSCSITargetRef target = NULL; @@ -1494,8 +1511,15 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) return EINVAL; } - CFDictionaryRef properties = iSCSIDaemonCreateCFPropertiesForSession(handle,target); - displayTargetInfo(handle,target,properties); + iSCSIDaemonHandle handle; + errno_t error = iSCSICtlConnectToDaemon(&handle); + + CFDictionaryRef properties = NULL; + if(!error) { + properties = iSCSIDaemonCreateCFPropertiesForSession(handle,target); + } + + displayTargetInfo(target,properties); // Get information about automatic login CFStringRef autoLogin = CFSTR("disabled"); @@ -1593,7 +1617,10 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) iSCSIPortalRef portal = iSCSIPreferencesCopyPortalForTarget(preferences,targetIQN,portalAddress); // Get negotiated portal parameters - CFDictionaryRef properties = iSCSIDaemonCreateCFPropertiesForConnection(handle,target,portal); + CFDictionaryRef properties = NULL; + + if(!error) + iSCSIDaemonCreateCFPropertiesForConnection(handle,target,portal); if(properties) { CFNumberRef headerDigest = CFDictionaryGetValue(properties,kRFC3720_Key_HeaderDigest); @@ -1616,7 +1643,7 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) kRFC3720_Key_MaxRecvDataSegmentLength,maxDataRecvSegLength); } - displayPortalInfo(handle,target,portal,properties); + displayPortalInfo(target,portal,properties); iSCSICtlDisplayString(portalConfig); CFRelease(portal); } @@ -1629,7 +1656,7 @@ errno_t iSCSICtlListTarget(iSCSIDaemonHandle handle,CFDictionaryRef options) return 0; } -errno_t iSCSICtlListDiscoveryConfig(iSCSIDaemonHandle handle,CFDictionaryRef optDictionary) +errno_t iSCSICtlListDiscoveryConfig() { iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); @@ -1680,6 +1707,7 @@ errno_t iSCSICtlListDiscoveryConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt iSCSICtlDisplayString(entry); CFRelease(entry); + iSCSIPortalRelease(portal); } iSCSIPreferencesRelease(preferences); @@ -1687,7 +1715,7 @@ errno_t iSCSICtlListDiscoveryConfig(iSCSIDaemonHandle handle,CFDictionaryRef opt return 0; } -errno_t iSCSICtlListInitiatorConfig(iSCSIDaemonHandle handle,CFDictionaryRef optDictionary) +errno_t iSCSICtlListInitiatorConfig() { iSCSIPreferencesRef preferences = iSCSIPreferencesCreateFromAppValues(); @@ -1739,20 +1767,35 @@ 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,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlAddDiscoveryPortal(AuthorizationRef authorization,CFDictionaryRef options) { + if(!authorization || !options) + return EINVAL; + + iSCSIDaemonHandle handle; iSCSIPortalRef portal = NULL; iSCSIPreferencesRef preferences = NULL; + bool lockAndSync = false; errno_t error = 0; if(!(portal = iSCSICtlCreatePortalFromOptions(options))) error = EINVAL; - - preferences = iSCSIPreferencesCreateFromAppValues(); - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); - + if(!error) + error = iSCSICtlConnectToDaemon(&handle); + + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); + + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } + if(!error) { CFStringRef portalAddress = iSCSIPortalGetAddress(portal); @@ -1760,8 +1803,6 @@ errno_t iSCSICtlAddDiscoveryPortal(iSCSIDaemonHandle handle,AuthorizationRef aut if(!iSCSIPreferencesContainsPortalForSendTargetsDiscovery(preferences,portalAddress)) { iSCSIPreferencesAddSendTargetsDiscoveryPortal(preferences,portal); - - CFStringRef status = CFStringCreateWithFormat(kCFAllocatorDefault,0, CFSTR("The discovery portal %@ has been added\n"), iSCSIPortalGetAddress(portal)); @@ -1775,14 +1816,15 @@ errno_t iSCSICtlAddDiscoveryPortal(iSCSIDaemonHandle handle,AuthorizationRef aut } if(!error) - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); - - iSCSIPreferencesRelease(preferences); + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); if(portal) iSCSIPortalRelease(portal); + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); return 0; } @@ -1791,16 +1833,31 @@ errno_t iSCSICtlAddDiscoveryPortal(iSCSIDaemonHandle handle,AuthorizationRef aut * @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,AuthorizationRef authorization,CFDictionaryRef optDictionary) +errno_t iSCSICtlModifyDiscovery(AuthorizationRef authorization,CFDictionaryRef optDictionary) { - errno_t error = 0; + if(!authorization || !optDictionary) + return EINVAL; + + iSCSIDaemonHandle handle; CFStringRef value = NULL; iSCSIPreferencesRef preferences = NULL; + bool lockAndSync = false; + errno_t error = 0; - preferences = iSCSIPreferencesCreateFromAppValues(); + if(!error) + error = iSCSICtlConnectToDaemon(&handle); + + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } // Check if user enabled or disable a discovery method and act accordingly if(!error && CFDictionaryGetValueIfPresent(optDictionary,kOptKeySendTargetsEnable,(const void **)&value)) @@ -1834,17 +1891,18 @@ errno_t iSCSICtlModifyDiscovery(iSCSIDaemonHandle handle,AuthorizationRef author } if(!error) { - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); iSCSICtlDisplayString(CFSTR("Discovery settings have been updated\n")); } - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); - - iSCSIPreferencesRelease(preferences); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); if(!error) iSCSIDaemonUpdateDiscovery(handle); - + if(preferences) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); + return error; } @@ -1880,22 +1938,34 @@ CFArrayRef iSCSICtlCreateArrayOfActiveTargetsForDiscoveryPortal(iSCSIDaemonHandl * @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,AuthorizationRef authorization,CFDictionaryRef options) +errno_t iSCSICtlRemoveDiscoveryPortal(AuthorizationRef authorization,CFDictionaryRef options) { - if(handle < 0 || !authorization || !options) + if(!authorization || !options) return EINVAL; - errno_t error = 0; + iSCSIDaemonHandle handle = 0; iSCSIPortalRef portal = NULL; iSCSIPreferencesRef preferences = NULL; + bool lockAndSync = false; + errno_t error = 0; if(!(portal = iSCSICtlCreatePortalFromOptions(options))) error = EINVAL; - preferences = iSCSIPreferencesCreateFromAppValues(); + if(!error) + error = iSCSICtlConnectToDaemon(&handle); + + if(!error) + preferences = iSCSIPreferencesCreateFromAppValues(); - if((error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences))) - iSCSICtlDisplayError(CFSTR("Permission denied")); + if(!error) { + error = iSCSIDaemonPreferencesIOLockAndSync(handle,authorization,preferences); + + if(error) + iSCSICtlDisplayError(kPermissionsErrorString); + else + lockAndSync = true; + } if (!error) { @@ -1937,18 +2007,23 @@ errno_t iSCSICtlRemoveDiscoveryPortal(iSCSIDaemonHandle handle,AuthorizationRef iSCSICtlDisplayString(status); CFRelease(status); - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,preferences); + iSCSIDaemonPreferencesIOUnlockAndSync(handle,preferences); } - else - iSCSIDaemonPreferencesIOUnlockAndSync(handle,authorization,NULL); + else if(lockAndSync) + iSCSIDaemonPreferencesIOUnlockAndSync(handle,NULL); - iSCSIPreferencesRelease(preferences); + if(!error) + iSCSIPreferencesRelease(preferences); + iSCSICtlDisconnectFromDaemon(handle); return 0; } void displayTargetProperties(CFDictionaryRef propertiesDict) { + if(!propertiesDict) + return; + CFStringRef targetVendor = CFDictionaryGetValue(propertiesDict,CFSTR(kIOPropertySCSIVendorIdentification)); CFStringRef targetProduct = CFDictionaryGetValue(propertiesDict,CFSTR(kIOPropertySCSIProductIdentification)); CFStringRef targetRevision = CFDictionaryGetValue(propertiesDict,CFSTR(kIOPropertySCSIProductRevisionLevel)); @@ -2017,6 +2092,9 @@ void displayIOMediaProperties(CFDictionaryRef propertiesDict) errno_t displayTargetDeviceTree(io_object_t target) { + if(!target) + return EINVAL; + io_object_t LUN = IO_OBJECT_NULL; io_iterator_t LUNIterator = IO_OBJECT_NULL; @@ -2068,8 +2146,11 @@ errno_t displayTargetDeviceTree(io_object_t target) * @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 iSCSICtlListLUNs(iSCSIDaemonHandle handle,CFDictionaryRef options) +errno_t iSCSICtlListLUNs(CFDictionaryRef options) { + if(!options) + return EINVAL; + io_object_t target = IO_OBJECT_NULL; io_iterator_t targetIterator = IO_OBJECT_NULL; @@ -2136,71 +2217,64 @@ int main(int argc, char * argv[]) AuthorizationRef authorization; AuthorizationCreate(NULL,NULL,0,&authorization); - // Connect to the daemon - iSCSIDaemonHandle handle = iSCSIDaemonConnect(); - switch(cmd) { case kiSCSICtlCmdAdd: if(subCmd == kiSCSICtlSubCmdTarget) - error = iSCSICtlAddTarget(handle,authorization,optDictionary); + error = iSCSICtlAddTarget(authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryPortal) - error = iSCSICtlAddDiscoveryPortal(handle,authorization,optDictionary); + error = iSCSICtlAddDiscoveryPortal(authorization,optDictionary); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for add")); break; case kiSCSICtlCmdModify: if(subCmd == kiSCSICtlSubCmdTargetConfig) - error = iSCSICtlModifyTarget(handle,authorization,optDictionary); + error = iSCSICtlModifyTarget(authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdInitiatorConfig) - error = iSCSICtlModifyInitiator(handle,authorization,optDictionary); + error = iSCSICtlModifyInitiator(authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryConfig) - error = iSCSICtlModifyDiscovery(handle,authorization,optDictionary); + error = iSCSICtlModifyDiscovery(authorization,optDictionary); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for modify")); break; case kiSCSICtlCmdRemove: if(subCmd == kiSCSICtlSubCmdTarget) - error = iSCSICtlRemoveTarget(handle,authorization,optDictionary); + error = iSCSICtlRemoveTarget(authorization,optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryPortal) - error = iSCSICtlRemoveDiscoveryPortal(handle,authorization,optDictionary); + error = iSCSICtlRemoveDiscoveryPortal(authorization,optDictionary); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for remove")); break; case kiSCSICtlCmdList: if(subCmd == kiSCSICtlSubCmdTargets) - error = iSCSICtlListTargets(handle,optDictionary); + error = iSCSICtlListTargets(optDictionary); else if(subCmd == kiSCSICtlSubCmdTargetConfig) - error = iSCSICtlListTarget(handle,optDictionary); + error = iSCSICtlListTarget(optDictionary); else if(subCmd == kiSCSICtlSubCmdLUNs) - error = iSCSICtlListLUNs(handle,optDictionary); + error = iSCSICtlListLUNs(optDictionary); else if(subCmd == kiSCSICtlSubCmdDiscoveryConfig) - error = iSCSICtlListDiscoveryConfig(handle,optDictionary); + error = iSCSICtlListDiscoveryConfig(); else if(subCmd == kiSCSICtlSubCmdInitiatorConfig) - error = iSCSICtlListInitiatorConfig(handle,optDictionary); + error = iSCSICtlListInitiatorConfig(); else iSCSICtlDisplayError(CFSTR("Invalid subcommand for list")); break; case kiSCSICtlCmdLogin: - error = iSCSICtlLogin(handle,authorization,optDictionary); break; + error = iSCSICtlLogin(authorization,optDictionary); break; case kiSCSICtlCmdLogout: - error = iSCSICtlLogout(handle,authorization,optDictionary); break; + error = iSCSICtlLogout(authorization,optDictionary); break; case kiSCSICtlCmdInvalid: iSCSICtlDisplayUsage(); - + break; }; - iSCSIDaemonDisconnect(handle); CFWriteStreamClose(stdoutStream); - -// AuthorizationFree(<#AuthorizationRef _Nonnull authorization#>, <#AuthorizationFlags flags#>) + AuthorizationFree(authorization,kAuthorizationFlagDefaults); } - - return error; } \ No newline at end of file diff --git a/Source/User/iscsid/iSCSIAuth.c b/Source/User/iscsid/iSCSIAuth.c index 36e7d028..ff06de77 100644 --- a/Source/User/iscsid/iSCSIAuth.c +++ b/Source/User/iscsid/iSCSIAuth.c @@ -287,9 +287,12 @@ errno_t iSCSIAuthNegotiateCHAP(iSCSIMutableTargetRef target, statusCode, &rejectCode, authCmd,authRsp); - - // Now perform target authentication (we authenticate target) - if(targetUser && targetSecret) + + if(*statusCode != kiSCSILoginSuccess) + error = EAUTH; + + // If target authenticated us successfully, perform target authentication (we authenticate target) + if(!error && targetUser && targetSecret) { // Calculate the response we expect to get CFStringRef expResponse = iSCSIAuthNegotiateCHAPCreateResponse( @@ -366,6 +369,8 @@ void iSCSIAuthNegotiateBuildDict(iSCSITargetRef target, CFStringRef methodStrings = CFStringCreateByCombiningStrings( kCFAllocatorDefault,methods,CFSTR(",")); CFDictionaryAddValue(authCmd,kRFC3720_Key_AuthMethod,methodStrings); + CFRelease(methodStrings); + CFRelease(methods); } // Bidirectional CHAP else { diff --git a/Source/User/iscsid/iSCSIDaemon.c b/Source/User/iscsid/iSCSIDaemon.c index 2cf07b50..6e2351f6 100644 --- a/Source/User/iscsid/iSCSIDaemon.c +++ b/Source/User/iscsid/iSCSIDaemon.c @@ -91,6 +91,9 @@ pthread_mutex_t preferencesMutex = PTHREAD_MUTEX_INITIALIZER; /*! Preferences object used to syncrhonize iSCSI preferences. */ iSCSIPreferencesRef preferences = NULL; +/*! Incoming request information struct. */ +struct iSCSIDIncomingRequestInfo * reqInfo = NULL; + struct iSCSIDIncomingRequestInfo { CFSocketRef socket; @@ -167,6 +170,16 @@ const iSCSIDMsgPreferencesIOUnlockAndSyncRsp iSCSIDMsgPreferencesIOUnlockAndSync .errorCode = 0, }; +const iSCSIDMsgSetSharedSecretRsp iSCSIDMsgSetSharedSecretRspInit = { + .funcCode = kiSCSIDSetSharedSecret, + .errorCode = 0, +}; + +const iSCSIDMsgRemoveSharedSecretRsp iSCSIDMsgRemoveSharedSecretRspInit = { + .funcCode = kiSCSIDRemoveSharedSecret, + .errorCode = 0, +}; + /*! Used for the logout process. */ typedef struct iSCSIDLogoutContext { int fd; @@ -215,7 +228,7 @@ iSCSIConnectionConfigRef iSCSIDCreateConnectionConfig(CFStringRef targetIQN, if(digestType == kiSCSIDigestInvalid) digestType = kiSCSIDigestNone; - iSCSIConnectionConfigSetHeaderDigest(config,iSCSIPreferencesGetHeaderDigestForTarget(preferences,targetIQN)); + iSCSIConnectionConfigSetHeaderDigest(config,digestType); return config; } @@ -340,7 +353,27 @@ errno_t iSCSIDLoginCommon(SID sessionId, asl_log(NULL,NULL,ASL_LEVEL_ERR,"%s",CFStringGetCStringPtr(errorString,kCFStringEncodingASCII)); CFRelease(errorString); } - + // Update target alias in preferences (if one was furnished) + else + { + pthread_mutex_lock(&preferencesMutex); + iSCSIPreferencesSetTargetAlias(preferences,targetIQN,iSCSITargetGetAlias(target)); + iSCSIPreferencesSynchronzeAppValues(preferences); + pthread_mutex_unlock(&preferencesMutex); + } + + if(sessCfg) + iSCSISessionConfigRelease(sessCfg); + + if(connCfg) + iSCSIConnectionConfigRelease(connCfg); + + if(targetAuth) + iSCSIAuthRelease(targetAuth); + + if(initiatorAuth) + iSCSIAuthRelease(initiatorAuth); + return error; } @@ -421,6 +454,9 @@ errno_t iSCSIDLoginAllPortals(iSCSIMutableTargetRef target, } }; + if(portals) + CFRelease(portals); + return errorCode; } @@ -516,6 +552,8 @@ errno_t iSCSIDLogin(int fd,iSCSIDMsgLoginCmd * cmd) if(authorization) { if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthLoginRight) != errAuthorizationSuccess) errorCode = EAUTH; + + AuthorizationFree(authorization,kAuthorizationFlagDefaults); } else errorCode = EINVAL; @@ -663,6 +701,8 @@ errno_t iSCSIDLogout(int fd,iSCSIDMsgLogoutCmd * cmd) if(authorization) { if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthLoginRight) != errAuthorizationSuccess) errorCode = EAUTH; + + AuthorizationFree(authorization,kAuthorizationFlagDefaults); } else errorCode = EINVAL; @@ -775,6 +815,7 @@ errno_t iSCSIDCreateArrayOfActiveTargets(int fd,iSCSIDMsgCreateArrayOfActiveTarg errno_t iSCSIDCreateArrayofActivePortalsForTarget(int fd, iSCSIDMsgCreateArrayOfActivePortalsForTargetCmd * cmd) { +// TODO: null check CFArrayRef sessionIds = iSCSICreateArrayOfSessionIds(); CFIndex sessionCount = CFArrayGetCount(sessionIds); @@ -808,6 +849,9 @@ errno_t iSCSIDCreateArrayofActivePortalsForTarget(int fd, if(data) CFRelease(data); + + if(sessionIds) + CFRelease(sessionIds); return 0; } @@ -827,6 +871,8 @@ errno_t iSCSIDIsTargetActive(int fd,iSCSIDMsgIsTargetActiveCmd *cmd) if(target) { iSCSIDMsgIsTargetActiveRsp rsp = iSCSIDMsgIsTargetActiveRspInit; rsp.active = (iSCSIGetSessionIdForTarget(iSCSITargetGetIQN(target)) != kiSCSIInvalidSessionId); + + iSCSITargetRelease(target); if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) return EAGAIN; @@ -860,6 +906,12 @@ errno_t iSCSIDIsPortalActive(int fd,iSCSIDMsgIsPortalActiveCmd *cmd) rsp.active = false; else rsp.active = (iSCSIGetConnectionIdForPortal(sessionId,portal) != kiSCSIInvalidConnectionId); + + if(target) + iSCSITargetRelease(target); + + if(portal) + iSCSIPortalRelease(portal); if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) return EAGAIN; @@ -946,6 +998,10 @@ errno_t iSCSIDCreateCFPropertiesForSession(int fd, if(data) CFRelease(data); } + + if(target) + iSCSITargetRelease(target); + return error; } @@ -998,6 +1054,12 @@ errno_t iSCSIDCreateCFPropertiesForConnection(int fd, if(data) CFRelease(data); } + + if(target) + iSCSITargetRelease(target); + + if(portal) + iSCSIPortalRelease(portal); return error; } @@ -1092,8 +1154,6 @@ errno_t iSCSIDUpdateDiscovery(int fd, discoveryTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + 2.0, interval,0,0,callout,NULL); - - CFRunLoopAddTimer(CFRunLoopGetCurrent(),discoveryTimer,kCFRunLoopDefaultMode); } @@ -1132,6 +1192,8 @@ errno_t iSCSIDPreferencesIOLockAndSync(int fd,iSCSIDMsgPreferencesIOLockAndSyncC if(authorization) { if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthModifyRight) != errAuthorizationSuccess) error = EAUTH; + + AuthorizationFree(authorization,kAuthorizationFlagDefaults); } else error = EINVAL; @@ -1151,25 +1213,11 @@ errno_t iSCSIDPreferencesIOLockAndSync(int fd,iSCSIDMsgPreferencesIOLockAndSyncC 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); - } + CFDataRef preferencesData = NULL; + errno_t error = iSCSIDaemonRecvMsg(fd,0,&preferencesData,cmd->preferencesLength,NULL); iSCSIPreferencesRef preferencesToSync = NULL; @@ -1184,11 +1232,12 @@ errno_t iSCSIDPreferencesIOUnlockAndSync(int fd,iSCSIDMsgPreferencesIOUnlockAndS 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; @@ -1199,6 +1248,125 @@ errno_t iSCSIDPreferencesIOUnlockAndSync(int fd,iSCSIDMsgPreferencesIOUnlockAndS return 0; } +errno_t iSCSIDSetSharedSecret(int fd,iSCSIDMsgSetSharedSecretCmd *cmd) +{ + // Verify that the client is authorized for the operation + CFDataRef authorizationData = NULL, nodeIQNData = NULL, sharedSecretData = NULL; + errno_t error = iSCSIDaemonRecvMsg(fd,0,&authorizationData,cmd->authorizationLength, + &nodeIQNData,cmd->nodeIQNLength, + &sharedSecretData,cmd->secretLength,NULL); + + AuthorizationRef authorization = NULL; + CFStringRef nodeIQN = NULL; + CFStringRef sharedSecret = NULL; + + if(authorizationData) { + AuthorizationExternalForm authorizationExtForm; + + CFDataGetBytes(authorizationData, + CFRangeMake(0,kAuthorizationExternalFormLength), + (UInt8 *)&authorizationExtForm.bytes); + + AuthorizationCreateFromExternalForm(&authorizationExtForm,&authorization); + CFRelease(authorizationData); + } + + if(nodeIQNData) { + nodeIQN = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,nodeIQNData,kCFStringEncodingASCII); + CFRelease(nodeIQNData); + } + + if(sharedSecretData) { + sharedSecret = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,sharedSecretData,kCFStringEncodingASCII); + CFRelease(sharedSecretData); + } + + // If no errors then update secret + if(!error && nodeIQN) { + // If authorization object is valid, get the necessary rights + if(authorization) { + if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthModifyRight) == errSecSuccess) { + if(iSCSIKeychainSetCHAPSecretForNode(nodeIQN,sharedSecret) == errSecSuccess) + error = 0; + else + error = EAUTH; + } + } + else + error = EINVAL; + } + + + // Compose a response to send back to the client + iSCSIDMsgSetSharedSecretRsp rsp = iSCSIDMsgSetSharedSecretRspInit; + rsp.errorCode = error; + + if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EAGAIN; + + if(nodeIQN) + CFRelease(nodeIQN); + + if(sharedSecret) + CFRelease(sharedSecret); + + return 0; +} + +errno_t iSCSIDRemoveSharedSecret(int fd,iSCSIDMsgRemoveSharedSecretCmd *cmd) +{ + // Verify that the client is authorized for the operation + CFDataRef authorizationData = NULL, nodeIQNData = NULL; + errno_t error = iSCSIDaemonRecvMsg(fd,0,&authorizationData,cmd->authorizationLength, + &nodeIQNData,cmd->nodeIQNLength,NULL); + + AuthorizationRef authorization = NULL; + CFStringRef nodeIQN = NULL; + + if(authorizationData) { + AuthorizationExternalForm authorizationExtForm; + + CFDataGetBytes(authorizationData, + CFRangeMake(0,kAuthorizationExternalFormLength), + (UInt8 *)&authorizationExtForm.bytes); + + AuthorizationCreateFromExternalForm(&authorizationExtForm,&authorization); + CFRelease(authorizationData); + } + + if(nodeIQNData) { + nodeIQN = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault,nodeIQNData,kCFStringEncodingASCII); + CFRelease(nodeIQNData); + } + + // If no errors then remove secret + if(!error && nodeIQN) { + // If authorization object is valid, get the necessary rights + if(authorization) { + if(iSCSIAuthRightsAcquire(authorization,kiSCSIAuthModifyRight) == errSecSuccess) { + if(iSCSIKeychainDeleteCHAPSecretForNode(nodeIQN) == errSecSuccess) + error = 0; + else + error = EAUTH; + } + } + else + error = EINVAL; + } + + // Compose a response to send back to the client + iSCSIDMsgRemoveSharedSecretRsp rsp = iSCSIDMsgRemoveSharedSecretRspInit; + rsp.errorCode = error; + + if(send(fd,&rsp,sizeof(rsp),0) != sizeof(rsp)) + return EAGAIN; + + if(nodeIQN) + CFRelease(nodeIQN); + + 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. */ @@ -1299,7 +1467,6 @@ void iSCSIDPrepareForSystemSleep() &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - for(CFIndex idx = 0; idx < sessionCount; idx++) { SID sessionId = (SID)CFArrayGetValueAtIndex(sessionIds,idx); @@ -1366,7 +1533,6 @@ bool iSCSIDRegisterForPowerEvents() &powerNotifyPortRef, iSCSIDHandlePowerEvent, &powerNotifier); - if(powerPlaneRoot == 0) return false; @@ -1397,6 +1563,7 @@ void iSCSIDProcessIncomingRequest(void * info) if(fd != 0 && recv(fd,&cmd,sizeof(cmd),MSG_WAITALL) == sizeof(cmd)) { errno_t error = 0; + switch(cmd.funcCode) { case kiSCSIDLogin: @@ -1423,11 +1590,18 @@ void iSCSIDProcessIncomingRequest(void * info) error = iSCSIDPreferencesIOLockAndSync(fd,(iSCSIDMsgPreferencesIOLockAndSyncCmd*)&cmd); break; case kiSCSIDPreferencesIOUnlockAndSync: error = iSCSIDPreferencesIOUnlockAndSync(fd,(iSCSIDMsgPreferencesIOUnlockAndSyncCmd*)&cmd); break; - default: + case kiSCSIDSetSharedSecret: + error = iSCSIDSetSharedSecret(fd,(iSCSIDMsgSetSharedSecretCmd*)&cmd); break; + case kiSCSIDRemoveSharedSecret: + error = iSCSIDRemoveSharedSecret(fd,(iSCSIDMsgRemoveSharedSecretCmd*)&cmd); break; + default: CFSocketInvalidate(reqInfo->socket); reqInfo->fd = 0; pthread_mutex_unlock(&preferencesMutex); }; + + if(error) + asl_log(NULL,NULL,ASL_LEVEL_ERR,"error code %d while processing user request",error); } // If a request came in while we were processing, queue it up... @@ -1470,6 +1644,17 @@ void iSCSIDAcceptConnection(CFSocketRef socket, iSCSIDProcessIncomingRequest(info); } +void sig_pipe_handler(int signal) +{ + if(!reqInfo) + return; + + // Cleanup since pipe was broken + CFSocketInvalidate(reqInfo->socket); + reqInfo->fd = 0; + pthread_mutex_unlock(&preferencesMutex); +} + /*! iSCSI daemon entry point. */ int main(void) { @@ -1541,7 +1726,7 @@ int main(void) // Context for processing incoming requests. Holds references to CFSocket and // associated structures (e.g., runloop sources) - struct iSCSIDIncomingRequestInfo * reqInfo = malloc(sizeof(struct iSCSIDIncomingRequestInfo)); + reqInfo = malloc(sizeof(struct iSCSIDIncomingRequestInfo)); // Create a socket with a callback to accept incoming connections CFSocketContext sockContext; @@ -1574,7 +1759,7 @@ int main(void) asl_log(NULL,NULL,ASL_LEVEL_INFO,"daemon started"); // Ignore SIGPIPE (generated when the client closes the connection) - signal(SIGPIPE,SIG_IGN); + signal(SIGPIPE,sig_pipe_handler); // Initialize iSCSI connection to kernel (ability to call iSCSI kernel // functions and receive notifications from the kernel). @@ -1599,7 +1784,7 @@ int main(void) iSCSIDDeregisterForPowerEvents(); // Free all CF objects and reqInfo structure... - + free(reqInfo); launch_data_free(reg_response); asl_close(log); return 0; diff --git a/Source/User/iscsid/iSCSIDiscovery.c b/Source/User/iscsid/iSCSIDiscovery.c index bb69e6a4..35aabe49 100644 --- a/Source/User/iscsid/iSCSIDiscovery.c +++ b/Source/User/iscsid/iSCSIDiscovery.c @@ -58,6 +58,8 @@ errno_t iSCSIDiscoveryAddTargetForSendTargets(iSCSIPreferencesRef preferences, iSCSIPreferencesAddDynamicTargetForSendTargets(preferences,targetIQN,portal,discoveryPortal); } } + + CFRelease(portalGroups); return 0; } @@ -143,6 +145,7 @@ errno_t iSCSIDiscoveryUpdatePreferencesWithDiscoveredTargets(iSCSIPreferencesRef } } + CFRelease(targets); CFRelease(discTargets); CFRelease(existingTargets); @@ -194,7 +197,8 @@ CFDictionaryRef iSCSIDiscoveryCreateRecordsWithSendTargets(iSCSIPreferencesRef p // If there was an error, log it and move on to the next portal errno_t error = 0; - if((error = iSCSIQueryPortalForTargets(portal,iSCSIAuthCreateNone(),&discoveryRec,&statusCode))) + iSCSIAuthRef auth = iSCSIAuthCreateNone(); + if((error = iSCSIQueryPortalForTargets(portal,auth,&discoveryRec,&statusCode))) { CFStringRef errorString = CFStringCreateWithFormat( kCFAllocatorDefault,0, @@ -220,6 +224,9 @@ CFDictionaryRef iSCSIDiscoveryCreateRecordsWithSendTargets(iSCSIPreferencesRef p iSCSIDiscoveryRecRelease(discoveryRec); } } + + iSCSIAuthRelease(auth); + iSCSIPortalRelease(portal); } // Release the array of discovery portals diff --git a/Source/User/iscsid/iSCSIKernelInterface.c b/Source/User/iscsid/iSCSIKernelInterface.c index 149e0c3d..1b4624da 100644 --- a/Source/User/iscsid/iSCSIKernelInterface.c +++ b/Source/User/iscsid/iSCSIKernelInterface.c @@ -243,6 +243,7 @@ errno_t iSCSIKernelCreateSession(CFStringRef targetIQN, free(params[1]); free(params[2]); free(params[3]); + free(inputStruct); if(result == kIOReturnSuccess && outputCnt == expOutputCnt) { *sessionId = (UInt16)output[0]; diff --git a/Source/User/iscsid/iSCSIPDUUser.c b/Source/User/iscsid/iSCSIPDUUser.c index 29b2a85f..3114c3f5 100644 --- a/Source/User/iscsid/iSCSIPDUUser.c +++ b/Source/User/iscsid/iSCSIPDUUser.c @@ -156,11 +156,15 @@ void iSCSIPDUDataParseCommon(void * data,size_t length, currentByte++; } - if (keyString) { + if(keyString) { CFRelease(keyString); keyString = NULL; } - + + if(valString) { + CFRelease(valString); + valString = NULL; + } } void iSCSIPDUDataParseToDictCallback(void * keyContainer,CFStringRef keyString, diff --git a/Source/User/iscsid/iSCSISession.c b/Source/User/iscsid/iSCSISession.c index 5cf1e7f3..baff3f28 100644 --- a/Source/User/iscsid/iSCSISession.c +++ b/Source/User/iscsid/iSCSISession.c @@ -1052,6 +1052,7 @@ errno_t iSCSIQueryPortalForTargets(iSCSIPortalRef portal, error = iSCSIKernelSend(sessionId,connectionId,(iSCSIPDUInitiatorBHS *)&cmd,data,length); iSCSIPDUDataRelease(&data); + CFRelease(textCmd); if(error) { diff --git a/iSCSIInitiator.xcodeproj/project.pbxproj b/iSCSIInitiator.xcodeproj/project.pbxproj index 4216027b..e97979c5 100644 --- a/iSCSIInitiator.xcodeproj/project.pbxproj +++ b/iSCSIInitiator.xcodeproj/project.pbxproj @@ -7,50 +7,61 @@ objects = { /* Begin PBXBuildFile section */ + 2B171E421CE23677003C3E08 /* iSCSIAuthRights.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B171E401CE23677003C3E08 /* iSCSIAuthRights.c */; }; + 2B171E431CE23677003C3E08 /* iSCSIAuthRights.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B171E411CE23677003C3E08 /* iSCSIAuthRights.h */; }; + 2B1EDC121CFAEC1F007BAB99 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B1EDC111CFAEC1F007BAB99 /* AppDelegate.m */; }; + 2B1EDC151CFAEC1F007BAB99 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B1EDC141CFAEC1F007BAB99 /* main.m */; }; + 2B1EDC1A1CFAEC1F007BAB99 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2B1EDC191CFAEC1F007BAB99 /* Assets.xcassets */; }; + 2B1EDC1D1CFAEC1F007BAB99 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2B1EDC1B1CFAEC1F007BAB99 /* Main.storyboard */; }; 2B459D551B7B8192008F656F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B459D541B7B8192008F656F /* Security.framework */; }; 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 = (); }; }; + 2B56ACED1C4A48C800930E79 /* Distribution in Resources */ = {isa = PBXBuildFile; fileRef = 2B56ACEC1C4A48C800930E79 /* Distribution */; }; 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 */; }; + 2B7762991CFF220D003093CC /* NodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B7762921CFEF9E7003093CC /* NodeViewController.m */; }; + 2B77629A1CFF2211003093CC /* Node.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B7762941CFEF9E7003093CC /* Node.m */; }; + 2B77629B1D00B388003093CC /* iSCSI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */; }; + 2B77629E1D02CC9D003093CC /* InitiatorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B77629D1D02CC9D003093CC /* InitiatorViewController.m */; }; 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"; }; }; - 2B9E3CBE1C49ED0000440116 /* crc32c.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3CBA1C49ECF900440116 /* crc32c.c */; settings = {ASSET_TAGS = (); }; }; + 2B9E3CBE1C49ED0000440116 /* crc32c.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9E3CBA1C49ECF900440116 /* crc32c.c */; }; + 2BAAB8B71D03E8EF00C01C79 /* SplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BAAB8B61D03E8EF00C01C79 /* SplitViewController.m */; }; 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 = (); }; }; + 2BDE5E281C8B0274004BDB5F /* iscsictl.8 in Resources */ = {isa = PBXBuildFile; fileRef = 2BDE5E261C8B0274004BDB5F /* iscsictl.8 */; }; + 2BDE5E6E1C8B0292004BDB5F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2BDE5E481C8B028B004BDB5F /* Info.plist */; }; + 2BDE5E6F1C8B0292004BDB5F /* iSCSI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E491C8B028B004BDB5F /* iSCSI.h */; }; + 2BDE5E701C8B0292004BDB5F /* iSCSIDA.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E4A1C8B028B004BDB5F /* iSCSIDA.c */; }; + 2BDE5E711C8B0292004BDB5F /* iSCSIDA.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E4B1C8B028B004BDB5F /* iSCSIDA.h */; }; + 2BDE5E721C8B0292004BDB5F /* iSCSIDaemonInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E4C1C8B028B004BDB5F /* iSCSIDaemonInterface.c */; }; + 2BDE5E731C8B0292004BDB5F /* iSCSIDaemonInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E4D1C8B028B004BDB5F /* iSCSIDaemonInterface.h */; }; + 2BDE5E741C8B0292004BDB5F /* iSCSIDaemonInterfaceShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E4E1C8B028B004BDB5F /* iSCSIDaemonInterfaceShared.h */; }; + 2BDE5E751C8B0292004BDB5F /* iSCSIIORegistry.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E4F1C8B028B004BDB5F /* iSCSIIORegistry.c */; }; + 2BDE5E761C8B0292004BDB5F /* iSCSIIORegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E501C8B028B004BDB5F /* iSCSIIORegistry.h */; }; + 2BDE5E771C8B0292004BDB5F /* iSCSIKeychain.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E511C8B028B004BDB5F /* iSCSIKeychain.c */; }; + 2BDE5E781C8B0292004BDB5F /* iSCSIKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E521C8B028B004BDB5F /* iSCSIKeychain.h */; }; + 2BDE5E791C8B0292004BDB5F /* iSCSIPreferences.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E531C8B028B004BDB5F /* iSCSIPreferences.c */; }; + 2BDE5E7A1C8B0292004BDB5F /* iSCSIPreferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E541C8B028B004BDB5F /* iSCSIPreferences.h */; }; + 2BDE5E7B1C8B0292004BDB5F /* iSCSIRFC3720Keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E551C8B028B004BDB5F /* iSCSIRFC3720Keys.h */; }; + 2BDE5E7C1C8B0292004BDB5F /* iSCSITypes.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E561C8B028B004BDB5F /* iSCSITypes.c */; }; + 2BDE5E7D1C8B0292004BDB5F /* iSCSITypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E571C8B028B004BDB5F /* iSCSITypes.h */; }; + 2BDE5E7E1C8B0292004BDB5F /* iSCSITypesShared.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E581C8B028B004BDB5F /* iSCSITypesShared.h */; }; + 2BDE5E7F1C8B0292004BDB5F /* iSCSIUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E591C8B028B004BDB5F /* iSCSIUtils.c */; }; + 2BDE5E801C8B0292004BDB5F /* iSCSIUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDE5E5A1C8B028B004BDB5F /* iSCSIUtils.h */; }; + 2BDE5E881C8B3E7D004BDB5F /* iSCSIAuth.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E2B1C8B0281004BDB5F /* iSCSIAuth.c */; }; + 2BDE5E891C8B3E7D004BDB5F /* iSCSIDaemon.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E2E1C8B0281004BDB5F /* iSCSIDaemon.c */; }; + 2BDE5E8A1C8B3E7D004BDB5F /* iSCSIDiscovery.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E2F1C8B0281004BDB5F /* iSCSIDiscovery.c */; }; + 2BDE5E8B1C8B3E7D004BDB5F /* iSCSIKernelInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E311C8B0281004BDB5F /* iSCSIKernelInterface.c */; }; + 2BDE5E8C1C8B3E7D004BDB5F /* iSCSIPDUUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E331C8B0281004BDB5F /* iSCSIPDUUser.c */; }; + 2BDE5E8D1C8B3E7D004BDB5F /* iSCSIQueryTarget.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E351C8B0281004BDB5F /* iSCSIQueryTarget.c */; }; + 2BDE5E8E1C8B3E7D004BDB5F /* iSCSISession.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E371C8B0281004BDB5F /* iSCSISession.c */; }; + 2BDE5E8F1C8B3E96004BDB5F /* iSCSICtl.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BDE5E271C8B0274004BDB5F /* iSCSICtl.m */; }; 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 */; }; @@ -83,7 +94,16 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2B171E401CE23677003C3E08 /* iSCSIAuthRights.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIAuthRights.c; path = "Source/User/iSCSI Framework/iSCSIAuthRights.c"; sourceTree = ""; }; + 2B171E411CE23677003C3E08 /* iSCSIAuthRights.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIAuthRights.h; path = "Source/User/iSCSI Framework/iSCSIAuthRights.h"; sourceTree = ""; }; 2B1B972A1C4937B400DA5281 /* Scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Scripts; sourceTree = ""; }; + 2B1EDC0E1CFAEC1F007BAB99 /* iSCSI Utility.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iSCSI Utility.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2B1EDC101CFAEC1F007BAB99 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 2B1EDC111CFAEC1F007BAB99 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 2B1EDC141CFAEC1F007BAB99 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2B1EDC191CFAEC1F007BAB99 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2B1EDC1C1CFAEC1F007BAB99 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 2B1EDC1E1CFAEC1F007BAB99 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2B20904F18C6E43C00C43190 /* libsystem_kernel.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsystem_kernel.dylib; path = usr/lib/system/libsystem_kernel.dylib; sourceTree = SDKROOT; }; 2B459D541B7B8192008F656F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 2B56ACEC1C4A48C800930E79 /* Distribution */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Distribution; sourceTree = ""; }; @@ -94,6 +114,12 @@ 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; }; + 2B7762911CFEF9E7003093CC /* NodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeViewController.h; sourceTree = ""; }; + 2B7762921CFEF9E7003093CC /* NodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NodeViewController.m; sourceTree = ""; }; + 2B7762931CFEF9E7003093CC /* Node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Node.h; sourceTree = ""; }; + 2B7762941CFEF9E7003093CC /* Node.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Node.m; sourceTree = ""; }; + 2B77629C1D02CC9D003093CC /* InitiatorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitiatorViewController.h; sourceTree = ""; }; + 2B77629D1D02CC9D003093CC /* InitiatorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InitiatorViewController.m; sourceTree = ""; }; 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; }; @@ -118,6 +144,12 @@ 2B9E3C821C493B9C00440116 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Prefix.pch; path = Source/Kernel/Prefix.pch; sourceTree = ""; }; 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 = ""; }; + 2BAAB8B51D03E8EF00C01C79 /* SplitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SplitViewController.h; sourceTree = ""; }; + 2BAAB8B61D03E8EF00C01C79 /* SplitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SplitViewController.m; sourceTree = ""; }; + 2BB321F31D087AAA0030DB94 /* libcurses.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurses.tbd; path = usr/lib/libcurses.tbd; sourceTree = SDKROOT; }; + 2BB321F41D087AAA0030DB94 /* libncurses.5.4.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libncurses.5.4.tbd; path = usr/lib/libncurses.5.4.tbd; sourceTree = SDKROOT; }; + 2BB321F51D087AAA0030DB94 /* libncurses.5.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libncurses.5.tbd; path = usr/lib/libncurses.5.tbd; sourceTree = SDKROOT; }; + 2BB321F61D087AAA0030DB94 /* libncurses.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libncurses.tbd; path = usr/lib/libncurses.tbd; sourceTree = SDKROOT; }; 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 = ""; }; @@ -147,8 +179,8 @@ 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 = ""; }; + 2BDE5E531C8B028B004BDB5F /* iSCSIPreferences.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iSCSIPreferences.c; path = "Source/User/iSCSI Framework/iSCSIPreferences.c"; sourceTree = ""; }; + 2BDE5E541C8B028B004BDB5F /* iSCSIPreferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iSCSIPreferences.h; path = "Source/User/iSCSI Framework/iSCSIPreferences.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 = ""; }; @@ -173,6 +205,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2B1EDC0B1CFAEC1F007BAB99 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B77629B1D00B388003093CC /* iSCSI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 2B7A0B701C8AEC47008290E9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -202,6 +242,35 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2B1EDC0F1CFAEC1F007BAB99 /* iSCSI Utility */ = { + isa = PBXGroup; + children = ( + 2B7762911CFEF9E7003093CC /* NodeViewController.h */, + 2B7762921CFEF9E7003093CC /* NodeViewController.m */, + 2B77629C1D02CC9D003093CC /* InitiatorViewController.h */, + 2B77629D1D02CC9D003093CC /* InitiatorViewController.m */, + 2BAAB8B51D03E8EF00C01C79 /* SplitViewController.h */, + 2BAAB8B61D03E8EF00C01C79 /* SplitViewController.m */, + 2B7762931CFEF9E7003093CC /* Node.h */, + 2B7762941CFEF9E7003093CC /* Node.m */, + 2B1EDC101CFAEC1F007BAB99 /* AppDelegate.h */, + 2B1EDC111CFAEC1F007BAB99 /* AppDelegate.m */, + 2B1EDC191CFAEC1F007BAB99 /* Assets.xcassets */, + 2B1EDC1B1CFAEC1F007BAB99 /* Main.storyboard */, + 2B1EDC1E1CFAEC1F007BAB99 /* Info.plist */, + 2B1EDC131CFAEC1F007BAB99 /* Supporting Files */, + ); + path = "iSCSI Utility"; + sourceTree = ""; + }; + 2B1EDC131CFAEC1F007BAB99 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2B1EDC141CFAEC1F007BAB99 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; 2B5935541810CE6800FFC3D3 = { isa = PBXGroup; children = ( @@ -215,12 +284,17 @@ 2BDEA9411A715C7B00D5B48B /* iscsid */, 2BDEA9421A715C7B00D5B48B /* iscsictl */, 2B7A0B741C8AEC47008290E9 /* iSCSI.framework */, + 2B1EDC0E1CFAEC1F007BAB99 /* iSCSI Utility.app */, ); sourceTree = ""; }; 2B5935631810D38E00FFC3D3 /* Frameworks */ = { isa = PBXGroup; children = ( + 2BB321F31D087AAA0030DB94 /* libcurses.tbd */, + 2BB321F41D087AAA0030DB94 /* libncurses.5.4.tbd */, + 2BB321F51D087AAA0030DB94 /* libncurses.5.tbd */, + 2BB321F61D087AAA0030DB94 /* libncurses.tbd */, 2B459D541B7B8192008F656F /* Security.framework */, 2BC4CBB11AA55046003611F7 /* DiskArbitration.framework */, 2B20904F18C6E43C00C43190 /* libsystem_kernel.dylib */, @@ -283,14 +357,15 @@ 2BDE5E1A1C8B020A004BDB5F /* User */ = { isa = PBXGroup; children = ( + 2B1EDC0F1CFAEC1F007BAB99 /* iSCSI Utility */, 2BDE5E231C8B0255004BDB5F /* iscsictl */, 2BDE5E221C8B024A004BDB5F /* iscsid */, - 2BDE5E211C8B0241004BDB5F /* iSCSI.Framwork */, + 2BDE5E211C8B0241004BDB5F /* iSCSI Framwork */, ); name = User; sourceTree = ""; }; - 2BDE5E211C8B0241004BDB5F /* iSCSI.Framwork */ = { + 2BDE5E211C8B0241004BDB5F /* iSCSI Framwork */ = { isa = PBXGroup; children = ( 2BDE5E481C8B028B004BDB5F /* Info.plist */, @@ -304,16 +379,18 @@ 2BDE5E501C8B028B004BDB5F /* iSCSIIORegistry.h */, 2BDE5E511C8B028B004BDB5F /* iSCSIKeychain.c */, 2BDE5E521C8B028B004BDB5F /* iSCSIKeychain.h */, - 2BDE5E531C8B028B004BDB5F /* iSCSIPropertyList.c */, - 2BDE5E541C8B028B004BDB5F /* iSCSIPropertyList.h */, + 2BDE5E531C8B028B004BDB5F /* iSCSIPreferences.c */, + 2BDE5E541C8B028B004BDB5F /* iSCSIPreferences.h */, 2BDE5E551C8B028B004BDB5F /* iSCSIRFC3720Keys.h */, 2BDE5E561C8B028B004BDB5F /* iSCSITypes.c */, 2BDE5E571C8B028B004BDB5F /* iSCSITypes.h */, 2BDE5E581C8B028B004BDB5F /* iSCSITypesShared.h */, 2BDE5E591C8B028B004BDB5F /* iSCSIUtils.c */, 2BDE5E5A1C8B028B004BDB5F /* iSCSIUtils.h */, + 2B171E401CE23677003C3E08 /* iSCSIAuthRights.c */, + 2B171E411CE23677003C3E08 /* iSCSIAuthRights.h */, ); - name = iSCSI.Framwork; + name = "iSCSI Framwork"; sourceTree = ""; }; 2BDE5E221C8B024A004BDB5F /* iscsid */ = { @@ -359,10 +436,11 @@ 2BDE5E761C8B0292004BDB5F /* iSCSIIORegistry.h in Headers */, 2BDE5E731C8B0292004BDB5F /* iSCSIDaemonInterface.h in Headers */, 2BDE5E741C8B0292004BDB5F /* iSCSIDaemonInterfaceShared.h in Headers */, - 2BDE5E7A1C8B0292004BDB5F /* iSCSIPropertyList.h in Headers */, + 2BDE5E7A1C8B0292004BDB5F /* iSCSIPreferences.h in Headers */, 2BDE5E6F1C8B0292004BDB5F /* iSCSI.h in Headers */, 2BDE5E781C8B0292004BDB5F /* iSCSIKeychain.h in Headers */, 2BDE5E7E1C8B0292004BDB5F /* iSCSITypesShared.h in Headers */, + 2B171E431CE23677003C3E08 /* iSCSIAuthRights.h in Headers */, 2BDE5E7B1C8B0292004BDB5F /* iSCSIRFC3720Keys.h in Headers */, 2BDE5E711C8B0292004BDB5F /* iSCSIDA.h in Headers */, ); @@ -395,6 +473,23 @@ productReference = 2BDEA9421A715C7B00D5B48B /* iscsictl */; productType = "com.apple.product-type.tool"; }; + 2B1EDC0D1CFAEC1F007BAB99 /* iSCSI Utility */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2B1EDC1F1CFAEC1F007BAB99 /* Build configuration list for PBXNativeTarget "iSCSI Utility" */; + buildPhases = ( + 2B1EDC0A1CFAEC1F007BAB99 /* Sources */, + 2B1EDC0B1CFAEC1F007BAB99 /* Frameworks */, + 2B1EDC0C1CFAEC1F007BAB99 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "iSCSI Utility"; + productName = "iSCSI Utility"; + productReference = 2B1EDC0E1CFAEC1F007BAB99 /* iSCSI Utility.app */; + productType = "com.apple.product-type.application"; + }; 2B7A0B731C8AEC47008290E9 /* iSCSI */ = { isa = PBXNativeTarget; buildConfigurationList = 2B7A0B891C8AEC47008290E9 /* Build configuration list for PBXNativeTarget "iSCSI" */; @@ -455,8 +550,12 @@ 2B5935551810CE6800FFC3D3 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0700; TargetAttributes = { + 2B1EDC0D1CFAEC1F007BAB99 = { + CreatedOnToolsVersion = 7.3.1; + }; 2B7A0B731C8AEC47008290E9 = { CreatedOnToolsVersion = 7.0.1; }; @@ -479,11 +578,21 @@ 2BA96D8818D4F60200F135E3 /* iscsid */, 2B16EEC8196085A40061E7FA /* iscsictl */, 2B7A0B731C8AEC47008290E9 /* iSCSI */, + 2B1EDC0D1CFAEC1F007BAB99 /* iSCSI Utility */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 2B1EDC0C1CFAEC1F007BAB99 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B1EDC1A1CFAEC1F007BAB99 /* Assets.xcassets in Resources */, + 2B1EDC1D1CFAEC1F007BAB99 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 2B7A0B721C8AEC47008290E9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -522,13 +631,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2B1EDC0A1CFAEC1F007BAB99 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2B77629A1CFF2211003093CC /* Node.m in Sources */, + 2BAAB8B71D03E8EF00C01C79 /* SplitViewController.m in Sources */, + 2B7762991CFF220D003093CC /* NodeViewController.m in Sources */, + 2B77629E1D02CC9D003093CC /* InitiatorViewController.m in Sources */, + 2B1EDC151CFAEC1F007BAB99 /* main.m in Sources */, + 2B1EDC121CFAEC1F007BAB99 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 2B7A0B6F1C8AEC47008290E9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2B171E421CE23677003C3E08 /* iSCSIAuthRights.c in Sources */, 2BDE5E701C8B0292004BDB5F /* iSCSIDA.c in Sources */, 2BDE5E721C8B0292004BDB5F /* iSCSIDaemonInterface.c in Sources */, - 2BDE5E791C8B0292004BDB5F /* iSCSIPropertyList.c in Sources */, + 2BDE5E791C8B0292004BDB5F /* iSCSIPreferences.c in Sources */, 2BDE5E751C8B0292004BDB5F /* iSCSIIORegistry.c in Sources */, 2BDE5E771C8B0292004BDB5F /* iSCSIKeychain.c in Sources */, 2BDE5E7F1C8B0292004BDB5F /* iSCSIUtils.c in Sources */, @@ -566,6 +689,17 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXVariantGroup section */ + 2B1EDC1B1CFAEC1F007BAB99 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 2B1EDC1C1CFAEC1F007BAB99 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 2B16EED0196085A40061E7FA /* Debug */ = { isa = XCBuildConfiguration; @@ -644,12 +778,101 @@ }; name = Release; }; + 2B1EDC201CFAEC1F007BAB99 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + 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; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + 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; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + 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_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = "iSCSI Utility/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.github.iscsi-osx.iSCSI-Utility"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 2B1EDC211CFAEC1F007BAB99 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + 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; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + 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; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + 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_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = "iSCSI Utility/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "com.github.iscsi-osx.iSCSI-Utility"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 2B5935591810CE6800FFC3D3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CF_PREFERENCES_APP_ID = "$(NAME_PREFIX_D).iSCSIInitiator"; CODE_SIGN_IDENTITY = ""; - CURRENT_PROJECT_VERSION = "1.0.0-beta"; + CURRENT_PROJECT_VERSION = "1.0.0-beta2"; ENABLE_TESTABILITY = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "CF_PREFERENCES_APP_ID=\\\"$(NAME_PREFIX_D).iSCSIInitiator\\\"", @@ -671,7 +894,7 @@ buildSettings = { CF_PREFERENCES_APP_ID = "$(NAME_PREFIX_D).iSCSIInitiator"; CODE_SIGN_IDENTITY = ""; - CURRENT_PROJECT_VERSION = "1.0.0-beta"; + CURRENT_PROJECT_VERSION = "1.0.0-beta2"; GCC_PREPROCESSOR_DEFINITIONS = ( "CF_PREFERENCES_APP_ID=\\\"$(NAME_PREFIX_D).iSCSIInitiator\\\"", "NAME_PREFIX_U=$(NAME_PREFIX_U)", @@ -980,6 +1203,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2B1EDC1F1CFAEC1F007BAB99 /* Build configuration list for PBXNativeTarget "iSCSI Utility" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2B1EDC201CFAEC1F007BAB99 /* Debug */, + 2B1EDC211CFAEC1F007BAB99 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 2B5935581810CE6800FFC3D3 /* Build configuration list for PBXProject "iSCSIInitiator" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSI.framework.xcscheme b/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSI.framework.xcscheme new file mode 100644 index 00000000..a8ec144c --- /dev/null +++ b/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSI.framework.xcscheme @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSIInitiator.xcscheme b/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSI.kext.xcscheme similarity index 100% rename from iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSIInitiator.xcscheme rename to iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iSCSI.kext.xcscheme diff --git a/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iscsictl.xcscheme b/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iscsictl.xcscheme index 561e92b8..87c8b827 100644 --- a/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iscsictl.xcscheme +++ b/iSCSIInitiator.xcodeproj/xcshareddata/xcschemes/iscsictl.xcscheme @@ -45,6 +45,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + debugAsWhichUser = "root" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO"