diff -Nru librabbitmq-0.7.1/appveyor.yml librabbitmq-0.8.0/appveyor.yml --- librabbitmq-0.7.1/appveyor.yml 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/appveyor.yml 2016-04-10 05:03:24.000000000 +0000 @@ -1,13 +1,36 @@ # appveyor configuration version: '{build}' +# Limit history cloned. This matches what travis-CI currently does. +clone_depth: 50 + environment: matrix: - GENERATOR: Visual Studio 12 Win64 + BITS: 64 - GENERATOR: Visual Studio 12 + BITS: 32 + +cache: + - c:\deps -> appveyor.yml + +install: + - ps: $file = "Win${env:BITS}OpenSSL-1_0_2g.exe" + - ps: $dir = "c:\deps" + - ps: $exists = Test-Path "$dir\$file" + - ps: >- + If ($exists -ne $True) { + Write-Host "Downloading: $dir\$file." + New-Item -Path $dir -type directory -force + Start-FileDownload "http://slproweb.com/download/$file" -FileName "$dir\$file" + } Else { + Write-Host "Reusing cached: $dir\$file." + } + - ps: >- + & "$dir\$file" /silent /verysilent /sp- /suppressmsgboxes /dir="c:\OpenSSL" before_build: - - cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_TESTS=ON -DENABLE_SSL_SUPPORT=False -G"%GENERATOR%" . + - cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_TESTS=ON -DENABLE_SSL_SUPPORT=True -G"%GENERATOR%" . build: project: ALL_BUILD.vcxproj diff -Nru librabbitmq-0.7.1/.astyle librabbitmq-0.8.0/.astyle --- librabbitmq-0.7.1/.astyle 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/.astyle 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ ---style=1tbs ---indent=spaces=2 ---indent-preprocessor ---align-pointer=name diff -Nru librabbitmq-0.7.1/ChangeLog.md librabbitmq-0.8.0/ChangeLog.md --- librabbitmq-0.7.1/ChangeLog.md 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/ChangeLog.md 2016-04-10 05:03:24.000000000 +0000 @@ -1,4 +1,34 @@ # Change Log +## v0.8.0 - 2016-04-09 +### Added: +- SSL: peer certificate and hostname validation can now be controlled separately + using `amqp_ssl_socket_set_verify_peer` and + `amqp_ssl_socket_set_verify_hostname`. +- SSL: the desire SSL version range can now be specified using the + `amqp_ssl_socket_set_ssl_versions` function. +- Add flags to SSL examples on controlling hostname verification. + +### Changed: +- SSL: SSLv2, and SSLv3 have been disabled by default. +- SSL: OpenSSL hostname validation has been improved. +- Win32 debug information is built with /Z7 on MSVC to embed debug info instead + of using a .pdb + +### Fixed: +- Connection failure results in hang on Win32 (#297, #346) +- Rabbitmq-c may block when attempting to close an SSL socket (#313) +- amqp_parse_url does not correctly initialize default parameters (#319) +- x509 objects are leaked in verify_hostname (#323) +- TCP_NOPUSH doesn't work under cygwin (#335) + +### Deprecated +- SSL: `amqp_ssl_socket_set_verify` is being replaced by + `amqp_ssl_socket_set_verify_peer` and `amqp_ssl_socket_set_verify_hostname`. + +### Removed: +- OpenVMS build system and related files. +- Unmaintained PolarSSL, CyaSSL, and gnuTLS SSL backends + ## Changes since v0.7.0 (a.k.a., v0.7.1) - `41fa9df` Autoconf: add missing files in build system - `ef73c06` Win32: Use WSAEWOULDBLOCK instead of EWOULDBLOCK on Win32 diff -Nru librabbitmq-0.7.1/cmake/FindcyaSSL.cmake librabbitmq-0.8.0/cmake/FindcyaSSL.cmake --- librabbitmq-0.7.1/cmake/FindcyaSSL.cmake 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/cmake/FindcyaSSL.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# - Try to find the cyaSSL SSL Library -# The module will set the following variables -# -# CYASSL_FOUND - System has popt -# CYASSL_INCLUDE_DIR - The popt include directory -# CYASSL_LIBRARIES - The libraries needed to use popt - -# Find the include directories -FIND_PATH(CYASSL_INCLUDE_DIR - NAMES cyassl/ssl.h - DOC "Path containing the cyassl/ssl.h include file" - ) - -FIND_LIBRARY(CYASSL_LIBRARIES - NAMES cyassl - DOC "cyassl library path" - ) - -include(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(CYASSL - REQUIRED_VARS CYASSL_INCLUDE_DIR CYASSL_LIBRARIES - ) diff -Nru librabbitmq-0.7.1/cmake/FindPolarSSL.cmake librabbitmq-0.8.0/cmake/FindPolarSSL.cmake --- librabbitmq-0.7.1/cmake/FindPolarSSL.cmake 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/cmake/FindPolarSSL.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -# - Try to find the PolarSSL SSL Library -# The module will set the following variables -# -# POLARSSL_FOUND - System has popt -# POLARSSL_INCLUDE_DIR - The popt include directory -# POLARSSL_LIBRARIES - The libraries needed to use popt - -# Find the include directories -FIND_PATH(POLARSSL_INCLUDE_DIR - NAMES polarssl/ssl.h - DOC "Path containing the polarssl/ssl.h include file" - ) - -FIND_LIBRARY(POLARSSL_LIBRARIES - NAMES polarssl - DOC "polarssl library path" - ) - -include(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(POLARSSL - REQUIRED_VARS POLARSSL_INCLUDE_DIR POLARSSL_LIBRARIES - ) diff -Nru librabbitmq-0.7.1/cmake/InstallMacros.cmake librabbitmq-0.8.0/cmake/InstallMacros.cmake --- librabbitmq-0.7.1/cmake/InstallMacros.cmake 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/cmake/InstallMacros.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -# vim:set ts=2 sw=2 sts=2 et: -# -# This module install PDB files. -# -# Based on users posts: -# http://www.cmake.org/pipermail/cmake/2007-October/016924.html -# -# Copyright (c) 2006-2011 Mathieu Malaterre -# -# Redistribution and use is allowed according to the terms of the New -# BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# - -macro (install_pdb library) - if (MSVC) - if(CMAKE_CONFIGURATION_TYPES) - # Visual Studio - # The following does not work with LOCATION keyword. See: - # http://www.cmake.org/pipermail/cmake/2011-February/042579.html - foreach(cfg ${CMAKE_CONFIGURATION_TYPES}) - get_target_property(library_dll ${library} LOCATION_${cfg}) - string(REPLACE .dll .pdb library_pdb ${library_dll}) - string(TOLOWER ${cfg} lcfg) - if(lcfg STREQUAL "debug" OR lcfg STREQUAL "relwithdebinfo") - install (FILES ${library_pdb} - DESTINATION bin - CONFIGURATIONS ${cfg} - ) - endif() - endforeach() - else() - # nmake - # Same as above we need the explicit location_ variable to account for - # the value of CMAKE_DEBUG_POSTFIX - get_target_property(library_dll ${library} LOCATION_${CMAKE_BUILD_TYPE}) - string(REPLACE .dll .pdb library_pdb ${library_dll}) - string(TOLOWER ${CMAKE_BUILD_TYPE} lcfg) - if(lcfg STREQUAL "debug" OR lcfg STREQUAL "relwithdebinfo") - install (FILES ${library_pdb} - DESTINATION bin - ) - endif() - endif() - endif () -endmacro () diff -Nru librabbitmq-0.7.1/CMakeLists.txt librabbitmq-0.8.0/CMakeLists.txt --- librabbitmq-0.7.1/CMakeLists.txt 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/CMakeLists.txt 2016-04-10 05:03:24.000000000 +0000 @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 2.6) project(rabbitmq-c "C") +# Enable MACOSX_RPATH by default. See: cmake --help-policy CMP0042 +if (POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) +endif() + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # Follow all steps below in order to calculate new ABI version when updating the library @@ -12,9 +17,9 @@ # 3. If any interfaces have been added since the last public release, then increment age. # 4. If any interfaces have been removed since the last public release, then set age to 0. -set(RMQ_SOVERSION_CURRENT 5) -set(RMQ_SOVERSION_REVISION 3) -set(RMQ_SOVERSION_AGE 1) +set(RMQ_SOVERSION_CURRENT 6) +set(RMQ_SOVERSION_REVISION 0) +set(RMQ_SOVERSION_AGE 2) math(EXPR RMQ_SOVERSION_MAJOR "${RMQ_SOVERSION_CURRENT} - ${RMQ_SOVERSION_AGE}") math(EXPR RMQ_SOVERSION_MINOR "${RMQ_SOVERSION_AGE}") @@ -34,19 +39,6 @@ # VERSION to match what is in autotools set(VERSION ${_API_VERSION_MAJOR}.${_API_VERSION_MINOR}.${_API_VERSION_PATCH}) -if (MSVC) - set(CMAKE_C_FLAGS "/W4 /nologo ${CMAKE_C_FLAGS}") -elseif (CMAKE_C_COMPILER_ID MATCHES ".*Clang") - set(CMAKE_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common -fvisibility=hidden ${CMAKE_C_FLAGS}") -elseif (CMAKE_COMPILER_IS_GNUCC) - set(RMQ_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common") - execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - if (GCC_VERSION VERSION_GREATER 4.0 OR GCC_VERSION VERSION_EQUAL 4.0) - set(RMQ_C_FLAGS "${RMQ_C_FLAGS} -fvisibility=hidden") - endif() - set(CMAKE_C_FLAGS "${RMQ_C_FLAGS} ${CMAKE_C_FLAGS}") -endif () - if (CMAKE_GENERATOR MATCHES ".*(Make|Ninja).*" AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) @@ -54,23 +46,12 @@ endif() include(TestCInline) -include(CheckFunctionExists) include(CheckSymbolExists) include(CheckLibraryExists) include(CMakePushCheckState) include(GNUInstallDirs) include(CheckCCompilerFlag) -CHECK_C_COMPILER_FLAG("-std=gnu90" HAVE_GNU90) -if (HAVE_GNU90) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90") -else() - CHECK_C_COMPILER_FLAG("-std=c90" HAVE_C90) - if (HAVE_C90) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c90") - endif() -endif() - # Detect if we need to link against a socket library: cmake_push_check_state() if (WIN32) @@ -78,13 +59,15 @@ set(SOCKET_LIBRARIES ws2_32) else () # Is it in the default link? - CHECK_FUNCTION_EXISTS(getaddrinfo HAVE_GETADDRINFO) + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO) if (NOT (HAVE_GETADDRINFO EQUAL 1)) - CHECK_LIBRARY_EXISTS(socket getaddrinfo "" HAVE_GETADDRINFO2) + SET(CMAKE_REQUIRED_LIBRARIES "socket") + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO2) if (HAVE_GETADDRINFO2 EQUAL 1) set(SOCKET_LIBRARIES socket) else () - CHECK_LIBRARY_EXISTS("socket;nsl" getaddrinfo "" HAVE_GETADDRINFO3) + SET(CMAKE_REQUIRED_LIBRARIES "socket;nsl") + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO3) if (HAVE_GETADDRINFO3 EQUAL 1) set(SOCKET_LIBRARIES socket nsl) else () @@ -94,13 +77,15 @@ endif () set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES}) - CHECK_FUNCTION_EXISTS(socket HAVE_SOCKET) + check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET) if (NOT HAVE_SOCKET EQUAL 1) - CHECK_LIBRARY_EXISTS(socket socket "" HAVE_SOCKET2) - if (NOT HAVE_SOCKET2 EQUAL 1) + set(CMAKE_REQUIRED_LIBRARIES socket ${SOCKET_LIBRARIES}) + check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET2) + if (HAVE_SOCKET2 EQUAL 1) set(SOCKET_LIBRARIES socket ${SOCKET_LIBRARIES}) else () - CHECK_LIBRARY_EXISTS("socket;nsl" socket "" HAVE_SOCKET3) + set(CMAKE_REQUIRED_LIBRARIES socket nsl ${SOCKET_LIBRARIES}) + check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET3) if (HAVE_SOCKET3 EQUAL 1) set(SOCKET_LIBRARIES socket nsl ${SOCKET_LIBRARIES}) else () @@ -121,16 +106,13 @@ cmake_pop_check_state() cmake_push_check_state() -set(CMAKE_REQUIRED_INCLUDES "poll.h") -check_function_exists(poll HAVE_POLL) -set(CMAKE_REQUIRED_INCLUDES ) +set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES}) +check_symbol_exists(poll poll.h HAVE_POLL) if (NOT HAVE_POLL) if (WIN32) set(HAVE_SELECT 1) else() - set(CMAKE_REQUIRED_INCLUDES sys/select.h) - check_function_exists(select HAVE_SELECT) - set(CMAKE_REQUIRED_INCLUDES ) + check_symbol_exists(select sys/select.h HAVE_SELECT) endif() if (NOT HAVE_SELECT) message(FATAL_ERROR "rabbitmq-c requires poll() or select() to be available") @@ -139,10 +121,34 @@ cmake_pop_check_state() check_library_exists(rt clock_gettime "time.h" CLOCK_GETTIME_NEEDS_LIBRT) -if (CLOCK_GETTIME_NEEDS_LIBRT) +check_library_exists(rt posix_spawnp "spawn.h" POSIX_SPAWNP_NEEDS_LIBRT) +if (CLOCK_GETTIME_NEEDS_LIBRT OR POSIX_SPAWNP_NEEDS_LIBRT) set(LIBRT rt) endif() +if (MSVC) + set(CMAKE_C_FLAGS "/W4 /nologo ${CMAKE_C_FLAGS}") +elseif (CMAKE_C_COMPILER_ID MATCHES ".*Clang") + set(CMAKE_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common -fvisibility=hidden ${CMAKE_C_FLAGS}") +elseif (CMAKE_COMPILER_IS_GNUCC) + set(RMQ_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common") + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (GCC_VERSION VERSION_GREATER 4.0 OR GCC_VERSION VERSION_EQUAL 4.0) + set(RMQ_C_FLAGS "${RMQ_C_FLAGS} -fvisibility=hidden") + endif() + set(CMAKE_C_FLAGS "${RMQ_C_FLAGS} ${CMAKE_C_FLAGS}") +endif () + +CHECK_C_COMPILER_FLAG("-std=gnu90" HAVE_GNU90) +if (HAVE_GNU90) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90") +else() + CHECK_C_COMPILER_FLAG("-std=c90" HAVE_C90) + if (HAVE_C90) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c90") + endif() +endif() + option(REGENERATE_AMQP_FRAMING "Regenerate amqp_framing.h/amqp_framing.c sources (for developer use)" OFF) mark_as_advanced(REGENERATE_AMQP_FRAMING) @@ -263,25 +269,8 @@ option(ENABLE_SSL_SUPPORT "Enable SSL support" ON) option(ENABLE_THREAD_SAFETY "Enable thread safety when using OpenSSL" ${Threads_FOUND}) -set(SSL_ENGINE "OpenSSL" CACHE STRING "SSL Backend to use, valid options: OpenSSL, cyaSSL, GnuTLS, PolarSSL") -mark_as_advanced(SSL_ENGINE) - if (ENABLE_SSL_SUPPORT) - if (SSL_ENGINE STREQUAL "OpenSSL") - find_package(OpenSSL 0.9.8 REQUIRED) - - elseif (SSL_ENGINE STREQUAL "cyaSSL") - find_package(cyaSSL REQUIRED) - - elseif (SSL_ENGINE STREQUAL "GnuTLS") - find_package(GnuTLS REQUIRED) - - elseif (SSL_ENGINE STREQUAL "PolarSSL") - find_package(PolarSSL REQUIRED) - - else() - message(FATAL_ERROR "Unsupported SSL_ENGINE ${SSL_ENGINE}, valid engines: OpenSSL, cyaSSL, GnuTLS, or PolarSSL") - endif() + find_package(OpenSSL 0.9.8 REQUIRED) endif() if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS) diff -Nru librabbitmq-0.7.1/configure.ac librabbitmq-0.8.0/configure.ac --- librabbitmq-0.7.1/configure.ac 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/configure.ac 2016-04-10 05:03:24.000000000 +0000 @@ -2,8 +2,8 @@ AC_PREREQ([2.59]) m4_define([major_version], [0]) -m4_define([minor_version], [7]) -m4_define([micro_version], [1]) +m4_define([minor_version], [8]) +m4_define([micro_version], [0]) # Follow all steps below in order to calculate new ABI version when updating the library # NOTE: THIS IS UNRELATED to the actual project version @@ -12,13 +12,13 @@ # 2. If any interfaces have been added, removed, or changed since the last update, increment current and set revision to 0. # 3. If any interfaces have been added since the last public release, then increment age. # 4. If any interfaces have been removed since the last public release, then set age to 0. -m4_define([soversion_current], [5]) -m4_define([soversion_revision], [3]) -m4_define([soversion_age], [1]) +m4_define([soversion_current], [6]) +m4_define([soversion_revision], [0]) +m4_define([soversion_age], [2]) AC_INIT([rabbitmq-c], [major_version.minor_version.micro_version], - [https://github.com/alanxz/rabbitmq-c/issues], [rabbitmq-c], - [http://www.rabbitmq.com/]) + [https://github.com/alanxz/rabbitmq-c/issues], [rabbitmq-c], + [http://www.rabbitmq.com/]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.9 subdir-objects foreign -Wno-portability]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -31,9 +31,9 @@ # Program checks m4_ifdef([AC_PROG_CC_89], [AC_PROG_CC_89], - [AC_MSG_WARN([Attempt c89 workaround for old versions of autoconf]) - AC_PROG_CC - AX_TRY_CFLAGS([-std=gnu90], [AX_CFLAGS([-std=gnu90])])]) + [AC_MSG_WARN([Attempt c89 workaround for old versions of autoconf]) + AC_PROG_CC + AX_TRY_CFLAGS([-std=gnu90], [AX_CFLAGS([-std=gnu90])])]) PKG_PROG_PKG_CONFIG([0.17]) # Environment setup @@ -98,10 +98,11 @@ [-lnsl])]) AC_SEARCH_LIBS([socket], [socket], [], [AC_CHECK_LIB([socket], [socket], - [LIBS="-lsocket -lnsl $LIBS"], + [LIBS="-lsocket -lnsl $LIBS"], [AC_MSG_ERROR([cannot find socket library (library with socket symbol)])], [-lnsl])]) AC_SEARCH_LIBS([clock_gettime], [rt]) +AC_SEARCH_LIBS([posix_spawnp], [rt]) AC_MSG_CHECKING([if htonll is defined]) dnl # Check for htonll @@ -130,64 +131,53 @@ # Configure SSL/TLS AC_ARG_WITH([ssl], - [AS_HELP_STRING([--with-ssl=@<:@cyassl/gnutls/no/openssl/polarssl/yes@:>@], - [enable SSL/TLS support @<:@default=openssl@:>@])], - [AS_CASE([$withval], - [yes], [with_ssl=openssl], - [*], [with_ssl=$withval])], - [with_ssl=openssl]) - -AS_IF([test "x$with_ssl" = "xcyassl"], - [PKG_CHECK_MODULES([SSL], [libcyassl],, [with_ssl=no])], - [test "x$with_ssl" = "xgnutls"], - [PKG_CHECK_MODULES([SSL], [gnutls],, [with_ssl=no])], - [test "x$with_ssl" = "xopenssl"], + [AS_HELP_STRING([--with-ssl=@<:@no/openssl/yes@:>@], + [enable SSL/TLS support @<:@default=openssl@:>@])], + [AS_CASE([$withval], + [yes], [with_ssl=openssl], + [*], [with_ssl=$withval])], + [with_ssl=openssl]) + +AS_IF([test "x$with_ssl" = "xopenssl"], [PKG_CHECK_MODULES([SSL], [openssl >= 0.9.8], [ssl_pkg_required=openssl], [with_ssl=no])], - [test "x$with_ssl" = "xpolarssl"], - [AX_LIB_POLARSSL([SSL_CFLAGS=$POLARSSL_CFLAGS - SSL_LIBS=$POLARSSL_LIBS], - [with_ssl=no])], [test "x$with_ssl" = "xno"],, [AC_MSG_ERROR([unknown SSL/TLS implementation: $with_ssl])]) -AM_CONDITIONAL([SSL_CYASSL], [test "x$with_ssl" = "xcyassl"]) -AM_CONDITIONAL([SSL_GNUTLS], [test "x$with_ssl" = "xgnutls"]) AM_CONDITIONAL([SSL_OPENSSL], [test "x$with_ssl" = "xopenssl"]) -AM_CONDITIONAL([SSL_POLARSSL], [test "x$with_ssl" = "xpolarssl"]) AM_CONDITIONAL([SSL], [test "x$with_ssl" != "xno"]) AS_IF([test "x$with_ssl" != "xno"], [AC_DEFINE([WITH_SSL], [1], [Define to 1 if SSL/TLS is enabled.])]) # Configure AMQP command-line tools AC_ARG_ENABLE([tools], - [AS_HELP_STRING([--enable-tools], - [build AMQP command-line tools @<:@auto@:>@])],, - [enable_tools=auto]) + [AS_HELP_STRING([--enable-tools], + [build AMQP command-line tools @<:@auto@:>@])],, + [enable_tools=auto]) AS_IF([test "x$enable_tools" != "xno"], [AX_LIB_POPT([enable_tools=yes], [enable_tools=no])]) AM_CONDITIONAL([TOOLS], [test "x$enable_tools" = "xyes"]) # Configure command-line tool documentation AC_ARG_ENABLE([docs], - [AS_HELP_STRING([--enable-docs], - [build command-line tool documentation @<:@auto@:>@])],, - [AS_IF([test "x$enable_tools" = "xno"], - [enable_docs=no], - [enable_docs=auto])]) + [AS_HELP_STRING([--enable-docs], + [build command-line tool documentation @<:@auto@:>@])],, + [AS_IF([test "x$enable_tools" = "xno"], + [enable_docs=no], + [enable_docs=auto])]) AC_ARG_VAR([XMLTO], [xmlto command]) AS_IF([test "x$enable_docs" != "xno"], - [AS_IF([test "x$XMLTO" = "x"], - [AC_CHECK_PROGS([XMLTO], [xmlto])]) - AS_IF([test "x$XMLTO" != "x"], - [enable_docs=yes], - [enable_docs=no])]) + [AS_IF([test "x$XMLTO" = "x"], + [AC_CHECK_PROGS([XMLTO], [xmlto])]) + AS_IF([test "x$XMLTO" != "x"], + [enable_docs=yes], + [enable_docs=no])]) AM_CONDITIONAL([DOCS], [test "x$enable_docs" = "xyes"]) # Configure examples AC_ARG_ENABLE([examples], - [AS_HELP_STRING([--enable-examples], - [build example code @<:@auto@:>@])],, - [enable_examples=yes]) + [AS_HELP_STRING([--enable-examples], + [build example code @<:@auto@:>@])],, + [enable_examples=yes]) AM_CONDITIONAL([EXAMPLES], [test "x$enable_examples" = "xyes"]) AC_SUBST([requires_private], [$ssl_pkg_required]) @@ -195,16 +185,16 @@ AC_DEFINE_UNQUOTED([AMQ_PLATFORM], ["$host_os"], [Host operating system string]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ - librabbitmq.pc - Makefile + librabbitmq.pc + Makefile ]) AC_OUTPUT AC_MSG_RESULT([ $PACKAGE_NAME build options: - Host: $host - Version: $VERSION - SSL/TLS: $with_ssl - Tools: $enable_tools - Documentation: $enable_docs - Examples: $enable_examples + Host: $host + Version: $VERSION + SSL/TLS: $with_ssl + Tools: $enable_tools + Documentation: $enable_docs + Examples: $enable_examples ]) diff -Nru librabbitmq-0.7.1/coverity/model.c librabbitmq-0.8.0/coverity/model.c --- librabbitmq-0.7.1/coverity/model.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/coverity/model.c 2016-04-10 05:03:24.000000000 +0000 @@ -1,16 +1,16 @@ /* Functions to help coverity do static analysis on rabbitmq-c */ -void amqp_abort(const char *fmt, ...) -{ - __coverity_panic__(); -} +typedef struct {} amqp_rpc_reply_t; -void die_on_amqp_error(amqp_rpc_reply *r) -{ - __coverity_panic__(); -} +/* librabbitmq/amqp_private.h */ +void amqp_abort(const char *fmt, ...) { __coverity_panic__(); } -void die_on_error(int r) -{ - __coverity_panic__(); -} +/* tools/common.h */ +void die(const char* fmt, ...) { __coverity_panic__(); } +void die_errno(int err, const char* fmt, ...) { __coverity_panic__(); } +void die_amqp_error(int err, const char* fmt, ...) { __coverity_panic__(); } +void die_rpc(amqp_rpc_reply_t r, const char* fmt, ...) { __coverity_panic__(); } + +/* examples/utils.h */ +void die_on_amqp_error(amqp_rpc_reply_t *r) { __coverity_panic__(); } +void die_on_error(int r) { __coverity_panic__(); } diff -Nru librabbitmq-0.7.1/debian/changelog librabbitmq-0.8.0/debian/changelog --- librabbitmq-0.7.1/debian/changelog 2016-01-18 14:13:03.000000000 +0000 +++ librabbitmq-0.8.0/debian/changelog 2017-08-10 22:12:00.000000000 +0000 @@ -1,8 +1,17 @@ -librabbitmq (0.7.1-1+deb.sury.org~trusty+4) trusty; urgency=medium +librabbitmq (0.8.0-1+ubuntu14.04.1+deb.sury.org+1) trusty; urgency=medium - * Backport for Trusty Tahr (14.04 LTS) + * No-change backport to trusty - -- Ondřej Surý Mon, 18 Jan 2016 15:13:03 +0100 + -- Ondřej Surý Fri, 11 Aug 2017 00:12:00 +0200 + +librabbitmq (0.8.0-1) unstable; urgency=medium + + * Update Vcs-Git header to use https. + * Update standards version to 3.9.8. + * New upstream version. Closes: #824792. + * Distribute static archive. Closes: #686829. + + -- Brian May Sun, 24 Jul 2016 11:14:26 +1000 librabbitmq (0.7.1-1) unstable; urgency=medium diff -Nru librabbitmq-0.7.1/debian/control librabbitmq-0.8.0/debian/control --- librabbitmq-0.7.1/debian/control 2016-01-18 14:12:42.000000000 +0000 +++ librabbitmq-0.8.0/debian/control 2016-07-24 01:14:26.000000000 +0000 @@ -3,15 +3,15 @@ Section: libs Maintainer: Michael Fladischer Uploaders: Brian May -Build-Depends: cmake (>= 3.2.2~), +Build-Depends: cmake, debhelper (>= 9), docbook-to-man, libpopt-dev, libssl-dev, libtool -Standards-Version: 3.9.6 +Standards-Version: 3.9.8 Homepage: https://github.com/alanxz/rabbitmq-c -Vcs-Git: git://anonscm.debian.org/collab-maint/librabbitmq.git +Vcs-Git: https://anonscm.debian.org/git/collab-maint/librabbitmq.git Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/librabbitmq.git Package: librabbitmq-dev diff -Nru librabbitmq-0.7.1/debian/librabbitmq4.symbols librabbitmq-0.8.0/debian/librabbitmq4.symbols --- librabbitmq-0.7.1/debian/librabbitmq4.symbols 2016-01-18 14:12:42.000000000 +0000 +++ librabbitmq-0.8.0/debian/librabbitmq4.symbols 2016-07-24 01:14:26.000000000 +0000 @@ -86,7 +86,10 @@ amqp_ssl_socket_set_cacert@Base 0.6.0 amqp_ssl_socket_set_key@Base 0.6.0 amqp_ssl_socket_set_key_buffer@Base 0.6.0 + amqp_ssl_socket_set_ssl_versions@Base 0.8.0 amqp_ssl_socket_set_verify@Base 0.6.0 + amqp_ssl_socket_set_verify_hostname@Base 0.8.0 + amqp_ssl_socket_set_verify_peer@Base 0.8.0 amqp_table_clone@Base 0.6.0 amqp_table_entry_cmp@Base 0.6.0 amqp_tcp_socket_new@Base 0.6.0 diff -Nru librabbitmq-0.7.1/debian/librabbitmq-dev.install librabbitmq-0.8.0/debian/librabbitmq-dev.install --- librabbitmq-0.7.1/debian/librabbitmq-dev.install 2016-01-18 14:12:42.000000000 +0000 +++ librabbitmq-0.8.0/debian/librabbitmq-dev.install 2016-07-24 01:14:26.000000000 +0000 @@ -1,3 +1,4 @@ usr/include/*.h usr/lib/*/lib*.so +usr/lib/*/lib*.a usr/lib/*/pkgconfig/librabbitmq.pc diff -Nru librabbitmq-0.7.1/descrip.mms librabbitmq-0.8.0/descrip.mms --- librabbitmq-0.7.1/descrip.mms 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/descrip.mms 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ - -ALL : LIBRABBITMQ - @ CONTINUE - -LIBRABBITMQ : - SET DEFAULT [.LIBRABBITMQ] - MMK$(MMSQUALIFIERS) - SET DEFAULT [-] - -EXAMPLES : LIBRABBITMQ - SET DEFAULT [.EXAMPLES] - MMK$(MMSQUALIFIERS) - SET DEFAULT [-] - diff -Nru librabbitmq-0.7.1/etc/build-ms.sh librabbitmq-0.8.0/etc/build-ms.sh --- librabbitmq-0.7.1/etc/build-ms.sh 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/etc/build-ms.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -#!/bin/bash - -# Build rabbitmq-c using Microsoft's C compiler - -set -e - -vs64= -sdk64= - -while [ $# -gt 0 ] ; do - case $1 in - --enable-64-bit) - vs64=/amd64 - sdk64=/x64 - ;; - *) - echo "Usage: build-ms.sh [ --enable-64-bit ]" 1>&2 - exit 1 - esac - shift -done - -# Locate the necessary lib and include directories - -drive=$(echo "$SYSTEMDRIVE" | sed 's|^\([A-Za-z]\):$|/\1|') - -for vsvers in 10.0 9.0 8 ; do - vsdir="$drive/Program Files/Microsoft Visual Studio $vsvers" - [ -x "$vsdir/VC/bin$vs64/cl.exe" ] && break - - vsdir="$drive/Program Files (x86)/Microsoft Visual Studio $vsvers" - [ -x "$vsdir/VC/bin$vs64/cl.exe" ] && break - - vsdir= -done - -if [ -z "$vsdir" ] ; then - echo "Couldn't find a suitable Visual Studio installation" - exit 1 -fi - -echo "Using Visual Studio install at $vsdir" - -for sdkpath in "Microsoft SDKs/Windows/"{v7.0A,v6.0A} "Microsoft Visual Studio 8/VC/PlatformSDK" ; do - sdkdir="$drive/Program Files/$sdkpath" - [ -d "$sdkdir/lib$sdk64" -a -d "$sdkdir/include" ] && break - - sdkdir="$drive/Program Files (x86)/$sdkpath" - [ -d "$sdkdir/lib$sdk64" -a -d "$sdkdir/include" ] && break - - sdkdir= -done - -if [ -z "$sdkdir" ] ; then - echo "Couldn't find suitable Windows SDK installation" - exit 1 -fi - -echo "Using Windows SDK install at $sdkdir" - -PATH="$PATH:$vsdir/VC/bin$vs64:$vsdir/Common7/IDE" -LIB="$vsdir/VC/lib$vs64:$sdkdir/lib$sdk64" -INCLUDE="$vsdir/VC/include:$sdkdir/include" -export PATH LIB INCLUDE - -# Do the build -set -x -autoreconf -i -./configure CC=cl.exe LD=link.exe CFLAGS='-nologo' -sed -i -e 's/^fix_srcfile_path=.*$/fix_srcfile_path=""/;s/^deplibs_check_method=.*$/deplibs_check_method=pass_all/;/^archive_cmds=/s/-link -dll/& -implib:\\$libname.\\$libext/' libtool -make - -# Copy the results of the build into one place, as "make install" -# isn't too useful here. -mkdir -p build/lib build/include build/bin -cp -a librabbitmq/.libs/*.dll examples/.libs/*.exe build/bin -cp -a librabbitmq/win32/msinttypes/*.h librabbitmq/amqp.h librabbitmq/amqp_framing.h build/include -cp -a librabbitmq/*.exp librabbitmq/*.lib build/lib diff -Nru librabbitmq-0.7.1/etc/install-mingw.sh librabbitmq-0.8.0/etc/install-mingw.sh --- librabbitmq-0.7.1/etc/install-mingw.sh 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/etc/install-mingw.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -#!/bin/bash - -if [ $# -ne 1 ] ; then - echo "usage: install-mingw.sh " 1>&2 - exit 1 -fi - -unpack_dir=$1 - -if [ -e "$unpack_dir" ] ; then - echo "Destination directory already exists; please delete it if you are sure" 1>&2 - exit 1 -fi - -set -e - -download_dir=/tmp/install-mingw.$$ -mkdir -p $download_dir $unpack_dir - -while read f ; do - wget -P $download_dir -N http://switch.dl.sourceforge.net/project/mingw/$f -done <&2 - exit 1 - ;; - esac -done - -rm -rf $download_dir diff -Nru librabbitmq-0.7.1/examples/amqp_connect_timeout.c librabbitmq-0.8.0/examples/amqp_connect_timeout.c --- librabbitmq-0.7.1/examples/amqp_connect_timeout.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqp_connect_timeout.c 2016-04-10 05:03:24.000000000 +0000 @@ -64,6 +64,7 @@ int port; amqp_socket_t *socket; amqp_connection_state_t conn; + struct timeval tval; struct timeval *tv; if (argc < 3) { @@ -72,7 +73,7 @@ } if (argc > 3) { - tv = malloc(sizeof(struct timeval)); + tv = &tval; tv->tv_sec = atoi(argv[3]); diff -Nru librabbitmq-0.7.1/examples/amqp_consumer.c librabbitmq-0.8.0/examples/amqp_consumer.c --- librabbitmq-0.7.1/examples/amqp_consumer.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqp_consumer.c 2016-04-10 05:03:24.000000000 +0000 @@ -61,7 +61,7 @@ uint64_t now; - while (1) { + for (;;) { amqp_rpc_reply_t ret; amqp_envelope_t envelope; @@ -130,7 +130,7 @@ return; default: - fprintf(stderr ,"An unexpected method was received %d\n", frame.payload.method.id); + fprintf(stderr ,"An unexpected method was received %u\n", frame.payload.method.id); return; } } diff -Nru librabbitmq-0.7.1/examples/amqp_listen.c librabbitmq-0.8.0/examples/amqp_listen.c --- librabbitmq-0.7.1/examples/amqp_listen.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqp_listen.c 2016-04-10 05:03:24.000000000 +0000 @@ -104,7 +104,7 @@ die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { - while (1) { + for (;;) { amqp_rpc_reply_t res; amqp_envelope_t envelope; diff -Nru librabbitmq-0.7.1/examples/amqp_listenq.c librabbitmq-0.8.0/examples/amqp_listenq.c --- librabbitmq-0.7.1/examples/amqp_listenq.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqp_listenq.c 2016-04-10 05:03:24.000000000 +0000 @@ -85,7 +85,7 @@ die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { - while (1) { + for (;;) { amqp_rpc_reply_t res; amqp_envelope_t envelope; diff -Nru librabbitmq-0.7.1/examples/amqp_rpc_sendstring_client.c librabbitmq-0.8.0/examples/amqp_rpc_sendstring_client.c --- librabbitmq-0.7.1/examples/amqp_rpc_sendstring_client.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqp_rpc_sendstring_client.c 2016-04-10 05:03:24.000000000 +0000 @@ -160,7 +160,7 @@ size_t body_target; size_t body_received; - while (1) { + for (;;) { amqp_maybe_release_buffers(conn); result = amqp_simple_wait_frame(conn, &frame); printf("Result: %d\n", result); @@ -168,7 +168,7 @@ break; } - printf("Frame type: %d channel: %d\n", frame.frame_type, frame.channel); + printf("Frame type: %u channel: %u\n", frame.frame_type, frame.channel); if (frame.frame_type != AMQP_FRAME_METHOD) { continue; } diff -Nru librabbitmq-0.7.1/examples/amqps_bind.c librabbitmq-0.8.0/examples/amqps_bind.c --- librabbitmq-0.7.1/examples/amqps_bind.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_bind.c 2016-04-10 05:03:24.000000000 +0000 @@ -59,7 +59,7 @@ if (argc < 6) { fprintf(stderr, "Usage: amqps_bind host port exchange bindingkey queue " - "[cacert.pem [key.pem cert.pem]]\n"); + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } @@ -76,17 +76,29 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 6) { + int nextarg = 7; status = amqp_ssl_socket_set_cacert(socket, argv[6]); if (status) { die("setting CA certificate"); } - } - - if (argc > 8) { - status = amqp_ssl_socket_set_key(socket, argv[8], argv[7]); - if (status) { - die("setting client cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client cert"); + } } } diff -Nru librabbitmq-0.7.1/examples/amqps_connect_timeout.c librabbitmq-0.8.0/examples/amqps_connect_timeout.c --- librabbitmq-0.7.1/examples/amqps_connect_timeout.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_connect_timeout.c 2016-04-10 05:03:24.000000000 +0000 @@ -63,33 +63,31 @@ int main(int argc, char const *const *argv) { - char const nofile[2] = "-"; char const *hostname; - int port, status; + int port; + int timeout; amqp_socket_t *socket; amqp_connection_state_t conn; + struct timeval tval; struct timeval *tv; if (argc < 3) { - fprintf(stderr, "Usage: amqps_connect_timeout host port " - "[cacert.pem [key.pem cert.pem [timeout_sec [timeout_usec=0]]]]\n"); + fprintf( + stderr, + "Usage: amqps_connect_timeout host port timeout_sec " + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } hostname = argv[1]; port = atoi(argv[2]); - if (argc > 6) { - tv = malloc(sizeof(struct timeval)); - - tv->tv_sec = atoi(argv[6]); - - if (argc > 7 ) { - tv->tv_usec = atoi(argv[7]); - } else { - tv->tv_usec = 0; - } + timeout = atoi(argv[3]); + if (timeout > 0) { + tv = &tval; + tv->tv_sec = timeout; + tv->tv_usec = 0; } else { tv = NULL; } @@ -101,21 +99,25 @@ die("creating SSL/TLS socket"); } - if (argc > 3 && strcmp(nofile, argv[3])) { - die_on_error(amqp_ssl_socket_set_cacert(socket, argv[3]), "setting CA certificate"); - } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); if (argc > 5) { - if (!strcmp(nofile, argv[5]) && !strcmp(nofile, argv[4])) { - status = 0; - } else if (!strcmp(nofile, argv[5]) || !strcmp(nofile, argv[4])) { - status = -1; - } else { - status = amqp_ssl_socket_set_key(socket, argv[5], argv[4]); + int nextarg = 6; + die_on_error(amqp_ssl_socket_set_cacert(socket, argv[5]), + "setting CA certificate"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; } - - if (status) { - die("setting client key"); + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + die_on_error( + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]), + "setting client key"); } } diff -Nru librabbitmq-0.7.1/examples/amqps_consumer.c librabbitmq-0.8.0/examples/amqps_consumer.c --- librabbitmq-0.7.1/examples/amqps_consumer.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_consumer.c 2016-04-10 05:03:24.000000000 +0000 @@ -63,7 +63,7 @@ uint64_t now; - while (1) { + for (;;) { amqp_rpc_reply_t ret; amqp_envelope_t envelope; @@ -132,7 +132,7 @@ return; default: - fprintf(stderr ,"An unexpected method was received %d\n", frame.payload.method.id); + fprintf(stderr ,"An unexpected method was received %u\n", frame.payload.method.id); return; } } @@ -159,7 +159,7 @@ if (argc < 3) { fprintf(stderr, "Usage: amqps_consumer host port " - "[cacert.pem [key.pem cert.pem]]\n"); + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } @@ -175,17 +175,29 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 3) { + int nextarg = 4; status = amqp_ssl_socket_set_cacert(socket, argv[3]); if (status) { die("setting CA certificate"); } - } - - if (argc > 5) { - status = amqp_ssl_socket_set_key(socket, argv[5], argv[4]); - if (status) { - die("setting client key"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client key"); + } } } diff -Nru librabbitmq-0.7.1/examples/amqps_exchange_declare.c librabbitmq-0.8.0/examples/amqps_exchange_declare.c --- librabbitmq-0.7.1/examples/amqps_exchange_declare.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_exchange_declare.c 2016-04-10 05:03:24.000000000 +0000 @@ -58,7 +58,8 @@ if (argc < 5) { fprintf(stderr, "Usage: amqps_exchange_declare host port exchange " - "exchangetype [cacert.pem [key.pem cert.pem]]\n"); + "exchangetype [cacert.pem [verifypeer] [verifyhostname] " + "[key.pem cert.pem]]\n"); return 1; } @@ -74,17 +75,29 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 5) { + int nextarg = 6; status = amqp_ssl_socket_set_cacert(socket, argv[5]); if (status) { die("setting CA certificate"); } - } - - if (argc > 7) { - status = amqp_ssl_socket_set_key(socket, argv[7], argv[6]); - if (status) { - die("setting client key/cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client key/cert"); + } } } diff -Nru librabbitmq-0.7.1/examples/amqps_listen.c librabbitmq-0.8.0/examples/amqps_listen.c --- librabbitmq-0.7.1/examples/amqps_listen.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_listen.c 2016-04-10 05:03:24.000000000 +0000 @@ -62,7 +62,7 @@ if (argc < 5) { fprintf(stderr, "Usage: amqps_listen host port exchange bindingkey " - "[cacert.pem [key.pem cert.pem]]\n"); + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } @@ -78,20 +78,33 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 5) { + int nextarg = 6; status = amqp_ssl_socket_set_cacert(socket, argv[5]); if (status) { die("setting CA certificate"); } - } - - if (argc > 7) { - status = amqp_ssl_socket_set_key(socket, argv[7], argv[6]); - if (status) { - die("setting client cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client cert"); + } } } + status = amqp_socket_open(socket, hostname, port); if (status) { die("opening SSL/TLS connection"); @@ -121,7 +134,7 @@ die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { - while (1) { + for (;;) { amqp_rpc_reply_t res; amqp_envelope_t envelope; diff -Nru librabbitmq-0.7.1/examples/amqps_listenq.c librabbitmq-0.8.0/examples/amqps_listenq.c --- librabbitmq-0.7.1/examples/amqps_listenq.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_listenq.c 2016-04-10 05:03:24.000000000 +0000 @@ -59,7 +59,7 @@ if (argc < 4) { fprintf(stderr, "Usage: amqps_listenq host port queuename " - "[cacert.pem [key.pem cert.pem]]\n"); + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } @@ -74,20 +74,33 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 4) { + int nextarg = 5; status = amqp_ssl_socket_set_cacert(socket, argv[4]); if (status) { die("setting CA certificate"); } - } - - if (argc > 6) { - status = amqp_ssl_socket_set_key(socket, argv[6], argv[5]); - if (status) { - die("setting client cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client cert"); + } } } + status = amqp_socket_open(socket, hostname, port); if (status) { die("opening SSL/TLS connection"); @@ -102,7 +115,7 @@ die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); { - while (1) { + for (;;) { amqp_rpc_reply_t res; amqp_envelope_t envelope; diff -Nru librabbitmq-0.7.1/examples/amqps_producer.c librabbitmq-0.8.0/examples/amqps_producer.c --- librabbitmq-0.7.1/examples/amqps_producer.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_producer.c 2016-04-10 05:03:24.000000000 +0000 @@ -103,7 +103,7 @@ { uint64_t stop_time = now_microseconds(); - int total_delta = stop_time - start_time; + int total_delta = (int)(stop_time - start_time); printf("PRODUCER - Message count: %d\n", message_count); printf("Total time, milliseconds: %d\n", total_delta / 1000); @@ -122,7 +122,7 @@ if (argc < 5) { fprintf(stderr, "Usage: amqps_producer host port rate_limit message_count " - "[cacert.pem [key.pem cert.pem]]\n"); + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } @@ -138,17 +138,29 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 5) { + int nextarg = 6; status = amqp_ssl_socket_set_cacert(socket, argv[5]); if (status) { die("setting CA certificate"); } - } - - if (argc > 7) { - status = amqp_ssl_socket_set_key(socket, argv[7], argv[6]); - if (status) { - die("setting client cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client cert"); + } } } diff -Nru librabbitmq-0.7.1/examples/amqps_sendstring.c librabbitmq-0.8.0/examples/amqps_sendstring.c --- librabbitmq-0.7.1/examples/amqps_sendstring.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_sendstring.c 2016-04-10 05:03:24.000000000 +0000 @@ -59,7 +59,8 @@ if (argc < 6) { fprintf(stderr, "Usage: amqps_sendstring host port exchange routingkey " - "messagebody [cacert.pem [key.pem cert.pem]]\n"); + "messagebody [cacert.pem [verifypeer] [verifyhostname] " + "[key.pem cert.pem]]\n"); return 1; } @@ -76,17 +77,29 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 6) { + int nextarg = 7; status = amqp_ssl_socket_set_cacert(socket, argv[6]); if (status) { die("setting CA certificate"); } - } - - if (argc > 8) { - status = amqp_ssl_socket_set_key(socket, argv[8], argv[7]); - if (status) { - die("setting client cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client cert"); + } } } diff -Nru librabbitmq-0.7.1/examples/amqps_unbind.c librabbitmq-0.8.0/examples/amqps_unbind.c --- librabbitmq-0.7.1/examples/amqps_unbind.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/amqps_unbind.c 2016-04-10 05:03:24.000000000 +0000 @@ -59,7 +59,7 @@ if (argc < 6) { fprintf(stderr, "Usage: amqps_unbind host port exchange bindingkey queue " - "[cacert.pem [key.pem cert.pem]]\n"); + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); return 1; } @@ -76,17 +76,29 @@ die("creating SSL/TLS socket"); } + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + if (argc > 6) { + int nextarg = 7; status = amqp_ssl_socket_set_cacert(socket, argv[6]); if (status) { die("setting CA certificate"); } - } - - if (argc > 8) { - status = amqp_ssl_socket_set_key(socket, argv[8], argv[7]); - if (status) { - die("setting client cert"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + status = + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]); + if (status) { + die("setting client cert"); + } } } diff -Nru librabbitmq-0.7.1/examples/descrip.mms librabbitmq-0.8.0/examples/descrip.mms --- librabbitmq-0.7.1/examples/descrip.mms 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/descrip.mms 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ - -OBJS = AMQP_BIND.OBJ, AMQP_CONSUMER.OBJ, AMQP_EXCHANGE_DECLARE.OBJ, AMQP_LISTEN.OBJ,- - AMQP_LISTENQ.OBJ, AMQP_PRODUCER.OBJ, AMQP_SENDSTRING.OBJ, AMQP_UNBIND.OBJ, UTILS.OBJ,- - PLATFORM_UTILS.OBJ - -COM_OBJS = UTILS.OBJ, PLATFORM_UTILS.OBJ - -REAL_TARGETS = AMQP_BIND.EXE AMQP_CONSUMER.EXE AMQP_EXCHANGE_DECLARE.EXE AMQP_LISTEN.EXE AMQP_LISTENQ.EXE AMQP_PRODUCER.EXE AMQP_SENDSTRING.EXE AMQP_UNBIND.EXE - -.INCLUDE [-.vms]INCLUDE.MMS - -CFLAGS = $(OPTFLAGS)/DEFINE=($(DEFS))/INCLUDE=($(INC),"../vms","../librabbitmq") -LDFLAGS = /TRACE - -AMQP_BIND.EXE : AMQP_BIND.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_CONSUMER.EXE : AMQP_CONSUMER.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_EXCHANGE_DECLARE.EXE : AMQP_EXCHANGE_DECLARE.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_LISTEN.EXE : AMQP_LISTEN.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_LISTENQ.EXE : AMQP_LISTENQ.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_PRODUCER.EXE : AMQP_PRODUCER.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_SENDSTRING.EXE : AMQP_SENDSTRING.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - -AMQP_UNBIND.EXE : AMQP_UNBIND.OBJ, $(COM_OBJS) - LINK$(LDFLAGS)/EXE=$(MMS$TARGET) $(MMS$SOURCE_LIST),[-.librabbitmq]rabbitmq.olb/lib - - -PLATFORM_UTILS.OBJ : [.UNIX]PLATFORM_UTILS.C -PLATFORM_UTILS.MMSD : [.UNIX]PLATFORM_UTILS.C diff -Nru librabbitmq-0.7.1/examples/utils.c librabbitmq-0.8.0/examples/utils.c --- librabbitmq-0.7.1/examples/utils.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/examples/utils.c 2016-04-10 05:03:24.000000000 +0000 @@ -82,7 +82,7 @@ switch (x.reply.id) { case AMQP_CONNECTION_CLOSE_METHOD: { amqp_connection_close_t *m = (amqp_connection_close_t *) x.reply.decoded; - fprintf(stderr, "%s: server connection error %d, message: %.*s\n", + fprintf(stderr, "%s: server connection error %uh, message: %.*s\n", context, m->reply_code, (int) m->reply_text.len, (char *) m->reply_text.bytes); @@ -90,7 +90,7 @@ } case AMQP_CHANNEL_CLOSE_METHOD: { amqp_channel_close_t *m = (amqp_channel_close_t *) x.reply.decoded; - fprintf(stderr, "%s: server channel error %d, message: %.*s\n", + fprintf(stderr, "%s: server channel error %uh, message: %.*s\n", context, m->reply_code, (int) m->reply_text.len, (char *) m->reply_text.bytes); @@ -163,7 +163,7 @@ int ch = buf[i]; if (numinrow == 16) { - int i; + int j; if (rows_eq(oldchs, chs)) { if (!showed_dots) { @@ -175,8 +175,8 @@ dump_row(count, numinrow, chs); } - for (i=0; i<16; i++) { - oldchs[i] = chs[i]; + for (j=0; j<16; j++) { + oldchs[j] = chs[j]; } numinrow = 0; diff -Nru librabbitmq-0.7.1/.gitignore librabbitmq-0.8.0/.gitignore --- librabbitmq-0.7.1/.gitignore 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/.gitignore 2016-04-10 05:03:24.000000000 +0000 @@ -7,6 +7,7 @@ /aclocal.m4 /autom4te.cache /bin* +/build /compile /config.guess /config.h diff -Nru librabbitmq-0.7.1/.hgignore librabbitmq-0.8.0/.hgignore --- librabbitmq-0.7.1/.hgignore 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/.hgignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -^scratch$ - -^autom4te\.cache$ -^aclocal\.m4$ -^config\.(guess|log|status|sub|h\.in~?)$ -^configure$ -^depcomp$ -^install-sh$ -^ltmain.sh$ -^missing$ - -(^|/)\.libs$ -(^|/)\.deps$ -\.(o|lo|la)$ -^config\.h$ -^stamp-h1$ -^libtool$ - -^librabbitmq/amqp_framing\.[ch]$ - -^(|librabbitmq/|tests/|examples/|tools/|tools/doc/)Makefile(\.in)?$ -^tests/test_tables$ -^tests/test_parse_url$ -^examples/amqp_sendstring$ -^examples/amqp_rpc_sendstring_client$ -^examples/amqp_exchange_declare$ -^examples/amqp_listen$ -^examples/amqp_producer$ -^examples/amqp_consumer$ -^examples/amqp_unbind$ -^examples/amqp_bind$ -^examples/amqp_listenq$ - -^tools/amqp-publish$ -^tools/amqp-get$ -^tools/amqp-consume$ -^tools/amqp-declare-queue$ -^tools/amqp-delete-queue$ -^tools/.*\.[17]$ -^tools/doc/man-date.ent$ diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_api.c librabbitmq-0.8.0/librabbitmq/amqp_api.c --- librabbitmq-0.7.1/librabbitmq/amqp_api.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_api.c 2016-04-10 05:03:24.000000000 +0000 @@ -47,7 +47,6 @@ #include "amqp_private.h" #include "amqp_time.h" -#include #include #include #include @@ -83,7 +82,8 @@ "unexpected protocol state", /* AMQP_STATUS_UNEXPECTED STATE -0x0010 */ "socket is closed", /* AMQP_STATUS_SOCKET_CLOSED -0x0011 */ "socket already open", /* AMQP_STATUS_SOCKET_INUSE -0x0012 */ - "unsupported sasl method requested" /* AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD -0x0013 */ + "unsupported sasl method requested", /* AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD -0x0013 */ + "parameter value is unsupported" /* AMQP_STATUS_UNSUPPORTED -0x0014 */ }; static const char *tcp_error_strings[] = { @@ -170,11 +170,6 @@ const amqp_table_t amqp_empty_table = { 0, NULL }; const amqp_array_t amqp_empty_array = { 0, NULL }; -#define RPC_REPLY(replytype)\ - (state->most_recent_api_result.reply_type == AMQP_RESPONSE_NORMAL\ - ? (replytype *) state->most_recent_api_result.reply.decoded\ - : NULL) - int amqp_basic_publish(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange, @@ -272,7 +267,11 @@ amqp_method_number_t replies[2] = { AMQP_CHANNEL_CLOSE_OK_METHOD, 0}; amqp_channel_close_t req; - req.reply_code = code; + if (code < 0 || code > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + + req.reply_code = (uint16_t)code; req.reply_text.bytes = codestr; req.reply_text.len = sprintf(codestr, "%d", code); req.class_id = 0; @@ -289,7 +288,11 @@ amqp_method_number_t replies[2] = { AMQP_CONNECTION_CLOSE_OK_METHOD, 0}; amqp_channel_close_t req; - req.reply_code = code; + if (code < 0 || code > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + + req.reply_code = (uint16_t)code; req.reply_text.bytes = codestr; req.reply_text.len = sprintf(codestr, "%d", code); req.class_id = 0; diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_connection.c librabbitmq-0.8.0/librabbitmq/amqp_connection.c --- librabbitmq-0.7.1/librabbitmq/amqp_connection.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_connection.c 2016-04-10 05:03:24.000000000 +0000 @@ -45,7 +45,6 @@ #include "amqp_tcp_socket.h" #include "amqp_private.h" #include "amqp_time.h" -#include #include #include #include @@ -60,15 +59,15 @@ #define AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE 131072 #endif - -#define ENFORCE_STATE(statevec, statenum) \ - { \ - amqp_connection_state_t _check_state = (statevec); \ - size_t _wanted_state = (statenum); \ - if (_check_state->state != _wanted_state) \ - amqp_abort("Programming error: invalid AMQP connection state: expected %d, got %d", \ - _wanted_state, \ - _check_state->state); \ +#define ENFORCE_STATE(statevec, statenum) \ + { \ + amqp_connection_state_t _check_state = (statevec); \ + amqp_connection_state_enum _wanted_state = (statenum); \ + if (_check_state->state != _wanted_state) \ + amqp_abort( \ + "Programming error: invalid AMQP connection state: expected %d, " \ + "got %d", \ + _wanted_state, _check_state->state); \ } amqp_connection_state_t amqp_new_connection(void) @@ -405,8 +404,8 @@ } default: - amqp_abort("Internal error: invalid amqp_connection_state_t->state %d", state->state); - return (int)bytes_consumed; + amqp_abort("Internal error: invalid amqp_connection_state_t->state %d", + state->state); } } @@ -498,22 +497,26 @@ break; } - case AMQP_FRAME_HEADER: + case AMQP_FRAME_HEADER: { + amqp_bytes_t properties_encoded; + amqp_e16(out_frame, HEADER_SIZE, frame->payload.properties.class_id); amqp_e16(out_frame, HEADER_SIZE + 2, 0); /* "weight" */ amqp_e64(out_frame, HEADER_SIZE + 4, frame->payload.properties.body_size); - encoded->bytes = amqp_offset(out_frame, HEADER_SIZE + 12); - encoded->len = buffer.len - HEADER_SIZE - 12 - FOOTER_SIZE; + properties_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 12); + properties_encoded.len = buffer.len - HEADER_SIZE - 12 - FOOTER_SIZE; res = amqp_encode_properties(frame->payload.properties.class_id, - frame->payload.properties.decoded, *encoded); + frame->payload.properties.decoded, + properties_encoded); if (res < 0) { return res; } out_frame_len = res + 12; break; + } case AMQP_FRAME_HEARTBEAT: out_frame_len = 0; diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_consumer.c librabbitmq-0.8.0/librabbitmq/amqp_consumer.c --- librabbitmq-0.7.1/librabbitmq/amqp_consumer.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_consumer.c 2016-04-10 05:03:24.000000000 +0000 @@ -39,7 +39,7 @@ amqp_basic_properties_t *clone, amqp_pool_t *pool) { - memset(clone, 0, sizeof(amqp_basic_properties_t)); + memset(clone, 0, sizeof(*clone)); clone->_flags = original->_flags; #define CLONE_BYTES_POOL(original, clone, pool) \ @@ -148,8 +148,8 @@ amqp_basic_deliver_t *delivery_method; amqp_rpc_reply_t ret; - memset(&ret, 0, sizeof(amqp_rpc_reply_t)); - memset(envelope, 0, sizeof(amqp_envelope_t)); + memset(&ret, 0, sizeof(ret)); + memset(envelope, 0, sizeof(*envelope)); res = amqp_simple_wait_frame_noblock(state, &frame, timeout); if (AMQP_STATUS_OK != res) { @@ -211,8 +211,8 @@ char *body_read_ptr; int res; - memset(&ret, 0, sizeof(amqp_rpc_reply_t)); - memset(message, 0, sizeof(amqp_message_t)); + memset(&ret, 0, sizeof(ret)); + memset(message, 0, sizeof(*message)); res = amqp_simple_wait_frame_on_channel(state, channel, &frame); if (AMQP_STATUS_OK != res) { diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_cyassl.c librabbitmq-0.8.0/librabbitmq/amqp_cyassl.c --- librabbitmq-0.7.1/librabbitmq/amqp_cyassl.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_cyassl.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,270 +0,0 @@ -/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */ -/* - * Copyright 2012-2013 Michael Steinert - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "amqp_ssl_socket.h" -#include "amqp_private.h" -#include -#include -#include - -#ifndef AMQP_USE_UNTESTED_SSL_BACKEND -# error This SSL backend is alpha quality and likely contains errors.\ - -DAMQP_USE_UNTESTED_SSL_BACKEND to use this backend -#endif - -struct amqp_ssl_socket_t { - const struct amqp_socket_class_t *klass; - CYASSL_CTX *ctx; - CYASSL *ssl; - int sockfd; - char *buffer; - size_t length; - int last_error; -}; - -static ssize_t -amqp_ssl_socket_send(void *base, - const void *buf, - size_t len, - AMQP_UNUSED int flags) -{ - int status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - - self->last_error = 0; - status = CyaSSL_write(self->ssl, buf, len); - if (status <= 0) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - - return status; -} - -static ssize_t -amqp_ssl_socket_writev(void *base, - const struct iovec *iov, - int iovcnt) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - ssize_t written = -1; - char *bufferp; - size_t bytes; - int i; - self->last_error = 0; - bytes = 0; - for (i = 0; i < iovcnt; ++i) { - bytes += iov[i].iov_len; - } - if (self->length < bytes) { - free(self->buffer); - self->buffer = malloc(bytes); - if (!self->buffer) { - self->length = 0; - self->last_error = AMQP_STATUS_NO_MEMORY; - goto exit; - } - self->length = bytes; - } - bufferp = self->buffer; - for (i = 0; i < iovcnt; ++i) { - memcpy(bufferp, iov[i].iov_base, iov[i].iov_len); - bufferp += iov[i].iov_len; - } - written = amqp_ssl_socket_send(self, self->buffer, bytes, 0); -exit: - return written; -} - -static ssize_t -amqp_ssl_socket_recv(void *base, - void *buf, - size_t len, - AMQP_UNUSED int flags) -{ - int status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - - self->last_error = 0; - status = CyaSSL_read(self->ssl, buf, len); - if (status <= 0) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - - return status; -} - -static int -amqp_ssl_socket_get_sockfd(void *base) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - return self->sockfd; -} - -static int -amqp_ssl_socket_close(void *base) -{ - int status = -1; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - if (self->sockfd >= 0) { - status = amqp_os_socket_close(self->sockfd); - } - if (self) { - CyaSSL_free(self->ssl); - CyaSSL_CTX_free(self->ctx); - free(self->buffer); - free(self); - } - return status; -} - -static int -amqp_ssl_socket_error(void *base) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - return self->last_error; -} - -char * -amqp_ssl_error_string(AMQP_UNUSED int err) -{ - return strdup("A ssl socket error occurred."); -} - -static int -amqp_ssl_socket_open(void *base, const char *host, int port, struct timeval *timeout) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - int status; - self->last_error = 0; - - self->ssl = CyaSSL_new(self->ctx); - if (NULL == self->ssl) { - self->last_error = AMQP_STATUS_SSL_ERROR; - return -1; - } - - self->sockfd = amqp_open_socket_noblock(host, port, timeout); - if (0 > self->sockfd) { - self->last_error = - self->sockfd; - return -1; - } - CyaSSL_set_fd(self->ssl, self->sockfd); - status = CyaSSL_connect(self->ssl); - if (SSL_SUCCESS != status) { - self->last_error = AMQP_STATUS_SSL_ERROR; - return -1; - } - return 0; -} - -static const struct amqp_socket_class_t amqp_ssl_socket_class = { - amqp_ssl_socket_writev, /* writev */ - amqp_ssl_socket_send, /* send */ - amqp_ssl_socket_recv, /* recv */ - amqp_ssl_socket_open, /* open */ - amqp_ssl_socket_close, /* close */ - amqp_ssl_socket_error, /* error */ - amqp_ssl_socket_get_sockfd /* get_sockfd */ -}; - -amqp_socket_t * -amqp_ssl_socket_new(void) -{ - struct amqp_ssl_socket_t *self = calloc(1, sizeof(*self)); - if (!self) { - goto error; - } - CyaSSL_Init(); - self->ctx = CyaSSL_CTX_new(CyaSSLv23_client_method()); - if (!self->ctx) { - goto error; - } - self->klass = &amqp_ssl_socket_class; - return (amqp_socket_t *)self; -error: - amqp_socket_close((amqp_socket_t *)self); - return NULL; -} - -int -amqp_ssl_socket_set_cacert(amqp_socket_t *base, - const char *cacert) -{ - int status; - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - status = CyaSSL_CTX_load_verify_locations(self->ctx, cacert, NULL); - if (SSL_SUCCESS != status) { - return -1; - } - return 0; -} - -int -amqp_ssl_socket_set_key(amqp_socket_t *base, - const char *cert, - const char *key) -{ - int status; - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - status = CyaSSL_CTX_use_PrivateKey_file(self->ctx, key, - SSL_FILETYPE_PEM); - if (SSL_SUCCESS != status) { - return -1; - } - status = CyaSSL_CTX_use_certificate_chain_file(self->ctx, cert); - return 0; -} - -int -amqp_ssl_socket_set_key_buffer(AMQP_UNUSED amqp_socket_t *base, - AMQP_UNUSED const char *cert, - AMQP_UNUSED const void *key, - AMQP_UNUSED size_t n) -{ - amqp_abort("%s is not implemented for CyaSSL", __func__); - return -1; -} - -void -amqp_ssl_socket_set_verify(AMQP_UNUSED amqp_socket_t *base, - AMQP_UNUSED amqp_boolean_t verify) -{ - /* noop for CyaSSL */ -} - -void -amqp_set_initialize_ssl_library(AMQP_UNUSED amqp_boolean_t do_initialize) -{ -} diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_gnutls.c librabbitmq-0.8.0/librabbitmq/amqp_gnutls.c --- librabbitmq-0.7.1/librabbitmq/amqp_gnutls.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_gnutls.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,362 +0,0 @@ -/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */ -/* - * Copyright 2012-2013 Michael Steinert - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "amqp_ssl_socket.h" -#include "amqp_private.h" -#include -#include -#include -#include - -#ifndef AMQP_USE_UNTESTED_SSL_BACKEND -# error This SSL backend is alpha quality and likely contains errors.\ - -DAMQP_USE_UNTESTED_SSL_BACKEND to use this backend -#endif - -struct amqp_ssl_socket_t { - const struct amqp_socket_class_t *klass; - gnutls_session_t session; - gnutls_certificate_credentials_t credentials; - int sockfd; - char *host; - char *buffer; - size_t length; - int last_error; -}; - -static ssize_t -amqp_ssl_socket_send(void *base, - const void *buf, - size_t len, - AMQP_UNUSED int flags) -{ - ssize_t status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - - self->last_error = 0; - status = gnutls_record_send(self->session, buf, len); - if (status < 0) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - return status; -} - -static ssize_t -amqp_ssl_socket_writev(void *base, - const struct iovec *iov, - int iovcnt) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - ssize_t written = -1; - char *bufferp; - size_t bytes; - int i; - self->last_error = 0; - bytes = 0; - for (i = 0; i < iovcnt; ++i) { - bytes += iov[i].iov_len; - } - if (self->length < bytes) { - free(self->buffer); - self->buffer = malloc(bytes); - if (!self->buffer) { - self->length = 0; - self->last_error = AMQP_STATUS_NO_MEMORY; - goto exit; - } - self->length = 0; - } - bufferp = self->buffer; - for (i = 0; i < iovcnt; ++i) { - memcpy(bufferp, iov[i].iov_base, iov[i].iov_len); - bufferp += iov[i].iov_len; - } - written = amqp_ssl_socket_send(self, self->buffer, bytes, 0); -exit: - return written; -} - -static ssize_t -amqp_ssl_socket_recv(void *base, - void *buf, - size_t len, - AMQP_UNUSED int flags) -{ - ssize_t status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - - self->last_error = 0; - status = gnutls_record_recv(self->session, buf, len); - if (status < 0) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - - return status; -} - -static int -amqp_ssl_socket_open(void *base, const char *host, int port, struct timeval *timeout) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - int status; - self->last_error = 0; - - free(self->host); - self->host = strdup(host); - if (NULL == self->host) { - self->last_error = AMQP_STATUS_NO_MEMORY; - return -1; - } - - self->sockfd = amqp_open_socket_noblock(host, port, timeout); - if (0 > self->sockfd) { - self->last_error = -self->sockfd; - return -1; - } - gnutls_transport_set_ptr(self->session, - (gnutls_transport_ptr_t)self->sockfd); - do { - status = gnutls_handshake(self->session); - } while (status < 0 && !gnutls_error_is_fatal(status)); - - if (gnutls_error_is_fatal(status)) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - - return status; -} - -static int -amqp_ssl_socket_close(void *base) -{ - int status = -1; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - if (self->sockfd >= 0) { - status = amqp_os_socket_close(self->sockfd); - } - if (self) { - gnutls_deinit(self->session); - gnutls_certificate_free_credentials(self->credentials); - free(self->host); - free(self->buffer); - free(self); - } - return status; -} - -static int -amqp_ssl_socket_error(void *base) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - return self->last_error; -} - -char * -amqp_ssl_error_string(AMQP_UNUSED int err) -{ - return strdup("A SSL error occurred"); -} - -static int -amqp_ssl_socket_get_sockfd(void *base) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - return self->sockfd; -} - -static int -amqp_ssl_verify(gnutls_session_t session) -{ - int ret; - unsigned int status, size; - const gnutls_datum_t *list; - gnutls_x509_crt_t cert = NULL; - struct amqp_ssl_socket_t *self = gnutls_session_get_ptr(session); - ret = gnutls_certificate_verify_peers2(session, &status); - if (0 > ret) { - goto error; - } - if (status & GNUTLS_CERT_INVALID) { - goto error; - } - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { - goto error; - } - if (status & GNUTLS_CERT_REVOKED) { - goto error; - } - if (status & GNUTLS_CERT_EXPIRED) { - goto error; - } - if (status & GNUTLS_CERT_NOT_ACTIVATED) { - goto error; - } - if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509) { - goto error; - } - if (gnutls_x509_crt_init(&cert) < 0) { - goto error; - } - list = gnutls_certificate_get_peers(session, &size); - if (!list) { - goto error; - } - ret = gnutls_x509_crt_import(cert, &list[0], GNUTLS_X509_FMT_DER); - if (0 > ret) { - goto error; - } - if (!gnutls_x509_crt_check_hostname(cert, self->host)) { - goto error; - } - gnutls_x509_crt_deinit(cert); - return 0; -error: - if (cert) { - gnutls_x509_crt_deinit (cert); - } - return GNUTLS_E_CERTIFICATE_ERROR; -} - -static const struct amqp_socket_class_t amqp_ssl_socket_class = { - amqp_ssl_socket_writev, /* writev */ - amqp_ssl_socket_send, /* send */ - amqp_ssl_socket_recv, /* recv */ - amqp_ssl_socket_open, /* open */ - amqp_ssl_socket_close, /* close */ - amqp_ssl_socket_error, /* error */ - amqp_ssl_socket_get_sockfd /* get_sockfd */ -}; - -amqp_socket_t * -amqp_ssl_socket_new(void) -{ - struct amqp_ssl_socket_t *self = calloc(1, sizeof(*self)); - const char *error; - int status; - if (!self) { - goto error; - } - gnutls_global_init(); - status = gnutls_init(&self->session, GNUTLS_CLIENT); - if (GNUTLS_E_SUCCESS != status) { - goto error; - } - status = gnutls_certificate_allocate_credentials(&self->credentials); - if (GNUTLS_E_SUCCESS != status) { - goto error; - } - gnutls_certificate_set_verify_function(self->credentials, - amqp_ssl_verify); - status = gnutls_credentials_set(self->session, GNUTLS_CRD_CERTIFICATE, - self->credentials); - if (GNUTLS_E_SUCCESS != status) { - goto error; - } - gnutls_session_set_ptr(self->session, self); - status = gnutls_priority_set_direct(self->session, "NORMAL", &error); - if (GNUTLS_E_SUCCESS != status) { - goto error; - } - self->klass = &amqp_ssl_socket_class; - return (amqp_socket_t *)self; -error: - amqp_socket_close((amqp_socket_t *)self); - return NULL; -} - -int -amqp_ssl_socket_set_cacert(amqp_socket_t *base, - const char *cacert) -{ - int status; - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - status = gnutls_certificate_set_x509_trust_file(self->credentials, - cacert, - GNUTLS_X509_FMT_PEM); - if (0 > status) { - return -1; - } - return 0; -} - -int -amqp_ssl_socket_set_key(amqp_socket_t *base, - const char *cert, - const char *key) -{ - int status; - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - status = gnutls_certificate_set_x509_key_file(self->credentials, - cert, - key, - GNUTLS_X509_FMT_PEM); - if (0 > status) { - return -1; - } - return 0; -} - -int -amqp_ssl_socket_set_key_buffer(AMQP_UNUSED amqp_socket_t *base, - AMQP_UNUSED const char *cert, - AMQP_UNUSED const void *key, - AMQP_UNUSED size_t n) -{ - amqp_abort("%s is not implemented for GnuTLS", __func__); - return -1; -} - -void -amqp_ssl_socket_set_verify(amqp_socket_t *base, - amqp_boolean_t verify) -{ - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - if (verify) { - gnutls_certificate_set_verify_function(self->credentials, - amqp_ssl_verify); - } else { - gnutls_certificate_set_verify_function(self->credentials, - NULL); - } -} - -void -amqp_set_initialize_ssl_library(AMQP_UNUSED amqp_boolean_t do_initialize) -{ -} diff -Nru librabbitmq-0.7.1/librabbitmq/amqp.h librabbitmq-0.8.0/librabbitmq/amqp.h --- librabbitmq-0.7.1/librabbitmq/amqp.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp.h 2016-04-10 05:03:24.000000000 +0000 @@ -223,8 +223,8 @@ */ #define AMQP_VERSION_MAJOR 0 -#define AMQP_VERSION_MINOR 7 -#define AMQP_VERSION_PATCH 1 +#define AMQP_VERSION_MINOR 8 +#define AMQP_VERSION_PATCH 0 #define AMQP_VERSION_IS_RELEASE 1 @@ -726,7 +726,9 @@ AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD = -0x0013, /**< Broker does not support the requested SASL mechanism */ - _AMQP_STATUS_NEXT_VALUE = -0x0014, /**< Internal value */ + AMQP_STATUS_UNSUPPORTED = -0x0014, /**< Parameter is unsupported + in this version */ + _AMQP_STATUS_NEXT_VALUE = -0x0015, /**< Internal value */ AMQP_STATUS_TCP_ERROR = -0x0100, /**< A generic TCP error occurred */ @@ -1873,10 +1875,10 @@ * \param [in] routing_key the routing key to use when publishing the message * \param [in] mandatory indicate to the broker that the message MUST be routed * to a queue. If the broker cannot do this it should respond with - * a basic.reject method. + * a basic.return method. * \param [in] immediate indicate to the broker that the message MUST be delivered * to a consumer immediately. If the broker cannot do this it should - * response with a basic.reject method. + * response with a basic.return method. * \param [in] properties the properties associated with the message * \param [in] body the message body * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. Note @@ -2304,6 +2306,10 @@ * amqp://guest:guest\@localhost:5672// * amqp://guest:guest\@localhost/myvhost * + * Any missing parts of the URL will be set to the defaults specified in + * amqp_default_connection_info. For amqps: URLs the default port will be set + * to 5671 instead of 5672 for non-SSL URLs. + * * \note This function modifies url parameter. * * \param [in] url URI to parse, note that this parameter is modified by the diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_hostcheck.c librabbitmq-0.8.0/librabbitmq/amqp_hostcheck.c --- librabbitmq-0.7.1/librabbitmq/amqp_hostcheck.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_hostcheck.c 2016-04-10 05:03:24.000000000 +0000 @@ -23,7 +23,7 @@ * copyright holder. */ -#include "amqp_private.h" +#include "amqp_hostcheck.h" #include @@ -145,15 +145,15 @@ * http://tools.ietf.org/html/rfc6125#section-6.4.3 */ -static int -amqp_hostmatch(const char *hostname, const char *pattern) -{ +static amqp_hostcheck_result amqp_hostmatch(const char *hostname, + const char *pattern) { const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; int wildcard_enabled; size_t prefixlen, suffixlen; pattern_wildcard = strchr(pattern, '*'); if (pattern_wildcard == NULL) { - return amqp_raw_equal(pattern, hostname) ? 1 : 0; + return amqp_raw_equal(pattern, hostname) ? AMQP_HCR_MATCH + : AMQP_HCR_NO_MATCH; } /* We require at least 2 dots in pattern to avoid too wide wildcard match. */ wildcard_enabled = 1; @@ -165,37 +165,37 @@ wildcard_enabled = 0; } if (!wildcard_enabled) { - return amqp_raw_equal(pattern, hostname) ? 1 : 0; + return amqp_raw_equal(pattern, hostname) ? AMQP_HCR_MATCH + : AMQP_HCR_NO_MATCH; } hostname_label_end = strchr(hostname, '.'); if (hostname_label_end == NULL || !amqp_raw_equal(pattern_label_end, hostname_label_end)) { - return 0; + return AMQP_HCR_NO_MATCH; } /* The wildcard must match at least one character, so the left-most * label of the hostname is at least as large as the left-most label * of the pattern. */ if (hostname_label_end - hostname < pattern_label_end - pattern) { - return 0; + return AMQP_HCR_NO_MATCH; } prefixlen = pattern_wildcard - pattern; suffixlen = pattern_label_end - (pattern_wildcard + 1); return amqp_raw_nequal(pattern, hostname, prefixlen) && amqp_raw_nequal(pattern_wildcard + 1, hostname_label_end - suffixlen, - suffixlen) ? 1 : 0; + suffixlen) ? AMQP_HCR_MATCH : AMQP_HCR_NO_MATCH; } -int -amqp_hostcheck(const char *match_pattern, const char *hostname) -{ +amqp_hostcheck_result amqp_hostcheck(const char *match_pattern, + const char *hostname) { /* sanity check */ if (!match_pattern || !*match_pattern || !hostname || !*hostname) { - return 0; + return AMQP_HCR_NO_MATCH; } /* trivial case */ if (amqp_raw_equal(hostname, match_pattern)) { - return 1; + return AMQP_HCR_MATCH; } return amqp_hostmatch(hostname, match_pattern); } diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_hostcheck.h librabbitmq-0.8.0/librabbitmq/amqp_hostcheck.h --- librabbitmq-0.7.1/librabbitmq/amqp_hostcheck.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_hostcheck.h 2016-04-10 05:03:24.000000000 +0000 @@ -26,11 +26,24 @@ * copyright holder. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +typedef enum { + AMQP_HCR_NO_MATCH = 0, + AMQP_HCR_MATCH = 1 +} amqp_hostcheck_result; -int -amqp_hostcheck(const char *match_pattern, const char *hostname); +/** + * Determine whether hostname matches match_pattern. + * + * match_pattern may include wildcards. + * + * Match is performed based on the rules set forth in RFC6125 section 6.4.3. + * http://tools.ietf.org/html/rfc6125#section-6.4.3 + * + * \param match_pattern RFC6125 compliant pattern + * \param hostname to match against + * \returns AMQP_HCR_MATCH if its a match, AMQP_HCR_NO_MATCH otherwise. + */ +amqp_hostcheck_result amqp_hostcheck(const char *match_pattern, + const char *hostname); #endif diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_mem.c librabbitmq-0.8.0/librabbitmq/amqp_mem.c --- librabbitmq-0.7.1/librabbitmq/amqp_mem.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_mem.c 2016-04-10 05:03:24.000000000 +0000 @@ -136,6 +136,7 @@ return NULL; } if (!record_pool_block(&pool->large_blocks, result)) { + free(result); return NULL; } return result; diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_openssl.c librabbitmq-0.8.0/librabbitmq/amqp_openssl.c --- librabbitmq-0.7.1/librabbitmq/amqp_openssl.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_openssl.c 2016-04-10 05:03:24.000000000 +0000 @@ -29,14 +29,15 @@ #include "config.h" #endif +#include "amqp_openssl_hostname_validation.h" #include "amqp_ssl_socket.h" #include "amqp_socket.h" -#include "amqp_hostcheck.h" #include "amqp_private.h" #include "amqp_time.h" #include "threads.h" #include +#include #include #include #include @@ -70,24 +71,31 @@ SSL_CTX *ctx; int sockfd; SSL *ssl; - amqp_boolean_t verify; + amqp_boolean_t verify_peer; + amqp_boolean_t verify_hostname; int internal_error; }; static ssize_t amqp_ssl_socket_send(void *base, const void *buf, size_t len, AMQP_UNUSED int flags) { struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - ssize_t res; + int res; if (-1 == self->sockfd) { return AMQP_STATUS_SOCKET_CLOSED; } + /* SSL_write takes an int for length of buffer, protect against len being + * larger than larger than what SSL_write can take */ + if (len > INT_MAX) { + return AMQP_STATUS_INVALID_PARAMETER; + } + ERR_clear_error(); self->internal_error = 0; /* This will only return on error, or once the whole buffer has been * written to the SSL stream. See SSL_MODE_ENABLE_PARTIAL_WRITE */ - res = SSL_write(self->ssl, buf, len); + res = SSL_write(self->ssl, buf, (int)len); if (0 >= res) { self->internal_error = SSL_get_error(self->ssl, res); /* TODO: Close connection if it isn't already? */ @@ -110,7 +118,7 @@ self->internal_error = 0; } - return res; + return (ssize_t)res; } static ssize_t @@ -120,14 +128,21 @@ AMQP_UNUSED int flags) { struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - ssize_t received; + int received; if (-1 == self->sockfd) { return AMQP_STATUS_SOCKET_CLOSED; } + + /* SSL_read takes an int for length of buffer, protect against len being + * larger than larger than what SSL_read can take */ + if (len > INT_MAX) { + return AMQP_STATUS_INVALID_PARAMETER; + } + ERR_clear_error(); self->internal_error = 0; - received = SSL_read(self->ssl, buf, len); + received = SSL_read(self->ssl, buf, (int)len); if (0 >= received) { self->internal_error = SSL_get_error(self->ssl, received); switch (self->internal_error) { @@ -146,111 +161,7 @@ } } - return received; -} - -static int match(ASN1_STRING *entry_string, const char *string) -{ - unsigned char *utf8_value = NULL, *cp, ch; - int utf8_length, status = 1; - utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_string); - if (0 > utf8_length) { - goto error; - } - while (utf8_length > 0 && utf8_value[utf8_length - 1] == 0) { - --utf8_length; - } - if (utf8_length >= 256) { - goto error; - } - if ((size_t)utf8_length != strlen((char *)utf8_value)) { - goto error; - } - for (cp = utf8_value; (ch = *cp) != '\0'; ++cp) { - if (isascii(ch) && !isprint(ch)) { - goto error; - } - } - if (!amqp_hostcheck((char *)utf8_value, string)) { - goto error; - } -exit: - OPENSSL_free(utf8_value); - return status; -error: - status = 0; - goto exit; -} - -/* Does this hostname match an entry in the subjectAltName extension? - * returns: 0 if no, 1 if yes, -1 if no subjectAltName entries were found. - */ -static int hostname_matches_subject_alt_name(const char *hostname, X509 *cert) -{ - int found_any_entries = 0; - int found_match; - GENERAL_NAME *namePart = NULL; - STACK_OF(GENERAL_NAME) *san = - (STACK_OF(GENERAL_NAME)*) X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); - - while (sk_GENERAL_NAME_num(san) > 0) - { - namePart = sk_GENERAL_NAME_pop(san); - - if (namePart->type == GEN_DNS) { - found_any_entries = 1; - found_match = match(namePart->d.uniformResourceIdentifier, hostname); - if (found_match) - return 1; - } - } - - return (found_any_entries ? 0 : -1); -} - -static int hostname_matches_subject_common_name(const char *hostname, X509 *cert) -{ - X509_NAME *name; - X509_NAME_ENTRY *name_entry; - int position; - ASN1_STRING *entry_string; - - name = X509_get_subject_name(cert); - position = -1; - for (;;) { - position = X509_NAME_get_index_by_NID(name, NID_commonName, position); - if (position == -1) - break; - name_entry = X509_NAME_get_entry(name, position); - entry_string = X509_NAME_ENTRY_get_data(name_entry); - if (match(entry_string, hostname)) - return 1; - } - return 0; -} - -static int -amqp_ssl_socket_verify_hostname(void *base, const char *host) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - int status = 0; - X509 *cert; - int res; - cert = SSL_get_peer_certificate(self->ssl); - if (!cert) { - goto error; - } - res = hostname_matches_subject_alt_name(host, cert); - if (res != 1) { - res = hostname_matches_subject_common_name(host, cert); - if (!res) - goto error; - } -exit: - return status; -error: - status = -1; - goto exit; + return (ssize_t)received; } static int @@ -260,6 +171,7 @@ long result; int status; amqp_time_t deadline; + X509 *cert; if (-1 != self->sockfd) { return AMQP_STATUS_SOCKET_INUSE; } @@ -312,27 +224,45 @@ goto error_out2; } - result = SSL_get_verify_result(self->ssl); - if (X509_V_OK != result) { - self->internal_error = result; - status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; - goto error_out3; - } - if (self->verify) { - int verify_status = amqp_ssl_socket_verify_hostname(self, host); - if (verify_status) { + cert = SSL_get_peer_certificate(self->ssl); + + if (self->verify_peer) { + if (!cert) { + self->internal_error = 0; + status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; + goto error_out3; + } + + result = SSL_get_verify_result(self->ssl); + if (X509_V_OK != result) { + self->internal_error = result; + status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; + goto error_out4; + } + } + if (self->verify_hostname) { + if (!cert) { self->internal_error = 0; status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED; goto error_out3; } + + if (AMQP_HVR_MATCH_FOUND != amqp_ssl_validate_hostname(host, cert)) { + self->internal_error = 0; + status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED; + goto error_out4; + } } + X509_free(cert); self->internal_error = 0; status = AMQP_STATUS_OK; exit: return status; +error_out4: + X509_free(cert); error_out3: SSL_shutdown(self->ssl); error_out2: @@ -345,34 +275,19 @@ } static int -amqp_ssl_socket_close(void *base) +amqp_ssl_socket_close(void *base, amqp_socket_close_enum force) { - int res; struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; if (-1 == self->sockfd) { return AMQP_STATUS_SOCKET_CLOSED; } -start_shutdown: - res = SSL_shutdown(self->ssl); - if (0 == res) { - goto start_shutdown; - } else if (-1 == res) { - self->internal_error = SSL_get_error(self->ssl, res); - switch (self->internal_error) { - case SSL_ERROR_WANT_READ: - res = amqp_poll(self->sockfd, AMQP_SF_POLLIN, amqp_time_infinite()); - break; - case SSL_ERROR_WANT_WRITE: - res = amqp_poll(self->sockfd, AMQP_SF_POLLOUT, amqp_time_infinite()); - break; - } - if (AMQP_STATUS_OK == res) { - goto start_shutdown; - } - /* Swallow errors in poll, just consider the connection dead */ + if (AMQP_SC_NONE == force) { + /* don't try too hard to shutdown the connection */ + SSL_shutdown(self->ssl); } + SSL_free(self->ssl); self->ssl = NULL; @@ -397,7 +312,7 @@ struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; if (self) { - amqp_ssl_socket_close(self); + amqp_ssl_socket_close(self, AMQP_SC_NONE); SSL_CTX_free(self->ctx); free(self); @@ -425,7 +340,8 @@ self->sockfd = -1; self->klass = &amqp_ssl_socket_class; - self->verify = 1; + self->verify_peer = 1; + self->verify_hostname = 1; status = initialize_openssl(); if (status) { @@ -436,6 +352,8 @@ if (!self->ctx) { goto error; } + /* Disable SSLv2 and SSLv3 */ + SSL_CTX_set_options(self->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); amqp_set_socket(state, (amqp_socket_t *)self); @@ -492,7 +410,6 @@ AMQP_UNUSED void *user_data) { amqp_abort("rabbitmq-c does not support password protected keys"); - return 0; } int @@ -508,12 +425,15 @@ if (base->klass != &amqp_ssl_socket_class) { amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); } + if (n > INT_MAX) { + return AMQP_STATUS_INVALID_PARAMETER; + } self = (struct amqp_ssl_socket_t *)base; status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); if (1 != status) { return AMQP_STATUS_SSL_ERROR; } - buf = BIO_new_mem_buf((void *)key, n); + buf = BIO_new_mem_buf((void *)key, (int)n); if (!buf) { goto error; } @@ -555,12 +475,88 @@ amqp_ssl_socket_set_verify(amqp_socket_t *base, amqp_boolean_t verify) { + amqp_ssl_socket_set_verify_peer(base, verify); + amqp_ssl_socket_set_verify_hostname(base, verify); +} + +void amqp_ssl_socket_set_verify_peer(amqp_socket_t *base, + amqp_boolean_t verify) { + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + self->verify_peer = verify; +} + +void amqp_ssl_socket_set_verify_hostname(amqp_socket_t *base, + amqp_boolean_t verify) { + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + self->verify_hostname = verify; +} + +int amqp_ssl_socket_set_ssl_versions(amqp_socket_t *base, + amqp_tls_version_t min, + amqp_tls_version_t max) { struct amqp_ssl_socket_t *self; if (base->klass != &amqp_ssl_socket_class) { amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); } self = (struct amqp_ssl_socket_t *)base; - self->verify = verify; + + { + long clear_options; + long set_options = 0; +#if defined(SSL_OP_NO_TLSv1_2) + amqp_tls_version_t max_supported = AMQP_TLSv1_2; + clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2; +#elif defined(SSL_OP_NO_TLSv1_1) + amqp_tls_version_t max_supported = AMQP_TLSv1_1; + clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1; +#elif defined(SSL_OP_NO_TLSv1) + amqp_tls_version_t max_supported = AMQP_TLSv1; + clear_options = SSL_OP_NO_TLSv1; +#else +# error "Need a version of OpenSSL that can support TLSv1 or greater." +#endif + + if (AMQP_TLSvLATEST == max) { + max = max_supported; + } + if (AMQP_TLSvLATEST == min) { + min = max_supported; + } + + if (min > max) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + if (max > max_supported || min > max_supported) { + return AMQP_STATUS_UNSUPPORTED; + } + + if (min > AMQP_TLSv1) { + set_options |= SSL_OP_NO_TLSv1; + } +#ifdef SSL_OP_NO_TLSv1_1 + if (min > AMQP_TLSv1_1 || max < AMQP_TLSv1_1) { + set_options |= SSL_OP_NO_TLSv1_1; + } +#endif +#ifdef SSL_OP_NO_TLSv1_2 + if (max < AMQP_TLSv1_2) { + set_options |= SSL_OP_NO_TLSv1_2; + } +#endif + SSL_CTX_clear_options(self->ctx, clear_options); + SSL_CTX_set_options(self->ctx, set_options); + } + + return AMQP_STATUS_OK; } void diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_openssl_hostname_validation.c librabbitmq-0.8.0/librabbitmq/amqp_openssl_hostname_validation.c --- librabbitmq-0.7.1/librabbitmq/amqp_openssl_hostname_validation.c 1970-01-01 00:00:00.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_openssl_hostname_validation.c 2016-04-10 05:03:24.000000000 +0000 @@ -0,0 +1,167 @@ +/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */ +/* + * Copyright (C) 2012, iSEC Partners. + * Copyright (C) 2015 Alan Antonuk. + * + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + + +/* Originally from: + * https://github.com/iSECPartners/ssl-conservatory + * https://wiki.openssl.org/index.php/Hostname_validation + */ + +#include +#include + +#include "amqp_openssl_hostname_validation.h" +#include "amqp_hostcheck.h" + +#define HOSTNAME_MAX_SIZE 255 + +/** +* Tries to find a match for hostname in the certificate's Common Name field. +* +* Returns AMQP_HVR_MATCH_FOUND if a match was found. +* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. +* Returns AMQP_HVR_MALFORMED_CERTIFICATE if the Common Name had a NUL character embedded in it. +* Returns AMQP_HVR_ERROR if the Common Name could not be extracted. +*/ +static amqp_hostname_validation_result amqp_matches_common_name( + const char *hostname, const X509 *server_cert) { + int common_name_loc = -1; + X509_NAME_ENTRY *common_name_entry = NULL; + ASN1_STRING *common_name_asn1 = NULL; + char *common_name_str = NULL; + + // Find the position of the CN field in the Subject field of the certificate + common_name_loc = X509_NAME_get_index_by_NID( + X509_get_subject_name((X509 *)server_cert), NID_commonName, -1); + if (common_name_loc < 0) { + return AMQP_HVR_ERROR; + } + + // Extract the CN field + common_name_entry = X509_NAME_get_entry( + X509_get_subject_name((X509 *)server_cert), common_name_loc); + if (common_name_entry == NULL) { + return AMQP_HVR_ERROR; + } + + // Convert the CN field to a C string + common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); + if (common_name_asn1 == NULL) { + return AMQP_HVR_ERROR; + } + common_name_str = (char *)ASN1_STRING_data(common_name_asn1); + + // Make sure there isn't an embedded NUL character in the CN + if ((size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) { + return AMQP_HVR_MALFORMED_CERTIFICATE; + } + + // Compare expected hostname with the CN + if (amqp_hostcheck(common_name_str, hostname) == AMQP_HCR_MATCH) { + return AMQP_HVR_MATCH_FOUND; + } else { + return AMQP_HVR_MATCH_NOT_FOUND; + } +} + +/** +* Tries to find a match for hostname in the certificate's Subject Alternative +* Name extension. +* +* Returns AMQP_HVR_MATCH_FOUND if a match was found. +* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. +* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL +* character embedded in it. +* Returns AMQP_HVR_NO_SAN_PRESENT if the SAN extension was not present in the +* certificate. +*/ +static amqp_hostname_validation_result amqp_matches_subject_alternative_name( + const char *hostname, const X509 *server_cert) { + amqp_hostname_validation_result result = AMQP_HVR_MATCH_NOT_FOUND; + int i; + int san_names_nb = -1; + STACK_OF(GENERAL_NAME) *san_names = NULL; + + // Try to extract the names within the SAN extension from the certificate + san_names = + X509_get_ext_d2i((X509 *)server_cert, NID_subject_alt_name, NULL, NULL); + if (san_names == NULL) { + return AMQP_HVR_NO_SAN_PRESENT; + } + san_names_nb = sk_GENERAL_NAME_num(san_names); + + // Check each name within the extension + for (i = 0; i < san_names_nb; i++) { + const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i); + + if (current_name->type == GEN_DNS) { + // Current name is a DNS name, let's check it + char *dns_name = (char *)ASN1_STRING_data(current_name->d.dNSName); + + // Make sure there isn't an embedded NUL character in the DNS name + if ((size_t)ASN1_STRING_length(current_name->d.dNSName) != + strlen(dns_name)) { + result = AMQP_HVR_MALFORMED_CERTIFICATE; + break; + } else { // Compare expected hostname with the DNS name + if (amqp_hostcheck(dns_name, hostname) == AMQP_HCR_MATCH) { + result = AMQP_HVR_MATCH_FOUND; + break; + } + } + } + } + sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free); + + return result; +} + +/** +* Validates the server's identity by looking for the expected hostname in the +* server's certificate. As described in RFC 6125, it first tries to find a match +* in the Subject Alternative Name extension. If the extension is not present in +* the certificate, it checks the Common Name instead. +* +* Returns AMQP_HVR_MATCH_FOUND if a match was found. +* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. +* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL +* character embedded in it. +* Returns AMQP_HVR_ERROR if there was an error. +*/ +amqp_hostname_validation_result amqp_ssl_validate_hostname( + const char *hostname, const X509 *server_cert) { + amqp_hostname_validation_result result; + + if ((hostname == NULL) || (server_cert == NULL)) return AMQP_HVR_ERROR; + + // First try the Subject Alternative Names extension + result = amqp_matches_subject_alternative_name(hostname, server_cert); + if (result == AMQP_HVR_NO_SAN_PRESENT) { + // Extension was not found: try the Common Name + result = amqp_matches_common_name(hostname, server_cert); + } + + return result; +} diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_openssl_hostname_validation.h librabbitmq-0.8.0/librabbitmq/amqp_openssl_hostname_validation.h --- librabbitmq-0.7.1/librabbitmq/amqp_openssl_hostname_validation.h 1970-01-01 00:00:00.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_openssl_hostname_validation.h 2016-04-10 05:03:24.000000000 +0000 @@ -0,0 +1,59 @@ +/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */ +#ifndef librabbitmq_amqp_openssl_hostname_validation_h +#define librabbitmq_amqp_openssl_hostname_validation_h + +/* + * Copyright (C) 2012, iSEC Partners. + * Copyright (C) 2015 Alan Antonuk. + * + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + +/* Originally from: + * https://github.com/iSECPartners/ssl-conservatory + * https://wiki.openssl.org/index.php/Hostname_validation + */ + +#include + +typedef enum { + AMQP_HVR_MATCH_FOUND, + AMQP_HVR_MATCH_NOT_FOUND, + AMQP_HVR_NO_SAN_PRESENT, + AMQP_HVR_MALFORMED_CERTIFICATE, + AMQP_HVR_ERROR +} amqp_hostname_validation_result; + +/** +* Validates the server's identity by looking for the expected hostname in the +* server's certificate. As described in RFC 6125, it first tries to find a match +* in the Subject Alternative Name extension. If the extension is not present in +* the certificate, it checks the Common Name instead. +* +* Returns AMQP_HVR_MATCH_FOUND if a match was found. +* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. +* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL +* character embedded in it. +* Returns AMQP_HVR_ERROR if there was an error. +*/ +amqp_hostname_validation_result amqp_ssl_validate_hostname( + const char *hostname, const X509 *server_cert); + +#endif diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_polarssl.c librabbitmq-0.8.0/librabbitmq/amqp_polarssl.c --- librabbitmq-0.7.1/librabbitmq/amqp_polarssl.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_polarssl.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,362 +0,0 @@ -/* vim:set ft=c ts=2 sw=2 sts=2 et cindent: */ -/* - * Copyright 2012-2013 Michael Steinert - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "amqp_ssl_socket.h" -#include "amqp_private.h" -#include -#include -#include -#include -#include -#include -#include - -#ifndef AMQP_USE_UNTESTED_SSL_BACKEND -# error This SSL backend is alpha quality and likely contains errors.\ - -DAMQP_USE_UNTESTED_SSL_BACKEND to use this backend -#endif - -struct amqp_ssl_socket_t { - const struct amqp_socket_class_t *klass; - int sockfd; - entropy_context *entropy; - ctr_drbg_context *ctr_drbg; - x509_cert *cacert; - rsa_context *key; - x509_cert *cert; - ssl_context *ssl; - ssl_session *session; - char *buffer; - size_t length; - int last_error; -}; - -static ssize_t -amqp_ssl_socket_send(void *base, - const void *buf, - size_t len, - AMQP_UNUSED int flags) -{ - ssize_t status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - - self->last_error = 0; - status = ssl_write(self->ssl, buf, len); - if (status < 0) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - - return status; -} - -static ssize_t -amqp_ssl_socket_writev(void *base, - const struct iovec *iov, - int iovcnt) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - ssize_t written = -1; - char *bufferp; - size_t bytes; - int i; - self->last_error = 0; - bytes = 0; - for (i = 0; i < iovcnt; ++i) { - bytes += iov[i].iov_len; - } - if (self->length < bytes) { - free(self->buffer); - self->buffer = malloc(bytes); - if (!self->buffer) { - self->length = 0; - self->last_error = AMQP_STATUS_NO_MEMORY; - goto exit; - } - self->length = bytes; - } - bufferp = self->buffer; - for (i = 0; i < iovcnt; ++i) { - memcpy(bufferp, iov[i].iov_base, iov[i].iov_len); - bufferp += iov[i].iov_len; - } - written = amqp_ssl_socket_send(self, (const unsigned char *)self->buffer, - bytes, 0); -exit: - return written; -} - -static ssize_t -amqp_ssl_socket_recv(void *base, - void *buf, - size_t len, - AMQP_UNUSED int flags) -{ - ssize_t status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - - self->last_error = 0; - status = ssl_read(self->ssl, buf, len); - if (status < 0) { - self->last_error = AMQP_STATUS_SSL_ERROR; - } - - return status; -} - -static int -amqp_ssl_socket_open(void *base, const char *host, int port, struct timeval *timeout) -{ - int status; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - self->last_error = 0; - - if (timeout && (timeout->tv_sec != 0 || timeout->tv_usec != 0)) { - /* We don't support PolarSSL for now because it uses its own connect() wrapper - * It is not too hard to implement net_connect() with noblock support, - * but then we will have to maintain that piece of code and keep it synced with main PolarSSL code base - */ - return AMQP_STATUS_INVALID_PARAMETER; - } - - status = net_connect(&self->sockfd, host, port); - if (status) { - /* This isn't quite right. We should probably translate between - * POLARSSL_ERR_* to our internal error codes - */ - self->last_error = AMQP_STATUS_SSL_ERROR; - return -1; - } - if (self->cacert) { - ssl_set_ca_chain(self->ssl, self->cacert, NULL, host); - } - ssl_set_bio(self->ssl, net_recv, &self->sockfd, - net_send, &self->sockfd); - if (self->key && self->cert) { - ssl_set_own_cert(self->ssl, self->cert, self->key); - } - while (0 != (status = ssl_handshake(self->ssl))) { - switch (status) { - case POLARSSL_ERR_NET_WANT_READ: - case POLARSSL_ERR_NET_WANT_WRITE: - continue; - default: - self->last_error = AMQP_STATUS_SSL_ERROR; - break; - } - } - return status; -} - -static int -amqp_ssl_socket_close(void *base) -{ - int status = -1; - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - if (self) { - free(self->entropy); - free(self->ctr_drbg); - x509_free(self->cacert); - free(self->cacert); - rsa_free(self->key); - free(self->key); - x509_free(self->cert); - free(self->cert); - ssl_free(self->ssl); - free(self->ssl); - free(self->session); - free(self->buffer); - if (self->sockfd >= 0) { - net_close(self->sockfd); - status = 0; - } - free(self); - } - return status; -} - -static int -amqp_ssl_socket_error(AMQP_UNUSED void *user_data) -{ - return AMQP_STATUS_SSL_ERROR; -} - -char * -amqp_ssl_error_string(AMQP_UNUSED int err) -{ - return strdup("A SSL socket error occurred"); -} - -static int -amqp_ssl_socket_get_sockfd(void *base) -{ - struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; - return self->sockfd; -} - -static const struct amqp_socket_class_t amqp_ssl_socket_class = { - amqp_ssl_socket_writev, /* writev */ - amqp_ssl_socket_send, /* send */ - amqp_ssl_socket_recv, /* recv */ - amqp_ssl_socket_open, /* open */ - amqp_ssl_socket_close, /* close */ - amqp_ssl_socket_error, /* error */ - amqp_ssl_socket_get_sockfd /* get_sockfd */ -}; - -amqp_socket_t * -amqp_ssl_socket_new(void) -{ - struct amqp_ssl_socket_t *self = calloc(1, sizeof(*self)); - int status; - if (!self) { - goto error; - } - self->entropy = calloc(1, sizeof(*self->entropy)); - if (!self->entropy) { - goto error; - } - self->sockfd = -1; - entropy_init(self->entropy); - self->ctr_drbg = calloc(1, sizeof(*self->ctr_drbg)); - if (!self->ctr_drbg) { - goto error; - } - status = ctr_drbg_init(self->ctr_drbg, entropy_func, self->entropy, - NULL, 0); - if (status) { - goto error; - } - self->ssl = calloc(1, sizeof(*self->ssl)); - if (!self->ssl) { - goto error; - } - status = ssl_init(self->ssl); - if (status) { - goto error; - } - ssl_set_endpoint(self->ssl, SSL_IS_CLIENT); - ssl_set_rng(self->ssl, ctr_drbg_random, self->ctr_drbg); - ssl_set_ciphersuites(self->ssl, ssl_default_ciphersuites); - ssl_set_authmode(self->ssl, SSL_VERIFY_REQUIRED); - self->session = calloc(1, sizeof(*self->session)); - if (!self->session) { - goto error; - } -#if POLARSSL_VERSION_NUMBER >= 0x01020000 - ssl_set_session(self->ssl, self->session); -#else - ssl_set_session(self->ssl, 0, 0, self->session); -#endif - - self->klass = &amqp_ssl_socket_class; - return (amqp_socket_t *)self; -error: - amqp_socket_close((amqp_socket_t *)self); - return NULL; -} - -int -amqp_ssl_socket_set_cacert(amqp_socket_t *base, - const char *cacert) -{ - int status; - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - self->cacert = calloc(1, sizeof(*self->cacert)); - if (!self->cacert) { - return -1; - } - status = x509parse_crtfile(self->cacert, cacert); - if (status) { - return -1; - } - return 0; -} - -int -amqp_ssl_socket_set_key(amqp_socket_t *base, - const char *cert, - const char *key) -{ - int status; - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - self->key = calloc(1, sizeof(*self->key)); - if (!self->key) { - return -1; - } - status = x509parse_keyfile(self->key, key, NULL); - if (status) { - return -1; - } - self->cert = calloc(1, sizeof(*self->cert)); - if (!self->cert) { - return -1; - } - status = x509parse_crtfile(self->cert, cert); - if (status) { - return -1; - } - return 0; -} - -int -amqp_ssl_socket_set_key_buffer(AMQP_UNUSED amqp_socket_t *base, - AMQP_UNUSED const char *cert, - AMQP_UNUSED const void *key, - AMQP_UNUSED size_t n) -{ - amqp_abort("%s is not implemented for PolarSSL", __func__); - return -1; -} - -void -amqp_ssl_socket_set_verify(amqp_socket_t *base, - amqp_boolean_t verify) -{ - struct amqp_ssl_socket_t *self; - if (base->klass != &amqp_ssl_socket_class) { - amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); - } - self = (struct amqp_ssl_socket_t *)base; - if (verify) { - ssl_set_authmode(self->ssl, SSL_VERIFY_REQUIRED); - } else { - ssl_set_authmode(self->ssl, SSL_VERIFY_NONE); - } -} - -void -amqp_set_initialize_ssl_library(AMQP_UNUSED amqp_boolean_t do_initialize) -{ -} diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_private.h librabbitmq-0.8.0/librabbitmq/amqp_private.h --- librabbitmq-0.7.1/librabbitmq/amqp_private.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_private.h 2016-04-10 05:03:24.000000000 +0000 @@ -64,7 +64,7 @@ #endif /* GCC attributes */ -#if __GNUC__ > 2 | (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) #define AMQP_NORETURN \ __attribute__ ((__noreturn__)) #define AMQP_UNUSED \ @@ -369,6 +369,13 @@ int amqp_bytes_equal(amqp_bytes_t r, amqp_bytes_t l); +static inline amqp_rpc_reply_t amqp_rpc_reply_error(amqp_status_enum status) { + amqp_rpc_reply_t reply; + reply.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + reply.library_error = status; + return reply; +} + int amqp_send_frame_inner(amqp_connection_state_t state, const amqp_frame_t *frame, int flags); #endif diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_socket.c librabbitmq-0.8.0/librabbitmq/amqp_socket.c --- librabbitmq-0.7.1/librabbitmq/amqp_socket.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_socket.c 2016-04-10 05:03:24.000000000 +0000 @@ -86,7 +86,7 @@ amqp_os_socket_init(void) { #ifdef _WIN32 - static called_wsastartup = 0; + static int called_wsastartup = 0; if (!called_wsastartup) { WSADATA data; int res = WSAStartup(0x0202, &data); @@ -153,7 +153,7 @@ { #ifdef _WIN32 - int nonblock = !block; + u_long nonblock = !block; if (NO_ERROR != ioctlsocket(sock, FIONBIO, &nonblock)) { return AMQP_STATUS_SOCKET_ERROR; } else { @@ -234,11 +234,11 @@ } int -amqp_socket_close(amqp_socket_t *self) +amqp_socket_close(amqp_socket_t *self, amqp_socket_close_enum force) { assert(self); assert(self->klass->close); - return self->klass->close(self); + return self->klass->close(self, force); } void @@ -303,27 +303,40 @@ return AMQP_STATUS_OK; #elif defined(HAVE_SELECT) fd_set fds; + fd_set exceptfds; + fd_set *exceptfdsp; int res; struct timeval tv; struct timeval *tvp; - assert(event == AMQP_SF_POLLIN || event == AMQP_SF_POLLOUT); + assert((0 != (event & AMQP_SF_POLLIN)) || (0 != (event & AMQP_SF_POLLOUT))); +#ifndef _WIN32 + /* On Win32 connect() failure is indicated through the exceptfds, it does not + * make any sense to allow POLLERR on any other platform or condition */ + assert(0 == (event & AMQP_SF_POLLERR)); +#endif start_select: FD_ZERO(&fds); FD_SET(fd, &fds); + if (event & AMQP_SF_POLLERR) { + FD_ZERO(&exceptfds); + FD_SET(fd, &exceptfds); + exceptfdsp = &exceptfds; + } else { + exceptfdsp = NULL; + } + res = amqp_time_tv_until(deadline, &tv, &tvp); if (res != AMQP_STATUS_OK) { return res; } - switch (event) { - case AMQP_SF_POLLIN: - res = select(fd + 1, &fds, NULL, NULL, tvp); - break; - case AMQP_SF_POLLOUT: - res = select(fd + 1, NULL, &fds, NULL, tvp); + if (event & AMQP_SF_POLLIN) { + res = select(fd + 1, &fds, NULL, exceptfdsp, tvp); + } else if (event & AMQP_SF_POLLOUT) { + res = select(fd + 1, NULL, &fds, exceptfdsp, tvp); } if (0 < res) { @@ -338,7 +351,6 @@ return AMQP_STATUS_SOCKET_ERROR; } } - return AMQP_STATUS_OK; #else # error "poll() or select() is needed to compile rabbitmq-c" #endif @@ -417,7 +429,7 @@ struct addrinfo *addr; char portnumber_string[33]; int sockfd = -1; - int last_error = AMQP_STATUS_OK; + int last_error; int one = 1; /* for setsockopt */ int res; @@ -481,10 +493,12 @@ #ifdef _WIN32 if (WSAEWOULDBLOCK == amqp_os_socket_error()) { + int event = AMQP_SF_POLLOUT | AMQP_SF_POLLERR; #else if (EINPROGRESS == amqp_os_socket_error()) { + int event = AMQP_SF_POLLOUT; #endif - last_error = amqp_poll(sockfd, AMQP_SF_POLLOUT, deadline); + last_error = amqp_poll(sockfd, event, deadline); if (AMQP_STATUS_OK == last_error) { int result; socklen_t result_len = sizeof(result); @@ -549,12 +563,10 @@ switch (method) { case AMQP_SASL_METHOD_PLAIN: - res.bytes = "PLAIN"; - res.len = 5; + res = amqp_cstring_bytes("PLAIN"); break; case AMQP_SASL_METHOD_EXTERNAL: - res.bytes = "EXTERNAL"; - res.len = 8; + res = amqp_cstring_bytes("EXTERNAL"); break; default: @@ -792,9 +804,7 @@ return res; } - while (1) { - int res; - + for (;;) { while (amqp_data_in_buffer(state)) { res = consume_one_frame(state, decoded_frame); @@ -837,7 +847,7 @@ if (AMQP_STATUS_TIMEOUT == res) { if (amqp_time_equal(deadline, state->next_recv_heartbeat)) { - amqp_socket_close(state->socket); + amqp_socket_close(state->socket, AMQP_SC_FORCE); return AMQP_STATUS_HEARTBEAT_TIMEOUT; } else if (amqp_time_equal(deadline, timeout_deadline)) { return AMQP_STATUS_TIMEOUT; @@ -938,7 +948,7 @@ } } - while (1) { + for (;;) { res = wait_frame_inner(state, decoded_frame, NULL); if (AMQP_STATUS_OK != res) { @@ -1226,11 +1236,32 @@ { int res; amqp_method_t method; - int server_frame_max; + + uint16_t client_channel_max; + uint32_t client_frame_max; + uint16_t client_heartbeat; + uint16_t server_channel_max; + uint32_t server_frame_max; uint16_t server_heartbeat; + amqp_rpc_reply_t result; + if (channel_max < 0 || channel_max > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + client_channel_max = (uint16_t)channel_max; + + if (frame_max < 0) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + client_frame_max = (uint32_t)frame_max; + + if (heartbeat < 0 || heartbeat > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + client_heartbeat = (uint16_t)heartbeat; + res = amqp_send_header(state); if (AMQP_STATUS_OK != res) { goto error_res; @@ -1238,7 +1269,7 @@ res = amqp_simple_wait_method(state, 0, AMQP_CONNECTION_START_METHOD, &method); - if (res < 0) { + if (res != AMQP_STATUS_OK) { goto error_res; } @@ -1355,30 +1386,31 @@ } if (server_channel_max != 0 && - (server_channel_max < channel_max || channel_max == 0)) { - channel_max = server_channel_max; - } else if (server_channel_max == 0 && channel_max == 0) { - channel_max = UINT16_MAX; + (server_channel_max < client_channel_max || client_channel_max == 0)) { + client_channel_max = server_channel_max; + } else if (server_channel_max == 0 && client_channel_max == 0) { + client_channel_max = UINT16_MAX; } - if (server_frame_max != 0 && server_frame_max < frame_max) { - frame_max = server_frame_max; + if (server_frame_max != 0 && server_frame_max < client_frame_max) { + client_frame_max = server_frame_max; } - if (server_heartbeat != 0 && server_heartbeat < heartbeat) { - heartbeat = server_heartbeat; + if (server_heartbeat != 0 && server_heartbeat < client_heartbeat) { + client_heartbeat = server_heartbeat; } - res = amqp_tune_connection(state, channel_max, frame_max, heartbeat); + res = amqp_tune_connection(state, client_channel_max, client_frame_max, + client_heartbeat); if (res < 0) { goto error_res; } { amqp_connection_tune_ok_t s; - s.frame_max = frame_max; - s.channel_max = channel_max; - s.heartbeat = heartbeat; + s.frame_max = client_frame_max; + s.channel_max = client_channel_max; + s.heartbeat = client_heartbeat; res = amqp_send_method(state, 0, AMQP_CONNECTION_TUNE_OK_METHOD, &s); if (res < 0) { @@ -1399,7 +1431,7 @@ result = amqp_simple_rpc(state, 0, AMQP_CONNECTION_OPEN_METHOD, - (amqp_method_number_t *) &replies, + replies, &s); if (result.reply_type != AMQP_RESPONSE_NORMAL) { goto out; diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_socket.h librabbitmq-0.8.0/librabbitmq/amqp_socket.h --- librabbitmq-0.7.1/librabbitmq/amqp_socket.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_socket.h 2016-04-10 05:03:24.000000000 +0000 @@ -41,9 +41,15 @@ AMQP_SF_NONE = 0, AMQP_SF_MORE = 1, AMQP_SF_POLLIN = 2, - AMQP_SF_POLLOUT = 4 + AMQP_SF_POLLOUT = 4, + AMQP_SF_POLLERR = 8 } amqp_socket_flag_enum; +typedef enum { + AMQP_SC_NONE = 0, + AMQP_SC_FORCE = 1 +} amqp_socket_close_enum; + int amqp_os_socket_error(void); @@ -54,7 +60,7 @@ typedef ssize_t (*amqp_socket_send_fn)(void *, const void *, size_t, int); typedef ssize_t (*amqp_socket_recv_fn)(void *, void *, size_t, int); typedef int (*amqp_socket_open_fn)(void *, const char *, int, struct timeval *); -typedef int (*amqp_socket_close_fn)(void *); +typedef int (*amqp_socket_close_fn)(void *, amqp_socket_close_enum); typedef int (*amqp_socket_get_sockfd_fn)(void *); typedef void (*amqp_socket_delete_fn)(void *); @@ -131,11 +137,13 @@ * longer be referenced. * * \param [in,out] self A socket object. + * \param [in] force, if set, just close the socket, don't attempt a TLS + * shutdown. * * \return Zero upon success, non-zero otherwise. */ int -amqp_socket_close(amqp_socket_t *self); +amqp_socket_close(amqp_socket_t *self, amqp_socket_close_enum force); /** * Destroy a socket object diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_ssl_socket.h librabbitmq-0.8.0/librabbitmq/amqp_ssl_socket.h --- librabbitmq-0.7.1/librabbitmq/amqp_ssl_socket.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_ssl_socket.h 2016-04-10 05:03:24.000000000 +0000 @@ -119,6 +119,9 @@ /** * Enable or disable peer verification. * + * \deprecated use \amqp_ssl_socket_set_verify_peer and + * \amqp_ssl_socket_set_verify_hostname instead. + * * If peer verification is enabled then the common name in the server * certificate must match the server name. Peer verification is enabled by * default. @@ -128,11 +131,72 @@ * * \since v0.4.0 */ +AMQP_DEPRECATED( + AMQP_PUBLIC_FUNCTION + void + AMQP_CALL + amqp_ssl_socket_set_verify(amqp_socket_t *self, amqp_boolean_t verify) +); + +/** + * Enable or disable peer verification. + * + * Peer verification validates the certificate chain that is sent by the broker. + * Hostname validation is controlled by \amqp_ssl_socket_set_verify_peer. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] verify enable or disable peer validation + * + * \since v0.8.0 + */ AMQP_PUBLIC_FUNCTION void AMQP_CALL -amqp_ssl_socket_set_verify(amqp_socket_t *self, - amqp_boolean_t verify); +amqp_ssl_socket_set_verify_peer(amqp_socket_t *self, amqp_boolean_t verify); + +/** + * Enable or disable hostname verification. + * + * Hostname verification checks the broker cert for a CN or SAN that matches the + * hostname that amqp_socket_open() is presented. Peer verification is + * controlled by \amqp_ssl_socket_set_verify_peer + * + * \since v0.8.0 + */ +AMQP_PUBLIC_FUNCTION +void +AMQP_CALL +amqp_ssl_socket_set_verify_hostname(amqp_socket_t *self, amqp_boolean_t verify); + +typedef enum { + AMQP_TLSv1 = 1, + AMQP_TLSv1_1 = 2, + AMQP_TLSv1_2 = 3, + AMQP_TLSvLATEST = 0xFFFF +} amqp_tls_version_t; + +/** + * Set min and max TLS versions. + * + * Set the oldest and newest acceptable TLS versions that are acceptable when + * connecting to the broker. Set min == max to restrict to just that + * version. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] min the minimum acceptable TLS version + * \param [in] max the maxmium acceptable TLS version + * \returns AMQP_STATUS_OK on success, AMQP_STATUS_UNSUPPORTED if OpenSSL does + * not support the requested TLS version, AMQP_STATUS_INVALID_PARAMETER if an + * invalid combination of parameters is passed. + * + * \since v0.8.0 + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL +amqp_ssl_socket_set_ssl_versions(amqp_socket_t *self, + amqp_tls_version_t min, + amqp_tls_version_t max); /** * Sets whether rabbitmq-c initializes the underlying SSL library. diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_table.c librabbitmq-0.8.0/librabbitmq/amqp_table.c --- librabbitmq-0.7.1/librabbitmq/amqp_table.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_table.c 2016-04-10 05:03:24.000000000 +0000 @@ -106,14 +106,18 @@ output->num_entries = num_entries; output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_field_value_t)); - res = AMQP_STATUS_NO_MEMORY; /* NULL is legitimate if we requested a zero-length block. */ - if (output->entries == NULL && num_entries > 0) { + if (output->entries == NULL) { + if (num_entries == 0) { + res = AMQP_STATUS_OK; + } else { + res = AMQP_STATUS_NO_MEMORY; + } goto out; } memcpy(output->entries, entries, num_entries * sizeof(amqp_field_value_t)); - res = 0; + res = AMQP_STATUS_OK; out: free(entries); @@ -178,9 +182,13 @@ output->num_entries = num_entries; output->entries = amqp_pool_alloc(pool, num_entries * sizeof(amqp_table_entry_t)); - res = AMQP_STATUS_NO_MEMORY; /* NULL is legitimate if we requested a zero-length block. */ - if (output->entries == NULL && num_entries > 0) { + if (output->entries == NULL) { + if (num_entries == 0) { + res = AMQP_STATUS_OK; + } else { + res = AMQP_STATUS_NO_MEMORY; + } goto out; } diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_tcp_socket.c librabbitmq-0.8.0/librabbitmq/amqp_tcp_socket.c --- librabbitmq-0.7.1/librabbitmq/amqp_tcp_socket.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_tcp_socket.c 2016-04-10 05:03:24.000000000 +0000 @@ -69,7 +69,9 @@ if (flags & AMQP_SF_MORE) { flagz |= MSG_MORE; } -#elif defined(TCP_NOPUSH) + /* Cygwin defines TCP_NOPUSH, but trying to use it will return not + * implemented. Disable it here. */ +#elif defined(TCP_NOPUSH) && !defined(__CYGWIN__) if (flags & AMQP_SF_MORE && !(self->state & AMQP_SF_MORE)) { int one = 1; res = setsockopt(self->sockfd, IPPROTO_TCP, TCP_NOPUSH, &one, sizeof(one)); @@ -180,7 +182,7 @@ } static int -amqp_tcp_socket_close(void *base) +amqp_tcp_socket_close(void *base, AMQP_UNUSED amqp_socket_close_enum force) { struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; if (-1 == self->sockfd) { @@ -208,7 +210,7 @@ struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; if (self) { - amqp_tcp_socket_close(self); + amqp_tcp_socket_close(self, AMQP_SC_NONE); free(self); } } diff -Nru librabbitmq-0.7.1/librabbitmq/amqp_url.c librabbitmq-0.8.0/librabbitmq/amqp_url.c --- librabbitmq-0.7.1/librabbitmq/amqp_url.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/amqp_url.c 2016-04-10 05:03:24.000000000 +0000 @@ -43,6 +43,7 @@ #endif #include "amqp_private.h" +#include #include #include #include @@ -92,14 +93,14 @@ int chars; int res = sscanf(from, "%2x%n", &val, &chars); - if (res == EOF || res < 1 || chars != 2) + if (res == EOF || res < 1 || chars != 2 || val > CHAR_MAX) /* Return a surprising delimiter to force an error. */ { return '%'; } - *to++ = val; + *to++ = (char)val; from += 2; break; } @@ -120,6 +121,8 @@ char *host; char *port = NULL; + amqp_default_connection_info(parsed); + /* check the prefix */ if (!strncmp(url, "amqp://", 7)) { /* do nothing */ diff -Nru librabbitmq-0.7.1/librabbitmq/CMakeLists.txt librabbitmq-0.8.0/librabbitmq/CMakeLists.txt --- librabbitmq-0.7.1/librabbitmq/CMakeLists.txt 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/CMakeLists.txt 2016-04-10 05:03:24.000000000 +0000 @@ -80,38 +80,19 @@ add_definitions(-DWITH_SSL=1) set(AMQP_SSL_SOCKET_H_PATH amqp_ssl_socket.h) - if (SSL_ENGINE STREQUAL "OpenSSL") - set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH} - amqp_openssl.c - amqp_hostcheck.c - amqp_hostcheck.h - ) - include_directories(${OPENSSL_INCLUDE_DIR}) - set(AMQP_SSL_LIBS ${OPENSSL_LIBRARIES}) - if (APPLE) - # Apple has deprecated OpenSSL in 10.7+. This disables that warning. - set_source_files_properties(${AMQP_SSL_SRCS} - PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations) - endif() - - elseif (SSL_ENGINE STREQUAL "cyaSSL") - set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH} amqp_cyassl.c) - include_directories(${CYASSL_INCLUDE_DIR}) - set(AMQP_SSL_LIBS ${CYASSL_LIBRARIES}) - - elseif (SSL_ENGINE STREQUAL "GnuTLS") - set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH} amqp_gnutls.c) - include_directories(${GNUTLS_INCLUDE_DIR}) - add_definitions(${GNUTLS_DEFINITIONS}) - set(AMQP_SSL_LIBS ${GNUTLS_LIBRARIES}) - - elseif (SSL_ENGINE STREQUAL "PolarSSL") - set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH} amqp_polarssl.c) - include_directories(${POLARSSL_INCLUDE_DIR}) - set(AMQP_SSL_LIBS ${POLARSSL_LIBRARIES}) - - else() - message(FATAL_ERROR "Unknown SSL_ENGINE ${SSL_ENGINE}") + set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH} + amqp_openssl.c + amqp_openssl_hostname_validation.c + amqp_openssl_hostname_validation.h + amqp_hostcheck.c + amqp_hostcheck.h + ) + include_directories(${OPENSSL_INCLUDE_DIR}) + set(AMQP_SSL_LIBS ${OPENSSL_LIBRARIES}) + if (APPLE) + # Apple has deprecated OpenSSL in 10.7+. This disables that warning. + set_source_files_properties(${AMQP_SSL_SRCS} + PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations) endif() if (ENABLE_THREAD_SAFETY) @@ -136,8 +117,6 @@ add_definitions(-DAMQP_BUILD) -include(InstallMacros) - set(RMQ_LIBRARIES ${AMQP_SSL_LIBS} ${SOCKET_LIBRARIES} ${LIBRT} ${CMAKE_THREAD_LIBS_INIT}) if (BUILD_SHARED_LIBS) @@ -156,7 +135,6 @@ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) - install_pdb(rabbitmq) set(RMQ_LIBRARY_TARGET rabbitmq) endif (BUILD_SHARED_LIBS) @@ -168,7 +146,12 @@ set_target_properties(rabbitmq-static PROPERTIES COMPILE_DEFINITIONS AMQP_STATIC) if (WIN32) - set_target_properties(rabbitmq-static PROPERTIES VERSION ${RMQ_VERSION} OUTPUT_NAME librabbitmq.${RMQ_SOVERSION}) + set_target_properties(rabbitmq-static PROPERTIES + # Embed debugging info in the library itself instead of generating + # a .pdb file. + COMPILE_OPTIONS "/Z7" + VERSION ${RMQ_VERSION} + OUTPUT_NAME librabbitmq.${RMQ_SOVERSION}) else (WIN32) set_target_properties(rabbitmq-static PROPERTIES VERSION ${RMQ_VERSION} SOVERSION ${RMQ_SOVERSION} OUTPUT_NAME rabbitmq) endif (WIN32) @@ -176,7 +159,6 @@ install(TARGETS rabbitmq-static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) - install_pdb(rabbitmq-static) if (NOT DEFINED RMQ_LIBRARY_TARGET) set(RMQ_LIBRARY_TARGET rabbitmq-static) diff -Nru librabbitmq-0.7.1/librabbitmq/descrip.mms librabbitmq-0.8.0/librabbitmq/descrip.mms --- librabbitmq-0.7.1/librabbitmq/descrip.mms 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/descrip.mms 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -OBJS = AMQP_FRAMING.OBJ, AMQP_API.OBJ, AMQP_CONNECTION.OBJ, AMQP_MEM.OBJ, AMQP_SOCKET.OBJ, AMQP_TABLE.OBJ, AMQP_URL.OBJ, AMQP_TCP_SOCKET.OBJ, AMQP_TIMER.OBJ - -REAL_TARGETS = RABBITMQ.OLB - -.INCLUDE [-.vms]INCLUDE.MMS - -CFLAGS = $(OPTFLAGS)/DEFINE=($(DEFS))/INCLUDE=($(INC),"./","../vms","./unix")/WARN=(DIS=PTRMISMATCH1) -LDFLAGS = /TRACE - -RABBITMQ.OLB : $(OBJS) - IF F$SEARCH("$(MMS$TARGET)") .EQS. "" THEN LIBRARY/CREATE $(MMS$TARGET) - LIBRARY/REPLACE $(MMS$TARGET) $(MMS$SOURCE_LIST) - -SOCKET.OBJ : [.UNIX]SOCKET.C -SOCKET.MMSD : [.UNIX]SOCKET.C diff -Nru librabbitmq-0.7.1/librabbitmq/win32/threads.c librabbitmq-0.8.0/librabbitmq/win32/threads.c --- librabbitmq-0.7.1/librabbitmq/win32/threads.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/librabbitmq/win32/threads.c 2016-04-10 05:03:24.000000000 +0000 @@ -23,6 +23,8 @@ #include "threads.h" +#include + DWORD pthread_self(void) { diff -Nru librabbitmq-0.7.1/m4/polarssl.m4 librabbitmq-0.8.0/m4/polarssl.m4 --- librabbitmq-0.7.1/m4/polarssl.m4 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/m4/polarssl.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -# polarssl.m4 - Check for PolarSSL -# -# Copyright 2012 Michael Steinert -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -# THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#serial 1 - -# _AX_LIB_POLARSSL -# ---------------- -# Check for the PolarSSL library and header file. If found the cache variable -# ax_cv_have_polarssl will be set to yes. -AC_DEFUN([_AX_LIB_POLARSSL], -[dnl -ax_cv_have_polarssl=no -_ax_polarssl_h=no -_ax_polarssl_lib=no -AC_ARG_VAR([POLARSSL_CFLAGS], - [C compiler flags for PolarSSL, overriding defaults]) -AC_ARG_VAR([POLARSSL_LIBS], [linker flags for PolarSSL, overriding defaults]) -AC_CHECK_HEADERS([polarssl/ssl.h], - [_ax_polarssl_h=yes],, - [$POLARSSL_CFLAGS]) -AS_IF([test "x$POLARSSL_LIBS" = "x"], - [AC_CHECK_LIB([polarssl], [entropy_init], - [POLARSSL_LIBS=-lpolarssl - _ax_polarssl_lib=yes])], - [_ax_polarssl_cflags=$CFLAGS - CFLAGS="$POLARSSL_CFLAGS $CFLAGS" - _ax_polarssl_ldflags=$LDFLAGS - LDFLAGS="$POLARSSL_LIBS $LDFLAGS" - AC_MSG_CHECKING([for libpolarssl]) - AC_TRY_LINK([#include ], - [entropy_init(NULL)], - [AC_MSG_RESULT([$POLARSSL_LIBS]) - _ax_polarssl_lib=yes], - [AC_MSG_RESULT([no])]) - CFLAGS=$_ax_polarssl_cflags - LDFLAGS=$_ax_polarssl_ldflags]) -AS_IF([test "x$_ax_polarssl_h" = "xyes" && \ - test "x$_ax_polarssl_lib" = "xyes"], - [ax_cv_have_polarssl=yes]) -])dnl - -# AX_LIB_POLARSSL([ACTION-IF-TRUE], [ACTION-IF-FALSE]) -# ------------------------------------------------ -# Check if PolarSSL is installed. If found the variable ax_have_polarssl will -# be set to yes. -# ACTION-IF-TRUE: commands to execute if PolarSSL is installed -# ACTION-IF-FALSE: commands to execute if PoloarSSL is not installed -AC_DEFUN([AX_LIB_POLARSSL], -[dnl -AC_CACHE_VAL([ax_cv_have_polarssl], [_AX_LIB_POLARSSL]) -ax_have_polarssl=$ax_cv_have_polarssl -AS_IF([test "x$ax_have_polarssl" = "xyes"], - [AC_DEFINE([HAVE_POLARSSL], [1], [Define to 1 if PolarSSL is available.]) - $1], [$2]) -])dnl diff -Nru librabbitmq-0.7.1/Makefile.am librabbitmq-0.8.0/Makefile.am --- librabbitmq-0.7.1/Makefile.am 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/Makefile.am 2016-04-10 05:03:24.000000000 +0000 @@ -40,29 +40,18 @@ librabbitmq/amqp_time.h \ librabbitmq/amqp_url.c - -if SSL_CYASSL -librabbitmq_librabbitmq_la_SOURCES += librabbitmq/amqp_cyassl.c -endif - -if SSL_GNUTLS -librabbitmq_librabbitmq_la_SOURCES += librabbitmq/amqp_gnutls.c -endif - if SSL_OPENSSL librabbitmq_librabbitmq_la_SOURCES += \ librabbitmq/amqp_hostcheck.c \ librabbitmq/amqp_hostcheck.h \ - librabbitmq/amqp_openssl.c + librabbitmq/amqp_openssl.c \ + librabbitmq/amqp_openssl_hostname_validation.c \ + librabbitmq/amqp_openssl_hostname_validation.h if OS_APPLE librabbitmq_librabbitmq_la_CFLAGS += -Wno-deprecated-declarations endif endif -if SSL_POLARSSL -librabbitmq_librabbitmq_la_SOURCES += librabbitmq/amqp_polarssl.c -endif - if OS_UNIX librabbitmq_librabbitmq_la_SOURCES += librabbitmq/unix/threads.h librabbitmq_librabbitmq_la_CFLAGS += -I$(top_srcdir)/librabbitmq/unix diff -Nru librabbitmq-0.7.1/README.md librabbitmq-0.8.0/README.md --- librabbitmq-0.7.1/README.md 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/README.md 2016-04-10 05:03:24.000000000 +0000 @@ -22,9 +22,9 @@ ## Documentation -API documentation for v0.5.0+ can viewed from: +API documentation for v0.8.0+ can viewed from: - + ## Getting started diff -Nru librabbitmq-0.7.1/README.vms librabbitmq-0.8.0/README.vms --- librabbitmq-0.7.1/README.vms 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/README.vms 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -# rabbitmq-c on OpenVMS - -This rabbitmq-c has been tested and appears to work on OpenVMS v8.3 on the -Alpha platform, with HP TCP/IP services v5.5 -running. There is no reason to believe it won't work on OpenVMS v8.3 on -IA-64 (Itanium, a.k.a., Integrety) with an equivalent version of TCP/IP. -Or an older version of either of these pieces of software. - -NOTE: the maintainers of rabbitmq-c do not have access to an OpenVMS box to -regularly build and test rabbitmq-c, so this code may not build out of the box -and if it does it may not work correctly. However, the build system should -serve as a good starting point for getting something that does work. - -# Pre-reqs for building: -- HP C compiler - -# Instructions for building -1. Extract this package somewhere where you have space. -2. Run mms or mmk to run the build -3. The result of the build are a library and header files: - [.librabbitmq]rabbitmq.OLB for the library - [.librabbitmq]amqp.h and [.librabbitmq]amqp_framing.h for the header files. -To build against the library put these in a place where your compiler/linker can find them - -# Other notes about the build: -- The library is built using IEEE float with denormals enabled. This can be - adjusted by editing the OPTFLAGS line in [.vms]include.mms - - NOTE: the library takes no special care to translate vax-floats into IEEE-floats - so if you plan on compiling the library with vax-floats enabled you'll need - to make some changes - -- The library is built using /NAMES=(UPPER,TRUNC). Adjust OPTFLAGS line in [.vms]include.mms - as necessary to get the desired naming scheme. - -- The library is built using /POINTER=SHORT. Adjust OPTFLAGS line in [.vms]include.mms as - necessary to get the desired pointer size diff -Nru librabbitmq-0.7.1/README-win32.md librabbitmq-0.8.0/README-win32.md --- librabbitmq-0.7.1/README-win32.md 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/README-win32.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -# Using rabbitmq-c on Windows - -================== -# This document is out of date - -To build rabbitmq-c on Win32 look at the "Building and Installing with CMake" section of README.md -================== - -There are three approaches to building rabbitmq-c under Windows: - -- THE PREFERRED METHOD: - Build using CMake, which will cover building with MSVC or MinGW - See the README file for details on how to build with cmake. - -- Build using the MinGW/MSYS (MinGW/MSYS is a port of the GNU - toolchain and utilities to Windows, including the gcc compiler). - The results of building in this way are native Windows DLLs and - EXEs, and can be used without having MinGW installed. The drawback - to this approach is that you cannot safely call the resulting - librabbitmq DLL from code compiled with Microsoft's C compiler. The - advantage is that the whole of rabbitmq-c can be built under - Windows, including the tools. - -- Build using Microsoft's C compiler. You will still need to install - MinGW/MSYS in order to run the rabbitmq-c build scripts, but - Microsoft's compiler is used to compile the code. The resulting - librabbitmq DLL can be used from code compiled with Microsoft's C - compiler (i.e. code developed in Visual Studio). The downside to - this approach is that the rabbitmq-c tools cannot be built, due to - dependencies on other libraries. - - -## Common steps - -With either of the approaches, the initial steps are the same: You -should download and install MinGW/MSYS and Python. - -Installing installing the relevant parts of MinGW/MSYS can be fairly -time consuming - there are dozens of files to be downloaded and -unpacked. To make it easier, we provide a bash script that automates -this process, in `rabbitmq-c/etc/install-mingw.sh`. You can run this -script under cygwin or Linux (obviously if you use Linux you'll need -to transfer the resulting files over to the Windows machine). - -Note that some MinGW packages are .tar.lzma files, so it requires a -system with the xz compression utility and a tar that supports the -J -option. Recent cygwin and Linux distros should be fine here. - -Run the install-mingw.sh script specifying the destination directory, -e.g. - - $ etc/install-mingw.sh mingw - -This will download all the required MinGW/MSYS packages, and unpack -them into the `mingw` directory. - -The other prerequisite for the rabbitmq-c build is Python. The -Windows installer from python.org for the latest 2.x version of Python -will do fine. - -You will also need to copy the source code for rabbitmq-c and -rabbitmq-codegen somewhere under your `mingw` directory. - -Then to start the MSYS bash shell, open a `cmd` window, and ensure -that both the MinGW bin directory and the python install directory are -in the path, e.g. - - C:\>set PATH=%PATH%;C:\mingw\bin;C:\Python27 - -Then start bash, and run the following mount command (substituting the -Windows path of your MinGW install if it isn't `C:\mingw`): - - C:\>bash - bash-3.1$ mount 'C:\mingw' /mingw - -Finally, go to wherever you copied the rabbitmq-c source. - - bash-3.1$ cd /rabbitmq-c - - -## Building rabbitmq-c with Microsoft's C compiler - -The Microsoft C/C++ compiler is part of MS Visual Studio, including -the gratis Visual Studio Express. Visual Studio 2005 and higher are -known to work. - -Start by following the steps in the previous section. The GNU build -tools have limited support for Microsoft toolchain, but the -install-mingw.sh script will install versions of the packages that are -known to be suitable. In particular, only libtool version 2.2.7a is -known to work; later versions have been reported to introduce -problems. - -Once you are at the bash prompt, build rabbitmq-c by running the -script in `rabbitmq-c/etc/build-ms.sh`: - - bash-3.1$ etc/build-ms.sh - -You should end up with a directory `build` containing the librabbitmq -DLL, the corresponding .lib file, and header files. These are -sufficient to create applications using librabbitmq within Visual -Studio. - -build-ms.sh produces 32-bit binaries by default. If you have an -appropriate version of Visual Studio (e.g. VS2010), you can build -64-bit binaries with: - - bash-3.1$ etc/build-ms.sh --enable-64-bit - - -## Building rabbitmq-c with gcc - -There is no script to build rabbitmq-c with gcc, but it is as -documented in the README file: - - bash-3.1$ autoreconf -i && ./configure && make - -You can run the resulting tool EXEs without needing the rest of MinGW. To do -this, copy the following files into a single directory: - -- rabbitmq-c/tools/.libs/*.exe - -- rabbitmq-c/librabbitmq/.libs/librabbitmq-0.dll - -- /bin/libpopt-0.dll - -- /bin/libiconv-2.dll - -- /bin/libintl-8.dll - - diff -Nru librabbitmq-0.7.1/tests/test_parse_url.c librabbitmq-0.8.0/tests/test_parse_url.c --- librabbitmq-0.7.1/tests/test_parse_url.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/tests/test_parse_url.c 2016-04-10 05:03:24.000000000 +0000 @@ -78,7 +78,6 @@ struct amqp_connection_info ci; int res; - amqp_default_connection_info(&ci); res = amqp_parse_url(s, &ci); if (res) { fprintf(stderr, diff -Nru librabbitmq-0.7.1/tests/test_tables.c librabbitmq-0.8.0/tests/test_tables.c --- librabbitmq-0.7.1/tests/test_tables.c 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/tests/test_tables.c 2016-04-10 05:03:24.000000000 +0000 @@ -119,7 +119,7 @@ break; case AMQP_FIELD_KIND_DECIMAL: - fprintf(out, " %d:::%u\n", v.value.decimal.decimals, + fprintf(out, " %u:::%u\n", v.value.decimal.decimals, v.value.decimal.value); break; @@ -314,7 +314,7 @@ entries[5].key = amqp_cstring_bytes("byte"); entries[5].value.kind = AMQP_FIELD_KIND_I8; - entries[5].value.value.i8 = (int8_t)255; + entries[5].value.value.i8 = (int8_t)-1; entries[6].key = amqp_cstring_bytes("long"); entries[6].value.kind = AMQP_FIELD_KIND_I64; @@ -465,6 +465,9 @@ } expected_path = malloc(strlen(srcdir) + strlen(expected_file_name) + 2); + if (!expected_path) { + die("out of memory"); + } sprintf(expected_path, "%s/%s", srcdir, expected_file_name); expected = fopen(expected_path, "r"); if (!expected) { diff -Nru librabbitmq-0.7.1/travis.sh librabbitmq-0.8.0/travis.sh --- librabbitmq-0.7.1/travis.sh 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/travis.sh 2016-04-10 05:03:24.000000000 +0000 @@ -7,9 +7,8 @@ } build_cmake() { - CFLAGS="-fsanitize=undefined" mkdir $PWD/_build && cd $PWD/_build - cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/../_install + cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/../_install -DCMAKE_C_FLAGS="-Werror" cmake --build . --target install ctest -V . } @@ -17,7 +16,7 @@ build_asan() { mkdir $PWD/_build && cd $PWD/_build cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ - -DCMAKE_C_FLAGS="-fsanitize=address,undefined -O1" + -DCMAKE_C_FLAGS="-Werror -fsanitize=address,undefined -O1" cmake --build . --target install ctest -V . } @@ -25,17 +24,33 @@ build_tsan() { mkdir $PWD/_build && cd $PWD/_build cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ - -DCMAKE_C_FLAGS="-fsanitize=thread,undefined -O1" + -DCMAKE_C_FLAGS="-Werror -fsanitize=thread,undefined -O1" cmake --build . --target install ctest -V . } +build_scan-build() { + mkdir $PWD/_build && cd $PWD/_build + scan-build-3.7 cmake .. -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ + -DCMAKE_C_FLAGS="-Werror" + scan-build-3.7 make install +} + if [ "$#" -ne 1 ]; then - echo "Usage: $0 {autotools|cmake|asan|tsan}" + echo "Usage: $0 {autotools|cmake|asan|tsan|scan-build}" exit 1 fi set -e # exit on error. set -x # echo commands. +case $TRAVIS_OS_NAME in +osx) + # This prints out a long list of updated packages, which isn't useful. + brew update > /dev/null + brew install popt + ;; +esac + eval "build_$1" diff -Nru librabbitmq-0.7.1/.travis.yml librabbitmq-0.8.0/.travis.yml --- librabbitmq-0.7.1/.travis.yml 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/.travis.yml 2016-04-10 05:03:24.000000000 +0000 @@ -14,6 +14,8 @@ matrix: include: + # Note that the first compiler in the matrix must be gcc, so that the + # coverity_scan branch hack below works correctly. - compiler: gcc os: linux env: CONFIG=autotools @@ -30,23 +32,42 @@ os: linux env: CONFIG=tsan - compiler: clang + os: linux + env: CONFIG=scan-build + - compiler: clang os: osx env: CONFIG=cmake -# Run the Build script +before_install: + # ugly hack; if running a coverity scan abort all except the 1st build + # see note re gcc compiler above needing to be 1st + # also note that branch_pattern & the TRAVIS_BRANCH check must match + # unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the + # build process + - if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi + script: - - ./travis.sh $CONFIG + # Don't bother building if this is being done in the coverity_scan branch. + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./travis.sh $CONFIG ; fi addons: apt: + # List of whitelisted in travis packages for ubuntu-precise can be found here: + # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise + # List of whitelisted in travis apt-sources: + # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.7 packages: - libpopt-dev + - clang-3.7 coverity_scan: project: name: "alanxz/rabbitmq-c" description: "C AMQP client for RabbitMQ" notification_email: alan.antonuk@gmail.com - build_command_prepend: cmake .. - build_command: cmake --build . + build_command_prepend: mkdir build && pushd build && cmake .. && popd + build_command: cmake --build ./build branch_pattern: coverity_scan diff -Nru librabbitmq-0.7.1/vms/config.h librabbitmq-0.8.0/vms/config.h --- librabbitmq-0.7.1/vms/config.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/vms/config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -#ifndef LIBRABBITMQ_CONFIG_H -#define LIBRABBITMQ_CONFIG_H - -#define VERSION "v0.1" - -#endif diff -Nru librabbitmq-0.7.1/vms/include.mms librabbitmq-0.8.0/vms/include.mms --- librabbitmq-0.7.1/vms/include.mms 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/vms/include.mms 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ - -.SUFFIXES ; - -.SUFFIXES .EXE $(OLB) .OBJ .MMSD .cpp .cc .C .FOR .Y .L - -.L.C - flex -l $(MMS$SOURCE) -o $(MMS$TARGET) - -.Y.C - yacc $(MMS$SOURCE) -o $(MMS$TARGET) - -.C.OBJ - CC$(CFLAGS)/MMS=(FILE=$(MMS$TARGET_NAME).MMSD)/OBJ=$(MMS$TARGET_NAME).OBJ $(MMS$SOURCE) - -.C.MMSD - CC$(CFLAGS)/MMS=(FILE=$(MMS$TARGET_NAME).MMSD)/OBJ=$(MMS$TARGET_NAME).OBJ $(MMS$SOURCE) - -.CPP.OBJ - CXX$(CXXFLAGS)/MMS=(FILE=$(MMS$TARGET_NAME).MMSD)/OBJ=$(MMS$TARGET) $(MMS$SOURCE) - -.CPP.MMSD - CXX$(CXXFLAGS)/MMS=(FILE=$(MMS$TARGET))/OBJ=$(MMS$TARGET_NAME).OBJ $(MMS$SOURCE) - -.CC.OBJ - CXX$(CXXFLAGS)/MMS=(FILE=$(MMS$TARGET_NAME).MMSD)/OBJ=$(MMS$TARGET) $(MMS$SOURCE) - -.CC.MMSD - CXX$(CXXFLAGS)/MMS=(FILE=$(MMS$TARGET))/OBJ=$(MMS$TARGET_NAME).OBJ $(MMS$SOURCE) - -.OBJ$(OLB) - @ IF F$SEARCH("$(MMS$TARGET)") .EQS. "" THEN LIBRARY/CREATE $(MMS$TARGET) - LIBRARY/REPLACE $(MMS$TARGET) $(MMS$SOURCE_LIST) - -.FOR.OBJ - FOR$(FORFLAGS)/OBJ=$(MMS$TARGET) $(MMS$SOURCE) - -.FIRST - @ continue - -.IFDEF USE_DEPEND -.ELSE - @ WRITE SYS$OUTPUT "Entering ''F$ENVIRONMENT(""DEFAULT"")'" -.ENDIF - -.IFDEF USE_DEPEND -.ELSE -.LAST - @ WRITE SYS$OUTPUT "Leaving ''F$ENVIRONMENT(""DEFAULT"")'" -.ENDIF - -ECHO = WRITE SYS$OUTPUT - -DEPS = $(OBJS:.OBJ=.MMSD) - -OPTFLAGS = /PREFIX=ALL/FLOAT=IEEE/IEEE=DENORM/NAMES=(UPPER,TRUNC)/POINTER=SHORT -DEFS = __USE_STD_IOSTREAM=1,VMS -CDEFS = VMS -INC = . - -DEFAULT_TARGET : $(DEPS) MMS$DEPEND.MMSD INCLUDE_DEPS - @ CONTINUE - -MMS$DEPEND.MMSD : $(DEPS) MMS$GEN_DEPEND.COM - @MMS$GEN_DEPEND.COM - -MMS$GEN_DEPEND.COM : - @ WRITE SYS$OUTPUT "Regenerating GEN_DEPEND.COM" - @ OPEN/WRITE F MMS$GEN_DEPEND.COM - @ WRITE F "$ OPEN/WRITE FH MMS$DEPEND.MMSD" - @ WRITE F "$ WRITE FH ""# File generated by GEN_DEPEND.COM - DO NOT EDIT""" - @ WRITE F "$ WRITE FH ""# Changes will be overwritten next time product is built""" - @ WRITE F "$ WRITE FH "".IFDEF USE_DEPEND""" - @ WRITE F "$ LOOP:" - @ WRITE F "$ FIL = F$SEARCH(""*.MMSD"")" - @ WRITE F "$ IF FIL .NES. """"" - @ WRITE F "$ THEN" - @ WRITE F "$ NAM = F$PARSE(FIL,,,""NAME"")" - @ WRITE F "$ IF NAM .EQS. ""MMS$DEPEND"" THEN GOTO LOOP" - @ WRITE F "$ TYP = F$PARSE(FIL,,,""TYPE"")" - @ WRITE F "$ FUL = NAM + TYP" - @ WRITE F "$ WRITE FH "".INCLUDE "" + FUL" - @ WRITE F "$ GOTO LOOP" - @ WRITE F "$ ENDIF" - @ WRITE F "$ WRITE FH "".ELSE""" - @ WRITE F "$ WRITE FH ""DUMMY :""" - @ WRITE F "$ WRITE FH "" @ WRITE SYS$OUTPUT """"MMS$DEPEND.MMS must .INCLUDED by appropriate DESCRIP.MMS and not called directly""""""" - @ WRITE F "$ WRITE FH "".ENDIF""" - @ WRITE F "$ CLOSE FH" - @ CLOSE F - -INCLUDE_DEPS : - MMK/EXTEND/MACRO=("USE_DEPEND=1") REAL_TARGET - -REAL_TARGET : $(REAL_TARGETS) - @ CONTINUE - -CLEAN : - IF F$SEARCH("*.MMSD*") .NES. "" THEN DEL/NOLOG *.MMSD*;* - IF F$SEARCH("MMS$GEN_DEPEND.COM*") .NES. "" THEN DEL/NOLOG MMS$GEN_DEPEND.COM*;* - IF F$SEARCH("MMS$LINK.OPT*") .NES. "" THEN DEL/NOLOG MMS$LINK.OPT*;* - IF F$SEARCH("MMS$SYMBOLS.OPT*") .NES. "" THEN DEL/NOLOG MMS$SYMBOLS.OPT*;* - IF F$SEARCH("*.OBJ*") .NES. "" THEN DEL/NOLOG *.OBJ*;* - IF F$SEARCH("[.CXX_REPOSITORY*]*.*") .NES. "" THEN DEL/NOLOG [.CXX_REPOSITORY*]*.*;* - IF F$SEARCH("CXX_REPOSITORY*.DIR") .NES. "" THEN - - PIPE (SET SEC/PROT=O:D CXX_REPOSITORY*.DIR; && DEL CXX_REPOSITORY*.DIR;) - IF F$SEARCH("*.OLB") .NES. "" THEN DEL/NOLOG *.OLB;* - IF F$SEARCH("*.EXE") .NES. "" THEN DEL/NOLOG *.EXE;* - IF F$SEARCH("*.OUT") .NES. "" THEN DEL/NOLOG *.OUT;* - IF F$SEARCH("*.TMP") .NES. "" THEN DEL/NOLOG *.TMP;* - IF F$SEARCH("TAGS.") .NES. "" THEN DEL/NOLOG TAGS.;* -.IFDEF EXTRA_FILES - - DEL/NOLOG $(EXTRA_FILES) -.ENDIF - -PURGE : - - PURGE *.OLB,*.MMSD,*.OBJ,*.EXE,[.CXX_REPOSITORY]*.* - -TAGS. : - @ IF "''CTAGS'" .NES. "" THEN CTAGS --language-force=c++ --c++-kinds=+p --fields=+iaS --extra=+q *.h *.cxx *.cpp - -.IFDEF USE_DEPEND -.INCLUDE MMS$DEPEND.MMSD -.ELSE -.ENDIF - diff -Nru librabbitmq-0.7.1/vms/stdint.h librabbitmq-0.8.0/vms/stdint.h --- librabbitmq-0.7.1/vms/stdint.h 2015-10-13 02:40:12.000000000 +0000 +++ librabbitmq-0.8.0/vms/stdint.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -/* Simply forward this header to what VMS has */ -#include