fence-agents: master - fence_ilo: Replacing nss_wrapper with gnutls-cli

Marek GrĂ¡c marx at fedoraproject.org
Mon Feb 17 13:25:09 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=52ed50a1bd4b4bfe632bd560de27195fcea65802
Commit:        52ed50a1bd4b4bfe632bd560de27195fcea65802
Parent:        4ad407fa2fe278ae205ae890b3ca548bd1e59335
Author:        Marek 'marx' Grac <mgrac at redhat.com>
AuthorDate:    Mon Feb 17 14:20:24 2014 +0100
Committer:     Marek 'marx' Grac <mgrac at redhat.com>
CommitterDate: Mon Feb 17 14:20:24 2014 +0100

fence_ilo: Replacing nss_wrapper with gnutls-cli

SSLv2 was disabled in nss package (rhbz#1001841), ilo2 now supports also SSLv3
and it is possible to use standard tool for communication.
---
 configure.ac                                 |    2 +-
 fence/agents/Makefile.am                     |    1 -
 fence/agents/lib/fencing.py.py               |    5 +-
 fence/agents/nss_wrapper/Makefile.am         |    7 -
 fence/agents/nss_wrapper/fence_nss_wrapper.c |  484 --------------------------
 make/fencebuild.mk                           |    1 +
 6 files changed, 4 insertions(+), 496 deletions(-)

diff --git a/configure.ac b/configure.ac
index c394690..510347e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -166,6 +166,7 @@ CLUSTERDATA=${datadir}/cluster
 ## path to 3rd-party binaries
 AC_PATH_PROG([IPMITOOL_PATH], [ipmitool], [/usr/bin/ipmitool])
 AC_PATH_PROG([AMTTOOL_PATH], [amttool], [/usr/bin/amttool])
+AC_PATH_PROG([GNUTLSCLI_PATH], [gnutlscli], [/usr/bin/gnutls-cli])
 ## do subst
 
 AC_SUBST([DEFAULT_CONFIG_DIR])
@@ -284,7 +285,6 @@ AC_CONFIG_FILES([Makefile
 		 fence/agents/manual/Makefile
 		 fence/agents/mcdata/Makefile
 		 fence/agents/netio/Makefile
-		 fence/agents/nss_wrapper/Makefile
 		 fence/agents/rackswitch/Makefile
 		 fence/agents/ovh/Makefile
 		 fence/agents/rhevm/Makefile
diff --git a/fence/agents/Makefile.am b/fence/agents/Makefile.am
index f14d27f..c47f5d5 100644
--- a/fence/agents/Makefile.am
+++ b/fence/agents/Makefile.am
@@ -1,5 +1,4 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
 SUBDIRS 		= lib \
-			  nss_wrapper \
 			  $(AGENTS_LIST)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index fd21c69..798f855 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -28,7 +28,7 @@ EC_INVALID_PRIVILEGES = 11
 
 TELNET_PATH = "/usr/bin/telnet"
 SSH_PATH    = "/usr/bin/ssh"
-SSL_PATH    = "@LIBEXECDIR@/fence_nss_wrapper"
+SSL_PATH    = "@GNUTLSCLI_PATH@"
 SUDO_PATH   = "/usr/bin/sudo"
 
 all_opt = {
@@ -960,11 +960,10 @@ def fence_login(options, re_login_string = "(login\s*: )|(Login Name:  )|(userna
 		re_pass  = re.compile("(password)|(pass phrase)", re.IGNORECASE)
 
 		if options.has_key("--ssl"):
-			command = '%s %s %s %s' % (SSL_PATH, force_ipvx, options["--ip"], options["--ipport"])
+			command = '%s --insecure --crlf -p %s %s' % (SSL_PATH, options["--ipport"], options["--ip"])
 			try:
 				conn = fspawn(options, command)
 			except pexpect.ExceptionPexpect, ex:
-			 	## SSL telnet is part of the fencing package
 				sys.stderr.write(str(ex) + "\n")
 				syslog.syslog(syslog.LOG_ERR, str(ex))
 				sys.exit(EC_GENERIC_ERROR)
diff --git a/fence/agents/nss_wrapper/Makefile.am b/fence/agents/nss_wrapper/Makefile.am
deleted file mode 100644
index 16273ed..0000000
--- a/fence/agents/nss_wrapper/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-MAINTAINERCLEANFILES	  = Makefile.in
-
-libexec_PROGRAMS          = fence_nss_wrapper
-
-fence_nss_wrapper_CFLAGS  = $(nss_CFLAGS) $(nspr_CFLAGS)
-
-fence_nss_wrapper_LDFLAGS = $(nss_LIBS) $(nspr_LIBS)
diff --git a/fence/agents/nss_wrapper/fence_nss_wrapper.c b/fence/agents/nss_wrapper/fence_nss_wrapper.c
deleted file mode 100644
index b960cf0..0000000
--- a/fence/agents/nss_wrapper/fence_nss_wrapper.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/** @file fence_nss_wrapper.c - Main source code of hobbit like tool with
-  support for NSS (SSL) connection.
-*/
-#include "clusterautoconfig.h"
-
-#include <stdio.h>
-#include <nss.h>
-#include <ssl.h>
-#include <prio.h>
-#include <prnetdb.h>
-#include <prerror.h>
-#include <prinit.h>
-#include <getopt.h>
-#include <libgen.h>
-
-/*---- CONSTANTS -------------*/
-
-/** Default operation = connect and telnet*/
-#define OPERATION_DEFAULT 0
-/** Operation display help*/
-#define OPERATION_HELP 1
-
-/** Default mode of connection. Try first found working address*/
-#define MODE_DEFAULT 3
-/** Use only IPv4*/
-#define MODE_IP4MODE 1
-/** Use only IPv6*/
-#define MODE_IP6MODE 2
-/** Use RAW mode - no change of \r and \n to \r\n*/
-#define MODE_RAW     4
-/** Use non-secure mode (without SSL, only pure socket)*/
-#define MODE_NO_SSL  8
-
-/*------ Functions ---------------*/
-
-/** Return port inserted in string. Fuction tests, if port is integer, and than return
-  integer value of string. Otherwise, it will use /etc/services.  On fail, it returns
-  port -1.
-  @param port_s Input port or service name
-  @return port number (converted with ntohs) on success, otherwise -1.
-*/
-static int return_port(char *port_s) {
-  char *end_c;
-  int res;
-  struct servent *serv;
-
-  res=strtol(port_s,&end_c,10);
-
-  if (*end_c=='\0') return res;
-
-  /*It's not number, so try service name*/
-  serv=getservbyname(port_s,NULL);
-
-  if (serv==NULL) return -1;
-
-  return ntohs(serv->s_port);
-}
-
-/** Hook handler for bad certificate (because we have no DB, EVERY certificate is bad).
-  Returned value is always SECSuccess = it's ok certificate.
-  @param arg NULL value
-  @param fd socket cased error
-  @return SECSuccess.
-*/
-static SECStatus nss_bad_cert_hook(void *arg,PRFileDesc *fd) {
-  return SECSuccess;
-}
-
-/** Display last NSPR/NSS error code and user readable message.
-*/
-static void print_nspr_error(void) {
-  fprintf(stderr,"Error (%d): %s\n",PR_GetError(),PR_ErrorToString(PR_GetError(),PR_LANGUAGE_I_DEFAULT));
-}
-
-/** Initialize NSS. NSS is initialized without DB and with
-  domnestic policy.
-  @return 1 on success, otherwise 0.
-*/
-static int init_nss(void) {
-  if ((NSS_NoDB_Init(NULL)!=SECSuccess) ||
-      (NSS_SetDomesticPolicy()!=SECSuccess)) {
-    print_nspr_error();
-
-    return 0;
-  }
-
-  SSL_ClearSessionCache();
-
-  return 1;
-}
-
-/** Create socket. If ssl is >0, socket is ssl enabled.
-  @param ssl Enable ssl (Client, SSL2+3, no TLS, compatible hello) if PR_TRUE, otherwise no.
-  @param ipv6 New socket will be IPv4 if this value is 0, otherwise it will be ipv6
-  @return NULL on error, otherwise socket.
-*/
-static PRFileDesc *create_socket(int ssl,int ipv6) {
-  PRFileDesc *res_socket;
-
-  res_socket=PR_OpenTCPSocket((ipv6?PR_AF_INET6:PR_AF_INET));
-  if (res_socket==NULL) {
-    print_nspr_error();
-
-    return NULL;
-  }
-
-  if (!ssl) return res_socket;
-
-  if (!(res_socket=SSL_ImportFD(NULL,res_socket))) {
-    print_nspr_error();
-
-    return NULL;
-  }
-
-  if ((SSL_OptionSet(res_socket,SSL_SECURITY,ssl)!=SECSuccess) ||
-      (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_SERVER,PR_FALSE)!=SECSuccess) ||
-      (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_CLIENT,PR_TRUE)!=SECSuccess) ||
-      (SSL_OptionSet(res_socket,SSL_ENABLE_SSL2,ssl)!=SECSuccess) ||
-      (SSL_OptionSet(res_socket,SSL_ENABLE_SSL3,ssl)!=SECSuccess) ||
-      (SSL_OptionSet(res_socket,SSL_ENABLE_TLS,PR_FALSE)!=SECSuccess) ||
-      (SSL_OptionSet(res_socket,SSL_V2_COMPATIBLE_HELLO,ssl)!=SECSuccess) ||
-      (SSL_SetPKCS11PinArg(res_socket,NULL)==-1) ||
-      (SSL_AuthCertificateHook(res_socket,SSL_AuthCertificate,CERT_GetDefaultCertDB())!=SECSuccess) ||
-      (SSL_BadCertHook(res_socket,nss_bad_cert_hook,NULL)!=SECSuccess)) {
-    print_nspr_error();
-
-    if (PR_Close(res_socket)!=PR_SUCCESS) {
-      print_nspr_error();
-    }
-
-    return NULL;
-  }
-
-  return res_socket;
-}
-
-/** Create socket and connect to it.
-  @param hostname Hostname to connect
-  @param port Port name/number to connect
-  @param mode Connection mode. Bit-array of MODE_NO_SSL, MODE_IP6MODE, MODE_IP4MODE.
-  @return NULL on error, otherwise connected socket.
-*/
-static PRFileDesc *create_connected_socket(char *hostname,int port,int mode) {
-  PRAddrInfo *addr_info;
-  void *addr_iter;
-  PRNetAddr addr;
-  PRFileDesc *localsocket;
-  int can_exit,valid_socket;
-  PRUint16 af_spec;
-
-  localsocket=NULL;
-
-  addr_info=NULL;
-
-  af_spec=PR_AF_UNSPEC;
-
-  if (!(mode&MODE_IP6MODE)) af_spec=PR_AF_INET;
-
-  addr_info=PR_GetAddrInfoByName(hostname,af_spec,PR_AI_ADDRCONFIG);
-
-  if (addr_info == NULL) {
-    print_nspr_error();
-    return NULL;
-  }
-
-  /*We have socket -> enumerate and try to connect*/
-  addr_iter=NULL;
-  can_exit=0;
-  valid_socket=0;
-
-  while (!can_exit) {
-    addr_iter=PR_EnumerateAddrInfo(addr_iter,addr_info,port,&addr);
-
-    if (addr_iter==NULL) {
-      can_exit=1;
-    } else {
-      if ((PR_NetAddrFamily(&addr)==PR_AF_INET && (mode&MODE_IP4MODE)) ||
-          (PR_NetAddrFamily(&addr)==PR_AF_INET6 && (mode&MODE_IP6MODE))) {
-        /*Type of address is what user want, try to create socket and make connection*/
-
-        /*Create socket*/
-        localsocket=create_socket(!(mode&MODE_NO_SSL),(PR_NetAddrFamily(&addr)==PR_AF_INET6));
-
-        if (localsocket) {
-          /*Try to connect*/
-          if (PR_Connect(localsocket,&addr,PR_INTERVAL_NO_TIMEOUT)==PR_SUCCESS) {
-            /*Force handshake*/
-            if ((!(mode&MODE_NO_SSL)) && SSL_ForceHandshake(localsocket)!=SECSuccess) {
-              /*Handhake failure -> fail*/
-              print_nspr_error();
-              if (PR_Close(localsocket)!=PR_SUCCESS) {
-                print_nspr_error();
-                can_exit=1;
-              }
-              localsocket=NULL;
-            }
-
-            /*Socket is connected -> we can return it*/
-            can_exit=1;
-          } else {
-            /*Try another address*/
-            if (PR_Close(localsocket)!=PR_SUCCESS) {
-              print_nspr_error();
-              can_exit=1;
-            }
-            localsocket=NULL;
-          }
-        }
-      }
-    }
-  }
-
-  if (!localsocket) {
-    /*Socket is unvalid -> we don't found any usable address*/
-    fprintf(stderr,"Can't connect to host %s on port %d!\n",hostname,port);
-  }
-
-  PR_FreeAddrInfo(addr_info);
-
-  return localsocket;
-}
-
-/** Parse arguments from command line.
-  @param argc Number of arguments in argv
-  @param argv Array of arguments
-  @param mode Pointer to int will be filled with OPERATION_DEFAULT or OPERATION_HELP.
-  @param mode Pointer to int will be filled with MODE_DEFAULT, MODE_IP4MODE or MODE_IP4MODE.
-  @return 1 on success, otherwise 0.
-*/
-static int parse_cli(int argc,char *argv[],int *operation,int *mode,char **hostname,char **port) {
-  int opt;
-
-  *operation=OPERATION_DEFAULT;
-  *mode=MODE_DEFAULT;
-  *port=NULL;
-  *hostname=NULL;
-
-  while ((opt=getopt(argc,argv,"h46rz"))!=-1) {
-    switch (opt) {
-      case 'h':
-        *operation=OPERATION_HELP;
-
-        return 0;
-      break;
-
-      case '4':
-        (*mode)&=~MODE_IP6MODE;
-        (*mode)|=MODE_IP4MODE;
-      break;
-
-      case '6':
-        (*mode)&=~MODE_IP4MODE;
-        (*mode)|=MODE_IP6MODE;
-      break;
-
-      case 'r':
-        (*mode)|=MODE_RAW;
-      break;
-
-      case 'z':
-        (*mode)|=MODE_NO_SSL;
-      break;
-
-      default:
-        return 0;
-      break;
-    }
-  }
-
-  if (argc-optind<2) {
-    fprintf(stderr,"Hostname and port is expected!\n");
-
-    return 0;
-  }
-
-  *hostname=argv[optind];
-  *port=argv[optind+1];
-
-  return 1;
-}
-
-/** Show usage of application.
-  @param pname Name of program (usually basename of argv[0])
-*/
-static void show_usage(char *pname) {
-  printf("usage: %s [options] hostname port\n", pname);
-  printf("   -4             Force to use IPv4\n");
-  printf("   -6             Force to use IPv6\n");
-  printf("   -r             Use RAW connection (don't convert \\r and \\n characters)\n");
-  printf("   -z             Don't use SSL connection (use pure socket)\n");
-  printf("   -h             Show this help\n");
-}
-
-/** Convert End Of Lines (Unix \n, Macs \r or DOS/Win \r\n) to \r\n.
-  @param in_buffer Input buffer
-  @param in_size Input buffer size
-  @param out_buffer Output buffer (must be prealocated). Should be (2*in_size) (in worst case)
-  @param out_size There will be size of out_buffer
-  @param in_state Internal state of finite automata. First call should have this 0, other calls
-    shouldn't change this value. After end of file, you may add to this value +100 and call this
-    again, to make sure of proper end (in_buffer can be in this case everything, including NULL).
-*/
-static void convert_eols(char *in_buffer,int in_size,char *out_buffer,int *out_size,int *in_state) {
-  int in_pos,out_pos;
-  int status;
-  char in_char;
-
-  out_pos=0;
-  status=*in_state;
-
-  if (status==100 || status==101) {
-    if (status==101) {
-      out_buffer[out_pos++]='\r';
-      out_buffer[out_pos++]='\n';
-    }
-  } else {
-    for (in_pos=0;in_pos<in_size;in_pos++) {
-      in_char=in_buffer[in_pos];
-
-      switch (status) {
-        case 0:
-          if (in_char=='\r') status=1;
-          if (in_char=='\n') {
-            out_buffer[out_pos++]='\r';
-            out_buffer[out_pos++]='\n';
-          }
-          if ((in_char!='\r') && (in_char!='\n')) out_buffer[out_pos++]=in_char;
-        break;
-
-        case 1:
-          out_buffer[out_pos++]='\r';
-          out_buffer[out_pos++]='\n';
-
-          if (in_char!='\n') out_buffer[out_pos++]=in_char;
-
-          status=0;
-        break;
-      }
-    }
-  }
-
-  *out_size=out_pos;
-  *in_state=status;
-}
-
-/** Start polling cycle.
-  @param socket Network connected socket.
-  @param mode Bit-array of MODE_*. This function take care on MODE_RAW.
-  @return 0 on failure, otherwise 1
-*/
-static int poll_cycle(PRFileDesc *localsocket,int mode) {
-  PRPollDesc pool[2];
-  char buffer[1024],buffer_eol[1024*2];
-  int readed_bytes;
-  int can_exit;
-  int res;
-  int bytes_to_write;
-  int eol_state;
-
-  can_exit=0;
-  eol_state=0;
-
-  /* Fill pool*/
-  pool[1].fd=localsocket;
-  pool[0].fd=PR_STDIN;
-  pool[0].in_flags=pool[1].in_flags=PR_POLL_READ;
-  pool[0].out_flags=pool[1].out_flags=0;
-
-  while (!can_exit) {
-    res=(PR_Poll(pool,sizeof(pool)/sizeof(PRPollDesc),PR_INTERVAL_NO_TIMEOUT));
-
-    if (res==-1) {
-      print_nspr_error();
-
-      return 0;
-    }
-
-    if (pool[1].out_flags&PR_POLL_READ) {
-      /*We have something in socket*/
-      if ((readed_bytes=PR_Read(pool[1].fd,buffer,sizeof(buffer)))>0) {
-        if (PR_Write(PR_STDOUT,buffer,readed_bytes)!=readed_bytes) {
-          print_nspr_error();
-
-          return 0;
-        }
-      } else {
-        /*End of stream -> quit*/
-        can_exit=1;
-      }
-    }
-
-    if (pool[0].out_flags&(PR_POLL_READ|PR_POLL_HUP)) {
-      /*We have something in stdin*/
-      if ((readed_bytes=PR_Read(pool[0].fd,buffer,sizeof(buffer)))>0) {
-
-        if (!(mode&MODE_RAW)) {
-          convert_eols(buffer,readed_bytes,buffer_eol,&bytes_to_write,&eol_state);
-        } else
-          bytes_to_write=readed_bytes;
-
-        if (PR_Write(pool[1].fd,(mode&MODE_RAW?buffer:buffer_eol),bytes_to_write)!=bytes_to_write) {
-          print_nspr_error();
-
-          return 0;
-        }
-      } else {
-        /*End of stream -> send EOL (if needed)*/
-        if (!(mode&MODE_RAW)) {
-          eol_state+=100;
-          convert_eols(NULL,0,buffer_eol,&bytes_to_write,&eol_state);
-          if (PR_Write(pool[1].fd,buffer_eol,bytes_to_write)!=bytes_to_write) {
-            print_nspr_error();
-
-            return 0;
-          }
-        }
-      }
-    }
-
-    pool[0].out_flags=pool[1].out_flags=0;
-  } /*while (!can_exit)*/
-
-  return 1;
-}
-
-static void atexit_handler(void) {
-  if (PR_Initialized())
-    PR_Cleanup();
-
-  if (fclose(stdout)!=0) {
-    fprintf(stderr,"Can't close stdout!\n");
-
-    exit(1);
-  }
-}
-
-/** Entry point of application.
-  @param argc Number of arguments on command line
-  @param argv Array of strings with arguments from command line
-  @return 0 on success, otherwise >0.
-*/
-int main(int argc,char *argv[]) {
-  int mode,operation;
-  char *hostname, *port;
-  char *pname;
-  int port_n;
-  PRFileDesc *fd_socket;
-  int res;
-
-  pname=basename(argv[0]);
-
-  atexit(atexit_handler);
-
-  if (!parse_cli(argc,argv,&operation,&mode,&hostname,&port) || operation==OPERATION_HELP) {
-    show_usage(pname);
-
-    if (operation!=OPERATION_HELP) return 1;
-
-    return 0;
-  }
-
-  if ((port_n=return_port(port))==-1) {
-    fprintf(stderr,"Error. Unknown port number/name %s!\n",port);
-
-    return 1;
-  }
-
-  if (!(mode&MODE_NO_SSL)) {
-    if (!init_nss()) return 1;
-  }
-
-  if (!(fd_socket=create_connected_socket(hostname,port_n,mode)))
-    return 1;
-
-  res=poll_cycle(fd_socket,mode);
-
-  if (PR_Close(fd_socket)!=PR_SUCCESS) {
-    print_nspr_error();
-
-    return 1;
-  }
-
-  return (res?0:1);
-}
diff --git a/make/fencebuild.mk b/make/fencebuild.mk
index 14e33b7..819ac36 100644
--- a/make/fencebuild.mk
+++ b/make/fencebuild.mk
@@ -11,6 +11,7 @@ $(TARGET): $(SRC)
 		-e 's#@''LIBEXECDIR@#${libexecdir}#g' \
 		-e 's#@''IPMITOOL_PATH@#${IPMITOOL_PATH}#g' \
 		-e 's#@''AMTTOOL_PATH@#${AMTTOOL_PATH}#g' \
+		-e 's#@''GNUTLSCLI_PATH@#${GNUTLSCLI_PATH}#g' \
 	> $@
 
 	if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \


More information about the cluster-commits mailing list