using System; using System.Text; using System.Runtime.InteropServices; namespace Novell.SecretStore.NSSSWrapper { /// /// Summary description for Class1. /// 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