Merge branch 'ky/imap-send-openssl-1.1.0'
authorJunio C Hamano <gitster@pobox.com>
Fri, 22 Apr 2016 22:45:08 +0000 (15:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 22 Apr 2016 22:45:08 +0000 (15:45 -0700)
Upcoming OpenSSL 1.1.0 will break compilation b updating a few APIs
we use in imap-send, which has been adjusted for the change.

* ky/imap-send-openssl-1.1.0:
configure: remove checking for HMAC_CTX_cleanup
imap-send: avoid deprecated TLSv1_method()
imap-send: check NULL return of SSL_CTX_new()
imap-send: use HMAC() function provided by OpenSSL

1  2 
Makefile
configure.ac
git-compat-util.h
imap-send.c
diff --combined Makefile
index c7354bf2adc626926a276fd49e874dbfa1081ad8,cad1f45222e304caaafba3ab56fc12df3540e026..a83e322f468a2bd3cad4058a7dffffbda822033f
+++ b/Makefile
@@@ -77,6 -77,8 +77,6 @@@ all:
  # Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
  # it specifies.
  #
 -# Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
 -#
  # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
  # d_type in struct dirent (Cygwin 1.5, fixed in Cygwin 1.7).
  #
  #
  # Define NO_TCLTK if you do not want Tcl/Tk GUI.
  #
 +# Define SANE_TEXT_GREP to "-a" if you use recent versions of GNU grep
 +# and egrep that are pickier when their input contains non-ASCII data.
 +#
  # The TCL_PATH variable governs the location of the Tcl interpreter
  # used to optimize git-gui for your system.  Only used if NO_TCLTK
  # is not set.  Defaults to the bare 'tclsh'.
  #
  # Define HAVE_CLOCK_MONOTONIC if your platform has CLOCK_MONOTONIC in librt.
  #
- # Define NO_HMAC_CTX_CLEANUP if your OpenSSL is version 0.9.6b or earlier to
- # cleanup the HMAC context with the older HMAC_cleanup function.
- #
  # Define USE_PARENS_AROUND_GETTEXT_N to "yes" if your compiler happily
  # compiles the following initialization:
  #
@@@ -383,18 -379,6 +380,18 @@@ ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS
  ALL_LDFLAGS = $(LDFLAGS)
  STRIP ?= strip
  
 +ifdef DEVELOPER
 +CFLAGS += -Werror \
 +      -Wdeclaration-after-statement \
 +      -Wno-format-zero-length \
 +      -Wold-style-definition \
 +      -Woverflow \
 +      -Wpointer-arith \
 +      -Wstrict-prototypes \
 +      -Wunused \
 +      -Wvla
 +endif
 +
  # Create as necessary, replace existing, make ranlib unneeded.
  ARFLAGS = rcs
  
@@@ -598,7 -582,6 +595,7 @@@ TEST_PROGRAMS_NEED_X += test-delt
  TEST_PROGRAMS_NEED_X += test-dump-cache-tree
  TEST_PROGRAMS_NEED_X += test-dump-split-index
  TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
 +TEST_PROGRAMS_NEED_X += test-fake-ssh
  TEST_PROGRAMS_NEED_X += test-genrandom
  TEST_PROGRAMS_NEED_X += test-hashmap
  TEST_PROGRAMS_NEED_X += test-index-version
@@@ -751,7 -734,6 +748,7 @@@ LIB_OBJS += list-objects.
  LIB_OBJS += ll-merge.o
  LIB_OBJS += lockfile.o
  LIB_OBJS += log-tree.o
 +LIB_OBJS += mailinfo.o
  LIB_OBJS += mailmap.o
  LIB_OBJS += match-trees.o
  LIB_OBJS += merge.o
@@@ -788,7 -770,6 +785,7 @@@ LIB_OBJS += reachable.
  LIB_OBJS += read-cache.o
  LIB_OBJS += reflog-walk.o
  LIB_OBJS += refs.o
 +LIB_OBJS += refs/files-backend.o
  LIB_OBJS += ref-filter.o
  LIB_OBJS += remote.o
  LIB_OBJS += replace_object.o
@@@ -834,7 -815,6 +831,7 @@@ LIB_OBJS += version.
  LIB_OBJS += versioncmp.o
  LIB_OBJS += walker.o
  LIB_OBJS += wildmatch.o
 +LIB_OBJS += worktree.o
  LIB_OBJS += wrapper.o
  LIB_OBJS += write_or_die.o
  LIB_OBJS += ws.o
@@@ -930,7 -910,6 +927,7 @@@ BUILTIN_OBJS += builtin/shortlog.
  BUILTIN_OBJS += builtin/show-branch.o
  BUILTIN_OBJS += builtin/show-ref.o
  BUILTIN_OBJS += builtin/stripspace.o
 +BUILTIN_OBJS += builtin/submodule--helper.o
  BUILTIN_OBJS += builtin/symbolic-ref.o
  BUILTIN_OBJS += builtin/tag.o
  BUILTIN_OBJS += builtin/unpack-file.o
@@@ -1138,9 -1117,6 +1135,6 @@@ ifndef NO_OPENSS
        ifdef NEEDS_CRYPTO_WITH_SSL
                OPENSSL_LIBSSL += -lcrypto
        endif
-       ifdef NO_HMAC_CTX_CLEANUP
-               BASIC_CFLAGS += -DNO_HMAC_CTX_CLEANUP
-       endif
  else
        BASIC_CFLAGS += -DNO_OPENSSL
        BLK_SHA1 = 1
@@@ -1190,6 -1166,9 +1184,6 @@@ endi
  ifdef NO_D_TYPE_IN_DIRENT
        BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT
  endif
 -ifdef NO_D_INO_IN_DIRENT
 -      BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT
 -endif
  ifdef NO_GECOS_IN_PWENT
        BASIC_CFLAGS += -DNO_GECOS_IN_PWENT
  endif
@@@ -1743,7 -1722,7 +1737,7 @@@ common-cmds.h: $(wildcard Documentation
  
  SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
        $(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\
 -      $(gitwebdir_SQ):$(PERL_PATH_SQ)
 +      $(gitwebdir_SQ):$(PERL_PATH_SQ):$(SANE_TEXT_GREP)
  define cmd_munge_script
  $(RM) $@ $@+ && \
  sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
      -e $(BROKEN_PATH_FIX) \
      -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \
      -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
 +    -e 's|@@SANE_TEXT_GREP@@|$(SANE_TEXT_GREP)|g' \
      $@.sh >$@+
  endef
  
@@@ -2042,7 -2020,6 +2036,7 @@@ $(VCSSVN_LIB): $(VCSSVN_OBJS
  
  export DEFAULT_EDITOR DEFAULT_PAGER
  
 +.PHONY: doc man html info pdf
  doc:
        $(MAKE) -C Documentation all
  
@@@ -2086,7 -2063,6 +2080,7 @@@ po/git.pot: $(GENERATED_H) FORC
                $(LOCALIZED_PERL)
        mv $@+ $@
  
 +.PHONY: pot
  pot: po/git.pot
  
  POFILES := $(wildcard po/*.po)
@@@ -2263,10 -2239,10 +2257,10 @@@ sparse: $(SP_OBJ
  check: common-cmds.h
        @if sparse; \
        then \
 -              echo 2>&1 "Use 'make sparse' instead"; \
 +              echo >&2 "Use 'make sparse' instead"; \
                $(MAKE) --no-print-directory sparse; \
        else \
 -              echo 2>&1 "Did you mean 'make test'?"; \
 +              echo >&2 "Did you mean 'make test'?"; \
                exit 1; \
        fi
  
@@@ -2296,7 -2272,6 +2290,7 @@@ mergetools_instdir_SQ = $(subst ','\'',
  
  install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X)
  
 +.PHONY: profile-install profile-fast-install
  profile-install: profile
        $(MAKE) install
  
@@@ -2363,8 -2338,6 +2357,8 @@@ endi
        done && \
        ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
  
 +.PHONY: install-gitweb install-doc install-man install-html install-info install-pdf
 +.PHONY: quick-install-doc quick-install-man quick-install-html
  install-gitweb:
        $(MAKE) -C gitweb install
  
@@@ -2424,7 -2397,6 +2418,7 @@@ rpm: dis
  
  htmldocs = git-htmldocs-$(GIT_VERSION)
  manpages = git-manpages-$(GIT_VERSION)
 +.PHONY: dist-doc distclean
  dist-doc:
        $(RM) -r .doc-tmp-dir
        mkdir .doc-tmp-dir
@@@ -2456,7 -2428,7 +2450,7 @@@ profile-clean
        $(RM) $(addsuffix *.gcno,$(addprefix $(PROFILE_DIR)/, $(object_dirs)))
  
  clean: profile-clean coverage-clean
 -      $(RM) *.o *.res block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o
 +      $(RM) *.o *.res refs/*.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o
        $(RM) xdiff/*.o vcs-svn/*.o ewah/*.o builtin/*.o
        $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
        $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
@@@ -2493,8 -2465,6 +2487,8 @@@ ALL_COMMANDS += gi
  ALL_COMMANDS += gitk
  ALL_COMMANDS += gitweb
  ALL_COMMANDS += git-gui git-citool
 +
 +.PHONY: check-docs
  check-docs::
        @(for v in $(ALL_COMMANDS); \
        do \
@@@ -2539,7 -2509,6 +2533,7 @@@ check-builtins:
  ### Test suite coverage testing
  #
  .PHONY: coverage coverage-clean coverage-compile coverage-test coverage-report
 +.PHONY: coverage-untested-functions cover_db cover_db_html
  .PHONY: coverage-clean-results
  
  coverage:
diff --combined configure.ac
index 0cd9f4680b84bccd0a98193c401b13749b05b833,367e72fe9a5de757259e42a7e142fd58d6ed6701..c279025747349c19039b0e061954ae67b91b735a
@@@ -471,13 -471,6 +471,13 @@@ if test -n "$ASCIIDOC"; the
        esac
  fi
  
 +if grep -a ascii configure.ac >/dev/null; then
 +  AC_MSG_RESULT([Using 'grep -a' for sane_grep])
 +  SANE_TEXT_GREP=-a
 +else
 +  SANE_TEXT_GREP=
 +fi
 +GIT_CONF_SUBST([SANE_TEXT_GREP])
  
  ## Checks for libraries.
  AC_MSG_NOTICE([CHECKS for libraries])
@@@ -797,6 -790,13 +797,6 @@@ elif test x$ac_cv_member_struct_stat_st
        GIT_CONF_SUBST([NO_NSEC])
  fi
  #
 -# Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
 -AC_CHECK_MEMBER(struct dirent.d_ino,
 -[NO_D_INO_IN_DIRENT=],
 -[NO_D_INO_IN_DIRENT=YesPlease],
 -[#include <dirent.h>])
 -GIT_CONF_SUBST([NO_D_INO_IN_DIRENT])
 -#
  # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
  # d_type in struct dirent (latest Cygwin -- will be fixed soonish).
  AC_CHECK_MEMBER(struct dirent.d_type,
@@@ -970,10 -970,6 +970,6 @@@ AC_CHECK_LIB([iconv], [locale_charset]
                       [CHARSET_LIB=-lcharset])])
  GIT_CONF_SUBST([CHARSET_LIB])
  #
- # Define NO_HMAC_CTX_CLEANUP=YesPlease if HMAC_CTX_cleanup is missing.
- AC_CHECK_LIB([crypto], [HMAC_CTX_cleanup],
-       [], [GIT_CONF_SUBST([NO_HMAC_CTX_CLEANUP], [YesPlease])])
- #
  # Define HAVE_CLOCK_GETTIME=YesPlease if clock_gettime is available.
  GIT_CHECK_FUNC(clock_gettime,
        [HAVE_CLOCK_GETTIME=YesPlease],
diff --combined git-compat-util.h
index 474395471f623d6a02de9814a5490f3b1df3a0f1,c062ddfb5a80ea3f2931a1ed7f706a7812b72123..1f8b5f3b1f1ac17716681fee2d72b9c124a9b99c
@@@ -237,7 -237,7 +237,7 @@@ typedef unsigned long uintptr_t
  #else
  #define precompose_str(in,i_nfd2nfc)
  #define precompose_argv(c,v)
 -#define probe_utf8_pathname_composition(a,b)
 +#define probe_utf8_pathname_composition()
  #endif
  
  #ifdef MKDIR_WO_TRAILING_SLASH
@@@ -261,8 -261,6 +261,8 @@@ struct itimerval 
  #else
  #define basename gitbasename
  extern char *gitbasename(char *);
 +#define dirname gitdirname
 +extern char *gitdirname(char *);
  #endif
  
  #ifndef NO_ICONV
  #endif
  #include <openssl/ssl.h>
  #include <openssl/err.h>
- #ifdef NO_HMAC_CTX_CLEANUP
- #define HMAC_CTX_cleanup HMAC_cleanup
- #endif
  #endif
  
  /* On most systems <netdb.h> would have given us this, but
  #define _PATH_DEFPATH "/usr/local/bin:/usr/bin:/bin"
  #endif
  
 -#ifndef STRIP_EXTENSION
 -#define STRIP_EXTENSION ""
 -#endif
 -
  #ifndef has_dos_drive_prefix
  static inline int git_has_dos_drive_prefix(const char *path)
  {
  #define has_dos_drive_prefix git_has_dos_drive_prefix
  #endif
  
 +#ifndef skip_dos_drive_prefix
 +static inline int git_skip_dos_drive_prefix(char **path)
 +{
 +      return 0;
 +}
 +#define skip_dos_drive_prefix git_skip_dos_drive_prefix
 +#endif
 +
  #ifndef is_dir_sep
  static inline int git_is_dir_sep(int c)
  {
@@@ -677,6 -668,7 +674,6 @@@ extern int git_vsnprintf(char *str, siz
  #ifdef __GLIBC_PREREQ
  #if __GLIBC_PREREQ(2, 1)
  #define HAVE_STRCHRNUL
 -#define HAVE_MEMPCPY
  #endif
  #endif
  
@@@ -690,6 -682,14 +687,6 @@@ static inline char *gitstrchrnul(const 
  }
  #endif
  
 -#ifndef HAVE_MEMPCPY
 -#define mempcpy gitmempcpy
 -static inline void *gitmempcpy(void *dest, const void *src, size_t n)
 -{
 -      return (char *)memcpy(dest, src, n) + n;
 -}
 -#endif
 -
  #ifdef NO_INET_PTON
  int inet_pton(int af, const char *src, void *dst);
  #endif
@@@ -715,8 -715,8 +712,8 @@@ static inline size_t st_add(size_t a, s
                    (uintmax_t)a, (uintmax_t)b);
        return a + b;
  }
 -#define st_add3(a,b,c)   st_add((a),st_add((b),(c)))
 -#define st_add4(a,b,c,d) st_add((a),st_add3((b),(c),(d)))
 +#define st_add3(a,b,c)   st_add(st_add((a),(b)),(c))
 +#define st_add4(a,b,c,d) st_add(st_add3((a),(b),(c)),(d))
  
  static inline size_t st_mult(size_t a, size_t b)
  {
@@@ -764,72 -764,8 +761,72 @@@ extern int xmkstemp_mode(char *template
  extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
  extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
  extern char *xgetcwd(void);
 +extern FILE *fopen_for_writing(const char *path);
  
 -#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
 +#define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc)))
 +#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc)))
 +
 +/*
 + * These functions help you allocate structs with flex arrays, and copy
 + * the data directly into the array. For example, if you had:
 + *
 + *   struct foo {
 + *     int bar;
 + *     char name[FLEX_ARRAY];
 + *   };
 + *
 + * you can do:
 + *
 + *   struct foo *f;
 + *   FLEX_ALLOC_MEM(f, name, src, len);
 + *
 + * to allocate a "foo" with the contents of "src" in the "name" field.
 + * The resulting struct is automatically zero'd, and the flex-array field
 + * is NUL-terminated (whether the incoming src buffer was or not).
 + *
 + * The FLEXPTR_* variants operate on structs that don't use flex-arrays,
 + * but do want to store a pointer to some extra data in the same allocated
 + * block. For example, if you have:
 + *
 + *   struct foo {
 + *     char *name;
 + *     int bar;
 + *   };
 + *
 + * you can do:
 + *
 + *   struct foo *f;
 + *   FLEX_ALLOC_STR(f, name, src);
 + *
 + * and "name" will point to a block of memory after the struct, which will be
 + * freed along with the struct (but the pointer can be repointed anywhere).
 + *
 + * The *_STR variants accept a string parameter rather than a ptr/len
 + * combination.
 + *
 + * Note that these macros will evaluate the first parameter multiple
 + * times, and it must be assignable as an lvalue.
 + */
 +#define FLEX_ALLOC_MEM(x, flexname, buf, len) do { \
 +      (x) = NULL; /* silence -Wuninitialized for offset calculation */ \
 +      (x) = xalloc_flex(sizeof(*(x)), (char *)(&((x)->flexname)) - (char *)(x), (buf), (len)); \
 +} while (0)
 +#define FLEXPTR_ALLOC_MEM(x, ptrname, buf, len) do { \
 +      (x) = xalloc_flex(sizeof(*(x)), sizeof(*(x)), (buf), (len)); \
 +      (x)->ptrname = (void *)((x)+1); \
 +} while(0)
 +#define FLEX_ALLOC_STR(x, flexname, str) \
 +      FLEX_ALLOC_MEM((x), flexname, (str), strlen(str))
 +#define FLEXPTR_ALLOC_STR(x, ptrname, str) \
 +      FLEXPTR_ALLOC_MEM((x), ptrname, (str), strlen(str))
 +
 +static inline void *xalloc_flex(size_t base_len, size_t offset,
 +                              const void *src, size_t src_len)
 +{
 +      unsigned char *ret = xcalloc(1, st_add3(base_len, src_len, 1));
 +      memcpy(ret + offset, src, src_len);
 +      return ret;
 +}
  
  static inline char *xstrdup_or_null(const char *str)
  {
@@@ -843,9 -779,6 +840,9 @@@ static inline size_t xsize_t(off_t len
        return (size_t)len;
  }
  
 +__attribute__((format (printf, 3, 4)))
 +extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
 +
  /* in ctype.c, for kwset users */
  extern const unsigned char tolower_trans_tbl[256];
  
@@@ -916,9 -849,6 +913,9 @@@ static inline int strtoul_ui(char cons
        char *p;
  
        errno = 0;
 +      /* negative values would be accepted by strtoul */
 +      if (strchr(s, '-'))
 +              return -1;
        ul = strtoul(s, &p, base);
        if (errno || *p || p == s || (unsigned int) ul != ul)
                return -1;
diff --combined imap-send.c
index 407e46bc8c0e7c6748a5c0e92a47d86cacd55a13,78b6ff64945221b7583c5d4974627373bd44bdd9..938c6915858b93b7c860e49e906c45e0e2ea5d03
@@@ -287,17 -287,20 +287,20 @@@ static int ssl_socket_connect(struct im
        SSL_library_init();
        SSL_load_error_strings();
  
-       if (use_tls_only)
-               meth = TLSv1_method();
-       else
-               meth = SSLv23_method();
+       meth = SSLv23_method();
        if (!meth) {
                ssl_socket_perror("SSLv23_method");
                return -1;
        }
  
        ctx = SSL_CTX_new(meth);
+       if (!ctx) {
+               ssl_socket_perror("SSL_CTX_new");
+               return -1;
+       }
+       if (use_tls_only)
+               SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
  
        if (verify)
                SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
@@@ -862,7 -865,6 +865,6 @@@ static char hexchar(unsigned int b
  static char *cram(const char *challenge_64, const char *user, const char *pass)
  {
        int i, resp_len, encoded_len, decoded_len;
-       HMAC_CTX hmac;
        unsigned char hash[16];
        char hex[33];
        char *response, *response_64, *challenge;
                                      (unsigned char *)challenge_64, encoded_len);
        if (decoded_len < 0)
                die("invalid challenge %s", challenge_64);
-       HMAC_Init(&hmac, (unsigned char *)pass, strlen(pass), EVP_md5());
-       HMAC_Update(&hmac, (unsigned char *)challenge, decoded_len);
-       HMAC_Final(&hmac, hash, NULL);
-       HMAC_CTX_cleanup(&hmac);
+       if (!HMAC(EVP_md5(), pass, strlen(pass), (unsigned char *)challenge, decoded_len, hash, NULL))
+               die("HMAC error");
  
        hex[32] = 0;
        for (i = 0; i < 16; i++) {
        }
  
        /* response: "<user> <digest in hex>" */
 -      resp_len = strlen(user) + 1 + strlen(hex) + 1;
 -      response = xmalloc(resp_len);
 -      sprintf(response, "%s %s", user, hex);
 +      response = xstrfmt("%s %s", user, hex);
 +      resp_len = strlen(response);
  
 -      response_64 = xmalloc(ENCODED_SIZE(resp_len) + 1);
 +      response_64 = xmallocz(ENCODED_SIZE(resp_len));
        encoded_len = EVP_EncodeBlock((unsigned char *)response_64,
                                      (unsigned char *)response, resp_len);
        if (encoded_len < 0)
                die("EVP_EncodeBlock error");
 -      response_64[encoded_len] = '\0';
        return (char *)response_64;
  }
  
@@@ -1095,6 -1097,11 +1095,6 @@@ static struct imap_store *imap_open_sto
                                srvc->pass = xstrdup(cred.password);
                }
  
 -              if (CAP(NOLOGIN)) {
 -                      fprintf(stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host);
 -                      goto bail;
 -              }
 -
                if (srvc->auth_method) {
                        struct imap_cmd_cb cb;
  
                                goto bail;
                        }
                } else {
 +                      if (CAP(NOLOGIN)) {
 +                              fprintf(stderr, "Skipping account %s@%s, server forbids LOGIN\n",
 +                                      srvc->user, srvc->host);
 +                              goto bail;
 +                      }
                        if (!imap->buf.sock.ssl)
                                imap_warn("*** IMAP Warning *** Password is being "
                                          "sent in the clear\n");
@@@ -1187,7 -1189,7 +1187,7 @@@ static void lf_to_crlf(struct strbuf *m
                j++;
        }
  
 -      new = xmalloc(j + 1);
 +      new = xmallocz(j);
  
        /*
         * Second pass: write the new string.  Note that this loop is