static XdmClientAuthPtr XdmAuthorizationValidate (unsigned char *plain, int length, XdmAuthKeyPtr rho, ClientPtr xclient, const char **reason) { XdmClientAuthPtr client, existing; long now; int i; if (length != (192 / 8)) { if (reason) *reason = "Bad XDM authorization key length"; return NULL; } client = malloc(sizeof (XdmClientAuthRec)); if (!client) return NULL; XdmClientAuthDecode (plain, client); if (!XdmcpCompareKeys (&client->rho, rho)) { free(client); if (reason) *reason = "Invalid XDM-AUTHORIZATION-1 key (failed key comparison)"; return NULL; } for (i = 18; i < 24; i++) if (plain[i] != 0) { free(client); if (reason) *reason = "Invalid XDM-AUTHORIZATION-1 key (failed NULL check)"; return NULL; } if (xclient) { int family, addr_len; Xtransaddr *addr; if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn, &family, &addr_len, &addr) == 0 && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) { #if defined(TCPCONN) || defined(STREAMSCONN) if (family == FamilyInternet && memcmp((char *)addr, client->client, 4) != 0) { free(client); free(addr); if (reason) *reason = "Invalid XDM-AUTHORIZATION-1 key (failed address comparison)"; return NULL; } #endif free(addr); } } now = time(0); if (!gotClock) { clockOffset = client->time - now; gotClock = TRUE; } now += clockOffset; XdmClientAuthTimeout (now); if (abs (client->time - now) > TwentyMinutes) { free(client); if (reason) *reason = "Excessive XDM-AUTHORIZATION-1 time offset"; return NULL; } for (existing = xdmClients; existing; existing=existing->next) { if (XdmClientAuthCompare (existing, client)) { free(client); if (reason) *reason = "XDM authorization key matches an existing client!"; return NULL; } } return client; }
char * ClientAuthorized(ClientPtr client, unsigned int proto_n, char *auth_proto, unsigned int string_n, char *auth_string) { OsCommPtr priv; Xtransaddr *from = NULL; int family; int fromlen; XID auth_id; char *reason = NULL; XtransConnInfo trans_conn; priv = (OsCommPtr)client->osPrivate; trans_conn = priv->trans_conn; /* Allow any client to connect without authorization on a launchd socket, because it is securely created -- this prevents a race condition on launch */ if(trans_conn->flags & TRANS_NOXAUTH) { auth_id = (XID) 0L; } else { auth_id = CheckAuthorization (proto_n, auth_proto, string_n, auth_string, client, &reason); } if (auth_id == (XID) ~0L) { if (_XSERVTransGetPeerAddr(trans_conn, &family, &fromlen, &from) != -1) { if (InvalidHost ((struct sockaddr *) from, fromlen, client)) AuthAudit(client, FALSE, (struct sockaddr *) from, fromlen, proto_n, auth_proto, auth_id); else { auth_id = (XID) 0; #ifdef XSERVER_DTRACE if ((auditTrailLevel > 1) || XSERVER_CLIENT_AUTH_ENABLED()) #else if (auditTrailLevel > 1) #endif AuthAudit(client, TRUE, (struct sockaddr *) from, fromlen, proto_n, auth_proto, auth_id); } xfree (from); } if (auth_id == (XID) ~0L) { if (reason) return reason; else return "Client is not authorized to connect to Server"; } } #ifdef XSERVER_DTRACE else if ((auditTrailLevel > 1) || XSERVER_CLIENT_AUTH_ENABLED()) #else else if (auditTrailLevel > 1) #endif { if (_XSERVTransGetPeerAddr (trans_conn, &family, &fromlen, &from) != -1) { AuthAudit(client, TRUE, (struct sockaddr *) from, fromlen, proto_n, auth_proto, auth_id); xfree (from); } } priv->auth_id = auth_id; priv->conn_time = 0; #ifdef XDMCP /* indicate to Xdmcp protocol that we've opened new client */ XdmcpOpenDisplay(priv->fd); #endif /* XDMCP */ XaceHook(XACE_AUTH_AVAIL, client, auth_id); /* At this point, if the client is authorized to change the access control * list, we should getpeername() information, and add the client to * the selfhosts list. It's not really the host machine, but the * true purpose of the selfhosts list is to see who may change the * access control list. */ return((char *)NULL); }