Does anyone know how to get a ticket from the Key Distribution Center (KDC) using the MIT krb5 API in C/C++?
I already have a working Java Client which uses GSS-API to obtain a ticket from the KDC (using a local TGT) and forwards it to a Java Server.
The server accepts the security context using the following logic:
private GSSContext acceptSecurityContext(Subject serverSubject, final byte[] kerberosServiceTicket) {
return Subject.doAs(serverSubject, (PrivilegedAction<GSSContext>) () -> {
GSSContext gssContext;
try {
gssContext = manager.createContext((GSSCredential) null);
} catch (GSSException ex) {
LOGGER.warn("Could not create Kerberos gssContext: " + ex.getMessage(), ex);
return null;
}
try {
gssContext.acceptSecContext(kerberosServiceTicket, 0, kerberosServiceTicket.length);
} catch (GSSException ex) {
LOGGER.warn("Could not accept security context: " + ex.getMessage(), ex);
return null;
}
return gssContext;
});
}
I am trying to implement a C client - similar to the Java one - using MIT krb5 API and I can't seem to make it work. So far this is my C client code:
krb5_context context;
krb5_ccache ccache;
krb5_creds *outCreds = NULL;
krb5_creds inCreds;
int retval;
char *principal = "...";
retval = krb5_init_secure_context(&context);
...
retval = krb5_cc_default(context, &ccache);
...
memset(&inCreds, 0, sizeof(inCreds));
retval = krb5_parse_name(context, principal, &inCreds.server);
...
retval = krb5_cc_get_principal(context, ccache, &inCreds.client);
...
retval = krb5_get_credentials(context, 0, ccache, &inCreds, &outCreds);
...
// also tried using the following: krb5Ticket->enc_part.ciphertext.data
// (maybe this is the correct way, but I should somehow decrypt it and use krb5Ticket->enc_part2 ?)
// retval = krb5_decode_ticket(&outCreds->ticket, &krb5Ticket);
// ...
char *base64KerberosTicket = base64_encode(outCreds->ticket.data, strlen(outCreds->ticket.data));
char *response = loginKerberos(base64KerberosTicket);
...
After some further reading it appears that my approach was not correct for my use case. I should have used GSS-API directly.
The following snippet works:
gss_name_t get_spn(char *spn)
{
OM_uint32 maj_stat;
OM_uint32 min_stat;
gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER;
gss_name_t spn_gss_name = GSS_C_NO_NAME;
name_buf.value = spn;
name_buf.length = strlen(name_buf.value);
maj_stat = gss_import_name(&min_stat, &name_buf, GSS_KRB5_NT_PRINCIPAL_NAME, &spn_gss_name);
if (GSS_ERROR(maj_stat))
{
display_status("Major status", maj_stat, GSS_C_GSS_CODE);
display_status("Minor status", min_stat, GSS_C_MECH_CODE);
}
return spn_gss_name;
}
char* init_sec_context(char *spn)
{
OM_uint32 maj_stat;
OM_uint32 min_stat;
OM_uint32 flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG;
gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
gss_name_t spn_gss_name = get_spn(spn);
gss_buffer_desc output_token;
char *base64_encoded_kerberos_token = NULL;
maj_stat = gss_init_sec_context( //
&min_stat, // minor_status
GSS_C_NO_CREDENTIAL, // claimant_cred_handle
&gss_context, // context_handle
spn_gss_name, // target_name
GSS_C_NO_OID, // mech_type of the desired mechanism
flags, // req_flags
0, // time_req for the context to remain valid. 0 for default lifetime.
GSS_C_NO_CHANNEL_BINDINGS, // channel bindings
GSS_C_NO_BUFFER, // input token
NULL, // actual_mech_type
&output_token, // output token
NULL, // ret_flags
NULL // time_req
);
if (GSS_ERROR(maj_stat))
{
...
}
else if (output_token.length != 0)
{
base64_encoded_kerberos_token = base64_encode(output_token.value, output_token.length, &(output_token.length));
}
if (gss_context != GSS_C_NO_CONTEXT)
{
gss_delete_sec_context(&min_stat, &gss_context, GSS_C_NO_BUFFER);
}
if (spn_gss_name != GSS_C_NO_NAME)
{
gss_release_name(&min_stat, &spn_gss_name);
}
gss_release_buffer(&min_stat, &output_token);
return base64_encoded_kerberos_token;
}
Related
Im trying to run some WMI queries using JACOB, and so far i've been successfull in getting the services and processes however i need to query the registry to see if a certain key is there
i've stummbled across this link
but i dont understand how to implement it
in order to query the services i've used the following code
ActiveXComponent wmi = null;
wmi = new ActiveXComponent("WbemScripting.SWbemLocator"); <-- side question what is the WbemScripting...
variantParameters[0] = new Variant("localhost");
variantParameters[1] = new Variant("root\\cimv2"); <-- what is this root?
String query = "Select ExitCode,Name,ProcessId,StartMode,State,Status from Win32_Service where State='Running' and Name='MSDTC'";
Variant vCollection = wmiconnect
.invoke("ExecQuery", new Variant(query));
is there a place with decent documentation for this?
and how to implement queries on the registry?
Thanks
UPDATE
Im trying a new implementation where i try to call the StdRegProv
and i have the following code
int HKEY_LOCAL_MACHINE = 0x80000002;
String strKeyPath = "SYSTEM\\CurrentControlSet\\Services";
String [] sNames = new String [5];
ActiveXComponent wmi = new ActiveXComponent("WbemScripting.SWbemLocator");
// no connection parameters means to connect to the local machine
Variant variantParameters[] = new Variant[4];
variantParameters[0] = new Variant("192.168.1.2");
variantParameters[1] = new Variant("root\\default");
variantParameters[2] = new Variant("admin");
variantParameters[3] = new Variant("pass");
Dispatch services = wmi.invoke("ConnectServer", variantParameters).toDispatch();
Dispatch oReg = Dispatch.call(services, "Get", "StdRegProv").toDispatch();
Variant ret = Dispatch.call(oReg, "EnumKey", HKEY_LOCAL_MACHINE, strKeyPath, sNames);
System.out.println("EnumKey: HKEY_LOCAL_MACHINE\\"+strKeyPath+"="+ret);
I was hoping to get the sNames array filled with data but its just nulls
I was unable to do it with Jacob but succeeded using j-interop library
here is the code that cost me so much suffering
IJIAuthInfo authInfo = new JIDefaultAuthInfoImpl("remoteComputerIpAddress", "wmiUserName", "wmiUserPassword");
IJIWinReg registry = null;
try {
registry = JIWinRegFactory.getSingleTon().getWinreg(authInfo, "remoteComputerIpAddress", true);
JIPolicyHandle policyHandle = registry.winreg_OpenHKLM();
JIPolicyHandle policyHandle2 = registry.winreg_OpenKey(policyHandle, "SOFTWARE\\wisemon",
IJIWinReg.KEY_ALL_ACCESS);
// JIPolicyHandle policyHandle3 =
// registry.winreg_OpenKey(policyHandle2,"wisemon",IJIWinReg.KEY_ALL_ACCESS);
System.out.println("Printing first 1000 entries under HKEY_LOCAL_MACHINE\\BCD00000000...");
for (int i = 0; i < 1; i++) {
// String[] values = registry.winreg_EnumKey(policyHandle3,i);
// Object[] values = registry.winreg_EnumValue(policyHandle3,i);
Object[] values = registry.winreg_QueryValue(policyHandle2, "name", 100);
Object[] values2 = registry.winreg_QueryValue(policyHandle2, "date", 100);
System.out.println(new String((byte[]) values[1]));
System.out.println(new String((byte[]) values2[1]));
}
} catch (UnknownHostException | JIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("Closing registry connection");
registry.closeConnection();
}
I am using Java as back end to communicate with AWS Cognito. I am able to login, logout, create users, sign out and other functions. I am also able to verify an access token by following this link:
But I want to verify if a user is logged in or not.
In JAVA, is there a isLoggedin() function that returns a boolean or is there a way to see if the token is revoked? These functions exist for Android and iOS but what about JAVA.
I thought this verifies if the token is active, but it only verifies if the token is in the right format:
// This parses token to JWT.
JWT jwtparser = JWTParser.parse(accessToken);
String JWTissuer = jwtparser.getJWTClaimsSet().getIssuer();
JWSHeader header = (JWSHeader) jwtparser.getHeader();
Object token_use = jwtparser.getJWTClaimsSet().getClaim("token_use");
Object exp = jwtparser.getJWTClaimsSet().getClaim("iat");
Date expirationDate = jwtparser.getJWTClaimsSet().getExpirationTime();
// Read in JSON Key file saved somewhere safe
File file = new File("jwks.json");
String content = FileUtils.readFileToString(file, "utf-8");
JSONObject JsonObjects = new JSONObject(content);
JSONArray keysArray = JsonObjects.getJSONArray("keys");
JSONObject keyString = (JSONObject) keysArray.get(1);
if (header.getKeyID().equals(keyString.get("kid")) && token_use.toString().equals("access") && JWTissuer.equals("https://cognito-idp.us-west-2.amazonaws.com/us-west-2_xxxxxxx")) {
return true;
} else { return false; }
I want to see if a user is logged in. I have not found an appropriate method to do so.
Mahalo
I found a work around:
public boolean isLoggedin(String accessToken) {
GetUserRequest request = new GetUserRequest();
request.withAccessToken(accessToken);
AWSCognitoIdentityProviderClientBuilder builder =
AWSCognitoIdentityProviderClientBuilder.standard();
builder.withRegion("us-west-2");
AWSCognitoIdentityProvider cognitoCreate = builder.build();
GetUserResult result = cognitoCreate.getUser(request);
try {
System.out.println("success");
return true;
} catch (Exception e) {
e.getMessage();
return false;
}
}
I am using Android Studio 1.5.1 targeting Android API 18 (before Android KitKat 4.4, so I’m dealing with Dalvik, not ART runtime).
My questions are:
How to call the hidden Android method getTotalUss() using Java
reflection?
If not possible, how to find the current process USS (Unique Set Size) memory programmatically?
I am trying to use the code below to do that but I am getting a compiler error "Unexpected token" at the statement labelled //ERROR! below in the code.
ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
Map<Integer, String> pidMap = new TreeMap<Integer, String>();
for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses)
{
pidMap.put(runningAppProcessInfo.pid, runningAppProcessInfo.processName);
}
Collection<Integer> keys = pidMap.keySet();
int id= android.os.Process.myPid();
for(int key : keys)
{
if (key != id) continue;
int pids[] = new int[1];
int Uss;
pids[0] = key;
android.os.Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
for(android.os.Debug.MemoryInfo pidMemoryInfo: memoryInfoArray)
{
try {
Class c;
c = Class.forName("android.app.ActivityManager");
Method m = c.getMethod("getTotalUss", null);
Uss = m.invoke(null,int); // << == ERROR!
} catch (ClassNotFoundException e) {
}
catch (NoSuchMethodException e) {
}
catch (IllegalAccessException e) {
}
System.out.println("** Uss = " + Uss);
You're calling getMethod() on the ActivityManager class which doesn't contain a getTotalUss() method. That's why you're getting the error.
Instead, you'll want to reflectively get the method from the MemoryInfo class which has the getTotalUss() method. You'll also want to be sure to pass pidMemoryInfo as the receiver to the invoke() call. It's like calling pidMemoryInfo.getTotalUss().
Method m = android.os.Debug.MemoryInfo.class.getMethod("getTotalUss", null);
totalUss = (int) m.invoke(pidMemoryInfo,(Object[]) null);
See the documentation on Method's invoke() for more details.
I am writing my first C# program and I want to check using C# code if I am running a 32 or 64 bit version of java ?
I tried this but when I add this code to my class I am not able to debug it
RegistryKey rk = Registry.LocalMachine;
RegistryKey subKey = rk.OpenSubKey("SOFTWARE\\JavaSoft\\Java Runtime Environment");
string currentVerion = subKey.GetValue("CurrentVersion").ToString();
How can I do it ?
Thanks
It isn't clear how you are going to identify which java.exe you are using - a single machine can have many installed. You may have a specific path, or you may need to either use the JAVA_HOME environment variable, or search PATH, or do a combination of both and give priority to one or the other depending on your requirements.
Once you've got your path to java.exe you can use the technique from Kris Stanton on MSDN (which I will repeat here, but is currently linked at MSDN > "Exploring pe file headers using managed code"):
public enum MachineType
{
Native = 0, I586 = 0x014c, Itanium = 0x0200, x64 = 0x8664
}
public static MachineType GetMachineType(string fileName)
{
// dos header is 64 bytes
// PE header address is 4 bytes
const int PE_PTR_OFFSET = 60;
const int MACHINE_OFFSET = 4;
byte[] data = new byte[4096];
using (Stream stm = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
stm.Read(data, 0, 4096);
}
int PE_HDR_ADDR = BitConverter.ToInt32(data, PE_PTR_OFFSET);
int machineUint = BitConverter.ToUInt16(data, PE_HDR_ADDR + MACHINE_OFFSET);
return (MachineType)machineUint;
}
To find java.exe on the %PATH% variable, you can call FindOnPath("java.exe"):
public static String FindOnPath(string exeName)
{
foreach (string test in (Environment.GetEnvironmentVariable("PATH") ?? "").Split(';'))
{
string path = test.Trim();
if (!String.IsNullOrEmpty(path) && File.Exists(path = Path.Combine(path, exeName)))
return Path.GetFullPath(path);
}
return null;
}
On my machine, the following code
static void Main(string[] args)
{
String path = FindOnPath("java.exe");
Console.WriteLine(path);
Console.WriteLine(GetMachineType(path));
}
writes the following output:
C:\ProgramData\Oracle\Java\javapath\java.exe
x64
You can do it through the registry. I knocked together a quick example for you:
private string GetJavaInstallationPath()
{
string environmentPath = Environment.GetEnvironmentVariable("JAVA_HOME");
if (!string.IsNullOrEmpty(environmentPath))
{
return environmentPath;
}
string javaKey = "SOFTWARE\\JavaSoft\\Java Runtime Environment\\";
using (Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(javaKey))
{
string currentVersion = rk.GetValue("CurrentVersion").ToString();
using (Microsoft.Win32.RegistryKey key = rk.OpenSubKey(currentVersion))
{
return key.GetValue("JavaHome").ToString();
}
}
}
Then to use it, just do the following:
string installPath = GetJavaInstallationPath();
string filePath = System.IO.Path.Combine(installPath, "bin\\Java.exe");
if (System.IO.File.Exists(filePath))
{
// We have a winner
}
I`m use this code:
public static bool CheckJavaInstallation()
{
try
{
//ProcessStartInfo procStartInfo = new ProcessStartInfo("java", " -version"); // Check that any Java installed
//ProcessStartInfo procStartInfo = new ProcessStartInfo("java", "-d32 -version"); // Check that 32 bit Java installed
ProcessStartInfo procStartInfo = new ProcessStartInfo("java", "-d64 -version"); // Check that 64 bit Java installed
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
Process proc = new Process {StartInfo = procStartInfo};
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
return proc.ExitCode == 0;
}
catch (Exception ex)
{
return false;
}
}
I'd like to monitor Informatica ETL Workflows from custom Java program, via informatica Development Platform (LMapi), v9.1
I already have got C program, it works fine, but it would be great port to Java.
We get a lot of C DLLs, with asynchronous functions e.g.: JavaLMApi.dll, INFA_LMMonitorServerA (with detailed event-log possibilities)
In header we can see:
PMLM_API_EXTSPEC INFA_API_STATUS
INFA_LMMonitorServerA
(
INFA_UINT32 connectionId,
struct INFA_LMAPI_MONITOR_SERVER_REQUEST_PARAMS *request,
void *clientContext,
INFA_UINT32 *requestId
);
There is no any documentation for this problem, only with this information should I use for soulution.
The question is: how to call/use INFA_LMMonitorServerA in Java? (Dll-load with JNA/JNI is not problem, only the callback).
static INFA_UINT32 nConnectionId = 0;
/* C-"skeleton": */
void GetSrvDetailcallback(struct INFA_API_REPLY_CONTEXT* GetSrvDetailReplyCtxt)
{
INFA_API_STATUS apiRet;
struct INFA_LMAPI_SERVER_DETAILS *serverDetails = NULL;
char *serverStatus = NULL;
/* Check if the return status is Acknowledgement */
if (GetSrvDetailReplyCtxt->returnStatus == INFA_REQUEST_ACKNOWLEDGED)
{
fprintf(stdout, "\nINFA REQUEST ACKNOWLEDGED \n\n",NULL);
return;
}
apiRet = INFA_LMGetServerDetailsResults(GetSrvDetailReplyCtxt, &serverDetails);
/* Check the return code if if is an error */
if (INFA_SUCCESS != apiRet)
{
fprintf(stderr, "Error: INFA_LMGetServerDetailsResults returns %d\n", apiRet);
return;
}
printResults(serverDetails);
}
static void myServer()
{
struct INFA_LMAPI_CONNECT_SERVER_REQUEST_PARAMS_EX connectParamsex;
INFA_API_STATUS apiRet;
struct INFA_LMAPI_LOGIN_REQUEST_PARAMS loginparams;
apiRet = INFA_LMLogin(nConnectionId, &loginparams, NULL);
if (INFA_SUCCESS != apiRet)
{
fprintf(stderr, "Error: INFA_LMLogin returns %d\n", apiRet);
return;
}
struct INFA_LMAPI_MONITOR_SERVER_REQUEST_PARAMS strMonitorRequestParams;
//Only Running Tasks
strMonitorRequestParams.monitorMode = INFA_LMAPI_MONITOR_RUNNING;
strMonitorRequestParams.continuous = INFA_TRUE;
/* Get Server Details */
INFA_UINT32 GetSrvDetailsrequestId = 0;
/* Register a callback function. */
INFA_LMRegisterCallback(INFA_LMAPI_MONITOR_SERVER, &GetSrvDetailcallback);
apiRet = INFA_LMMonitorServerA(nConnectionId, &strMonitorRequestParams, NULL, &GetSrvDetailsrequestId);
if (INFA_SUCCESS != apiRet && INFA_REQUEST_PENDING != apiRet)
{
fprintf(stderr, "Error: INFA_LMMonitorServerA returns %d\n", apiRet);
return;
}
}