Example #1
0
static void direct_query_respond(struct sockaddr *from, int fromlen, int length, xdmOpCode type, int fd)
{
    ARRAYofARRAY8 queryAuthenticationNames;
    int expectedLen;
    int i;

    if(!XdmcpReadARRAYofARRAY8(&buffer, &queryAuthenticationNames))
        return;
    expectedLen = 1;
    for(i = 0; i < (int)queryAuthenticationNames.length; i++)
        expectedLen += 2 + queryAuthenticationNames.data[i].length;
    if(length == expectedLen)
        all_query_respond(from, fromlen, &queryAuthenticationNames, type, fd);
    XdmcpDisposeARRAYofARRAY8(&queryAuthenticationNames);
}
Example #2
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 #3
0
File: Read.c Project: aosm/X11libs
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;
}
Example #4
0
void
XdmcpRegisterAuthorizations(void)
{
    XdmcpDisposeARRAYofARRAY8(&AuthorizationNames);
    RegisterAuthorizations();
}
Example #5
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;
}
Example #6
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 #7
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);
}