Exemple #1
0
int
XdmcpReadHeader (XdmcpBufferPtr buffer, XdmcpHeaderPtr header)
{
    if (XdmcpReadCARD16 (buffer, &header->version) &&
        XdmcpReadCARD16 (buffer, &header->opcode) &&
	XdmcpReadCARD16 (buffer, &header->length))
	return TRUE;
    return FALSE;
}
Exemple #2
0
static void send_alive(struct sockaddr *from, int fromlen, int length, int fd)
{
    CARD32 sessionID;
    CARD16 displayNumber;
    struct display *d;
    XdmcpHeader header;
    CARD8 sendRunning;
    CARD32 sendSessionID;

    Debug("send <alive>\n");
    if(XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadCARD32(&buffer, &sessionID))
    {
        if(length == 6)
        {
            if(!(d = FindDisplayBySessionID(sessionID)))
                d = FindDisplayByAddress((XdmcpNetaddr)from, fromlen, displayNumber);
            sendRunning = 0;
            sendSessionID = 0;
            if(d && d->status == running)
            {
                if(d->sessionID == sessionID)
                    sendRunning = 1;
                sendSessionID = d->sessionID;
            }
            header.version = XDM_PROTOCOL_VERSION;
            header.opcode = (CARD16)ALIVE;
            header.length = 5;
            Debug("<alive>: %d %ld\n", sendRunning, (long)sendSessionID);
            XdmcpWriteHeader(&buffer, &header);
            XdmcpWriteCARD8(&buffer, sendRunning);
            XdmcpWriteCARD32(&buffer, sendSessionID);
            XdmcpFlush(fd, &buffer, (XdmcpNetaddr)from, fromlen);
        }
    }
}
Exemple #3
0
int
XdmcpReadARRAY16 (XdmcpBufferPtr buffer, ARRAY16Ptr array)
{
    int	    i;

    /*
     * When returning FALSE, guarantee that array->data = 0.
     * This allows the user to safely call XdmcpDisposeARRAY16(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 = (CARD16 *) malloc(array->length * sizeof (CARD16));
    if (!array->data)
	return FALSE;
    for (i = 0; i < (int)array->length; i++)
    {
	if (!XdmcpReadCARD16 (buffer, &array->data[i]))
	{
	    free(array->data);
	    array->data = NULL;
	    array->length = 0;
	    return FALSE;
	}
    }
    return TRUE;
}
Exemple #4
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);
}
Exemple #5
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);
}