CASA/c_sharp/NSSSWrapper/NativeCalls.cs
2005-10-11 19:51:00 +00:00

678 lines
19 KiB
C#

using System;
using System.Text;
using System.Runtime.InteropServices;
namespace Novell.SecretStore.NSSSWrapper
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class NativeCalls
{
//private uint NSSS_GET_CONTEXT_F = 0x00000100;
private string m_host = null;
private string m_userId = null;
private string m_password = null;
private string m_certFile = null;
private SSS_CONTEXT_T m_context = null;
private SS_OBJECT_DN_T m_objectDN = null;
public NativeCalls(string host, string userId, string password, string certFile)
{
//
// TODO: Add constructor logic here
//
m_host = host;
m_userId = userId;
m_password = password;
m_certFile = certFile;
}
//* Get service info extended data
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class SSS_GSINFOEXT_T
{
public uint statFlags;
public uint secretCount;
public uint lockCount;
public uint enumBufLen;
public uint hidSecCount;
public uint clientVersion;
public uint serverVersion;
public uint serverCryptoStrength;
public uint clientCryptoStrength;
public uint unlockTStamp;
public uint admnDNLen;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 516)]
public string admnDN; //[NSSS_MAX_DN_LEN];
public uint hintLen;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string hint; //[NSSS_MAX_MP_PWORD_HINT_LEN]];
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_SERVER_INFO_T
{
//char treeName[NSSS_MAX_TREE_NAME_LEN];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] // in bytes?
public string treeName;
//char ssServerDN[NSSS_MAX_DN_LEN];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 516)]
public string ssServerDN;
//char ssServerIPAddr[NSSS_MAX_IP_ADDR_LEN];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string ssServerIPAddr;
//char sssConfigDN[NSSS_MAX_DN_LEN];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 516)]
public string sssConfigDN;
} ;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_OBJECT_DN_T
{
public int len;
//char id[NSSS_MAX_DN_LEN];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 516)]
public string id;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SSS_CONTEXT_T
{
public uint flags; //* IN- context type indicator and
public uint dsCtx; //* IN/OUT- ldap/ncp context
public uint version; //* IN- context version indicator
public SS_SERVER_INFO_T ssServerInfo; //* IN/OUT- preferred SecretStore server info
public SS_OBJECT_DN_T callerDN; //* IN/OUT- DN of the caller. OUT-For NCP.
public IntPtr handles;
public IntPtr bindInfo;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class SSCS_EXT_T
{
public int extID; // defined to identify the extension
public int version; // defined as the version of the specified extension
//void *ext; // points to the actual extension
public IntPtr ext;
} ;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_LDAPBIND_INFO_T
{
public uint portNum; //* default: 636
//char lHostName[ NSSS_MAX_DN_LEN ]; //* Ex: "nsd10.novell.com" or ip addr
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 516)]
public string lHostHame;
//char trustedRootCert[ NSSS_MAX_DN_LEN ]; //* default: "c:\TrustedRootCertificate.der"
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 516)]
public string trustedRootCert;
//char loginPword[ NSSS_MAX_LDAP_PWORD_LEN ]; //* LDAP login password (utf8)
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string loginPword;
} ;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_SECRET_T
{
public int len;
public IntPtr data;
};
//* password structure
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_PWORD_T
{
public uint pwordLen; //* enhanced protection len & pword to set
//char pword[NSSS_MAX_EP_PWORD_LEN]; //* should be passed in # of chars
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string pword;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SSS_READEXT_T
{
public uint statFlags; //* OUT - return flags on the secret
public uint crtStamp; //* OUT - secret creation time stamp
public uint latStamp; //* OUT - last accessed time stamp (optional)
public uint lmtStamp; //* OUT - last modified time stamp
};
//* Secret ID type
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_SECRET_ID_T
{
public int len; //* max id len in bytes
//char id[NSSS_MAX_SECRET_ID_LEN]; //* should be passed in # of chars
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
public string id;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class SS_SH_SECRET_ID_T
{
public int type; // The shared secret type i.e. SS_App or SS_CredSet
//char pName[NSSS_MAX_SECRET_ID_LEN]; // The shared secret name. This is the same as the identifier
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
public string id;
public int len; // except that it excludes the header and is not escaped.
} ;
#if DEBUG
private const string NDK_LIBRARY = "nsss";
//private const string NDK_LIBRARY = "/opt/novell/sss/libnsss.so";
#else
private const string NDK_LIBRARY = "nsss";
#endif
[DllImport(NDK_LIBRARY, CharSet=CharSet.Ansi)]
public static extern int NSSSGetServiceInformation
(
[In, Out] SSS_CONTEXT_T context,
[In] SS_OBJECT_DN_T targetObjDN,
[In] uint ssFlags,
[In, Out] SSS_GSINFOEXT_T gsData,
[In, Out] SSCS_EXT_T ext
);
[DllImport(NDK_LIBRARY, CharSet=CharSet.Ansi)]
public static extern int NSSSEnumerateSecretIDs
(
[In, Out] SSS_CONTEXT_T context,
[In] SS_OBJECT_DN_T targetObjDN,
[In] uint ssFlags,
[In, Out] IntPtr srchStr,
[In, Out] ref uint count,
[In, Out] SS_SECRET_T secretIDList,
[In, Out] SSCS_EXT_T ext
);
[DllImport(NDK_LIBRARY, CharSet=CharSet.Ansi)]
public static extern int NSSSReadSecret
(
[In, Out] SSS_CONTEXT_T context,
[In] SS_OBJECT_DN_T targetObjDN,
[In] uint ssFlags,
[In] SS_PWORD_T epPassword,
[In, Out] SSS_READEXT_T readData,
[In] SS_SECRET_ID_T secretID,
[In, Out] SS_SECRET_T secretValue,
[In, Out] SSCS_EXT_T ext
);
//**************************************************************
//* Support Functions for processing (populating or extracting)
//* data components from a Shared Secret
//**************************************************************
[DllImport(NDK_LIBRARY)]
public static extern IntPtr NSSSCreateSHSHandle();
[DllImport(NDK_LIBRARY)]
public static extern int NSSSDestroySHSHandle(
[In] IntPtr handle); // in
[DllImport(NDK_LIBRARY, CharSet=CharSet.Ansi) ]
public static extern int NSSSGetNextSHSEntry
(
[In] int restart, //* in (set to 1 to begin from head of list)
[In] IntPtr secretHandle, //* in
[In, Out] ref uint keyLen, //* out
//[MarshalAs(UnmanagedType.LPTStr)]
// StringBuilder key, //* out uchar
[In, Out] IntPtr pKey,
[In, Out] ref uint valLen, //* out
//[MarshalAs(UnmanagedType.LPTStr)]
// StringBuilder val, //* out uchar
[In, Out] IntPtr pVal,
[In] uint ssCtxFlags
);
[DllImport(NDK_LIBRARY, CharSet=CharSet.Ansi)]
public static extern int NSSSAddSHSEntry
(
[In] IntPtr secretHandle, //* in]
//[MarshalAs(UnmanagedType.B)]
string key, //* in /wchar
//[MarshalAs(UnmanagedType.LPTStr)]
string val, //* in /uchar
[In] uint ssCtxFlags
);
[DllImport(NDK_LIBRARY)]
public static extern int NSSSRemoveSHSEntry
(
[In] IntPtr secretHandle, //* in
[MarshalAs(UnmanagedType.LPWStr)]
string key, //* out /uchar
[MarshalAs(UnmanagedType.LPTStr)]
string val, //* out /uchar
[In] uint ssCtxFlags
);
//**************************************************************
//* These function calls will utilize the Support Functions for
//* populating or extracting data from a Shared Secret.
//**************************************************************
[DllImport(NDK_LIBRARY)]
public static extern int NSSSWriteSharedSecret
(
[In] IntPtr secretHandle, //* in
[In] SS_SH_SECRET_ID_T pSharedSecret,
[In, Out] SSS_CONTEXT_T context,
[In] SS_OBJECT_DN_T targetObjDN,
[In] uint ssFlags,
[In] SS_PWORD_T epPassword,
[In, Out] SSCS_EXT_T ext
);
[DllImport(NDK_LIBRARY)]
public static extern int NSSSReadSharedSecret
(
[In] IntPtr secretHandle, //* in
[In] SS_SH_SECRET_ID_T pSharedSecret,
[In, Out] SSS_CONTEXT_T context,
[In] SS_OBJECT_DN_T targetObjDN,
[In] uint ssFlags,
[In] SS_PWORD_T epPassword,
[In, Out] SSS_READEXT_T readData,
[In, Out] SSCS_EXT_T ext
);
[DllImport(NDK_LIBRARY)]
public static extern int NSSSRemoveSharedSecret
(
[In] SS_SH_SECRET_ID_T pSharedSecret,
[In, Out] SSS_CONTEXT_T context,
[In] SS_OBJECT_DN_T targetObjDN,
[In] uint ssFlags,
[In, Out] SSCS_EXT_T ext
);
// code starts here
public void setContextInfo(string sHost, string sUsername, string sPassword, string sCertFile)
{
m_host = sHost;
m_userId = sUsername;
m_password = sPassword;
m_certFile = sCertFile;
}
public void getStoreInfo()
{
// set up locals
SSS_CONTEXT_T context = new SSS_CONTEXT_T();
SS_OBJECT_DN_T objectDN = new SS_OBJECT_DN_T();
SS_LDAPBIND_INFO_T ldapBindInfo = new SS_LDAPBIND_INFO_T();
SSS_GSINFOEXT_T gsData = new SSS_GSINFOEXT_T();
SSCS_EXT_T ext = new SSCS_EXT_T();
// init params
objectDN.id = m_userId;
objectDN.len = objectDN.id.Length + 1;
//ldapBindInfo.lHostHame = "151.155.152.209";
//ldapBindInfo.lHostHame = "jim1.provo.novell.com";
ldapBindInfo.lHostHame = m_host;
//ldapBindInfo.loginPword = "test";
ldapBindInfo.loginPword = m_password;
ldapBindInfo.portNum = 636;
ldapBindInfo.trustedRootCert = m_certFile;
context.bindInfo = Marshal.AllocHGlobal(Marshal.SizeOf(ldapBindInfo));
Marshal.StructureToPtr(ldapBindInfo, context.bindInfo, false);
//context.callerDN = objectDN;
context.callerDN = objectDN;
context.flags = 2050;
context.handles = IntPtr.Zero;
context.version = 0;
//context.bindInfo = ldapBindInfo;
//context.bindInfo = new IntPtr(4);
context.ssServerInfo = new SS_SERVER_INFO_T();
Console.WriteLine("ServerInfoSize: "+Marshal.SizeOf(context.ssServerInfo));
int rcode = NSSSGetServiceInformation(context,
objectDN,
0x00000100, //0x00000110, // 0x00000010, ALL STRINGS UNICODE....
gsData,
ext);
if (rcode != 0)
{
Console.Write("NSSSGetServiceInformation return error: " + rcode);
throw new Exception("Login Failed");
}
else
{
m_context = context;
m_objectDN = objectDN;
}
//enumerateSecretIDs(context, objectDN, 0x00000110);
}
public string[] enumerateSecretIDs()
{
return enumerateSecretIDs(m_context, m_objectDN, 0x00000000);
}
private string[] enumerateSecretIDs(SSS_CONTEXT_T context, SS_OBJECT_DN_T targetObjDN, uint ssFlags)
{
int rcode = 0;
uint count = 0;
SS_SECRET_T secretIDList = new SS_SECRET_T();
secretIDList.data = Marshal.AllocHGlobal(16384+1);
secretIDList.len = 16384+1;
SSCS_EXT_T ext = new SSCS_EXT_T();
rcode = NSSSEnumerateSecretIDs(context,
targetObjDN,
ssFlags,
IntPtr.Zero, // [In, Out] IntPtr srchStr,
ref count,
secretIDList,
ext);
if (rcode != 0)
{
Console.Write("NSSSGetServiceInformation return error: " + rcode);
return null;
}
string ids = Marshal.PtrToStringAnsi(secretIDList.data);
if (ids.EndsWith("*"))
ids = ids.Substring(0, ids.Length-1);
// parse the buffer
string [] split = null;
string delimStr = "*";
char [] delimiter = delimStr.ToCharArray();
for (int i = 1; i <= count; i++)
{
split = ids.Split(delimiter, i);
}
/*
if (false)
{
// dump em out.
for (int i=0; i<split.Length; i++)
{
Console.WriteLine("-------------------");
string sTemp = split[i].ToString().TrimEnd(delimiter);
Console.WriteLine("ID: "+sTemp);
if (sTemp.StartsWith("SS_CredSet"))
getSharedSecret(context, targetObjDN, ssFlags, sTemp);
else
getSecret(context, targetObjDN, ssFlags, sTemp);
Console.WriteLine();
}
}
*/
return split;
}
public RemoteSecret getSecret(uint ssFlags, string sSecretID)
{
return getSecret(m_context, m_objectDN, ssFlags, sSecretID);
}
public RemoteSecret getSecret(SSS_CONTEXT_T context,
SS_OBJECT_DN_T targetObjDN,
uint ssFlags,
string sSecretID)
{
if (sSecretID.StartsWith("SS_CredSet") || sSecretID.StartsWith("SS_App"))
{
return getSharedSecret(context, targetObjDN, ssFlags, sSecretID);
}
int rcode = 0;
SS_PWORD_T epPassword = new SS_PWORD_T();
SSS_READEXT_T readData = new SSS_READEXT_T();
SS_SECRET_ID_T secretId = new SS_SECRET_ID_T();
secretId.id = sSecretID;
secretId.len = sSecretID.Length+1;
SS_SECRET_T secretValue = new SS_SECRET_T();
secretValue.data = Marshal.AllocHGlobal(1024*64);
secretValue.len = (1024*64);
SSCS_EXT_T ext = new SSCS_EXT_T();
rcode = NSSSReadSecret(context, targetObjDN, ssFlags, epPassword, readData, secretId, secretValue, ext);
if (rcode == 0)
{
RemoteSecret rs = new RemoteSecret(sSecretID, readData.crtStamp, readData.lmtStamp, readData.latStamp);
String sValue = Marshal.PtrToStringAnsi(secretValue.data, secretValue.len);
//String sValue = Marshal.PtrToStringAnsi(secretValue.data, secretValue.len);
rs.setValue(sValue);
Marshal.FreeHGlobal(secretValue.data);
return rs;
}
else
Console.WriteLine("value: not found "+ rcode);
// release unmanaged memory.
Marshal.FreeHGlobal(secretValue.data);
return null;
}
public static RemoteSecret getSharedSecret(SSS_CONTEXT_T context,
SS_OBJECT_DN_T targetObjDN,
uint ssFlags,
string sSecretID)
{
int rcode = 0;
SS_PWORD_T epPassword = new SS_PWORD_T();
SSS_READEXT_T readData = new SSS_READEXT_T();
SS_SH_SECRET_ID_T pSharedSecretID = new SS_SH_SECRET_ID_T();
if (sSecretID.StartsWith("SS_CredSet"))
{
pSharedSecretID.id = sSecretID.Substring(11);
pSharedSecretID.len = pSharedSecretID.id.Length;
pSharedSecretID.type = 2;
}
else //SS_App
{
pSharedSecretID.id = sSecretID.Substring(7);
pSharedSecretID.len = pSharedSecretID.id.Length;
pSharedSecretID.type = 1;
}
SSCS_EXT_T ext = new SSCS_EXT_T();
// get secretHandle
IntPtr secretHandle = NSSSCreateSHSHandle();
rcode = NSSSReadSharedSecret(secretHandle, pSharedSecretID, context, targetObjDN, ssFlags, epPassword, readData, ext);
if (rcode == 0)
{
RemoteSecret rs = new RemoteSecret(pSharedSecretID.id, readData.crtStamp, readData.lmtStamp, readData.latStamp);
// enumerate key/value pairs
loadKeyValuePairs(context, secretHandle, rs);
return rs;
}
else
return null;
}
internal static void loadKeyValuePairs(SSS_CONTEXT_T context, IntPtr secretHandle, RemoteSecret rs)
{
int rcode=0;
int iStart = 1;
uint iKeyLen = 60416;
//StringBuilder sKey = new StringBuilder((int)iKeyLen);
IntPtr pKey; // = new IntPtr(4);
pKey = Marshal.AllocHGlobal(60416);
uint iValueLen = 60416;
//StringBuilder sValue = new StringBuilder((int)iValueLen);
IntPtr pValue; // = new IntPtr(4);
pValue = Marshal.AllocHGlobal(60416);
while (true)
{
rcode = NSSSGetNextSHSEntry(
iStart,
secretHandle,
ref iKeyLen,
//sKey,
pKey,
ref iValueLen,
//sValue,
pValue,
context.flags
);
if (rcode != 0)
break;
else
{
/*
UTF8Encoding encoder = new UTF8Encoding();
System.Text.Decoder decoder = encoder.GetDecoder();
byte[] baKey= new byte[(int)iKeyLen];
Marshal.Copy(pKey, baKey, 0, (int)iKeyLen-1);
char[] caKey = new char[256];
rcode = decoder.GetChars(baKey, 0, baKey.Length, caKey, 0);
string sKey = new String(caKey);
Console.WriteLine("baKeyBytes");
for (int j=0; j<baKey.Length; j++)
Console.Write(baKey[j] + " ");
Console.WriteLine();
byte[] baValue = new byte[(int)iValueLen];
Marshal.Copy(pValue, baValue, 0, (int)iValueLen-1);
char[] caValue = new char[256];
rcode = decoder.GetChars(baValue, 0, baValue.Length, caValue, 0);
string sValue = new string(caValue);
Console.WriteLine("Adding key-value " + sKey.Trim() + "=" +sValue.Trim());
rs.setKeyValuePair(sKey.Trim(), sValue.Trim());
*/
string sKey = Marshal.PtrToStringAnsi(pKey, (int)iKeyLen-1);
string sValue = Marshal.PtrToStringAnsi(pValue, (int)iValueLen-1);
//Marshal.PtrToStringAnsi(
//Console.WriteLine(sKey + "=" + sValue);
rs.setKeyValuePair(sKey, sValue);
iKeyLen = 60416;
iValueLen = 60416;
iStart = 0;
}
}
Marshal.FreeHGlobal(pKey);
Marshal.FreeHGlobal(pValue);
}
public void setSecret(RemoteSecret secret)
{
setSecret(m_context, m_objectDN, 0, secret);
}
internal void setSecret(SSS_CONTEXT_T context,
SS_OBJECT_DN_T targetObjDN,
uint ssFlags,
RemoteSecret secret)
{
int rcode = 0;
// create a secretHandle
// get secretHandle
IntPtr secretHandle = NSSSCreateSHSHandle();
// write out the keyValue Pairs
System.Collections.Specialized.NameValueCollection nvc = secret.getKeyValueCollection();
//int NSSS_LDAP_CTX_F 0x00000002; //* Context is for LDAP
//int NSSS_CONTEXT_INITIALIZED_F 0x00000004;
for (int i=0; i<nvc.Count; i++)
{
string sKey = nvc.GetKey(i);
string sValue = nvc.Get(i);
rcode = NSSSAddSHSEntry(secretHandle, sKey, sValue, 6);
}
SS_PWORD_T epPassword = new SS_PWORD_T();
SS_SH_SECRET_ID_T pSharedSecretID = new SS_SH_SECRET_ID_T();
pSharedSecretID.id = secret.getID();
pSharedSecretID.len = pSharedSecretID.id.Length;
pSharedSecretID.type = 2;
SSCS_EXT_T ext = new SSCS_EXT_T();
// Write the SharedSecret
rcode = NSSSWriteSharedSecret(secretHandle,
pSharedSecretID,
context,
targetObjDN,
ssFlags,
epPassword,
ext);
}
}
}