Different realms

Imanuel Greenfeld imanuel.greenfeld1 at ntlworld.com
Tue Jan 30 16:28:31 EST 2018


Thank you Todd.

 

Appreciated.

 

I understand everything you are saying, but I think you misunderstand me.

 

So I'm re-sending you the existing code.  Any ideas how this needs to change so that I can authenticate ?  For example, do I need to encrypt the JSON message before calling json_call ?

 

 

struct SOAP_ENV__Header

{

    struct ns3__Header *ns3__MyHeader; };

 

struct ns3__Header

{

    char *Username;    

    char *Password;

};

 

soap * mysoap = soap_new1(SOAP_C_UTFSTRING); soap_init(&mysoap); mysoap.header = (SOAP_ENV__Header *)soap_malloc(&mysoap, sizeof(SOAP_ENV__Header)); mysoap.header->ns3__MyHeader = (ns3__Header*)malloc(sizeof(ns3__Header));

 

 

/******  I know that hard coding username and password is contrary to Kerberos but I'm just trying to see if I can pass the authentication. ******/

 

mysoap.header->ns3__MyHeader->Username = (char*)malloc(10 * sizeof(char));

strcpy(mysoap.header->ns3__MyHeader-> Username,  "<username>");                                                                      

 

mysoap.header->ns3__MyHeader-> Password = (char*)malloc(10 * sizeof(char)); 

strcpy(mysoap.header->ns3__MyHeader-> Password,  "<password>");

 

const char *endpointURL = "http://...";

value request(mysoap), response(mysoap);   

 

... // now populate the request data to send

request[0] = ...;                

request[1] = ...;                

 

if (json_call(mysoap, endpointURL, request, response)) {

  ... // use response value

}

 

 

Thank you.

 

Imanuel.

 

 

From: Todd Grayson [mailto:tgrayson at cloudera.com] 
Sent: 28 January 2018 21:30
To: Imanuel Greenfeld <imanuel.greenfeld1 at ntlworld.com>
Cc: Robbie Harwood <rharwood at redhat.com>; kerberos at MIT.EDU; Simo Sorce <simo at redhat.com>
Subject: Re: Different realms

 

Imanuel,

 

You are describing a custom implementation of some sort, or we are confusing terminology of "Service ticket" vs "Kerberos Keytab".

 

  I'm afraid what you are describing is flawed in its premise that a kerberos keytab is ever actually "presented" over the wire in the way you are detailing.  A service ticket is what is conveyed, and each side uses its respective kerberos authentication and Ticket Granting Ticket, Service Ticket and in the case of multi-realm, the cross realm trust kerberos principal which is based on a shared secret (key, which is a password encrypted by agreed upon encryption types).

 

I hope (given your CC of the redhat team member) that you are not describing something you are attempting to code within the keycloak implementation or something similar to that.  Keycloak plays by the same SPNEGO authentication rules as well.

 

http://blog.keycloak.org/2015/04/kerberos-support-in-keycloak.html 

 

This might be an important read to get through so we are all discussing the same contexts along with that keycloak discussion.

 

https://msdn.microsoft.com/en-us/library/ms995331.aspx

 

The HTTP 401 response is to direct a client to begin negotiating authentication, with kerberos SPNEGO being an example of what can be done (Windows NTLM authentication, etc).  The HTTP 401 error would be indicating the client failed to properly negotiate authentication on its side and is most likely properly set up session context in its response to the server. 

 

If things work with setting up negotiation but then an error occurs (HTTP 403 error) processing the response,, this can take place for a number of reasons.   The 403 error can be based on  issues with encryption types in use, or other failures at the mechanism layer. 

 

Understand you would never transmit a keytab in that way over the wire.  

 

The service ticket would be espressed as a SPNEGO token for authentication and maintained throughout the client interaction.  The cross realm trust in the background, and the cross realm principal and its shared key (password) and common encryption types allow both sides of the connection to validate the token being exchanged. 

 

It would defeat the kerberos security design to present a kerberos keytab over the wire. Service ticket would be what gets presented by a client to a kerberos authenticated service, and SPNEGO describes that process implemented over HTTP.  Cross realm trust is fundamental to things working.  The presentation of a keytab that is not related to a KDC realm the actual service is running in is not going to work. 

 

Datafusion had a really good wiki page covering this in a visual way, unfortunately it looks like that site is down, but the internet wayback archives still have it.  This does a good job of breaking down the logic of the kerberos authentication model in a visual way...  SPNEGO is HTTP based kerberos authentication using the Service Principal Negotiated authentication mechanism that builds on top of these concepts.   This gives a visual breakdown of the lengths the kerberos protocol, and its use over HTTP, go towards to NEVER transmit a password or keytab representation of a password) over the network.  

 

https://web.archive.org/web/20170215124230/http://dfusion.com.au/wiki/tiki-index.php?page=Kerberos+Tutorial <https://web.archive.org/web/20170215124230/http:/dfusion.com.au/wiki/tiki-index.php?page=Kerberos+Tutorial> 

 

On Sun, Jan 28, 2018 at 4:17 AM, Imanuel Greenfeld <imanuel.greenfeld1 at ntlworld.com <mailto:imanuel.greenfeld1 at ntlworld.com> > wrote:

Thanks Robbie.

Noted.

Ok, let me explain so that all is clear :-

I'm not on Java, I'm on C++.

I am trying to send HTTP request from machine_a (client) to machine_b
(server) and these 2 realms have no trust between them.

I found a way to get this to work with Java, but I am on C++.  So in Java,
there is a way to add the keytab to the HTTP request and all works ok.  Java
does it like this :-

public void doWithKeytabFile() {
    KerberosRestTemplate restTemplate =
            new KerberosRestTemplate("/tmp/user2.keytab",
"user2 at EXAMPLE.ORG <mailto:user2 at EXAMPLE.ORG> ");
    restTemplate.getForObject("http://neo.example.org:8080/hello",
String.class);
}

As you can see the HTTP request just has one "endpoint" so the keytab needs
to be part of it.

But in C++ I cannot find a way how to achieve the same - in other words,
once I have the keytab in the code, and I separately build the HTTP request,
how do I incorporate that keytab to that HTTP request ?

I can only change the client code - the server code is not available to me.

Once again, I'm trying to find C/C++ good example.

Can you help ?

Many thanks

Imanuel.


-----Original Message-----
From: Robbie Harwood [mailto:rharwood at redhat.com <mailto:rharwood at redhat.com> ]
Sent: 28 January 2018 09:31
To: Imanuel Greenfeld <imanuel.greenfeld1 at ntlworld.com <mailto:imanuel.greenfeld1 at ntlworld.com> >; kerberos at mit.edu <mailto:kerberos at mit.edu> 
Cc: 'Simo Sorce' <simo at redhat.com <mailto:simo at redhat.com> >

Subject: RE: Different realms

"Imanuel Greenfeld" <imanuel.greenfeld1 at ntlworld.com <mailto:imanuel.greenfeld1 at ntlworld.com> > writes:

> Robbie Harwood <rharwood at redhat.com <mailto:rharwood at redhat.com> > writes:
>> "Imanuel Greenfeld" <imanuel.greenfeld1 at ntlworld.com <mailto:imanuel.greenfeld1 at ntlworld.com> > writes:
>>
>>> I have 2 domains which there is no trust between them.
>>
>> Do you have two realms (A and B), with two machines (machine_a in A,
>> and machine_b in B), and two services (service_a on machine_a, and
>> service_b on machine_b)?
>
> Yes
>
>> I'm not overly familiar with the Java bindings, but this isn't
>> something one really wants to be doing in Kerberos.
>
> So how can I pass the Kerberos authentication is there is no trust
> between the realms ?

Without a trust, service_a has no way to *prove* to service_b the identity
of the user who is connecting to service_a.

Now, depending on what you're doing, this may not matter - maybe whatever
service_b is doing doesn't care about that.  If that's the case, then
service_a just needs a credential to authenticate against service_b with.
(This will come from realm B.)

For making Kerberized HTTP requests, the best approach is, as Simo says, to
use something like mod_auth_gssapi on the server.  You're in Java, not
Python, on the client, so you won't be able to use requests-gssapi; I'm not
sure if there is a SPNEGO module for Java.

You can, however, look at how the token is generated by requests-gssapi and
make similar GSSAPI calls from Java - the function is
generate_request_header()
https://github.com/pythongssapi/requests-gssapi/blob/master/requests_gssapi/ <https://github.com/pythongssapi/requests-gssapi/blob/master/requests_gssapi/gssapi_.py#L139-L150> 
gssapi_.py#L139-L150
https://github.com/pythongssapi/requests-gssapi/blob/master/requests_gssapi/ <https://github.com/pythongssapi/requests-gssapi/blob/master/requests_gssapi/gssapi_.py#L63> 
gssapi_.py#L63

>> What is the actual, higher level thing you are trying to accomplish?
>
> As explained, I'm sending HTTP rest JSON request from machine_a to
> machine_b endpoint but I'm getting Unauthorised 401 error, so I'm
> trying to incorporate into the HTTP JSON request the keytab which is
> on machine_a to pass the authentication.

Let me ask a different way.  Why are you doing this at all?

On another note: your email replies are very difficult to read.  At the very
least, please use blank lines to separate your replies from the text you are
replying to, and make your quoting levels work correctly.

Thanks,
--Robbie

________________________________________________
Kerberos mailing list           Kerberos at mit.edu <mailto:Kerberos at mit.edu> 
https://mailman.mit.edu/mailman/listinfo/kerberos





 

-- 

Todd Grayson

Business Operations Manager

Customer Operations Engineering

Security SME

  <http://files.cloudera.com.s3.amazonaws.com/New%20Branding/cloudera-small.png> 



More information about the Kerberos mailing list