]> sourceware.org Git - systemtap.git/commitdiff
PR 11862: remove obsolete stap-client script and friends
authorDave Brolley <brolley@redhat.com>
Wed, 19 Jan 2011 22:15:31 +0000 (17:15 -0500)
committerDave Brolley <brolley@redhat.com>
Fri, 21 Jan 2011 17:37:42 +0000 (12:37 -0500)
- Integrate stap-client-connect.c into csclient.cxx
- Remove stap-client-connect.c

Makefile.am
Makefile.in
csclient.cxx
stap-client-connect.c [deleted file]

index 9bd5f673047e7d1e013bb70d865d925b99f3942c..e99c26b6a0aa39c6a72042681874bbe98e94b0fc 100644 (file)
@@ -111,7 +111,7 @@ stap_LDADD += -lavahi-client -lavahi-common
 endif
 
 if HAVE_NSS
-stap_SOURCES += stap-client-connect.c nsscommon.c
+stap_SOURCES += nsscommon.c
 stap_CFLAGS += $(nss_CFLAGS) $(nspr_CFLAGS) -DSTAP
 stap_CXXFLAGS += $(nss_CFLAGS) $(nspr_CFLAGS)
 stap_CPPFLAGS += $(nss_CFLAGS) $(nspr_CFLAGS)
index b492f54fa5551b65c9815d564607c0b2bf2c8cc0..5a32a658d8e30a25938863c45d8a3f8d143af149 100644 (file)
@@ -50,7 +50,7 @@ bin_PROGRAMS = $(am__EXEEXT_1)
 @BUILD_TRANSLATOR_TRUE@@HAVE_AVAHI_TRUE@am__append_10 = $(avahi_CFLAGS)
 @BUILD_TRANSLATOR_TRUE@@HAVE_AVAHI_TRUE@am__append_11 = $(avahi_CFLAGS)
 @BUILD_TRANSLATOR_TRUE@@HAVE_AVAHI_TRUE@am__append_12 = -lavahi-client -lavahi-common
-@BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__append_13 = stap-client-connect.c nsscommon.c
+@BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__append_13 = nsscommon.c
 @BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__append_14 = $(nss_CFLAGS) $(nspr_CFLAGS) -DSTAP
 @BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__append_15 = $(nss_CFLAGS) $(nspr_CFLAGS)
 @BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__append_16 = $(nss_CFLAGS) $(nspr_CFLAGS)
@@ -107,8 +107,7 @@ am__DEPENDENCIES_1 =
 @BUILD_TRANSLATOR_TRUE@        $(am__DEPENDENCIES_2)
 loc2c_test_LINK = $(CCLD) $(loc2c_test_CFLAGS) $(CFLAGS) \
        $(loc2c_test_LDFLAGS) $(LDFLAGS) -o $@
-@BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__objects_1 = stap-stap-client-connect.$(OBJEXT) \
-@BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@ stap-nsscommon.$(OBJEXT)
+@BUILD_TRANSLATOR_TRUE@@HAVE_NSS_TRUE@am__objects_1 = stap-nsscommon.$(OBJEXT)
 @BUILD_TRANSLATOR_TRUE@am_stap_OBJECTS = stap-main.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-session.$(OBJEXT) \
 @BUILD_TRANSLATOR_TRUE@        stap-parse.$(OBJEXT) \
@@ -695,7 +694,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-rpm_finder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-session.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-setupdwfl.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-stap-client-connect.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-staptree.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-been.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-itrace.Po@am__quote@
@@ -793,22 +791,6 @@ stap-mdfour.obj: mdfour.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CFLAGS) $(CFLAGS) -c -o stap-mdfour.obj `if test -f 'mdfour.c'; then $(CYGPATH_W) 'mdfour.c'; else $(CYGPATH_W) '$(srcdir)/mdfour.c'; fi`
 
-stap-stap-client-connect.o: stap-client-connect.c
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CFLAGS) $(CFLAGS) -MT stap-stap-client-connect.o -MD -MP -MF $(DEPDIR)/stap-stap-client-connect.Tpo -c -o stap-stap-client-connect.o `test -f 'stap-client-connect.c' || echo '$(srcdir)/'`stap-client-connect.c
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/stap-stap-client-connect.Tpo $(DEPDIR)/stap-stap-client-connect.Po
-@am__fastdepCC_FALSE@  $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='stap-client-connect.c' object='stap-stap-client-connect.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CFLAGS) $(CFLAGS) -c -o stap-stap-client-connect.o `test -f 'stap-client-connect.c' || echo '$(srcdir)/'`stap-client-connect.c
-
-stap-stap-client-connect.obj: stap-client-connect.c
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CFLAGS) $(CFLAGS) -MT stap-stap-client-connect.obj -MD -MP -MF $(DEPDIR)/stap-stap-client-connect.Tpo -c -o stap-stap-client-connect.obj `if test -f 'stap-client-connect.c'; then $(CYGPATH_W) 'stap-client-connect.c'; else $(CYGPATH_W) '$(srcdir)/stap-client-connect.c'; fi`
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/stap-stap-client-connect.Tpo $(DEPDIR)/stap-stap-client-connect.Po
-@am__fastdepCC_FALSE@  $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='stap-client-connect.c' object='stap-stap-client-connect.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CFLAGS) $(CFLAGS) -c -o stap-stap-client-connect.obj `if test -f 'stap-client-connect.c'; then $(CYGPATH_W) 'stap-client-connect.c'; else $(CYGPATH_W) '$(srcdir)/stap-client-connect.c'; fi`
-
 stap-nsscommon.o: nsscommon.c
 @am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CFLAGS) $(CFLAGS) -MT stap-nsscommon.o -MD -MP -MF $(DEPDIR)/stap-nsscommon.Tpo -c -o stap-nsscommon.o `test -f 'nsscommon.c' || echo '$(srcdir)/'`nsscommon.c
 @am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/stap-nsscommon.Tpo $(DEPDIR)/stap-nsscommon.Po
index 887bfd185c22b5b728e4d8a1760e6ab953800afb..fe91187949b5b1e8671262168a2c03dd20e40f0e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  Compile server client functions
- Copyright (C) 2010 Red Hat Inc.
+ Copyright (C) 2010-2011 Red Hat Inc.
 
  This file is part of systemtap, and is free software.  You can
  redistribute it and/or modify it under the terms of the GNU General
@@ -142,8 +142,9 @@ static void merge_server_info (const vector<compile_server_info> &source, vector
 static void resolve_host (systemtap_session& s, compile_server_info &server, vector<compile_server_info> &servers);
 
 #if HAVE_NSS
-static const char *server_cert_nickname = "stap-server";
-
+// -----------------------------------------------------
+// NSS related code used by the compile server client
+// -----------------------------------------------------
 static void add_server_trust (systemtap_session &s, const string &cert_db_path, const vector<compile_server_info> &server_list);
 static void revoke_server_trust (systemtap_session &s, const string &cert_db_path, const vector<compile_server_info> &server_list);
 static void get_server_info_from_db (systemtap_session &s, vector<compile_server_info> &servers, const string &cert_db_path);
@@ -165,6 +166,489 @@ signing_cert_db_path ()
 {
   return SYSCONFDIR "/systemtap/staprun";
 }
+
+static const char *server_cert_nickname = "stap-server";
+
+/* Connection state.  */
+typedef struct connectionState_t
+{
+  const char *hostName;
+  PRNetAddr   addr;
+  PRUint16    port;
+  const char *infileName;
+  const char *outfileName;
+  const char *trustNewServerMode;
+} connectionState_t;
+
+#if 0 /* No client authorization */
+static char *
+myPasswd(PK11SlotInfo *info, PRBool retry, void *arg)
+{
+  char * passwd = NULL;
+
+  if ( (!retry) && arg )
+    passwd = PORT_Strdup((char *)arg);
+
+  return passwd;
+}
+#endif
+
+/* Add the server's certificate to our database of trusted servers.  */
+static SECStatus
+trustNewServer (CERTCertificate *serverCert)
+{
+  SECStatus secStatus;
+  CERTCertTrust *trust = NULL;
+  PK11SlotInfo *slot;
+
+  /* Import the certificate.  */
+  slot = PK11_GetInternalKeySlot();;
+  secStatus = PK11_ImportCert(slot, serverCert, CK_INVALID_HANDLE, "stap-server", PR_FALSE);
+  if (secStatus != SECSuccess)
+    goto done;
+  
+  /* Make it a trusted peer.  */
+  trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
+  if (! trust)
+    {
+      secStatus = SECFailure;
+      goto done;
+    }
+
+  secStatus = CERT_DecodeTrustString(trust, "P,P,P");
+  if (secStatus != SECSuccess)
+    goto done;
+
+  secStatus = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), serverCert, trust);
+  if (secStatus != SECSuccess)
+    goto done;
+
+done:
+  if (trust)
+    PORT_Free(trust);
+  return secStatus;
+}
+
+/* Called when the server certificate verification fails. This gives us
+   the chance to trust the server anyway and add the certificate to the
+   local database.  */
+static SECStatus
+badCertHandler(void *arg, PRFileDesc *sslSocket)
+{
+  SECStatus secStatus;
+  PRErrorCode errorNumber;
+  CERTCertificate *serverCert;
+  SECItem subAltName;
+  PRArenaPool *tmpArena = NULL;
+  CERTGeneralName *nameList, *current;
+  char *expected = NULL;
+  const connectionState_t *connectionState = (connectionState_t *)arg;
+
+  errorNumber = PR_GetError ();
+  switch (errorNumber)
+    {
+    case SSL_ERROR_BAD_CERT_DOMAIN:
+      /* Since we administer our own client-side databases of trustworthy
+        certificates, we don't need the domain name(s) on the certificate to
+        match. If the cert is in our database, then we can trust it.
+        Issue a warning and accept the certificate.  */
+      expected = SSL_RevealURL (sslSocket);
+      fprintf (stderr, "WARNING: The domain name, %s, does not match the DNS name(s) on the server certificate:\n", expected);
+
+      /* List the DNS names from the server cert as part of the warning.
+        First, find the alt-name extension on the certificate.  */
+      subAltName.data = NULL;
+      serverCert = SSL_PeerCertificate (sslSocket);
+      secStatus = CERT_FindCertExtension (serverCert,
+                                         SEC_OID_X509_SUBJECT_ALT_NAME,
+                                         & subAltName);
+      if (secStatus != SECSuccess || ! subAltName.data)
+       {
+         fprintf (stderr, "Unable to find alt name extension on the server certificate\n");
+         secStatus = SECSuccess; /* Not a fatal error */
+         break;
+       }
+
+      // Now, decode the extension.
+      tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+      if (! tmpArena) 
+       {
+         fprintf (stderr, "Out of memory\n");
+         secStatus = SECSuccess; /* Not a fatal error here */
+         break;
+       }
+      nameList = CERT_DecodeAltNameExtension (tmpArena, & subAltName);
+      SECITEM_FreeItem(& subAltName, PR_FALSE);
+      if (! nameList)
+       {
+         fprintf (stderr, "Unable to decode alt name extension on server certificate\n");
+         secStatus = SECSuccess; /* Not a fatal error */
+         break;
+       }
+
+      /* List the DNS names from the server cert as part of the warning.
+        The names are in a circular list.  */
+      current = nameList;
+      do
+       {
+         /* Make sure this is a DNS name.  */
+         if (current->type == certDNSName)
+           {
+             fprintf (stderr, "  %.*s\n",
+                      (int)current->name.other.len, current->name.other.data);
+           }
+         current = CERT_GetNextGeneralName (current);
+       }
+      while (current != nameList);
+
+      /* Accept the certificate */
+      secStatus = SECSuccess;
+      break;
+
+    case SEC_ERROR_CA_CERT_INVALID:
+      /* The server's certificate is not trusted. Should we trust it? */
+      secStatus = SECFailure; /* Do not trust by default. */
+      if (! connectionState->trustNewServerMode)
+       break;
+
+      /* Trust it for this session only?  */
+      if (strcmp (connectionState->trustNewServerMode, "session") == 0)
+       {
+         secStatus = SECSuccess;
+         break;
+       }
+
+      /* Trust it permanently?  */
+      if (strcmp (connectionState->trustNewServerMode, "permanent") == 0)
+       {
+         /* The user wants to trust this server. Get the server's certificate so
+            and add it to our database.  */
+         serverCert = SSL_PeerCertificate (sslSocket);
+         if (serverCert != NULL)
+           secStatus = trustNewServer (serverCert);
+       }
+      break;
+    default:
+      secStatus = SECFailure; /* Do not trust this server */
+      break;
+    }
+
+  if (expected)
+    PORT_Free (expected);
+  if (tmpArena)
+    PORT_FreeArena (tmpArena, PR_FALSE);
+
+  return secStatus;
+}
+
+static PRFileDesc *
+setupSSLSocket (connectionState_t *connectionState)
+{
+  PRFileDesc         *tcpSocket;
+  PRFileDesc         *sslSocket;
+  PRSocketOptionData   socketOption;
+  PRStatus            prStatus;
+  SECStatus           secStatus;
+
+  tcpSocket = PR_NewTCPSocket();
+  if (tcpSocket == NULL)
+    goto loser;
+
+  /* Make the socket blocking. */
+  socketOption.option = PR_SockOpt_Nonblocking;
+  socketOption.value.non_blocking = PR_FALSE;
+
+  prStatus = PR_SetSocketOption(tcpSocket, &socketOption);
+  if (prStatus != PR_SUCCESS)
+    goto loser;
+
+  /* Import the socket into the SSL layer. */
+  sslSocket = SSL_ImportFD(NULL, tcpSocket);
+  if (!sslSocket)
+    goto loser;
+
+  /* Set configuration options. */
+  secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
+  if (secStatus != SECSuccess)
+    goto loser;
+
+  secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
+  if (secStatus != SECSuccess)
+    goto loser;
+
+  /* Set SSL callback routines. */
+#if 0 /* no client authentication */
+  secStatus = SSL_GetClientAuthDataHook(sslSocket,
+                                       (SSLGetClientAuthData)myGetClientAuthData,
+                                       (void *)certNickname);
+  if (secStatus != SECSuccess)
+    goto loser;
+#endif
+#if 0 /* Use the default */
+  secStatus = SSL_AuthCertificateHook(sslSocket,
+                                     (SSLAuthCertificate)myAuthCertificate,
+                                     (void *)CERT_GetDefaultCertDB());
+  if (secStatus != SECSuccess)
+    goto loser;
+#endif
+
+  secStatus = SSL_BadCertHook(sslSocket, (SSLBadCertHandler)badCertHandler,
+                             connectionState);
+  if (secStatus != SECSuccess)
+    goto loser;
+
+#if 0 /* No handshake callback */
+  secStatus = SSL_HandshakeCallback(sslSocket, myHandshakeCallback, NULL);
+  if (secStatus != SECSuccess)
+    goto loser;
+#endif
+
+  return sslSocket;
+
+ loser:
+  if (tcpSocket)
+    PR_Close(tcpSocket);
+  return NULL;
+}
+
+
+static SECStatus
+handle_connection (PRFileDesc *sslSocket, connectionState_t *connectionState)
+{
+  PRInt32     numBytes;
+  char       *readBuffer;
+  PRFileInfo  info;
+  PRFileDesc *local_file_fd;
+  PRStatus    prStatus;
+  SECStatus   secStatus = SECSuccess;
+
+#define READ_BUFFER_SIZE (60 * 1024)
+
+  /* read and send the data. */
+  /* Try to open the local file named. 
+   * If successful, then write it to the server
+   */
+  prStatus = PR_GetFileInfo(connectionState->infileName, &info);
+  if (prStatus != PR_SUCCESS ||
+      info.type != PR_FILE_FILE ||
+      info.size < 0)
+    {
+      fprintf (stderr, "could not find input file %s\n",
+              connectionState->infileName);
+      return SECFailure;
+    }
+
+  local_file_fd = PR_Open(connectionState->infileName, PR_RDONLY, 0);
+  if (local_file_fd == NULL)
+    {
+      fprintf (stderr, "could not open input file %s\n", connectionState->infileName);
+      return SECFailure;
+    }
+
+  /* Send the file size first, so the server knows when it has the entire file. */
+  numBytes = htonl ((PRInt32)info.size);
+  numBytes = PR_Write(sslSocket, & numBytes, sizeof (numBytes));
+  if (numBytes < 0)
+    {
+      PR_Close(local_file_fd);
+      return SECFailure;
+    }
+
+  /* Transmit the local file across the socket.  */
+  numBytes = PR_TransmitFile(sslSocket, local_file_fd, 
+                            NULL, 0,
+                            PR_TRANSMITFILE_KEEP_OPEN,
+                            PR_INTERVAL_NO_TIMEOUT);
+  if (numBytes < 0)
+    {
+      PR_Close(local_file_fd);
+      return SECFailure;
+    }
+
+  PR_Close(local_file_fd);
+
+  /* read until EOF */
+  readBuffer = (char *)PORT_Alloc(READ_BUFFER_SIZE);
+  if (! readBuffer) {
+    fprintf (stderr, "Out of memory\n");
+    return SECFailure;
+  }
+
+  local_file_fd = PR_Open(connectionState->outfileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
+                         PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH);
+  if (local_file_fd == NULL)
+    {
+      fprintf (stderr, "Unable to open output file %s\n", connectionState->outfileName);
+      return SECFailure;
+    }
+  while (PR_TRUE)
+    {
+      numBytes = PR_Read(sslSocket, readBuffer, READ_BUFFER_SIZE);
+      if (numBytes == 0)
+       break;  /* EOF */
+
+      if (numBytes < 0)
+       {
+         secStatus = SECFailure;
+         break;
+       }
+
+      /* Write to output file */
+      numBytes = PR_Write(local_file_fd, readBuffer, numBytes);
+      if (numBytes < 0)
+       {
+         fprintf (stderr, "could not write to %s\n", connectionState->outfileName);
+         secStatus = SECFailure;
+         break;
+       }
+    }
+
+  PR_Free(readBuffer);
+  PR_Close(local_file_fd);
+
+  /* Caller closes the socket. */
+  return secStatus;
+}
+
+/* make the connection.
+*/
+static SECStatus
+do_connect (connectionState_t *connectionState)
+{
+  PRFileDesc *sslSocket;
+  PRStatus    prStatus;
+  SECStatus   secStatus;
+
+  secStatus = SECSuccess;
+
+  /* Set up SSL secure socket. */
+  sslSocket = setupSSLSocket (connectionState);
+  if (sslSocket == NULL)
+    return SECFailure;
+
+#if 0 /* no client authentication */
+  secStatus = SSL_SetPKCS11PinArg(sslSocket, password);
+  if (secStatus != SECSuccess)
+    goto done;
+#endif
+
+  secStatus = SSL_SetURL(sslSocket, connectionState->hostName);
+  if (secStatus != SECSuccess)
+    goto done;
+
+  prStatus = PR_Connect(sslSocket, & connectionState->addr, PR_INTERVAL_NO_TIMEOUT);
+  if (prStatus != PR_SUCCESS)
+    {
+      secStatus = SECFailure;
+      goto done;
+    }
+
+  /* Established SSL connection, ready to send data. */
+  secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE);
+  if (secStatus != SECSuccess)
+    goto done;
+
+  /* This is normally done automatically on the first I/O operation,
+     but doing it here catches any authentication problems early.  */
+  secStatus = SSL_ForceHandshake(sslSocket);
+  if (secStatus != SECSuccess)
+    goto done;
+
+  /* If we don't have both the input and output file names, then we're
+     contacting this server only in order to establish trust. No need to
+     handle the connection in this case.  */
+  if (connectionState->infileName && connectionState->outfileName)
+    secStatus = handle_connection(sslSocket, connectionState);
+
+ done:
+  prStatus = PR_Close(sslSocket);
+  return secStatus;
+}
+
+/* Exit error codes */
+#define SUCCESS               0
+#define GENERAL_ERROR         1
+#define CA_CERT_INVALID_ERROR 2
+
+int
+client_connect (const char *hostName, PRUint32 ip,
+            PRUint16 port,
+            const char* infileName, const char* outfileName,
+            const char* trustNewServer)
+{
+  SECStatus   secStatus;
+  PRStatus    prStatus;
+  PRInt32     rv;
+  PRHostEnt   hostEntry;
+  PRErrorCode errorNumber;
+  char        buffer[PR_NETDB_BUF_SIZE];
+  int         attempt;
+  int         errCode = GENERAL_ERROR;
+  struct connectionState_t connectionState;
+
+  connectionState.hostName = hostName;
+  connectionState.port = port;
+  connectionState.infileName = infileName;
+  connectionState.outfileName = outfileName;
+  connectionState.trustNewServerMode = trustNewServer;
+
+  /* Setup network connection. If we have an ip address, then
+     simply use it, otherwise we need to resolve the host name.  */
+  if (ip)
+    {
+      connectionState.addr.inet.family = PR_AF_INET;
+      connectionState.addr.inet.port = htons (port);
+      connectionState.addr.inet.ip = htonl (ip);
+    }
+  else
+    {
+      prStatus = PR_GetHostByName(hostName, buffer, sizeof (buffer), &hostEntry);
+      if (prStatus != PR_SUCCESS) {
+       fprintf (stderr, "Unable to resolve server host name");
+       return errCode;
+      }
+
+      rv = PR_EnumerateHostEnt(0, &hostEntry, port, &connectionState.addr);
+      if (rv < 0) {
+       fprintf (stderr, "Unable to resolve server host address");
+       return errCode;
+      }
+    }
+
+  /* Some errors (see below) represent a situation in which trying again
+     should succeed. However, don't try forever.  */
+  for (attempt = 0; attempt < 5; ++attempt)
+    {
+      secStatus = do_connect (& connectionState);
+      if (secStatus == SECSuccess)
+       return SUCCESS;
+
+      errorNumber = PR_GetError ();
+      switch (errorNumber)
+       {
+       case PR_CONNECT_RESET_ERROR:
+         /* Server was not ready. */
+         sleep (1);
+         break; /* Try again */
+       case SEC_ERROR_EXPIRED_CERTIFICATE:
+         /* The server's certificate has expired. It should
+            generate a new certificate. Give the server a chance to recover
+            and try again.  */
+         sleep (2);
+         break; /* Try again */
+       case SEC_ERROR_CA_CERT_INVALID:
+         /* The server's certificate is not trusted. The exit code must
+            reflect this.  */
+         errCode = CA_CERT_INVALID_ERROR;
+         return errCode;
+       default:
+         /* This error is fatal.  */
+         return errCode;
+       }
+    }
+
+  return errCode;
+}
 #endif // HAVE_NSS
 
 int
@@ -556,13 +1040,6 @@ compile_server_client::find_and_connect_to_server ()
 
   return 1; // Failure - message already generated.
 }
-
-// Temporary until the stap-client-connect program goes away.
-extern "C"
-int
-client_main (const char *hostName, PRUint32 ip, PRUint16 port,
-            const char* infileName, const char* outfileName,
-            const char* trustNewServer);
 #endif // HAVE_NSS
 
 // Convert the given string to an ip address in host byte order.
@@ -664,7 +1141,7 @@ compile_server_client::compile_using_server (
          else
            hostName = j->host_name;
 
-         rc = client_main (hostName.c_str (),
+         rc = client_connect (hostName.c_str (),
                            stringToIpAddress (j->ip_address),
                            j->port,
                            client_zipfile.c_str(), server_zipfile.c_str (),
@@ -1359,7 +1836,7 @@ add_server_trust (
 
   // Iterate over the servers to become trusted. Contact each one and
   // add it to the list of trusted servers if it is not already trusted.
-  // client_main will issue any error messages.
+  // client_connect will issue any error messages.
   for (vector<compile_server_info>::const_iterator server = server_list.begin();
        server != server_list.end ();
        ++server)
@@ -1383,7 +1860,7 @@ add_server_trust (
       // number in order to contact the server.
       if (server->empty () || server->port == 0)
        continue;
-      int rc = client_main (server->host_name.c_str (),
+      int rc = client_connect (server->host_name.c_str (),
                            stringToIpAddress (server->ip_address),
                            server->port,
                            NULL, NULL, "permanent");
diff --git a/stap-client-connect.c b/stap-client-connect.c
deleted file mode 100644 (file)
index d6626db..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
-  SSL client program that sets up a connection to a SSL server, transmits
-  the given input file and then writes the reply to the given output file.
-
-  Copyright (C) 2008-2011 Red Hat Inc.
-
-  This file is part of systemtap, and is free software.  You can
-  redistribute it and/or modify it under the terms of the GNU General Public
-  License as published by the Free Software Foundation; either version 2 of the
-  License, or (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-
-#include <ssl.h>
-#include <nspr.h>
-#include <plgetopt.h>
-#include <nss.h>
-#include <pk11pub.h>
-#include <prerror.h>
-#include <secerr.h>
-#include <sslerr.h>
-
-#include "nsscommon.h"
-
-#include <assert.h>
-
-#define READ_BUFFER_SIZE (60 * 1024)
-static const char *trustNewServer_p = NULL;
-
-
-#if 0 /* No client authorization */
-static char *
-myPasswd(PK11SlotInfo *info, PRBool retry, void *arg)
-{
-  char * passwd = NULL;
-
-  if ( (!retry) && arg )
-    passwd = PORT_Strdup((char *)arg);
-
-  return passwd;
-}
-#endif
-
-/* Add the server's certificate to our database of trusted servers.  */
-static SECStatus
-trustNewServer (CERTCertificate *serverCert)
-{
-  SECStatus secStatus;
-  CERTCertTrust *trust = NULL;
-  PK11SlotInfo *slot;
-
-  /* Import the certificate.  */
-  slot = PK11_GetInternalKeySlot();;
-  secStatus = PK11_ImportCert(slot, serverCert, CK_INVALID_HANDLE, "stap-server", PR_FALSE);
-  if (secStatus != SECSuccess)
-    goto done;
-  
-  /* Make it a trusted peer.  */
-  trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));
-  if (! trust)
-    {
-      secStatus = SECFailure;
-      goto done;
-    }
-
-  secStatus = CERT_DecodeTrustString(trust, "P,P,P");
-  if (secStatus != SECSuccess)
-    goto done;
-
-  secStatus = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), serverCert, trust);
-  if (secStatus != SECSuccess)
-    goto done;
-
-done:
-  if (trust)
-    PORT_Free(trust);
-  return secStatus;
-}
-
-/* Called when the server certificate verification fails. This gives us
-   the chance to trust the server anyway and add the certificate to the
-   local database.  */
-static SECStatus
-badCertHandler(void *arg __attribute__ ((unused)), PRFileDesc *sslSocket)
-{
-  SECStatus secStatus;
-  PRErrorCode errorNumber;
-  CERTCertificate *serverCert;
-  SECItem subAltName;
-  PRArenaPool *tmpArena = NULL;
-  CERTGeneralName *nameList, *current;
-  char *expected = NULL;
-
-  errorNumber = PR_GetError ();
-  switch (errorNumber)
-    {
-    case SSL_ERROR_BAD_CERT_DOMAIN:
-      /* Since we administer our own client-side databases of trustworthy
-        certificates, we don't need the domain name(s) on the certificate to
-        match. If the cert is in our database, then we can trust it.
-        Issue a warning and accept the certificate.  */
-      expected = SSL_RevealURL (sslSocket);
-      fprintf (stderr, "WARNING: The domain name, %s, does not match the DNS name(s) on the server certificate:\n", expected);
-
-      /* List the DNS names from the server cert as part of the warning.
-        First, find the alt-name extension on the certificate.  */
-      subAltName.data = NULL;
-      serverCert = SSL_PeerCertificate (sslSocket);
-      secStatus = CERT_FindCertExtension (serverCert,
-                                         SEC_OID_X509_SUBJECT_ALT_NAME,
-                                         & subAltName);
-      if (secStatus != SECSuccess || ! subAltName.data)
-       {
-         fprintf (stderr, "Unable to find alt name extension on the server certificate\n");
-         secStatus = SECSuccess; /* Not a fatal error */
-         break;
-       }
-
-      // Now, decode the extension.
-      tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-      if (! tmpArena) 
-       {
-         fprintf (stderr, "Out of memory\n");
-         secStatus = SECSuccess; /* Not a fatal error here */
-         break;
-       }
-      nameList = CERT_DecodeAltNameExtension (tmpArena, & subAltName);
-      SECITEM_FreeItem(& subAltName, PR_FALSE);
-      if (! nameList)
-       {
-         fprintf (stderr, "Unable to decode alt name extension on server certificate\n");
-         secStatus = SECSuccess; /* Not a fatal error */
-         break;
-       }
-
-      /* List the DNS names from the server cert as part of the warning.
-        The names are in a circular list.  */
-      current = nameList;
-      do
-       {
-         /* Make sure this is a DNS name.  */
-         if (current->type == certDNSName)
-           {
-             fprintf (stderr, "  %.*s\n",
-                      (int)current->name.other.len, current->name.other.data);
-           }
-         current = CERT_GetNextGeneralName (current);
-       }
-      while (current != nameList);
-
-      /* Accept the certificate */
-      secStatus = SECSuccess;
-      break;
-
-    case SEC_ERROR_CA_CERT_INVALID:
-      /* The server's certificate is not trusted. Should we trust it? */
-      secStatus = SECFailure; /* Do not trust by default. */
-      if (trustNewServer_p == NULL)
-       break;
-
-      /* Trust it for this session only?  */
-      if (strcmp (trustNewServer_p, "session") == 0)
-       {
-         secStatus = SECSuccess;
-         break;
-       }
-
-      /* Trust it permanently?  */
-      if (strcmp (trustNewServer_p, "permanent") == 0)
-       {
-         /* The user wants to trust this server. Get the server's certificate so
-            and add it to our database.  */
-         serverCert = SSL_PeerCertificate (sslSocket);
-         if (serverCert != NULL)
-           secStatus = trustNewServer (serverCert);
-       }
-      break;
-    default:
-      secStatus = SECFailure; /* Do not trust this server */
-      break;
-    }
-
-  if (expected)
-    PORT_Free (expected);
-  if (tmpArena)
-    PORT_FreeArena (tmpArena, PR_FALSE);
-
-  return secStatus;
-}
-
-static PRFileDesc *
-setupSSLSocket(void)
-{
-  PRFileDesc         *tcpSocket;
-  PRFileDesc         *sslSocket;
-  PRSocketOptionData   socketOption;
-  PRStatus            prStatus;
-  SECStatus           secStatus;
-
-  tcpSocket = PR_NewTCPSocket();
-  if (tcpSocket == NULL)
-    goto loser;
-
-  /* Make the socket blocking. */
-  socketOption.option = PR_SockOpt_Nonblocking;
-  socketOption.value.non_blocking = PR_FALSE;
-
-  prStatus = PR_SetSocketOption(tcpSocket, &socketOption);
-  if (prStatus != PR_SUCCESS)
-    goto loser;
-
-  /* Import the socket into the SSL layer. */
-  sslSocket = SSL_ImportFD(NULL, tcpSocket);
-  if (!sslSocket)
-    goto loser;
-
-  /* Set configuration options. */
-  secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE);
-  if (secStatus != SECSuccess)
-    goto loser;
-
-  secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
-  if (secStatus != SECSuccess)
-    goto loser;
-
-  /* Set SSL callback routines. */
-#if 0 /* no client authentication */
-  secStatus = SSL_GetClientAuthDataHook(sslSocket,
-                                       (SSLGetClientAuthData)myGetClientAuthData,
-                                       (void *)certNickname);
-  if (secStatus != SECSuccess)
-    goto loser;
-#endif
-#if 0 /* Use the default */
-  secStatus = SSL_AuthCertificateHook(sslSocket,
-                                     (SSLAuthCertificate)myAuthCertificate,
-                                     (void *)CERT_GetDefaultCertDB());
-  if (secStatus != SECSuccess)
-    goto loser;
-#endif
-
-  secStatus = SSL_BadCertHook(sslSocket, (SSLBadCertHandler)badCertHandler, NULL);
-  if (secStatus != SECSuccess)
-    goto loser;
-
-#if 0 /* No handshake callback */
-  secStatus = SSL_HandshakeCallback(sslSocket, myHandshakeCallback, NULL);
-  if (secStatus != SECSuccess)
-    goto loser;
-#endif
-
-  return sslSocket;
-
- loser:
-  if (tcpSocket)
-    PR_Close(tcpSocket);
-  return NULL;
-}
-
-
-static SECStatus
-handle_connection(
-  PRFileDesc *sslSocket, const char *infileName, const char *outfileName
-)
-{
-#if DEBUG
-  int        countRead = 0;
-#endif
-  PRInt32     numBytes;
-  char       *readBuffer;
-  PRFileInfo  info;
-  PRFileDesc *local_file_fd;
-  PRStatus    prStatus;
-  SECStatus   secStatus = SECSuccess;
-
-  /* read and send the data. */
-  /* Try to open the local file named. 
-   * If successful, then write it to the server
-   */
-  prStatus = PR_GetFileInfo(infileName, &info);
-  if (prStatus != PR_SUCCESS ||
-      info.type != PR_FILE_FILE ||
-      info.size < 0)
-    {
-      fprintf (stderr, "could not find input file %s\n", infileName);
-      return SECFailure;
-    }
-
-  local_file_fd = PR_Open(infileName, PR_RDONLY, 0);
-  if (local_file_fd == NULL)
-    {
-      fprintf (stderr, "could not open input file %s\n", infileName);
-      return SECFailure;
-    }
-
-  /* Send the file size first, so the server knows when it has the entire file. */
-  numBytes = htonl ((PRInt32)info.size);
-  numBytes = PR_Write(sslSocket, & numBytes, sizeof (numBytes));
-  if (numBytes < 0)
-    {
-      PR_Close(local_file_fd);
-      return SECFailure;
-    }
-
-  /* Transmit the local file across the socket.  */
-  numBytes = PR_TransmitFile(sslSocket, local_file_fd, 
-                            NULL, 0,
-                            PR_TRANSMITFILE_KEEP_OPEN,
-                            PR_INTERVAL_NO_TIMEOUT);
-  if (numBytes < 0)
-    {
-      PR_Close(local_file_fd);
-      return SECFailure;
-    }
-
-#if DEBUG
-  /* Transmitted bytes successfully. */
-  fprintf(stderr, "PR_TransmitFile wrote %d bytes from %s\n",
-         numBytes, infileName);
-#endif
-
-  PR_Close(local_file_fd);
-
-  /* read until EOF */
-  readBuffer = PORT_Alloc(READ_BUFFER_SIZE);
-  if (! readBuffer) {
-    fprintf (stderr, "Out of memory\n");
-    return SECFailure;
-  }
-
-  local_file_fd = PR_Open(outfileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
-                         PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH);
-  if (local_file_fd == NULL)
-    {
-      fprintf (stderr, "Unable to open output file %s\n", outfileName);
-      return SECFailure;
-    }
-  while (PR_TRUE)
-    {
-      numBytes = PR_Read(sslSocket, readBuffer, READ_BUFFER_SIZE);
-      if (numBytes == 0)
-       break;  /* EOF */
-
-      if (numBytes < 0)
-       {
-         secStatus = SECFailure;
-         break;
-       }
-#if DEBUG
-      countRead += numBytes;
-#endif
-      /* Write to output file */
-      numBytes = PR_Write(local_file_fd, readBuffer, numBytes);
-      if (numBytes < 0)
-       {
-         fprintf (stderr, "could not write to %s\n", outfileName);
-         secStatus = SECFailure;
-         break;
-       }
-#if DEBUG
-      fprintf(stderr, "***** Connection read %d bytes (%d total).\n", 
-             numBytes, countRead );
-      readBuffer[numBytes] = '\0';
-      fprintf(stderr, "************\n%s\n************\n", readBuffer);
-#endif
-    }
-
-  PR_Free(readBuffer);
-  PR_Close(local_file_fd);
-
-  /* Caller closes the socket. */
-#if DEBUG
-  fprintf(stderr, "***** Connection read %d bytes total.\n", countRead);
-#endif
-
-  return secStatus;
-}
-
-/* make the connection.
-*/
-static SECStatus
-do_connect(
-  PRNetAddr *addr,
-  const char *hostName,
-  unsigned short port __attribute__ ((unused)),
-  const char *infileName,
-  const char *outfileName
-)
-{
-  PRFileDesc *sslSocket;
-  PRStatus    prStatus;
-  SECStatus   secStatus;
-
-  secStatus = SECSuccess;
-
-  /* Set up SSL secure socket. */
-  sslSocket = setupSSLSocket();
-  if (sslSocket == NULL)
-    return SECFailure;
-
-#if 0 /* no client authentication */
-  secStatus = SSL_SetPKCS11PinArg(sslSocket, password);
-  if (secStatus != SECSuccess)
-    goto done;
-#endif
-
-  secStatus = SSL_SetURL(sslSocket, hostName);
-  if (secStatus != SECSuccess)
-    goto done;
-
-  prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT);
-  if (prStatus != PR_SUCCESS)
-    {
-      secStatus = SECFailure;
-      goto done;
-    }
-
-  /* Established SSL connection, ready to send data. */
-  secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE);
-  if (secStatus != SECSuccess)
-    goto done;
-
-  /* This is normally done automatically on the first I/O operation,
-     but doing it here catches any authentication problems early.  */
-  secStatus = SSL_ForceHandshake(sslSocket);
-  if (secStatus != SECSuccess)
-    goto done;
-
-  /* If we don't have both the input and output file names, then we're
-     contacting this server only in order to establish trust. No need to
-     handle the connection in this case.  */
-  if (infileName && outfileName)
-    secStatus = handle_connection(sslSocket, infileName, outfileName);
-
- done:
-  prStatus = PR_Close(sslSocket);
-  return secStatus;
-}
-
-/* Exit error codes */
-#define SUCCESS               0
-#define GENERAL_ERROR         1
-#define CA_CERT_INVALID_ERROR 2
-
-int
-client_main (const char *hostName, PRUint32 ip,
-            PRUint16 port,
-            const char* infileName, const char* outfileName,
-            const char* trustNewServer)
-{
-  SECStatus   secStatus;
-  PRStatus    prStatus;
-  PRInt32     rv;
-  PRNetAddr   addr;
-  PRHostEnt   hostEntry;
-  PRErrorCode errorNumber;
-  char        buffer[PR_NETDB_BUF_SIZE];
-  int         attempt;
-  int         errCode = GENERAL_ERROR;
-
-  trustNewServer_p = trustNewServer;
-
-  /* Setup network connection. If we have an ip address, then
-     simply use it, otherwise we need to resolve the host name.  */
-  if (ip)
-    {
-      addr.inet.family = PR_AF_INET;
-      addr.inet.port = htons (port);
-      addr.inet.ip = htonl (ip);
-    }
-  else
-    {
-      prStatus = PR_GetHostByName(hostName, buffer, sizeof (buffer), &hostEntry);
-      if (prStatus != PR_SUCCESS) {
-       fprintf (stderr, "Unable to resolve server host name");
-       return errCode;
-      }
-
-      rv = PR_EnumerateHostEnt(0, &hostEntry, port, &addr);
-      if (rv < 0) {
-       fprintf (stderr, "Unable to resolve server host address");
-       return errCode;
-      }
-    }
-
-  /* Some errors (see below) represent a situation in which trying again
-     should succeed. However, don't try forever.  */
-  for (attempt = 0; attempt < 5; ++attempt)
-    {
-      secStatus = do_connect (&addr, hostName, port, infileName, outfileName);
-      if (secStatus == SECSuccess)
-       return SUCCESS;
-
-      errorNumber = PR_GetError ();
-      switch (errorNumber)
-       {
-       case PR_CONNECT_RESET_ERROR:
-         /* Server was not ready. */
-         sleep (1);
-         break; /* Try again */
-       case SEC_ERROR_EXPIRED_CERTIFICATE:
-         /* The server's certificate has expired. It should
-            generate a new certificate. Give the server a chance to recover
-            and try again.  */
-         sleep (2);
-         break; /* Try again */
-       case SEC_ERROR_CA_CERT_INVALID:
-         /* The server's certificate is not trusted. The exit code must
-            reflect this.  */
-         errCode = CA_CERT_INVALID_ERROR;
-         goto failed; /* break switch and loop */
-       default:
-         /* This error is fatal.  */
-         goto failed; /* break switch and loop */
-       }
-    }
-
- failed:
-  /* Unrecoverable error */
-  fprintf (stderr, "Unable to connect to server\n");
-  return errCode;
-}
-
-/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.056037 seconds and 5 git commands to generate.