W
Webdiyer
I want to integrate SecurID two-factor authentication system of the
RSASecurity.inc into our asp.net application,but I get into trouble when
trying to call the API functions of the ACE Agent,I got an error message
saying "Cannot marshal parameter #2: Invalid managed/unmanaged type
combination (this value type must be paired with Struct)" when calling
"AceGetPinParams(iHandle,ref sd_pin)" function,here's my test code:
[DllImport("aceclnt")]
private static extern bool AceInitialize();
[DllImport("aceclnt")]
private static extern int SD_Init(ref IntPtr iHandle);
[DllImport("aceclnt")]
private static extern int SD_Close(IntPtr iHandle);
[DllImport("aceclnt")]
private static extern int SD_Lock(IntPtr iHandle,string uname);
[DllImport("aceclnt")]
private static extern int SD_Check(IntPtr iHandle,string passwd,string
uname);
[DllImport("aceclnt")]
private static extern int SD_Pin(IntPtr iHandle,string pin);
[DllImport("aceclnt")]
private static extern int AceGetPinParams(IntPtr iHandle,ref SD_PinParams
pin);
private void button1_Click(object sender, System.EventArgs e)
{
AuthStatus aStatus=AuthStatus.InitFailed;
if(AceInitialize())//Initialize succeeded
{
int statusCode;
aStatus=AuthStatus.CommunicationFailed;
IntPtr iHandle=new IntPtr(0);
statusCode=SD_Init(ref iHandle);
if(statusCode==0)//Communication with the auth server succeeded
{
aStatus=AuthStatus.AccessDenied;
statusCode=SD_Lock(iHandle,uname.Text);//user has been locked
if(statusCode==0)
{
statusCode=SD_Check(iHandle,pwd.Text,uname.Text);
aStatus=(AuthStatus)statusCode;
if(aStatus==AuthStatus.NewPinRequired)
{
MessageBox.Show("New Pin Required£¡");
SD_PinParams sd_pin=new SD_PinParams();
int i=AceGetPinParams(iHandle,ref sd_pin);
if(i==1)
{
MessageBox.Show(sd_pin.Min.ToString());
MessageBox.Show(sd_pin.Selectable.ToString());
}
}
}
}
SD_Close(iHandle);
}
}
public const int LENPRNST = 16;
[StructLayout(LayoutKind.Sequential)]
public struct SD_PinParams
{
public byte Min;
public byte Max;
public byte Selectable;
public byte Alphanumeric;
[MarshalAs(UnmanagedType.LPArray, SizeConst=LENPRNST+2)]
public byte[] System;
}
public enum AuthStatus
{
InitFailed=1000,//Initialize Failed
CommunicationFailed=1001,//Communication failed
NextCodeRequired=2,//Next token code required
NewPinRequired=5,//New Pin required
Succeeded=0,//Authentication succeeded
AccessDenied=1,//Access denied
InvalidPassCode=902,//Invalid passcode
InvalidUserName901,//Invalid user name
InvalidHandle=101,//Invalid handle
}
public enum NewPinStatus
{
InvalidPin=800,//Invalid pin
Accepted=6,//new pin accepted
Rejected=7,//new pin rejected
InvalidHandle=101,//invalid handle
}
Here's the description of the ACEGetPinParams API function:
Description
int WINAPI AceGetPinParams(
SDI_HANDLE Sdi_handle,
SD_PIN *val)
typedef struct{
SD_CHAR Min;
SD_CHAR Max;
SD_CHAR Selectable;
SD_CHAR Alphanumeric;
SD_CHAR System[LENPRNST+2];
}SD_PIN
The AceGetPinParams function obtains all of the PIN-related parameters at
once. It is
helpful to retrieve this value when the result code from AceCheck is
ACM_NEW_PIN_REQUIRED and the Agent is designed to validate that the new PIN
entered by the user conforms to the required PIN characteristics set by the
RSA ACE/Server
administrator. Any such checking done by the Agent is simply as a
convenience to the user.
The PIN will be fully checked for correctness by the RSA ACE/Server.
Architecture
The caller of this synchronous function must supply, as the second argument,
a pointer to a
structure of type SD_PIN, into which the function will copy the PIN
parameters.
AceGetPinParams does not allocate storage for the data on its own.
Input Arguments
SdiHandle The value of a handle originally assigned by a call to AceInit.
Val A pointer to a structure of type SD_PIN that will contain
copies of the PIN parameters.
Outputs and Post Conditions
The function returns ACE_SUCCESS if the handle to the authentication data
was found and
the PIN value was provided by the function.
Error Handling
A value of ACE_ERR_INVALID_HANDLE is returned if the handle to the
authentication
data cannot be found.
//type definition
typedef int SDI_HANDLE, * LP_SDI_HANDLE;
typedef char SD_CHAR; /* ch or sz */
#define LENPRNST 16
How can I solve this problem,any help will be greatly appreciated!
RSASecurity.inc into our asp.net application,but I get into trouble when
trying to call the API functions of the ACE Agent,I got an error message
saying "Cannot marshal parameter #2: Invalid managed/unmanaged type
combination (this value type must be paired with Struct)" when calling
"AceGetPinParams(iHandle,ref sd_pin)" function,here's my test code:
[DllImport("aceclnt")]
private static extern bool AceInitialize();
[DllImport("aceclnt")]
private static extern int SD_Init(ref IntPtr iHandle);
[DllImport("aceclnt")]
private static extern int SD_Close(IntPtr iHandle);
[DllImport("aceclnt")]
private static extern int SD_Lock(IntPtr iHandle,string uname);
[DllImport("aceclnt")]
private static extern int SD_Check(IntPtr iHandle,string passwd,string
uname);
[DllImport("aceclnt")]
private static extern int SD_Pin(IntPtr iHandle,string pin);
[DllImport("aceclnt")]
private static extern int AceGetPinParams(IntPtr iHandle,ref SD_PinParams
pin);
private void button1_Click(object sender, System.EventArgs e)
{
AuthStatus aStatus=AuthStatus.InitFailed;
if(AceInitialize())//Initialize succeeded
{
int statusCode;
aStatus=AuthStatus.CommunicationFailed;
IntPtr iHandle=new IntPtr(0);
statusCode=SD_Init(ref iHandle);
if(statusCode==0)//Communication with the auth server succeeded
{
aStatus=AuthStatus.AccessDenied;
statusCode=SD_Lock(iHandle,uname.Text);//user has been locked
if(statusCode==0)
{
statusCode=SD_Check(iHandle,pwd.Text,uname.Text);
aStatus=(AuthStatus)statusCode;
if(aStatus==AuthStatus.NewPinRequired)
{
MessageBox.Show("New Pin Required£¡");
SD_PinParams sd_pin=new SD_PinParams();
int i=AceGetPinParams(iHandle,ref sd_pin);
if(i==1)
{
MessageBox.Show(sd_pin.Min.ToString());
MessageBox.Show(sd_pin.Selectable.ToString());
}
}
}
}
SD_Close(iHandle);
}
}
public const int LENPRNST = 16;
[StructLayout(LayoutKind.Sequential)]
public struct SD_PinParams
{
public byte Min;
public byte Max;
public byte Selectable;
public byte Alphanumeric;
[MarshalAs(UnmanagedType.LPArray, SizeConst=LENPRNST+2)]
public byte[] System;
}
public enum AuthStatus
{
InitFailed=1000,//Initialize Failed
CommunicationFailed=1001,//Communication failed
NextCodeRequired=2,//Next token code required
NewPinRequired=5,//New Pin required
Succeeded=0,//Authentication succeeded
AccessDenied=1,//Access denied
InvalidPassCode=902,//Invalid passcode
InvalidUserName901,//Invalid user name
InvalidHandle=101,//Invalid handle
}
public enum NewPinStatus
{
InvalidPin=800,//Invalid pin
Accepted=6,//new pin accepted
Rejected=7,//new pin rejected
InvalidHandle=101,//invalid handle
}
Here's the description of the ACEGetPinParams API function:
Description
int WINAPI AceGetPinParams(
SDI_HANDLE Sdi_handle,
SD_PIN *val)
typedef struct{
SD_CHAR Min;
SD_CHAR Max;
SD_CHAR Selectable;
SD_CHAR Alphanumeric;
SD_CHAR System[LENPRNST+2];
}SD_PIN
The AceGetPinParams function obtains all of the PIN-related parameters at
once. It is
helpful to retrieve this value when the result code from AceCheck is
ACM_NEW_PIN_REQUIRED and the Agent is designed to validate that the new PIN
entered by the user conforms to the required PIN characteristics set by the
RSA ACE/Server
administrator. Any such checking done by the Agent is simply as a
convenience to the user.
The PIN will be fully checked for correctness by the RSA ACE/Server.
Architecture
The caller of this synchronous function must supply, as the second argument,
a pointer to a
structure of type SD_PIN, into which the function will copy the PIN
parameters.
AceGetPinParams does not allocate storage for the data on its own.
Input Arguments
SdiHandle The value of a handle originally assigned by a call to AceInit.
Val A pointer to a structure of type SD_PIN that will contain
copies of the PIN parameters.
Outputs and Post Conditions
The function returns ACE_SUCCESS if the handle to the authentication data
was found and
the PIN value was provided by the function.
Error Handling
A value of ACE_ERR_INVALID_HANDLE is returned if the handle to the
authentication
data cannot be found.
//type definition
typedef int SDI_HANDLE, * LP_SDI_HANDLE;
typedef char SD_CHAR; /* ch or sz */
#define LENPRNST 16
How can I solve this problem,any help will be greatly appreciated!