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);
}
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);
}
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);
}
Beispiel #4
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);
}
Beispiel #5
0
int
XdmcpReadARRAYofARRAY8 (XdmcpBufferPtr buffer, ARRAYofARRAY8Ptr array)
{
    CARD8    i;

    /*
     * When returning FALSE, guarantee that array->data = 0.
     * This allows the user to safely call XdmcpDisposeARRAYofARRAY8(array)
     * regardless of the return value below.
     * Note that XdmcpDisposeARRAY*(array) will call free(array->data),
     * so we must guarantee that array->data is NULL or a malloced pointer.
     */
    if (!XdmcpReadCARD8 (buffer, &array->length)) {
	array->data = NULL;
	return FALSE;
    }
    if (!array->length)
    {
	array->data = NULL;
	return TRUE;
    }
    array->data = (ARRAY8 *) malloc(array->length * sizeof (ARRAY8));
    if (!array->data)
	return FALSE;
    for (i = 0; i < array->length; i++)
    {
	if (!XdmcpReadARRAY8 (buffer, &array->data[i]))
	{
	    /*
	     * We must free all of the arrays allocated thus far in the loop
	     * and free array->data and finally set array->data = 0;
	     * The easiest way to do this is to reset the length and call
	     * XdmcpDisposeARRAYofARRAY8(array).
	     */
	    array->length = i;
	    XdmcpDisposeARRAYofARRAY8(array);
	    return FALSE;
	}
    }
    return TRUE;
}
Beispiel #6
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);
}
Beispiel #7
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);
}
Beispiel #8
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);
}