mirror of
https://github.com/bstansell/conserver.git
synced 2024-12-19 04:47:53 +00:00
Increase buffer size for GSSAPI exchanges
Kerberos ticket may include additional authorization data (AD) information. With MIT Kerberos 1.21 a minimal PAC AD is included. In Active Directory or FreeIPA environments where a full PAC AD is available, the size of Kerberos ticket may be up to 64Kb. Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
parent
47c232b881
commit
8e3b84789d
@ -89,6 +89,7 @@ typedef struct client { /* Connection Information: */
|
||||
FLAG confirmed; /* confirm state */
|
||||
CLIENTSTATE cState; /* state needing confirmation */
|
||||
char cOption; /* option initiating the confirmation */
|
||||
size_t tokenSize; /* buffer size for GSSAPI token */
|
||||
} CONSCLIENT;
|
||||
|
||||
extern void Replay(CONSENT *, CONSFILE *, unsigned short);
|
||||
|
@ -1964,13 +1964,19 @@ int
|
||||
AttemptGSSAPI(CONSCLIENT *pCL)
|
||||
{
|
||||
int nr, ret = 0;
|
||||
char buf[1024];
|
||||
char *buf = NULL;
|
||||
gss_buffer_desc sendtok, recvtok, dbuf;
|
||||
gss_ctx_id_t gssctx = GSS_C_NO_CONTEXT;
|
||||
OM_uint32 stmaj, stmin, mctx, dmin;
|
||||
gss_name_t user = 0;
|
||||
|
||||
if ((nr = FileRead(pCL->fd, buf, sizeof(buf))) <= 0) {
|
||||
buf = malloc(pCL->tokenSize);
|
||||
if (buf == NULL) {
|
||||
Error("Unable to allocate a buffer for GSSAPI token");
|
||||
return -1;
|
||||
}
|
||||
if ((nr = FileRead(pCL->fd, buf, pCL->tokenSize)) <= 0) {
|
||||
free(buf);
|
||||
return nr;
|
||||
}
|
||||
recvtok.value = buf;
|
||||
@ -2009,6 +2015,8 @@ AttemptGSSAPI(CONSCLIENT *pCL)
|
||||
Error("GSSAPI didn't work, %*s", dbuf.length, dbuf.value);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@ -3097,12 +3105,31 @@ DoClientRead(GRPENT *pGE, CONSCLIENT *pCLServing)
|
||||
}
|
||||
#endif
|
||||
#if HAVE_GSSAPI
|
||||
#define MAX_GSSAPI_TOKSIZE 64*1024
|
||||
} else if (pCLServing->iState == S_IDENT &&
|
||||
strcmp(pcCmd, "gssapi") == 0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", -1);
|
||||
/* Change the I/O mode right away, we'll do the read
|
||||
* and accept when the select gets back to us */
|
||||
pCLServing->ioState = INGSSACCEPT;
|
||||
if (pcArgs == (char *)0) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"gssapi requires argument\r\n", -1);
|
||||
} else {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "ok\r\n", -1);
|
||||
/* Read the token size but limit it to 64K,
|
||||
* that's practical limit for GSSAPI krb5 mechanism.
|
||||
*
|
||||
* The client connection will be rejected for large
|
||||
* requests as server will not be able to parse
|
||||
* incomplete ASN.1 but this is intentional. */
|
||||
pCLServing->tokenSize = (size_t) strtol(pcArgs, NULL, 10);
|
||||
if (pCLServing->tokenSize > MAX_GSSAPI_TOKSIZE) {
|
||||
FileWrite(pCLServing->fd, FLAGFALSE,
|
||||
"gssapi token size too large\r\n", -1);
|
||||
pCLServing->tokenSize = MAX_GSSAPI_TOKSIZE;
|
||||
}
|
||||
|
||||
/* Change the I/O mode right away, we'll do the read
|
||||
* and accept when the select gets back to us */
|
||||
pCLServing->ioState = INGSSACCEPT;
|
||||
}
|
||||
#endif
|
||||
} else if (pCLServing->iState == S_IDENT &&
|
||||
strcmp(pcCmd, "login") == 0) {
|
||||
|
@ -167,11 +167,12 @@ AttemptSSL(CONSFILE *pcf)
|
||||
#endif
|
||||
|
||||
#if HAVE_GSSAPI
|
||||
#define MAX_GSSAPI_TOKSIZE 64*1024
|
||||
gss_name_t gss_server_name = GSS_C_NO_NAME;
|
||||
gss_ctx_id_t secctx = GSS_C_NO_CONTEXT;
|
||||
gss_buffer_desc mytok = GSS_C_EMPTY_BUFFER;
|
||||
|
||||
int
|
||||
size_t
|
||||
CanGetGSSContext(const char *servername)
|
||||
{
|
||||
char namestr[128];
|
||||
@ -208,18 +209,22 @@ CanGetGSSContext(const char *servername)
|
||||
}
|
||||
|
||||
int
|
||||
AttemptGSSAPI(CONSFILE *pcf)
|
||||
AttemptGSSAPI(CONSFILE *pcf, size_t toksize)
|
||||
{
|
||||
OM_uint32 stmaj, stmin;
|
||||
gss_buffer_desc servertok;
|
||||
char buf[1024];
|
||||
char *buf = NULL;
|
||||
int nr;
|
||||
int ret;
|
||||
|
||||
buf = malloc(toksize);
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
FileSetQuoteIAC(pcf, FLAGFALSE);
|
||||
FileWrite(pcf, FLAGFALSE, mytok.value, mytok.length);
|
||||
FileSetQuoteIAC(pcf, FLAGTRUE);
|
||||
nr = FileRead(pcf, buf, sizeof(buf));
|
||||
nr = FileRead(pcf, buf, toksize);
|
||||
servertok.length = nr;
|
||||
servertok.value = buf;
|
||||
|
||||
@ -233,6 +238,7 @@ AttemptGSSAPI(CONSFILE *pcf)
|
||||
|
||||
ret = (stmaj == GSS_S_COMPLETE);
|
||||
gss_release_name(&stmin, &gss_server_name);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@ -1586,7 +1592,7 @@ DoCmds(char *master, char *pports, int cmdi)
|
||||
char *pcopy;
|
||||
char *serverName;
|
||||
#if HAVE_GSSAPI
|
||||
int toksize;
|
||||
size_t toksize;
|
||||
#endif
|
||||
|
||||
if ((pcopy = ports = StrDup(pports)) == (char *)0)
|
||||
@ -1671,10 +1677,16 @@ DoCmds(char *master, char *pports, int cmdi)
|
||||
#endif
|
||||
#if HAVE_GSSAPI
|
||||
if ((toksize = CanGetGSSContext(server)) > 0) {
|
||||
if (toksize > MAX_GSSAPI_TOKSIZE) {
|
||||
Error("Maximum support GSSAPI token size is %lu, "
|
||||
"GSSAPI context creation reported %lu. "
|
||||
"Server will reject authentication.",
|
||||
MAX_GSSAPI_TOKSIZE, toksize);
|
||||
}
|
||||
FilePrint(pcf, FLAGFALSE, "gssapi %d\r\n", toksize);
|
||||
t = ReadReply(pcf, FLAGFALSE);
|
||||
if (strcmp(t, "ok\r\n") == 0) {
|
||||
if (AttemptGSSAPI(pcf)) {
|
||||
if (AttemptGSSAPI(pcf, toksize)) {
|
||||
goto gssapi_logged_me_in;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user