int main(int argc, char *argv[]) { static XtAppContext appContext; IceConn iceConn; IceProtocolSetupStatus setupstat; char *vendor = NULL; char *release = NULL; pmGetProxyAddrMsg *pMsg; char *pData; int i; size_t len; IceReplyWaitInfo replyWait; GetProxyAddrReply reply; int majorVersion, minorVersion; Bool gotReply, ioErrorOccured; char errorString[255]; char *serviceName = NULL, *serverAddress = NULL; char *hostAddress = NULL, *startOptions = NULL; char *managerAddress = NULL; Bool haveAuth = 0; char authName[40]; char authData[128]; char *authDataBinary = NULL; int authLen = 0; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'a': /* -auth */ haveAuth = 1; continue; case 'm': /* -manager */ if (++i >= argc) goto usage; managerAddress = (char *) XtNewString (argv[i]); continue; case 's': /* -server */ if (++i >= argc) goto usage; serverAddress = (char *) XtNewString (argv[i]); continue; case 'n': /* -name */ if (++i >= argc) goto usage; serviceName = XtNewString (argv[i]); continue; case 'h': /* -host */ if (++i >= argc) goto usage; hostAddress = XtNewString (argv[i]); continue; case 'o': /* -options */ if (++i >= argc) goto usage; startOptions = XtNewString (argv[i]); continue; case 'v': puts(PACKAGE_STRING); exit(0); } } usage: if (i >= argc) fprintf (stderr, "%s: %s requires an argument\n", argv[0], argv[i-1]); else fprintf (stderr, "%s: unrecognized argument '%s'\n", argv[0], argv[i]); usage(); } if (serviceName == NULL) { fprintf (stderr, "%s: -name serviceName must be specified\n", argv[0]); usage(); } if (serverAddress == NULL) { fprintf (stderr, "%s: -server serverAddr must be specified\n", argv[0]); usage(); } if (managerAddress == NULL) { managerAddress = getenv("PROXY_MANAGER"); if (managerAddress == NULL) { fprintf (stderr, "Error: -manager option must be specified when PROXY_MANAGER is not in the environment\n"); exit (1); } } /* * Register support for PROXY_MANAGEMENT. */ if ((PMopcode = IceRegisterForProtocolSetup ( PM_PROTOCOL_NAME, "XC", "1.0", PMversionCount, PMversions, 0, /* authcount */ NULL, /* authnames */ NULL, /* authprocs */ NULL /* IceIOErrorProc */ )) < 0) { fprintf (stderr, "Could not register PROXY_MANAGEMENT protocol with ICE"); exit (1); } appContext = XtCreateApplicationContext (); InitWatchProcs (appContext); if ((iceConn = IceOpenConnection ( managerAddress, NULL, 0, 0, 256, errorString)) == NULL) { fprintf (stderr, "Could not open ICE connection to proxy manager: %s", errorString); exit (1); } setupstat = IceProtocolSetup (iceConn, PMopcode, NULL, False /* mustAuthenticate */, &majorVersion, &minorVersion, &vendor, &release, 256, errorString); if (setupstat != IceProtocolSetupSuccess) { IceCloseConnection (iceConn); fprintf (stderr, "Could not initialize proxy management protocol: %s\n", errorString); exit (1); } /* * If auth data is supplied, read it from stdin. */ if (haveAuth) { fgets (authName, sizeof (authName), stdin); fgets (authData, sizeof (authData), stdin); for (i = 0; i < strlen (authName); i++) if (authName[i] == '\n') { authName[i] = '\0'; break; } for (i = 0; i < strlen (authData); i++) if (authData[i] == '\n') { authData[i] = '\0'; break; } /* * Convert the hex auth data to binary. */ authLen = cvthexkey (authData, &authDataBinary); if (authLen == -1) { fprintf (stderr, "Could not convert hex auth data to binary\n"); exit (1); } } /* * Now send the GetProxyAddr request. */ len = STRING_BYTES (serviceName) + STRING_BYTES (serverAddress) + STRING_BYTES (hostAddress) + STRING_BYTES (startOptions) + (authLen > 0 ? (STRING_BYTES (authName) + authLen) : 0); IceGetHeaderExtra (iceConn, PMopcode, PM_GetProxyAddr, SIZEOF (pmGetProxyAddrMsg), WORD64COUNT (len), pmGetProxyAddrMsg, pMsg, pData); pMsg->authLen = (CARD16) authLen; STORE_STRING (pData, serviceName); STORE_STRING (pData, serverAddress); STORE_STRING (pData, hostAddress); STORE_STRING (pData, startOptions); if (authLen > 0) { STORE_STRING (pData, authName); memcpy (pData, authDataBinary, authLen); } IceFlush (iceConn); replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn); replyWait.major_opcode_of_request = PMopcode; replyWait.minor_opcode_of_request = PM_GetProxyAddr; replyWait.reply = (IcePointer) &reply; gotReply = False; ioErrorOccured = False; while (!gotReply && !ioErrorOccured) { ioErrorOccured = (IceProcessMessages ( iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); if (ioErrorOccured) { fprintf (stderr, "IO error occured\n"); exit (1); } else if (gotReply) { if (reply.status == PM_Success) { fprintf (stdout, "%s\n", reply.addr); exit (0); } else { fprintf (stderr, "Error from proxy manager: %s\n", reply.error); exit (1); } } } /*NOTREACHED*/ exit(0); }
/* * add displayname protocolname hexkey */ static int do_add(char *inputfilename, int lineno, int argc, char **argv) { int n, nnew, nrepl; int len; char *dpyname; char *protoname; char *hexkey; char *key; Xauth *auth; AuthList *list; if (argc != 4 || !argv[1] || !argv[2] || !argv[3]) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } dpyname = argv[1]; protoname = argv[2]; hexkey = argv[3]; len = strlen(hexkey); if (hexkey[0] == '"' && hexkey[len-1] == '"') { key = malloc(len-1); strncpy(key, hexkey+1, len-2); len -= 2; } else if (!strcmp(protoname, SECURERPC) || !strcmp(protoname, K5AUTH)) { key = malloc(len+1); strcpy(key, hexkey); } else { len = cvthexkey (hexkey, &key); if (len < 0) { prefix (inputfilename, lineno); fprintf (stderr, "key contains odd number of or non-hex characters\n"); return 1; } } auth = (Xauth *) malloc (sizeof (Xauth)); if (!auth) { prefix (inputfilename, lineno); fprintf (stderr, "unable to allocate %ld bytes for Xauth structure\n", (unsigned long)sizeof (Xauth)); free (key); return 1; } if (!get_displayname_auth (dpyname, auth)) { prefix (inputfilename, lineno); baddisplayname (dpyname, argv[0]); free (auth); free (key); return 1; } /* * allow an abbreviation for common protocol names */ if (strcmp (protoname, DEFAULT_PROTOCOL_ABBREV) == 0) { protoname = DEFAULT_PROTOCOL; } auth->name_length = strlen (protoname); auth->name = copystring (protoname, auth->name_length); if (!auth->name) { prefix (inputfilename, lineno); fprintf (stderr, "unable to allocate %d character protocol name\n", auth->name_length); free (auth); free (key); return 1; } auth->data_length = len; auth->data = key; list = (AuthList *) malloc (sizeof (AuthList)); if (!list) { prefix (inputfilename, lineno); fprintf (stderr, "unable to allocate %ld bytes for auth list\n", (unsigned long)sizeof (AuthList)); free (auth); free (key); free (auth->name); return 1; } list->next = NULL; list->auth = auth; /* * merge it in; note that merge will deal with allocation */ n = merge_entries (&xauth_head, list, &nnew, &nrepl); if (n <= 0) { prefix (inputfilename, lineno); fprintf (stderr, "unable to merge in added record\n"); return 1; } xauth_modified = True; return 0; }
/* * generate */ static int do_generate(const char *inputfilename, int lineno, int argc, const char **argv) { const char *displayname; int major_version, minor_version; XSecurityAuthorization id_return; Xauth *auth_in, *auth_return; XSecurityAuthorizationAttributes attributes; unsigned long attrmask = 0; Display *dpy; int status; const char *args[4]; const char *protoname = "."; int i; int authdatalen = 0; const char *hexdata; char *authdata = NULL; char *hex; if (argc < 2 || !argv[1]) { prefix (inputfilename, lineno); badcommandline (argv[0]); return 1; } displayname = argv[1]; if (argc > 2) { protoname = argv[2]; } for (i = 3; i < argc; i++) { if (0 == strcmp(argv[i], "timeout")) { if (++i == argc) { prefix (inputfilename, lineno); badcommandline (argv[i-1]); return 1; } attributes.timeout = atoi(argv[i]); attrmask |= XSecurityTimeout; } else if (0 == strcmp(argv[i], "trusted")) { attributes.trust_level = XSecurityClientTrusted; attrmask |= XSecurityTrustLevel; } else if (0 == strcmp(argv[i], "untrusted")) { attributes.trust_level = XSecurityClientUntrusted; attrmask |= XSecurityTrustLevel; } else if (0 == strcmp(argv[i], "group")) { if (++i == argc) { prefix (inputfilename, lineno); badcommandline (argv[i-1]); return 1; } attributes.group = atoi(argv[i]); attrmask |= XSecurityGroup; } else if (0 == strcmp(argv[i], "data")) { if (++i == argc) { prefix (inputfilename, lineno); badcommandline (argv[i-1]); return 1; } hexdata = argv[i]; authdatalen = strlen(hexdata); if (hexdata[0] == '"' && hexdata[authdatalen-1] == '"') { authdata = malloc(authdatalen-1); strncpy(authdata, hexdata+1, authdatalen-2); authdatalen -= 2; } else { authdatalen = cvthexkey (hexdata, &authdata); if (authdatalen < 0) { prefix (inputfilename, lineno); fprintf (stderr, "data contains odd number of or non-hex characters\n"); return 1; } } } else { prefix (inputfilename, lineno); badcommandline (argv[i]); return 1; } } /* generate authorization using the Security extension */ dpy = XOpenDisplay (displayname); if (!dpy) { prefix (inputfilename, lineno); fprintf (stderr, "unable to open display \"%s\".\n", displayname); return 1; } status = XSecurityQueryExtension(dpy, &major_version, &minor_version); if (!status) { prefix (inputfilename, lineno); fprintf (stderr, "couldn't query Security extension on display \"%s\"\n", displayname); return 1; } /* fill in input Xauth struct */ auth_in = XSecurityAllocXauth(); if (strcmp (protoname, DEFAULT_PROTOCOL_ABBREV) == 0) { auth_in->name = copystring(DEFAULT_PROTOCOL, strlen(DEFAULT_PROTOCOL)); } else auth_in->name = copystring (protoname, strlen(protoname)); auth_in->name_length = strlen(auth_in->name); auth_in->data = authdata; auth_in->data_length = authdatalen; x_protocol_error = 0; XSetErrorHandler(catch_x_protocol_error); auth_return = XSecurityGenerateAuthorization(dpy, auth_in, attrmask, &attributes, &id_return); XSync(dpy, False); if (!auth_return || x_protocol_error) { prefix (inputfilename, lineno); fprintf (stderr, "couldn't generate authorization\n"); return 1; } if (verbose) printf("authorization id is %ld\n", id_return); /* create a fake input line to give to do_add */ hex = bintohex(auth_return->data_length, auth_return->data); args[0] = "add"; args[1] = displayname; args[2] = auth_in->name; args[3] = hex; status = do_add(inputfilename, lineno, 4, args); if (authdata) free(authdata); XSecurityFreeXauth(auth_in); XSecurityFreeXauth(auth_return); free(hex); XCloseDisplay(dpy); return status; }