Beispiel #1
0
void
XdmcpRegisterConnection(int type, const char *address, int addrlen)
{
    int i;
    CARD8 *newAddress;

    if (xdmcpGeneration != serverGeneration) {
        XdmcpDisposeARRAY16(&ConnectionTypes);
        XdmcpDisposeARRAYofARRAY8(&ConnectionAddresses);
        xdmcpGeneration = serverGeneration;
    }
    if (xdm_from != NULL) {     /* Only register the requested address */
        const void *regAddr = address;
        const void *fromAddr = NULL;
        int regAddrlen = addrlen;

        if (addrlen == sizeof(struct in_addr)) {
            if (SOCKADDR_FAMILY(FromAddress) == AF_INET) {
                fromAddr = &((struct sockaddr_in *) &FromAddress)->sin_addr;
            }
#if defined(IPv6) && defined(AF_INET6)
            else if ((SOCKADDR_FAMILY(FromAddress) == AF_INET6) &&
                     IN6_IS_ADDR_V4MAPPED(&
                                          ((struct sockaddr_in6 *)
                                           &FromAddress)->sin6_addr)) {
                fromAddr =
                    &((struct sockaddr_in6 *) &FromAddress)->sin6_addr.
                    s6_addr[12];
            }
#endif
        }
#if defined(IPv6) && defined(AF_INET6)
        else if (addrlen == sizeof(struct in6_addr)) {
            if (SOCKADDR_FAMILY(FromAddress) == AF_INET6) {
                fromAddr = &((struct sockaddr_in6 *) &FromAddress)->sin6_addr;
            }
            else if ((SOCKADDR_FAMILY(FromAddress) == AF_INET) &&
                     IN6_IS_ADDR_V4MAPPED((const struct in6_addr *) address)) {
                fromAddr = &((struct sockaddr_in *) &FromAddress)->sin_addr;
                regAddr =
                    &((struct sockaddr_in6 *) &address)->sin6_addr.s6_addr[12];
                regAddrlen = sizeof(struct in_addr);
            }
        }
#endif
        if (!fromAddr || memcmp(regAddr, fromAddr, regAddrlen) != 0) {
            return;
        }
    }
    if (ConnectionAddresses.length + 1 == 256)
        return;
    newAddress = malloc(addrlen * sizeof(CARD8));
    if (!newAddress)
        return;
    if (!XdmcpReallocARRAY16(&ConnectionTypes, ConnectionTypes.length + 1)) {
        free(newAddress);
        return;
    }
    if (!XdmcpReallocARRAYofARRAY8(&ConnectionAddresses,
                                   ConnectionAddresses.length + 1)) {
        free(newAddress);
        return;
    }
    ConnectionTypes.data[ConnectionTypes.length - 1] = (CARD16) type;
    for (i = 0; i < addrlen; i++)
        newAddress[i] = address[i];
    ConnectionAddresses.data[ConnectionAddresses.length - 1].data = newAddress;
    ConnectionAddresses.data[ConnectionAddresses.length - 1].length = addrlen;
}
Beispiel #2
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);
}