15c10afb9Smrg 25c10afb9Smrg/* 35c10afb9SmrgCopyright 1996, 1998 The Open Group 45c10afb9Smrg 55c10afb9SmrgPermission to use, copy, modify, distribute, and sell this software and its 65c10afb9Smrgdocumentation for any purpose is hereby granted without fee, provided that 75c10afb9Smrgthe above copyright notice appear in all copies and that both that 85c10afb9Smrgcopyright notice and this permission notice appear in supporting 95c10afb9Smrgdocumentation. 105c10afb9Smrg 115c10afb9SmrgThe above copyright notice and this permission notice shall be included 125c10afb9Smrgin all copies or substantial portions of the Software. 135c10afb9Smrg 145c10afb9SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 155c10afb9SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 165c10afb9SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 175c10afb9SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 185c10afb9SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 195c10afb9SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 205c10afb9SmrgOTHER DEALINGS IN THE SOFTWARE. 215c10afb9Smrg 225c10afb9SmrgExcept as contained in this notice, the name of The Open Group shall 235c10afb9Smrgnot be used in advertising or otherwise to promote the sale, use or 245c10afb9Smrgother dealings in this Software without prior written authorization 255c10afb9Smrgfrom The Open Group. 265c10afb9Smrg*/ 275c10afb9Smrg 285c10afb9Smrg#include <stdlib.h> 295c10afb9Smrg#include "pmint.h" 305c10afb9Smrg#include <X11/StringDefs.h> 315c10afb9Smrg#include <X11/Intrinsic.h> 325c10afb9Smrg#include <X11/ICE/ICEmsg.h> 335c10afb9Smrg#include <X11/ICE/ICEproto.h> 345c10afb9Smrg#include <X11/PM/PMproto.h> 355c10afb9Smrg#include <X11/PM/PM.h> 365c10afb9Smrg#include "pmdb.h" 375c10afb9Smrg#include "config.h" 385c10afb9Smrg#include <assert.h> 395c10afb9Smrg 405c10afb9Smrg#include <netinet/in.h> 415c10afb9Smrg#include <arpa/inet.h> 425c10afb9Smrg#include <sys/socket.h> 435c10afb9Smrg#include <netdb.h> 445c10afb9Smrg 455c10afb9Smrgstatic int PMprotocolSetupProc ( IceConn iceConn, int majorVersion, 465c10afb9Smrg int minorVersion, char *vendor, 475c10afb9Smrg char *release, IcePointer *clientDataRet, 485c10afb9Smrg char **failureReasonRet ); 495c10afb9Smrgstatic void SendGetProxyAddr ( PMconn *pmConn, char *serviceName, 505c10afb9Smrg char *serverAddress, char *hostAddress, 515c10afb9Smrg char *startOptions, int authLen, 525c10afb9Smrg char *authName, char *authData ); 535c10afb9Smrg 545c10afb9Smrgstatic int PMAcceptorOpcode; 555c10afb9Smrgstatic int PMOriginatorOpcode; 565c10afb9Smrg 57b3078addSmrgstatic int PMversionCount = 1; 58b3078addSmrgstatic IcePaVersionRec PMReplyVersions[] = {{PM_MAJOR_VERSION, PM_MINOR_VERSION, 595c10afb9Smrg PMReplyProcessMessages}}; 60b3078addSmrgstatic IcePoVersionRec PMSetupVersions[] = {{PM_MAJOR_VERSION, PM_MINOR_VERSION, 615c10afb9Smrg PMSetupProcessMessages}}; 625c10afb9Smrg 63cf2f63c2Smrgconst char *PM_VENDOR_STRING = XVENDORNAME; 64cf2f63c2Smrgconst char *PM_VENDOR_RELEASE = XORG_RELEASE; 655c10afb9Smrg 665c10afb9Smrgint verbose = 0; 675c10afb9Smrg 68b3078addSmrgstatic XtAppContext appContext; 695c10afb9Smrg 705c10afb9Smrg#define PM_PORT "6500" 715c10afb9Smrg 72cf2f63c2Smrgstatic const char *configFile = NULL; 735c10afb9Smrg 745c10afb9Smrgvoid 75b3078addSmrgUsage(void) 765c10afb9Smrg{ 775c10afb9Smrg fprintf (stderr, "Usage: proxymngr [-config file] [-verbose]\n"); 785c10afb9Smrg exit (1); 795c10afb9Smrg} 805c10afb9Smrg 815c10afb9Smrgvoid 82b3078addSmrgSetCloseOnExec(int fd) 835c10afb9Smrg{ 845c10afb9Smrg#ifdef F_SETFD 855c10afb9Smrg#ifdef FD_CLOEXEC 865c10afb9Smrg (void) fcntl (fd, F_SETFD, FD_CLOEXEC); 875c10afb9Smrg#else 885c10afb9Smrg (void) fcntl (fd, F_SETFD, 1); 895c10afb9Smrg#endif /* FD_CLOEXEC */ 905c10afb9Smrg#endif /* F_SETFD */ 915c10afb9Smrg} 925c10afb9Smrg 935c10afb9Smrg/* 945c10afb9Smrg * Main program 955c10afb9Smrg */ 965c10afb9Smrg 975c10afb9Smrgint 985c10afb9Smrgmain (int argc, char *argv[]) 995c10afb9Smrg{ 1005c10afb9Smrg IceListenObj *listenObjs; 1015c10afb9Smrg int numTransports, i; 1025c10afb9Smrg char errormsg[256]; 1035c10afb9Smrg char *networkIds, *p; 1045c10afb9Smrg 1055c10afb9Smrg for (i = 1; i < argc; i++) 1065c10afb9Smrg { 1075c10afb9Smrg if (strcmp (argv[i], "-config") == 0) 1085c10afb9Smrg { 1095c10afb9Smrg if (++i < argc) 1105c10afb9Smrg configFile = argv[i]; 1115c10afb9Smrg else 1125c10afb9Smrg Usage (); 1135c10afb9Smrg } 1145c10afb9Smrg else if (strcmp(argv[i], "-verbose") == 0) 1155c10afb9Smrg { 1165c10afb9Smrg verbose = 1; 1175c10afb9Smrg } 1185c10afb9Smrg else 1195c10afb9Smrg Usage (); 1205c10afb9Smrg } 1215c10afb9Smrg 1225c10afb9Smrg if (!configFile) 1235c10afb9Smrg configFile = CONFIG_FILE; 1245c10afb9Smrg 1255c10afb9Smrg if (verbose) 1265c10afb9Smrg fprintf (stderr, "config file = %s\n", configFile); 1275c10afb9Smrg 1285c10afb9Smrg /* 1295c10afb9Smrg * Install an IO error handler. 1305c10afb9Smrg */ 1315c10afb9Smrg InstallIOErrorHandler (); 1325c10afb9Smrg 1335c10afb9Smrg /* 1345c10afb9Smrg * Register support for PROXY_MANAGEMENT. 1355c10afb9Smrg */ 1365c10afb9Smrg 1375c10afb9Smrg /* For Managed proxies, the proxy does the Setup */ 1385c10afb9Smrg if ((PMAcceptorOpcode = IceRegisterForProtocolReply ( 1395c10afb9Smrg PM_PROTOCOL_NAME, PM_VENDOR_STRING, PM_VENDOR_RELEASE, 1405c10afb9Smrg PMversionCount, PMReplyVersions, 1415c10afb9Smrg 0, /* authcount */ 1425c10afb9Smrg NULL, /* authnames */ 1435c10afb9Smrg NULL, /* authprocs */ 1445c10afb9Smrg HostBasedAuthProc, 1455c10afb9Smrg PMprotocolSetupProc, 1465c10afb9Smrg NULL, /* protocolActivateProc */ 1475c10afb9Smrg NULL /* IceIOErrorProc */ )) < 0) 1485c10afb9Smrg { 1495c10afb9Smrg fprintf (stderr, 1505c10afb9Smrg "Could not register PROXY_MANAGEMENT protocol reply with ICE"); 1515c10afb9Smrg exit (1); 1525c10afb9Smrg } 1535c10afb9Smrg 1545c10afb9Smrg /* For Unmanaged proxies, we do the Setup 1555c10afb9Smrg * ICElib doesn't specify that the same opCode will be returned 1565c10afb9Smrg * so don't bet on it. 1575c10afb9Smrg */ 1585c10afb9Smrg if ((PMOriginatorOpcode = IceRegisterForProtocolSetup ( 1595c10afb9Smrg PM_PROTOCOL_NAME, PM_VENDOR_STRING, PM_VENDOR_RELEASE, 1605c10afb9Smrg PMversionCount, PMSetupVersions, 1615c10afb9Smrg 0, /* authcount */ 1625c10afb9Smrg NULL, /* authnames */ 1635c10afb9Smrg NULL, /* authprocs */ 1645c10afb9Smrg NULL /* IceIOErrorProc */ )) < 0) 1655c10afb9Smrg { 1665c10afb9Smrg fprintf (stderr, 1675c10afb9Smrg "Could not register PROXY_MANAGEMENT protocol setup with ICE"); 1685c10afb9Smrg exit (1); 1695c10afb9Smrg } 1705c10afb9Smrg 1715c10afb9Smrg 1725c10afb9Smrg if (!IceListenForWellKnownConnections ( 1735c10afb9Smrg PM_PORT, &numTransports, &listenObjs, 256, errormsg)) 1745c10afb9Smrg { 1755c10afb9Smrg fprintf (stderr, "%s\n", errormsg); 1765c10afb9Smrg exit (1); 1775c10afb9Smrg } 1785c10afb9Smrg 1795c10afb9Smrg networkIds = IceComposeNetworkIdList (numTransports, listenObjs); 180cf2f63c2Smrg p = malloc (sizeof ("PROXY_MANAGER") + strlen(networkIds) + 2); 1815c10afb9Smrg sprintf (p, "PROXY_MANAGER=%s", networkIds); 1825c10afb9Smrg putenv (p); 1835c10afb9Smrg printf ("%s\n", p); 1845c10afb9Smrg free (networkIds); 1855c10afb9Smrg 1865c10afb9Smrg appContext = XtCreateApplicationContext (); 1875c10afb9Smrg 1885c10afb9Smrg InitWatchProcs (appContext); 1895c10afb9Smrg 1905c10afb9Smrg for (i = 0; i < numTransports; i++) 1915c10afb9Smrg { 1925c10afb9Smrg XtAppAddInput (appContext, 1935c10afb9Smrg IceGetListenConnectionNumber (listenObjs[i]), 1945c10afb9Smrg (XtPointer) XtInputReadMask, 1955c10afb9Smrg NewConnectionXtProc, (XtPointer) listenObjs[i]); 1965c10afb9Smrg 1975c10afb9Smrg IceSetHostBasedAuthProc (listenObjs[i], HostBasedAuthProc); 1985c10afb9Smrg 1995c10afb9Smrg SetCloseOnExec (IceGetListenConnectionNumber (listenObjs[i])); 2005c10afb9Smrg } 2015c10afb9Smrg 2025c10afb9Smrg /* 2035c10afb9Smrg * Main loop 2045c10afb9Smrg */ 2055c10afb9Smrg XtAppMainLoop (appContext); 2065c10afb9Smrg exit (0); 2075c10afb9Smrg} 2085c10afb9Smrg 2095c10afb9Smrg 2105c10afb9Smrg/* 2115c10afb9Smrg * Xt callback invoked when a client attempts to connect. 2125c10afb9Smrg */ 2135c10afb9Smrg 2145c10afb9Smrg/* ARGSUSED */ 2155c10afb9Smrgvoid 216b3078addSmrgNewConnectionXtProc(XtPointer client_data, int *source, XtInputId *id) 2175c10afb9Smrg{ 2185c10afb9Smrg IceConn ice_conn; 2195c10afb9Smrg char *connstr; 2205c10afb9Smrg IceAcceptStatus status; 2215c10afb9Smrg 2225c10afb9Smrg ice_conn = IceAcceptConnection((IceListenObj) client_data, &status); 2235c10afb9Smrg if (! ice_conn) { 2245c10afb9Smrg if (verbose) 2255c10afb9Smrg printf ("IceAcceptConnection failed\n"); 2265c10afb9Smrg } else { 2275c10afb9Smrg IceConnectStatus cstatus; 2285c10afb9Smrg 2295c10afb9Smrg /* 2305c10afb9Smrg * Mark this fd to be closed upon exec 2315c10afb9Smrg */ 2325c10afb9Smrg SetCloseOnExec (IceConnectionNumber (ice_conn)); 2335c10afb9Smrg 2345c10afb9Smrg while ((cstatus = IceConnectionStatus (ice_conn))==IceConnectPending) { 2355c10afb9Smrg XtAppProcessEvent (appContext, XtIMAll); 2365c10afb9Smrg } 2375c10afb9Smrg 2385c10afb9Smrg if (cstatus == IceConnectAccepted) { 2395c10afb9Smrg if (verbose) { 2405c10afb9Smrg printf ("ICE Connection opened by client, IceConn fd = %d, ", 2415c10afb9Smrg IceConnectionNumber (ice_conn)); 2425c10afb9Smrg connstr = IceConnectionString (ice_conn); 2435c10afb9Smrg printf ("Accept at networkId %s\n", connstr); 2445c10afb9Smrg free (connstr); 2455c10afb9Smrg printf ("\n"); 2465c10afb9Smrg } 2475c10afb9Smrg } else { 2485c10afb9Smrg if (verbose) 2495c10afb9Smrg { 2505c10afb9Smrg if (cstatus == IceConnectIOError) 2515c10afb9Smrg printf ("IO error opening ICE Connection!\n"); 2525c10afb9Smrg else 2535c10afb9Smrg printf ("ICE Connection rejected!\n"); 2545c10afb9Smrg } 2555c10afb9Smrg 2565c10afb9Smrg IceCloseConnection (ice_conn); 2575c10afb9Smrg } 2585c10afb9Smrg } 2595c10afb9Smrg} 2605c10afb9Smrg 2615c10afb9Smrg 2625c10afb9Smrg/* 2635c10afb9Smrg * See ConnectToProxy() if you change any of the pmConn structure 2645c10afb9Smrg */ 2655c10afb9Smrgstatic Status 266b3078addSmrgPMprotocolSetupProc(IceConn iceConn, int majorVersion, int minorVersion, 267b3078addSmrg char *vendor, char *release, IcePointer *clientDataRet, 268b3078addSmrg char **failureReasonRet) 2695c10afb9Smrg 2705c10afb9Smrg{ 2715c10afb9Smrg /* 2725c10afb9Smrg * Allocate new pmConn. 2735c10afb9Smrg */ 2745c10afb9Smrg 2755c10afb9Smrg static char standardError[] = "Could not allocate memory for new client"; 2765c10afb9Smrg PMconn *pmConn; 2775c10afb9Smrg 278cf2f63c2Smrg if ((pmConn = malloc (sizeof (PMconn))) == NULL) 2795c10afb9Smrg { 2805c10afb9Smrg if (verbose) 2815c10afb9Smrg fprintf (stderr, "%s\n", standardError); 2825c10afb9Smrg 2835c10afb9Smrg *failureReasonRet = standardError; 2845c10afb9Smrg return (0); 2855c10afb9Smrg } 2865c10afb9Smrg 2875c10afb9Smrg pmConn->iceConn = iceConn; 2885c10afb9Smrg pmConn->pmOpcode = PMAcceptorOpcode; 2895c10afb9Smrg pmConn->proto_major_version = majorVersion; 2905c10afb9Smrg pmConn->proto_minor_version = minorVersion; 2915c10afb9Smrg pmConn->vendor = vendor; 2925c10afb9Smrg pmConn->release = release; 2935c10afb9Smrg 2945c10afb9Smrg *clientDataRet = (IcePointer) pmConn; 2955c10afb9Smrg 2965c10afb9Smrg return (1); 2975c10afb9Smrg} 2985c10afb9Smrg 2995c10afb9Smrg 3005c10afb9Smrgstatic void 3015c10afb9SmrgSendGetProxyAddr ( 3025c10afb9Smrg PMconn *pmConn, 3035c10afb9Smrg char *serviceName, 3045c10afb9Smrg char *serverAddress, 3055c10afb9Smrg char *hostAddress, 3065c10afb9Smrg char *startOptions, 3075c10afb9Smrg int authLen, 3085c10afb9Smrg char *authName, 3095c10afb9Smrg char *authData) 3105c10afb9Smrg 3115c10afb9Smrg{ 3125c10afb9Smrg IceConn iceConn = pmConn->iceConn; 3135c10afb9Smrg pmGetProxyAddrMsg *pMsg; 3145c10afb9Smrg char *pData; 3155c10afb9Smrg int len; 3165c10afb9Smrg 3175c10afb9Smrg if (verbose) { 3185c10afb9Smrg printf ("Sending GetProxyAddr to proxy %d, serviceName = %s, serverAddr = %s\n", 3195c10afb9Smrg IceConnectionNumber(iceConn), serviceName, serverAddress); 3205c10afb9Smrg printf (" hostAddr = %s, options = %s, authLen = %d\n", 3215c10afb9Smrg hostAddress ? hostAddress : "", 3225c10afb9Smrg startOptions ? startOptions : "", 3235c10afb9Smrg authLen); 3245c10afb9Smrg if (authLen > 0) 3255c10afb9Smrg printf (" authName = %s\n", authName); 3265c10afb9Smrg } 3275c10afb9Smrg 3285c10afb9Smrg len = STRING_BYTES (serviceName) + 3295c10afb9Smrg STRING_BYTES (serverAddress) + 3305c10afb9Smrg STRING_BYTES (hostAddress) + 3315c10afb9Smrg STRING_BYTES (startOptions) + 3325c10afb9Smrg (authLen > 0 ? (STRING_BYTES (authName) + authLen) : 0); 3335c10afb9Smrg 3345c10afb9Smrg IceGetHeaderExtra (iceConn, pmConn->pmOpcode, PM_GetProxyAddr, 3355c10afb9Smrg SIZEOF (pmGetProxyAddrMsg), WORD64COUNT (len), 3365c10afb9Smrg pmGetProxyAddrMsg, pMsg, pData); 3375c10afb9Smrg 3385c10afb9Smrg pMsg->authLen = authLen; 3395c10afb9Smrg 3405c10afb9Smrg STORE_STRING (pData, serviceName); 3415c10afb9Smrg STORE_STRING (pData, serverAddress); 3425c10afb9Smrg STORE_STRING (pData, hostAddress); 3435c10afb9Smrg STORE_STRING (pData, startOptions); 3445c10afb9Smrg if (authLen > 0) 3455c10afb9Smrg { 3465c10afb9Smrg STORE_STRING (pData, authName); 3475c10afb9Smrg memcpy (pData, authData, authLen); 3485c10afb9Smrg } 3495c10afb9Smrg 3505c10afb9Smrg IceFlush (iceConn); 3515c10afb9Smrg} 3525c10afb9Smrg 3535c10afb9Smrg 3545c10afb9Smrgvoid 3555c10afb9SmrgSendGetProxyAddrReply ( 3565c10afb9Smrg PMconn *requestor, 3575c10afb9Smrg int status, 358cf2f63c2Smrg const char *addr, 359cf2f63c2Smrg const char *error) 3605c10afb9Smrg 3615c10afb9Smrg{ 3625c10afb9Smrg int len = STRING_BYTES (addr) + STRING_BYTES (error); 3635c10afb9Smrg pmGetProxyAddrReplyMsg *pReply; 3645c10afb9Smrg char *pData; 3655c10afb9Smrg 3665c10afb9Smrg if (verbose) { 3675c10afb9Smrg fputs ("Replying with ", stderr); 3685c10afb9Smrg fputs (status == PM_Success ? "Success: " : 3695c10afb9Smrg status == PM_Failure ? "Failure: " : 3705c10afb9Smrg status == PM_Unable ? "Unable: " : 3715c10afb9Smrg "?unknown status", stderr); 3725c10afb9Smrg fputs (status == PM_Success ? addr : error, stderr); 3735c10afb9Smrg fputc ('\n', stderr); 3745c10afb9Smrg } 3755c10afb9Smrg 3765c10afb9Smrg IceGetHeaderExtra (requestor->iceConn, 3775c10afb9Smrg requestor->pmOpcode, PM_GetProxyAddrReply, 3785c10afb9Smrg SIZEOF (pmGetProxyAddrReplyMsg), WORD64COUNT (len), 3795c10afb9Smrg pmGetProxyAddrReplyMsg, pReply, pData); 3805c10afb9Smrg 3815c10afb9Smrg pReply->status = status; 3825c10afb9Smrg 3835c10afb9Smrg STORE_STRING (pData, addr); 3845c10afb9Smrg STORE_STRING (pData, error); 3855c10afb9Smrg 3865c10afb9Smrg IceFlush (requestor->iceConn); 3875c10afb9Smrg} 3885c10afb9Smrg 3895c10afb9Smrg 3905c10afb9Smrg 3915c10afb9Smrgvoid 392b3078addSmrgPMReplyProcessMessages(IceConn iceConn, IcePointer clientData, int opcode, 393b3078addSmrg unsigned long length, Bool swap) 3945c10afb9Smrg 3955c10afb9Smrg{ 3965c10afb9Smrg PMconn *pmConn = (PMconn *) clientData; 3975c10afb9Smrg 3985c10afb9Smrg assert(pmConn->iceConn == iceConn); 3995c10afb9Smrg 4005c10afb9Smrg switch (opcode) 4015c10afb9Smrg { 4025c10afb9Smrg case PM_GetProxyAddr: 4035c10afb9Smrg { 4045c10afb9Smrg pmGetProxyAddrMsg *pMsg; 4055c10afb9Smrg char *pData, *pStart; 4065c10afb9Smrg char *serviceName = NULL, *serverAddress = NULL; 4075c10afb9Smrg char *hostAddress = NULL, *startOptions = NULL; 4085c10afb9Smrg char *authName = NULL, *authData = NULL; 4095c10afb9Smrg int authLen; 4105c10afb9Smrg 4115c10afb9Smrg#if 0 /* No-op */ 4125c10afb9Smrg CHECK_AT_LEAST_SIZE (iceConn, pmConn->pmOpcode, opcode, 4135c10afb9Smrg length, SIZEOF (pmGetProxyAddrMsg), IceFatalToProtocol); 4145c10afb9Smrg#endif 4155c10afb9Smrg 4165c10afb9Smrg IceReadCompleteMessage (iceConn, SIZEOF (pmGetProxyAddrMsg), 4175c10afb9Smrg pmGetProxyAddrMsg, pMsg, pStart); 4185c10afb9Smrg 4195c10afb9Smrg if (!IceValidIO (iceConn)) 4205c10afb9Smrg { 4215c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 4225c10afb9Smrg return; 4235c10afb9Smrg } 4245c10afb9Smrg 4255c10afb9Smrg authLen = swap ? lswaps (pMsg->authLen) : pMsg->authLen; 4265c10afb9Smrg 4275c10afb9Smrg pData = pStart; 4285c10afb9Smrg 4295c10afb9Smrg SKIP_STRING (pData, swap); /* proxy-service */ 4305c10afb9Smrg SKIP_STRING (pData, swap); /* server-address */ 4315c10afb9Smrg SKIP_STRING (pData, swap); /* host-address */ 4325c10afb9Smrg SKIP_STRING (pData, swap); /* start-options */ 4335c10afb9Smrg if (authLen > 0) 4345c10afb9Smrg { 4355c10afb9Smrg SKIP_STRING (pData, swap); /* auth-name */ 4365c10afb9Smrg pData += (authLen + PAD64 (authLen)); /* auth-data */ 4375c10afb9Smrg } 4385c10afb9Smrg 4395c10afb9Smrg CHECK_COMPLETE_SIZE (iceConn, pmConn->pmOpcode, opcode, 4405c10afb9Smrg length, pData - pStart + SIZEOF (pmGetProxyAddrMsg), 4415c10afb9Smrg pStart, IceFatalToProtocol); 4425c10afb9Smrg 4435c10afb9Smrg pData = pStart; 4445c10afb9Smrg 4455c10afb9Smrg EXTRACT_STRING (pData, swap, serviceName); 4465c10afb9Smrg EXTRACT_STRING (pData, swap, serverAddress); 4475c10afb9Smrg EXTRACT_STRING (pData, swap, hostAddress); 4485c10afb9Smrg EXTRACT_STRING (pData, swap, startOptions); 4495c10afb9Smrg if (authLen > 0) 4505c10afb9Smrg { 4515c10afb9Smrg EXTRACT_STRING (pData, swap, authName); 452cf2f63c2Smrg authData = malloc (authLen); 4535c10afb9Smrg memcpy (authData, pData, authLen); 4545c10afb9Smrg } 4555c10afb9Smrg 4565c10afb9Smrg if (serverAddress) 4575c10afb9Smrg { 4585c10afb9Smrg /* 4595c10afb9Smrg * Assume that if serverAddress is something like :0 or :0.0 4605c10afb9Smrg * then the request is for a server on the client's host. 4615c10afb9Smrg * 4625c10afb9Smrg * However, the proxy handling this request may be on a 4635c10afb9Smrg * different host than the client or the client host, 4645c10afb9Smrg * proxy host and the server host may all be different, 4655c10afb9Smrg * thus a serverAddress of :0 or :0.0 is not useful. 4665c10afb9Smrg * Therefore, change serverAddress to use the client's 4675c10afb9Smrg * hostname. 4685c10afb9Smrg */ 4695c10afb9Smrg char *tmpName; 4705c10afb9Smrg 4715c10afb9Smrg tmpName = strrchr (serverAddress, ':'); 4725c10afb9Smrg 4735c10afb9Smrg if (tmpName && ((tmpName == serverAddress) || 4745c10afb9Smrg (!strncmp (serverAddress, "unix:", 5)))) 4755c10afb9Smrg { 4765c10afb9Smrg#if defined(IPv6) && defined(AF_INET6) 4775c10afb9Smrg struct sockaddr_storage serverSock; 4785c10afb9Smrg#else 4795c10afb9Smrg struct sockaddr_in serverSock; 4805c10afb9Smrg#endif 4815c10afb9Smrg int retVal; 4825c10afb9Smrg int addrLen = sizeof(serverSock); 4835c10afb9Smrg 4845c10afb9Smrg retVal = getpeername(IceConnectionNumber(iceConn), 4855c10afb9Smrg (struct sockaddr *) &serverSock, 4865c10afb9Smrg (void *) &addrLen); 4875c10afb9Smrg if (!retVal) 4885c10afb9Smrg { 4895c10afb9Smrg char *canonname = NULL; 4905c10afb9Smrg#if defined(IPv6) && defined(AF_INET6) 4915c10afb9Smrg char hostname[NI_MAXHOST]; 4925c10afb9Smrg struct addrinfo *ai = NULL, hints; 4935c10afb9Smrg 4945c10afb9Smrg if (getnameinfo((struct sockaddr *) &serverSock, 4955c10afb9Smrg addrLen, hostname, sizeof(hostname), NULL, 0, 0) == 0) { 4965c10afb9Smrg (void)memset(&hints, 0, sizeof(hints)); 4975c10afb9Smrg hints.ai_flags = AI_CANONNAME; 4985c10afb9Smrg if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) { 4995c10afb9Smrg canonname = ai->ai_canonname; 5005c10afb9Smrg } 5015c10afb9Smrg } 5025c10afb9Smrg#else 5035c10afb9Smrg struct hostent *hostent; 5045c10afb9Smrg 5055c10afb9Smrg hostent = gethostbyname (inet_ntoa(serverSock.sin_addr)); 5065c10afb9Smrg 5075c10afb9Smrg if (hostent && hostent->h_name) 5085c10afb9Smrg canonname = hostent->h_name; 5095c10afb9Smrg#endif 5105c10afb9Smrg if (canonname) 5115c10afb9Smrg { 5125c10afb9Smrg int len; 5135c10afb9Smrg char * pch = strdup (tmpName); 5145c10afb9Smrg 5155c10afb9Smrg len = strlen(canonname) + strlen(tmpName) + 1; 516cf2f63c2Smrg serverAddress = realloc (serverAddress, len); 5175c10afb9Smrg sprintf (serverAddress, "%s%s", canonname, pch); 5185c10afb9Smrg free (pch); 5195c10afb9Smrg } 5205c10afb9Smrg#if defined(IPv6) && defined(AF_INET6) 5215c10afb9Smrg if (ai != NULL) 5225c10afb9Smrg freeaddrinfo(ai); 5235c10afb9Smrg#endif 5245c10afb9Smrg } 5255c10afb9Smrg } 5265c10afb9Smrg } 5275c10afb9Smrg 5285c10afb9Smrg if (verbose) { 5295c10afb9Smrg printf ("Got GetProxyAddr, serviceName = %s, serverAddr = %s\n", 5305c10afb9Smrg serviceName, serverAddress); 5315c10afb9Smrg printf (" hostAddr = %s, options = %s, authLen = %d\n", 5325c10afb9Smrg hostAddress, startOptions, authLen); 5335c10afb9Smrg if (authLen > 0) 5345c10afb9Smrg printf (" authName = %s\n", authName); 5355c10afb9Smrg } 5365c10afb9Smrg 5375c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 5385c10afb9Smrg 5395c10afb9Smrg ForwardRequest (pmConn, serviceName, serverAddress, hostAddress, 5405c10afb9Smrg startOptions, authLen, authName, authData); 5415c10afb9Smrg 542cf2f63c2Smrg free (serviceName); 543cf2f63c2Smrg free (serverAddress); 544cf2f63c2Smrg free (hostAddress); 545cf2f63c2Smrg free (startOptions); 546cf2f63c2Smrg free (authName); 547cf2f63c2Smrg free (authData); 5485c10afb9Smrg 5495c10afb9Smrg break; 5505c10afb9Smrg } 5515c10afb9Smrg 5525c10afb9Smrg case PM_StartProxy: 5535c10afb9Smrg { 5545c10afb9Smrg pmStartProxyMsg *pMsg; 5555c10afb9Smrg char *pData, *pStart; 5565c10afb9Smrg char *serviceName = NULL; 5575c10afb9Smrg char *serverAddress; 5585c10afb9Smrg char *hostAddress; 5595c10afb9Smrg char *startOptions; 5605c10afb9Smrg int authLen; 5615c10afb9Smrg char *authName; 5625c10afb9Smrg char *authData; 5635c10afb9Smrg 5645c10afb9Smrg#if 0 /* No-op */ 5655c10afb9Smrg CHECK_AT_LEAST_SIZE (iceConn, pmConn->pmOpcode, opcode, 5665c10afb9Smrg length, SIZEOF (pmStartProxyMsg), IceFatalToProtocol); 5675c10afb9Smrg#endif 5685c10afb9Smrg 5695c10afb9Smrg IceReadCompleteMessage (iceConn, SIZEOF (pmStartProxyMsg), 5705c10afb9Smrg pmStartProxyMsg, pMsg, pStart); 5715c10afb9Smrg 5725c10afb9Smrg if (!IceValidIO (iceConn)) 5735c10afb9Smrg { 5745c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 5755c10afb9Smrg return; 5765c10afb9Smrg } 5775c10afb9Smrg 5785c10afb9Smrg pData = pStart; 5795c10afb9Smrg 5805c10afb9Smrg SKIP_STRING (pData, swap); /* proxy-service */ 5815c10afb9Smrg 5825c10afb9Smrg CHECK_COMPLETE_SIZE (iceConn, pmConn->pmOpcode, opcode, 5835c10afb9Smrg length, pData - pStart + SIZEOF (pmStartProxyMsg), 5845c10afb9Smrg pStart, IceFatalToProtocol); 5855c10afb9Smrg 5865c10afb9Smrg pData = pStart; 5875c10afb9Smrg 5885c10afb9Smrg EXTRACT_STRING (pData, swap, serviceName); 5895c10afb9Smrg 5905c10afb9Smrg assert(serviceName); 5915c10afb9Smrg 5925c10afb9Smrg if (verbose) 5935c10afb9Smrg printf ("Got StartProxy on fd %d, serviceName = %s\n", 5945c10afb9Smrg IceConnectionNumber(iceConn), serviceName); 5955c10afb9Smrg 5965c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 5975c10afb9Smrg 5985c10afb9Smrg if (! ActivateProxyService (serviceName, pmConn)) { 5995c10afb9Smrg fputs ("Configuration error: received unexpected StartProxy for service ", stderr); 6005c10afb9Smrg fputs (serviceName, stderr); 6015c10afb9Smrg fputc ('\n', stderr); 6025c10afb9Smrg IceCloseConnection (iceConn); 6035c10afb9Smrg } 6045c10afb9Smrg else { 6055c10afb9Smrg 6065c10afb9Smrg /* 6075c10afb9Smrg * Now send the GetProxyAddr message to the proxy. 6085c10afb9Smrg */ 6095c10afb9Smrg if (PeekRequestorQueue(pmConn, 6105c10afb9Smrg NULL, NULL, NULL, 6115c10afb9Smrg &serverAddress, &hostAddress, &startOptions, 6125c10afb9Smrg &authLen, &authName, &authData)) { 6135c10afb9Smrg SendGetProxyAddr(pmConn, 6145c10afb9Smrg serviceName, serverAddress, 6155c10afb9Smrg hostAddress, startOptions, 6165c10afb9Smrg authLen, authName, authData); 6175c10afb9Smrg } 6185c10afb9Smrg else if (verbose) { 6195c10afb9Smrg fputs ("Received StartProxy for service ", stderr); 6205c10afb9Smrg fputs (serviceName, stderr); 6215c10afb9Smrg fputs (" but no waiting GetproxyAddr requests\n", stderr); 6225c10afb9Smrg } 6235c10afb9Smrg } 6245c10afb9Smrg 6255c10afb9Smrg free (serviceName); 6265c10afb9Smrg 6275c10afb9Smrg break; 6285c10afb9Smrg } 6295c10afb9Smrg 6305c10afb9Smrg case PM_GetProxyAddrReply: 6315c10afb9Smrg 6325c10afb9Smrg { 6335c10afb9Smrg pmGetProxyAddrReplyMsg *pMsg; 6345c10afb9Smrg char *pData, *pStart; 6355c10afb9Smrg char *addr = NULL, *error = NULL; 6365c10afb9Smrg 6375c10afb9Smrg#if 0 /* No-op */ 6385c10afb9Smrg CHECK_AT_LEAST_SIZE (iceConn, pmConn->pmOpcode, opcode, 6395c10afb9Smrg length, SIZEOF (pmGetProxyAddrReplyMsg), IceFatalToProtocol); 6405c10afb9Smrg#endif 6415c10afb9Smrg 6425c10afb9Smrg IceReadCompleteMessage (iceConn, SIZEOF (pmGetProxyAddrReplyMsg), 6435c10afb9Smrg pmGetProxyAddrReplyMsg, pMsg, pStart); 6445c10afb9Smrg 6455c10afb9Smrg if (!IceValidIO (iceConn)) 6465c10afb9Smrg { 6475c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 6485c10afb9Smrg return; 6495c10afb9Smrg } 6505c10afb9Smrg 6515c10afb9Smrg pData = pStart; 6525c10afb9Smrg 6535c10afb9Smrg SKIP_STRING (pData, swap); /* proxy-address */ 6545c10afb9Smrg SKIP_STRING (pData, swap); /* failure-reason */ 6555c10afb9Smrg 6565c10afb9Smrg CHECK_COMPLETE_SIZE (iceConn, pmConn->pmOpcode, opcode, 6575c10afb9Smrg length, pData - pStart + SIZEOF (pmGetProxyAddrReplyMsg), 6585c10afb9Smrg pStart, IceFatalToProtocol); 6595c10afb9Smrg 6605c10afb9Smrg pData = pStart; 6615c10afb9Smrg 6625c10afb9Smrg EXTRACT_STRING (pData, swap, addr); 6635c10afb9Smrg EXTRACT_STRING (pData, swap, error); 6645c10afb9Smrg 6655c10afb9Smrg if (verbose) { 6665c10afb9Smrg printf ("Got GetProxyAddrReply from proxy %d, status = %d, ", 6675c10afb9Smrg IceConnectionNumber(iceConn), pMsg->status); 6685c10afb9Smrg if (pMsg->status == PM_Success) 6695c10afb9Smrg printf ("addr = %s\n", addr); 6705c10afb9Smrg else 6715c10afb9Smrg printf ("error = %s\n", error); 6725c10afb9Smrg } 6735c10afb9Smrg 6745c10afb9Smrg { /* Ignore any unsolicited replies so we don't get further confused */ 6755c10afb9Smrg running_proxy *proxy = ProxyForPMconn(pmConn); 6765c10afb9Smrg 6775c10afb9Smrg if (!proxy || !proxy->requests) 6785c10afb9Smrg { 6795c10afb9Smrg if (verbose) 6805c10afb9Smrg fprintf (stderr, "Received unsolicited GetProxyAddrReply from proxy %d; ignoring it.\n", 6815c10afb9Smrg IceConnectionNumber(iceConn)); 6825c10afb9Smrg 6835c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 6845c10afb9Smrg break; 6855c10afb9Smrg } 6865c10afb9Smrg } 6875c10afb9Smrg 6885c10afb9Smrg switch (pMsg->status) { 6895c10afb9Smrg 6905c10afb9Smrg case PM_Success: 6915c10afb9Smrg { 6925c10afb9Smrg /* 6935c10afb9Smrg * Now send the GetProxyAddr reply to xfindproxy. 6945c10afb9Smrg */ 6955c10afb9Smrg 6965c10afb9Smrg SendGetProxyAddrReply ( 6975c10afb9Smrg PopRequestorQueue (pmConn, True, True /* free proxy list */), 6985c10afb9Smrg PM_Success /* status */, addr, NULL); 6995c10afb9Smrg 7005c10afb9Smrg break; 7015c10afb9Smrg } 7025c10afb9Smrg 7035c10afb9Smrg case PM_Unable: 7045c10afb9Smrg { 7055c10afb9Smrg running_proxy_list *proxyList; 7065c10afb9Smrg char *serviceName, *serverAddress, *hostAddress, *startOptions; 7075c10afb9Smrg PMconn *requestor; 7085c10afb9Smrg int authLen; 7095c10afb9Smrg char *authName; 7105c10afb9Smrg char *authData; 7115c10afb9Smrg 7125c10afb9Smrg { 7135c10afb9Smrg running_proxy *proxy = ProxyForPMconn(pmConn); 7145c10afb9Smrg if (proxy) 7155c10afb9Smrg proxy->refused_service = True; 7165c10afb9Smrg else 7175c10afb9Smrg fputs("Internal error: received GetProxyAddrReply from an unknown proxy\n", stderr); 7185c10afb9Smrg } 7195c10afb9Smrg 7205c10afb9Smrg if (! PeekRequestorQueue (pmConn, &requestor, 7215c10afb9Smrg &proxyList, &serviceName, &serverAddress, 7225c10afb9Smrg &hostAddress, &startOptions, 7235c10afb9Smrg &authLen, &authName, &authData)) { 7245c10afb9Smrg if (verbose) 7255c10afb9Smrg fputs("Received GetProxyAddrReply from a proxy with no requests\n", stderr); 7265c10afb9Smrg 7275c10afb9Smrg proxyList = NULL; 7285c10afb9Smrg serviceName = "?unknown service--internal error"; 7295c10afb9Smrg } 7305c10afb9Smrg 7315c10afb9Smrg if (proxyList && (proxyList->current < proxyList->count - 1)) 7325c10afb9Smrg { 7335c10afb9Smrg /* 7345c10afb9Smrg * Ask the next running proxy if it can service this request. 7355c10afb9Smrg */ 7365c10afb9Smrg running_proxy *nextProxy; 7375c10afb9Smrg 7385c10afb9Smrg proxyList->current++; 7395c10afb9Smrg nextProxy = proxyList->list[proxyList->current]; 7405c10afb9Smrg 7415c10afb9Smrg if (nextProxy->pmConn != NULL) { 7425c10afb9Smrg /* send only if the proxy has started */ 7435c10afb9Smrg SendGetProxyAddr (nextProxy->pmConn, serviceName, 7445c10afb9Smrg serverAddress, hostAddress, startOptions, 7455c10afb9Smrg authLen, authName, authData); 7465c10afb9Smrg } 7475c10afb9Smrg 7485c10afb9Smrg PushRequestorQueue (nextProxy, requestor, proxyList, 7495c10afb9Smrg serviceName, serverAddress, hostAddress, startOptions, 7505c10afb9Smrg authLen, authName, authData); 7515c10afb9Smrg 7525c10afb9Smrg PopRequestorQueue (pmConn, False, False); 7535c10afb9Smrg } 7545c10afb9Smrg else 7555c10afb9Smrg { 7565c10afb9Smrg /* 7575c10afb9Smrg * Start a new proxy. 7585c10afb9Smrg */ 7595c10afb9Smrg 7605c10afb9Smrg running_proxy *runningProxy = NULL; 7615c10afb9Smrg char *startCommand; 7625c10afb9Smrg char *proxyAddress; 7635c10afb9Smrg Bool managed; 7645c10afb9Smrg 7655c10afb9Smrg if (!GetConfig (configFile, serviceName, &managed, 7665c10afb9Smrg &startCommand, &proxyAddress)) 7675c10afb9Smrg { 7685c10afb9Smrg SendGetProxyAddrReply (requestor, PM_Failure, 7695c10afb9Smrg NULL, "Could not read proxy manager config file"); 7705c10afb9Smrg } 7715c10afb9Smrg else 7725c10afb9Smrg { 7735c10afb9Smrg runningProxy = StartNewProxy (serviceName, startCommand); 7745c10afb9Smrg 7755c10afb9Smrg if (runningProxy) 7765c10afb9Smrg { 7775c10afb9Smrg PushRequestorQueue (runningProxy, 7785c10afb9Smrg requestor, proxyList, 7795c10afb9Smrg serviceName, serverAddress, 7805c10afb9Smrg hostAddress, startOptions, 7815c10afb9Smrg authLen, authName, authData); 7825c10afb9Smrg } 7835c10afb9Smrg else 7845c10afb9Smrg { 7855c10afb9Smrg SendGetProxyAddrReply (pmConn, PM_Failure, 7865c10afb9Smrg NULL, "Can't start new proxy"); 7875c10afb9Smrg } 7885c10afb9Smrg } 7895c10afb9Smrg 790cf2f63c2Smrg free (startCommand); 791cf2f63c2Smrg free (proxyAddress); 7925c10afb9Smrg 7935c10afb9Smrg PopRequestorQueue (pmConn, False, 7945c10afb9Smrg runningProxy ? False : True /* free proxy list */); 7955c10afb9Smrg } 7965c10afb9Smrg break; 7975c10afb9Smrg } 7985c10afb9Smrg 7995c10afb9Smrg default: 8005c10afb9Smrg if (verbose && pMsg->status != PM_Unable) 8015c10afb9Smrg fprintf(stderr, 8025c10afb9Smrg "Error: proxy returned unrecognized status: %d\n", 8035c10afb9Smrg pMsg->status); 8045c10afb9Smrg /* FALLTHROUGH */ 8055c10afb9Smrg 8065c10afb9Smrg case PM_Failure: 8075c10afb9Smrg SendGetProxyAddrReply ( 8085c10afb9Smrg PopRequestorQueue (pmConn, True, True /* free proxy list */), 8095c10afb9Smrg pMsg->status, NULL, error); 8105c10afb9Smrg } 8115c10afb9Smrg 8125c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 8135c10afb9Smrg 8145c10afb9Smrg /* see if there was more work queued for this proxy */ 8155c10afb9Smrg { 8165c10afb9Smrg char *serviceName, *serverAddress, *hostAddress, *startOptions; 8175c10afb9Smrg int authLen; 8185c10afb9Smrg char *authName, *authData; 8195c10afb9Smrg 8205c10afb9Smrg if (PeekRequestorQueue(pmConn, 8215c10afb9Smrg NULL, NULL, &serviceName, 8225c10afb9Smrg &serverAddress, &hostAddress, &startOptions, 8235c10afb9Smrg &authLen, &authName, &authData)) { 8245c10afb9Smrg SendGetProxyAddr(pmConn, 8255c10afb9Smrg serviceName, serverAddress, 8265c10afb9Smrg hostAddress, startOptions, 8275c10afb9Smrg authLen, authName, authData); 8285c10afb9Smrg } 8295c10afb9Smrg } 8305c10afb9Smrg 831cf2f63c2Smrg free (addr); 832cf2f63c2Smrg free (error); 8335c10afb9Smrg 8345c10afb9Smrg break; 8355c10afb9Smrg } 8365c10afb9Smrg 8375c10afb9Smrg case PM_Error: 8385c10afb9Smrg { 8395c10afb9Smrg iceErrorMsg *pMsg; 8405c10afb9Smrg char *pStart; 8415c10afb9Smrg 8425c10afb9Smrg CHECK_AT_LEAST_SIZE (iceConn, pmConn->pmOpcode, PM_Error, length, 8435c10afb9Smrg sizeof(iceErrorMsg), IceFatalToProtocol); 8445c10afb9Smrg 8455c10afb9Smrg IceReadCompleteMessage (iceConn, SIZEOF (iceErrorMsg), 8465c10afb9Smrg iceErrorMsg, pMsg, pStart); 8475c10afb9Smrg 8485c10afb9Smrg if (!IceValidIO (iceConn)) 8495c10afb9Smrg { 8505c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 8515c10afb9Smrg return; 8525c10afb9Smrg } 8535c10afb9Smrg 8545c10afb9Smrg if (swap) 8555c10afb9Smrg { 8565c10afb9Smrg pMsg->errorClass = lswaps (pMsg->errorClass); 8575c10afb9Smrg pMsg->offendingSequenceNum = lswapl (pMsg->offendingSequenceNum); 8585c10afb9Smrg } 8595c10afb9Smrg 8605c10afb9Smrg fprintf(stderr, "Received ICE Error: class=0x%x\n offending minor opcode=%d, severity=%d, sequence=%d\n", 8615c10afb9Smrg pMsg->errorClass, pMsg->offendingMinorOpcode, pMsg->severity, 8625c10afb9Smrg (int)pMsg->offendingSequenceNum); 8635c10afb9Smrg 8645c10afb9Smrg IceDisposeCompleteMessage (iceConn, pStart); 8655c10afb9Smrg 8665c10afb9Smrg break; 8675c10afb9Smrg } 8685c10afb9Smrg 8695c10afb9Smrg default: 8705c10afb9Smrg { 8715c10afb9Smrg _IceErrorBadMinor (iceConn, pmConn->pmOpcode, opcode, IceCanContinue); 8725c10afb9Smrg _IceReadSkip (iceConn, length << 3); 8735c10afb9Smrg break; 8745c10afb9Smrg } 8755c10afb9Smrg } 8765c10afb9Smrg} 8775c10afb9Smrg 8785c10afb9Smrgvoid 879b3078addSmrgPMSetupProcessMessages(IceConn iceConn, IcePointer clientData, int opcode, 880b3078addSmrg unsigned long length, Bool swap, 881b3078addSmrg IceReplyWaitInfo *replyWait, Bool *replyReadyRet) 8825c10afb9Smrg 8835c10afb9Smrg{ 8845c10afb9Smrg assert (replyWait == NULL); 8855c10afb9Smrg 8865c10afb9Smrg PMReplyProcessMessages (iceConn, clientData, opcode, length, swap); 8875c10afb9Smrg} 8885c10afb9Smrg 8895c10afb9Smrg 8905c10afb9Smrgvoid 891b3078addSmrgForwardRequest(PMconn *requestor, char *serviceName, char *serverAddress, 892b3078addSmrg char *hostAddress, char *startOptions, int authLen, 893b3078addSmrg char *authName, char *authData) 8945c10afb9Smrg{ 8955c10afb9Smrg running_proxy_list *proxyList; 8965c10afb9Smrg running_proxy *runningProxy = NULL; 8975c10afb9Smrg int pushRequest = 0; 8985c10afb9Smrg 8995c10afb9Smrg if ((proxyList = GetRunningProxyList ( 9005c10afb9Smrg serviceName, serverAddress)) != NULL) 9015c10afb9Smrg { 9025c10afb9Smrg while (proxyList->current < proxyList->count) { 9035c10afb9Smrg runningProxy = proxyList->list[proxyList->current]; 9045c10afb9Smrg 9055c10afb9Smrg if (runningProxy->pmConn != NULL) { 9065c10afb9Smrg SendGetProxyAddr (runningProxy->pmConn, serviceName, 9075c10afb9Smrg serverAddress, hostAddress, NULL, 9085c10afb9Smrg authLen, authName, authData); 9095c10afb9Smrg break; 9105c10afb9Smrg } 9115c10afb9Smrg proxyList->current++; 9125c10afb9Smrg } 9135c10afb9Smrg 9145c10afb9Smrg pushRequest = 1; 9155c10afb9Smrg } 9165c10afb9Smrg else 9175c10afb9Smrg { 9185c10afb9Smrg Bool managed; 9195c10afb9Smrg char *startCommand; 9205c10afb9Smrg char *proxyAddress; 9215c10afb9Smrg 9225c10afb9Smrg if (!GetConfig (configFile, serviceName, &managed, 9235c10afb9Smrg &startCommand, &proxyAddress)) 9245c10afb9Smrg { 9255c10afb9Smrg SendGetProxyAddrReply (requestor, PM_Failure, 9265c10afb9Smrg NULL, "Could not find requested service"); 9275c10afb9Smrg } 9285c10afb9Smrg else 9295c10afb9Smrg { 9305c10afb9Smrg if (managed) 9315c10afb9Smrg { 9325c10afb9Smrg runningProxy = StartNewProxy (serviceName, startCommand); 9335c10afb9Smrg 9345c10afb9Smrg if (runningProxy) 9355c10afb9Smrg pushRequest = 1; 9365c10afb9Smrg else 9375c10afb9Smrg { 9385c10afb9Smrg SendGetProxyAddrReply (requestor, PM_Failure, 9395c10afb9Smrg NULL, "Can't start new proxy"); 9405c10afb9Smrg } 9415c10afb9Smrg } 9425c10afb9Smrg else 9435c10afb9Smrg { 9445c10afb9Smrg /* 9455c10afb9Smrg * We have the unmanged proxy's address; now forward 9465c10afb9Smrg * the request to it. 9475c10afb9Smrg */ 9485c10afb9Smrg 9495c10afb9Smrg runningProxy = ConnectToProxy (PMOriginatorOpcode, 9505c10afb9Smrg serviceName, proxyAddress); 9515c10afb9Smrg 9525c10afb9Smrg if (runningProxy) { 9535c10afb9Smrg SendGetProxyAddr (runningProxy->pmConn, 9545c10afb9Smrg serviceName, serverAddress, 9555c10afb9Smrg hostAddress, startOptions, 9565c10afb9Smrg authLen, authName, authData); 9575c10afb9Smrg pushRequest = 1; 9585c10afb9Smrg } 9595c10afb9Smrg else 9605c10afb9Smrg { 9615c10afb9Smrg /* %%% We should reread the config file and look 9625c10afb9Smrg * for another proxy address before giving up. 9635c10afb9Smrg */ 9645c10afb9Smrg SendGetProxyAddrReply (requestor, PM_Failure, 9655c10afb9Smrg NULL, "Can't connect to proxy"); 9665c10afb9Smrg } 9675c10afb9Smrg } 9685c10afb9Smrg 969cf2f63c2Smrg free (startCommand); 970cf2f63c2Smrg free (proxyAddress); 9715c10afb9Smrg } 9725c10afb9Smrg } 9735c10afb9Smrg 9745c10afb9Smrg if (pushRequest) 9755c10afb9Smrg { 9765c10afb9Smrg PushRequestorQueue (runningProxy, requestor, proxyList, 9775c10afb9Smrg serviceName, serverAddress, hostAddress, startOptions, 9785c10afb9Smrg authLen, authName, authData); 9795c10afb9Smrg } 9805c10afb9Smrg} 9815c10afb9Smrg 9825c10afb9Smrg 9835c10afb9Smrg/* ARGSUSED */ 9845c10afb9Smrgvoid 985b3078addSmrg_XtProcessIceMsgProc(XtPointer client_data, int *source, XtInputId *id) 9865c10afb9Smrg{ 9875c10afb9Smrg IceConn ice_conn = (IceConn) client_data; 9885c10afb9Smrg IceProcessMessagesStatus status; 9895c10afb9Smrg 9905c10afb9Smrg status = IceProcessMessages (ice_conn, NULL, NULL); 9915c10afb9Smrg 9925c10afb9Smrg if (status == IceProcessMessagesIOError) 9935c10afb9Smrg { 9945c10afb9Smrg Bool activeReqs; 9955c10afb9Smrg 9965c10afb9Smrg ProxyGone (ice_conn, &activeReqs); 9975c10afb9Smrg IceSetShutdownNegotiation (ice_conn, False); 9985c10afb9Smrg IceCloseConnection (ice_conn); 9995c10afb9Smrg } 10005c10afb9Smrg} 10015c10afb9Smrg 10025c10afb9Smrg 10035c10afb9Smrgvoid 1004b3078addSmrg_XtIceWatchProc(IceConn ice_conn, IcePointer client_data, 1005b3078addSmrg Bool opening, IcePointer *watch_data) 10065c10afb9Smrg 10075c10afb9Smrg{ 10085c10afb9Smrg if (opening) 10095c10afb9Smrg { 10105c10afb9Smrg XtAppContext appContext = (XtAppContext) client_data; 10115c10afb9Smrg 10125c10afb9Smrg *watch_data = (IcePointer) XtAppAddInput ( 10135c10afb9Smrg appContext, 10145c10afb9Smrg IceConnectionNumber (ice_conn), 10155c10afb9Smrg (XtPointer) XtInputReadMask, 10165c10afb9Smrg _XtProcessIceMsgProc, 10175c10afb9Smrg (XtPointer) ice_conn); 10185c10afb9Smrg } 10195c10afb9Smrg else 10205c10afb9Smrg { 10215c10afb9Smrg XtRemoveInput ((XtInputId) *watch_data); 10225c10afb9Smrg } 10235c10afb9Smrg} 10245c10afb9Smrg 10255c10afb9Smrg 10265c10afb9SmrgStatus 1027b3078addSmrgInitWatchProcs(XtAppContext appContext) 10285c10afb9Smrg 10295c10afb9Smrg{ 10305c10afb9Smrg return (IceAddConnectionWatch (_XtIceWatchProc, (IcePointer) appContext)); 10315c10afb9Smrg} 10325c10afb9Smrg 10335c10afb9Smrg 10345c10afb9Smrg/* 10355c10afb9Smrg * The real way to handle IO errors is to check the return status 10365c10afb9Smrg * of IceProcessMessages. xsm properly does this. 10375c10afb9Smrg * 10385c10afb9Smrg * Unfortunately, a design flaw exists in the ICE library in which 10395c10afb9Smrg * a default IO error handler is invoked if no IO error handler is 10405c10afb9Smrg * installed. This default handler exits. We must avoid this. 10415c10afb9Smrg * 10425c10afb9Smrg * To get around this problem, we install an IO error handler that 10435c10afb9Smrg * does a little magic. Since a previous IO handler might have been 10445c10afb9Smrg * installed, when we install our IO error handler, we do a little 10455c10afb9Smrg * trick to get both the previous IO error handler and the default 10465c10afb9Smrg * IO error handler. When our IO error handler is called, if the 10475c10afb9Smrg * previous handler is not the default handler, we call it. This 10485c10afb9Smrg * way, everyone's IO error handler gets called except the stupid 10495c10afb9Smrg * default one which does an exit! 10505c10afb9Smrg */ 10515c10afb9Smrg 10525c10afb9Smrgstatic IceIOErrorHandler prev_handler; 10535c10afb9Smrg 10545c10afb9Smrgvoid 1055b3078addSmrgMyIoErrorHandler(IceConn ice_conn) 10565c10afb9Smrg{ 10575c10afb9Smrg if (prev_handler) 10585c10afb9Smrg (*prev_handler) (ice_conn); 10595c10afb9Smrg} 10605c10afb9Smrg 10615c10afb9Smrgvoid 1062b3078addSmrgInstallIOErrorHandler(void) 10635c10afb9Smrg{ 10645c10afb9Smrg IceIOErrorHandler default_handler; 10655c10afb9Smrg 10665c10afb9Smrg prev_handler = IceSetIOErrorHandler (NULL); 10675c10afb9Smrg default_handler = IceSetIOErrorHandler (MyIoErrorHandler); 10685c10afb9Smrg if (prev_handler == default_handler) 10695c10afb9Smrg prev_handler = NULL; 10705c10afb9Smrg} 10715c10afb9Smrg 10725c10afb9Smrg 10735c10afb9Smrg/* 10745c10afb9Smrg * Since proxy manager does not authenticate connections, we disable 10755c10afb9Smrg * authentication by always returning true in the host based auth proc. 10765c10afb9Smrg */ 10775c10afb9Smrg 10785c10afb9SmrgBool 1079b3078addSmrgHostBasedAuthProc(char *hostname) 10805c10afb9Smrg{ 10815c10afb9Smrg return (1); 10825c10afb9Smrg} 1083