Example #1
0
ARRAY8Ptr
IndirectChoice (
    ARRAY8Ptr   clientAddress,
    CARD16      connectionType)
{
    ChoicePtr	c, next, prev;
    long	now;

    now = time (0);
    prev = 0;
    for (c = choices; c; c = next)
    {
	next = c->next;
	if (now - c->time > 15)
	{
	    Debug ("Timeout choice\n");
	    if (prev)
		prev->next = next;
	    else
		choices = next;
	    XdmcpDisposeARRAY8 (&c->client);
	    XdmcpDisposeARRAY8 (&c->choice);
	    free ((char *) c);
	}
	else
	{
	    if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
	    	connectionType == c->connectionType)
	    	return &c->choice;
	    prev = c;
	}
    }
    return 0;
}
Example #2
0
static void
recv_decline_msg(unsigned length)
{
    ARRAY8  status, DeclineAuthenticationName, DeclineAuthenticationData;

    status.data = 0;
    DeclineAuthenticationName.data = 0;
    DeclineAuthenticationData.data = 0;
    if (XdmcpReadARRAY8 (&buffer, &status) &&
	XdmcpReadARRAY8 (&buffer, &DeclineAuthenticationName) &&
	XdmcpReadARRAY8 (&buffer, &DeclineAuthenticationData))
    {
    	if (length == 6 + status.length +
		      	  DeclineAuthenticationName.length +
 		      	  DeclineAuthenticationData.length &&
	    XdmcpCheckAuthentication (&DeclineAuthenticationName,
				      &DeclineAuthenticationData, DECLINE))
    	{
	    XdmcpFatal ("Session declined", &status);
    	}
    }
    XdmcpDisposeARRAY8 (&status);
    XdmcpDisposeARRAY8 (&DeclineAuthenticationName);
    XdmcpDisposeARRAY8 (&DeclineAuthenticationData);
}
Example #3
0
static int
RegisterIndirectChoice (
    ARRAY8Ptr   clientAddress,
    CARD16 connectionType,
    ARRAY8Ptr   choice)
{
    ChoicePtr	c;
    int		insert;
    int		found;

    Debug ("Got indirect choice back (%s)\n", Print8Address(clientAddress));
    for (c = choices; c; c = c->next) {
	if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
	    connectionType == c->connectionType) {
	    found = 1;
	    break;
	}
    }
    if (!found)
	return 0;

    insert = 0;

    if (!c)
    {
	c = (ChoicePtr) malloc (sizeof (ChoiceRec));
	insert = 1;
	if (!c)
	    return 0;
	c->connectionType = connectionType;
    	if (!XdmcpCopyARRAY8 (clientAddress, &c->client))
    	{
	    free ((char *) c);
	    return 0;
    	}
    }
    else
    {
	XdmcpDisposeARRAY8 (&c->choice);
    }

    if (!XdmcpCopyARRAY8 (choice, &c->choice))
    {
	XdmcpDisposeARRAY8 (&c->client);
	free ((char *) c);
	return 0;
    }
    if (insert)
    {
	c->next = choices;
	choices = c;
    }
    c->time = time (0);

    Debug("choice=(%s)\n", Print8Address(choice)); 

    return 1;
}
Example #4
0
static void
recv_accept_msg(unsigned length)
{
    CARD32  AcceptSessionID;
    ARRAY8  AcceptAuthenticationName, AcceptAuthenticationData;
    ARRAY8  AcceptAuthorizationName, AcceptAuthorizationData;

    if (state != XDM_AWAIT_REQUEST_RESPONSE)
	return;
    AcceptAuthenticationName.data = 0;
    AcceptAuthenticationData.data = 0;
    AcceptAuthorizationName.data = 0;
    AcceptAuthorizationData.data = 0;
    if (XdmcpReadCARD32 (&buffer, &AcceptSessionID) &&
	XdmcpReadARRAY8 (&buffer, &AcceptAuthenticationName) &&
	XdmcpReadARRAY8 (&buffer, &AcceptAuthenticationData) &&
	XdmcpReadARRAY8 (&buffer, &AcceptAuthorizationName) &&
	XdmcpReadARRAY8 (&buffer, &AcceptAuthorizationData))
    {
    	if (length == 12 + AcceptAuthenticationName.length +
		      	   AcceptAuthenticationData.length +
		      	   AcceptAuthorizationName.length +
 		      	   AcceptAuthorizationData.length)
    	{
	    if (!XdmcpCheckAuthentication (&AcceptAuthenticationName,
				      &AcceptAuthenticationData, ACCEPT))
	    {
		XdmcpFatal ("Authentication Failure", &AcceptAuthenticationName);
	    }
	    /* permit access control manipulations from this host */
	    AugmentSelf (&req_sockaddr, req_socklen);
	    /* if the authorization specified in the packet fails
	     * to be acceptable, enable the local addresses
	     */
	    if (!XdmcpAddAuthorization (&AcceptAuthorizationName,
					&AcceptAuthorizationData))
	    {
		AddLocalHosts ();
	    }
	    SessionID = AcceptSessionID;
    	    state = XDM_MANAGE;
    	    send_packet();
    	}
    }
    XdmcpDisposeARRAY8 (&AcceptAuthenticationName);
    XdmcpDisposeARRAY8 (&AcceptAuthenticationData);
    XdmcpDisposeARRAY8 (&AcceptAuthorizationName);
    XdmcpDisposeARRAY8 (&AcceptAuthorizationData);
}
Example #5
0
static void all_query_respond(struct sockaddr *from, int fromlen, ARRAYofARRAY8Ptr authenticationNames, xdmOpCode type, int fd)
{
    ARRAY8Ptr authenticationName;
    ARRAY8 status;
    ARRAY8 addr;
    CARD16 connectionType;
    int family;
    int length;

    family = ConvertAddr((XdmcpNetaddr)from, &length, &(addr.data));
    addr.length = length; /* convert int to short */
    Debug("all_query_respond: conntype=%d, addr=%02[*:hhx\n", family, addr.length, addr.data);
    if(family < 0)
        return;
    connectionType = family;

    if(type == INDIRECT_QUERY)
        RememberIndirectClient(&addr, connectionType);
    else
        ForgetIndirectClient(&addr, connectionType);

    authenticationName = ChooseAuthentication(authenticationNames);
    if(Willing(&addr, connectionType, authenticationName, &status, type))
        send_willing(from, fromlen, authenticationName, &status, fd);
    else if(type == QUERY)
        send_unwilling(from, fromlen, authenticationName, &status, fd);
    XdmcpDisposeARRAY8(&status);
}
Example #6
0
static void indirect_respond(struct sockaddr *from, int fromlen, int length, int fd)
{
    ARRAYofARRAY8 queryAuthenticationNames;
    ARRAY8 clientAddress;
    ARRAY8 clientPort;
    CARD16 connectionType;
    int expectedLen;
    int i;
    XdmcpHeader header;
    int localHostAsWell;

    Debug("<indirect> respond %d\n", length);
    if(!XdmcpReadARRAYofARRAY8(&buffer, &queryAuthenticationNames))
        return;
    expectedLen = 1;
    for(i = 0; i < (int)queryAuthenticationNames.length; i++)
        expectedLen += 2 + queryAuthenticationNames.data[i].length;
    if(length == expectedLen)
    {
        ClientAddress(from, &clientAddress, &clientPort, &connectionType);
        /*
         * set up the forward query packet
         */
        header.version = XDM_PROTOCOL_VERSION;
        header.opcode = (CARD16)FORWARD_QUERY;
        header.length = 0;
        header.length += 2 + clientAddress.length;
        header.length += 2 + clientPort.length;
        header.length += 1;
        for(i = 0; i < (int)queryAuthenticationNames.length; i++)
            header.length += 2 + queryAuthenticationNames.data[i].length;
        XdmcpWriteHeader(&buffer, &header);
        XdmcpWriteARRAY8(&buffer, &clientAddress);
        XdmcpWriteARRAY8(&buffer, &clientPort);
        XdmcpWriteARRAYofARRAY8(&buffer, &queryAuthenticationNames);

        localHostAsWell = ForEachMatchingIndirectHost(&clientAddress, connectionType, sendForward, (char *)fd);

        XdmcpDisposeARRAY8(&clientAddress);
        XdmcpDisposeARRAY8(&clientPort);
        if(localHostAsWell)
            all_query_respond(from, fromlen, &queryAuthenticationNames, INDIRECT_QUERY, fd);
    }
    else
        Debug("<indirect> length error got %d expect %d\n", length, expectedLen);
    XdmcpDisposeARRAYofARRAY8(&queryAuthenticationNames);
}
Example #7
0
void
XdmcpRegisterAuthentication (
    char    *name,
    int	    namelen,
    char    *data,
    int	    datalen,
    ValidatorFunc Validator,
    GeneratorFunc Generator,
    AddAuthorFunc AddAuth)
{
    int	    i;
    ARRAY8  AuthenticationName, AuthenticationData;
    static AuthenticationFuncsPtr	newFuncs;

    if (!XdmcpAllocARRAY8 (&AuthenticationName, namelen))
	return;
    if (!XdmcpAllocARRAY8 (&AuthenticationData, datalen))
    {
	XdmcpDisposeARRAY8 (&AuthenticationName);
	return;
    }
    for (i = 0; i < namelen; i++)
	AuthenticationName.data[i] = name[i];
    for (i = 0; i < datalen; i++)
	AuthenticationData.data[i] = data[i];
    if (!(XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
				     AuthenticationNames.length + 1) &&
	  XdmcpReallocARRAYofARRAY8 (&AuthenticationDatas,
				     AuthenticationDatas.length + 1) &&
	  (newFuncs = (AuthenticationFuncsPtr) xalloc (
			(AuthenticationNames.length + 1) * sizeof (AuthenticationFuncsRec)))))
    {
	XdmcpDisposeARRAY8 (&AuthenticationName);
	XdmcpDisposeARRAY8 (&AuthenticationData);
	return;
    }
    for (i = 0; i < AuthenticationNames.length - 1; i++)
	newFuncs[i] = AuthenticationFuncsList[i];
    newFuncs[AuthenticationNames.length-1].Validator = Validator;
    newFuncs[AuthenticationNames.length-1].Generator = Generator;
    newFuncs[AuthenticationNames.length-1].AddAuth = AddAuth;
    xfree (AuthenticationFuncsList);
    AuthenticationFuncsList = newFuncs;
    AuthenticationNames.data[AuthenticationNames.length-1] = AuthenticationName;
    AuthenticationDatas.data[AuthenticationDatas.length-1] = AuthenticationData;
}
Example #8
0
static void
XdmcpRegisterManufacturerDisplayID(const char *name, int length)
{
    int i;

    XdmcpDisposeARRAY8(&ManufacturerDisplayID);
    if (!XdmcpAllocARRAY8(&ManufacturerDisplayID, length))
        return;
    for (i = 0; i < length; i++)
        ManufacturerDisplayID.data[i] = (CARD8) name[i];
}
Example #9
0
static void
XdmcpRegisterDisplayClass(const char *name, int length)
{
    int i;

    XdmcpDisposeARRAY8(&DisplayClass);
    if (!XdmcpAllocARRAY8(&DisplayClass, length))
        return;
    for (i = 0; i < length; i++)
        DisplayClass.data[i] = (CARD8) name[i];
}
Example #10
0
static void
recv_willing_msg(
    struct sockaddr	*from,
    int			fromlen,
    unsigned		length)
{
    ARRAY8	authenticationName;
    ARRAY8	hostname;
    ARRAY8	status;

    authenticationName.data = 0;
    hostname.data = 0;
    status.data = 0;
    if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
	XdmcpReadARRAY8 (&buffer, &hostname) &&
	XdmcpReadARRAY8 (&buffer, &status))
    {
    	if (length == 6 + authenticationName.length +
		      hostname.length + status.length)
    	{
	    switch (state)
	    {
	    case XDM_COLLECT_QUERY:
	    	XdmcpSelectHost(from, fromlen, &authenticationName);
	    	break;
	    case XDM_COLLECT_BROADCAST_QUERY:
#if defined(IPv6) && defined(AF_INET6)
	    case XDM_COLLECT_MULTICAST_QUERY:
#endif
	    case XDM_COLLECT_INDIRECT_QUERY:
	    	XdmcpAddHost(from, fromlen, &authenticationName, &hostname, &status);
	    	break;
	    default:
		break;
    	    }
    	}
    }
    XdmcpDisposeARRAY8 (&authenticationName);
    XdmcpDisposeARRAY8 (&hostname);
    XdmcpDisposeARRAY8 (&status);
}
Example #11
0
void RemoveDisplay(struct display *old)
{
    struct display *d, **dp;
    int i;

    for(dp = &displays; (d = *dp); dp = &(*dp)->next)
    {
        if(d == old)
        {
            Debug("Removing display %s\n", d->name);
            *dp = d->next;
            IfFree(d->class2);
            IfFree(d->cfg.data);
            delStr(d->cfg.dep.name);
#ifdef XDMCP
            IfFree(d->remoteHost);
#endif
            if(d->authorizations)
            {
                for(i = 0; i < d->authNum; i++)
                    XauDisposeAuth(d->authorizations[i]);
                free((char *)d->authorizations);
            }
            if(d->authFile)
            {
                (void)unlink(d->authFile);
                free(d->authFile);
            }
            IfFree(d->authNameLens);
#ifdef XDMCP
            XdmcpDisposeARRAY8(&d->peer);
            XdmcpDisposeARRAY8(&d->from);
            XdmcpDisposeARRAY8(&d->clientAddr);
#endif
            free((char *)d);
            break;
        }
    }
}
Example #12
0
static void
FreeHostEntry (HostEntry *h)
{
    switch (h->type) {
    case HOST_ALIAS:
	free (h->entry.aliasName);
	break;
    case HOST_ADDRESS:
	XdmcpDisposeARRAY8 (&h->entry.hostAddress);
	break;
    case HOST_CHOOSER:
	break;
    }
    free (h);
}
Example #13
0
static void
recv_failed_msg(unsigned length)
{
    CARD32 FailedSessionID;
    ARRAY8 status;

    if (state != XDM_AWAIT_MANAGE_RESPONSE)
        return;
    status.data = 0;
    if (XdmcpReadCARD32(&buffer, &FailedSessionID) &&
        XdmcpReadARRAY8(&buffer, &status)) {
        if (length == 6 + status.length && SessionID == FailedSessionID) {
            XdmcpFatal("Session failed", &status);
        }
    }
    XdmcpDisposeARRAY8(&status);
}
Example #14
0
static void freeDisplay(struct display *d)
{
	char **x;
	int i;

	IfFree(d->name);
	IfFree(d->class);
	for (x = d->argv; x && *x; x++)
		IfFree(*x);
	IfFree(d->argv);
	IfFree(d->resources);
	IfFree(d->xrdb);
	IfFree(d->setup);
	IfFree(d->startup);
	IfFree(d->reset);
	IfFree(d->session);
	IfFree(d->userPath);
	IfFree(d->systemPath);
	IfFree(d->systemShell);
	IfFree(d->failsafeClient);
	IfFree(d->chooser);
	if (d->authorizations) {
		for (i = 0; i < d->authNum; i++)
			XauDisposeAuth(d->authorizations[i]);
		free(d->authorizations);
	}
	IfFree(d->clientAuthFile);
	if (d->authFile)
		(void)unlink(d->authFile);
	IfFree(d->authFile);
	IfFree(d->userAuthDir);
	for (x = d->authNames; x && *x; x++)
		IfFree(*x);
	IfFree(d->authNames);
	IfFree(d->authNameLens);
#ifdef XDMCP
	IfFree(d->peer);
	IfFree(d->from);
	XdmcpDisposeARRAY8(&d->clientAddr);
#endif
	free(d);
}
Example #15
0
static void
FreeDisplayEntry (DisplayEntry *d)
{
    HostEntry	*h, *next;
    switch (d->type) {
    case DISPLAY_ALIAS:
	free (d->entry.aliasName);
	break;
    case DISPLAY_PATTERN:
	free (d->entry.displayPattern);
	break;
    case DISPLAY_ADDRESS:
	XdmcpDisposeARRAY8 (&d->entry.displayAddress.clientAddress);
	break;
    }
    for (h = d->hosts; h; h = next) {
	next = h->next;
	FreeHostEntry (h);
    }
    free ((char *) d);
}
Example #16
0
ForgetIndirectClient (
    ARRAY8Ptr   clientAddress,
    CARD16      connectionType)
{
    IndirectUsersPtr	i, prev;

    prev = 0;
    for (i = indirectUsers; i; i = i->next)
    {
	if (XdmcpARRAY8Equal (clientAddress, &i->client) &&
	    connectionType == i->connectionType)
	{
	    if (prev)
		prev->next = i->next;
	    else
		indirectUsers = i->next;
	    XdmcpDisposeARRAY8 (&i->client);
	    free ((char *) i);
	    break;
	}
	prev = i;
    }
}
Example #17
0
static void
FreeDisplayEntry (DisplayEntry *d)
{
    HostEntry	*h, *next;
    switch (d->type) {
    case DISPLAY_ALIAS:
	free (d->entry.aliasName);
	break;
    case DISPLAY_PATTERN:
	free (d->entry.displayPattern);
	break;
    case DISPLAY_ADDRESS:
	XdmcpDisposeARRAY8 (&d->entry.displayAddress.clientAddress);
	break;
    case DISPLAY_LISTEN:
	/* do nothing - this case doesn't use the d->entry union */
	break;
    }
    for (h = d->hosts; h; h = next) {
	next = h->next;
	FreeHostEntry (h);
    }
    free (d);
}
Example #18
0
static void
processDPipe( struct display *d )
{
	char *user, *pass, *args;
	int cmd;
	GTalk dpytalk;
#ifdef XDMCP
	int ct, len;
	ARRAY8 ca, ha;
#endif

	dpytalk.pipe = &d->pipe;
	if (Setjmp( dpytalk.errjmp )) {
		StopDisplay( d );
		return;
	}
	GSet( &dpytalk );
	if (!GRecvCmd( &cmd )) {
		/* process already exited */
		UnregisterInput( d->pipe.rfd );
		return;
	}
	switch (cmd) {
	case D_User:
		d->userSess = GRecvInt();
		d->userName = GRecvStr();
		d->sessName = GRecvStr();
		break;
	case D_ReLogin:
		user = GRecvStr();
		pass = GRecvStr();
		args = GRecvStr();
		setNLogin( d, user, pass, args, 1 );
		free( args );
		free( pass );
		free( user );
		break;
#ifdef XDMCP
	case D_ChooseHost:
		ca.data = (unsigned char *)GRecvArr( &len );
		ca.length = (CARD16)len;
		ct = GRecvInt();
		ha.data = (unsigned char *)GRecvArr( &len );
		ha.length = (CARD16)len;
		RegisterIndirectChoice( &ca, ct, &ha );
		XdmcpDisposeARRAY8( &ha );
		XdmcpDisposeARRAY8( &ca );
		break;
	case D_RemoteHost:
		if (d->remoteHost)
			free( d->remoteHost );
		d->remoteHost = GRecvStr();
		break;
#endif
	case D_XConnOk:
		startingServer = 0;
		break;
	default:
		LogError( "Internal error: unknown D_* command %d\n", cmd );
		StopDisplay( d );
		break;
	}
}
Example #19
0
/*ARGSUSED*/
static void forward_respond(struct sockaddr *from, int fromlen ATTR_UNUSED, int length, int fd)
{
    ARRAY8 clientAddress;
    ARRAY8 clientPort;
    ARRAYofARRAY8 authenticationNames;
    struct sockaddr *client;
    int clientlen;
    int expectedLen;
    int i;

    Debug("<forward> respond %d\n", length);
    clientAddress.length = 0;
    clientAddress.data = 0;
    clientPort.length = 0;
    clientPort.data = 0;
    authenticationNames.length = 0;
    authenticationNames.data = 0;
    if(XdmcpReadARRAY8(&buffer, &clientAddress) && XdmcpReadARRAY8(&buffer, &clientPort) && XdmcpReadARRAYofARRAY8(&buffer, &authenticationNames))
    {
        expectedLen = 0;
        expectedLen += 2 + clientAddress.length;
        expectedLen += 2 + clientPort.length;
        expectedLen += 1; /* authenticationNames */
        for(i = 0; i < (int)authenticationNames.length; i++)
            expectedLen += 2 + authenticationNames.data[i].length;
        if(length == expectedLen)
        {
            int j;

            j = 0;
            for(i = 0; i < (int)clientPort.length; i++)
                j = j * 256 + clientPort.data[i];
            Debug("<forward> client address (port %d) %[*hhu\n", j, clientAddress.length, clientAddress.data);
            switch(from->sa_family)
            {
#ifdef AF_INET
                case AF_INET:
                {
                    struct sockaddr_in in_addr;

                    if(clientAddress.length != 4 || clientPort.length != 2)
                        goto badAddress;
                    bzero((char *)&in_addr, sizeof(in_addr));
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
                    in_addr.sin_len = sizeof(in_addr);
#endif
                    in_addr.sin_family = AF_INET;
                    memmove(&in_addr.sin_addr, clientAddress.data, 4);
                    memmove((char *)&in_addr.sin_port, clientPort.data, 2);
                    client = (struct sockaddr *)&in_addr;
                    clientlen = sizeof(in_addr);
                    all_query_respond(client, clientlen, &authenticationNames, FORWARD_QUERY, fd);
                }
                break;
#endif
#if defined(IPv6) && defined(AF_INET6)
                case AF_INET6:
                {
                    struct sockaddr_in6 in6_addr;

                    if(clientAddress.length != 16 || clientPort.length != 2)
                        goto badAddress;
                    bzero((char *)&in6_addr, sizeof(in6_addr));
#ifdef SIN6_LEN
                    in6_addr.sin6_len = sizeof(in6_addr);
#endif
                    in6_addr.sin6_family = AF_INET6;
                    memmove(&in6_addr, clientAddress.data, clientAddress.length);
                    memmove((char *)&in6_addr.sin6_port, clientPort.data, 2);
                    client = (struct sockaddr *)&in6_addr;
                    clientlen = sizeof(in6_addr);
                    all_query_respond(client, clientlen, &authenticationNames, FORWARD_QUERY, fd);
                }
                break;
#endif
#ifdef AF_UNIX
                case AF_UNIX:
                {
                    struct sockaddr_un un_addr;

                    if(clientAddress.length >= sizeof(un_addr.sun_path))
                        goto badAddress;
                    bzero((char *)&un_addr, sizeof(un_addr));
                    un_addr.sun_family = AF_UNIX;
                    memmove(un_addr.sun_path, clientAddress.data, clientAddress.length);
                    un_addr.sun_path[clientAddress.length] = '\0';
                    client = (struct sockaddr *)&un_addr;
#if defined(HAVE_STRUCT_SOCKADDR_IN_SIN_LEN) && !defined(__Lynx__) && defined(UNIXCONN)
                    un_addr.sun_len = strlen(un_addr.sun_path);
                    clientlen = SUN_LEN(&un_addr);
#else
                    clientlen = sizeof(un_addr);
#endif
                    all_query_respond(client, clientlen, &authenticationNames, FORWARD_QUERY, fd);
                }
                break;
#endif
#ifdef AF_CHAOS
                case AF_CHAOS:
                    goto badAddress;
#endif
#ifdef AF_DECnet
                case AF_DECnet:
                    goto badAddress;
#endif
            }
        }
        else
            Debug("<forward> length error got %d expect %d\n", length, expectedLen);
    }
badAddress:
    XdmcpDisposeARRAY8(&clientAddress);
    XdmcpDisposeARRAY8(&clientPort);
    XdmcpDisposeARRAYofARRAY8(&authenticationNames);
}
Example #20
0
static void request_respond(struct sockaddr *from, int fromlen, int length, int fd)
{
    CARD16 displayNumber;
    ARRAY16 connectionTypes;
    ARRAYofARRAY8 connectionAddresses;
    ARRAY8 authenticationName;
    ARRAY8 authenticationData;
    ARRAYofARRAY8 authorizationNames;
    ARRAY8 manufacturerDisplayID;
    ARRAY8Ptr reason = 0;
    int expectlen;
    int i, j;
    struct protoDisplay *pdpy;
    ARRAY8 authorizationName, authorizationData;
    ARRAY8Ptr connectionAddress;

    Debug("<request> respond %d\n", length);
    connectionTypes.data = 0;
    connectionAddresses.data = 0;
    authenticationName.data = 0;
    authenticationData.data = 0;
    authorizationNames.data = 0;
    authorizationName.length = 0;
    authorizationData.length = 0;
    manufacturerDisplayID.data = 0;
    if(XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadARRAY16(&buffer, &connectionTypes)
       && XdmcpReadARRAYofARRAY8(&buffer, &connectionAddresses) && XdmcpReadARRAY8(&buffer, &authenticationName)
       && XdmcpReadARRAY8(&buffer, &authenticationData) && XdmcpReadARRAYofARRAY8(&buffer, &authorizationNames)
       && XdmcpReadARRAY8(&buffer, &manufacturerDisplayID))
    {
        expectlen = 0;
        expectlen += 2;                              /* displayNumber */
        expectlen += 1 + 2 * connectionTypes.length; /* connectionTypes */
        expectlen += 1;                              /* connectionAddresses */
        for(i = 0; i < (int)connectionAddresses.length; i++)
            expectlen += 2 + connectionAddresses.data[i].length;
        expectlen += 2 + authenticationName.length; /* authenticationName */
        expectlen += 2 + authenticationData.length; /* authenticationData */
        expectlen += 1;                             /* authoriationNames */
        for(i = 0; i < (int)authorizationNames.length; i++)
            expectlen += 2 + authorizationNames.data[i].length;
        expectlen += 2 + manufacturerDisplayID.length; /* displayID */
        if(expectlen != length)
        {
            Debug("<request> length error got %d expect %d\n", length, expectlen);
            goto abort;
        }
        if(connectionTypes.length == 0 || connectionAddresses.length != connectionTypes.length)
        {
            reason = &noValidAddr;
            pdpy = 0;
            goto decline;
        }
        pdpy = FindProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber);
        if(!pdpy)
        {

            /* Check this Display against the Manager's policy */
            reason = Accept(from, fromlen, displayNumber);
            if(reason)
                goto decline;

            /* Check the Display's stream services against Manager's policy */
            i = SelectConnectionTypeIndex(&connectionTypes, &connectionAddresses);
            if(i < 0)
            {
                reason = &noValidAddr;
                goto decline;
            }

            /* The Manager considers this a new session */
            connectionAddress = &connectionAddresses.data[i];
            pdpy = NewProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber, connectionTypes.data[i], connectionAddress, NextSessionID());
            Debug("NewProtoDisplay %p\n", pdpy);
            if(!pdpy)
            {
                reason = &outOfMemory;
                goto decline;
            }
        }
        if(authorizationNames.length == 0)
            j = 0;
        else
            j = SelectAuthorizationTypeIndex(&authenticationName, &authorizationNames);
        if(j < 0)
        {
            reason = &noValidAuth;
            goto decline;
        }
        if(!CheckAuthentication(pdpy, &manufacturerDisplayID, &authenticationName, &authenticationData))
        {
            reason = &noAuthentic;
            goto decline;
        }
        if(j < (int)authorizationNames.length)
        {
            Xauth *auth;
            SetProtoDisplayAuthorization(pdpy, (unsigned short)authorizationNames.data[j].length, (char *)authorizationNames.data[j].data);
            auth = pdpy->xdmcpAuthorization;
            if(!auth)
                auth = pdpy->fileAuthorization;
            if(auth)
            {
                authorizationName.length = auth->name_length;
                authorizationName.data = (CARD8Ptr)auth->name;
                authorizationData.length = auth->data_length;
                authorizationData.data = (CARD8Ptr)auth->data;
            }
        }
        if(pdpy)
        {
            send_accept(from, fromlen, pdpy->sessionID, &authenticationName, &authenticationData, &authorizationName, &authorizationData, fd);
        }
        else
        {
        decline:
            send_decline(from, fromlen, &authenticationName, &authenticationData, reason, fd);
            if(pdpy)
                DisposeProtoDisplay(pdpy);
        }
    }
abort:
    XdmcpDisposeARRAY16(&connectionTypes);
    XdmcpDisposeARRAYofARRAY8(&connectionAddresses);
    XdmcpDisposeARRAY8(&authenticationName);
    XdmcpDisposeARRAY8(&authenticationData);
    XdmcpDisposeARRAYofARRAY8(&authorizationNames);
    XdmcpDisposeARRAY8(&manufacturerDisplayID);
}
Example #21
0
static void manage(struct sockaddr *from, int fromlen, int length, int fd)
{
    CARD32 sessionID;
    CARD16 displayNumber;
    ARRAY8 displayClass;
    int expectlen;
    struct protoDisplay *pdpy;
    struct display *d;
    char *name = NULL;
    char *class2 = NULL;
    XdmcpNetaddr from_save;
    ARRAY8 clientAddress, clientPort;
    CARD16 connectionType;

    Debug("<manage> %d\n", length);
    displayClass.data = 0;
    displayClass.length = 0;
    if(XdmcpReadCARD32(&buffer, &sessionID) && XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadARRAY8(&buffer, &displayClass))
    {
        expectlen = 4 +                      /* session ID */
                    2 +                      /* displayNumber */
                    2 + displayClass.length; /* displayClass */
        if(expectlen != length)
        {
            Debug("<manage> length error got %d expect %d\n", length, expectlen);
            goto abort;
        }
        pdpy = FindProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber);
        Debug("<manage> session ID %ld, pdpy %p\n", (long)sessionID, pdpy);
        if(!pdpy || pdpy->sessionID != sessionID)
        {
            /*
             * We may have already started a session for this display
             * but it hasn't seen the response in the form of an
             * XOpenDisplay() yet. So check if it is in the list of active
             * displays, and if so check that the session id's match.
             * If all this is true, then we have a duplicate request that
             * can be ignored.
             */
            if(!pdpy && (d = FindDisplayByAddress((XdmcpNetaddr)from, fromlen, displayNumber)) && d->sessionID == sessionID)
            {
                Debug("manage: got duplicate pkt, ignoring\n");
                goto abort;
            }
            Debug("session ID %ld refused\n", (long)sessionID);
            if(pdpy)
                Debug("existing session ID %ld\n", (long)pdpy->sessionID);
            send_refuse(from, fromlen, sessionID, fd);
        }
        else
        {
            name = NetworkAddressToName(pdpy->connectionType, &pdpy->connectionAddress, from, pdpy->displayNumber);
            if(!name)
            {
                Debug("could not compute display name\n");
                send_failed(from, fromlen, "(no name)", sessionID, "out of memory", fd);
                goto abort;
            }
            Debug("computed display name: %s\n", name);
            if((d = FindDisplayByName(name)))
            {
                Debug("terminating active session for %s\n", d->name);
                StopDisplay(d);
            }
            if(displayClass.length)
            {
                if(!StrNDup(&class2, (char *)displayClass.data, displayClass.length))
                {
                    send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                    goto abort;
                }
            }
            if(!(from_save = (XdmcpNetaddr)Malloc(fromlen)))
            {
                send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                goto abort;
            }
            memmove(from_save, from, fromlen);
            if(!(d = NewDisplay(name)))
            {
                free((char *)from_save);
                send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                goto abort;
            }
            d->class2 = class2;
            class2 = 0;
            d->displayType = dForeign | dTransient | dFromXDMCP;
            d->sessionID = pdpy->sessionID;
            d->from.data = (unsigned char *)from_save;
            d->from.length = fromlen;
            d->displayNumber = pdpy->displayNumber;
            ClientAddress(from, &clientAddress, &clientPort, &connectionType);
            d->useChooser = 0;
            d->xdmcpFd = fd;
            if(IsIndirectClient(&clientAddress, connectionType))
            {
                Debug("IsIndirectClient\n");
                ForgetIndirectClient(&clientAddress, connectionType);
                if(UseChooser(&clientAddress, connectionType))
                {
                    d->useChooser = 1;
                    Debug("use chooser for %s\n", d->name);
                }
            }
            d->clientAddr = clientAddress;
            d->connectionType = connectionType;
            d->remoteHost = NetworkAddressToHostname(pdpy->connectionType, &pdpy->connectionAddress);

            XdmcpDisposeARRAY8(&clientPort);
            if(pdpy->fileAuthorization)
            {
                d->authorizations = (Xauth **)Malloc(sizeof(Xauth *));
                if(!d->authorizations)
                {
                    free((char *)from_save);
                    free((char *)d);
                    send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                    goto abort;
                }
                d->authorizations[0] = pdpy->fileAuthorization;
                d->authNum = 1;
                pdpy->fileAuthorization = 0;
            }
            DisposeProtoDisplay(pdpy);
            Debug("starting display %s,%s\n", d->name, d->class2);
            if(LoadDisplayResources(d) < 0)
            {
                LogError(
                    "Unable to read configuration for display %s; "
                    "stopping it.\n",
                    d->name);
                StopDisplay(d);
            }
            else
                StartDisplay(d);
            CloseGetter();
        }
    }
abort:
    XdmcpDisposeARRAY8(&displayClass);
    if(name)
        free((char *)name);
    if(class2)
        free((char *)class2);
}
Example #22
0
static void
send_request_msg(void)
{
    XdmcpHeader header;
    int length;
    int i;
    CARD16 XdmcpConnectionType;
    ARRAY8 authenticationData;
    int socketfd = xdmcpSocket;

    switch (SOCKADDR_FAMILY(ManagerAddress)) {
    case AF_INET:
        XdmcpConnectionType = FamilyInternet;
        break;
#if defined(IPv6) && defined(AF_INET6)
    case AF_INET6:
        XdmcpConnectionType = FamilyInternet6;
        break;
#endif
    default:
        XdmcpConnectionType = 0xffff;
        break;
    }

    header.version = XDM_PROTOCOL_VERSION;
    header.opcode = (CARD16) REQUEST;

    length = 2;                 /* display number */
    length += 1 + 2 * ConnectionTypes.length;   /* connection types */
    length += 1;                /* connection addresses */
    for (i = 0; i < ConnectionAddresses.length; i++)
        length += 2 + ConnectionAddresses.data[i].length;
    authenticationData.length = 0;
    authenticationData.data = 0;
    if (AuthenticationFuncs) {
        (*AuthenticationFuncs->Generator) (AuthenticationData,
                                           &authenticationData, REQUEST);
    }
    length += 2 + AuthenticationName->length;   /* authentication name */
    length += 2 + authenticationData.length;    /* authentication data */
    length += 1;                /* authorization names */
    for (i = 0; i < AuthorizationNames.length; i++)
        length += 2 + AuthorizationNames.data[i].length;
    length += 2 + ManufacturerDisplayID.length; /* display ID */
    header.length = length;

    if (!XdmcpWriteHeader(&buffer, &header)) {
        XdmcpDisposeARRAY8(&authenticationData);
        return;
    }
    XdmcpWriteCARD16(&buffer, DisplayNumber);
    XdmcpWriteCARD8(&buffer, ConnectionTypes.length);

    /* The connection array is send reordered, so that connections of   */
    /* the same address type as the XDMCP manager connection are send   */
    /* first. This works around a bug in xdm. [email protected]          */
    for (i = 0; i < (int) ConnectionTypes.length; i++)
        if (ConnectionTypes.data[i] == XdmcpConnectionType)
            XdmcpWriteCARD16(&buffer, ConnectionTypes.data[i]);
    for (i = 0; i < (int) ConnectionTypes.length; i++)
        if (ConnectionTypes.data[i] != XdmcpConnectionType)
            XdmcpWriteCARD16(&buffer, ConnectionTypes.data[i]);

    XdmcpWriteCARD8(&buffer, ConnectionAddresses.length);
    for (i = 0; i < (int) ConnectionAddresses.length; i++)
        if ((i < ConnectionTypes.length) &&
            (ConnectionTypes.data[i] == XdmcpConnectionType))
            XdmcpWriteARRAY8(&buffer, &ConnectionAddresses.data[i]);
    for (i = 0; i < (int) ConnectionAddresses.length; i++)
        if ((i >= ConnectionTypes.length) ||
            (ConnectionTypes.data[i] != XdmcpConnectionType))
            XdmcpWriteARRAY8(&buffer, &ConnectionAddresses.data[i]);

    XdmcpWriteARRAY8(&buffer, AuthenticationName);
    XdmcpWriteARRAY8(&buffer, &authenticationData);
    XdmcpDisposeARRAY8(&authenticationData);
    XdmcpWriteARRAYofARRAY8(&buffer, &AuthorizationNames);
    XdmcpWriteARRAY8(&buffer, &ManufacturerDisplayID);
#if defined(IPv6) && defined(AF_INET6)
    if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
        socketfd = xdmcpSocket6;
#endif
    if (XdmcpFlush(socketfd, &buffer,
                   (XdmcpNetaddr) &req_sockaddr, req_socklen))
        state = XDM_AWAIT_REQUEST_RESPONSE;
}
Example #23
0
static void
processDPipe(struct display *d)
{
    char *user, *pass, *args;
    int cmd;
    GTalk dpytalk;
#ifdef XDMCP
    int ct, len;
    ARRAY8 ca, cp, ha;
#endif

    dpytalk.pipe = &d->pipe;
    if (Setjmp(dpytalk.errjmp)) {
        stopDisplay(d);
        return;
    }
    gSet(&dpytalk);
    if (!gRecvCmd(&cmd)) {
        /* process already exited */
        unregisterInput(d->pipe.fd.r);
        return;
    }
    switch (cmd) {
    case D_User:
        d->userSess = gRecvInt();
        d->userName = gRecvStr();
        d->sessName = gRecvStr();
        break;
    case D_UnUser:
        sessionDone(d);
        if (d->sdRec.how) {
            if (d->sdRec.force == SHUT_ASK &&
                (anyUserLogins(-1) || d->allowShutdown == SHUT_ROOT))
            {
                gSendInt(True);
            } else {
                if (!sdRec.how || sdRec.force != SHUT_FORCE ||
                    !((d->allowNuke == SHUT_NONE && sdRec.uid != d->sdRec.uid) ||
                      (d->allowNuke == SHUT_ROOT && d->sdRec.uid)))
                {
                    free(sdRec.osname);
                    sdRec = d->sdRec;
                } else {
                    free(d->sdRec.osname);
                }
                d->sdRec.how = 0;
                d->sdRec.osname = 0;
                gSendInt(False);
            }
        } else {
            gSendInt(False);
        }
        break;
    case D_ReLogin:
        user = gRecvStr();
        pass = gRecvStr();
        args = gRecvStr();
        setNLogin(d, user, pass, args, 1);
        free(args);
        free(pass);
        free(user);
        break;
#ifdef XDMCP
    case D_ChooseHost:
        ca.data = (unsigned char *)gRecvArr(&len);
        ca.length = (CARD16)len;
        cp.data = (unsigned char *)gRecvArr(&len);
        cp.length = (CARD16)len;
        ct = gRecvInt();
        ha.data = (unsigned char *)gRecvArr(&len);
        ha.length = (CARD16)len;
        registerIndirectChoice(&ca, &cp, ct, &ha);
        XdmcpDisposeARRAY8(&ha);
        XdmcpDisposeARRAY8(&cp);
        XdmcpDisposeARRAY8(&ca);
        break;
    case D_RemoteHost:
        free(d->remoteHost);
        d->remoteHost = gRecvStr();
        break;
#endif
    case D_XConnOk:
        startingServer = 0;
        break;
    default:
        logError("Internal error: unknown D_* command %d\n", cmd);
        stopDisplay(d);
        break;
    }
}