[Cvsnt] gserver impersonation

Brian Smith brian-l-smith at uiowa.edu
Tue Feb 26 11:11:40 GMT 2002


This is a multi-part message in MIME format.
--
Tony,

My work is coming along okay. I actually threw away my old patch and I'm
using your SSPI (not gssapi_win32, but the SSPI.C) to do the Kerberos
authentication. Actually, by changing your hard-coded "NTLM" to
"Kerberos" and making a few other minor changes, I was able to accept a
non-encrypted connection from a linux client in :gserver: mode with the
code. The modifications were really trivial:

1. Instead of writing 32-bit machine-dependent integers for the token
length, I am writing 16-bit network-byte-order integers just like
:gserver: expects.

2. I changed all the hard-coded "NTLM" to "Kerberos". Actually, in my
current codebase, I have the server auto-detecting Kerberos vs. NTLM by
inspecting the "BEGIN xxx REQUEST" header.

The problem I am having right now is that DecryptMessage won't decrypt a
wrapped sent by the linux client with "cvs -x" or "cvs -a". I am afraid
that it might be because of an interoperability problem between MIT
Kerberos and Windows 2000 Active Directory. I will need to do some more
testing by having a fully-Active-Directorized client connecting with
Kerberos (right now I've just been testing with cvs 1.11.1p1/MIT
Kerberos on Linux as the client).

I have a couple of suggestions for changes before you release a "gold"
version of CVSNT 1.1.11.3:

(1) Please use 16-bit network-byte-order integers for token sizes in
SSPI mode, as mentioned above. This will let me re-use all of that code
for the Active-Directory-enabled gserver code. I have included some
helper code to do this at the bottom of the email; it is part of my
current codebase. I can send a real patch later this week if you'd like.
I think it it best to do this now since so that you don't have to break
production versions later.

(3) Please change the name of "SSPI" mode to "NTLM" mode. The reason is
that, as far as the protocol is concerned, you are using NTLM; SSPI is
just an API that happens to support NTLM. This was a mistake that was
made a long time ago with CVS: Since GSS-API is just a generic library
(like SSPI), there is no guarentee that the client is using the same
protocol that the server is using, even if both of them are using
GSS-API. There is also no way to negotiate a "flavor" of GSS-API in the
CVS protocol. Instead, the client user and the server user have to
standardize on one GSS-API implementation ahead of time. For example,
the client could be using GSI instead of Kerberos, and the server could
be using Kerberos. In this case, it won't work. It is even worse because
the server might support Kerberos AND GSI, but it won't be able to tell
what protocol the client is using because the client is just saying
"GSSAPI". The same reasoning applies to SSPI mode. (In fact, in the
current CVS code, when it says "GSS-API" it means "Kerberos" since
gserver has Kerberos-specific code in it. At least that is true in the
current CVSNT version; there are patches floating around the internet
for CVS to work with GSI and also non-MIT kerberos GSS-API
implementations). Similarly, using SSPI, the client might be using NTLM
while the server is expecting Kerberos or the client might send Kerberos
credentials to an NTLM-only (4.0) server.

Thanks,
Brian

--
void delete_tok_buffer(SecBuffer * b) {
	assert(b != NULL);
	if (b->pvBuffer) {
		free(b->pvBuffer);
		b->pvBuffer = NULL;
	}
}

/* new_tok_buffer does not attempt to free the memory */
void new_tok_buffer(SecBuffer * b, unsigned int size) {
	assert(b != NULL);
	b->cbBuffer = size;
	b->pvBuffer = malloc(size);
	if (b->pvBuffer == NULL)
		server_error(1, "out of memory");
}

/* read_tok fills ib with the token from the stream. read_tok allocates
   the memory for ib->pvBuffer */
void read_tok(SecBuffer * ib) {
	char cbuf[2];
	int rc;
	int bytesReceived = 2;
	int n;
	char * p;

	assert(ib != NULL);
    if (fread (cbuf, 1, 2, stdin) != 2)
		server_error (1, "read of length failed");

	new_tok_buffer(ib, ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff));

	p = (char *) ib->pvBuffer;
	n = ib->cbBuffer;
	while (n > 0)
	{
		rc = fread( (char *) p, 1, n, stdin);
		if(rc<=0)
			break;
		bytesReceived += rc;
		n -= rc;
		p += rc;
	}
	if (bytesReceived != 2 + ib->cbBuffer)
		server_error(1, "couldn't read input token"); // BLS-TODO:
}
--

_______________________________________________
Cvsnt mailing list
Cvsnt at cvsnt.org
http://www.cvsnt.org/cgi-bin/mailman/listinfo/cvsnt



More information about the cvsnt mailing list