diff options
141 files changed, 13704 insertions, 8128 deletions
diff --git a/libs/freeimage/Docs/Whatsnew.txt b/libs/freeimage/Docs/Whatsnew.txt deleted file mode 100644 index 1b5eedaba2..0000000000 --- a/libs/freeimage/Docs/Whatsnew.txt +++ /dev/null @@ -1,1258 +0,0 @@ -What's New for FreeImage - -* : fixed -- : removed -! : changed -+ : added - -March 15th, 2015 - 3.17.0 -! FreeImage now uses LibPNG 1.6.16 -! FreeImage now uses LibWebP 0.4.2 (GIT patch 2015-03-03) -! FreeImage now uses LibRaw 0.17-Alpha1 -! FreeImage now uses LibTIFF 4.0.4 (CVS patch 2015-01-26) -! FreeImage now uses OpenEXR 2.2.0 -- [Herve Drolon] removed VS 2003 project files : this IDE is no longer supported because of its outdated C++ compiler -+ [Mihail Naydenov] added FreeImage_ConvertFromRawBitsEx -+ [Herve Drolon] added RAW_UNPROCESSED load flag to the RAW plugin -+ [Herve Drolon] added FreeImage_SetMetadataKeyValue -+ [Herve Drolon] added support for metadata writing to the JPEG-JXR plugin -+ [Herve Drolon] added VS 2013 project files -+ [Herve Drolon] added support for PNG tIME metadata (read/write, handle as Exif-TIFF DateTime) -+ [Carsten Klein] added explicit definition of endianness and color order in compiler options -+ [Carsten Klein] added FIQ_LFPQUANT quantizer algorithm -+ [Carsten Klein] added support for input 32-bit dib in Wu quantizer -+ [Tanner Helland] added FreeImage_ConvertToRGBAF and updated conversions in FreeImage_ConvertToType -+ [Herve Drolon] added FreeImage_ConvertToRGBA16 and updated conversions in FreeImage_ConvertToType -+ [Carsten Klein] added FreeImage_CreateView -+ [Carsten Klein] added FreeImage_RescaleRect -+ [Carsten Klein] added FreeImage_GetMemorySize -* [Tanner Helland] ICO plugin: improved support for Vista icons -* [fpgaminer] fixed a rounding error in RGB to greyscale conversion formula -* [Sven-Hendrik Haase] fixed Makefile.fip so that it installs symlinks -* [Joachim Reichel] fixed a potential memory access violation in PluginHDR Save function -* [Christian Schluchter] fixed a bug in FreeImage_LookupSVGColor ("green" color was not found) -* [Marco Altomonte] fixed TARGA signature validation for TARGA versions < 2.0 -* [Jeremy Reyniers] fixed FreeImage_GetScanLine not working with very large images on x64 platforms -* [Herve Drolon] improved PluginTIFF compatibility with LibTIFF 4 -* [Aaron Shumate] fixed a segfault occuring on a corrupted animated GIF -* [Herve Drolon] improved memory allocation in PluginRAW -* [Herve Drolon] fixed loading/saving of TIFF containing a GPS IFD inside the Exif-TIFF metadata segment (the solution is to ignore the tag) -* [Mihail Naydenov] fixed a bug in FreeImage_JPEGCrop*/_JPEGTransform* functions occuring when using the same source / destination filename -* [Herve Drolon] fixed a bug with output image quality in PluginJP2::Save & PluginJ2K::Save functions (regression from FI 3.15.4) -* [Herve Drolon] improved RAW file format detection -* [Aaron Shumate] fixed FreeImage_GetFileType behavior with ANI file formats -* [Herve Drolon] improved Exif reader so as to handle Exif IFD with a suspicious offset (can occur with maker notes) -* [Herve Drolon] fixed a memory leak in PluginPNG:Save occuring when dealing with invalid PNG files -* [Tanner Helland] fixed PNG plugin handling of 16-bit grayscale + 16-bit alpha images -* [Tanner Helland] fixed PNG plugin handling of 16-bit grayscale + tRNS chunk images -* [Tanner Helland] fixed PNG plugin handling of 24-bit RGB + tRNS chunk images -* [Tanner Helland] fixed PNG plugin handling of 1-,4-bit greyscale/palettized + tRNS chunk images -* [ekpyron] fixed invalid directory delimiter in include statement (mingw-w64) in Source/LibJXR/image/sys/strcodec.h -* [ekpyron] fixed Invalid condition for defining _byteswap_ulong (mingw-w64) in Source/LibJXR/image/sys/strcodec.c -* [tostercx] fixed FreeImage_Get*Mask not returning 0 for greyscale images -* [robpats] fixed loading of external plugins when using UNICODE directory names to store plugins -* [Herve Drolon] fixed loading of JXR files when using memory streams -* [Carsten Klein] added Dist/ directory creation in Makefiles (in case it is not already present) - -March 23rd, 2014 - 3.16.0 -! FreeImage now uses LibJPEG 9a -! FreeImage now uses LibPNG 1.6.10 -! FreeImage now uses LibTIFF 4.0.3 (CVS patch 2013-11-30) -! FreeImage now uses LibRaw 0.16.0 -! FreeImage now uses OpenJPEG 2.1.0 (SVN patch 2748) -! FreeImage now uses ZLib 1.2.8 -! FreeImage now uses LibWebP 0.4.0 (GIT patch 2014-03-21) -! FreeImage now uses LibJXR 1.1 (GIT patch 2014-01-31) -+ [Herve Drolon] added loading & writing support for the JPEG-XR image format (also support the FIF_LOAD_NOPIXELS flag) -+ [Herve Drolon] added loading & writing support for the WebP image format (also support the FIF_LOAD_NOPIXELS flag) -+ [Herve Drolon] added support for FIF_LOAD_NOPIXELS flag to JP2/J2K plugins -+ [Gaлl Zimmermann] added basic support for BMP v4, v5 in BMP plugin (useful for drag and drop from another application such as Firefox) -+ [Mihail Naydenov] FreeImage_GetFIFFromFilename[U] : added support for *rgb,*rgba,*.bw extensions to the SGI plugin -+ [Mihail Naydenov] improved FreeImage_Rescale speed & spatial accuracy -+ [Mihail Naydenov] improved JPEG transform functions and added new functions (see below) : - added FreeImage_JPEGTransformFromHandle - added FreeImage_JPEGTransformCombined - added FreeImage_JPEGTransformCombinedU - added FreeImage_JPEGTransformCombinedFromMemory -* [Herve Drolon] fixed FreeImage_CloneTag behavior with ASCII data handling (regression that appeared in 3.15.2, affect metadata writing) -* [Carsten Klein] ICO plugin: avoid using the AND mask when loading a 32-bit (already transparent) icon -* [Andreas Baumann] HDR plugin: removed a comma at end of an enumerator list -* [mark] added missing <string.h> in OpenEXR (needed with mingw) -* [Herve Drolon] added support for FIC_MINISWHITE color type inside FreeImage_GetColorType for FIT_UINT16 images -* [Takamasa Mitsuji] FreeImage_Rescale : fixed a NULL-pointer access bug occurring for transparent images with a linear palette -* [Herve Drolon] fixed PSD parser when reading PSD files with corrupted resources -* [Herve Drolon] fixed TIFF plugin truncating metadata tag on loading if type is ASCII and it's value is of variable size (TIFF_VARIABLE) -* [Herve Drolon] fixed loading of TGA 8-bit files with a palette size greater that 256 -* [Anton Kukoba] TIFF parser didn't initialize the memory with zeros in stripped mode. This caused random bitmap data if the tiff file was corrupted/invalid. -* [Herve Drolon] improved TGA file detection when the format version is < 2.0 -* [Christian Heimes] fixed compiler errors on 64bit Linux (INT64 / UINT64 type mismatches and missing prototype for memset) -* [Christian Heimes] fixed FreeImage_Get*Mask() returning 0 on 24-, -32-bit FIT_BITMAP images -* [Mihail Naydenov] fixed GIF plugin LZW decoder failing on some images -* [Herve Drolon] fixed the TIFF plugin against race condition when used simultaneously in multiple threads -* [Herve Drolon] fixed float <--> rgb[a]f conversions when pixels are out of [0..1] range - -October 27th, 2012 - 3.15.4 -! FreeImage now uses LibPNG 1.5.13 -! FreeImage now uses LibRaw 0.14.7 -! FreeImage now uses ZLib 1.2.7 -! FreeImage now uses LibTIFF 4.0.3 -! FreeImage now uses OpenJPEG 1.5.1 -! FreeImage now uses OpenEXR 1.7.1 -+ [Herve Drolon] improved the speed of RAW files detection in FreeImage_GetFileType* functions -+ [Herve Drolon] added JPEG_GREYSCALE load flag to the JPEG plugin (force to load as 8-bit greyscale) -+ [Herve Drolon] added 64-bit RGBA to 24-bit conversion support in FreeImage_ConvertTo24Bits -+ [Carsten Klein] improved the speed of FreeImage_Rescale for FIT_BITMAP & UINT16, RGB[A]16 types -+ [Carsten Klein] improved the speed of FreeImage_ConvertToGreyscale -* [Carsten Klein] updated makefile for building FreeImage with MinGW -* [Herve Drolon] fixed BigTIFF signature validation in FreeImage_GetFileType* functions -* [Carsten Klein] fixed handling of RGB-565 16-bit images (needed for conversion from HBITMAP to FIBITMAP) -* [Herve Drolon] fixed loading of JPEG with invalid IPTC marker -* [Herve Drolon] changed default TIF RowsPerStrips to image height when saving as TIF G3 or TIF G4 (improved compression) -* [Herve Drolon] improved the memory behavior of the RAW plugin (do not allocate huge variables on the stack) -* [Herve Drolon] fixed FreeImage_AllocateT so that it returns NULL with images with a zero width and/or height -* [Herve Drolon] replaced FIUINT64/FIINT64 with standard types UINT64/INT64 -* [Rustam Abdullaev] fixed PNG plugin with saving of transparent monochrome images -* [Floris van den Berg] improved plugin registering when replacing an existing internal plugin with a new equivalent plugin -* [Herve Drolon] fixed a crash when calling FreeImage_GetColorType on a 32-bit RGBA images loaded with the FIF_LOAD_NOPIXELS flag -* [Herve Drolon] fixed FreeImage_SetTransparencyTable falsely setting a dib to 'transparent' when called with a count of 0 -* [Carsten Klein] fixed storing of RGB masks for 16-bit RGB standard images in order to be in a MSDN compatible way -* [Herve Drolon] added an error handling message inside HDR plugin when trying to save an unsupported format -* [Corey Taylor] fixed DDS plugin color channel swapping for RGB color order, when using FREEIMAGE_COLORORDER_RGB color order -* [Herve Drolon] fixed internal TagLib singleton initialization against double-checked locking so that it is multi-thread safe - -March 17th, 2012 - 3.15.3 -! FreeImage now uses LibPNG 1.5.9 -! FreeImage now uses LibTIFF 4.0.1 -+ [Herve Drolon] added new 64-bit data types FIINT64, FIUINT64 -+ [Herve Drolon] added new 64-bit metadata types to FREE_IMAGE_MDTYPE (FIDT_LONG8, FIDT_SLONG8, FIDT_IFD8) -+ [Herve Drolon] added support for 64-bit metadata types to FreeImage_TagToString -* [Herve Drolon] fixed a regression with Fax3/Fax4 TIFF images on 64-bit OS (introduced with FI 3.15.2) -* [Herve Drolon] fixed some gcc 4.4.6 warnings -* [Petr Pytelka] refactored FreeImage_InsertPage and FreeImage_AppendPage -* [Herve Drolon] fixed JP2/J2K plugins with saving of 32-bit dib with a fully opaque layer -* [Herve Drolon] fixed loading of CMYK JPEG when using JPEG_CMYK load flag (need to invert pixels) -* [Herve Drolon] fixed loading of CMYK PSD when using PSD_CMYK load flag - -February 20th, 2012 - 3.15.2 -! FreeImage now uses LibRaw 0.14.5 -! FreeImage now uses LibPNG 1.5.8 -! FreeImage now uses LibJPEG 8d -! FreeImage now uses ZLib 1.2.6 -! FreeImage now uses OpenJPEG 1.5.0 (released version) -! FreeImage now uses LibTIFF 4.0.0 -- [Herve Drolon] removed dependency on LibMNG 1.0.10 (MNG and JNG files are now handled internally) -+ [Herve Drolon] replaced the MNG plugin with a new MNG internal FreeImage plugin (with read support) -+ [Herve Drolon] added a new JNG internal FreeImage plugin (with read/write support) -+ [Christian Heimes] added write support to the TIFF plugin for EXIF_MAIN tags -+ [Herve Drolon] added new Exif maker note tags -+ [Herve Drolon] added TAG_COMPRESSION conversion to FreeImage_TagToString -* [Mylek Grey] enabled the use of multi-component transforms (MCT) in J2K and JP2 saving -* [Herve Drolon] refactored PluginICO in order to correctly support Windows Vista 256x256 icons -* [Herve Drolon] added minor speed improvements to FreeImage_Rescale -* [Herve Drolon] fixed dib allocation failing with very large images (i.e. more than 4GB) -* [Herve Drolon] fixed FreeImage_CloneTag behavior with ASCII data handling -* [Herve Drolon] improved JPEG plugin behavior with very big images -* [Herve Drolon] improved JPEG plugin behavior with C++ exceptions -* [Herve Drolon] fixed loading of palettized PNG with more that 256 palette entries -* [Herve Drolon] fixed a bug inside IFF plugin occuring when loading a 24-bit dib with a palette -* [Herve Drolon] fixed a bug with loading of PNG images containing a cHRM chunk (regression introduced by LibPNG 1.5.4 and fixed by LibPNG 1.5.5) -* [Herve Drolon] allowed loading of PNG with benign errors (such as images with too many IDATs) -* [Mihail Naydenov] fixed some incorrect MIME types returned by FreeImage_GetFIFMimeType -* [Herve Drolon] fixed loading of Exif with bad thumbnail data or with a bad first offset size - -July 25th, 2011 - 3.15.1 -! FreeImage now uses LibRaw 0.13.7 -! FreeImage now uses LibPNG 1.5.4 -! FreeImage now uses LibTIFF 3.9.5 -! FreeImage now uses OpenJPEG 1.5.0 (SVN patch 2011-07-23) -+ [Herve Drolon] added FreeImage_ConvertToRGB16 and updated FreeImage_ConvertToType -+ [Herve Drolon] added RAW_HALFSIZE flag to RAW plugin -* [Herve Drolon] fixed a memory leak in JPEG plugin occuring when loading some corrupted images -* [Eberhard Mattes] improved thread safety behavior inside internal TagLib class -* [Hew How Chee] fixed a bug in FreeImage_EnlargeCanvas when called with negative left and right parameters and bpp <= 4 -* [Herve Drolon] improved memory allocation checking in FreeImage_ConvertTo[Float/RGBF/UINT16] -* [Herve Drolon] allowed loading of TIF with missing bitspersample/samplesperpixel/photometric tags -* [Herve Drolon] fixed FreeImage_AllocateHeaderT against possible malloc overflow -* [Herve Drolon] fixed CUT plugin against heap corruption vulnerability -* [Herve Drolon] fixed BMP plugin for images with a truncated input data stream -* [Herve Drolon] improved PCX format detection in FreeImage_GetFileType* functions -* [Christian Heimes] fixed a TIFF G4 compression bug occuring with gcc-Version 4.1.2 20080704 (Red Hat 4.1.2-50) - -January 24th, 2011 - 3.15.0 -! FreeImage now uses LibRaw 0.13-Beta3 -! FreeImage now uses LibPNG 1.4.5 -! FreeImage now uses LibTIFF 3.9.4 (CVS patch 2011-01-03) -! FreeImage now uses LibJPEG 8c -! FreeImage now uses OpenJPEG 1.4.0 (SVN patch 2011-01-18) -! [Herve Drolon] FreeImage_CloneMetadata now clone resolution info returned by FreeImage_GetDotsPerMeter(X / Y) -+ [Herve Drolon] added loading support for "half float" format to TIF plugin -+ [Herve Drolon] FreeImage_IsTransparent is now independant of FREE_IMAGE_TYPE -+ [Herve Drolon] added FIT_UINT16 to FIT_RGBF conversion to FreeImage_ConvertToRGBF & FreeImage_ConvertToType -+ [Herve Drolon] added FreeImage_ConvertToUINT16 and updated FreeImage_ConvertToType -+ [Mihail Naydenov] added FreeImage_GetThumbnail / FreeImage_SetThumbnail -+ [Mihail Naydenov] added thumbnail support to Exif, JPEG, EXR, PSD, TGA, TIF formats -+ [Mihail Naydenov] added JPEG_BASELINE save flag to the JPEG plugin -+ [Herve Drolon] added new Exif-TIFF tags (PageName, PageNumber, XPosition, YPosition) and Exif WinXP tags -+ [Herve Drolon] added support for 256x256 icon size to PluginICO:Save -* [Domingo Stephan] fixed a compilation error in TARGA plugin when using a big endian OS (OS X 10.6) -* [Christian Heimes] fixed a compilation error with gcc 4.3.x and OpenEXR -* [Eric Fruhinsholz] fixed a crash in JPEG plugin when reading a JPEG with corrupted XMP data -* [Herve Drolon] improved FreeImage_MultigridPoissonSolver for images whose size is a power-of-two -* [Herve Drolon] fixed a crash in PSD plugin when loading a PSD with a CMYK embedded thumbnail -* [Herve Drolon] fixed loading of JPEG images with a not null but zero length IPTC segment (bad files produced by Picasa) -* [Carsten Klein] fixed a bug in FreeImage_ColorQuantizeEx when using FIQ_WUQUANT quantizer -* [Herve Drolon] added support for RGBA[16][F] to FreeImage_IsTransparent -* [Herve Drolon] fixed loading of resolution info in TIFF CMYK images (bug introduced with 3.14.0) -* [Tom May] fixed JPEG plugin crashing on some Exif files containing tags with an invalid tag length -* [Herve Drolon] fixed a crash when loading TIFF images with a TIFFTAG_TRANSFERFUNCTION Exif tag -* [Tom May] removed assertions in PSD plugin, causing crashes on some malformed images in debug mode -* [Mihail Naydenov] fixed a crash in TIFF plugin when reading an uncommon 24-bit palettized file -* [Carsten Klein] fixed a bug in FreeImage_EnlargeCanvas when using the function as a FreeImage_Copy function -* [Herve Drolon] fixed a bug in PluginBMP with loading of OS/2 2.x palettized BMP -* [luispedro] fixed a bug in PluginBMP when reading malformed 16-bit RGB-555 BMP - -August 12th, 2010 - 3.14.1 -+ [Mihail Naydenov] added support for FIF_LOAD_NOPIXELS flag to EXR plugin -+ [Herve Drolon] added support for FIF_LOAD_NOPIXELS flag to CUT, HDR, RAS, ICO, PNM, RAW, BMP, PFM, XPM plugins -* [Eberhard Mattes] fixed memory allocation checking in multipage API -* [Herve Drolon] (compiler options) removed Win32 OpenMP support introduced in 3.14.0 - -August 9th, 2010 - 3.14.0 -! FreeImage now uses OpenEXR 1.7.0 -! FreeImage now uses ZLib 1.2.5 -! FreeImage now uses LibPNG 1.4.3 -! FreeImage now uses LibJPEG 8b -! FreeImage now uses LibTIFF 3.9.4 (CVS patch 2010-07-13) -! FreeImage now uses LibRaw 0.10-Beta3 -! FreeImage now uses OpenJPEG 1.4.0 (SVN patch 2010-04-16) -! [Herve Drolon] FreeImage_AllocateT now builds a default greyscale palette for 8-bit images -! [Volodymyr Goncharov] FreeImage_LoadMultiBitmapFromMemory now supports read/write operations -! [Herve Drolon] FreeImage_OpenMultiBitmapFromHandle now supports read/write operations -! [Herve Drolon] greyscale conversions now use the Rec. 709 formula -! [Mihail Naydenov] saving RGBF images to TIFF no longer use LogLuv encoding (unless you use the TIFF_LOGLUV save flag) -+ [Herve Drolon] added FIT_FLOAT to FIT_RGBF conversion to FreeImage_ConvertToRGBF & FreeImage_ConvertToType -+ [Herve Drolon] added VS 2008 project files -+ [Herve Drolon] added FreeImage_ConvertToFloat -+ [Mihail Naydenov] added RLE saving to the Targa plugin (see flag TARGA_SAVE_RLE) -+ [Volodymyr Goncharov] added FreeImage_SaveMultiBitmapToHandle -+ [Herve Drolon] added FreeImage_SaveMultiBitmapToMemory -+ [Herve Drolon] added new Exif maker note tags -+ [Lucian Sabo] added JPEG_OPTIMIZE to PluginJPEG:Save -+ [Mihail Naydenov] improved support for Exif tag reading in TIFF plugin -+ [Mihail Naydenov] allowed dataWindow with minimal bounds different from zero in OpenEXR plugin -+ [Herve Drolon] added FIMD_EXIF_RAW metadata model -+ [Herve Drolon] JPEG plugin can load & save raw Exif data (see FIMD_EXIF_RAW) -+ [Herve Drolon] added FIF_LOAD_NOPIXELS load flag constant - used to load header & metadata only -+ [Herve Drolon] added FreeImage_HasPixels -+ [Herve Drolon] added FreeImage_FIFSupportsNoPixels -+ [Herve Drolon] added support for FIF_LOAD_NOPIXELS flag to JPEG, PNG, PCD, PCX plugins -+ [Mihail Naydenov] added support for FIF_LOAD_NOPIXELS flag to TGA, PSD, TIFF plugins -+ [Mihail Naydenov] added support for 16-bit image types to FreeImage_Invert -+ [Mihail Naydenov] improved PSD plugin (faster code, added support for CMYK and LAB loading) + added load flags PSD_CMYK & PSD_LAB -+ [Mihail Naydenov] improved TIFF plugin (CMYK 16-bit loading and saving / RGBAF saving) + added TIFF_LOGLUV save flag -* [Herve Drolon] fixed FreeImage_GetFileType behavior with ANI file formats -* [Herve Drolon] fixed loading of JNG with progressive-JPEG formats -* [Mihail Naydenov] fixed loading of TGA with a corrupted rle count -* [Herve Drolon] fixed conversion formula in FreeImage_PreMultiplyWithAlpha -* [Christoph Brill] removed the use of libmng_data.h private API in MNG Plugin -* [phe02sf] fixed handling of bad Exif-GPS data in a Nikon D5000 image -* [Atsuhiro Igarashi] fixed handling of last data block in PluginGIF::Save (sometimes it saves corrupted images) -* [Christian Heimes] fixed saving of G3 & G4 compressed TIFF with 1bpp on 64bit Linux -* [Herve Drolon] fixed long data type being 64-bit on Unix/Linux platforms (use LONG/DWORD instead of long/unsigned long) -* [Herve Drolon] fixed a memory leak in FreeImage_DeletePage -* [Herve Drolon] fixed the loading of RGBZ images in OpenEXR plugin -* [Lucian Sabo] improved conversion from 1-, 4-, 8-bpp transparent images to 32-bpp -* [Roy F.] fixed a bug in FreeImage_EnlargeCanvas (unable to crop an image on the right) -* [Herve Drolon] fixed the loading of Exif with unusual IFD offset value -* [Eberhard Mattes] fixed page numbering info when saving multipage TIFF -* [Herve Drolon] fixed PluginPICT causing an infinite loop on a malformed PICT image -* [Eberhard Mattes] improved memory allocation checking when using the new operator -* [Herve Drolon] (multipage internals) fixed a potential buffer overflow in ReplaceExtension -* [Eberhard Mattes] improved error checking in FreeImage_CloseMultiBitmap - -December 22, 2009 - 3.13.1 -! FreeImage now uses libTIFF 3.9.2 -! FreeImage now uses OpenJPEG 1.3.0 (SVN patch 2009-11-05) -! FreeImage now uses libPNG 1.2.41 -+ [Berend Engelbrecht] added loading of Exif orientation tag in TIFF plugin -+ [Herve Drolon] added decoding support for the old and outdated JPEG-in-TIFF 6.0 format in TIFF plugin -+ [Herve Drolon] added new 'non standard' Exif tags -+ [Herve Drolon] added new Exif makernote tags -* [Herve Drolon] fixed TIF plugin crashing on a malformed TIFF-JPEG compressed image -* [Herve Drolon] fixed MNG plugin crashing on some old mng images -* [Herve Drolon] fixed handling of 2-bit grayscale transparent PNG -* [Herve Drolon] fixed a bug with the compression rate of JP2 and J2K encoders -* [zestony] fixed TIF plugin with the '65535 bytes' pitch size limitation on saving -* [Herve Drolon] fixed handling of PSD files with a non zero file header reserved member -* [Lucian Sabo] PNG plugin now keep transparency when saving 1- or 4-bit transparent images - -September 28th, 2009 - 3.13.0 -! FreeImage now uses LibJPEG 7 -! FreeImage now uses LibRaw-Lite 0.7.2 -! FreeImage now uses libPNG 1.2.40 -! FreeImage now uses libTIFF 3.9.1 -! FreeImage_RotateClassic is deprecated (use FreeImage_Rotate instead) -+ [Herve Drolon] added support for all Photoshop supported color modes to PSD plugin -+ [Herve Drolon] added support for 32-bit to JNG/MNG plugin -+ [Amir Ebrahimi] added loading support for the PICT format -+ [Herve Drolon] added loading support for camera RAW formats (using LibRawLite wrapper for dcraw) -+ [Mihail Naydenov] added UNICODE functions FreeImage_JPEGTransformU and FreeImage_JPEGCropU -+ [Carsten Klein] added FreeImage_OpenMultiBitmapFromHandle -+ [Carsten Klein] added FreeImage_FillBackground -+ [Carsten Klein] added FreeImage_EnlargeCanvas -+ [Carsten Klein] added FreeImage_AllocateEx / FreeImage_AllocateExT -+ [Mihail Naydenov/Herve Drolon] added FreeImage_TmoReinhard05Ex -+ [Herve Drolon] added FIT_RGBA16 to FIT_RGBF conversion to FreeImage_ConvertToRGBF -+ [Herve Drolon] added FreeImage_Rotate (support for most image types, support background color) -* [Christian Heimes] fixed function prototypes to use a void argument when no argument exist -* [Herve Drolon] fixed RGB color ordering on Intel macs -* [Herve Drolon] FreeImage_RotateClassic now keep transparency when applied to 8-bit images -* [Herve Drolon] fixed handling of transparency info in FreeImage_Copy -* [Herve Drolon] fixed a normalization error in FreeImage_GetAdjustColorsLookupTable -* [Herve Drolon] fixed invalid Exif rotation in PluginJPEG for orientation cases 2 and 4 -* [Mihail Naydenov / Carsten Klein] fixed compilation issues with MinGW32 -* [Mihail Naydenov] improved the loading speed of all targa images -* [Herve Drolon] FreeImage_TagToString now handles the Exif UserComment tag - -April 14th, 2009 - 3.12.0 -! FreeImage now uses libPNG 1.2.35 -! FreeImage now uses libTIFF 3.9.0beta (CVS patch 2009-02-12) -! FreeImage now uses OpenJPEG 1.3.0 (SVN patch 2008-08-21) -! [Herve Drolon] FreeImage_CloneMetadata no longer clone the FIMD_ANIMATION metadata (this was causing problems when saving to GIF format) -+ [Herve Drolon] added full support for the PFM format -+ [Herve Drolon] added JPEG_EXIFROTATE load flag to the JPEG plugin -+ [Herve Drolon] added 16-bit RGB(A) and float RGB(A)F support to FreeImage_GetChannel / FreeImage_SetChannel -+ [Herve Drolon] added src FIT_RGBA16 to dst 32-bit FIT_BITMAP conversion to FreeImage_ConvertToType -* [Carsten Klein] FreeImage_Copy now copies transparency info, resolution info, ICC profile and metadata -* [Carsten Klein] check for negative top/left values in FreeImage_Paste -* [Christian Heimes] changed exceptions with a "catch(char *text)" to a "catch(const char *text)" to make GCC 4.1 happy -* [Deif Lou] fixed a bug in FreeImage_SetTransparentIndex -* [Thomas Maiwald] BMP plugin: on saving, fixed correct setting of bfSize BMP file header for palettized images -* [Timothy Lee] fixed handling of frame disposal in GIF_PLAYBACK mode (GIF plugin) -* [Herve Drolon] fixed handling of Exif Olympus Type 2 maker notes (not yet supported but now safely ignored) -* [Rich Geldreich] fixed DXT1 color endpoint precision problem in DDS plugin -* [Mihail Naydenov] improved loading speed of 24-bit targa images -* [Eugene Golushkov] improved big endian / little endian swapping functions -* [Carsten Klein/Jean-Philippe Goerke] improved FreeImage_SetMetadata / FreeImage_GetMetadata accessors -* [Christian Ruppert] improved Linux Makefiles -* [Eugene Golushkov] fixed PluginBMP alignment bug while saving 16 or 24bit BMP on big endian or Apple machines - -July 28th, 2008 - 3.11.0 -! FreeImage now uses libTIFF 3.9.0beta (CVS patch 2008-05-24) -! FreeImage now uses OpenJPEG 1.3.0 (SVN patch 2008-05-22) -! FreeImage now uses libMNG 1.0.10 -! FreeImage now uses libPNG 1.2.29 -+ [Yves Schmid] added 48-bit RGB to 32-bit conversion support in FreeImage_ConvertTo32Bits -+ [Aaron Shumate] added RGB16-to-BITMAP and All-to-RGBF conversion support in FreeImage_ConvertToType -+ [Benjamin English] added a new OpenGL sample to FreeImage/Examples -+ [Lucian Sabo] added new compression flags to the PNG plugin -+ [Lucian Sabo] added new compression flags to the JPEG plugin (chroma subsampling options) -+ [Noam Gat] added support for SGI grayscale + alpha pics to SGI plugin -+ [Herve Drolon] added FreeImage_CloneMetadata -+ [Herve Drolon] added loading support for Windows Vista icons in ICO Plugin -+ [Herve Drolon] added loading and saving support for RGBF images to the TIF plugin (using the LogLuv codec) -* [Will Bryant] fixed makefile for MacOSX Tiger and Leopard -* [Maria Gullickson] fixed a 'divide by 0' error in PNM plugin and FreeImage_Rescale function -* [Yves Schmid] fixed a bug with Exif metadata reading in TIFF images -* [Herve Drolon] fixed some possible 64-bit portability issues with pointer calculations -* [wangyn] fixed a bug with transparency handling of indexed images in PNG plugin -* [Martin Dyring-Andersen] fixed a bug with GIFinfo structure initialization in GIF plugin -* [Noam Gat] fixed a bug in SGI plugin: when the file reports as two-dimensional, the height factor does not get loaded -* [Herve Drolon] added error messages in FreeImage_Load(U) / FreeImage_Save(U) in case of bad filenames -* [Scott Smith/Herve Drolon] added missing IPTC tags and renamed some tag names to be compatible with ExifTool naming convention -* [Martin Dyring-Andersen] fixed a crash problem with images containing exif data emitted by Picassa -* [Herve Drolon] removed RGBA to RGB transparent conversion in EXR plugin -* [Glenn Pierce] improved the speed of FreeImage_FlipHorizontal -* [Carsten Klein] fixed 65535 pixels width/height limitation in FreeImage_Paste - -November 19th, 2007 - 3.10.0 -! FreeImage now uses libTIFF 3.9.0beta (CVS patch 2007-10-05) -! FreeImage now uses OpenJPEG 1.2.0 (SVN patch 2007-07-13) -! FreeImage now uses OpenEXR 1.6.1 -! FreeImage now uses libPNG 1.2.23 -! FreeImage now hides its internal functions and internal libraries when compiled with gcc -- [Herve Drolon] removed VS C+ 6.0 project files : this IDE is no longer supported because of OpenEXR -+ [Herve Drolon] added VS 2005 project files -+ [Herve Drolon] added full support for the OpenEXR format -+ [Herve Drolon] added full support for the JPEG-2000 format -+ [Herve Drolon] added FreeImage_TmoFattal02 tone mapping operator -+ [Ryan Rubley] added support for RGB vs BGR regardless of endian -+ [Herve Drolon] added FreeImage_MultigridPoissonSolver -+ [Carsten Klein] added FreeImage_PreMultiplyWithAlpha -+ [Carsten Klein] added __stdcall version of FreeImage_OutputMessage -+ [Carsten Klein] added new palette and color manipulation functions (see below) : - added FreeImage_SetTransparentIndex - added FreeImage_GetTransparentIndex - added FreeImage_GetAdjustColorsLookupTable - added FreeImage_AdjustColors - added FreeImage_ApplyColorMapping - added FreeImage_SwapColors - added FreeImage_ApplyPaletteIndexMapping - added FreeImage_SwapPaletteIndices -* [Herve Drolon] fixed a bug in TIFF plugin when reading 8-bit + 8-bit alpha images -* [Herve Drolon] fixed a bug in TIFF plugin when reading images with uncommon bitdepths -* [rodrigo] fixed FreeImage exception handling under gcc (added -fexceptions to gcc compiler flags) -* [Martin Dyring-Andersen] fixed GIF plugin crashing on some corrupted files -* [Herve Drolon] fixed a bug with RLE encoding for 8-bit BMP images -* [Herve Drolon] fixed GPS metadata being skipped when reading metadata in Exif images -* [Herve Drolon] fixed a bug when reading OS/2 BMP images with a negative height -* [Ryan Rubley] fixed a bug with loading of GIFs with large amounts of solid color areas -* [Ryan Rubley] fixed OS X compile error in BitmapAccess.cpp -* [Herve Drolon] fixed a bug in FreeImage_Paste when pasting non-standard image types -* [Herve Drolon] saving 1-bit TIF with the TIFF_CCITTFAX3 flag is now compliant with the TIFF Class F specification -* [Carsten Klein] fixed topdown parameter in FreeImage_ConvertFromRawBits and FreeImage_ConvertToRawBits being handled in reverse -* [Herve Drolon] fixed a bug when reading some RLE-4 encoded BMP data -* [Carsten Klein] conversion from 1-bit to 32-bit now keep possibly present transparency - -February 11th, 2007 - 3.9.3 -! FreeImage now uses libPNG 1.2.16 -! [Ryan Rubley/Ryan Davis] reworked the MacOSX makefile in order to fully support Universal Binary builds of FreeImage -! [Herve Drolon] makefiles are now generated from VS2003 project files instead of VS6 project files -! [Herve Drolon] changed JPEG load/save flag option values -+ [Herve Drolon] added support for RGBAF images to FreeImage_ConvertToRGBF -+ [Herve Drolon] FreeImage_Paste now works with any bitmap type -+ [Herve Drolon] added full support for 64-bit RGBA images to the PNG and TIFF plugins -+ [Jascha Wetzel] added JPEG downsampling feature to PluginJPEG:Load -* [Thomas Chmielewski] fixed a bug in FreeImage_Dither and Bayer dithering, added FID_BAYER16x16 -* [Raphael Gaquer] greatly improved the speed of the GIF encoder -* [Herve Drolon] fixed saving of metadata in the PNG plugin -* [rampelstinskin] fixed transparency table to alpha channel conversion for 4-bit images in FreeImage_ConvertTo32Bits -* [Scott Smith] added missing IPTC tag named "Country/PrimaryLocationCode" -* [Herve Drolon] changed #include <stdint.h> by #include <inttypes.h> in FreeImage.h (needed by Solaris 9) -* [Pierre Arnaud] fixed the use of FreeImage in low memory condition by checking some returned values of the malloc function -* [Pierre Arnaud] fixed TagLib::getTagFieldName not being thread safe - -October 30th, 2006 - 3.9.2 -! FreeImage now uses libTIFF 3.8.2 (with patch 2006-10-13) -+ [Herve Drolon] added full support for 16-bit greyscale and 48-bit RGB to the PNM plugin -+ [Herve Drolon] added IPTC writing support to JPEG & TIFF plugins -+ [Herve Drolon] added new Exif maker note tags -+ [Herve Drolon] added FreeImage_JPEGCrop -+ [Thorsten Radde] added support for 8-bit palettized bitmaps in FreeImage_RotateClassic -+ [Matt Rice] added automatic call to FreeImage_Initialise / FreeImage_DeInitialise when using FreeImage as a .so -+ [Martin Dyring-Andersen] added FreeImage_LoadMultiBitmapFromMemory to the multi-page API -+ [Herve Drolon] added support for tiled TIFF images -* [Carsten Klein] fixed a bug in FreeImage_SetMetadata occuring when deleting a tag -* [Herve Drolon] fixed a bug in PNG plugin when reading Macromedia 'false' PNG files -* [Thorsten Radde] added resolution support to PluginPSD -* [Ryan Rubley] fixed a bug in PluginGIF occuring with interlaced GIF -* [Ryan Rubley] fixed a bug in the multipage cache mechanism (internal FreeImage_FindBlock function) -* [Thorsten Radde] fixed a stack corruption in TIFF plugin occuring when reading exif tags -* [checkered] fixed a bug in the multipage cache mechanism causing VS2005 to crash on multipage files -* [Herve Drolon] fixed a bug with transparency support of 1- and 4-bit images -* [Roar Flolo] fixed a bug in PSD plugin when reading non compressed RGB images (alpha channel initialization) -* [Nicolas Hatier] fixed a bug in PluginGIF when using the GIF_PLAYBACK flag -* [Herve Drolon] fixed a bug in TIFF plugin when saving 8-bit images using LZW with differenciation -* [Herve Drolon] fixed 64-bit compilation issue with LibPNG and assembler code - -July 16th, 2006 - 3.9.1 -* [Ryan Rubley] fixed a bug in PluginGIF plugin causing FreeImage to crash on malformed GIF files - -July 6th, 2006 - 3.9.0 -! FreeImage now uses libPNG 1.2.12 -! FreeImage now uses libTIFF 3.8.2 (with patch 2006-06-24) -! FreeImage_Allocate/FreeImage_Allocate now set the resolution to 72 dpi instead of 0 -+ [Herve Drolon/Petr Pytelka] added a raw FAX G3 format loader -+ [Herve Drolon] added support for most image types to FreeImage_Rescale -+ [Herve Drolon] added FreeImage_MakeThumbnail -+ [Herve Drolon] added support for 64-bit images to FreeImage_ConvertTo32Bits -+ [Herve Drolon] added support for Exif tags to TIF plugin (read only) -+ [Herve Drolon] added FreeImage_ReadMemory -+ [Herve Drolon] added FreeImage_WriteMemory -+ [Herve Drolon] added new Exif maker note tags -+ [Sherman Wilcox] added a SGI file format loader -+ [Herve Drolon] added support for separated images to PluginTIFF -+ [Herve Drolon] added support for progressive-JPEG saving to PluginJPEG -* [Carsten Klein] FreeImage_Dither and FreeImage_Threshold now work with palettized 8-bit dib -* [Christophe Petit] fixed a bug in FreeImage_GetFIFFromFilenameU occuring with files without extension -* [Leigh Brasington] fixed a bug in PluginGIF causing FreeImage not working on Win/98/ME -* [Herve Drolon] fixed a bug in PluginTIFF with writing of JPEG-in-TIFF files -* [Jojakim Stahl] fixed a bug occuring with 4-bit PCX files -* [Sandor Szalacsi] fixed a bug in FreeImage_SetBackgroundColor (bkgnd clearing) -* [Petr Pytelka] fixed PluginTIFF::_tiffSizeProc failing on some images -* [Sherman Wilcox] fixed a bug in DDS plugin when loading images whose size is not a multiple of 4 -* [Sherman Wilcox] fixed a memory leak in PluginDDS::LoadDXT_Helper -* [Sherman Wilcox] fixed DDS plugin bad behavior with invalid DDS files (such as files with zero length) -* [Floris van den Berg] fixed a memory leak in the MultiPage cache mechanism -* [Herve Drolon] replaced WIN32 #define by _WIN32 #define as this is needed by VS2005 -* [Herve Drolon] fixed a VS2005 error in FreeImage_DeletePage -* [Petr Supina] fixed a pow(long,long) function not being standard ANSI C/C++ -* [Petr Supina] fixed FreeImage_FindBlock function not being standard ANSI C/C++ -* [Olaf Stoyke] added support for 64-bit Linux OS -* [Craig Stark] fixed FreeImage support on Intel based Mac OS -* [Herve Drolon] fixed PluginTIFF failing on bad fax tiff images (bad images are now loaded 'as is') -* [Zack Simpson] fixed a bug occuring in rare situations with FreeImage_Aligned_Malloc - -September 5, 2005 - 3.8.0 -! FreeImage now uses libTIFF 3.7.3 -! FreeImage now uses ZLib 1.2.3 -+ [Herve Drolon] added support for 48-bit images to FreeImage_ConvertTo24Bits -+ [Herve Drolon] added FreeImage_ConvertToGreyscale -+ [Herve Drolon] added support for 16-bit greyscale images to FreeImage_ConvertTo8Bits -+ [Petr Pytelka] added UNICODE functions (see below) - added FreeImage_LoadU - added FreeImage_SaveU - added FreeImage_GetFIFFromFilenameU - added FreeImage_GetFileTypeU -+ [Herve Drolon] FreeImage_Copy now works with any bitmap type -+ [Herve Drolon] added support for 1-bit images to FreeImage_Paste -* [Ryan Rubley] fixed PluginGIF failing to link on some broken gcc versions -* [Karl-Heinz Bussian] fixed a bug in LookupX11Color/LookupSVGColor with handling of grey color names -* [Herve Drolon] FreeImage_Dither now uses FreeImage_ConvertToGreyscale and handles 4/8-bit palletized images -* [Herve Drolon] FreeImage_Threshold now uses FreeImage_ConvertToGreyscale and handles 4/8-bit palletized images -* [Craig Hockenberry] fixed PluginGIF::Save swapping the byte order for the height on big endian machines (e.g. PPC on Mac OS X.) -* [Herve Drolon] fixed a bug in JPEG plugin when reading Exif maker notes from images produced by Nikon Editor -* [Herve Drolon] fixed a bug in BMP plugin when reading some malformed RLE8 bmp -* [Herve Drolon] fixed a bug in RAS plugin when loading 8-bit palettized images with less than 256 colors -* [Herve Drolon] fixed a bug in FreeImage_Rescale with 16-,48-,64-bit images -* [Herve Drolon] fixed a bug in the ICC profiles API when loading profile-less CMYK TIFF -* [Herve Drolon] 4-bit PNG are now loaded as 4-bit and no longer converted to 8-bit -* [Greg Ng] fixed a bug in FreeImage_ConvertToRGBF (FIT_BITMAP -> FIT_RGBF conversion) - -May 7, 2005 - 3.7.0 -! FreeImage now uses libTIFF 3.7.2 -! [Ryan Rubley] improved FreeImage_OpenMultiBitmap -+ [Detlev Vendt] added FreeImage_ZLibGUnzip -+ [Herve Drolon] added new image data types FIT_RGB16, FIT_RGBA16, FIT_RGBF, FIT_RGBAF -+ [Herve Drolon] FreeImage_FlipHorizontal & FreeImage_FlipVertical now work with any bitmap type -+ [Herve Drolon] added conversions to float and double in FreeImage_ConvertToType -+ [Herve Drolon] added FreeImage_ConvertToRGBF -+ [Herve Drolon] added support for 16-, 48- and 96-bit images to FreeImage_Rescale -+ [Ryan Rubley] added FreeImage_ColorQuantizeEx -+ [Ryan Rubley] added FIMD_ANIMATION and FIDT_PALETTE -+ [Ryan Rubley] added brand new PluginGIF with full animation multipage and metadata support -+ [Herve Drolon] added support for FIC_MINISWHITE 8-bit images to FreeImage_Rescale -+ [Herve Drolon] added HDR (High Dynamic Range) format (loader & writer) -+ [Herve Drolon] added support for 48-bit images in TIFF plugin -+ [Herve Drolon] added support for 48-bit images in PNG plugin -+ [Herve Drolon] added tone mapping operators (see below) -+ added FreeImage_ToneMapping -+ added FreeImage_TmoDrago03 -+ added FreeImage_TmoReinhard05 -+ [Petr Pytelka] added FreeImage_JPEGTransform -* [Herve Drolon] allowed loading of corrupted JPEG with a premature end of file -* [Herve Drolon] fixed a memory leak with loading of exif JPEG images -* [Detlev Vendt] changed some 'pointer-to-int' casts to 'pointer-to-long' for 64bit machines -* [Ryan Rubley] fixed a memory leak in the multipage API -* [Ryan Rubley] updated VB6 wrapper generation for new functions -* [Herve Drolon] fixed incorrect behavior when reading JPEG comments containing special characters -* [Herve Drolon] fixed incorrect behavior when reading JPEG ICC profiles with a size greater than 64 KB -* [Herve Drolon] fixed a bug in TIFF plugin when loading malformed multipage TIFF -* [Herve Drolon] fixed PluginTIFF not being thread safe - -February 20, 2005 - 3.6.1 -* [Ryan Rubley] fixed a memory leak in the metadata API -* [luedi] improved the robustness of FIBITMAP allocations - -February 13, 2005 - 3.6.0 -! FreeImage now uses libMNG 1.0.9 -! [Herve Drolon] improved the speed of FreeImage_Rescale -! [Herve Drolon] improved FreeImage_RotateClassic (more compact code, a little faster) -! [Herve Drolon] improved the metadata API using tag accessors -+ [Detlev Vendt] added LZW support to PluginGIF:Save -+ [Herve Drolon] added VS.Net 2003 project files -+ [Herve Drolon] added VERSIONINFO resource to the DLL -+ [Herve Drolon] added support for CMYK JPEG on loading -+ [Petr Supina] added 16-bytes alignment to FIBITMAP palette and pixels starting address -+ [Petr Supina] added support for MMX/SSE2 code in LibJPEG (based on Mozilla/Firefox code) -+ [Herve Drolon] added TIFF_JPEG compression flag to the TIFF plugin -+ [Detlev Vendt] added FreeImage_ZLibGZip -+ [Detlev Vendt] added FreeImage_ZLibCRC32 -* [Detlev Vendt] fixed PluginPNG not being thread safe -* [Herve Drolon] fixed compiler warning C4018 occuring with VS.Net 2003 - -December 29, 2004 - 3.5.3 -! FreeImage now uses ZLib 1.2.2 -! FreeImage now uses libPNG 1.2.8 -! FreeImage now uses libTIFF 3.7.1 -! [Herve Drolon] improved FreeImage_RotateClassic -! [Detlev Vendt] improved FreeImage_Rescale (more compact code, preserving 8-bpp colors) -+ [Herve Drolon] added support for transparency saving in ICO plugin -+ [Herve Drolon] added support for 1-bit images to FreeImage_RotateClassic -+ [Herve Drolon] added FreeImage_SetDotsPerMeterX and FreeImage_SetDotsPerMeterY -* [Nan Feng] fixed memory leak in FreeImage_DeleteTag (internal stuff) -* [Nigel Stewart] added conditional #pragma with #ifdef _MSC_VER / #endif -* [Herve Drolon] fixed the '65536 lines' limit on loading in PNM plugin - -November 27th, 2004 - 3.5.2 -* [Herve Drolon] fixed a second bug in FreeImage_Clone function - -November 26th, 2004 - 3.5.1 -+ [Riley McNiff] added FreeImage_ConvertTo4Bits -* [Herve Drolon] fixed a buffer overrun with some ILBM images -* [Riley McNiff] fixed a potential problem when reading TIFF resolution info -* [Dimitar Atanasov] fixed a bug in FreeImage_Clone function -* [Dimitar Atanasov] fixed several bugs in TIFF plugin - -November 1st, 2004 - 3.5.0 -! FreeImage now uses libPNG 1.2.7 -! FreeImage now uses libTIFF 3.7.0 -! FreeImage now uses libMNG 1.0.8 -! [Herve Drolon] improved TIFF LZW compression using a predictor -! [Detlev Vendt] FreeImagesPlus: corrected references to FreeImage.h and FreeImage.lib -+ [Herve Drolon] added support for loading/saving of 8-bit transparent TIFF -+ [Riley McNiff] added support for 4-bit dib in FreeImage_Paste -+ [Herve Drolon] added support for memory IO streams (see below) -+ added FreeImage_OpenMemory -+ added FreeImage_CloseMemory -+ added FreeImage_LoadFromMemory -+ added FreeImage_SaveToMemory -+ added FreeImage_TellMemory -+ added FreeImage_SeekMemory -+ added FreeImage_AcquireMemory -+ added FreeImage_GetFileTypeFromMemory -+ [Petr Pytelka] added FreeImage_GetFIFMimeType to the plugins function list -+ [Herve Drolon] added ICC profile support to JPEG plugin -+ [Herve Drolon] added support for metadata (see below) -+ added FreeImage_SetMetadata -+ added FreeImage_GetMetadata -+ added FreeImage_GetMetadataCount -+ added FreeImage_TagToString -+ added FreeImage_FindFirstMetadata -+ added FreeImage_FindNextMetadata -+ added FreeImage_FindCloseMetadata -* [Riley McNiff] fixed a bug with FreeImage_SetPixelIndex and 4-bit images -* [Petr Pytelka] fixed returned value in FreeImage_CloseMultiBitmap -* [Petr Pytelka] fixed index of new page in FreeImage_InsertPage -* [Aaron Shumate] fixed a minor bug in PNG plugin -* [Aaron Shumate] fixed a bug in IFF plugin (odd-length chunks) -* [Rupert Hewitt] fixed FreeImage not compiling on National Instruments Cvi Ccompiler -* [Herve Drolon] fixed a bug in IFF plugin (ILBM data) -* [Fred Harju] added a Makefile for Solaris 9 -* [Roddy Pratt] fixed FreeImage not linking under Borland C++ Builder -* [Vadim Alexandrov] fixed a memory leak in the multipage API -* [Herve Drolon] fixed a bug with DDS plugin behaviour on Big Endian OS -* [Herve Drolon] fixed a bug with conversion of JPEG resolution info on saving - -July 8th, 2004 - 3.4.0 -! [Jim Keir] improved FreeImage_FlipVertical function -! [Herve Drolon] LZW compression is now enabled in FreeImage -+ [Karl-Heinz Bussian] added constants to FreeImage.h to get at compile time the library version -+ [Karl-Heinz Bussian] added color lookup functions for X11 and SVG -+ [Herve Drolon] added TIFF tags TIFF_CCITTFAX3, TIFF_CCITTFAX4 and TIFF_LZW -+ [Detlev Vendt] added support for CMYK TIFF files with alpha channel -+ [Detlev Vendt] added (re-introduction of) PluginGIF -* [Herve Drolon] fixed a bug with loading of FAX TIFF images (introduced with LibTIFF 3.6.1) -* [Herve Drolon] fixed a bug in Floyd-Steinberg dithering algorithm -* [Herve Drolon] fixed a bug in Targa plugin save function -* [Herve Drolon] fixed a bug in FreeImage_AdjustCurve function -* [Ryan Rubley] fixed a bug with FreeImage_Rescale's filters accuracy -* [Ryan Rubley] fixed a bug in NN quantizer -* [Herve Drolon] fixed a bug with TIFF files containing additional Photoshop alpha channels -* [James Rossfeld] fixed a memory leak with some PSD images -* [Herve Drolon] fixed a bug with saving of 32-bit non transparent PNG images -* [Alexandr Zamaraev] fixed FreeImage not compiling with mingw32 -* [Herve Drolon] fixed FreeImage not compiling with VC.NET (pow function needs casts) - -May 2, 2004 - 3.3.0 -! [Ryan Rubley] FreeImage has been ported to MacOSX and should also work on other big endian processors -+ [Ryan Rubley] rewrote XPM plugin (better load support) and added save support -+ [Ryan Rubley] added ICO_MAKEALPHA flag to ICO plugin -+ [Ryan Rubley] Set/GetPixelColor now works with 16-bit pixels (555 or 565) -+ [Herve Drolon] PNG plugin now supports loading and saving of unsigned 16-bit greyscale images -* [Herve Drolon] fixed a bug with loading of 8-bit and 16-bit PNG with a 8-bit alpha channel -* [Herve Drolon] fixed a bug in NN quantizer algorithm with handling of 4-byte boundary alignment. -* [Herve Drolon] fixed a bug in PluginIFF Validate function -* [Herve Drolon] fixed a minor design issue in FreeImage_GetFIFFromFormat -* [Brad Schick] fixed some compiler warnings with VC++ 7.1 -* [Herve Drolon] fixed a bug with saving of 8-bit palettized images to 24-bit JPEG (channel inversion) - -March 16, 2004 - 3.2.1 -! [Volker Gдrtner] improved the DDS plugin -! [Herve Drolon] FreeImage_Rescale now works on 8-, 24- and 32-bit images -! [Herve Drolon] FreeImage_Copy now works on 1-, 4-, 8-, 16-, 24- and 32-bit images -* [Floris van den Berg] fixed a bug in the MultiPage cache mechanism -* [Herve Drolon] fixed a bug with loading/saving of 8-bit transparent tga images -* [Herve Drolon] fixed a bug with loading of 1-bit TIFF (introduced with LibTIFF 3.6.1) - -February 18, 2004 - 3.2.0 -! FreeImage now uses libTIFF 3.6.1 -+ [Herve Drolon] added FreeImage_HasBackgroundColor -+ [Herve Drolon] added FreeImage_GetBackgroundColor -+ [Herve Drolon] added FreeImage_SetBackgroundColor -+ [Herve Drolon] added FreeImage_Composite -+ [Herve Drolon] added ICC profile support to PNG plugin -+ [Herve Drolon] added background color support to PNG plugin -+ [Volker Gдrtner] added support for DDS format (loader) -* [Steve Johnson] improved FreeImage_OpenMultiBitmap/FreeImage_CloseMultiBitmap -* [Steve Johnson] fixed a bug in FreeImage_InsertPage -* [Herve Drolon] fixed a bug with JPEG compressed TIFF (red/blue swapping) -* [Herve Drolon] fixed a bug in PluginTarga where 8-bit images were saved incorrectly - -January 26, 2004 - 3.1.0 -! FreeImage now uses ZLib 1.2.1 -+ [Herve Drolon] added support for integer, real and complex image types (see below) -+ added FREE_IMAGE_TYPE enum -+ added FreeImage_AllocateT -+ added FreeImage_GetImageType -+ added FreeImage_FIFSupportsExportType -+ added FreeImage_ConvertToStandardType -+ added FreeImage_ConvertToType -+ added load/save support of all image types to TIFF plugin -+ [Peter Lemmens] added a Validate function to TARGA plugin -+ [Herve Drolon] added FreeImage_GetPixelIndex / FreeImage_SetPixelIndex -+ [Herve Drolon] added FreeImage_GetPixelColor / FreeImage_SetPixelColor -+ [Herve Drolon] added FreeImage_GetComplexChannel / FreeImage_SetComplexChannel -* [Serge Ivanchenko] TIFF_DEFLATE compression is now enabled in TIFF plugin -* [Herve Drolon] fixed a bug in NeuQuant color reduction algorithm - -November 16, 2003 - 3.0.4 -* [Tobias Persson] fixed FreeImage_GetChannel not working with FICC_ALPHA channel -* [Detlev Vendt] fixed a minor bug with PNG plugin and PNG_IGNOREGAMMA flag -* [Detlev Vendt] fixed a memory leak in PNG plugin save routine -* [Detlev Vendt] fixed JPEG validation problem with .jpe files -* [Ryan Rubley] added Source/LibTIFF/tif_extension.c to LibTIFF (needed for MacOSX) -* [Herve Drolon] improved error handling in TIFF plugin -+ [Karl-Heinz Bussian] added FreeImage_IsLittleEndian -+ [Karl-Heinz Bussian] added JPEG save support for 8-bit miniswhite bitmaps (transparent conversion to minisblack) -+ [Karl-Heinz Bussian] FreeImage_GetColorType now recognizes 8-bit FIC_MINISWHITE images -! [Herve Drolon] FreeImage_Rescale now supports rescaling of 32-bit images with alpha channel -! [Herve Drolon] FreeImage_Invert now supports inversion of 32-bit images with alpha channel -! [Herve Drolon] FreeImage_AdjustCurve now supports working with FICC_ALPHA channel - -November 2, 2003 - 3.0.3 -* [Ryan Rubley] improved makefile for Linux -* [Ryan Rubley] fixed FreeImage not compiling under MacOSX -* [Detlev Vendt] fixed still present inconsistancy with 32bpp transparency handling -* [Herve Drolon] fixed incorrect loading of 4-bit greyscale images in TIFF plugin - -October 27, 2003 - 3.0.2 -! FreeImage now uses libMNG 1.0.6 -* [Herve Drolon] fixed a boolean test in PluginCUT returning always false -* [Herve Drolon] fixed a warning in PluginIFF generated with g++ -* [Linus Tan] fixed a bug in FreeImage_Copy -* [Herve Drolon] fixed FreeImage not compiling under Linux (thanks to Michal) - -October 20, 2003 - 3.0.1 - -! FreeImage now uses libTIFF 3.6.0 -* [Detlev Vendt] fixed incorrect definition of the FREE_IMAGE_FORMAT enum -* [Detlev Vendt] fixed a potential crash problem with Load / Save routines -* [Herve Drolon] fixed incorrect loading of 16-bit greyscale images in TIFF plugin -* [Dennis Lim] fixed a memory leak in Floyd & Steinberg dithering routine -* [Herve Drolon] fixed a bug in BMP loader (incorrect loading of RLE4 bmp) -* [Detlev Vendt] fixed some inconsistancy with 32bpp transparency handling -+ [David Boland] added a C# wrapper -// Linux compatibility issues -- [Michal Novotny] removed the round function in Utilities.h -! [Herve Drolon] replaced the round routine by the clamp routine in PluginPCD -+ [Herve Drolon] added _itoa version in Utilities.h -* [Michal Novotny] fixed untyped consts not accepted by g++ in PluginBMP - -September 8, 2003 - 3.0.0 -- [Herve Drolon] removed deprecated functions -- [Herve Drolon] removed deprecated flags (TARGA_LOAD_RGB555, ICO_*, except ICO_DEFAULT) -- [Herve Drolon] removed the FreeImage pointer table (internal stuff) -+ [Herve Drolon] added a C++ wrapper -+ [Herve Drolon] added the FreeImage Toolkit (see below) -+ added FreeImage_Rescale -+ added FreeImage_RotateClassic -+ added FreeImage_RotateEx -+ added FreeImage_FlipHorizontal -+ added FreeImage_FlipVertical -+ added FreeImage_Invert -+ added FreeImage_AdjustCurve -+ added FreeImage_AdjustGamma -+ added FreeImage_AdjustBrightness -+ added FreeImage_AdjustContrast -+ added FreeImage_GetHistogram -+ added FreeImage_GetChannel -+ added FreeImage_SetChannel -+ added FreeImage_Copy -+ added FreeImage_Paste -+ [Karl-Heinz Bussian] added XPM loader -+ [Karl-Heinz Bussian] added flags parameter to FreeImage_CloseMultiBitmap -+ [Karl-Heinz Bussian] added JPEG save support for 8-bit palettized bitmaps (transparent conversion to 24-bit) -+ [Herve Drolon] added interface to ZLib compression functions -+ [Herve Drolon] added ICO format to the multipage API (loader & writer) -+ [Herve Drolon] added a MIME type to all plugins -* [Karl-Heinz Bussian] fixed incorrect conversion from 1-bit FIC_MINISWHITE bitmaps to 8-bit -* [Herve Drolon] fixed a bug in FreeImage_CloseMultiBitmap -* [Herve Drolon] fixed a potential memory leak in conversion functions (8-, 24-, 32-bit) -* [Robert Walker] fixed incorrect conversion from 16-bit to 24-bit and 16-bit to 32-bit -* [blurble] fixed TIFF validate signature problem (3DS files were recognized as TIFF) -* [Kurt Jankowski-Tepe] fixed FreeImage not compiling on MinGW / LCC WIN32 -* [Jani Peltonen] fixed bug in PluginTARGA where 32-bit bitmaps are not always correctly flipped -* [Detlev Vendt] fixed a bug with TIFF (memory leak with ICC profiles) - -May 25, 2003 - 2.6.1 -+ [Detlev Vendt] added FIC_CMYK to FREE_IMAGE_COLOR_TYPE -+ [Detlev Vendt] added ICC profile support to the library (see below) -+ added FreeImage_GetICCProfile -+ added FreeImage_CreateICCProfile -+ added FreeImage_DestroyICCProfile -+ added FIICCPROFILE & FIICCPROFILE flags -+ added plugin function FreeImage_FIFSupportsICCProfiles -+ [Detlev Vendt] added ICC profile support for TIFF -+ [Herve Drolon] added XBM (X11 Bitmap Format) support : loading -* [Herve Drolon] fixed incorrect IFF file detection (thanks Floris) -* [Herve Drolon] fixed incorrect conversion from 1/4-bit greyscale bitmaps to 8-bit -* [Herve Drolon] fixed a bug in TIFF writer when saving 1,4,8 bit dib (introduced in 2.6.0, sorry) -* [Herve Drolon] fixed a palette problem in TIFF loader when loading 1-bit b & w images -* [Herve Drolon] improved FreeImage_Dither to handle any bitdepth - -May 5th, 2003 - 2.6.0 -! FreeImage now uses libPNG 1.2.5 -! FreeImage now uses libMNG 1.0.5 -! [Markus Loibl] ActiveX wrapper is now distributed in a separate release (since 2.5.5) -! [Herve Drolon] the function FreeImage_Free is now deprecated : use FreeImage_Unload instead -! [Herve Drolon] updated the generic samples and removed deprecated functions -+ [Detlev Vendt] added CMYK support to TIFF save function -+ [Detlev Vendt] added TIFF_SAVE_CMYK flag constant -+ [Detlev Vendt] added 32-bit support (with transparency handling) to TIFF plugin -+ [Herve Drolon] added FreeImage_Threshold -+ [Herve Drolon] added FreeImage_Dither -+ [Herve Drolon] added FREE_IMAGE_DITHER parameter to FreeImage_Dither -* [Herve Drolon] improved error handling in PluginMNG -* [Herve Drolon] improved TIFF flags handling in TIFF save function -* [Herve Drolon] fixed a potential crash-problem in FreeImage_OutputMessage (in case of a null message) -* [Detlev Vendt] fixed a bug with the deprecated FreeImage_GetBitsRowCol (trailling backslash behind the DEPRECATE macro) - -July 24th, 2002 - 2.5.5 -! FreeImage now uses libPNG 1.2.4 -! FreeImage now uses libMNG 1.0.4 -+ [Markus Loibl] added ActiveX wrapper - -June 22th, 2002 - 2.5.4 -* [Timothy Roughton] fixed FreeImage not compiling on LCC WIN32 -* [Markus Loibl] fixed PluginTIFF sometimes saving with wrong X/Y resolution -* fixed crashbug when loading some RLE4 BMPs -! FreeImage now uses LibPNG 1.2.3 -! [Markus Loibl] improved startup plugin locate handling code -! [Gerhard Gruber] made some changes so that FreeImage compiles on VC5 -+ [Markus Loibl] added flags TIFF_PACKBITS, TIFF_DEFLATE, TIFF_ADOBE_DEFLATE and TIFF_NONE - -May 21th, 2002 - 2.5.3 -* fixed wrong colors when loading 16-bit grayscale TIFF -* fixed crash-problem with FreeImageQt -* fixed PluginTIFF saving some bitmaps flipped vertically -* [Laurent Rocher] fixed bug in FreeImage_GetLockedPageNumbers -* [Laurent Rocher] fixed bug in FreeImage_UnlockPage -! FreeImage now uses libpng 1.2.2 -+ added TARGA save support -+ added BMP RLE8 save support - -March 30th, 2002 - 2.5.2 -* fixed bug in PluginTARGA where 32-bit bitmaps are not always correctly flipped -* fixed FreeImage_GetLockedPageNumber being mentioned in FreeImage.h -* fixed crash bug when handling read-only multipage bitmaps -- removed internal function FreeImage_GetExtraDataPointer -! FreeImage now uses zlib 1.1.4 -+ added function FreeImage_GetLockedPageNumbers - -March 2nd 2002 - 2.5.1 -* fixed pluginTIFF not being able to save 32-bit bitmaps -* fixed not being able to save PNM bitmaps through the LoadXXX wrappers -* fixed a webcam generated BMP image being loaded with wrong colors -! FI_ReadProc, FI_WriteProc, etc. do now carry the DLL_CALLCONV flag -! the function FreeImage_GetBitsRowCol is now deprecated -! FreeImage_SetTransparencyTable now taken an integer as count parameter -! FreeImage_IsTransparent now always returns true for 32-bit bitmaps -! PluginPNG::Save now ignores the result of FreeImage_IsTransparent -! PluginTIFF now converts all 32-bit bitmaps to 24-bit, until our patch - to fully support alpha in TIFF is applied in libtiff -+ added full multi-paging support -+ added octal and hexadecimal number support to FreeImage_OutputMessage - -January 3rd 2002 - 2.5.0 -* fixed bug in FreeImage_SaveJPEG -* fixed bug in FreeImage_LoadMNG -* fixed bug in FreeImage_LoadPNG -* fixed small Visual C++ 5.0 compiler issue in PluginMNG.cpp -* fixed FreeImage crashing on JPEG 6.0 encoded TIFFs -! FreeImage now uses libTIFF 3.5.7 -! FreeImage now uses libPNG 1.2.1 -! all the FreeImage_LoadXXX and FreeImage_SaveXXX functions are now deprecated -+ added Dr. Halo (*.cut) support -+ added printf-like format string support to SetOutputMessage -+ added basic multi-paging support: open, close, counting and grabbing -+ added deprecation manager -+ added FreeImage_Clone function - -October 3rd 2001 - 2.4.2 -* fixed missing BI_BITFIELDS support for 32-bit BMPs -* fixed bug in FreeImage_ConvertLine16_555_To16_565 and vice versa -* fixed bug in FreeImage_ConvertToRawBits -* fixed PluginTIFF behaving incorrectly on PHOTOMETRIC_MASK images -* fixed 16 bit TIFFs not loading correctly -* fixed incorrect handling of CCITTFAX3 and CCITTFAX4 TIFFs -* fixed JPEG encoded TIFFs not being supported -! [Yours Detlev] patched libTIFF to handle EXTRASAMPLE_UNSPECIFIED -! [Juergen Riecker] improved speed of PCX loading a lot -! rewrote parts of FreeImage to improve support for c -! the internal RGB555 and RGB565 macros now read BGR instead of RGB -! FreeImage now uses libMNG 1.0.3 -! FreeImage now uses libPNG 1.2.0 -! FreeImage_Save now opens files with the "w+b" flag -! renamed internal macro CalculateUsedColors to CalculateUsedPaletteEntries -! enabling/disabling plugins no longer has effect on FIFSupportsReading -! enabling/disabling plugins no longer has effect on FIFSupportsWriting -+ added flag PNG_IGNOREGAMMA -+ added function FreeImage_FIFSupportsExportBPP - -July 30th 2001 - 2.4.1 -* [Jan Nauta] fixed some plugin ids not being passed to plugins -* [Jan Nauta] fixed some functions being natively called instead of indirect -* [Jan Nauta] fixed BMPs with signature BA not being regognised -* [Remo Eichenberger] fixed memory leak in the plugin system -* fixed seek bug in PluginIFF's Validate -* fixed transparency issue in PluginPNG -* fixed uncaught exceptions in WUQuantizer and NNQuantizer -* fixed some problems with PluginTARGA -* fixed some problems with PluginICO -* fixed some problems with PluginBMP -! improved FreeImageQt's load function a little -! tell/seek control for validation is now handled inside the plugin framework - -July 22th 2001 - 2.4.0 -* (Yours Detlev) fixed memory leak in FreeImage_GetFIFFromFilename -* (Yours Detlev) fixed memory leak in the ICO plugin -* (Yours Detlev) fixed memory leak in the PNG plugin -* fixed potential NULL-pointer access bug in Plugin::AddNode -* fixed problems with linking the static lib -- removed LBM plugin. Its functionality is placed in the IFF plugin now -- removed FreeImage_GetFIFByIndex -! FreeImage now uses LibMNG 1.0.2 -! FreeImage_SetTransparent now only enables alpha when the bitmap is 8 or 32 bit -! FreeImage_SetTransparencyTable now only enables alpha when the bitmap is 8 bit -! FreeImage_LoadLBM now uses Mark Sibly's IFF plugin -! FreeImage_SaveBMP now converts to 24-bit when bpp is 32 and transparency is off -! FreeImage_SaveJPEG now converts to 24-bit when bpp is 32 and transparency is off -! FreeImage_SavePNM now converts to 24-bit when bpp is 32 and transparency is off -! FreeImage_SaveTIFF now converts to 24-bit when bpp is 32 and transparency is off -+ [Mark Sibly] added IFF (ILBM) support -+ added basic support for Photoshop files -+ added mime type support (FreeImage_GetFIFFromMime) -+ added functions FreeImage_SetPluginEnabled and FreeImage_IsPluginEnabled - Disabling plugins modifies the behaviour of the following functions: - * FreeImage_LoadFromHandle - * FreeImage_SaveToHandle - * FreeImage_FIFSupportsReading - * FreeImage_FIFSupportsWriting - * FreeImage_GetFIFFromFormat - * FreeImage_GetFIFFromFilename - * FreeImage_GetFIFFromMime - * FreeImage_Validate - -June 30th 2001 - 2.3.2 -* fixed missing "targa" extension in targa extension list -* fixed small memory leak in PluginList::AddNode -* fixed 32 bit PNG saving suddenly disappeared from the distro? -* fixed 'black line' bug in LoadTARGA -- removed project FreeImageM2 -- removed FreeImage_Combine -! FreeImage_RegisterLocalPlugin now receives a FI_InitProc as first parameter -! FreeImage_GetFIFFromFilename now also takes the format id into account -! cleanup up the code a little for PluginPCD and PluginPCX -+ added static lib project - -June 11th 2001 - 2.3.1 -* [Machiel ten Brinke] fixed the loading of some 'ancient' TARGAs -* [Rui Lopes] fixed some bugs in the external plugin registration -* fixed the plugin system crashing when the init function isn't called -- removed project FreeImagePy -- removed 32 to 24 bit conversion while saving PNG in FreeImageQt -! the scanline convert functions are now accessable in plugins -! FreeImage now uses an STL map to store the plugin list -! PluginSDK.h is now integrated into FreeImage.h -! FreeImage_Register now receives the boolean parameter 'load_local_plugins_only' -! FreeImage now uses LibPNG 1.0.12 -+ [Rui Lopes] added plugin for GIF reading/writing support -+ added function FreeImage_SetTransparencyCount -+ added support for 32 bit PNG saving -+ added FreeImage_RegisterLocalPlugin to allow plugins inside apps -+ added FreeImage_RegisterExternalPlugin to manually load DLLs -+ added plugin for JBIG reading/writing support - -May 4th 2001 - 2.3.0 -* [Martin Weber] fixed some small bugs in the TARGA and BMP plugins -* [Martin Weber] fixed tiny bug in new 16 bit conversions -* [Martin Weber] fixed load flag inconsistency in the TARGA plugin -* [Martin Weber] fixed plugin id / load reference inconsistency for PNM -* [Jan Nauta] fixed bug in conversion 16 -> 16 -* [Herve Drolon] fixed small bug in 4-bit PCX loader -- removed code that loads BMPs renamed to ICO in PluginICO -! the flag TARGA_LOAD_RGB555 is now obsolete -! the plugin list is now sorted internally -! ConvertTo32Bits now stores the transparency table as alpha mask -! FreeImage now uses LibMNG 1.0,1 -! FreeImage now uses LibPNG 1.0.11 -+ added external plugin support via DLLs -+ added function FreeImage_GetFIFByIndex -+ added internal function CalculateScanLine -+ added transparency support for high-color PNGs -+ added transparency support for high-color TIFFs -+ added functions FreeImage_SetTransparent and FreeImage_IsTransparent -+ added constant FIC_RGBALPHA to FREE_IMAGE_COLOR_TYPE - -April 5th 2001 - 2.2.0 -* [Remo Eichenberger] fixed small bug concerning DLLMain and static LIB generation -* fixed 1-bit bitmaps not properly loading in FreeImageQt -* fixed bug in conversion 16->16 -* FreeImage now uses LibPNG 1.0.10 -! [Martin Weber] improved loading of BMP files -! [Martin Weber] improved loading of TARGA files -! [Dave Larson] improved visual appearance after 16 conversions -! FreeImageQt now converts 32-bit bitmaps to 24-bit when saving PNGs and JPEGs -+ added functions FreeImage_Initialise and FreeImage_DeInitialise -+ added internal plugins -+ re-added combine/alphablend functions - -March 8th 2001 - 2.1.0 -* [Martin Hemming] fixed bug in 16-bit TARGA loading code -* fixed PNG's with alpha masks not loading correctly -! FreeImage is now dual-licensed: the FI-License and the GPL license -! FreeImage now uses LibPNG 1.0.9 -! FreeImage now uses LibTIFF 3.5.6 Beta -! FreeImage now uses LiBMNG 1.0.0 -! changed the ordering of the FREE_IMAGE_FORMAT table -! improved linux support -! improved test script -+ added transparency table support to SavePNG -+ added BI_BITFIELDS support to LoadBMP and SaveBMP -+ added reading support for OS/2 2.x BMPs -+ added support for MNG and JNG reading using LibMNG -+ added support for Deluxe Paint reading -+ added 'hot swap' support to the Core DLL -+ added 'hot swap' support to FreeImage Qt -+ added functions GetFIFFromFormat and GetFIFFromFilename -+ added functions FIFSupportsReading and FIFSupportsWriting -+ added function GetFIFRegExpr - -January 14th 2001 - 2.0.0 -* [Herve Drolon] fixed a bug in the conversion 4->8 -* [Herve Drolon] fixed a bug in metrics handling in SaveJPEG -* [Herve Drolon] fixed a bug in the return value of the function SaveTIFF -* fixed the presence of two WuQuantizer.cpp files in the distribution -* fixed bug where a BMP renamed to ICO isn't loaded -- removed FreeImage_ConvertToGreyScale. Use FreeImage_ConvertTo8Bits instead. -- removed the boolean parameters from all conversion routines -- removed page handling in LoadTIFF. A new range of functions will be added. -! The void pointers used in FreeImage are now typed -! LoadBMP now takes palettes in 24/32 bit images in respect -! All effects and MMX functions are now stored in a new library (FreeEffects) -! [Herve Drolon] fixed bug in FreeImage_GetColorType -! [Herve Drolon] improved PCX loader. It can now read 1, 4, 8 and 24-bit images -! [Manfred Tausch] improved FreeImage_Rotate -! [Luca Piergentili] fixed crash bug when saving some 1-bit TIFFs -! rewrote all bitdepth conversion routines making use of the new scanline converters -! rewrote bitdepth conversion in FreeImageQt (uses less memory) -! FreeImage is now compiled __stdcall -+ [Herve Drolon] added WBMP (Wireless Bitmap Format) support: loading and saving -+ [Herve Drolon] added 4, 16 and 32 bitdepth handling in GetColorType -+ [Herve Drolon] added handling of 8-bit greyscale bitmaps in SaveJPEG -+ [Herve Drolon] added NeuQuant color reduction algorithm to ColorQuantize -+ added DLL_CALLCONV (calling convention) flag -+ added bitmask support to all bitmaps -+ added a series of functions converting scanlines from one bitdepth to another -+ added functions ConvertFromRawBits and ConvertToRawBits -+ added project FreeImageM2: Magenta II MMT bindings for FreeImage -+ added basic foundation for linux support - -December 2th 2000 - 1.4.4 -* fixed small bug related to TIFFSetDirectory in FreeImage_LoadTIFF -* fixed FreeImage_Rotate sometimes clipping too much pixels -* fixed other small bug in FreeImage_Rotate -* fixed FreeImage_Clone not taking the FREEIMAGEHEADER in account -* fixed bug in FreeImageQt where 1-bit images are not correctly allocated -* fixed FreeImage_Crop not copying the palette -* fixed message function pointer crash bug -* fixed bug where the palette wasn't copied when saving in FreeImageQt -* fixed FreeImage_Clone not copying the transparency table -- removed FreeImage_WritePaletteEntry -! [Adam Gates] rewrote parts of FreeImage so that c compilers can handle it better -! FreeImageQt doesn't statically link with the FreeImage lib anymore -! FreeImageQt now uses atexit() to automatically unregister -! rewrote parts of FreeImage_LoadBMP to increase speed -+ [Markus Loibl] added metrics handling code to LoadBMP, LoadJPEG, LoadTIFF and LoadPCX -+ added metrics handling code to FreeImageQt -+ added functions FIQT_IsLoaded, FIQT_GetVersion and FIQT_GetCopyrightMessage -+ added conversion 1 -> 16 -+ added FreeImage_SaveJPEG and JPEG quality settings -+ added FreeImage_GetBitsRowCol -+ added function FIQT_SetOutputMessage to FreeImageQt -+ added FreeImage_GetFileTypeFromExtension and FIQT_GetFileTypeFromFormat -+ added project FreeImagePy: python bindings for FreeImage - -November 7th 2000 - 1.4.3 -* fixed FreeImage_SavePNG crash bug -* fixed slighly corrupt size filter in FreeImage_Combine -* fixed FreeImage_SaveTIFF not saving 4-bit images -* [Herve Drolon] fixed bug in FreeImage_LoadTIFF -* [Herve Drolon] fixed bug in FreeImage_GetColorType -- removed fclose from FreeImage_SavePNM (who put it there?) -! rewrote FreeImage_Rotate -! FreeImageQt now automatically detects which formats are supported by Qt and which not -! FreeImage_Allocate now returns a void pointer -! FreeImage_Unload is now called FreeImage_Free -+ added 16-bit 5-5-5 support to FreeImage_LoadBMP -+ added RLE_DELTA support to FreeImage_LoadBMP -+ added directory support to FreeImage_LoadTIFF -+ added functions dealing with transparency -+ added transparency support to 8-bit PNG's in Qt -+ added FREE_IMAGE_QUANTIZE parameter to FreeImage_ColorQuantize -+ added custom FREEIMAGEHEADER header prepended to internal bitmaps -+ added new documentation - -October 18th 2000 - 1.4.2 -* fixed FreeImage_SaveBMP storing an incorrect bfSize value in the BITMAPFILEHEADER -* fixed bug where JPEG and PNG wouldn't load in FreeImageQt -* fixed FreeImage_Mirror mirroring one pixel less than needed -! FreeImage_MaskedCombine24 is now called FreeImage_MaskedCombine24Ex -! FreeImage_MaskedCombine32 is now called FreeImage_MaskedCombine32Ex -+ added 16-bit bitmap support to FreeImage_Mirror -+ added 16-bit bitmap support to FreeImage_ConvertTo8Bits -+ added simple version of FreeImage_MaskedCombine24 -+ added simple version of FreeImage_MaskedCombine32 - -October 17th 2000 - 1.4.1 -* [Herve Drolon] fixed bug in FreeImage_ConvertTo8Bits -* fixed bug in conversion with 16 -> 24 and 16 -> 32 -- removed static library support -- removed all unnecessary files from LibTIFF, LibPNG, LibJPEG and ZLib -- removed all absolute seeks from the library -! FreeImageQt now makes use of the DLL distro -! rebuilt the entire directory structure -! improved handling of BMP -! renamed FreeImage_MaskedCombine to FreeImage_MaskedCombine32 -+ [Alexander Dymerets] added 24-bit masked alpha blending with a seperate alpha mask -+ added FreeImage_Rotate (known bug in degrees 76 to 106) -+ added 4-bit bitmap support to FreeImage_ConvertTo16Bits -+ added 8-bit bitmap support to FreeImage_ConvertTo16Bits -+ added 32-bit bitmap support to FreeImage_ConvertTo16Bits -+ added 32-bit bitmap support to FreeImage_Mirror -+ added 16-bit 5-5-5 support to FreeImage_ConvertTo24Bits -+ added 16-bit 5-5-5 support to FreeImage_ConvertTo32Bits - -October 2th 2000 - 1.4.0 -* [Jani Kajala] fixed bug in conversion with 4 -> 24 and 8 -> 32 -* [Jani Kajala] fixed bug in FreeImage_Flip -* [Jani Kajala] fixed minor bug in FreeImage_LoadBMP -- [Herve Drolon] removed PBMFlags, PGMFlags and PPMFlags -- [Herve Drolon] removed FI_LoadGeneric -- removed FreeImage_Win32.h -! [Herve Drolon] changed FI_GetFileType -! [Herve Drolon] replaced FI_LoadPBM, FI_LoadPGM and FI_LoadPPM with FI_LoadPNM -! [Herve Drolon] improved FreeImage_LoadPNG -! FreeImage_WritePaletteEntry is now exported -+ [Herve Drolon] added FreeImage_SavePNG -+ [Herve Drolon] added FreeImage_SavePNM and PNMFlags -+ [Herve Drolon] added XXXFlags parameter to save functions -+ [Herve Drolon] added FreeImage_LoadRAS and FIF_RAS -+ added FreeImage_GetFileTypeFromExt - -September 7th 2000 - 1.3.5 -+ added conversion 4 -> 8 to FI_ConvertTo8Bits -+ added simple version of FI_GetFileType -+ added project FreeImageQt; a port of the library to the TrollTech library - -August 31th 2000 - 1.3.4 -* fixed 'ice effect' bug in new 24 bit PCX code -* fixed some bugs with the conversion 16 -> 24 and 16 -> 32 -! FI_Blur now returns void -! A debug build of the library now produces FreeImaged.dll and FreeImaged.lib -! TARGA_LOAD_ARGB8888 is now called TARGA_LOAD_RGB888 -! Alpha channels are now automatically loaded unless TARGA_LOAD_RGB888 is specified -! cleaned up the code a lot -+ added 32-bit bitmap support to FreeImage_ConvertToGreyscale -+ added support for 32-bit bottom-left TARGA images -+ added internal functions FreeImage_WritePaletteEntry() and FreeImage_GetScanLine() -+ added FreeImage_Win32.h, containing Windows functions needed to create DIBs -+ added documentation through Doxygen - -July 30th 2000 - 1.3.3 -* [Jani Kajala] fixed some bugs with the conversion 4 -> 24 and 8 -> 24 -* [Jani Kajala] fixed some bugs with the conversion 4 -> 32 and 8 -> 32 -* fixed bug in FI_LoadPNM's ASCII number loader -! [Herve Drolon] improved FI_LoadPNG -! [Herve Drolon] changed FI_ConvertToGreyScale (added changeable macro for conversion) -! improved FI_ConvertTo24Bits -! improved FI_ConvertTo32Bits -! freeImage now uses LibPNG 1.0.8 -+ [Herve Drolon] added FI_ColorQuantize, based on Wu's color quantizer -+ added the conversion 1 -> 24 -+ added the conversion 1 -> 32 -+ added FI_ConvertTo8Bits -+ added FI_Invert (very useful for image processing) -+ added FI_GetColorType and 'enum FREE_IMAGE_COLOR_TYPE' - -June 30th 2000 - 1.3.2 -- removed color reduction functions from the project -! [Herve Drolon] Improved FI_LoadTIFF code -! renamed FI_ToGrayscale to FI_ConvertToGreyScale -! renamed FI_IncreaseColors to FI_ConvertTo24Bits -! LoadBMP now supports 32-bit bitmaps -! [Jani Kajala] Improved FI_LoadTARGA and FI_LoadPCX code -+ added FI_ConvertTo32Bits to convert a bitmap to 32-bit -+ added FI_MaskCombine to combine two 32-bit bitmaps using a alpha mask -+ added FI_AddAlphaMask to enrich a 32-bit bitmap with an alpha mask -+ added FI_SaveTIFF -+ added 16-bit bitmap (565) support to the ConvertToXXX functions. -+ added FI_ConvertTo16Bits (555 and 565) - -June 1th 2000 - 1.3.1 -- removed Standard Template Library (STL) code -* [Jani Kajala] fixed minor bug in FI_LoadTARGA -* [Jani Kajala] fixed some minor bugs in FI_LoadPCX -! streamlined FI_LoadJPEG a little -! FreeImage now uses LibPNG 1.0.6 -! FreeImage now uses LibTIFF 3.5.5 -! FreeImage now uses malloc and free instead of new and delete -+ introduced compiler flags to disable certain features in the DLL -+ added experimental nearest color reduction (FI_ReduceColorsNearestColor) - -April 13th 2000 - 1.3.0 -* fixed some 8 bit PCX files loading incorrectly -* fixed tiny bug in internally used CalculateUsedColors function -- removed FI_SaveXPM. Only BMP is supported now. -- removed Windows dependencies for easier porting -! optimized FI_LoadKOALA a little -! optimized FI_Combine using MMX technology -! FI_Combine now receives an 'unsigned integer' as alpha blend parameter -! FI_InCreaseColors and FI_ReduceColors don't dispose the old bitmap anymore -+ added PNM support (PGM, PPM and PBM; both binary and ascii) -+ [Alexander Dymerets] added FI_EnableMMX and FI_DisableMMX -+ added various effect functions (FI_Blur, FI_Brighten and FI_Crop) - -March 1st 2000 - 1.2.1 -* fixed some 24 bit PCX files loading incorrectly - -February 8th 2000 - 1.2.0 -* fixed last bitmap data block in JPEG files being truncated -* fixed 4/8 bit BMP's incorrectly loading when the palette is smaller than the bitcount predicts -- removed FI_Load. There is no reliable way to identify all image formats -- removed FI_SetJpegDecodeMode. - Mode selection is now done using the 'DataEnum data' parameter of FI_LoadJPEG -! read_proc/write_proc/tell_proc in FreeImageIO now are same as fread/fwrite/ftell -+ added a 'DataEnum data' parameter to all FI_LoadXXX functions. -+ added 16 bit TARGA support -+ added RLE support for TARGA images -+ added FI_GetDIBSize to get the size of a DIB in bytes -+ added Kodak PhotoCD support (Base, Base/4 and Base/16 encoding) -+ added KOALA support -+ added FI_GetFileType. Note: there is no reliable way to identify TARGA, ICO and PCD. Therefore they have been excluded -In KOALA files only the files converted by a C64 emulator can be identified. -+ added FI_Combine to combine two 24-bit bitmaps with (optional) alpha blending - -January 15th 2000 - 1.1.1 -! FI_Copy is now called FI_Clone -+ added FI_ToGrayscale to convert a color bitmap to grayscale -+ added 32 bit TARGA support -+ added FI_IncreaseColors to increase the bitmap bitdepth from 4/8 bit to 24 bit - -January 14th 2000 - 1.1.0 -* FI_MIRROR: fixed nibbles not being mirrored in 4 bit images -* FI_MIRROR: fixed bits not being mirrored in 1 bit images -* fixed improper loading of 1, 4 and 8 bit OS/2 BMP's -* fixed some inconsistensies in the calculation of lines and pitches -* fixed incorrectly loading of Huffman and FAX encoded TIFFs -* fixed LoadTGA accepting 16 bit TGA's and returning corrupt DIB's -- removed LZW support for TIFFs -! FreeImage now uses LibTIFF 3.5.4 -+ added ICO support -+ added overridable file I/O support in the form of FreeImageIO and fi_handle -+ added FI_Load for generic image loading -+ added FI_ReduceColors for color reduction -+ added FI_Copy to copy a bitmap in memory - -January 5th 2000 - 1.0.0 diff --git a/libs/freeimage/Docs/license-fi.txt b/libs/freeimage/Docs/license-fi.txt deleted file mode 100644 index 479fb4d511..0000000000 --- a/libs/freeimage/Docs/license-fi.txt +++ /dev/null @@ -1,142 +0,0 @@ -FreeImage Public License - Version 1.0 ---------------------------------------------- - -1. Definitions. - -1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. - -1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. - -1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. - -1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. - -1.5. "Executable" means Covered Code in any form other than Source Code. - -1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. - -1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. - -1.8. "License" means this document. - -1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a -Modification is: - -A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. - -B. Any new file that contains any part of the Original Code or previous Modifications. - -1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. - -1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control -compilation and installation of an Executable, or a list of source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. - -1.12. "You" means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the -direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity. - -2. Source Code License. - -2.1. The Initial Developer Grant. -The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: - -(a) to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, or as part of a Larger Work; and - -(b) under patents now or hereafter owned or controlled by Initial Developer, to make, have made, use and sell ("Utilize") the Original Code (or portions thereof), but solely to the extent that -any such patent is reasonably necessary to enable You to Utilize the Original Code (or portions thereof) and not to any greater extent that may be necessary to Utilize further Modifications or -combinations. - -2.2. Contributor Grant. -Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: - -(a) to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code or as part of a Larger Work; and - -(b) under patents now or hereafter owned or controlled by Contributor, to Utilize the Contributor Version (or portions thereof), but solely to the extent that any such patent is reasonably necessary to enable You to Utilize the Contributor Version (or portions thereof), and not to any greater extent that -may be necessary to Utilize further Modifications or combinations. - -3. Distribution Obligations. - -3.1. Application of License. -The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or -restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. - -3.2. Availability of Source Code. -Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. - -3.3. Description of Modifications. -You must cause all Covered Code to which you contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. - -3.4. Intellectual Property Matters - -(a) Third Party Claims. -If You have knowledge that a party claims an intellectual property right in particular functionality or code (or its utilization under this License), you must include a text file with the source code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If you obtain such knowledge after You make Your Modification available as described in Section 3.2, You shall promptly modify the LEGAL file in all copies You make -available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. - -(b) Contributor APIs. -If Your Modification is an application programming interface and You own or control patents which are reasonably necessary to implement that API, you must also include this information in the LEGAL file. - -3.5. Required Notices. -You must duplicate the notice in Exhibit A in each file of the Source Code, and this License in any documentation for the Source Code, where You describe recipients' rights relating to Covered Code. If You created one or more Modification(s), You may add your name as a Contributor to the notice described in Exhibit A. If it is not possible to put such notice in a particular Source Code file due to its -structure, then you must include such notice in a location (such as a relevant directory file) where a user would be likely to look for such a notice. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or -liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of -warranty, support, indemnity or liability terms You offer. - -3.6. Distribution of Executable Versions. -You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You -describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code under a license of Your choice, which may contain terms different from this License, -provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. - -3.7. Larger Works. -You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - -If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. - -5. Application of this License. - -This License applies to code to which the Initial Developer has attached the notice in Exhibit A, and to related Covered Code. - -6. Versions of the License. - -6.1. New Versions. -Floris van den Berg may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. - -6.2. Effect of New Versions. -Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Floris van den Berg -No one other than Floris van den Berg has the right to modify the terms applicable to Covered Code created under this License. - -6.3. Derivative Works. -If you create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), you must (a) rename Your license so that the phrases "FreeImage", `FreeImage Public License", "FIPL", or any confusingly similar phrase do not appear anywhere in your license and (b) otherwise make it clear that your version of the license contains terms which differ from the FreeImage Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) - -7. DISCLAIMER OF WARRANTY. - -COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - -This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. - -9. LIMITATION OF LIABILITY. - -UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE -EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - -The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. - -11. MISCELLANEOUS. - -This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by Dutch law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in, the The Netherlands: (a) unless otherwise agreed in writing, all disputes relating to this License (excepting any dispute relating to intellectual property rights) shall be subject to final and binding arbitration, with the losing party paying all costs of arbitration; (b) any arbitration relating to this Agreement shall be held in Almelo, The Netherlands; and (c) any litigation relating to this Agreement shall be subject to the jurisdiction of the court of Almelo, The Netherlands with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys fees and expenses. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. - -12. RESPONSIBILITY FOR CLAIMS. - -Except in cases where another Contributor has failed to comply with Section 3.4, You are responsible for damages arising, directly or indirectly, out of Your utilization of rights under this License, based -on the number of copies of Covered Code you made available, the revenues you received from utilizing such rights, and other relevant factors. You agree to work with affected parties to distribute -responsibility on an equitable basis. - -EXHIBIT A. - -"The contents of this file are subject to the FreeImage Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://home.wxs.nl/~flvdberg/freeimage-license.txt - -Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License.
\ No newline at end of file diff --git a/libs/freeimage/Docs/license-gplv2.txt b/libs/freeimage/Docs/license-gplv2.txt deleted file mode 100644 index 49de39db4f..0000000000 --- a/libs/freeimage/Docs/license-gplv2.txt +++ /dev/null @@ -1,126 +0,0 @@ -GNU General Public License, version 2 (GPL-2.0) -[OSI Approved License] -The GNU General Public License (GPL-2.0) -Version 2, June 1991 - -Copyright (C) 1989, 1991 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - -Preamble - -The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. - -To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. - -Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. - -Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and modification follow. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. - -1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. - -You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. - - c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. - -3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. - -If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. - -5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. - -6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. - -This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - -8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. - -9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. - -10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - -NO WARRANTY - -11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - - One line to give the program's name and a brief idea of what it does. - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. - - signature of Ty Coon, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. diff --git a/libs/freeimage/Docs/license-gplv3.txt b/libs/freeimage/Docs/license-gplv3.txt deleted file mode 100644 index 5190153fdf..0000000000 --- a/libs/freeimage/Docs/license-gplv3.txt +++ /dev/null @@ -1,228 +0,0 @@ -GNU General Public License, version 3 (GPL-3.0) -[OSI Approved License] -GNU GENERAL PUBLIC LICENSE - -Version 3, 29 June 2007 - -Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - -Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -Preamble - -The GNU General Public License is a free, copyleft license for software and other kinds of works. - -The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - -To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. - -For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. - -Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. - -Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. - -The precise terms and conditions for copying, distribution and modification follow. -TERMS AND CONDITIONS -0. Definitions. - -“This License†refers to version 3 of the GNU General Public License. - -“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. - -“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. - -To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. - -A “covered work†means either the unmodified Program or a work based on the Program. - -To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. - -To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. - -An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. -1. Source Code. - -The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. - -A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. - -The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. - -The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. - -The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. - -The Corresponding Source for a work in source code form is that same work. -2. Basic Permissions. - -All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. - -You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. - -Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. -3. Protecting Users' Legal Rights From Anti-Circumvention Law. - -No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. - -When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. -4. Conveying Verbatim Copies. - -You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. - -You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. -5. Conveying Modified Source Versions. - -You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified it, and giving a relevant date. - b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. - c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. - d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. - -A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. -6. Conveying Non-Source Forms. - -You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: - - a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. - b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. - c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. - d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. - e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. - -A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. - -A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. - -“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. - -If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). - -The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. - -Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. -7. Additional Terms. - -“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. - -Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or - b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or - c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or - d) Limiting the use for publicity purposes of names of licensors or authors of the material; or - e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or - f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. - -All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. - -If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. -8. Termination. - -You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). - -However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. - -Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. -9. Acceptance Not Required for Having Copies. - -You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. -10. Automatic Licensing of Downstream Recipients. - -Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. - -An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. -11. Patents. - -A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. - -A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. - -In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. - -If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. - -A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. -12. No Surrender of Others' Freedom. - -If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. -13. Use with the GNU Affero General Public License. - -Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. -14. Revised Versions of this License. - -The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. - -If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. - -Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. -15. Disclaimer of Warranty. - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. -16. Limitation of Liability. - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -17. Interpretation of Sections 15 and 16. - -If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. - -END OF TERMS AND CONDITIONS -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright†line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about boxâ€. - -You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer†for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>. - -The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index a384fadba8..cbb1072dc5 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,5570 +6,7166 @@ Changelog -Version 7.33.0 (13 Oct 2013) +Version 7.60.0 (15 May 2018) -Daniel Stenberg (13 Oct 2013) -- RELEASE-NOTES: synced with 92cf6141ed0de +Daniel Stenberg (15 May 2018) +- RELEASE-NOTES: 7.60.0 release -- curl: fix --oauth2-bearer in the --help output - - After the option rename in 5df04bfafd1 +- THANKS: added people from the curl 7.60.0 release -- OpenSSL: improve the grammar of the language in 39beaa5ffbcc +- docs/libcurl/index.html: removed + + The HTML files are long gone from the dist, now remove the last HTML + file pointing to those missing files. - Reported-by: Petr Pisar + d -- [Andrej E Baranov brought this change] +- [steini2000 brought this change] - OpenSSL: use failf() when subjectAltName mismatches + http2: remove unused variable - Write to CURLOPT_ERRORBUFFER information about mismatch alternative - certificate subject names. + Closes #2570 + +- [steini2000 brought this change] + + http2: use easy handle of stream for logging + +- gcc: disable picky gcc-8 function pointer warnings in two places - Signed-off-by: Andrej E Baranov <admin@andrej-andb.ru> + Reported-by: Rikard Falkeborn + Bug: #2560 + Closes #2569 -- curl: rename --bearer to --oauth2-bearer +- http2: use the correct function pointer typedef - The option '--bearer' might be slightly ambiguous in name. It doesn't - create any conflict that I am aware of at the moment, however, OAUTH v2 - is not the only authentication mechanism which uses "bearer" tokens. + Fixes gcc-8 picky compiler warnings + Reported-by: Rikard Falkeborn + Bug: #2560 + Closes #2568 + +- CODE_STYLE: mention return w/o parens, but sizeof with - Reported-by: Kyle L. Huff - URL: http://curl.haxx.se/mail/lib-2013-10/0064.html + ... and remove the github markdown syntax so that it renders better on + the web site. Also, don't use back-ticks inlined to allow the CSS to + highlight source code better. -- [Kamil Dudka brought this change] +- [Rikard Falkeborn brought this change] - ssh: improve the logic for detecting blocking direction + examples: Fix format specifiers - This fixes a regression introduced by commit 0feeab78 limiting the speed - of SCP upload to 16384 B/s on a fast connection (such as localhost). - -Dan Fandrich (12 Oct 2013) -- Fixed typo in Makefile.inc that left http2.h out of the tar ball + Closes #2561 -Daniel Stenberg (11 Oct 2013) -- [Heinrich Schaefer brought this change] +- [Rikard Falkeborn brought this change] - minor fix in doc + tool: Fix format specifiers -- [Gisle Vanem brought this change] +- [Rikard Falkeborn brought this change] - curl_setup_once: fix errno access for lwip on Windows - - lib/curl_setup_once.h assumed lwIP on Windows uses 'SetLastError()' to - set network errors. It doesn't; it uses 'errno'. + ntlm: Fix format specifiers -- test1239: verify 4cd444e01ad and the simulated 304 response +- [Rikard Falkeborn brought this change] -- [Derek Higgins brought this change] + tests: Fix format specifiers - HTTP: Output http response 304 when modified time is too old - - When using the -w '%{http_code}' flag and simulating a Not Modified then - 304 should be output. +- [Rikard Falkeborn brought this change] -- contributors: helper script to dig out contributors from git + lib: Fix format specifiers -- RELEASE-NOTES: add twos refs to bug reports +- contributors.sh: use "on github", not at -- RELEASE-NOTES: synced with 173160c0d068 +- http2: getsock fix for uploads + + When there's an upload in progress, make sure to wait for the socket to + become writable. + + Detected-by: steini2000 on github + Bug: #2520 + Closes #2567 -Nick Zitzmann (2 Oct 2013) -- darwinssl: block TLS_RSA_WITH_NULL_SHA256 cipher +- pingpong: fix response cache memcpy overflow - Credit (for catching a cipher I forgot to add to the blocked ciphers list): - https://www.ssllabs.com/ssltest/viewMyClient.html + Response data for a handle with a large buffer might be cached and then + used with the "closure" handle when it has a smaller buffer and then the + larger cache will be copied and overflow the new smaller heap based + buffer. + + Reported-by: Dario Weisser + CVE: CVE-2018-1000300 + Bug: https://curl.haxx.se/docs/adv_2018-82c2.html -Daniel Stenberg (2 Oct 2013) -- OpenSSL: acknowledge CURLOPT_SSL_VERIFYHOST without VERIFYPEER +- http: restore buffer pointer when bad response-line is parsed + + ... leaving the k->str could lead to buffer over-reads later on. - Setting only CURLOPT_SSL_VERIFYHOST without CURLOPT_SSL_VERIFYPEER set - should still verify that the host name fields in the server certificate - is fine or return failure. + CVE: CVE-2018-1000301 + Assisted-by: Max Dymond - Bug: http://curl.haxx.se/mail/lib-2013-10/0002.html - Reported-by: Ishan SinghLevett + Detected by OSS-Fuzz. + Bug: https://curl.haxx.se/docs/adv_2018-b138.html + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7105 -- KNOWN_BUGS: #84: CURLINFO_SSL_VERIFYRESULT +Patrick Monnerat (13 May 2018) +- cookies: do not take cookie name as a parameter - CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS - backends and not for any other! + RFC 6265 section 4.2.1 does not set restrictions on cookie names. + This is a follow-up to commit 7f7fcd0. + Also explicitly check proper syntax of cookie name/value pair. + + New test 1155 checks that cookie names are not reserved words. + + Reported-By: anshnd at github + Fixes #2564 + Closes #2566 -- [François Charlier brought this change] +Daniel Stenberg (12 May 2018) +- smb: reject negative file sizes + + Assisted-by: Max Dymond + + Detected by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8245 - xattr: add support for FreeBSD xattr API +- setup_transfer: deal with both sockets being -1 + + Detected by Coverity; CID 1435559. Follow-up to f8d608f38d00. It would + index the array with -1 if neither index was a socket. -- curl_easy_setopt.3: slight clarification of SEEKFUNCTION +- travis: add build using NSS + + Closes #2558 -Steve Holme (29 Sep 2013) -- tests: Fixed typos from commit 25a0c96a494297 +- [Sunny Purushe brought this change] -- tests: Updated email addresses in SMTP tests following recent changes + openssl: change FILE ops to BIO ops + + To make builds with VS2015 work. Recent changes in VS2015 _IOB_ENTRIES + handling is causing problems. This fix changes the OpenSSL backend code + to use BIO functions instead of FILE I/O functions to circumvent those + problems. + + Closes #2512 -- test909: Removed custom EHLO response after recent changes +- travis: add a build using WolfSSL + + Assisted-by: Dan Fandrich - ...as it is no longer required following capability and authentication - changes and is now causing problems following commit 49341628b50007 as - the test number is obtained from the client address in the EHLO. + Closes #2528 -- ftpserver.pl: Fixed compilation error from commit 49341628b50007 +- RELEASE-NOTES: typo -- ftpserver.pl: Moved specifying the test number from the RCPT address +- RELEASE-NOTES: synced + +- [Daniel Gustafsson brought this change] + + URLs: fix one more http url - ...to the client address as this frees the RCPT strings to contain - just an email address and by passing the test number into curl as the - client address remains consistent with POP3 and IMAP tests as they are - specified in the URL. + This file wasn't included in commit 4af40b3646d3b09 which updated all + haxx.se http urls to https. The file was committed prior to that update, + but may have been merged after it and hence didn't get updated. + + Closes #2550 -- ftpserver.pl: Added unwanted argument check to SMTP DATA command handler +- github/lock: auto-lock closed issues after 90 days of inactivity -Daniel Stenberg (29 Sep 2013) -- getinmemory: remove a comment +- vtls: fix missing commas - The comment mentioned the need to free the data, but the example already - does that free + follow-up to e66cca046cef -- postinmemory: new example +- vtls: use unified "supports" bitfield member in backends - This is similar to getinmemory.c but with an initial POST. + ... instead of previous separate struct fields, to make it easier to + extend and change individual backends without having to modify them all. - Combined-by: Ulf Samuelsson + closes #2547 -- win32: fix Visual Studio 2010 build with WINVER >= 0x600 +- transfer: don't unset writesockfd on setup of multiplexed conns - If no WINVER and/or _WIN32_IWNNT define was set, the Windows platform - SDK often defaults to high value, e.g. 0x601 (whoch may probably depend - on the Windows version being used, in my case Windows 7). + Curl_setup_transfer() can be called to setup a new individual transfer + over a multiplexed connection so it shouldn't unset writesockfd. - If WINVER >= 0x600 then winsock2.h includes some defines for WSAPoll(), - e.g. POLLIN, POLLPRI, POLLOUT etc. These defines clash with cURL's - lib/select.h. + Bug: #2520 + Closes #2549 + +- [Frank Gevaerts brought this change] + + configure: put CURLDEBUG and DEBUGBUILD in lib/curl_config.h - Make sure HAVE_STRUCT_POLLFD is defined then. + They are removed from the compiler flags. - Bug: http://curl.haxx.se/bug/view.cgi?id=1282 - Reported-by: "kdekker" - Patch-by: Marcel Raad - -Steve Holme (28 Sep 2013) -- ssluse.c: Fixed compilation warnings when ENGINE not supported + This ensures that make dependency tracking will force a rebuild whenever + configure --enable-debug or --enable-curldebug changes. - The function "ssl_ui_reader" was declared but never referenced - The function "ssl_ui_writer" was declared but never referenced + Closes #2548 -Daniel Stenberg (27 Sep 2013) -- configure: use icc options without space +- http: don't set the "rewind" flag when not uploading anything - The latest version(s) of the icc compiler no longer accept the extra - space in the -we (warning enable), -wd (warning disable), etc. + It triggers an assert. - Reported-by: Elmira A Semenova - Bug: http://curl.haxx.se/mail/lib-2013-09/0182.html + Detected by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8144 + Closes #2546 -Steve Holme (25 Sep 2013) -- imap: Added clarification to the code about odd continuation responses - -- ftp.c: Fixed compilation warning +- travis: add an mbedtls build - There is an implicit conversion from "unsigned long" to "long" + Closes #2531 -- sasl: Centralised the authentication mechanism strings +- configure: only check for CA bundle for file-using SSL backends + + When only building with SSL backends that don't use the CA bundle file + (by default), skip the check. - Moved the standard SASL mechanism strings into curl_sasl.h rather than - hard coding the same values over and over again in the protocols that - use SASL authentication. + Fixes #2543 + Fixes #2180 + Closes #2545 + +- ssh-libssh.c: fix left shift compiler warning - For more information about the mechanism strings see: + ssh-libssh.c:2429:21: warning: result of '1 << 31' requires 33 bits to + represent, but 'int' only has 32 bits [-Wshift-overflow=] - http://www.iana.org/assignments/sasl-mechanisms + 'len' will never be that big anyway so I converted the run-time check to + a regular assert. -Daniel Stenberg (23 Sep 2013) -- RELEASE-NOTES: added recent contributors missing +- [Stephan Mühlstrasser brought this change] -Steve Holme (23 Sep 2013) -- test906: Fixed type-2 response + URL: fix ASCII dependency in strcpy_url and strlen_url + + Commit 3c630f9b0af097663a64e5c875c580aa9808a92b partially reverted the + changes from commit dd7521bcc1b7a6fcb53c31f9bd1192fcc884bd56 because of + the problem that strcpy_url() was modified unilaterally without also + modifying strlen_url(). As a consequence strcpy_url() was again + depending on ASCII encoding. + + This change fixes strlen_url() and strcpy_url() in parallel to use a + common host-encoding independent criterion for deciding whether an URL + character must be %-escaped. + + Closes #2535 -- test915: Corrected test number from commit 22bccb0edaf041 +- [Denis Ollier brought this change] -- test906: Fixed type-1 message not handled error + docs: remove extraneous commas in man pages - ...from commit f81d1e16664976 due to copy paste error. + Closes #2544 -- tests: Added SMTP AUTH NTLM test +- RELEASE-NOTES: synced -- tests: Added SMTP multiple and invalid --mail-rcpt test +- Revert "TODO: remove configure --disable-pthreads" + + This reverts commit d5d683a97f9765bddfd964fe32e137aa6e703ed3. + + --disable-pthreads can be used to disable pthreads and get the threaded + resolver to use the windows threading when building with mingw. -- tests: Added SMTP multiple --mail-rcpt test +- vtls: don't define MD5_DIGEST_LENGTH for wolfssl + + ... as it defines it (too) -- tests: Added SMTP invalid --mail-rcpt test +- TODO: remove configure --disable-pthreads -- tests: Regrouping of SMTP tests +Jay Satiro (2 May 2018) +- [David Garske brought this change] -Daniel Stenberg (22 Sep 2013) -- [Benoit Sigoure brought this change] + wolfssl: Fix non-blocking connect + + Closes https://github.com/curl/curl/pull/2542 - test1112: Increase the timeout from 7s to 16s +Daniel Stenberg (30 Apr 2018) +- CURLOPT_URL.3: add ENCODING section [ci skip] - As someone reported on the mailing list a while back, the hard-coded - arbitrary timeout of 7s in test 1112 is not sufficient in some build - environments. At Arista Networks we build and test curl as part of our - automated build system, and we've run into this timeout 170 times so - far. Our build servers are typically quite busy building and testing a - lot of code in parallel, so despite being beefy machines with 32 cores - and 128GB of RAM we still hit this 7s timeout regularly. + Feedback-by: Michael Kilburn + +- KNOWN_BUGS: Client cert with Issuer DN differs between backends - URL: http://curl.haxx.se/mail/lib-2010-02/0200.html + Closes #1411 -Steve Holme (22 Sep 2013) -- tests: Fixed smtp rcpt to addresses +- KNOWN_BUGS: Passive transfer tries only one IP address + + Closes #1508 + +- KNOWN_BUGS: --upload-file . hang if delay in STDIN + + Closes #2051 -- ftpserver.pl: Expanded the SMTP RCPT handler to validate TO addresses +- KNOWN_BUGS: Connection information when using TCP Fast Open - RCPT_smtp() will now check for a correctly formatted TO address which - allows for invalid recipient addresses to be added. + Closes #1332 -- ftpserver.pl: Added cURL SMTP server detection to HELO command handler +- travis: enable libssh2 on both macos and Linux + + It seems to not be detected by default anymore (which is a bug I + believe) - As curl will send a HELO command after an negative EHLO response, added - the same detection from commit b07709f7417c3e to the HELO handler to - ensure the test server is identified correctly and an upload isn't - performed. + Closes #2541 -- ftpserver.pl: Corrected response code for successful RCPT command +- TODO: Support the clienthello extension + + Closes #2299 -- ftpserver.pl: Moved invalid RCPT TO: address detection to RCPT handler +- TODO: CLOEXEC - Rather than detecting the TO address as missing in the DATA handler, - moved the detection to the RCPT command handler where an error response - can be generated. + Closes #2252 -- RELEASE-NOTES: Corrected missed addition +- tests: provide 'manual' as a feature to optionally require + + ... and make test 1026 rely on that feature so that --disable-manual + builds don't cause test failures. - Somehow commit 60a20461629fda missed the last item in the sync list - even though I'm sure I added it during editing. + Reported-by: Max Dymond and Anders Roxell + Fixes #2533 + Closes #2540 + +- CURLINFO_PROTOCOL.3: mention the existing defined names -- RELEASE-NOTES: Synced with 6dd8bd8d2f9729 +Jay Satiro (27 Apr 2018) +- [Daniel Gustafsson brought this change] -- curl.1: Added information about optional login options to --user in manpage + cookies: remove unused macro - Added missing information, from curl 7.31.0, regarding the use of the - optional login options that may be specified as part of --user. + Commit 2bc230de63 made the macro MAX_COOKIE_LINE_TXT become unused, + so remove as it's not part of the published API. - For example: + Closes https://github.com/curl/curl/pull/2537 + +Daniel Stenberg (27 Apr 2018) +- [Daniel Gustafsson brought this change] + + checksrc: force indentation of lines after an else - --user 'user:password;auth=NTLM' in IMAP, POP3 and SMTP protocols. + This extends the INDENTATION case to also handle 'else' statements + and require proper indentation on the following line. Also fixes the + offending cases found in the codebase. + + Closes #2532 -- ftpserver.pl: Moved cURL SMTP server detection into EHLO command handler +- http2: fix null pointer dereference in http2_connisdead - Moved the special SMTP server detection code from the DATA command - handler, which happens further down the operation chain after EHLO, - MAIL and RCPT commands, to the EHLO command as it is the first command - to be generated by a SMTP operation as well as containing the special - "verifiedserver" string from the URL. + This function can get called on a connection that isn't setup enough to + have the 'recv_underlying' function pointer initialized so it would try + to call the NULL pointer. - This not only makes it easier and quicker to detect but also means that - cURL doesn't need to specify "verifiedserver" as --mail-from and - --mail-rcpt arguments. + Reported-by: Dario Weisser - More importantly, this also makes the upcoming verification changes to - the RCPT handler easier to implement. + Follow-up to db1b2c7fe9b093f8 (never shipped in a release) + Closes #2536 -Daniel Stenberg (21 Sep 2013) -- openssl: use correct port number in error message +- http2: get rid of another strstr() - In ossl_connect_step2() when the "Unknown SSL protocol error" occurs, it - would output the local port number instead of the remote one which - showed when doing SSL over a proxy (but with the correct remote host - name). As libcurl only speaks SSL to the remote we know it is the remote - port. + Follow-up to 1514c44655e12e: replace another strstr() call done on a + buffer that might not be zero terminated - with a memchr() call, even if + we know the substring will be found. - Bug: http://curl.haxx.se/bug/view.cgi?id=1281 - Reported-by: Gordon Marler - -- test1415: adjusted to work for 32bit time_t + Assisted-by: Max Dymond - The libcurl date parser returns INT_MAX for all dates > 2037 so this - test is now made to use 2037 instead of 2038 to work the same for both - 32bit and 64bit time_t systems. - -Steve Holme (21 Sep 2013) -- tests: Reworked existing SMTP tests to be single recipient based + Detected by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8021 - ...in preparation of upcoming multiple recipient tests. + Closes #2534 -- ftpserver.pl: Corrected SMTP QUIT response to be more realistic +- cyassl: adapt to libraries without TLS 1.0 support built-in + + WolfSSL doesn't enable it by default anymore -Daniel Stenberg (20 Sep 2013) -- curl_easy_setopt.3: clarify that TIMEOUT and TIMEOUT_MS set the same value +- configure: provide --with-wolfssl as an alias for --with-cyassl -- [Kim Vandry brought this change] +- RELEASE-NOTES: synced - Documented --dns-* options in curl manpage +- [Daniel Gustafsson brought this change] -Steve Holme (20 Sep 2013) -- pop3: Added basic SASL XOAUTH2 support + os400.c: fix ASSIGNWITHINCONDITION checksrc warnings - Added the ability to use an XOAUTH2 bearer token [RFC6750] with POP3 for - authentication using RFC6749 "OAuth 2.0 Authorization Framework". + All occurrences of assignment within conditional expression in + os400sys.c rewritten into two steps: first assignment and then the check + on the success of the assignment. Also adjust related incorrect brace + positions to match project indentation style. - The bearer token is expected to be valid for the user specified in - conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has - an advertised auth mechanism of "XOAUTH2", the user and access token are - formatted as a base64 encoded string and sent to the server as - "AUTH XOAUTH2 <bearer token>". - -- curl: Added clarification to the --mail options in the --help output + This was spurred by seeing "if((inp = input_token))", but while in there + all warnings were fixed. - ... that these options apply to SMTP only. - -- ftpserver.pl: Moved SMTP RCPT response text into command handler + There should be no functional change from these changes. + + Closes #2525 -- tests: Added SMTP invalid --mail-from test +- [Daniel Gustafsson brought this change] -Nick Zitzmann (19 Sep 2013) -- darwinssl: enable BEAST workaround on iOS 7 & later + cookies: ensure that we have cookies before writing jar - iOS 7 finally added the option to enable 1/n-1 when using TLS 1.0 - and a CBC cipher, so we now always turn that on unless the user - manually turns it off using CURLSSLOPT_ALLOW_BEAST. + The jar should be written iff there are cookies, so ensure that we still + have cookies after expiration to avoid creating an empty file. - It appears Apple also added some new PSK ciphers, but no interface to - use them yet, so we at least support printing them if we find them. + Closes #2529 -Steve Holme (19 Sep 2013) -- tests: Updated SMTP AUTH tests to use the new AUTH directive +- strcpy_url: only %-encode values >= 0x80 - ...rather than specify a customised EHLO response. - -- tests: Corrected test913 as the QUIT response is received - -- tests: Added SMTP large message SIZE test - -- ftpserver.pl: Updated email regex from commit 98f7ca7e971006 + OSS-Fuzz detected - ...to not be as strict as it was rejecting valid numeric email - addresses. - -- tests: Fixed smtp mail from addresses + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8000 + + Broke in dd7521bcc1b7 -- ftpserver.pl: Standardised CAPA and AUTH responses +- mime: avoid NULL pointer dereference risk + + Coverity detected, CID 1435120 + + Closes #2527 -- ftpserver.pl: Corrected POP3 QUIT reply to be more realistic +- [Stephan Mühlstrasser brought this change] -- runtests.pl: Fixed syntax error in commit c873375123343e + ctype: restore character classification for non-ASCII platforms - Possible unintended interpolation in string at line 796 - -- runtests.pl: Fixed smtp mail from address + With commit 4272a0b0fc49a1ac0ceab5c4a365c9f6ab8bf8e2 curl-speficic + character classification macros and functions were introduced in + curl_ctype.[ch] to avoid dependencies on the locale. This broke curl on + non-ASCII, e.g. EBCDIC platforms. This change restores the previous set + of character classification macros when CURL_DOES_CONVERSIONS is + defined. - Following changes to ftpserver.pl fixed the mail from address to be a - correctly formatted address otherwise the server response will be 501 - Invalid address. + Closes #2494 -- ftpserver.pl: Fixed syntax error in commit 98f7ca7e971006 +- ftplistparser: keep state between invokes - Can't modify constant item in scalar assignment line 779, near "0;" - -- ftpserver.pl: Expanded the SMTP MAIL handler to validate messages + Fixes FTP wildcard parsing when done over a number of read buffers. - MAIl_smtp() will now check for a correctly formatted FROM address as - well as the optional SIZE parameter comparing it against the server - capability when specified. - -Daniel Stenberg (17 Sep 2013) -- [YAMADA Yasuharu brought this change] - - cookies: add expiration + Regression from f786d1f14 - Implement: Expired Cookies These following situation, curl removes - cookie(s) from struct CookieInfo if the cookie expired. - - Curl_cookie_add() - - Curl_cookie_getlist() - - cookie_output() + Reported-by: wncboy on github + Fixes #2445 + Closes #2526 -Steve Holme (17 Sep 2013) -- ftpserver.pl: Corrected response code for successful MAIL command +- examples/http2-upload: expand buffer to avoid silly warning + + http2-upload.c:135:44: error: ‘%02d’ directive output may be truncated + writing between 2 and 11 bytes into a region of size between 8 and 17 -- ftpserver.pl: Moved SMTP MAIL handler into own function +- examples/sftpuploadresume: typecast fseek argument to long + + /docs/examples/sftpuploadresume.c:102:12: warning: conversion to 'long + int' from 'curl_off_t {aka long long int}' may alter its value -- dns: fix compilation with MinGW from commit df69440d05f113 +- Revert "ftplistparser: keep state between invokes" - Avoid 'interface' literal that some MinGW versions define as a macro + This reverts commit abbc8457d85aca74b7cfda1d394b0844932b2934. - Additionally, corrected some very, very minor coding style errors. + Caused fuzzer problems on travis not seen when this was a PR! -- tests: Fixed test 1406 following recent changes in ftpserver.pl +- Curl_memchr: zero length input can't match - By default the mail server doesn't send the SIZE capability but instead - it has to be specified as a supported capability. - -- tests: Added test for SMTP SIZE capability - -- ftpserver.pl: Added the ability to include spaces in capabilities + Avoids undefined behavior. - For example: + Reported-by: Geeknik Labs + +- ftplistparser: keep state between invokes - CAPA "SIZE 1048576" 8BITMIME BINARYMIME + Fixes FTP wildcard parsing when doing over a number of read buffers. - will populate the capabilities list with the following in: + Regression from f786d1f14 - SIZE 1048576 - 8BITMIME - BINARYMIME - -- ftpserver.pl: Corrected response code for successful SMTP QUIT command + Reported-by: wncboy on github + Fixes #2445 + Closes #2519 -- ftpserver.pl: Fixed syntax error in commit 33c1f2876b9029 +- ftplistparser: renamed some members and variables - Can't modify constant item in postincrement line 727, near "i++" + ... to make them better spell out what they're for. -- ftpserver.pl: Added CAPA & AUTH directive support to the SMTP EHLO handler +- RELEASE-NOTES: synced -- ftpserver.pl: Fixed SMTP QUIT handler from dadc495540946e +- [Christian Schmitz brought this change] -- ftpserver.pl: Moved SMTP EHLO and QUIT handlers in own functions + curl_global_sslset: always provide available backends + + Closes #2499 -- ftpserver.pl: Added support for SMTP HELO command +- http2: convert an assert to run-time check + + Fuzzing has proven we can reach code in on_frame_recv with status_code + not having been set, so let's detect that in run-time (instead of with + assert) and error error accordingly. - ...and updated test902 as explicit HELO response is no longer required. + (This should no longer happen with the latest nghttp2) + + Detected by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7903 + Closes #2514 + +- curl.1: clarify that options and URLs can be mixed + + Fixes #2515 + Closes #2517 -- ftpserver.pl: Added mailbox check to IMAP SELECT handler +Jay Satiro (23 Apr 2018) +- [Archangel_SDY brought this change] -- ftpserver.pl: Corrected invalid user details check + CURLOPT_SSLCERT.3: improve WinSSL-specific usage info + + Ref: https://github.com/curl/curl/pull/2376#issuecomment-381858780 - ...in both the IMAP LOGIN and POP3 PASS handlers introduced in commit - 187ac693744949 and 84ad1569e5fc93 respectively. + Closes https://github.com/curl/curl/pull/2504 -- ftpserver.pl: Moved IMAP LOGIN handler into own function +- [Archangel_SDY brought this change] -- ftpserver.pl: Moved POP3 USER and PASS handlers into own functions + schannel: fix build error on targets <= XP + + - Use CRYPT_STRING_HEX instead of CRYPT_STRING_HEXRAW since XP doesn't + support the latter. + + Ref: https://github.com/curl/curl/pull/2376#issuecomment-382153668 + + Closes https://github.com/curl/curl/pull/2504 -- ftpserver.pl: Corrected invalid argument check in POP3 TOP handler +Daniel Stenberg (23 Apr 2018) +- Revert "ftplistparser: keep state between invokes" - ...which was accidentally introduced in commit 4d6ef6297ae9b6. + This reverts commit 8fb78f9ddc6d858d630600059b8ad84a80892fd9. + + Unfortunately this fix introduces memory leaks I've not been able to fix + in several days. Reverting this for now to get the leaks fixed. -- ftpserver.pl: Added capability prerequisite for extended POP3 commands +Jay Satiro (21 Apr 2018) +- tool_help: clarify --max-time unit of time is seconds + + Before: + -m, --max-time <time> Maximum time allowed for the transfer + + After: + -m, --max-time <seconds> Maximum time allowed for the transfer -- tests: Updated descriptions to be more meaningful +Daniel Stenberg (20 Apr 2018) +- http2: handle GOAWAY properly + + When receiving REFUSED_STREAM, mark the connection for close and retry + streams accordingly on another/fresh connection. + + Reported-by: Terry Wu + Fixes #2416 + Fixes #1618 + Closes #2510 -- ftpserver.pl: Added support for IMAP NOOP command +- http2: clear the "drain counter" when a stream is closed + + This fixes the notorious "httpc->drain_total >= data->state.drain" + assert. + + Reported-by: Anders Bakken + + Fixes #1680 + Closes #2509 -- imap: Fixed response check for NOOP command +- http2: avoid strstr() on data not zero terminated + + It's not strictly clear if the API contract allows us to call strstr() + on a string that isn't zero terminated even when we know it will find + the substring, and clang's ASAN check dislikes us for it. + + Also added a check of the return code in case it fails, even if I can't + think of a situation how that can trigger. + + Detected by OSS-Fuzz + Closes #2513 + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7760 -- tests: Updated descriptions to be more meaningful +- [Stephan Mühlstrasser brought this change] -Daniel Stenberg (13 Sep 2013) -- curl.1: detail how short/long options work + openssl: fix subjectAltName check on non-ASCII platforms - URL: http://curl.haxx.se/bug/view.cgi?id=1279 - Suggested-by: Jerry Krinock + Curl_cert_hostcheck operates with the host character set, therefore the + ASCII subjectAltName string retrieved with OpenSSL must be converted to + the host encoding before comparison. + + Closes #2493 -Steve Holme (13 Sep 2013) -- curl: Fixed usage of DNS options when not using c-ares resolver +Jay Satiro (20 Apr 2018) +- openssl: Add support for OpenSSL 1.1.1 verbose-mode trace messages + + - Support handling verbose-mode trace messages of type + SSL3_RT_INNER_CONTENT_TYPE, SSL3_MT_ENCRYPTED_EXTENSIONS, + SSL3_MT_END_OF_EARLY_DATA, SSL3_MT_KEY_UPDATE, SSL3_MT_NEXT_PROTO, + SSL3_MT_MESSAGE_HASH - Commit 32352ed6adddcb introduced various DNS options, however, these - would cause curl to exit with CURLE_NOT_BUILT_IN when c-ares wasn't - being used as the backend resolver even if the options weren't set - by the user. + Reported-by: iz8mbw@users.noreply.github.com - Additionally corrected some minor coding style errors from the same - commit. + Fixes https://github.com/curl/curl/issues/2403 -Daniel Stenberg (13 Sep 2013) -- curl_easy_setopt.3: mention RTMP URL quirks +Daniel Stenberg (19 Apr 2018) +- ftplistparser: keep state between invokes - URL: http://curl.haxx.se/bug/view.cgi?id=1278 - Reported-by: Gorilla Maguila + Regression from f786d1f14 + + Reported-by: wncboy on github + Fixes #2445 + Closes #2508 -- [Ben Greear brought this change] +- detect_proxy: only show proxy use if it had contents - curl: Add support for various DNS binding options. +- http2: handle on_begin_headers() called more than once - (Passed on to c-ares.) + This triggered an assert if called more than once in debug mode (and a + memory leak if not debug build). With the right sequence of HTTP/2 + headers incoming it can happen. - Allows something like this: + Detected by OSS-Fuzz - curl --dns-interface sta8 --dns-ipv4-addr 8.8.1.111 --interface sta8 \ - --localaddr 8.8.1.111 --dns-servers 8.8.8.1 www.google.com - - Signed-off-by: Ben Greear <greearb@candelatech.com> + Closes #2507 + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7764 -- [Kim Vandry brought this change] +Jay Satiro (18 Apr 2018) +- [Dan McNulty brought this change] - libcurl: New options to bind DNS to local interfaces or IP addresses + schannel: add support for CURLOPT_CAINFO + + - Move verify_certificate functionality in schannel.c into a new + file called schannel_verify.c. Additionally, some structure defintions + from schannel.c have been moved to schannel.h to allow them to be + used in schannel_verify.c. + + - Make verify_certificate functionality for Schannel available on + all versions of Windows instead of just Windows CE. verify_certificate + will be invoked on Windows CE or when the user specifies + CURLOPT_CAINFO and CURLOPT_SSL_VERIFYPEER. + + - In verify_certificate, create a custom certificate chain engine that + exclusively trusts the certificate store backed by the CURLOPT_CAINFO + file. + + - doc updates of --cacert/CAINFO support for schannel + + - Use CERT_NAME_SEARCH_ALL_NAMES_FLAG when invoking CertGetNameString + when available. This implements a TODO in schannel.c to improve + handling of multiple SANs in a certificate. In particular, all SANs + will now be searched instead of just the first name. + + - Update tool_operate.c to not search for the curl-ca-bundle.crt file + when using Schannel to maintain backward compatibility. Previously, + any curl-ca-bundle.crt file found in that search would have been + ignored by Schannel. But, with CAINFO support, the file found by + that search would have been used as the certificate store and + could cause issues for any users that have curl-ca-bundle.crt in + the search path. + + - Update url.c to not set the build time CURL_CA_BUNDLE if the selected + SSL backend is Schannel. We allow setting CA location for schannel + only when explicitly specified by the user via CURLOPT_CAINFO / + --cacert. + + - Add new test cases 3000 and 3001. These test cases check that the first + and last SAN, respectively, matches the connection hostname. New test + certificates have been added for these cases. For 3000, the certificate + prefix is Server-localhost-firstSAN and for 3001, the certificate + prefix is Server-localhost-secondSAN. + + - Remove TODO 15.2 (Add support for custom server certificate + validation), this commit addresses it. + + Closes https://github.com/curl/curl/pull/1325 -- libcurl.3: for multi interface connections are held in the multi handle +- schannel: fix warning + + - Fix warning 'integer from pointer without a cast' on 3rd arg in + CertOpenStore. The arg type HCRYPTPROV may be a pointer or integer + type of the same size. - ... and a few more cleanups/clarifications + Follow-up to e35b025. + + Caught by Marc's CI builds. -Steve Holme (12 Sep 2013) -- ftpserver.pl: Fixed missing comma from 7fd84b14d219b1 +- [Jakub Wilk brought this change] -- ftpserver.pl: Fixed variable error introduced in 7fd84b14d219b1 + docs: fix typos - Global symbol "$mailbox" requires explicit package name + Closes https://github.com/curl/curl/pull/2503 -- ftpserver.pl: Added support for UID command +Daniel Stenberg (17 Apr 2018) +- RELEASE-NOTES: synced -- ftpserver.pl: Added support for LSUB command +Jay Satiro (17 Apr 2018) +- [Kees Dekker brought this change] -- imap: Fixed response check for LSUB and UID commands + winbuild: Support custom devel paths for each dependency + + - Support custom devel paths for c-ares, mbedTLS, nghttp2, libSSH2, + OpenSSL and zlib. Respectively: CARES_PATH, MBEDTLS_PATH, + NGHTTP2_PATH, SSH2_PATH, SSL_PATH and ZLIB_PATH. + + - Use lib.exe for making the static library instead of link.exe /lib. + The latter is undocumented and could cause problems as noted in the + comments. + + - Remove a dangling URL that no longer worked. (I was not able to find + the IDN download at MSDN/microsoft.com, so it seems to be removed.) + + - Remove custom override for release-ssh2-ssl-dll-zlib configuration. + Nobody knows why it was there and as far as we can see is unnecessary. + + Closes https://github.com/curl/curl/pull/2474 -- ftpserver.pl: Added support for IMAP COPY command +Daniel Stenberg (17 Apr 2018) +- [Jess brought this change] -- ftpserver.pl: Added support for IMAP CLOSE and EXPUNGE commands + README.md: add backers and sponsors + + Closes #2484 -- ftpserver.pl: Added support for POP3 RSET command +- [Archangel_SDY brought this change] -- ftpserver.pl: Added the ability to remember what messages are deleted + schannel: add client certificate authentication - ...as this will be required for IMAP CLOSE and EXPUNGE commands as well - as the POP3 RSET command. + Users can now specify a client certificate in system certificates store + explicitly using expression like `--cert "CurrentUser\MY\<thumbprint>"` + + Closes #2376 + +Marcel Raad (16 Apr 2018) +- [toughengineer brought this change] -Daniel Stenberg (10 Sep 2013) -- NI_MAXSERV: remove all use of it + ntlm_sspi: fix authentication using Credential Manager - Solaris with the SunStudio Compiler is reportedly missing this define, - but as we're using it without any good reason on all the places it was - used I've now instead switched to just use sensible buffer sizes that - fit a 32 bit decimal number. Which also happens to be smaller than the - common NI_MAXSERV value which is 32 on most machines. + If you pass empty user/pass asking curl to use Windows Credential + Storage (as stated in the docs) and it has valid credentials for the + domain, e.g. + curl -v -u : --ntlm example.com + currently authentication fails. + This change fixes it by providing proper SPN string to the SSPI API + calls. - Bug: http://curl.haxx.se/bug/view.cgi?id=1277 - Reported-by: D.Flinkmann + Fixes https://github.com/curl/curl/issues/1622 + Closes https://github.com/curl/curl/pull/1660 -- http2: use the support HTTP2 draft version in the upgrade header +Daniel Stenberg (16 Apr 2018) +- configure: keep LD_LIBRARY_PATH changes local - ... instead of HTTP/2.0 to work fine with the nghttpx proxy/server. - -Steve Holme (10 Sep 2013) -- ldap.c: Fix compilation warning + ... only set it when we actually have to run tests to reduce its impact + on for example build commands etc. - warning: comparison between signed and unsigned integer expressions - -- [Jiri Hruska brought this change] - - imap/pop3/smtp: Speed up SSL connection initialization + Fixes #2490 + Closes #2492 - Don't wait for the next callback call (usually 1 second) before - continuing with protocol specific connection initialization. + Reported-by: Dmitry Mikhirev -- ldap.c: Corrected build error from commit 857f999353f333 +Marcel Raad (16 Apr 2018) +- urldata: make service names unconditional + + The ifdefs have become quite long. Also, the condition for the + definition of CURLOPT_SERVICE_NAME and for setting it from + CURLOPT_SERVICE_NAME have diverged. We will soon also need the two + options for NTLM, at least when using SSPI, for + https://github.com/curl/curl/pull/1660. + Just make the definitions unconditional to make that easier. + + Closes https://github.com/curl/curl/pull/2479 -- RELEASE-NOTES: Corrected duplicate in bfefe2400a16b8 +Daniel Stenberg (16 Apr 2018) +- test1148: tolerate progress updates better + + Fixes #2446 + Closes #2488 -- RELEASE-NOTES: Corrected typo from bfefe2400a16b8 +- [Christian Schmitz brought this change] -- RELEASE-NOTES: synced with 25c68903756d6b + ssh: show libSSH2 error code when closing fails + + Closes #2500 -Daniel Stenberg (10 Sep 2013) -- README.http2: explain nghttp2 a little +Jay Satiro (15 Apr 2018) +- [Daniel Gustafsson brought this change] -Steve Holme (9 Sep 2013) -- tests: Added test for POP3 TOP command + vauth: Fix typo + + Address various spellings of "credentials". + + Closes https://github.com/curl/curl/pull/2496 -- ftpserver.pl: Added support for POP3 TOP command +- [Dagobert Michelsen brought this change] -- tests: Added test for POP3 UIDL command + system.h: Add sparcv8plus to oracle/sunpro 32-bit detection + + With specific compiler options selecting the arch like -xarch=sparc on + newer compilers like Oracle Studio 12.4 there is no definition of + __sparcv8 but __sparcv8plus which means the V9 ISA, but limited to the + 32ÃŽÃÎñbit subset defined by the V8plus ISA specification, without the + Visual Instruction Set (VIS), and without other implementation-specific + ISA extensions. So it should be the same as __sparcv8. + + Closes https://github.com/curl/curl/pull/2491 -- ftpserver.pl: Added support for POP3 UIDL command +- [Daniel Gustafsson brought this change] -Daniel Stenberg (9 Sep 2013) -- http2: adjust to new nghttp2_pack_settings_payload proto + checksrc: Fix typo - This function was modified in nghttp2 git commit a1c3f89c72e51 + Fix typo in "semicolon" spelling and remove stray tab character. + + Closes https://github.com/curl/curl/pull/2498 + +- [Daniel Gustafsson brought this change] -Kamil Dudka (9 Sep 2013) -- url: handle abortion by read/write callbacks, too + all: Refactor malloc+memset to use calloc - Otherwise, the FTP protocol would unnecessarily hang 60 seconds if - aborted in the CURLOPT_HEADERFUNCTION callback. + When a zeroed out allocation is required, use calloc() rather than + malloc() followed by an explicit memset(). The result will be the + same, but using calloc() everywhere increases consistency in the + codebase and avoids the risk of subtle bugs when code is injected + between malloc and memset by accident. - Reported by: Tomas Mlcoch - Bug: https://bugzilla.redhat.com/1005686 + Closes https://github.com/curl/curl/pull/2497 -Daniel Stenberg (9 Sep 2013) -- ldap: fix the build for systems with ldap_url_parse() +Daniel Stenberg (12 Apr 2018) +- duphandle: make sure CURLOPT_RESOLVE is duplicated fine too - Make sure that the custom struct fields are only used by code that - doesn't use a struct defintion from the outside. + Verified in test 1502 now - Attempts to fix the problem introduced in 3dc6fc42bfc61b + Fixes #2485 + Closes #2486 + Reported-by: Ernst Sjöstrand -Steve Holme (9 Sep 2013) -- [Jiri Hruska brought this change] +- mailmap: add a monnerat fixup [ci skip] - pingpong: Check SSL library buffers for already read data +- proxy: show getenv proxy use in verbose output - Otherwise the connection can get stuck during various phases, waiting - for new data on the socket using select() etc., but it will never be - received as the data has already been read into SSL library. - -- imap: Fixed calculation of transfer when partial FETCH received + ... to aid debugging etc as it sometimes isn't immediately obvious why + curl uses or doesn't use a proxy. - The transfer size would be calculated incorrectly if the email contained - within the FETCH response, had been partially received by the pingpong - layer. As such the following, example output, would be seen if the - amount remaining was smaller than the amount received: + Inspired by #2477 - * Excess found in a non pipelined read: excess = 1394, size = 262, - maxdownload = 262, bytecount = 1374 - * transfer closed with -1112 bytes remaining to read + Closes #2480 + +- travis: build libpsl and make builds use it - Bug: http://curl.haxx.se/mail/lib-2013-08/0170.html - Reported-by: John Dunn + closes #2471 -- ftpserver.pl: Fixed empty array checks +- travis: bump to clang 6 and gcc 7 - ...from commits 28427b408326a1 and e8313697b6554b. + Extra-eye-on-this-by: Marcel Raad + + Closes #2478 -- ftpserver: Reworked AUTH support to allow for specifying the mechanisms +Marcel Raad (10 Apr 2018) +- travis: use trusty for coverage build - Renamed SUPPORTAUTH to AUTH and added support for specifying a list of - supported SASL mechanisms to return to the client. + This works now and precise is in the process of being decommissioned. - Additionally added the directive to the FILEFORMAT document. + Closes https://github.com/curl/curl/pull/2476 -- ftpserver: Reworked CAPA support to allow for specifying the capabilities +- lib: silence null-dereference warnings - Renamed SUPPORTCAPA to CAPA and added support for specifying a list of - supported capabilities to return to the client. + In debug mode, MingGW-w64's GCC 7.3 issues null-dereference warnings + when dereferencing pointers after DEBUGASSERT-ing that they are not + NULL. + Fix this by removing the DEBUGASSERTs. - Additionally added the directive to the FILEFORMAT document. + Suggested-by: Daniel Stenberg + Ref: https://github.com/curl/curl/pull/2463 + +- [Kees Dekker brought this change] -- ftpserver.pl: Corrected POP3 LIST as message numbers should be contiguous + winbuild: fix URL - The message numbers given in the LIST response are an index into the - list, which are only valid for the current session, rather than being a - unique message identifier. An index would only be missing from the LIST - response if a DELE command had been issued within the same session and - had not been committed by the end of session QUIT command. Once - committed the POP3 server will regenerate the message numbers in the - next session to be contiguous again. As such our LIST response should - list message numbers contiguously until we support a DELE command in the - same session. + Follow up on https://github.com/curl/curl/pull/2472. + Now using en-us instead of nl-nl as language code in the URL. - Should a POP3 user require the unique message ID for any or all - messages then they should use the extended UIDL command. This command - will be supported by the test ftpserver in an upcoming commit. + Closes https://github.com/curl/curl/pull/2475 -Daniel Stenberg (8 Sep 2013) -- [Clemens Gruber brought this change] +Daniel Stenberg (9 Apr 2018) +- [Kees Dekker brought this change] - curl_easy_pause: suggest one way to unpause + winbuild: updated the documentation + + The setenv command no longer exists and visual studio build prompts got + changed. Used Visual Studio 2015/2017 as reference. + + Closes #2472 -Steve Holme (8 Sep 2013) -- tests: Updated descriptions to be more meaningful +- test1136: fix cookie order after commit c990eadd1277 -- tests: Added test for POP3 NOOP command +- build: cleanup to fix clang warnings/errors + + unit1309 and vtls/gtls: error: arithmetic on a null pointer treated as a + cast from integer to pointer is a GNU extension + + Reported-by: Rikard Falkeborn + + Fixes #2466 + Closes #2468 -- ftpserver.pl: Added support for POP3 NOOP command +Jay Satiro (7 Apr 2018) +- examples/sftpuploadresmue: Fix Windows large file seek + + - Use _fseeki64 instead of fseek (long) to seek curl_off_t in Windows. + + - Use CURL_FORMAT_CURL_OFF_T specifier instead of %ld to print + curl_off_t. + + Caught by Marc's CI builds. -- ftpserver.pl: Fixed 'Use of uninitialized value $args in string ne' +Daniel Stenberg (7 Apr 2018) +- curl_setup: provide a CURL_SA_FAMILY_T type if none exists + + ... and use this type instead of 'sa_family_t' in the code since several + platforms don't have it. + + Closes #2463 -- tests: Added test for POP3 STAT command +- [Eric Gallager brought this change] -- ftpserver.pl: Added support for POP STAT command + build: add picky compiler warning flags for gcc 6 and 7 -- ftpserver.pl: Moved POP3 QUIT handler into own function +- configure: detect sa_family_t -- ftpserver.pl: Reordered the POP3 handlers to be alphabetical - - In preparation for additional POP3 tests, re-ordered the command - function defintions to be sorted alphabetically. +Jay Satiro (7 Apr 2018) +- [Stefan Agner brought this change] -- ftpserver.pl: Corrected misaligned indentation in POP3 handlers + tool_operate: Fix retry on FTP 4xx to ignore other protocols + + Only treat response code as FTP response codes in case the + protocol type is FTP. + + This fixes an issue where an HTTP download was treated as FTP + in case libcurl returned with 33. This happens when the + download has already finished and the server responses 416: + HTTP/1.1 416 Requested Range Not Satisfiable - Fixed incorrect indentation used in both the RETR_pop3 and LIST_pop3 - functions which was 5 and 9 characters rather than 4 and 8. + This should not be treated as an FTP error. + + Fixes #2464 + Closes #2465 -- tests: Added test for POP3 DELE command +Daniel Stenberg (6 Apr 2018) +- hash: calculate sizes with size_t instead of longs + + ... since they return size_t anyway! + + closes #2462 -unknown (7 Sep 2013) -- [Steve Holme brought this change] +- RELEASE-NOTES: synced - ftpserver.pl: Added support for POP3 DELE command +- [Jay Satiro brought this change] -Daniel Stenberg (7 Sep 2013) -- http2: include curl_memory.h + build-openssl.bat: Refer to VS2017 as VC14.1 instead of VC15 - Detected by test 1132 - -Nick Zitzmann (7 Sep 2013) -- http: fix build warning under LLVM + .. and do the same for build-wolfssl.bat. + + Because MS calls it VC14.1. - When building the code using LLVM Clang without NGHTTP2, I was getting - this warning: - ../lib/http.h:155:1: warning: empty struct is a GNU extension [-Wgnu] - Placing a dummy variable into the data structure silenced the warning. + Closes https://github.com/curl/curl/pull/2189 -Daniel Stenberg (7 Sep 2013) -- http2: actually init nghttp2 and send HTTP2-Settings properly +- [Kees Dekker brought this change] -- README.http2: how to use it best with the multi API? + winbuild: make the clean target work without build-type + + Due to the check in Makefile.vc and MakefileBuild.vc, no make call can + be invoked unless a build-type was specified. However, a clean target + only existed when a build type was specified. As a result, the clean + target was unreachable. Made clean target unconditional. + + Closes #2455 -- http2: first embryo toward Upgrade: +- [patelvivekv1993 brought this change] -- http: rename use_http_1_1 to use_http_1_1plus + build-openssl.bat: allow custom paths for VS and perl - Since it now actually says if 1.1 or a later version should be used. + Fixes #2430 + Closes #2457 -- configure: improve CURL_CHECK_COMPILER_PROTOTYPE_MISMATCH +- [Laurie Clark-Michalek brought this change] + + FTP: allow PASV on IPv6 connections when a proxy is being used + + In the situation of a client connecting to an FTP server using an IPv6 + tunnel proxy, the connection info will indicate that the connection is + IPv6. However, because the server behing the proxy is IPv4, it is + permissable to attempt PSV mode. In the case of the FTP server being + IPv4 only, EPSV will always fail, and with the current logic curl will + be unable to connect to the server, as the IPv6 fwdproxy causes curl to + think that EPSV is impossible. - The compiler test used a variable before it was assigned when it tried - to see how it acts on a mismatching prototype, which could cause a false - positive. + Closes #2432 -- [Petr PÃsaÅ™ brought this change] +- [Jon DeVree brought this change] - Pass password to OpenSSL engine by user interface + file: restore old behavior for file:////foo/bar URLs - Recent OpenSSL uses user interface abstraction to negotiate access to - private keys in the cryprographical engines. An OpenSSL application is - expected to implement the user interface. Otherwise a default one - provided by OpenSSL (interactive standard I/O) will be used and the - aplication will have no way how to pass a password to the engine. + curl 7.57.0 and up interpret this according to Appendix E.3.2 of RFC + 8089 but then returns an error saying this is unimplemented. This is + actually a regression in behavior on both Windows and Unix. - Longer-desc: http://curl.haxx.se/mail/lib-2013-08/0265.html - -- urlglob: improved error messages and column number on bad use + Before curl 7.57.0 this URL was treated as a path of "//foo/bar" and + then passed to the relevant OS API. This means that the behavior of this + case is actually OS dependent. - Introduce a convenience macro and keep of the column better so that it - can point out the offending column better. + The Unix path resolution rules say that the OS must handle swallowing + the extra "/" and so this path is the same as "/foo/bar" - Updated test 75 accordingly. - -- urlglob: avoid error code translation + The Windows path resolution rules say that this is a UNC path and + automatically handles the SMB access for the program. So curl on Windows + was already doing Appendix E.3.2 without any special code in curl. + + Regression - By using the correct values from the start we don't have to translate - them! + Closes #2438 -- urlglob: avoid NULL pointer dereference +- [Gaurav Malhotra brought this change] + + Revert "openssl: Don't add verify locations when verifypeer==0" + + This reverts commit dc85437736e1fc90e689bb1f6c51c8f1aa9430eb. - Thanks to clang-analyzer + libcurl (with the OpenSSL backend) performs server certificate verification + even if verifypeer == 0 and the verification result is available using + CURLINFO_SSL_VERIFYRESULT. The commit that is being reverted caused the + CURLINFO_SSL_VERIFYRESULT to not have useful information for the + verifypeer == 0 use case (it would always have + X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY). + + Closes #2451 -- [Gisle Vanem brought this change] +- [Wyatt O'Day brought this change] - http2: use correct include for snprintf + tls: fix mbedTLS 2.7.0 build + handle sha256 failures - Using the first little merge of nghttp2 into libcurl, I stumbeled on the - missing 'snprintf' in MSVCRT. Isn't this how we do it for other libcurl - files? I.e. use 'curl_msnprintf' and not 'snprintf' directly: + (mbedtls 2.70 compiled with MBEDTLS_DEPRECATED_REMOVED) + + Closes #2453 -- --data: mention CRLF treatment when reading from file +- [Lauri Kasanen brought this change] -- [Geoff Beier brought this change] + cookie: case-insensitive hashing for the domains + + closes #2458 - LDAP: fix bad free() when URL parsing failed +Patrick Monnerat (4 Apr 2018) +- cookie: fix and optimize 2nd top level domain name extraction - When an error occurs parsing an LDAP URL, The ludp->lud_attrs[i] entries - could be freed even though they sometimes point to data within an - allocated area. + This fixes a segfault occurring when a name of the (invalid) form "domain..tld" + is processed. - This change introduces a lud_attrs_dup[] array for the duplicated string - pointers, and it removes the unused lud_exts array. + test46 updated to cover this case. - Bug: http://curl.haxx.se/mail/lib-2013-08/0209.html - -Nick Zitzmann (5 Sep 2013) -- darwinssl: add support for PKCS#12 files for client authentication + Follow-up to commit c990ead. - I also documented the fact that the OpenSSL engine also supports them. + Ref: https://github.com/curl/curl/pull/2440 -Daniel Stenberg (5 Sep 2013) -- symbols: added HTTP2 symbols and sorted list +Daniel Stenberg (4 Apr 2018) +- openssl: provide defines for argument typecasts to build warning-free - CURL_HTTP_VERSION_2_0 and CURL_VERSION_HTTP2 are new + ... as OpenSSL >= 1.1.0 and libressl >= 2.7.0 use different argument types. -- configure: add HTTP2 as a curl-config --feature output - - Fixes the test 1014 failure +- [Bernard Spil brought this change] -- curl: unbreak --http1.0 again + openssl: fix build with LibreSSL 2.7 - I broke it in 2eabb7d590 - -- SASL: fix compiler warnings + - LibreSSL 2.7 implements (most of) OpenSSL 1.1 API - comparison between signed and unsigned integer expressions + Fixes #2319 + Closes #2447 + Closes #2448 - suggest parentheses around '&&' within '||' (twice) + Signed-off-by: Bernard Spil <brnrd@FreeBSD.org> -- curl: add --http1.1 and --http2.0 options +- [Lauri Kasanen brought this change] -- Curl_setopt: refuse CURL_HTTP_VERSION_2_0 if built without support + cookie: store cookies per top-level-domain-specific hash table + + This makes libcurl handle thousands of cookies much better and speedier. + + Closes #2440 -- http2: add http2.[ch] and add nghttp2 version output +- [Lauri Kasanen brought this change] -- curl -V: output HTTP2 as a feature if present + cookies: when reading from a file, only remove_expired once + + This drops the cookie load time for 8k cookies from 178ms to 15ms. + + Closes #2441 -- curl.h: add CURL_VERSION_HTTP2 as a feature +- test1148: set a fixed locale for the test + + ...as otherwise it might use a different decimal sign. - It isn't added as a separate protocol as HTTP2 will be done over HTTP:// - URLs that can be upgraded to HTTP2 if the server supports it as well. + Bug: #2436 + Reported-by: Oumph on github -Steve Holme (4 Sep 2013) -- imap/smtp: Fixed incorrect SASL mechanism selection with XOAUTH2 servers +Jay Satiro (31 Mar 2018) +- docs: fix CURLINFO_*_T examples use of CURL_FORMAT_CURL_OFF_T - XOAUTH2 would be selected in preference to LOGIN and PLAIN if the IMAP - or SMTP server advertised support for it even though a user's password - was supplied but bearer token wasn't. + - Put a percent sign before each CURL_FORMAT_CURL_OFF_T in printf. - Modified the selection logic so that XOAUTH2 will only be selected if - the server supports it and A) The curl user/libcurl programmer has - specifically asked for XOAUTH via the ;AUTH=XOAUTH login option or 2) - The bearer token is specified. Obviously if XOAUTH is asked for via - the login option but no token is specified the user will receive a - authentication failure which makes more sense than no known - authentication mechanisms supported! + For example "%" CURL_FORMAT_CURL_OFF_T becomes %lld or similar. + + Bug: https://curl.haxx.se/mail/lib-2018-03/0140.html + Reported-by: David L. + +Sergei Nikulov (27 Mar 2018) +- [MichaÅ‚ Janiszewski brought this change] -Daniel Stenberg (4 Sep 2013) -- curl.h: added CURL_HTTP_VERSION_2_0 + cmake: Add advapi32 as explicit link library for win32 + + ARM targets need advapi32 explicitly. - Initial library considerations documented in lib/README.http2 + Closes #2363 -- configure: added --with-nghttp2 +Daniel Stenberg (27 Mar 2018) +- TODO: connection cache sharing is now supporte -- acinclude: fix --without-ca-path when cross-compiling +Jay Satiro (26 Mar 2018) +- travis: enable apt retry on fail - The commit 7b074a460b64811 to CURL_CHECK_CA_BUNDLE in 7.31 (don't check - for paths when cross-compiling) causes --without-ca-path to no longer - works when cross-compiling, since ca and capath only ever get set to - "no" when not cross-compiling, I attach a patch that works for me. Also - in the cross-compilation case, no ca-path seems to be a better default - (IMVHO) than empty ca-path. + This is a workaround for an unsolved travis issue that is causing CI + instances to sporadically fail due to 'unable to connect' issues during + apt stage. - Bug: http://curl.haxx.se/bug/view.cgi?id=1273 - Patch-by: Stefan Neis + Ref: https://github.com/travis-ci/travis-ci/issues/8507 + Ref: https://github.com/travis-ci/travis-ci/issues/9112#issuecomment-376305909 -Steve Holme (2 Sep 2013) -- lib1512.c: Fixed compilation warning +Michael Kaufmann (26 Mar 2018) +- runtests.pl: fix warning 'use of uninitialized value' - An enumerated type is mixed with another type. + follow-up to a9a7b60 - ...as well as a small coding style error. + Closes #2428 -Guenter Knauf (1 Sep 2013) -- Killed warning 'res' might be used uninitialized. +Daniel Stenberg (24 Mar 2018) +- gitignore: ignore more generated files -Steve Holme (1 Sep 2013) -- url.c: Fixed compilation warning +- threaded resolver: track resolver time and set suitable timeout values - An enumerated type is mixed with another type - -- easy.c: Fixed compilation warning + In order to make curl_multi_timeout() return suitable "sleep" times even + when there's no socket to wait for while the name is being resolved in a + helper thread. - warning: `code' might be used uninitialized in this function - -Daniel Stenberg (31 Aug 2013) -- -x: rephrased the --proxy section somewhat + It will increases the timeouts as time passes. + + Closes #2419 -Steve Holme (31 Aug 2013) -- tests: Added test for IMAP CHECK command +- [Howard Chu brought this change] -- ftpserver.pl: Added support for the IMAP CHECK command + openldap: fix for NULL return from ldap_get_attribute_ber() + + Closes #2399 -Guenter Knauf (31 Aug 2013) -- Removed reference to krb4.c. +GitHub (22 Mar 2018) +- [Sergei Nikulov brought this change] -Steve Holme (31 Aug 2013) -- ftpserver.pl: Corrected flawed logic in commit 1ca6ed7b75cad0 + travis-ci: enable -Werror for CMake builds (#2418) -- imap: Fixed response check for EXPUNGE command +- [Sergei Nikulov brought this change] -- ftpserver.pl: Added argument check to IMAP command handlers + cmake: avoid warn-as-error during config checks (#2411) - Added BAD argument check to the following IMAP command handlers: + - Move the CURL_WERROR option processing after the configuration checks + to avoid failures in case of warnings during the configuration checks. - APPEND, STORE, LIST, EXAMINE, STATUS and SEARCH + This is a partial fix for #2358 -- ftpserver.pl: More whitespace corrections - - LIST_imap() had a second level of indentation at 9 characters and not 8. +- [Sergei Nikulov brought this change] -- ftpserver.pl: Small correction tidy up + timeval: remove compilation warning by casting (#2417) - Corrected some IMAP variable names and whitespace issues. + This is fixes #2358 -- [Kyle L. Huff brought this change] +Daniel Stenberg (22 Mar 2018) +- http2: read pending frames (including GOAWAY) in connection-check + + If a connection has received a GOAWAY frame while not being used, the + function now reads frames off the connection before trying to reuse it + to avoid reusing connections the server has told us not to use. + + Reported-by: Alex Baines + Fixes #1967 + Closes #2402 - docs: Added documentation for CURLOPT_BEARER +- [Bas van Schaik brought this change] -- [Kyle L. Huff brought this change] + CI: add lgtm.yml for tweaking lgtm.com analysis + + Closes #2414 - curl.1: Add usage of '--bearer' option +- CURLINFO_SSL_VERIFYRESULT.3: fix the example, add some text + + Reported-by: Michal Trybus + + Fixes #2400 -- tests: Added tests for IMAP CREATE, DELETE and RENAME commands +- TODO: expand ~/ in config files + + Closes #2317 -Daniel Stenberg (30 Aug 2013) -- ftpserver: Bareword "to_mailbox" not allowed +- cookie.d: mention that "-" as filename means stdin - Added missing $ + Reported-by: Dongliang Mu + Fixes #2410 -Steve Holme (30 Aug 2013) -- ftpserver.pl: Added support for IMAP CREATE, DELETE and RENAME commands +- CURLINFO_COOKIELIST.3: made the example not leak memory + + Reported-by: Muz Dima -Daniel Stenberg (29 Aug 2013) -- FTP: fix getsock during DO_MORE state +- vauth/cleartext: fix integer overflow check - ... when doing upload it would return the wrong values at times. This - commit attempts to cleanup the mess. + Make the integer overflow check not rely on the undefined behavior that + a size_t wraps around on overflow. - Bug: http://curl.haxx.se/mail/lib-2013-08/0109.html - Reported-by: Mike Mio + Detected by lgtm.com + Closes #2408 -- curl_multi_remove_handle: allow multiple removes +- lib/curl_path.h: add #ifdef header guard - When removing an already removed handle, avoid that to ruin the - internals and just return OK instead. + Detected by lgtm.com -Steve Holme (29 Aug 2013) -- ftpserver.pl: Updated IMAP EXAMINE handler to use dynamic test data +- vauth/ntlm.h: fix the #ifdef header guard + + Detected by lgtm.com -Daniel Stenberg (29 Aug 2013) -- unit1304: include memdebug and free everything correctly +Jay Satiro (20 Mar 2018) +- examples/hiperfifo: checksrc compliance -- Curl_parsenetrc: document that the arguments must be allocated +Daniel Stenberg (19 Mar 2018) +- [Nikos Tsipinakis brought this change] -- easy: rename struct monitor to socketmonitor - - 'struct monitor', introduced in 6cf8413e, already exists in an IRIX - header file (sys/mon.h) which gets included via various standard headers - by lib/easy.c + parsedate: support UT timezone - cc-1101 cc: ERROR File = ../../curl/lib/easy.c, Line = 458 - "monitor" has already been declared in the current scope. + RFC822 section 5.2 mentions Universal Time, 'UT', to be synonymous with + GMT. - Reported-by: Tor Arntsen + Closes #2401 -Steve Holme (29 Aug 2013) -- ftpserver.pl: Added SELECT check to IMAP FETCH and STORE handlers +- RELEASE-NOTES: synced -- ftpserver.pl: Corrected accidental move of logmsg() call - - Corrected the call to logmsg() in the IMAP SEARCH handler from commit - 4ae7b7ea691497 as it should have been outputting the what argument and - not the test number. +- [Don brought this change] -Daniel Stenberg (28 Aug 2013) -- ftpserver: add missing '}' from 4ae7b7ea69149 - -Steve Holme (28 Aug 2013) -- ftpserver.pl: Added SELECT check to IMAP SEARCH command + cmake: add support for brotli + + Currently CMake cannot detect Brotli support. This adds detection of the + libraries and associated header files. It also adds this to the + generated config. + + Closes #2392 -- ftpserver.pl: Fixed IMAP SEARCH command +- [Chris Araman brought this change] -Daniel Stenberg (28 Aug 2013) -- bump: next release is 7.33.0 due to added features + darwinssl: fix iOS build -- symbols-in-versions: add CURLOPT_XOAUTH2_BEARER +Patrick Monnerat (18 Mar 2018) +- ILE/RPG binding: Add CURLOPT_HAPROXYPROTOCOL/Fix CURLOPT_DNS_SHUFFLE_ADDRESSES -Steve Holme (28 Aug 2013) -- tests: Added test for IMAP SEARCH command +Daniel Stenberg (17 Mar 2018) +- [Rick Deist brought this change] -Daniel Stenberg (28 Aug 2013) -- valgrind.supp: fix for regular curl_easy_perform too + resolve: add CURLOPT_DNS_SHUFFLE_ADDRESSES - When we introduced curl_easy_perform_ev, this got a slightly modified - call trace. Without this, test 165 causes a false positive valgrind - error. - -- valgrind.supp: add the event-based call stack-trace too + This patch adds CURLOPT_DNS_SHUFFLE_ADDRESSES to explicitly request + shuffling of IP addresses returned for a hostname when there is more + than one. This is useful when the application knows that a round robin + approach is appropriate and is willing to accept the consequences of + potentially discarding some preference order returned by the system's + implementation. - Without this, test 165 triggers a valgrind error when ran with - curl_easy_perform_ev + Closes #1694 -- multi_socket: improved 100-continue timeout handling +- add_handle/easy_perform: clear errorbuffer on start if set - When waiting for a 100-continue response from the server, the - Curl_readwrite() will refuse to run if called until the timeout has been - reached. + To offer applications a more defined behavior, we clear the buffer as + early as possible. - We timeout code in multi_socket() allows code to run slightly before the - actual timeout time, so for test 154 it could lead to the function being - executed but refused in Curl_readwrite() and then the application would - just sit idling forever. + Assisted-by: Jay Satiro - This was detected with runtests.pl -e on test 154. + Fixes #2190 + Closes #2377 -Steve Holme (27 Aug 2013) -- ftpserver.pl: Added support for IMAP SEARCH command - -- tool_operate.c: Fixed compilation warning - - warning: implicit declaration of function 'checkpasswd' +- [Lawrence Matthews brought this change] -- curl: Moved check for password out of get parameter loop + CURLOPT_HAPROXYPROTOCOL: support the HAProxy PROXY protocol - Moved the calls to checkpasswd() out of the getparameter() function - which allows for any related arguments to be specified on the command - line before or after --user (and --proxy-user). + Add --haproxy-protocol for the command line tool - For example: --bearer doesn't need to be specified before --user to - prevent curl from asking for an unnecessary password as is the case - with commit e7dcc454c67a2f. + Closes #2162 -- RELEASE-NOTES: synced with acf59be7f09a7 +- curl_version_info.3: fix ssl_version description + + Reported-by: Vincas Razma + Fixes #2364 -- [Kyle L. Huff brought this change] +- multi: improved pending transfers handling => improved performance + + When a transfer is requested to get done and it is put in the pending + queue when limited by number of connections, total or per-host, libcurl + would previously very aggressively retry *ALL* pending transfers to get + them transferring. That was very time consuming. + + By reducing the aggressiveness in how pending are being retried, we + waste MUCH less time on putting transfers back into pending again. + + Some test cases got a factor 30(!) speed improvement with this change. + + Reported-by: Cyril B + Fixes #2369 + Closes #2383 - curl: added --bearer option to help +- pause: when changing pause state, update socket state + + Especially unpausing a transfer might have to move the socket back to the + "currently used sockets" hash to get monitored. Otherwise it would never get + any more data and get stuck. Easily triggered with pausing using the + multi_socket API. - Added the --bearer option to the help output + Reported-by: Philip Prindeville + Bug: https://curl.haxx.se/mail/lib-2018-03/0048.html + Fixes #2393 + Closes #2391 -- [Kyle L. Huff brought this change] +- [Philip Prindeville brought this change] - curl: added basic SASL XOAUTH2 support + examples/hiperfifo.c: improved - Added the ability to specify an XOAUTH2 bearer token [RFC6750] via the - --bearer option. + * use member struct event’s instead of pointers to alloc’d struct + events - Example usage: - curl --url "imaps://imap.gmail.com:993/INBOX/;UID=1" --ssl-reqd - --bearer ya29.AHES6Z...OMfsHYI --user username@example.com - -- tool_urlglob.c: Fixed compiler warnings + * simplify the cases for the mcode_or_die() function via macros; - warning: 'variable' may be used uninitialized in this function - -Daniel Stenberg (26 Aug 2013) -- security.h: rename to curl_sec.h to avoid name collision + * make multi_timer_cb() actually do what the block comment says it + should; - I brought back security.h in commit bb5529331334e. As we actually - already found out back in 2005 in commit 62970da675249, the file name - security.h causes problems so I renamed it curl_sec.h instead. + * accept a “stop†command on the FIFO to shut down the service; + + * use cleaner notation for unused variables than the (void) hack; + + * allow following redirections (304’s); -- runtests.pl: allow -vc point to a separate curl binary to verify with +- rate-limit: use three second window to better handle high speeds + + Due to very frequent updates of the rate limit "window", it could + attempt to rate limit within the same milliseconds and that then made + the calculations wrong, leading to it not behaving correctly on very + fast transfers. - The specified curl binary will then be used to verify the running - server(s) instead of the development version. This is very useful in - some cases when the development version fails to verify correctly as - then the test case may not run at all. + This new logic updates the rate limit "window" to be no shorter than the + last three seconds and only updating the timestamps for this when + switching between the states TOOFAST/PERFORM. - The actual test will still be run with the "normal" curl executable - (unless the test case specifies something differently). + Reported-by: 刘佩东 + Fixes #2386 + Closes #2388 -Steve Holme (26 Aug 2013) -- [Kyle L. Huff brought this change] +- [luz.paz brought this change] - smtp: added basic SASL XOAUTH2 support + cleanup: misc typos in strings and comments - Added the ability to use an XOAUTH2 bearer token [RFC6750] with SMTP for - authentication using RFC6749 "OAuth 2.0 Authorization Framework". + Found via `codespell` - The bearer token is expected to be valid for the user specified in - conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has - an advertised auth mechanism of "XOAUTH2", the user and access token are - formatted as a base64 encoded string and sent to the server as - "AUTH XOAUTH2 <bearer token>". + Closes #2389 -- [Kyle L. Huff brought this change] +- RELEASE-NOTES: toward 7.60.0 - imap: added basic SASL XOAUTH2 support +- [Kobi Gurkan brought this change] + + http2: fixes typo - Added the ability to use an XOAUTH2 bearer token [RFC6750] with IMAP for - authentication using RFC6749 "OAuth 2.0 Authorization Framework". + Closes #2387 + +- user-agent.d:: mention --proxy-header as well - The bearer token is expected to be valid for the user specified in - conn->user. If CURLOPT_XOAUTH2_BEARER is defined and the connection has - an advertised auth mechanism of "XOAUTH2", the user and access token are - formatted as a base64 encoded string and sent to the server as - "A001 AUTHENTICATE XOAUTH2 <bearer token>". + Bug: https://github.com/curl/curl/issues/2381 -- security.h: Fixed compilation warning +- transfer: make HTTP without headers count correct body size - ISO C forbids forward references to 'enum' types + This is what "HTTP/0.9" basically looks like. + + Reported on IRC + + Closes #2382 -Daniel Stenberg (26 Aug 2013) -- KNOWN_BUGS: refer to bug numbers with the existing number series +- test1208: marked flaky - The old numbers would still redirect but who knows for how long... + It fails somewhere between every 3rd to 10th travis-CI run -Steve Holme (25 Aug 2013) -- [Kyle L. Huff brought this change] +- SECURITY-PROCESS: mention how we write/add advisories - options: added basic SASL XOAUTH2 support +- [dasimx brought this change] + + FTP: fix typo in recursive callback detection for seeking - Added the ability to specify an XOAUTH2 bearer token [RFC6750] via the - option CURLOPT_XOAUTH2_BEARER for authentication using RFC6749 "OAuth - 2.0 Authorization Framework". + Fixes #2380 + +Version 7.59.0 (13 Mar 2018) -- [Kyle L. Huff brought this change] +Daniel Stenberg (13 Mar 2018) +- release: 7.59.0 - sasl: added basic SASL XOAUTH2 support +Kamil Dudka (13 Mar 2018) +- tests/.../spnego.py: fix identifier typo - Added the ability to generated a base64 encoded XOAUTH2 token - containing: "user=<username>^Aauth=Bearer <bearer token>^A^A" - as per RFC6749 "OAuth 2.0 Authorization Framework". + Detected by Coverity Analysis: + + Error: IDENTIFIER_TYPO: + curl-7.58.0/tests/python_dependencies/impacket/spnego.py:229: identifier_typo: Using "SuportedMech" appears to be a typo: + * Identifier "SuportedMech" is only known to be referenced here, or in copies of this code. + * Identifier "SupportedMech" is referenced elsewhere at least 4 times. + curl-7.58.0/tests/python_dependencies/impacket/smbserver.py:2651: identifier_use: Example 1: Using identifier "SupportedMech". + curl-7.58.0/tests/python_dependencies/impacket/smbserver.py:2308: identifier_use: Example 2: Using identifier "SupportedMech". + curl-7.58.0/tests/python_dependencies/impacket/spnego.py:252: identifier_use: Example 3: Using identifier "SupportedMech" (2 total uses in this function). + curl-7.58.0/tests/python_dependencies/impacket/spnego.py:229: remediation: Should identifier "SuportedMech" be replaced by "SupportedMech"? + + Closes #2379 -Daniel Stenberg (25 Aug 2013) -- FTP: remove krb4 support +Daniel Stenberg (13 Mar 2018) +- CURLOPT_COOKIEFILE.3: "-" as file name means stdin - We've announced this pending removal for a long time and we've - repeatedly asked if anyone would care or if anyone objects. Nobody has - objected. It has probably not even been working for a good while since - nobody has tested/used this code recently. + Reported-by: Aron Bergman + Bug: https://curl.haxx.se/mail/lib-2018-03/0049.html - The stuff in krb4.h that was generic enough to be used by other sources - is now present in security.h + [ci skip] -- easy: define away easy_events() for non-debug builds +- Revert "hostip: fix compiler warning: 'variable set but not used'" + + This reverts commit a577059f92fc65bd6b81717f0737f897a5b34248. + + The assignment really needs to be there or we risk working with an + uninitialized pointer. -- FAQ: editorial updates +Michael Kaufmann (12 Mar 2018) +- limit-rate: fix compiler warning - Several language fixes. Several reformats that should make the HTML - generation of this document look better. + follow-up to 72a0f62 + +Viktor Szakats (12 Mar 2018) +- checksrc.pl: add -i and -m options - Reported-by: Dave Thompson + To sync it with changes made for the libssh2 project. + Also cleanup some whitespace. -- RELEASE-NOTES: synced with 22adb46a32bee +- curl-openssl.m4: fix spelling [ci skip] -- multi: move on from STATE_DONE faster +- FAQ: fix a broken URL [ci skip] + +Daniel Stenberg (12 Mar 2018) +- http2: mark the connection for close on GOAWAY - Make sure we always return CURLM_CALL_MULTI_PERFORM when we reach - CURLM_STATE_DONE since the state is transient and it can very well - continue executing as there is nothing to wait for. + ... don't consider it an error! - Bug: http://curl.haxx.se/mail/lib-2013-08/0211.html - Reported-by: Yi Huang + Assisted-by: Jay Satiro + Reported-by: Åukasz Domeradzki + Fixes #2365 + Closes #2375 -- curl.h: name space pollution by "enum type" - - Renamed to "enum curl_khtype" now. Will break compilation for programs - that rely on the enum name. +- credits: Viktor prefers without accent + +- openldap: white space changes, fixed up the copyright years + +- openldap: check ldap_get_attribute_ber() results for NULL before using - Bug: https://github.com/bagder/curl/pull/76 - Reported-by: Shawn Landden + CVE-2018-1000121 + Reported-by: Dario Weisser + Bug: https://curl.haxx.se/docs/adv_2018-97a2.html -- TFTP: make the CURLOPT_LOW_SPEED* options work +- FTP: reject path components with control codes - ... this also makes sure that the progess callback gets called more - often during TFTP transfers. + Refuse to operate when given path components featuring byte values lower + than 32. - Added test 1238 to verify. + Previously, inserting a %00 sequence early in the directory part when + using the 'singlecwd' ftp method could make curl write a zero byte + outside of the allocated buffer. - Bug: http://curl.haxx.se/bug/view.cgi?id=1269 - Reported-by: Jo3 + Test case 340 verifies. + + CVE-2018-1000120 + Reported-by: Duy Phan Thanh + Bug: https://curl.haxx.se/docs/adv_2018-9cd6.html -- tftpd: support "writedelay" within <servercmd> +- readwrite: make sure excess reads don't go beyond buffer end + + CVE-2018-1000122 + Bug: https://curl.haxx.se/docs/adv_2018-b047.html + + Detected by OSS-fuzz -- tftpd: convert 6 global variables into local ones +- BUGS: updated link to security process -- [Gisle Vanem brought this change] +- limit-rate: kick in even before "limit" data has been received + + ... and make sure to avoid integer overflows with really large values. + + Reported-by: 刘佩东 + Fixes #2371 + Closes #2373 + +- docs/SECURITY.md -> docs/SECURITY-PROCESS.md - curl_easy_perform_ev: make it CURL_EXTERN +- SECURITY.md: call it the security process + +Michael Kaufmann (11 Mar 2018) +- Curl_range: fix FTP-only and FILE-only builds - I build curl.exe (using MingW) with '-DCURLDEBUG' and by importing from - libcurl.dll. Which means the new curl_easy_perform_ev() must be - exported from libcurl.dll. + follow-up to e04417d + +- hostip: fix compiler warning: 'variable set but not used' -- CURLM_ADDED_ALREADY: new error code +Daniel Stenberg (11 Mar 2018) +- HTTP: allow "header;" to replace an internal header with a blank one - Doing curl_multi_add_handle() on an easy handle that is already added to - a multi handle now returns this error code. It previously returned - CURLM_BAD_EASY_HANDLE for this condition. + Reported-by: Michael Kaufmann + Fixes #2357 + Closes #2362 -- multi_init: moved init code here from add_handle +- http2: verbose output new MAX_CONCURRENT_STREAMS values - The closure_handle is "owned" by the multi handle and it is - unconditional so the setting up of it should be in the Curl_multi_handle - function rather than curl_multi_add_handle. + ... as it is interesting for many users. -- multi: remove dns cache creation code from *add_handle +- SECURITY: distros' max embargo time is 14 days now + +Patrick Monnerat (8 Mar 2018) +- curl tool: accept --compressed also if Brotli is enabled and zlib is not. + +Daniel Stenberg (5 Mar 2018) +- THANKS + mailmap: remove duplicates, fixup full names + +- [sergii.kavunenko brought this change] + + WolfSSL: adding TLSv1.3 - As it is done unconditionally in multi_init() this code will never run! + Closes #2349 -- curl_easy_perform_ev: debug/test function +- RELEASE-NOTES/THANKS: synced with cc1d4c505 + +- [Richard Alcock brought this change] + + winbuild: prefer documented zlib library names - This function is meant to work *exactly* as curl_easy_perform() but will - use the event-based libcurl API internally instead of - curl_multi_perform(). To avoid relying on an actual event-based library - and to not use non-portable functions (like epoll or similar), there's a - rather inefficient emulation layer implemented on top of Curl_poll() - instead. + Check for existence of import and static libraries with documented names + and use them if they do. Fallback to previous names. - There's currently some convenience logging done in curl_easy_perform_ev - which helps when tracking down problems. They may be suitable to remove - or change once things seem to be fine enough. + According to + https://github.com/madler/zlib/blob/master/win32/README-WIN32.txt on + Windows, the names of the import library is "zdll.lib" and static + library is "zlib.lib". - curl has a new --test-event option when built with debug enabled that - then uses curl_easy_perform_ev() instead of curl_easy_perform(). If - built without debug, using --test-event will only output a warning - message. + closes #2354 + +Marcel Raad (4 Mar 2018) +- krb5: use nondeprecated functions - NOTE: curl_easy_perform_ev() is not part if the public API on purpose. - It is only present in debug builds of libcurl and MUST NOT be considered - stable even then. Use it for libcurl-testing purposes only. + gss_seal/gss_unseal have been deprecated in favor of + gss_wrap/gss_unwrap with GSS-API v2 from January 1997 [1]. The first + version of "The Kerberos Version 5 GSS-API Mechanism" [2] from June + 1996 already says "GSS_Wrap() (formerly GSS_Seal())" and + "GSS_Unwrap() (formerly GSS_Unseal())". - runtests.pl now features an -e command line option that makes it use - --test-event for all curl command line tests. The man page is updated. - -- [Gisle Vanem brought this change] + Use the nondeprecated functions to avoid deprecation warnings. + + [1] https://tools.ietf.org/html/rfc2078 + [2] https://tools.ietf.org/html/rfc1964 + + Closes https://github.com/curl/curl/pull/2356 - transfer: the recent sessionhandle change broke CURL_DOES_CONVERSIONS +Daniel Stenberg (4 Mar 2018) +- curl.1: mention how to add numerical IP addresses in NO_PROXY -- test1237: verify 1000+ letter user name + passwords +- CURLOPT_NOPROXY.3: mention how to list numerical IPv6 addresses -- [Jonathan Nieder brought this change] +- NO_PROXY: fix for IPv6 numericals in the URL + + Added test 1265 that verifies. + + Reported-by: steelman on github + Fixes #2353 + Closes #2355 - url: handle arbitrary-length username and password before '@' +- build: get CFLAGS (including -werror) used for examples and tests + + ... so that the CI and more detects compiler warnings/errors properly! - libcurl quietly truncates usernames, passwords, and options from - before an '@' sign in a URL to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) - characters to fit in fixed-size buffers on the stack. Allocate a - buffer large enough to fit the parsed fields on the fly instead to - support longer passwords. + Closes #2337 + +Marcel Raad (3 Mar 2018) +- curl_ctype: fix macro redefinition warnings - After this change, there are no more uses of MAX_CURL_OPTIONS_LENGTH - left, so stop defining that constant while at it. The hardcoded max - username and password length constants, on the other hand, are still - used in HTTP proxy credential handling (which this patch doesn't - touch). + On MinGW and Cygwin, GCC and clang have been complaining about macro + redefinitions since 4272a0b0fc49a1ac0ceab5c4a365c9f6ab8bf8e2. Fix this + by undefining the macros before redefining them as suggested in + https://github.com/curl/curl/pull/2269. - Reported-by: Colby Ranger + Suggested-by: Daniel Stenberg -- [Jonathan Nieder brought this change] +Dan Fandrich (2 Mar 2018) +- unit1307: proper cleanup on OOM to fix torture tests - url: handle exceptional cases first in parse_url_login() +Marcel Raad (28 Feb 2018) +- unit1309: fix warning on Windows x64 - Instead of nesting "if(success)" blocks and leaving the reader in - suspense about what happens in the !success case, deal with failure - cases early, usually with a simple goto to clean up and return from - the function. + When targeting x64, MinGW-w64 complains about conversions between + 32-bit long and 64-bit pointers. Fix this by reusing the + GNUTLS_POINTER_TO_SOCKET_CAST / GNUTLS_SOCKET_TO_POINTER_CAST logic + from gtls.c, moving it to warnless.h as CURLX_POINTER_TO_INTEGER_CAST / + CURLX_INTEGER_TO_POINTER_CAST. - No functional change intended. The main effect is to decrease the - indentation of this function slightly. - -- [Jonathan Nieder brought this change] + Closes https://github.com/curl/curl/pull/2341 - Curl_setopt: handle arbitrary-length username and password +- travis: update compiler versions - libcurl truncates usernames, passwords, and options set with - curl_easy_setopt to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) characters. - This doesn't affect the return value from curl_easy_setopt(), so from - the caller's point of view, there is no sign anything strange has - happened, except that authentication fails. + Update clang to version 3.9 and GCC to version 6. - For example: + Closes https://github.com/curl/curl/pull/2345 + +Daniel Stenberg (26 Feb 2018) +- docs/MANUAL: formfind.pl is not accessible on the site anymore - # Prepare a long (300-char) password. - s=0123456789; s=$s$s$s$s$s$s$s$s$s$s; s=$s$s$s; - # Start a server. - nc -l -p 8888 | tee out & pid=$! - # Tell curl to pass the password to the server. - curl --user me:$s http://localhost:8888 & sleep 1; kill $pid - # Extract the password. - userpass=$( - awk '/Authorization: Basic/ {print $3}' <out | - tr -d '\r' | - base64 -d - ) - password=${userpass#me:} - echo ${#password} + Fixes #2342 + +Jay Satiro (24 Feb 2018) +- curl-openssl.m4: Fix version check for OpenSSL 1.1.1 - Expected result: 300 - Actual result: 255 + - Add OpenSSL 1.1.1 to the header/library version lists. - The fix is simple: allocate appropriately sized buffers on the heap - instead of trying to squeeze the provided values into fixed-size - on-stack buffers. + - Detect OpenSSL 1.1.1 library using its function ERR_clear_last_mark, + which was added in that version. - Bug: http://bugs.debian.org/719856 - Reported-by: Colby Ranger + Prior to this change an erroneous header/library mismatch was caused by + lack of OpenSSL 1.1.1 detection. I tested using openssl-1.1.1-pre1. -- [Jonathan Nieder brought this change] - - netrc: handle longer username and password +Viktor Szakats (23 Feb 2018) +- lib655: silence compiler warning - libcurl truncates usernames and passwords it reads from .netrc to - LOGINSIZE and PASSWORDSIZE (64) characters without any indication to - the user, to ensure the values returned from Curl_parsenetrc fit in a - caller-provided buffer. + Closes https://github.com/curl/curl/pull/2335 + +- spelling fixes - Fix the interface by passing back dynamically allocated buffers - allocated to fit the user's input. The parser still relies on a - 256-character buffer to read each line, though. + Detected using the `codespell` tool. - So now you can include an ~246-character password in your .netrc, - instead of the previous limit of 63 characters. + Also contains one URL protocol upgrade. - Reported-by: Colby Ranger + Closes https://github.com/curl/curl/pull/2334 -- [Jonathan Nieder brought this change] - - url: allocate username, password, and options on the heap +Daniel Stenberg (24 Feb 2018) +- projects/README: remove reference to dead IDN link/package + + Reported-by: Stefan Kanthak and Rod Widdowson - This makes it possible to increase the size of the buffers when needed - in later patches. No functional change yet. + Fixes #2325 -- [Jonathan Nieder brought this change] +Jay Satiro (23 Feb 2018) +- [Rod Widdowson brought this change] - url: use goto in create_conn() for exception handling + winbuild: Use macros for the names of some build utilities - Instead of remembering before each "return" statement which temporary - allocations, if any, need to be freed, take care to set pointers to - NULL when no longer needed and use a goto to a common block to exit - the function and free all temporaries. + - Add macros to the top of the makefile for rc and mt utilities so that + it is easier to change their locations. - No functional change intended. Currently the only temporary buffer in - this function is "proxy" which is already correctly freed when - appropriate, but there will be more soon. + Bug: https://curl.haxx.se/mail/lib-2018-02/0075.html + Reported-by: Stefan Kanthak + + Closes https://github.com/curl/curl/issues/2329 + +Daniel Stenberg (23 Feb 2018) +- TODO: remove "sha-256 digest", added in 2b5b37cb9109e7c2 -- [Jonathan Nieder brought this change] +- curl_share_setopt.3: connection cache is shared within multi handles - sasl: allow arbitrarily long username and password +Jay Satiro (22 Feb 2018) +- [Rod Widdowson brought this change] + + winbuild: Use CALL to run batch scripts - Use appropriately sized buffers on the heap instead of fixed-size - buffers on the stack, to allow for longer usernames and passwords. + Co-authored-by: Stefan Kanthak - Callers never pass anything longer than MAX_CURL_USER_LENGTH (resp. - MAX_CURL_PASSWORD_LENGTH), so no functional change inteded yet. + Closes https://github.com/curl/curl/issues/2330 + Closes https://github.com/curl/curl/pull/2331 + +Patrick Monnerat (22 Feb 2018) +- os400: add curl_resolver_start_callback type to ILE/RPG binding + +Daniel Stenberg (22 Feb 2018) +- form.d: rephrased somewhat, added two example command lines -Steve Holme (19 Aug 2013) -- [Alex McLellan brought this change] +Jay Satiro (21 Feb 2018) +- [Francisco Sedano brought this change] - imap: Fixed response check for SEARCH command + url: Add option CURLOPT_RESOLVER_START_FUNCTION + + - Add new option CURLOPT_RESOLVER_START_FUNCTION to set a callback that + will be called every time before a new resolve request is started + (ie before a host is resolved) with a pointer to backend-specific + resolver data. Currently this is only useful for ares. + + - Add new option CURLOPT_RESOLVER_START_DATA to set a user pointer to + pass to the resolver start callback. - Adding this line allows libcurl to return the server response when - performing a search command via a custom request. + Closes https://github.com/curl/curl/pull/2311 -Daniel Stenberg (16 Aug 2013) -- glob: error out on range overflow +- lib: CURLOPT_HAPPY_EYEBALLS_TIMEOUT => CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS - The new multiply() function detects range value overflows. 32bit - machines will overflow on a 32bit boundary while 64bit hosts support - ranges up to the full 64 bit range. + - In keeping with the naming of our other connect timeout options rename + CURLOPT_HAPPY_EYEBALLS_TIMEOUT to CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS. - Added test 1236 to verify. + This change adds the _MS suffix since the option expects milliseconds. + This is more intuitive for our users since other connect timeout options + that expect milliseconds use _MS such as CURLOPT_TIMEOUT_MS, + CURLOPT_CONNECTTIMEOUT_MS, CURLOPT_ACCEPTTIMEOUT_MS. - Bug: http://curl.haxx.se/bug/view.cgi?id=1267 - Reported-by: Will Dietz + The tool option already uses an -ms suffix, --happy-eyeballs-timeout-ms. + + Follow-up to 2427d94 which added the lib and tool option yesterday. + + Ref: https://github.com/curl/curl/pull/2260 -- urlglob: better detect unclosed braces, empty lists and overflows +Patrick Monnerat (21 Feb 2018) +- sasl: prefer PLAIN mechanism over LOGIN - A rather big overhaul and cleanup. + SASL PLAIN is a standard, LOGIN only a draft. The LOGIN draft says + PLAIN should be used instead if available. + +Daniel Stenberg (21 Feb 2018) +- RELEASE-NOTES: synced with 2427d94c6 + +Jay Satiro (20 Feb 2018) +- [Anders Bakken brought this change] + + url: Add option CURLOPT_HAPPY_EYEBALLS_TIMEOUT - 1 - curl wouldn't properly detect and reject globbing that ended with an - open brace if there were brackets or braces before it. Like "{}{" or - "[0-1]{" + - Add new option CURLOPT_HAPPY_EYEBALLS_TIMEOUT to set libcurl's happy + eyeball timeout value. - 2 - curl wouldn't properly reject empty lists so that "{}{}" would - result in curl getting (nil) strings in the output. + - Add new optval macro CURL_HET_DEFAULT to represent the default happy + eyeballs timeout value (currently 200 ms). - 3 - By using strtoul() instead of sscanf() the code will now detected - over and underflows. It now also better parses the step argument to only - accept positive numbers and only step counters that is smaller than the - delta between the maximum and minimum numbers. + - Add new tool option --happy-eyeballs-timeout-ms to expose + CURLOPT_HAPPY_EYEBALLS_TIMEOUT. The -ms suffix is used because the + other -timeout options in the tool expect seconds not milliseconds. - 4 - By switching to unsigned longs instead of signed ints for the - counters, the max values for []-ranges are now very large (on 64bit - machines). + Closes https://github.com/curl/curl/pull/2260 + +- hostip: fix 'potentially uninitialized variable' warning - 5 - Bumped the maximum number of globs in a single URL to 100 (from 10) + Follow-up to 50d1b33. - 6 - Simplified the code somewhat and now it stores fixed strings as - single- entry lists. That's also one of the reasons why I did (5) as now - all strings between "globs" will take a slot in the array. + Caught by AppVeyor. + +Daniel Stenberg (20 Feb 2018) +- TODO: warning if curl version is not in sync with libcurl version + +Jay Satiro (20 Feb 2018) +- [Anders Bakken brought this change] + + CURLOPT_RESOLVE: Add support for multiple IP addresses per entry - Added test 1234 and 1235 to verify. Updated test 87. + This enables users to preresolve but still take advantage of happy + eyeballs and trying multiple addresses if some are not connecting. - This commit fixes three separate bug reports. + Ref: https://github.com/curl/curl/pull/2260 + +Daniel Stenberg (20 Feb 2018) +- [Sergio Borghese brought this change] + + examples/sftpuploadresume: resume upload via CURLOPT_APPEND - Bug: http://curl.haxx.se/bug/view.cgi?id=1264 - Bug: http://curl.haxx.se/bug/view.cgi?id=1265 - Bug: http://curl.haxx.se/bug/view.cgi?id=1266 - Reported-by: Will Dietz + URL: https://curl.haxx.se/mail/lib-2018-02/0072.html -- [John Malmberg brought this change] +- curl --version: show PSL if the run-time lib has it enabled + + ... not of the #define was set at build-time! - VMS: Add RELEASE-NOTES to vms document +- TODO: "Support in-memory certs/ca certs/keys" - Add the curl release notes to the release note document generated for - VMS packages. + removed SSLKEYLOGFILE support (fixed) - Add the different filenames generated by a daily build to the - cleanup procedures. + removed "consider SSL patches" (outdated) + + Closes #2310 -- [Tor Arntsen brought this change] +- CURLOPT_HEADER.3: clarify problems with different data sizes - tests 2032, 2033: Don't hardcode port in expected output +- test1556: verify >16KB headers to the header callback -- ftp: convert state names to a global array +- header callback: don't chop headers into smaller pieces - ... just to make them easier to print in debug ouputs while debugging. - They are still within #ifdef [debugbuild]. + Reported-by: Guido Berhoerster + Fixes #2314 + Closes #2316 -- --help: fix the --sasl-ir in the help output +- test1154: verify that long HTTP headers get rejected -- ftp_domore_getsock: when passive mode, the second conn is already there +- http: fix the max header length detection logic + + Previously, it would only check for max length if the existing alloc + buffer was to small to fit it, which often would make the header still + get used. - This makes the socket callback get called with the proper bitmask as - otherwise the application could be left hanging waiting for reading on - an upload connection! + Reported-by: Guido Berhoerster + Bug: https://curl.haxx.se/mail/lib-2018-02/0056.html - Bug: http://curl.haxx.se/mail/lib-2013-08/0043.html - Reported-by: Bill Doyle + Closes #2315 -- curl: make --no-[option] work properly for several options +- CURLOPT_HEADERFUNCTION.3: fix typo from d939226813 - --create-dirs, --crlf, --socks5-gssapi-nec and --sasl-ir + Reported-by: Erik Johansson + Bug: https://github.com/curl/curl/commit/d9392268131c1b8d18dec3fa30e0bded833a5db7#commitcomment-27607495 -Kamil Dudka (12 Aug 2013) -- nss: make sure that NSS is initialized +- CURLOPT_HEADERFUNCTION.3: mention folded headers + +- TODO: 1.1 Option to refuse usernames in URLs - ... prior to calling PK11_GenerateRandom() + Also expanded the CURL_REFUSE_CLEARTEXT section with more ideas. + +- TODO: 1.7 Support HTTP/2 for HTTP(S) proxies -Daniel Stenberg (12 Aug 2013) -- multi: s/easy/data +- ssh: add two missing state names + + The list of state names (used in debug builds) was out of sync in + relation to the list of states (used in all builds). + + I now added an assert to make sure the sizes of the two lists match, to + aid in detecting this mistake better in the future. + + Regression since c92d2e14cf, shipped in 7.58.0. + + Reported-by: Somnath Kundu - With everything being struct SessionHandle pointers now, this rename - makes multi.c use the library-wide practise of calling that pointer - 'data' instead of the previously used 'easy'. + Fixes #2312 + Closes #2313 -- cleanup: removed one function, made one static +- Revert "KNOWN_BUGS: 2.5 curl should not offer "ALPN: h2" when using https-proxy" - Moved Curl_easy_addmulti() from easy.c to multi.c, renamed it to - easy_addmulti and made it static. + This reverts commit de9fac00c40db321d44fa6fbab6eb62ec4c83998. - Removed Curl_easy_initHandleData() and uses of it since it was emptied - in commit cdda92ab67b47d74a. + Reported-by: Jay Satiro -- SessionHandle: the protocol specific pointer is now a void * +Jay Satiro (15 Feb 2018) +- non-ascii: fix implicit declaration warning - All protocol handler structs are now opaque (void *) in the - SessionHandle struct and moved in the request-specific sub-struct - 'SingleRequest'. The intension is to keep the protocol specific - knowledge in their own dedicated source files [protocol].c etc. + Follow-up to b46cfbc. - There's some "leakage" where this policy is violated, to be addressed at - a later point in time. + Caught by Travis CI. -- urldata: clean up the use of the protocol specific structs +Daniel Stenberg (15 Feb 2018) +- travis: add build with iconv enabled - 1 - always allocate the struct in protocol->setup_connection. Some - protocol handlers had to get this function added. + ... to verify it builds and works fine. - 2 - always free at the end of a request. This is also an attempt to keep - less memory in the handle after it is completed. + Ref: https://curl.haxx.se/mail/lib-2017-09/0031.html + + Closes #1872 -- version number: bump to 7.32.1 for now +- TODO: 18.18 retry on network is unreachable - Start working on the next version and up some counters. + Closes #1603 -Version 7.32.0 (11 Aug 2013) +- KNOWN_BUGS: 2.5 curl should not offer "ALPN: h2" when using https-proxy + + Closes #1254 -Daniel Stenberg (11 Aug 2013) -- THANKS: added contributors from the 7.32.0 release notes +Kamil Dudka (15 Feb 2018) +- nss: use PK11_CreateManagedGenericObject() if available + + ... so that the memory allocated by applications using libcurl does not + grow per each TLS connection. + + Bug: https://bugzilla.redhat.com/1510247 + + Closes #2297 -- [Fabian Keil brought this change] +Daniel Stenberg (15 Feb 2018) +- [Björn Stenberg brought this change] - test1228: add 'HTTP proxy' to the keywords + TODO fixed: Detect when called from within callbacks + + Closes #2302 -- [Fabian Keil brought this change] +- BINDINGS: fix curb link (and remove ruby-curl-multi) + + Reported-by: Klaus Stein - tests: add keywords for a couple of FILE tests +- curl_gssapi: make sure this file too uses our *printf() -- [Fabian Keil brought this change] +- libcurl-security.3: separate file:// section + + ... just to make it more apparent. Even if it repeats + some pieces of information. - tests: add 'FAILURE' keywords to tests 1409 and 1410 +- libcurl-security.3: the http://192.168.0.1/my_router_config case + + Mentioned-By: Rich Moore -- [Fabian Keil brought this change] +- libcurl-security.3: mention the URL standards problems too - tests: add keywords for a couple of HTTP tests +- libcurl-security.3: split out from libcurl-tutorial.3 + + To make more accessible. + + Merged in some new language from "URLs are dangerous things" as discussed on + the mailing list a few days ago: + + Bug: https://curl.haxx.se/mail/lib-2018-02/0013.html -- [Fabian Keil brought this change] +- RELEASE-NOTES: synced with e551910f8 - tests: add keywords for a couple of FTP tests +Patrick Monnerat (13 Feb 2018) +- tests: new tests for http raw mode + + Test 319 checks proper raw mode data with non-chunked gzip + transfer-encoded server data. + Test 326 checks raw mode with chunked server data. + + Bug: #2303 + Closes #2308 -- [Fabian Keil brought this change] +Kamil Dudka (12 Feb 2018) +- tlsauthtype.d: works only if libcurl is built with TLS-SRP support + + Bug: https://bugzilla.redhat.com/1542256 + + Closes #2306 - test1511: consistently terminate headers with CRLF +Patrick Monnerat (12 Feb 2018) +- smtp: fix processing of initial dot in data + + RFC 5321 4.1.1.4 specifies the CRLF terminating the DATA command + should be taken into account when chasing the <CRLF>.<CRLF> end marker. + Thus a leading dot character in data is also subject to escaping. + + Tests 911 and test server are adapted to this situation. + New tests 951 and 952 check proper handling of initial dot in data. + + Closes #2304 + +Daniel Stenberg (12 Feb 2018) +- sha256: avoid redefine -- DISABLED: shut of test 1512 for now +- [Douglas Mencken brought this change] + + sha256: build with OpenSSL < 0.9.8 too + + support for SHA-2 was introduced in OpenSSL 0.9.8 - It shows intermittent failures and I haven't been able to track them - down yet. Disable this test for now. + Closes #2305 -- curl_multi_add_handle.3: ... that timer callback is for event-based +- [Bruno Grasselli brought this change] -- comments: remove old and wrong multi/easy interface statements + README: language fix + + s/off/from + + Closes #2300 -- curl_multi_add_handle.3: mention the CURLMOPT_TIMERFUNCTION use +Patrick Monnerat (12 Feb 2018) +- http_chunks: don't write chunks twice with CURLOPT_HTTP_TRANSFER_DECODING on + + Bug: #2303 + Reported-By: Henry Roeland -- [John E. Malmberg brought this change] +Daniel Stenberg (9 Feb 2018) +- get_posix_time: only check for overflows if they can happen! - KNOWN_BUGS: 22 and 57 have been fixed and committed +Michael Kaufmann (9 Feb 2018) +- schannel: fix "no previous prototype" compiler warning -- RELEASE-NOTES: synced with d20def20462e7 +Jay Satiro (9 Feb 2018) +- [Mohammad AlSaleh brought this change] -- global dns cache: fix memory leak + content_encoding: Add "none" alias to "identity" - The take down of the global dns cache didn't take CURLOPT_RESOLVE names - into account. - -- global dns cache: didn't work [regression] + Some servers return a "content-encoding" header with a non-standard + "none" value. - CURLOPT_DNS_USE_GLOBAL_CACHE broke in commit c43127414d89ccb (been - broken since the libcurl 7.29.0 release). While this option has been - documented as deprecated for almost a decade and nobody even reported - this bug, it should remain functional. + Add "none" as an alias to "identity" as a work-around, to avoid + unrecognised content encoding type errors. - Added test case 1512 to verify + Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com> + + Closes https://github.com/curl/curl/pull/2298 + +Steve Holme (8 Feb 2018) +- build-openssl.bat: Follow up to 648679ab8e to suppress copy/move output -Yang Tse (8 Aug 2013) -- [John Malmberg brought this change] +- build-openssl.bat: Fixed incorrect move if destination build folder exists - packages/vms: update VMS build files +Michael Kaufmann (8 Feb 2018) +- schannel: fix compiler warnings - VMS modified files either missing from a previous commit and changes - to remove references to CVS repositories. + Closes #2296 -Daniel Stenberg (8 Aug 2013) -- FTP: renamed several local functions +Steve Holme (7 Feb 2018) +- curl_addrinfo.c: Allow Unix Domain Sockets to compile under Windows - The previous naming scheme ftp_state_post_XXXX() wasn't really helpful - as it wasn't always immediately after 'xxxx' and it wasn't easy to - understand what it does based on such a name. + Windows 10.0.17061 SDK introduces support for Unix Domain Sockets. + Added the necessary include file to curl_addrinfo.c. - This new one is instead ftp_state_yyyy() where yyyy describes what it - does or sends. + Note: The SDK (which is considered beta) has to be installed, VS 2017 + project file has to be re-targeted for Windows 10.0.17061 and #define + enabled in config-win32.h. -- mk-ca-bundle.1: don't install on make install - - Since the mk-ca-bundle tool itself isn't installed with make install, - there's no point in installing its documentation. +Patrick Monnerat (7 Feb 2018) +- fnmatch: optimize processing of consecutive *s and ?s pattern characters - Bug: http://curl.haxx.se/mail/lib-2013-08/0057.html - Reported-by: Guenter Knauf + Reported-By: Daniel Stenberg + Fixes #2291 + Closes #2293 -Yang Tse (7 Aug 2013) -- packages/vms/Makefile.am: add latest file additions to EXTRA_DIST +Steve Holme (6 Feb 2018) +- build-openssl.bat/build-wolfssl.bat: Build platform is optional + + Whilst the compiler parameter is mandatory, platform is optional as it + is automatically calculated by the :configure section. + + This partially reverts commit 6d62d2c55d. -- [John Malmberg brought this change] +Daniel Stenberg (6 Feb 2018) +- [Patrick Schlangen brought this change] - Building_vms_pcsi_kit + openssl: Don't add verify locations when verifypeer==0 - These are the files needed to build VMS distribution packages known as - PCSI kits. + When peer verification is disabled, calling + SSL_CTX_load_verify_locations is not necessary. Only call it when + verification is enabled to save resources and increase performance. - Also minor update to the existing files, mainly to the documentation and - file clean up code. + Closes #2290 -Daniel Stenberg (6 Aug 2013) -- LIBCURL-STRUCTS: new document +Steve Holme (5 Feb 2018) +- build-wolfssl.bat: Extend VC15 support to include Enterprise and Professional - This is the first version of this new document, detailing the seven - perhaps most important internal structs in libcurl source code: - - 1.1 SessionHandle - 1.2 connectdata - 1.3 Curl_multi - 1.4 Curl_handler - 1.5 conncache - 1.6 Curl_share - 1.7 CookieInfo + ...and not just the Community Edition. -- CONTRIBUTE: minor language polish +- build-openssl.bat: Extend VC15 support to include Enterprise and Professional + + ...and not just the Community Edition. -- FTP: when EPSV gets a 229 but fails to connect, retry with PASV +Michael Kaufmann (5 Feb 2018) +- time-cond: fix reading the file modification time on Windows - This is a regression as this logic used to work. It isn't clear when it - broke, but I'm assuming in 7.28.0 when we went all-multi internally. + On Windows, stat() may adjust the unix file time by a daylight saving time + offset. Avoid this by calling GetFileTime() instead. - This likely never worked with the multi interface. As the failed - connection is detected once the multi state has reached DO_MORE, the - Curl_do_more() function was now expanded somewhat so that the - ftp_do_more() function can request to go "back" to the previous state - when it makes another attempt - using PASV. + Fixes #2164 + Closes #2204 + +Daniel Stenberg (5 Feb 2018) +- formdata: use the mime-content type function - Added test case 1233 to verify this fix. It has the little issue that it - assumes no service is listening/accepting connections on port 1... + Reduce code duplication by making Curl_mime_contenttype available and + used by the formdata function. This also makes the formdata function + recognize a set of more file extensions by default. - Reported-by: byte_bucket in the #curl IRC channel - -Nick Zitzmann (5 Aug 2013) -- md5: remove use of CommonCrypto-to-OpenSSL macros for the benefit of Leopard + PR #2280 brought this to my attention. - For some reason, OS X 10.5's GCC suddenly stopped working correctly with - macros that change MD5_Init etc. in the code to CC_MD5_Init etc., so I - worked around this by removing use of the macros and inserting static - functions that just call CommonCrypto's implementations of the functions - instead. + Closes #2282 -Guenter Knauf (5 Aug 2013) -- Simplify check for trusted certificates. +- getdate: return -1 for out of range - This changes the previous check for untrusted certs to a check for - certs explicitely marked as trusted. - The change is backward-compatible (tested with certdata.txt v1.80). - -Daniel Stenberg (5 Aug 2013) -- configure: warn on bad env variable use, don't error + ...as that's how the function is documented to work. + + Reported-by: Michael Kaufmann + Bug found in an autobuild with 32 bit time_t - Use XC_CHECK_BUILD_FLAGS instead XC_CHECK_USER_FLAGS. + Closes #2278 + +- [Ben Greear brought this change] -- Revert "configure: don't error out on variable confusions, just warn" + build: fix termios issue on android cross-compile - This reverts commit 6b27703b5f525eccdc0a8409f51de8595c75132a. + Bug: https://curl.haxx.se/mail/lib-2018-01/0122.html + Signed-off-by: Ben Greear <greearb@candelatech.com> -- formadd: wrong pointer for file name when CURLFORM_BUFFERPTR used +- time_t-fixes: remove typecasts to 'long' for info.filetime - The internal function that's used to detect known file extensions for - the default Content-Type got the the wrong pointer passed in when - CURLFORM_BUFFER + CURLFORM_BUFFERPTR were used. This had the effect that - strlen() would be used which could lead to an out-of-bounds read (and - thus segfault). In most cases it would only lead to it not finding or - using the correct default content-type. + They're now wrong. - It also showed that test 554 and test 587 were testing for the - previous/wrong behavior and now they're updated as well. + Reported-by: Michael Kaufmann - Bug: http://curl.haxx.se/bug/view.cgi?id=1262 - Reported-by: Konstantin Isakov + Closes #2277 -Guenter Knauf (4 Aug 2013) -- Skip more untrusted certificates. +- curl_setup: move the precautionary define of SIZEOF_TIME_T - Christian Heimes brought to our attention that the certdata.txt - format has recently changed [1], causing ca-bundle.crt created - with mk-ca-bundle.[pl|vbs] to include untrusted certs. + ... up to before it may be used for the TIME_T_MAX/MIN logic. - [1] http://lists.debian.org/debian-release/2012/11/msg00411.html - -Daniel Stenberg (4 Aug 2013) -- configure: don't error out on variable confusions, just warn + Reported-by: Michael Kaufmann -- configure: rephrase the notice in _XC_CHECK_VAR_* +- parsedate: s/#if/#ifdef - Instead of claiming it is an error, we call it a "note" to reduce the - severity level. But the following text now says the [variable] "*should* - only be used to specify"... instead of previously having said "may". + Reported-by: Michael Kaufmann + Bug: https://github.com/curl/curl/commit/1c39128d974666107fc6d9ea15f294036851f224#commitcomment-27246479 -- multi: remove data->state.current_conn struct field +Patrick Monnerat (31 Jan 2018) +- fnmatch: pattern syntax can no longer fail + + Whenever an expected pattern syntax rule cannot be matched, the + character starting the rule loses its special meaning and the parsing + is resumed: + - backslash at the end of pattern string matches itself. + - Error in [:keyword:] results in set containing :\[dekorwy. + + Unit test 1307 updated for this new situation. - Not needed + Closes #2273 -- multi: remove the one_easy struct field +- fnmatch: accept an alphanum to be followed by a non-alphanum in char set - Since the merge of SessionHandle with Curl_one_easy, this indirection - isn't used anymore. + Also be more tolerant about set pattern syntax. + Update unit test 1307 accordingly. + + Bug: https://curl.haxx.se/mail/lib-2018-01/0114.html -- multi: rename all Curl_one_easy to SessionHandle +- fnmatch: do not match the empty string with a character set -- multi: remove the multi_pos struct field +Jay Satiro (30 Jan 2018) +- build: fix windows build methods for curl_ctype.c - Since Curl_one_easy is really a SessionHandle now, this indirection - doesn't exist anymore. - -- multi: remove easy_handle struct field + - Fix winbuild and the VS project generator to treat curl_ctype.{c,h} as + curlx files since they are required by both src and lib. - It isn't needed anymore + Follow-up to 4272a0b which added curl_ctype. -- multi: remove 'Curl_one_easy' struct, phase 1 +Daniel Stenberg (30 Jan 2018) +- progress-bar.d: update to match implementation - The motivation for having a separate struct that keep track of an easy - handle when using the multi handle was removed when we switched to - always using the multi interface internally. Now they were just two - separate struct that was always allocated for each easy handle. + ... since commit 993dd5651a6 - This first step just moves the Curl_one_easy struct members into the - SessionHandle struct and hides this somehow (== keeps the source code - changes to a minimum) by defining Curl_one_easy to SessionHandle + Reported-by: Martin Dreher + Bug: https://github.com/curl/curl/pull/2242#issuecomment-361059228 - The biggest changes in this commit are: + Closes #2271 + +- http2: set DEBUG_HTTP2 to enable more HTTP/2 logging - 1 - the linked list of easy handles had to be changed somewhat due - to the new struct layout. This made the main linked list pointer - get renamed to 'easyp' and there's also a new pointer to the last - node, called easylp. It is no longer circular but ends with ->next - pointing to NULL. New nodes are still added last. + ... instead of doing it unconditionally in debug builds. It cluttered up + the output a little too much. + +- [Max Dymond brought this change] + + file: Check the return code from Curl_range and bail out on error + +- [Max Dymond brought this change] + + Curl_range: add check to ensure "from <= to" + +- [Max Dymond brought this change] + + Curl_range: commonize FTP and FILE range handling - 2 - easy->state is now called easy->mstate to avoid name collision + Closes #2205 -Steve Holme (2 Aug 2013) -- Revert "DOCS: Added IMAP URL example for listing new messages" +- RELEASE-NOTES: synced with 811beab9f + +- curlver: next release will be 7.59.0 + +- [MichaÅ‚ Janiszewski brought this change] + + curl/curl.h: fix comment typo for CURLOPT_DNS_LOCAL_IP6 + + Closes #2275 + +- time: support > year 2038 time stamps for system with 32bit long + + ... with the introduction of CURLOPT_TIMEVALUE_LARGE and + CURLINFO_FILETIME_T. - This reverts commit 82ab5f1b0c7c3f as this was the wrong place to - document the complexity of IMAP URLs and Custom Requests. + Fixes #2238 + Closes #2264 -- DOCS: Added IMAP URL example for listing new messages +- curl_easy_reset: clear digest auth state - In addition to listing the folder contents, in the URL examples, added - an example to list the new messages waiting in the user's inbox. + Bug: https://curl.haxx.se/mail/lib-2018-01/0074.html + Reported-by: Ruurd Beerstra + Fixes #2255 + Closes #2272 -Yang Tse (1 Aug 2013) -- packages/vms/Makefile.am: add latest file additions to EXTRA_DIST +- [Adam Marcionek brought this change] -- [John Malmberg brought this change] + winbuild: make linker generate proper PDB + + Link.exe requires /DEBUG to properly generate a full pdb file on release + builds. + + Closes #2274 - Add in the files needed to build libcurl shared images on VMS. +- curl: add --proxy-pinnedpubkey - Update the packages/vms/readme file to be current. + To verify a proxy's public key. For when using HTTPS proxies. - Also some files for the GNV based build were either missing or needed an - update. + Fixes #2192 + Closes #2268 + +- configure: set PATH_SEPARATOR to colon for PATH w/o separator - curl_crtl_init.c is a special file that is run before main() to - set up the proper C runtime behavior. + The logic tries to figure out what the path separator in the $PATH + variable is, but if there's only one directory in the $PATH it + fails. This change make configure *guess* on colon instead of erroring + out, simply because that is probably the more common character. - generate_vax_transfer.com generates the VAX transfer vector modules from - the gnv_libcurl_symbols.opt file. + PATH_SEPARATOR can always be set by the user to override the guessing. - gnv_conftest.c_first is a helper file needed for configure scripts to - come up with the expected answers on VMS. + (tricky bug to reproduce, as in my case for example the configure script + requires binaries in more than one directory so passing in a PATH with a + single dir fails.) - gnv_libcurl_symbols.opt is the public symbols for the libcurl shared - image. + Reported-by: Earnestly on github + Fixes #2202 + Closes #2265 + +- curl_ctype: private is*() type macros and functions - gnv_link_curl.com builds the shared libcurl image and rebuilds other - programs to use it. + ... since the libc provided one are locale dependent in a way we don't + want. Also, the "native" isalnum() (for example) works differently on + different platforms which caused test 1307 failures on macos only. - macro32_exactcase.patch is a hack to make a local copy of the VMS Macro32 - assembler case sensitive, which is needed to build the VAX transfer modules. + Closes #2269 + +Marcel Raad (29 Jan 2018) +- build: open VC15 projects with VS 2017 - report_openssl_version.c is a tool for help verify that the libcurl - shared image is being built for a minium version of openssl. + Previously, they were opened with Visual Studio 2015 by default, which + cannot build them. -- curl: second follow-up for commit 5af2bfb9 +Daniel Stenberg (29 Jan 2018) +- RELEASE-NOTES: synced with 094647fca + +- TODO: UTF-8 filenames in Content-Disposition - Display progress-bar unconditionally on first call + Closes #1888 -- curl: follow-up for commit 5af2bfb9 +- KNOWN_BUGS: DICT responses show the underlying protocol - Use tvnow() and tvdiff() to avoid introducing new linkage issues + Closes #1809 -Daniel Stenberg (31 Jul 2013) -- curl: --progress-bar max update frequency now at 5Hz +Jay Satiro (27 Jan 2018) +- [Alessandro Ghedini brought this change] -- curl: make --progress-bar update the line less frequently + docs: fix typos in man pages - Also, use memset() instead of a lame loop. + Closes https://github.com/curl/curl/pull/2266 + +Patrick Monnerat (26 Jan 2018) +- lib555: drop text conversion and encode data as ascii codes - The previous logic that tried to avoid too many updates were very - ineffective for really fast transfers, as then it could easily end up - doing hundreds of updates per second that would make a significant - impact in transfer performance! + If CURL_DOES_CONVERSION is enabled, uploaded LFs are mapped to CRLFs, + giving a result that is different from what is expected. + This commit avoids using CURLOPT_TRANSFERTEXT and directly encodes data + to upload in ascii. - Bug: http://curl.haxx.se/mail/archive-2013-07/0031.html - Reported-by: Marc Doughty + Bug: https://github.com/curl/curl/pull/1872 -Nick Zitzmann (30 Jul 2013) -- darwinssl: added LFs to some strings passed into infof() +Daniel Stenberg (26 Jan 2018) +- lib517: make variable static to avoid compiler warning - (This doesn't need to appear in the release notes.) I noticed a few places - where infof() was called, and there should've been an LF at the end of the - string, but there wasn't. + ... with clang on macos -- darwinssl: fix build error in crypto authentication under Snow Leopard +Patrick Monnerat (26 Jan 2018) +- lib544: sync ascii code data with textual data - It turns out Snow Leopard not only has SecItemCopyMatching() defined in - a header not included by the omnibus header, but it won't work for our - purposes, because searching for SecIdentityRef objects wasn't added - to that API until Lion. So we now use the old SecKeychainSearch API - instead if the user is building under, or running under, Snow Leopard. + Data mismatch caused test 545 to fail when character encoding + conversion is enabled. - Bug: http://sourceforge.net/p/curl/bugs/1255/ - Reported by: Edward Rudd + Bug: https://github.com/curl/curl/pull/1872 + +Daniel Stenberg (25 Jan 2018) +- [Travis Burtrum brought this change] -- md5 & metalink: use better build macros on Apple operating systems + GSKit: restore pinnedpubkey functionality - Previously we used __MAC_10_X and __IPHONE_X to mark digest-generating - code that was specific to OS X and iOS. Now we use - __MAC_OS_X_VERSION_MAX_ALLOWED and __IPHONE_OS_VERSION_MAX_ALLOWED - instead of those macros. + inadvertently removed in 283babfaf8d8f3bab9d3c63cea94eb0b84e79c37 - Bug: http://sourceforge.net/p/curl/bugs/1255/ - Reported by: Edward Rudd + Closes #2263 -Yang Tse (29 Jul 2013) -- tool_operhlp.c: fix add_file_name_to_url() OOM handling +- [Dair Grant brought this change] -- tool_operate.c: fix brace placement for vi/emacs delimiter matching - -- tool_operate.c: move <fabdef.h> header inclusion location + darwinssl: Don't import client certificates into Keychain on macOS + + Closes #2085 -Daniel Stenberg (29 Jul 2013) -- RELEASE-NOTES: synced with b5478a0e033e7 +- configure: fix the check for unsigned time_t + + Assign the time_t variable negative value and then check if it is + greater than zero, which will evaluate true for unsigned time_t but + false for signed time_t. -- curl_easy_pause: on unpause, trigger mulit-socket handling +- parsedate: fix date parsing for systems with 32 bit long + + Make curl_getdate() handle dates before 1970 as well (returning negative + values). + + Make test 517 test dates for 64 bit time_t. - When the multi-socket API is used, we need the handle to be checked - again when it gets unpaused. + This fixes bug (3) mentioned in #2238 - Bug: http://curl.haxx.se/mail/lib-2013-07/0239.html - Reported-by: Justin Karneges + Closes #2250 -- [John E. Malmberg brought this change] +- [McDonough, Tim brought this change] - curl_formadd: fix file upload on VMS + openssl: fix pinned public key build error in FIPS mode - For the standard VMS text file formats, VMS needs to read the file to - get the actual file size. + Here is a version that should work with all versions of openssl 0.9.7 + through 1.1.0. - For the standard VMS binary file formats, VMS needs a special format of - fopen() call so that it stops reading at the logical end of file instead - of at the end of the blocks allocated to the file. + Links to the docs: + https://www.openssl.org/docs/man1.0.2/crypto/EVP_DigestInit.html + https://www.openssl.org/docs/man1.1.0/crypto/EVP_DigestInit.html - I structured the patch this way as I was not sure about changing the - structures or parameters to the routines, but would prefer to only call - the stat() function once and pass the information to where the fopen() - call is made. - - Bug: https://sourceforge.net/p/curl/bugs/758/ - -- formadd: CURLFORM_FILECONTENT wrongly rejected some option combos + At the very bottom of the 1.1.0 documentation there is a history section + that states, " stack allocated EVP_MD_CTXs are no longer supported." - The code for CURLFORM_FILECONTENT had its check for duplicate options - wrong so that it would reject CURLFORM_PTRNAME if used in combination - with it (but not CURLFORM_COPYNAME)! The flags field used for this - purpose cannot be interpreted that broadly. + If EVP_MD_CTX_create and EVP_MD_CTX_destroy are not defined, then a + simple mapping can be used as described here: + https://wiki.openssl.org/index.php/Talk:OpenSSL_1.1.0_Changes - Bug: http://curl.haxx.se/mail/lib-2013-07/0258.html - Reported-by: Byrial Jensen + Closes #2258 -Yang Tse (25 Jul 2013) -- packages/vms/Makefile.am: add latest file additions to EXTRA_DIST +- [Travis Burtrum brought this change] -- [John E. Malmberg brought this change] + SChannel/WinSSL: Replace Curl_none_md5sum with Curl_schannel_md5sum - VMS: intial set of files to allow building using GNV toolkit. +- [Travis Burtrum brought this change] -- string formatting: fix too many arguments for format + SChannel/WinSSL: Implement public key pinning + + Closes #1429 -- string formatting: fix zero-length printf format string +- bump: towards 7.58.1 -- easy.c: curl_easy_getinfo() fix va_start/va_end matching +- cookies: remove verbose "cookie size:" output + + It was once used for some debugging/verifying logic but should never have + ended up in git! -- imap.c: imap_sendf() fix va_start/va_end matching +- TODO: hardcode the "localhost" addresses -- string formatting: fix 15+ printf-style format strings +- TODO: CURL_REFUSE_CLEARTEXT + + An idea that popped up in discussions on twitter. -Patrick Monnerat (24 Jul 2013) -- OS400: sync ILE/RPG binding with current curl.h +- progress-bar: don't use stderr explicitly, use bar->out + + Reported-By: Gisle Vanem + Bug: https://github.com/curl/curl/commit/993dd5651a6c853bfe3870f6a69c7b329fa4e8ce#commitcomment-27070080 -Yang Tse (24 Jul 2013) -- string formatting: fix 25+ printf-style format strings +GitHub (24 Jan 2018) +- [Gisle Vanem brought this change] -Daniel Stenberg (23 Jul 2013) -- Makefile.am: use LDFLAGS as well when linking libcurl + Fixes for MSDOS etc. + + djgpp do have 'mkdir(dir, mode)'. Other DOS-compilers does not + But djgpp seems the only choice for MSDOS anyway. - Linking on Solaris 10 x86 with Sun Studio 12 failed when we upgraded - automake for the release builds. + PellesC do have a 'F_OK' defined in it's <unistd.h>. - Bug: http://curl.haxx.se/bug/view.cgi?id=1217 - Reported-by: Dagobert Michelsen + Update year in Copyright. -- [Fabian Keil brought this change] +- [Gisle Vanem brought this change] - url.c: Fix dot file path cleanup when using an HTTP proxy - - Previously the path was cleaned, but the URL wasn't properly updated. + Fix small typo. -- [Fabian Keil brought this change] +Version 7.58.0 (23 Jan 2018) - tests: test1232 verifies dotdot removal from path with proxy +Daniel Stenberg (23 Jan 2018) +- RELEASE: 7.58.0 -- [Fabian Keil brought this change] +- [Gisle Vanem brought this change] - dotdot.c: Fix a RFC section number in a comment for Curl_dedotdotify() + progress-bar: get screen width on windows -- [John E. Malmberg brought this change] +- test1454: --connect-to with IPv6 address w/o IPv6 support! - build_vms.com: fix debug and float options +- CONNECT_TO: fail attempt to set an IPv6 numerical without IPv6 support - In the reorganization of the build_vms.com the debug and float options - were not fixed up correctly. + Bug: https://curl.haxx.se/mail/lib-2018-01/0087.html + Reported-by: John Hascall + + Closes #2257 -- [John E. Malmberg brought this change] +- docs: fix man page syntax to make test 1140 OK again - curl: fix upload of a zip file in OpenVMS +- http: prevent custom Authorization headers in redirects - Two fixes: + ... unless CURLOPT_UNRESTRICTED_AUTH is set to allow them. This matches how + curl already handles Authorization headers created internally. - 1. Force output file format to be stream-lf so that partial downloads - can be continued. + Note: this changes behavior slightly, for the sake of reducing mistakes. - This should have minor impact as if the file does not exist, it was - created with stream-lf format. The only time this was an issue is if - there was already an existing file with a different format. + Added test 317 and 318 to verify. - 2. Fix file uploads are now fixed. + Reported-by: Craig de Stigter + Bug: https://curl.haxx.se/docs/adv_2018-b3bf.html + +- curl: progress bar refresh, get width using ioctl() - a. VMS binary files such as ZIP archives are now uploaded - correctly. + Get screen width from the environment variable COLUMNS first, if set. If + not, use ioctl(). If nether works, assume 79. - b. VMS text files are read once to get the correct size - and then converted to line-feed terminated records as - they are read into curl. + Closes #2242 - The default VMS text formats do not contain either line-feed or - carriage-return terminated records. Those delimiters are added by the - operating system file read calls if the application requests them. + The "refresh" is for the -# output when no total transfer size is + known. It will now only use a single updated line even for this case: - Bug: http://curl.haxx.se/bug/view.cgi?id=496 + The "-=O=-" ship moves when data is transferred. The four flying + "hashes" move (on a sine wave) on each refresh, independent of data. -Yang Tse (22 Jul 2013) -- libtest: fix data type of some *_setopt() 'long' arguments +- RELEASE-NOTES: synced with bb0ffcc36 -- curl: fix symbolic names for CURL_NETRC_* enum in --libcurl output +- libcurl-env.3: first take -- curl: fix symbolic names for CURLUSESSL_* enum in --libcurl output +- TODO: two possible name resolver improvements -- tool_operate.c: fix passing curl_easy_setopt long arg on some x64 ABIs - - We no longer pass our 'bool' data type variables nor constants as - an argument to my_setopt(), instead we use proper 1L or 0L values. - - This also fixes macro used to pass string argument for CURLOPT_SSLCERT, - CURLOPT_SSLKEY and CURLOPT_EGDSOCKET using my_setopt_str() instead of - my_setopt(). - - This also casts enum or int argument data types to long when passed to - my_setopt_enum(). +- [Kartik Mahajan brought this change] -Daniel Stenberg (21 Jul 2013) -- curl_multi_wait: fix revents - - Commit 6d30f8ebed34e7276 didn't work properly. First, it used the wrong - array index, but this fix also: + http2: don't close connection when single transfer is stopped - 1 - only does the copying if indeed there was any activity + Fixes #2237 + Closes #2249 + +- test558: fix for multissl builds - 2 - makes sure to properly translate between internal and external - bitfields, which are not guaranteed to match + vtls.c:multissl_init() might do a curl_free() call so strip that out to + make this work with more builds. We just want to verify that + memorytracking works so skipping one line is no harm. + +- examples/url2file.c: add missing curl_global_cleanup() call - Reported-by: Evgeny Turnaev + Reported-by: XhstormR on github + Fixes #2245 -- RELEASE-NOTES: synced with d529f3882b9bca +- [Michael Gmelin brought this change] -- curl_easy_perform: gradually increase the delay time + SSH: Fix state machine for ssh-agent authentication - Instead of going 50,100,150 etc millisecond delay time when nothing has - been found to do or wait for, we now start lower and double each loop as - in 4,8,16,32 etc. + In case an identity didn't match[0], the state machine would fail in + state SSH_AUTH_AGENT instead of progressing to the next identity in + ssh-agent. As a result, ssh-agent authentication only worked if the + identity required happened to be the first added to ssh-agent. - This lowers the minimum wait without sacrifizing the longer wait too - much with unnecessary CPU cycles burnt. + This was introduced as part of commit c4eb10e2f06fbd6cc904f1d78e4, which + stated that the "else" statement was required to prevent getting stuck + in state SSH_AUTH_AGENT. Given the state machine's logic and libssh2's + interface I couldn't see how this could happen or reproduce it and I + also couldn't find a more detailed description of the problem which + would explain a test case to reproduce the problem this was supposed to + fix. - Bug: http://curl.haxx.se/mail/lib-2013-07/0103.html - Reported-by: Andreas Malzahn - -- ftp_do_more: consider DO_MORE complete when server connects back - - In the case of an active connection when ftp_do_more() detects that the - server has connected back, it must make sure to mark it as complete so - that the multi_runsingle() function will detect this and move on to the - next state. + [0] libssh2_agent_userauth returning LIBSSH2_ERROR_AUTHENTICATION_FAILED - Bug: http://curl.haxx.se/mail/lib-2013-07/0115.html - Reported-by: Clemens Gruber - -Yang Tse (19 Jul 2013) -- Makefile.b32: Borland makefile adjustments. Tested with BCC 5.5.1 - -- WIN32 MemoryTracking: require UNICODE for wide strdup code support + Closes #2248 -Daniel Stenberg (18 Jul 2013) -- CURLOPT_XFERINFOFUNCTION: introducing a new progress callback +- openssl: fix potential memory leak in SSLKEYLOGFILE logic - CURLOPT_XFERINFOFUNCTION is now the preferred progress callback function - and CURLOPT_PROGRESSFUNCTION is considered deprecated. - - This new callback uses pure 'curl_off_t' arguments to pass on full - resolution sizes. It otherwise retains the same characteristics: the - same call rate, the same meanings for the arguments and the return code - is used the same way. - - The progressfunc.c example is updated to show how to use the new - callback for newer libcurls while supporting the older one if built with - an older libcurl or even built with a newer libcurl while running with - an older. + Coverity CID 1427646. -Yang Tse (18 Jul 2013) -- Reinstate "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage". +- openssl: fix the libressl build again - This reverts commit 7ed25cc, reinstating commit 8ec2cb5. + Follow-up to 84fcaa2e7. libressl does not have the API even if it says it is + late OpenSSL version... - As of 18-jul-2013 we still do have code in libcurl that makes use of these - memory functions. Commit 8ec2cb5 comment still applies and is yet valid. + Fixes #2246 + Closes #2247 - These memory functions are solely used in Windows builds, so all related - code is protected with '#ifdef WIN32' preprocessor conditional compilation - directives. + Reported-by: jungle-boogie on github + +- unit1307: test many wildcards too + +- curl_fnmatch: only allow 5 '*' sections in a single pattern - Specifically, wcsdup() _wcsdup() are used when building a Windows target with - UNICODE and USE_WINDOWS_SSPI preprocessor symbols defined. This is the case - when building a Windows UNICODE target with Windows native SSL/TLS support - enabled. + ... to avoid excessive recursive calls. The number 5 is totally + arbitrary and could be modified if someone has a good motivation. + +- ftp-wildcard: fix matching an empty string with "*[^a]" - Realizing that wcsdup() _wcsdup() are used is a bit tricky given that usage - of these is hidden behind _tcsdup() which is MS way of dealing with code - that must tolerate UNICODE and non-UNICODE compilation. Additionally, MS - header files and those compatible from other compilers use this preprocessor - conditional compilation directive in order to select at compilation time - whether 'wide' or 'ansi' MS API functions are used. + .... and avoid advancing the pointer to trigger an out of buffer read. - Without this code, Windows build targets with Windows native SSL/TLS support - enabled and MemoryTracking support enabled misbehave in tracking memory usage, - regardless of being a UNICODE enabled build or not. - -- xc-am-iface.m4: comments refinement + Detected by OSS-fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5251 + Assisted-by: Max Dymond -- configure: fix 'subdir-objects' distclean related issue +- SMB: fix numeric constant suffix and variable types - See XC_AMEND_DISTCLEAN comments for details. + 1. don't use "ULL" suffix since unsupported in older MSVC + 2. use curl_off_t instead of custom long long ifdefs + 3. make get_posix_time() not do unaligned data access + + Fixes #2211 + Closes #2240 + Reported-by: Chester Liu -Daniel Stenberg (18 Jul 2013) -- [Evgeny Turnaev brought this change] +- [rouzier brought this change] - curl_multi_wait: set revents for extra fds + CURLOPT_TCP_NODELAY.3: fix typo - Pass back the revents that happened for the user-provided file - descriptors. - -- [Ben Greear brought this change] + Closes #2239 - asyn-ares: Don't blank ares servers if none configured. +- smtp/pop3/imap_get_message: decrease the data length too... - Best to just let c-ares use it's defaults if none are configured - in (lib)curl. + Follow-up commit to 615edc1f73 which was incomplete. - Signed-off-by: Ben Greear <greearb@candelatech.com> + Assisted-by: Max Dymond + Detected by OSS-fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5206 -- [Sergei Nikulov brought this change] +- openssl: enable SSLKEYLOGFILE support by default + + Fixes #2210 + Closes #2236 - cmake: Fix for MSVC2010 project generation +Patrick Monnerat (14 Jan 2018) +- mime: clone mime tree upon easy handle duplication. - Fixed issue with static build for MSVC2010. + A mime tree attached to an easy handle using CURLOPT_MIMEPOST is + strongly bound to the handle: there is a pointer to the easy handle in + each item of the mime tree and following the parent pointer list + of mime items ends in a dummy part stored within the handle. - After some investigation I've discovered known issue - http://public.kitware.com/Bug/view.php?id=11240 When .rc file is linked - to static lib it fails with following linker error + Because of this binding, a mime tree cannot be shared between different + easy handles, thus it needs to be cloned upon easy handle duplication. - LINK : warning LNK4068: /MACHINE not specified; defaulting to X86 - file.obj : fatal error LNK1112: module machine type 'x64' conflicts with - target machine type 'X86' + There is no way for the caller to get the duplicated mime tree + handle: it is then set to be automatically destroyed upon freeing the + new easy handle. - Fix add target property /MACHINE: for MSVC generation. + New test 654 checks proper mime structure duplication/release. - Also removed old workarounds - it caused errors during msvc build. + Add a warning note in curl_mime_data_cb() documentation about sharing + user data between duplicated handles. - Bug: http://curl.haxx.se/mail/lib-2013-07/0046.html + Closes #2235 -- mk-ca-bundle.1: point out certdata.txt format docs +- docs: comment about CURLE_READ_ERROR returned by curl_mime_filedata -Yang Tse (16 Jul 2013) -- slist.c: Curl_slist_append_nodup() OOM handling fix +Daniel Stenberg (13 Jan 2018) +- test395: HTTP with overflow Content-Length value -Daniel Stenberg (16 Jul 2013) -- test1414: FTP PORT download without SIZE support +- test394: verify abort of rubbish in Content-Length: value -Yang Tse (16 Jul 2013) -- tests/Makefile.am: add configurehelp.pm to DISTCLEANFILES +- test393: verify --max-filesize with excessive Content-Length -Patrick Monnerat (15 Jul 2013) -- curl_slist_append(): fix error detection +- HTTP: bail out on negative Content-Length: values + + ... and make the max filesize check trigger if the value is too big. + + Updates test 178. + + Reported-by: Brad Spencer + Fixes #2212 + Closes #2223 -- slist.c: fix indentation +Marcel Raad (13 Jan 2018) +- [Dan Johnson brought this change] -- OS400: new SSL backend GSKit + configure.ac: append extra linker flags instead of prepending them. + + Link order should list libraries after the libraries that use them, + so when we're guessing that we might also need to add -ldl in order + to use -lssl, we should add -ldl after -lssl. + + Closes https://github.com/curl/curl/pull/2234 -- OS400: add slist and certinfo EBCDIC support +Daniel Stenberg (13 Jan 2018) +- RELEASE-NOTES: synced with 6fa10c8fa -- config-os400.h: enable system strdup(), strcmpi(), etc. +Jay Satiro (13 Jan 2018) +- setopt: fix SSLVERSION to allow CURL_SSLVERSION_MAX_ values + + Broken since f121575 (precedes 7.56.1). + + Bug: https://github.com/curl/curl/issues/2225 + Reported-by: cmfrolick@users.noreply.github.com + + Closes https://github.com/curl/curl/pull/2227 -- x509asn1.c,x509asn1.h: new module to support ASN.1/X509 parsing & info extract - Use from qssl backend +Patrick Monnerat (13 Jan 2018) +- setopt: reintroduce non-static Curl_vsetopt() for OS400 support + + This also upgrades ILE/RPG bindings with latest setopt options. + + Reported-By: jonrumsey on github + Fixes #2230 + Closes #2233 -- ssluse.c,sslgen.c,sslgen.h: move certinfo support to generic SSL +Jay Satiro (11 Jan 2018) +- [Zhouyihai Ding brought this change] -- Merge branch 'master' of github.com:bagder/curl + http2: fix incorrect trailer buffer size - Merge for resync + Prior to this change the stored byte count of each trailer was + miscalculated and 1 less than required. It appears any trailer + after the first that was passed to Curl_client_write would be truncated + or corrupted as well as the size. Potentially the size of some + subsequent trailer could be erroneously extracted from the contents of + that trailer, and since that size is used by client write an + out-of-bounds read could occur and cause a crash or be otherwise + processed by client write. + + The bug appears to have been born in 0761a51 (precedes 7.49.0). + + Closes https://github.com/curl/curl/pull/2231 -- slist.c, slist.h, cookie.c: new internal procedure Curl_slist_append_nodup() +- [Basuke Suzuki brought this change] -Yang Tse (15 Jul 2013) -- sslgen.c: fix Curl_rand() compiler warning + easy: fix connection ownership in curl_easy_pause - Use simple seeding method upon RANDOM_FILE seeding method failure. - -- sslgen.c: fix unreleased Curl_rand() infinite recursion + Before calling Curl_client_chop_write(), change the owner of connection + to the current Curl_easy handle. This will fix the issue #2217. + + Fixes https://github.com/curl/curl/issues/2217 + Closes https://github.com/curl/curl/pull/2221 -Daniel Stenberg (14 Jul 2013) -- [Dave Reisner brought this change] +Daniel Stenberg (9 Jan 2018) +- [Dimitrios Apostolou brought this change] - src/tool: allow timeouts to accept decimal values + system.h: Additionally check __LONG_MAX__ for defining curl_off_t - Implement wrappers around strtod to convert the user argument to a - double with sane error checking. Use this to allow --max-time and - --connect-timeout to accept decimal values instead of strictly integers. + __SIZEOF_LONG__ was introduced in GCC 4.4, __LONG_MAX__ was introduced + in GCC 3.3. - The manpage is updated to make mention of this feature and, - additionally, forewarn that the actual timeout of the operation can - vary in its precision (particularly as the value increases in its - decimal precision). + Closes #2216 -- [Dave Reisner brought this change] +- COPYING: it's 2018! - curl.1: fix long line, found by checksrc.pl - -- [Dave Reisner brought this change] +- progress: calculate transfer speed on milliseconds if possible + + to increase accuracy for quick transfers + + Fixes #2200 + Closes #2206 - src/tool_paramhlp: try harder to catch negatives +Jay Satiro (7 Jan 2018) +- scripts: allow all perl scripts to be run directly + + - Enable execute permission (chmod +x) - strto* functions happily chomp off leading whitespace, so simply - checking for str[0] can lead to false negatives. Do the full parse and - check the out value instead. + - Change interpreter to /usr/bin/env perl + + Closes https://github.com/curl/curl/pull/2222 -- [John E. Malmberg brought this change] +- mail-rcpt.d: fix short-text description - build_vms.com: detect and use zlib shared image +- build: remove HAVE_LIMITS_H check - Update the build_vms.com to detect and use zlib shared image installed - by the ZLIB kit produced by Jean-Francois Pieronne, and the also the - future ZLIB 1.2.8 kit in addition to the older ZLIB kits. + .. because limits.h presence isn't optional, it's required by C89. - Also fix the indentation to match one of the common standards used for - VMS DCL command files and removed the hard tab characters. + Ref: http://port70.net/~nsz/c/c89/c89-draft.html#2.2.4.2 - Tested on OpenVMS 8.4 Alpha and IA64, and OpenVMS 7.3 VAX. + Closes https://github.com/curl/curl/pull/2215 -Yang Tse (14 Jul 2013) -- url.c: fix parse_url_login() OOM handling +- openssl: fix memory leak of SSLKEYLOGFILE filename + + - Free the copy of SSLKEYLOGFILE env returned by curl_getenv during ossl + initialization. + + Caught by ASAN. -- http_digest.c: SIGSEGV and OOM handling fixes +- Revert "curl/system.h: fix compilation with gcc on AIX PPC and IA64 HP-UX" + + This reverts commit c97648b55080343bb371522bf4233e94a2a13a99. + + SIZEOF_LONG should not be checked in system.h since that macro is only + defined when building libcurl. + + Ref: https://github.com/curl/curl/pull/2186#issuecomment-354767080 + Ref: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html -- url.c: fix parse_login_details() OOM handling +Michael Kaufmann (30 Dec 2017) +- test1554: improve the error handling -- [John E. Malmberg brought this change] +- test1554: add global initialization and cleanup - setup-vms.h: sk_pop symbol tweak +Daniel Stenberg (29 Dec 2017) +- curl_version_info.3: call the argument 'age' - Newer versions of curl are referencing a sk_pop symbol while the HP - OpenSSL library has the symbol in uppercase only. - -- getinfo.c: fix enumerated type mixed with another type + Reported-by: Pete Lomax + Bug: https://curl.haxx.se/mail/lib-2017-12/0074.html -- test 1511: fix enumerated type mixed with another type +Patrick Monnerat (27 Dec 2017) +- [Mikalai Ananenka brought this change] -- url.c: fix SIGSEGV + brotli: data at the end of content can be lost + + Decoding loop implementation did not concern the case when all + received data is consumed by Brotli decoder and the size of decoded + data internally hold by Brotli decoder is greater than CURL_MAX_WRITE_SIZE. + For content with unencoded length greater than CURL_MAX_WRITE_SIZE this + can result in the loss of data at the end of content. + + Closes #2194 -- dotdot.c: fix global declaration shadowing +Jay Satiro (26 Dec 2017) +- examples/cacertinmem: ignore cert-already-exists error + + - Ignore X509_R_CERT_ALREADY_IN_HASH_TABLE errors in the CTX callback + since it's possible the cert may have already been loaded by libcurl. + + - Remove the EXAMPLE code in the CURLOPT_SSL_CTX_FUNCTION.3 doc. + Instead have it direct the reader to this cacertinmem.c example. + + - Fix the CA certificate to use the right CA for example.com, Digicert. + + Bug: https://curl.haxx.se/mail/lib-2017-12/0057.html + Reported-by: Thomas van Hesteren + + Closes https://github.com/curl/curl/pull/2182 -- easy.c: fix global declaration shadowing +- [Gisle Vanem brought this change] -Kamil Dudka (9 Jul 2013) -- Revert "curl.1: document the --time-cond option in the man page" + tool_getparam: Support size modifiers for --max-filesize + + - Move the size modifier detection code from limit-rate to its own + function so that it can also be used with max-filesize. + + Size modifiers are the suffixes such as G (gigabyte), M (megabyte) etc. + + For example --max-filesize 1G - This reverts commit 3a0e931fc715a80004958794a96b12cf90503f99 because - the documentation of --time-cond was duplicated by mistake. + Ref: https://curl.haxx.se/mail/archive-2017-12/0000.html - Reported by: Dave Reisner + Closes https://github.com/curl/curl/pull/2179 -- curl.1: document the --sasl-ir option in the man page +Steve Holme (22 Dec 2017) +- build: Fixed incorrect script termination from commit ad1dc10e61 -- curl.1: document the --post303 option in the man page +- Makefile.vc: Added our standard copyright header -- curl.1: document the --time-cond option in the man page +- winbuild: Added support for VC15 -Yang Tse (9 Jul 2013) -- configure: automake 1.14 compatibility tweak (use XC_AUTOMAKE) +- build: Added Visual Studio 2017 project files -- xc-am-iface.m4: provide XC_AUTOMAKE macro +- build-wolfssl.bat: Added support for VC15 -Guenter Knauf (8 Jul 2013) -- Added winssl-zlib target to VC builds. +- build-openssl.bat: Added support for VC15 -- Synced Makefile.vc6 with recent changes. +Jay Satiro (22 Dec 2017) +- [Dimitrios Apostolou brought this change] + + curl/system.h: fix compilation with gcc on AIX PPC and IA64 HP-UX - Issue posted to the list by malinowsky AT FTW DOT at. + Closes https://github.com/curl/curl/pull/2186 -- Added libmetalink URL; added Android versions. +- [Mattias Fornander brought this change] -Dan Fandrich (3 Jul 2013) -- examples: Moved usercertinmem.c to COMPLICATED_EXAMPLES + examples/rtsp: fix error handling macros - This prevents it from being built during a "make check" since it - depends on OpenSSL. + Closes https://github.com/curl/curl/pull/2185 -Nick Zitzmann (2 Jul 2013) -- Merge branch 'master' of https://github.com/bagder/curl +Patrick Monnerat (20 Dec 2017) +- curl_easy_reset: release mime-related data. + + Move curl_mime_initpart() and curl_mime_cleanpart() calls to lower-level + functions dealing with UserDefined structure contents. + This avoids memory leakages on curl-generated part mime headers. + New test 2073 checks this using the cli tool --next option: it + triggers a valgrind error if bug is present. + + Bug: https://curl.haxx.se/mail/lib-2017-12/0060.html + Reported-by: Martin Galvan -- darwinssl: SSLv2 connections are aborted if unsupported by the OS +- content_encoding: rework zlib_inflate + + - When zlib version is < 1.2.0.4, process gzip trailer before considering + extra data as an error. + - Inflate with Z_BLOCK instead of Z_SYNC_FLUSH to maximize correct data + and minimize corrupt data output. + - Do not try to restart deflate decompression in raw mode if output has + started or if the leading data is not available anymore. + - New test 232 checks inflating raw-deflated content. - I just noticed that OS X no longer supports SSLv2. Other TLS engines return - an error if the requested protocol isn't supported by the underlying - engine, so we do that now for SSLv2 if the framework returns an error - when trying to turn on SSLv2 support. (Note: As always, SSLv2 support is - only enabled in curl when starting the app with the -2 argument; it's off - by default. SSLv2 is really old and insecure.) + Closes #2068 -Marc Hoersken (1 Jul 2013) -- lib506.c: Fixed possible use of uninitialized variables +- brotli: allow compiling with version 0.6.0. + + Some error codes were not yet defined in brotli 0.6.0: do not issue code + for them in this case. -Kamil Dudka (30 Jun 2013) -- url: restore the functionality of 'curl -u :' +Daniel Stenberg (13 Dec 2017) +- CURLOPT_READFUNCTION.3: refer to argument with correct name - This commit fixes a regression introduced in - fddb7b44a79d78e05043e1c97e069308b6b85f79. + Bug: #2175 - Reported by: Markus Moeller - Bug: http://curl.haxx.se/mail/archive-2013-06/0052.html - -Daniel Stenberg (25 Jun 2013) -- digest: append the timer to the random for the nonce + [ci skip] -- digest: improve nonce generation +- rand: add a clang-analyzer work-around - Use the new improved Curl_rand() to generate better random nonce for - Digest auth. + scan-build would warn on a potential access of an uninitialized + buffer. I deem it a false positive and had to add this somewhat ugly + work-around to silence it. -- curl.1: fix typo in --xattr description +- krb5: fix a potential access of uninitialized memory - Bug: http://curl.haxx.se/bug/view.cgi?id=1252 - Reported-by: Jean-Noël Rouvignac + A scan-build warning. -- RELEASE-NOTES: synced with 365c5ba39591 +- conncache: fix a return code [regression] - The 10 first bug fixes for the pending release... + This broke in 07cb27c98e. Make sure to return 'result' properly. Pointed + out by scan-build! -- formpost: better random boundaries +- curl: support >256 bytes warning messsages - When doing multi-part formposts, libcurl used a pseudo-random value that - was seeded with time(). This turns out to be bad for users who formpost - data that is provided with users who then can guess how the boundary - string will look like and then they can forge a different formpost part - and trick the receiver. + Bug: #2174 + +Michael Kaufmann (12 Dec 2017) +- libssh: fix a syntax error in configure.ac - My advice to such implementors is (still even after this change) to not - rely on the boundary strings being cryptographically strong. Fix your - code and logic to not depend on them that much! + Follow-up to c92d2e1 - I moved the Curl_rand() function into the sslgen.c source file now to be - able to take advantage of the SSL library's random function if it - provides one. If not, try to use the RANDOM_FILE for seeding and as a - last resort keep the old logic, just modified to also add microseconds - which makes it harder to properly guess the exact seed. + Closes #2172 + +Daniel Stenberg (12 Dec 2017) +- examples/smtp-mail.c: use separate defines for options and mail - The formboundary() function in formdata.c is now using 64 bit entropy - for the boundary and therefore the string of dashes was reduced by 4 - letters and there are 16 hex digits following it. The total length is - thus still the same. + ... to make it clearer that the options want address-only, while the + headers in an email can also have the real name. - Bug: http://curl.haxx.se/bug/view.cgi?id=1251 - Reported-by: "Floris" + Assisted-by: Sean MacLennan -- printf: make sure %x are treated unsigned +- THANKS: added missing names - When using %x, the number must be treated as unsigned as otherwise it - would get sign-extended on for example 64bit machines and do wrong - output. This problem showed when doing printf("%08x", 0xffeeddcc) on a - 64bit host. + ... as I reran the contrithanks script after the mailmap name fixups. -- tests: add test1395 to the tarball +- mailmap: added/clarified several names -- SIGPIPE: don't use 'data' in sigpipe restore +- setopt: less *or equal* than INT_MAX/1000 should be fine - Follow-up fix from 7d80ed64e43515. + ... for the CURLOPT_TIMEOUT, CURLOPT_CONNECTTIMEOUT and + CURLOPT_SERVER_RESPONSE_TIMEOUT range checks. - The SessionHandle may not be around to use when we restore the sigpipe - sighandler so we store the no_signal boolean in the local struct to know - if/how to restore. - -- TODO: 1.8 Modified buffer size approach + Reported-by: Dominik Hölzl + Bug: https://curl.haxx.se/mail/lib-2017-12/0037.html - Thoughts around buffer sizes and what might be possible to do... + Closes #2173 -- c-ares: improve error message on failed resolve - - When the c-ares based resolver backend failed to resolve a name, it - tried to show the name that failed from existing structs. This caused - the wrong output and shown hostname when for example --interface - [hostname] was used and that name resolving failed. +- [Dmitry Kostjuchenko brought this change] + + vtls: replaced getenv() with curl_getenv() - Now we use the hostname used in the actual resolve attempt in the error - message as well. + Fixed undefined symbol of getenv() which does not exist when compiling + for Windows 10 App (CURL_WINDOWS_APP). Replaced getenv() with + curl_getenv() which is aware of getenv() absence when CURL_WINDOWS_APP + is defined. - Bug: http://curl.haxx.se/bug/view.cgi?id=1191 - Reported-by: Kim Vandry + Closes #2171 -- ossl_recv: check for an OpenSSL error, don't assume - - When we recently started to treat a zero return code from SSL_read() as - an error we also got false positives - which primarily looks to be - because the OpenSSL documentation is wrong and a zero return code is not - at all an error case in many situations. +- RELEASE-NOTES: synced with 3b9ea70ee + +- TODO: Expose tried IP addresses that failed - Now ossl_recv() will check with ERR_get_error() to see if there is a - stored error and only then consider it to be a true error if SSL_read() - returned zero. + Suggested-by: Rainer Canavan - Bug: http://curl.haxx.se/bug/view.cgi?id=1249 - Reported-by: Nach M. S. - Patch-by: Nach M. S. + Closes #2126 -Nick Zitzmann (22 Jun 2013) -- Merge branch 'master' of https://github.com/bagder/curl +- curl.1: mention http:// and https:// as valid proxy prefixes -- darwinssl: fix crash that started happening in Lion - - Something (a recent security update maybe?) changed in Lion, and now it - has changed SSLCopyPeerTrust such that it may return noErr but also give - us a null trust, which caught us off guard and caused an eventual crash. +- curl.1: documented two missing valid exit codes + +- CURLOPT_DNS_LOCAL_IP4.3: fixed the seel also to not self-reference -Daniel Stenberg (22 Jun 2013) -- SIGPIPE: ignored while inside the library +- Revert "curl: don't set CURLOPT_INTERLEAVEDATA" - ... and restore the ordinary handling again when it returns. This is - done for curl_easy_perform() and curl_easy_cleanup() only for now - and - only when built to use OpenSSL as backend as this is the known culprit - for the spurious SIGPIPEs people have received. + This reverts commit 9ffad8eb1329bb35c8988115ac7ed85cf91ef955. - Bug: http://curl.haxx.se/bug/view.cgi?id=1180 - Reported by: LluÃs Batlle i Rossell + It was actually added rather recently in 8e8afa82cbb629 due to a crash + that would otherwise happen in the RTSP code. As I don't think we've + fixed that behavior yet, we better keep this work-around until we have + fixed it better. -- KNOWN_BUGS: #83 unable to load non-default openssl engines +Michael Kaufmann (10 Dec 2017) +- tests: mark data files as non-executable in git -- test1396: invoke the correct test tool! - - This erroneously run unit test 1310 instead of 1396! +- tests: update .gitignore for libtests -Kamil Dudka (22 Jun 2013) -- test1230: avoid using hard-wired port number +Daniel Stenberg (10 Dec 2017) +- multi_done: prune DNS cache - ... to prevent failure when a non-default -b option is given - -- curl-config.in: replace tabs by spaces - -Nick Zitzmann (22 Jun 2013) -- darwinssl: reform OS-specific #defines + Prune the DNS cache immediately after the dns entry is unlocked in + multi_done. Timed out entries will then get discarded in a more orderly + fashion. - This doesn't need to be in the release notes. I cleaned up a lot of the #if - lines in the code to use MAC_OS_X_VERSION_MIN_REQUIRED and - MAC_OS_X_VERSION_MAX_ALLOWED instead of checking for whether things like - __MAC_10_6 or whatever were defined, because for some SDKs Apple has released - they were defined out of place. - -Daniel Stenberg (22 Jun 2013) -- [Alessandro Ghedini brought this change] + Test506 is updated + + Reported-by: Oleg Pudeyev + + Fixes #2169 + Closes #2170 - docs: fix typo in curl_easy_getinfo manpage +- mailmap: fixup two old git Author "aliases" -- dotdot: introducing dot file path cleanup +Jay Satiro (10 Dec 2017) +- openssl: Disable file buffering for Win32 SSLKEYLOGFILE - RFC3986 details how a path part passed in as part of a URI should be - "cleaned" from dot sequences before getting used. The described - algorithm is now implemented in lib/dotdot.c with the accompanied test - case in test 1395. + Prior to this change SSLKEYLOGFILE used line buffering on WIN32 just + like it does for other platforms. However, the Windows CRT does not + actually support line buffering (_IOLBF) and will use full buffering + (_IOFBF) instead. We can't use full buffering because multiple processes + may be writing to the file and that could lead to corruption, and since + full buffering is the only buffering available this commit disables + buffering for Windows SSLKEYLOGFILE entirely (_IONBF). - Bug: http://curl.haxx.se/bug/view.cgi?id=1200 - Reported-by: Alex Vinnik + Ref: https://github.com/curl/curl/pull/1346#issuecomment-350530901 -- bump: start working towards what most likely will become 7.32.0 +Daniel Stenberg (10 Dec 2017) +- RESOLVE: output verbose text when trying to set a duplicate name + + ... to help users understand what is or isn't done! -- THANKS: added 24 new contributors from the 7.31.0 release +- CURLOPT_DNS_CACHE_TIMEOUT.3: see also CURLOPT_RESOLVE -Version 7.31.0 (22 Jun 2013) +- [John DeHelian brought this change] -Daniel Stenberg (22 Jun 2013) -- RELEASE-NOTES: synced with 0de7249bb39a2 - 7.31.0 + sftp: allow quoted commands to use relative paths + + Closes #1900 -- unit1396: unit tests to verify curl_easy_(un)escape +Jay Satiro (8 Dec 2017) +- [Richard Alcock brought this change] -- Curl_urldecode: no peeking beyond end of input buffer + CURLOPT_PRIVATE.3: fix grammar - Security problem: CVE-2013-2174 + - Change "never does nothing" double-negative to "never does anything". - If a program would give a string like "%FF" to curl_easy_unescape() but - ask for it to decode only the first byte, it would still parse and - decode the full hex sequence. The function then not only read beyond the - allowed buffer but it would also deduct the *unsigned* counter variable - for how many more bytes there's left to read in the buffer by two, - making the counter wrap. Continuing this, the function would go on - reading beyond the buffer and soon writing beyond the allocated target - buffer... - - Bug: http://curl.haxx.se/docs/adv_20130622.html - Reported-by: Timo Sirainen - -Guenter Knauf (20 Jun 2013) -- Use opened body.out file and write content to it. + Closes https://github.com/curl/curl/pull/2168 -Daniel Stenberg (20 Jun 2013) -- multi_socket: react on socket close immediately +Daniel Stenberg (8 Dec 2017) +- curl: remove __EMX__ #ifdefs - As a remedy to the problem when a socket gets closed and a new one is - opened with the same file descriptor number and as a result - multi.c:singlesocket() doesn't detect the difference, the new function - Curl_multi_closed() gets told when a socket is closed so that it can be - removed from the socket hash. When the old one has been removed, a new - socket should be detected fine by the singlesocket() on next invoke. + These are OS/2-specific things added to the code in the year 2000. They + were always ugly. If there's any user left, they still don't need it + done this way. - Bug: http://curl.haxx.se/bug/view.cgi?id=1248 - Reported-by: Erik Johansson - -- RELEASE-NOTES: synced with e305f5ec715f + Closes #2166 -- TODO: mention the DANE patch from March +Jay Satiro (8 Dec 2017) +- openssl: improve data-pending check for https proxy + + - Allow proxy_ssl to be checked for pending data even when connssl does + not yet have an SSL handle. + + This change is for posterity. Currently there doesn't seem to be a code + path that will cause a pending data check when proxyssl could have + pending data and the connssl handle doesn't yet exist [1]. + + [1]: Recall that an https proxy connection starts out in connssl but if + the destination is also https then the proxy SSL backend data is moved + from connssl to proxyssl, which means connssl handle is temporarily + empty until an SSL handle for the destination can be created. + + Ref: https://github.com/curl/curl/commit/f4a6238#commitcomment-24396542 + + Closes https://github.com/curl/curl/pull/1916 -- CURLOPT_COOKIELIST: take cookie share lock +Daniel Stenberg (8 Dec 2017) +- curl: don't set CURLOPT_INTERLEAVEDATA - When performing COOKIELIST operations the cookie lock needs to be taken - for the cases where the cookies are shared among multiple handles! + That data is only ever used by the CURLOPT_INTERLEAVEFUNCTION callback + and that option isn't set or used by the curl tool! - Verified by Benjamin Gilbert's updated test 506 + Updates the 9 tests that verify --libcurl + + Closes #2167 + +- curl.h: remove incorrect comment about ERRORBUFFER - Bug: http://curl.haxx.se/bug/view.cgi?id=1215 - Reported-by: Benjamin Gilbert + ... error messages are _not_ sent to stderr if this is not set. -- [Benjamin Gilbert brought this change] +- [Michael Felt brought this change] - test506: verify that CURLOPT_COOKIELIST takes share lock + configure: add AX_CODE_COVERAGE only if using gcc - It doesn't right now: http://curl.haxx.se/bug/view.cgi?id=1215 + Fixes #2076 + Closes #2125 -- TODO: HTTP2/SPDY support +- curl: limit -# update frequency for unknown total size + + Make it use a max 10Hz update frequency for this case as well. Return + early if the "point" hasn't moved since last invoke. + + Reported-by: Elliot Saba + + Fixes #2158 + Closes #2163 -- curl_easy_setopt.3: clarify CURLOPT_PROGRESSFUNCTION frequency +- BINDINGS: another PostgreSQL client + + ...the former link is dead. - Make it clearer that the CURLOPT_PROGRESSFUNCTION callback will be - called more frequently than once per second when things are happening. + Reported-by: Frank Gevaerts -- RELEASE-NOTES: synced with 9c3e098259b82 +- [Zachary Seguin brought this change] + + CONNECT: keep close connection flag in http_connect_state struct - Mention 7 recent bug fixes and their associated contributors + Fixes #2088 + Closes #2157 -- curl_multi_wait.3: clarify the numfds counter +- [Per Malmberg brought this change] -- curl_easy_perform: avoid busy-looping + include: get netinet/in.h before linux/tcp.h - When curl_multi_wait() finds no file descriptor to wait for, it returns - instantly and this must be handled gracefully within curl_easy_perform() - or cause a busy-loop. Starting now, repeated fast returns without any - file descriptors is detected and a gradually increasing sleep will be - used (up to a max of 1000 milliseconds) before continuing the loop. + ... to allow build on older Linux dists (specifically CentOS 4.8 on gcc + 4.8.5) - Bug: http://curl.haxx.se/bug/view.cgi?id=1238 - Reported-by: Miguel Angel + Closes #2160 + +- openldap: fix checksrc nits -- [YAMADA Yasuharu brought this change] +- [Stepan Broz brought this change] - cookies: follow-up fix for path checking + openldap: add commented out debug possibilities + + ... to aid debugging openldap library using its built-in debug messages. - The initial fix to only compare full path names were done in commit - 04f52e9b4db0 but found out to be incomplete. This takes should make the - change more complete and there's now two additional tests to verify - (test 31 and 62). + Closes #2159 -- [Sergei Nikulov brought this change] +- examples: move threaded-shared-conn.c to the "complicated" ones + + ... due it relying on pthreads to link. - lib1900: use tutil_tvnow instead of gettimeofday +- RELEASE-NOTES: synced with b261c44e8 - Makes it build on windows + ... and bump next release version to 7.58.0 -- [Eric Hu brought this change] +- [Jan Ehrhardt brought this change] - axtls: now done non-blocking + URL: tolerate backslash after drive letter for FILE: + + ... as in "file://c:\some\path\curl.out" + + Reviewed-by: Matthew Kerwin + Closes #2154 -- [Eric Hu brought this change] +- [Randall S. Becker brought this change] - test2033: requires NTLM support + tests: added netinet/in6.h includes in test servers -- KNOWN_BUGS: #82 failed build with Borland compiler +- [Randall S. Becker brought this change] -- Curl_output_digest: support auth-int for empty entity body + configure: check for netinet/in6.h - By always returning the md5 for an empty body when auth-int is asked - for, libcurl now at least sometimes does the right thing. + Needed by HPE NonStop NSE and NSX systems - Bug: http://curl.haxx.se/bug/view.cgi?id=1235 - Patched-by: Nach M. S. + Fixes #2146 + Closes #2155 -- multi_socket: reduce timeout inaccuracy margin +- curl-config: add --ssl-backends - Allow less room for "triggered too early" mistakes by applications / - timers on non-windows platforms. Starting now, we assume that a timeout - call is never made earlier than 3 milliseconds before the actual - timeout. This greatly improves timeout accuracy on Linux. + Lists all SSL backends that were enabled at build-time. - Bug: http://curl.haxx.se/bug/view.cgi?id=1228 - Reported-by: Hang Su + Suggested-by: Oleg Pudeyev + Fixes #2128 -- cert_stuff: avoid double free in the PKCS12 code +- conncache: only allow multiplexing within same multi handle - In the pkcs12 code, we get a list of x509 records returned from - PKCS12_parse but when iterating over the list and passing each to - SSL_CTX_add_extra_chain_cert() we didn't also properly remove them from - the "stack", which made them get freed twice (both in sk_X509_pop_free() - and then later in SSL_CTX_free). + Connections that are used for HTTP/1.1 Pipelining or HTTP/2 multiplexing + only get additional transfers added to them if the existing connection + is held by the same multi or easy handle. libcurl does not support doing + HTTP/2 streams in different threads using a shared connection. - This isn't really documented anywhere... - - Bug: http://curl.haxx.se/bug/view.cgi?id=1236 - Reported-by: Nikaiw + Closes #2152 -- cert_stuff: remove code duplication in the pkcs12 logic +- threaded-shared-conn.c: fixed typo in commenta -- [Aleksey Tulinov brought this change] +- threaded-shared-conn.c: new example - axtls: honor disabled VERIFYHOST +- conncache: fix several lock issues - When VERIFYHOST == 0, libcurl should let invalid certificates to pass. - -- [Peter Gal brought this change] + If the lock is released before the dealings with the bundle is over, it may + have changed by another thread in the mean time. + + Fixes #2132 + Fixes #2151 + Closes #2139 - curl_easy_setopt.3: HTTP header with no content +- libssh: remove dead code in sftp_qoute + + ... by removing a superfluous NULL pointer check that also confuses + Coverity. - Update the documentation on how to specify a HTTP header with no - content. + Fixes #2143 + Closes #2153 -- RELEASE-NOTES: synced with 87cf677eca55 +- sasl_getmesssage: make sure we have a long enough string to pass + + For pop3/imap/smtp, added test 891 to somewhat verify the pop3 + case. + + For this, I enhanced the pingpong test server to be able to send back + responses with LF-only instead of always using CRLF. - Added 11 bugs and 7 contributors + Closes #2150 -- lib1500: remove bad check +- libssh2: remove dead code from SSH_SFTP_QUOTE - After curl_multi_wait() returns, this test checked that we got exactly - one file descriptor told to read from, but we cannot be sure that is - true. curl_multi_wait() will sometimes return earlier without any file - descriptor to handle, just just because it is a suitable time to call - *perform(). + Figured out while reviewing code in the libssh backend. The pointer was + checked for NULL after having been dereferenced, so we know it would + always equal true or it would've crashed. - This problem showed up with commit 29bf0598. + Pointed-out-by: Nikos Mavrogiannopoulos - Bug: http://curl.haxx.se/mail/lib-2013-06/0029.html - Reported-by: Fabian Keil + Bug #2143 + Closes #2148 -- tests/Makefile: typo in the perlcheck target +- ssh-libssh.c: please checksrc + +Nikos Mavrogiannopoulos (4 Dec 2017) +- libssh: fixed dereference in statvfs access - Bug: http://curl.haxx.se/bug/view.cgi?id=1239 - Reported-by: Christian Weisgerber + The behavior is now equivalent to ssh.c when SSH_SFTP_QUOTE_STATVFS + handling fails. + + Fixes #2142 -- test1230: verify CONNECT to a numerical ipv6-address +Daniel Stenberg (4 Dec 2017) +- [Guitared brought this change] -- sws: support extracting test number from CONNECT ipv6-address! + RESOURCES: update spec names - If an ipv6-address is provided to CONNECT, the last hexadecimal group in - the address will be used as the test number! For example the address - "[1234::ff]" would be treated as test case 255. + Closes #2145 -- curl_multi_wait: only use internal timer if not -1 +Nikos Mavrogiannopoulos (3 Dec 2017) +- libssh: corrected use of sftp_statvfs() in SSH_SFTP_QUOTE_STATVFS - commit 29bf0598aad5 introduced a problem when the "internal" timeout is - prefered to the given if shorter, as it didn't consider the case where - -1 was returned. Now the internal timeout is only considered if not -1. + The previous code was incorrectly following the libssh2 error detection + for libssh2_sftp_statvfs, which is not correct for libssh's sftp_statvfs. - Reported-by: Tor Arntsen - Bug: http://curl.haxx.se/mail/lib-2013-06/0015.html - -Dan Fandrich (3 Jun 2013) -- libcurl-tutorial.3: added a section on IPv6 + Fixes #2142 - Also added a (correctly-escaped) backslash to the autoexec.bat - example file and a new Windows character device name with - a colon as examples of other characters that are special - and potentially dangerous (this reverts and reworks commit - 7d8d2a54). + Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org> -Daniel Stenberg (3 Jun 2013) -- curl_multi_wait: reduce timeout if the multi handle wants to +- libssh: no need to call sftp_get_error as ssh_get_error is sufficient - If the multi handle's pending timeout is less than what is passed into - this function, it will now opt to use the shorter time anyway since it - is a very good hint that the handle wants to process something in a - shorter time than what otherwise would happen. + Fixes #2141 - curl_multi_wait.3 was updated accordingly to clarify + Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org> + +Daniel Stenberg (2 Dec 2017) +- libssh: fix minor static code analyzer nits + + - remove superfluous NULL check which otherwise tricks the static code + analyzers to assume NULL pointer dereferences. - This is the reason for bug #1224 + - fix fallthrough in switch() - Bug: http://curl.haxx.se/bug/view.cgi?id=1224 - Reported-by: Andrii Moiseiev + - indent mistake -- multi_runsingle: switch an if() condition for readability +- openssl: pkcs12 is supported by boringssl + + Removes another #ifdef for BoringSSL - ... because there's an identical check right next to it so using the - operators in the check in the same order increases readability. + Pointed-out-by: David Benjamin + + Closes #2134 -Marc Hoersken (2 Jun 2013) -- curl_schannel.c: Removed variable unused since 35874298e4 +- [Jay Satiro brought this change] -- curl_setup.h: Fixed redefinition warning using mingw-w64 + travis: use pip2 instead of pip + + .. since now mac osx image expects pip2 or pip3, and doesn't know pip: + + 0.01s$ pip install --user cpp-coveralls + /Users/travis/.travis/job_stages: line 57: pip: command not found + + Ref: https://github.com/travis-ci/travis-ci/issues/8829 + + Closes https://github.com/curl/curl/pull/2133 -Daniel Stenberg (30 May 2013) -- multi_runsingle: add braces to clarify the code +- [Nikos Mavrogiannopoulos brought this change] -- libcurl-tutorial.3: remove incorrect backslash + lib582: do not verify host for SFTP - A single backslash in the content is not legal nroff syntax. + This SFTP test fails with libssh back-end due to failure to verify + the peer. Disable peer verification in the test as there seems to + be the intention of the test. - Reported and fixed by: Eric S. Raymond - Bug: http://curl.haxx.se/bug/view.cgi?id=1234 - -- curl_formadd.3: fixed wrong "end-marker" syntax + Note that the libssh back-end automatically verifies the peer's + host using the default known_hosts file. - Reported and fixed by: Eric S. Raymond - Bug: http://curl.haxx.se/bug/view.cgi?id=1233 + Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org> -- curl.1: clarify that --silent still outputs data +- [Nikos Mavrogiannopoulos brought this change] -- Digest auth: escape user names with \ or " in them + libssh: added SFTP support - When sending the HTTP Authorization: header for digest, the user name - needs to be escaped if it contains a double-quote or backslash. + The SFTP back-end supports asynchronous reading only, limited + to 32-bit file length. Writing is synchronous with no other + limitations. - Test 1229 was added to verify + This also brings keyboard-interactive authentication. - Reported and fixed by: Nach M. S - Bug: http://curl.haxx.se/bug/view.cgi?id=1230 + Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org> -- [Mike Giancola brought this change] +- [Nikos Mavrogiannopoulos brought this change] - ossl_recv: SSL_read() returning 0 is an error too + symbols-in-versions: added new symbols with 7.56.3 version - SSL_read can return 0 for "not successful", according to the open SSL - documentation: http://www.openssl.org/docs/ssl/SSL_read.html + Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org> -- [Mike Giancola brought this change] +- [Nikos Mavrogiannopoulos brought this change] - ossl_send: SSL_write() returning 0 is an error too + .travis.yml: added build --with-libssh - We found that in specific cases if the connection is abruptly closed, - the underlying socket is listed in a close_wait state. We continue to - call the curl_multi_perform, curl_mutli_fdset etc. None of these APIs - report the socket closed / connection finished. Since we have cases - where the multi connection is only used once, this can pose a problem - for us. I've read that if another connection was to come in, curl would - see the socket as bad and attempt to close it at that time - - unfortunately, this does not work for us. + Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com> + +- [Nikos Mavrogiannopoulos brought this change] + + libssh2: return CURLE_UPLOAD_FAILED on failure to upload - I found that in specific situations, if SSL_write returns 0, curl did - not recognize the socket as closed (or errored out) and did not report - it to the application. I believe we need to change the code slightly, to - check if ssl_write returns 0. If so, treat it as an error - the same as - a negative return code. + This brings its in sync with the error code returned by the + libssh backend. - For OpenSSL - the ssl_write documentation is here: - http://www.openssl.org/docs/ssl/SSL_write.html + Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org> -- KNOWN_BUGS: curl -OJC- fails to resume - - Bug: http://curl.haxx.se/bug/view.cgi?id=1169 +- [Nikos Mavrogiannopoulos brought this change] -- Curl_cookie_add: handle IPv6 hosts + libssh2: send the correct CURLE error code on scp file not found - 1 - don't skip host names with a colon in them in an attempt to bail out - on HTTP headers in the cookie file parser. It was only a shortcut anyway - and trying to parse a file with HTTP headers will still be handled, only - slightly slower. + That also updates tests to expect the right error code - 2 - don't skip domain names based on number of dots. The original - netscape cookie spec had this oddity mentioned and while our code - decreased the check to only check for two, the existing cookie spec has - no such dot counting required. + libssh2 back-end returns CURLE_SSH error if the remote file + is not found. Expect instead CURLE_REMOTE_FILE_NOT_FOUND + which is sent by the libssh backend. - Bug: http://curl.haxx.se/bug/view.cgi?id=1221 - Reported-by: Stefan Neis + Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com> -- curl_easy_setopt.3: expand the PROGRESSFUNCTION section +- [Nikos Mavrogiannopoulos brought this change] + + Added support for libssh SSH SCP back-end + + libssh is an alternative library to libssh2. + https://www.libssh.org/ - Explain the callback and its arguments better and with more descriptive - text. + That patch set also introduces support for ECDSA + ed25519 keys, as well as gssapi authentication. + + Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com> -- tests: add test1394 file to the tarball +- RELEASE-NOTES: synced with af8cc7a69 -- tarball: include the xmlstream example +- curlver: towards 7.57.1 -- [David Strauss brought this change] +- [W. Mark Kubacki brought this change] - xmlstream: XML stream parsing example source code + lib: don't export all symbols, just everything curl_* + + Absent any 'symbol map' or script to limit what gets exported, static + linking of libraries previously resulted in a libcurl with curl's and + those other symbols being (re-)exported. + + This did not happen if 'versioned symbols' were enabled (which is not + the default) because then a version script is employed. + + This limits exports to everything starting in 'curl_*'., which is + what "libcurl.vers" exports. - Add an XML stream parsing example using Expat. Add missing ignore for - the binary from an unrelated example. + This avoids strange side-effects such as with mixing methods + from system libraries and those erroneously offered by libcurl. + + Closes #2127 -- [YAMADA Yasuharu brought this change] +- [Johannes Schindelin brought this change] - cookies: only consider full path matches + SSL: Avoid magic allocation of SSL backend specific data - I found a bug which cURL sends cookies to the path not to aim at. - For example: - - cURL sends a request to http://example.fake/hoge/ - - server returns cookie which with path=/hoge; - the point is there is NOT the '/' end of path string. - - cURL sends a request to http://example.fake/hogege/ with the cookie. + Originally, my idea was to allocate the two structures (or more + precisely, the connectdata structure and the four SSL backend-specific + strucutres required for ssl[0..1] and proxy_ssl[0..1]) in one go, so + that they all could be free()d together. - The reason for this old "feature" is because that behavior is what is - described in the original netscape cookie spec: - http://curl.haxx.se/rfc/cookie_spec.html + However, getting the alignment right is tricky. Too tricky. - The current cookie spec (RFC6265) clarifies the situation: - http://tools.ietf.org/html/rfc6265#section-5.2.4 - -- [Eric Hu brought this change] + So let's just bite the bullet and allocate the SSL backend-specific + data separately. + + As a consequence, we now have to be very careful to release the memory + allocated for the SSL backend-specific data whenever we release any + connectdata. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> + + Closes #2119 - axtls: prevent memleaks on SSL handshake failures +- examples/xmlstream.c: don't switch off CURL_GLOBAL_SSL + + Reported-by: Dima Tisnek -- Revert "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage" +- travis: add boringssl build - This reverts commit 8ec2cb5544b86306b702484ea785b6b9596562ab. + Uses a separate build without --enable-debug and no valgrind. - We don't have any code anywhere in libcurl (or the curl tool) that use - wcsdup so there's no such memory use to track. It seems to cause mild - problems with the Borland compiler though that we may avoid by reverting - this change again. + The debug option causes far too many warnings in boringssl's headers + (C++ comments, trailing commas etc). Valgrind triggers some false + positive errors in thread-local data used by boringssl. - Bug: http://curl.haxx.se/mail/lib-2013-05/0070.html + Closes #2118 -- RELEASE-NOTES: synced with ae26ee3489588f0 +Version 7.57.0 (29 Nov 2017) -Guenter Knauf (11 May 2013) -- Updated zlib version in build files. +Daniel Stenberg (29 Nov 2017) +- RELEASE-NOTES: curl 7.57.0 -Daniel Stenberg (9 May 2013) -- [Renaud Guillard brought this change] +- THANKS: added contributors from 7.57.0 release - OS X framework: fix invalid symbolic link +- openssl: fix boringssl build again + + commit d3ab7c5a21e broke the boringssl build since it doesn't have + RSA_flags(), so we disable that code block for boringssl builds. + + Reported-by: W. Mark Kubacki + Fixes #2117 -Kamil Dudka (9 May 2013) -- [Daniel Stenberg brought this change] +- curl_ntlm_core.c: use the limits.h's SIZE_T_MAX if provided - nss: give PR_INTERVAL_NO_WAIT instead of -1 to PR_Recv/PR_Send - - Reported by: David Strauss - Bug: http://curl.haxx.se/mail/lib-2013-05/0088.html +- libcurl-share.3: the connection cache is shareable now -Daniel Stenberg (8 May 2013) -- libtest: gitignore more binary files +- global_init: ignore CURL_GLOBAL_SSL's absense + + This bit is no longer used. It is not clear what it meant for users to + "init the TLS" in a world with different TLS backends and since the + introduction of multissl, libcurl didn't properly work if inited without + this bit set. + + Not a single user responded to the call for users of it: + https://curl.haxx.se/mail/lib-2017-11/0072.html + + Reported-by: Evgeny Grin + Assisted-by: Jay Satiro + + Fixes #2089 + Fixes #2083 + Closes #2107 -- servercert: allow empty subject +- ntlm: avoid integer overflow for malloc size + + Reported-by: Alex Nichols + Assisted-by: Kamil Dudka and Max Dymond - Bug: http://curl.haxx.se/bug/view.cgi?id=1220 - Patch by: John Gardiner Myers + CVE-2017-8816 + + Bug: https://curl.haxx.se/docs/adv_2017-11e7.html -- [Steve Holme brought this change] +- wildcardmatch: fix heap buffer overflow in setcharset + + The code would previous read beyond the end of the pattern string if the + match pattern ends with an open bracket when the default pattern + matching function is used. + + Detected by OSS-Fuzz: + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4161 + + CVE-2017-8817 + + Bug: https://curl.haxx.se/docs/adv_2017-ae72.html - tests: Added new SMTP tests to verify commit 99b40451836d +- [Jay Satiro brought this change] -- runtests.pl: support nonewline="yes" in client/stdin sections + url: fix alignment of ssl_backend_data struct + + - Align the array of ssl_backend_data on a max 32 byte boundary. + + 8 is likely to be ok but I went with 32 for posterity should one of + the ssl_backend_data structs change to contain a larger sized variable + in the future. + + Prior to this change (since dev 70f1db3, release 7.56) the connectdata + structure was undersized by 4 bytes in 32-bit builds with ssl enabled + because long long * was mistakenly used for alignment instead of + long long, with the intention being an 8 byte boundary. Also long long + may not be an available type. + + The undersized connectdata could lead to oob read/write past the end in + what was expected to be the last 4 bytes of the connection's secondary + socket https proxy ssl_backend_data struct (the secondary socket in a + connection is used by ftp, others?). + + Closes https://github.com/curl/curl/issues/2093 + + CVE-2017-8818 + + Bug: https://curl.haxx.se/docs/adv_2017-af0a.html -- build: fixed unit1394 for debug and metlink builds +- ssh: remove check for a NULL pointer (!) + + With this check present, scan-build warns that we might dereference this + point in other places where it isn't first checked for NULL. Thus, if it + *can* be NULL we have a problem on a few places. However, this pointer + should not be possible to be NULL here so I remove the check and thus + also three different scan-build warnings. + + Closes #2111 -Kamil Dudka (6 May 2013) -- unit1394.c: plug the curl tool unit test in +- [Matthew Kerwin brought this change] -- [Jared Jennings brought this change] + test: add test for bad UNC/SMB path in file: URL - unit1394.c: basis of a unit test for parse_cert_parameter() +- [Matthew Kerwin brought this change] -- src/Makefile.am: build static lib for unit tests if enabled + test: add tests to ensure basic file: URLs -- tool_getparam: ensure string termination in parse_cert_parameter() +- [Matthew Kerwin brought this change] -- tool_getparam: fix memleak in handling the -E option + URL: update "file:" URL handling + + * LOTS of comment updates + * explicit error for SMB shares (e.g. "file:////share/path/file") + * more strict handling of authority (i.e. "//localhost/") + * now accepts dodgy old "C:|" drive letters + * more precise handling of drive letters in and out of Windows + (especially recognising both "file:c:/" and "file:/c:/") + + Closes #2110 -- tool_getparam: describe what parse_cert_parameter() does +- metalink: fix memory-leak and NULL pointer dereference + + Reported by scan-build - ... and de-duplicate the code initializing *passphrase + Closes #2109 -- curl.1: document escape sequences recognized by -E +- [Alessandro Ghedini brought this change] -- [Jared Jennings brought this change] + connect: add support for new TCP Fast Open API on Linux + + The new API added in Linux 4.11 only requires setting a socket option + before connecting, without the whole sento() machinery. + + Notably, this makes it possible to use TFO with SSL connections on Linux + as well, without the need to mess around with OpenSSL (or whatever other + SSL library) internals. + + Closes #2056 - curl -E: allow to escape ':' in cert nickname +- make: fix "make distclean" + + Fixes #2097 + Closes #2108 -Marc Hoersken (5 May 2013) -- curl_schannel.c: Fixed invalid memory access during SSL shutdown +- RELEASE-NOTES: synced with 31f18d272 -Steve Holme (4 May 2013) -- smtp: Fix trailing whitespace warning +Jay Satiro (23 Nov 2017) +- connect: improve the bind error message + + eg consider a non-existent interface eth8, curl --interface eth8 + + Before: curl: (45) Could not resolve host: eth8 + After: curl: (45) Couldn't bind to 'eth8' + + Bug: https://github.com/curl/curl/issues/2104 + Reported-by: Alfonso Martone -- smtp: Fix compilation warning +Daniel Stenberg (23 Nov 2017) +- examples/rtsp: clear RANGE again after use - comparison between signed and unsigned integer expressions + Fixes #2106 + Reported-by: youngchopin on github -- RELEASE-NOTES: synced with 92ef5f19c801 +- [Michael Kaufmann brought this change] -- smtp: Updated RFC-2821 references to RFC-5321 + test1264: verify URL with space in host name being rejected -- smtp: Fixed sending of double CRLF caused by first in EOB +- url: reject ASCII control characters and space in host names - If the mail sent during the transfer contains a terminating <CRLF> then - we should not send the first <CRLF> of the EOB as specified in RFC-5321. + Host names like "127.0.0.1 moo" would otherwise be accepted by some + getaddrinfo() implementations. - Additionally don't send the <CRLF> if there is "no mail data" as the - DATA command already includes it. - -- tests: Corrected MAIL SIZE for CRLF line endings + Updated test 1034 and 1035 accordingly. - ... which was missed in commit: f5c3d9538452 + Fixes #2073 + Closes #2092 -- tests: Corrected infilesize for CRLF line endings +- Curl_open: fix OOM return error correctly - ... which was missed in commit: f5c3d9538452 + Closes #2098 -- tests: Corrected test1406 to be RFC2821 compliant +- http2: fix "Value stored to 'end' is never read" scan-build error -- tests: Corrected test1320 to be RFC2821 compliant +- http2: fix "Value stored to 'hdbuf' is never read" scan-build error -- tests: Corrected typo in test909 - - Introduced in commit: 514817669e9e +- openssl: fix "Value stored to 'rc' is never read" scan-build error -- tests: Corrected test909 to be RFC2821 compliant +- mime: fix "Value stored to 'sz' is never read" scan-build error -- tests: Updated test references to 909 from 1411 +- Curl_llist_remove: fix potential NULL pointer deref - ...and removed references to libcurl and test1406. + Fixes a scan-build warning. + +- ntlm: remove unnecessary NULL-check to please scan-build -- tests: Renamed test1411 to test909 as this is a main SMTP test +- BUGS: spellchecked -Daniel Stenberg (1 May 2013) -- [Lars Johannesen brought this change] +Jay Satiro (18 Nov 2017) +- [fmmedeiros brought this change] - bindlocal: move brace out of #ifdef + examples/curlx: Fix code style - The code within #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID wrongly had two - closing braces when it should only have one, so builds without that - define would fail. + - Add braces around multi-line if statement. - Bug: http://curl.haxx.se/mail/lib-2013-05/0000.html + Closes https://github.com/curl/curl/pull/2096 -Steve Holme (30 Apr 2013) -- smtp: Tidy up to move the eob counter to the per-request structure +Daniel Stenberg (17 Nov 2017) +- resolve: allow IP address within [] brackets - Move the eob counter from the smtp_conn structure to the SMTP structure - as it is associated with a SMTP payload on a per-request basis. + ... so that IPv6 addresses can be passed like they can for connect-to + and how they're used in URLs. + + Added test 1324 to verify + Reported-by: Alex Malinovich + + Fixes #2087 + Closes #2091 -- TODO: Updated following the addition of CURLOPT_SASL_IR +- [Pavol Markovic brought this change] -- smtp: Fixed unknown percentage complete in progress bar + macOS: Fix missing connectx function with Xcode version older than 9.0 - The curl command line utility would display the the completed progress - bar with a percentage of zero as the progress routines didn't know the - size of the transfer. + The previous fix https://github.com/curl/curl/pull/1788 worked just for + Xcode 9. This commit extends the fix to older Xcode versions effectively + by not using connectx function. + + Fixes https://github.com/curl/curl/issues/1330 + Fixes https://github.com/curl/curl/issues/2080 + Closes https://github.com/curl/curl/pull/1336 + Closes #2082 + +- [Dirk Feytons brought this change] -Daniel Stenberg (29 Apr 2013) -- ftpserver: silence warnings + openssl: fix too broad use of HAVE_OPAQUE_EVP_PKEY - Fix regressions in commit b56e3d43e5d. Make @data local and filter off - non-numerical digits from $testno in STATUS_imap. + Fixes #2079 + Closes #2081 -Steve Holme (29 Apr 2013) -- ftpserver.pl: Corrected the imap LOGIN response +- TODO: ignore private IP addresses in PASV response - ...to be more realistic and consistent with the other imap responses. + Closes #1455 -- tests: Added imap STATUS command test +- RELEASE-NOTES: synced with ae7369b6d -- tests: Corrected the SMTP tests to be RFC2821 compliant +Michael Kaufmann (14 Nov 2017) +- URL: return error on malformed URLs with junk after IPv6 bracket - The emails that are sent to the server during these tests were - incorrectly formatted as they contained one or more LF terminated lines - rather than being CRLF terminated as per Section 2.3.7 of RFC-2821. + Follow-up to aadb7c7. Verified by new test 1263. - This wasn't a problem for the test suite as the <stdin> data matched the - <upload> data but anyone using these tests as reference would be sending - incorrect data to a server. + Closes #2072 -- email: Tidy up of *_perform_authenticate() - - Removed the hard returns from imap and pop3 by using the same style for - sending the authentication string as smtp. Moved the "Other mechanisms - not supported" check in smtp to match that of imap and pop3 to provide - consistency between the three email protocols. +Daniel Stenberg (14 Nov 2017) +- INTERNALS: we may use libidn2 now, not libidn -- smtp: Updated limit check to be more readable like the check in pop3 +Patrick Monnerat (13 Nov 2017) +- zlib/brotli: only include header files in modules needing them + + There is a conflict on symbol 'free_func' between openssl/crypto.h and + zlib.h on AIX. This is an attempt to resolve it. + + Bug: https://curl.haxx.se/mail/lib-2017-11/0032.html + Reported-By: Michael Felt -- pop3: Added 255 octet limit check when sending initial response +Daniel Stenberg (13 Nov 2017) +- SMB: fix uninitialized local variable - Added 255 octet limit check as per Section 4. Paragraph 8 of RFC-5034. + Reported-by: Brian Carpenter -- DOCS: Corrected line length of recent Secure Transport changes +- [Orgad Shaneh brought this change] -Nick Zitzmann (27 Apr 2013) -- darwinssl: add TLS crypto authentication + connect.c: remove executable bit on file - Users using the Secure Transport (darwinssl) back-end can now use a - certificate and private key to authenticate with a site using TLS. Because - Apple's security system is based around the keychain and does not have any - non-public function to create a SecIdentityRef data structure from data - loaded outside of the Keychain, the certificate and private key have to be - loaded into the Keychain first (using the certtool command line tool or - the Security framework's C API) before we can find it and use it. + Closes #2071 -Steve Holme (27 Apr 2013) -- Corrected version numbers after bump +- [hsiao yi brought this change] -Daniel Stenberg (27 Apr 2013) -- bump version + README.md: fixed layout - Since we're adding new stuff, the next release will bump the minor - version and we're looking forward to 7.31.0 - -Steve Holme (27 Apr 2013) -- RELEASE-NOTES: synced with f4e6e201b146 + Closes #2069 -- DOCS: Updated following the addition of CURLOPT_SASL_IR +- setopt: split out curl_easy_setopt() to its own file - Documented the the option in curl_easy_setopt() and added it to - symbols-in-versions. + ... to make url.c smaller. + + Closes #1944 -- tests: Corrected command line arguments in test907 and test908 +Jay Satiro (10 Nov 2017) +- [John Starks brought this change] -- tests: Added SMTP AUTH with initial response tests + cmake: Add missing setmode check + + Ensure HAVE_SETMODE is set to 1 on OSes that have setmode. Without this, + curl will corrupt binary files when writing them to stdout on Windows. + + Closes https://github.com/curl/curl/pull/2067 -- tests: Updated SMTP tests to decouple client initial response +Daniel Stenberg (10 Nov 2017) +- curl_share_setopt: va_end was not called if conncache errors - Updated test903 and test904 following the addition of CURLOPT_SASL_IR - as the default behaviour of SMTP AUTH responses is now to not include - the initial response. New tests with --sasl-ir support to follow. + CID 984459, detected by Coverity -- imap: Added support for overriding the SASL initial response +Sergei Nikulov (10 Nov 2017) +- [John Starks brought this change] + + cmake: Correctly include curl.rc in Windows builds (#2064) - In addition to checking for the SASL-IR capability the user can override - the sending of the client's initial response in the AUTHENTICATION - command with the use of CURLOPT_SASL_IR should the server erroneously - not report SASL-IR when it does support it. + Update CMakeLists.txt to add curl.rc to the correct list. + +Daniel Stenberg (9 Nov 2017) +- RELEASE-NOTES: synced with 32828cc4f -- smtp: Added support for disabling the SASL initial response +- [Luca Boccassi brought this change] + + --interface: add support for Linux VRF + + The --interface command (CURLOPT_INTERFACE option) already uses + SO_BINDTODEVICE on Linux, but it tries to parse it as an interface or IP + address first, which fails in case the user passes a VRF. - Updated the default behaviour of sending the client's initial response in the AUTH - command to not send it and added support for CURLOPT_SASL_IR to allow the user to - specify including the response. + Try to use the socket option immediately and parse it as a fallback + instead. Update the documentation to mention this feature, and that it + requires the binary to be ran by root or with CAP_NET_RAW capabilities + for this to work. - Related Bug: http://curl.haxx.se/mail/lib-2012-03/0114.html - Reported-by: Gokhan Sengun + Closes #2024 -- pop3: Added support for enabling the SASL initial response +- curl_share_setopt.3: document CURL_LOCK_DATA_CONNECT - Allowed the user to specify whether to send the client's intial response - in the AUTH command via CURLOPT_SASL_IR. + Closes #2043 + +- examples: add shared-connection-cache + +- test1554: verify connection cache sharing -- sasl-ir: Added --sasl-ir option to curl command line tool +- share: add support for sharing the connection cache -- sasl-ir: Added CURLOPT_SASL_IR to enable/disable the SASL initial response +- imap: deal with commands case insensitively + + As documented in RFC 3501 section 9: + https://tools.ietf.org/html/rfc3501#section-9 + + Closes #2061 -Daniel Stenberg (26 Apr 2013) -- curl_easy_init: use less mallocs +- connect: store IPv6 connection status after valid connection - By introducing an internal alternative to curl_multi_init() that accepts - parameters to set the hash sizes, easy handles will now use tiny socket - and connection hash tables since it will only ever add a single easy - handle to that multi handle. + ... previously it would store it already in the happy eyeballs stage + which could lead to the IPv6 bit being set for an IPv4 connection, + leading to curl not wanting to do EPSV=>PASV for FTP transfers. - This decreased the number mallocs in test 40 (which is a rather simple - and typical easy interface use case) from 1142 to 138. The maximum - amount of memory allocated used went down from 118969 to 78805. + Closes #2053 -Steve Holme (26 Apr 2013) -- ftpserver.pl: Fixed imap logout confirmation data +- curl_multi_fdset.3: emphasize curl_multi_timeout - An IMAP server should response with the BYE continuation response before - confirming the LOGOUT command was successful. + ... even when there's no socket to wait for, the timeout can still be + very short. -Daniel Stenberg (26 Apr 2013) -- ftp_state_pasv_resp: connect through proxy also when set by env +Jay Satiro (9 Nov 2017) +- content_encoding: fix inflate_stream for no bytes available - When connecting back to an FTP server after having sent PASV/EPSV, - libcurl sometimes didn't use the proxy properly even though the proxy - was used for the initial connect. + - Don't call zlib's inflate() when avail_in stream bytes is 0. - The function wrongly checked for the CURLOPT_PROXY variable to be set, - which made it act wrongly if the proxy information was set with an - environment variable. + This is a follow up to the parent commit 19e66e5. Prior to that change + libcurl's inflate_stream could call zlib's inflate even when no bytes + were available, causing inflate to return Z_BUF_ERROR, and then + inflate_stream would treat that as a hard error and return + CURLE_BAD_CONTENT_ENCODING. - Added test case 711 to verify (based on 707 which uses --socks5). Also - added test712 to verify another variation of setting the proxy: with - --proxy socks5:// + According to the zlib FAQ, Z_BUF_ERROR is not fatal. - Bug: http://curl.haxx.se/bug/view.cgi?id=1218 - Reported-by: Zekun Ni - -Kamil Dudka (26 Apr 2013) -- [Zdenek Pavlas brought this change] - - url: initialize speed-check data for file:// protocol + This bug would happen randomly since packet sizes are arbitrary. A test + of 10,000 transfers had 55 fail (ie 0.55%). - ... in order to prevent an artificial timeout event based on stale - speed-check data from a previous network transfer. This commit fixes - a regression caused by 9dd85bced56f6951107f69e581c872c1e7e3e58e. + Ref: https://zlib.net/zlib_faq.html#faq05 - Bug: https://bugzilla.redhat.com/906031 + Closes https://github.com/curl/curl/pull/2060 -Daniel Stenberg (25 Apr 2013) -- test709: clarify the test in the name +Patrick Monnerat (7 Nov 2017) +- content_encoding: do not write 0 length data -- sshserver: disable StrictHostKeyChecking +Daniel Stenberg (6 Nov 2017) +- fnmatch: remove dead code - I couldn't figure out why the host key logic isn't working, but having - it set to yes prevents my SSH-based test cases to run. I also don't see - a strong need to use strict host key checking on this test server. + There was a duplicate check for backslashes in the setcharset() + function. - So I disabled it. + Coverity CID 1420611 -- runtests: log more commands in verbose mode +- url: remove unncessary NULL-check + + Since 'conn' won't be NULL in there and we also access the pointer in + there without the check. - ... to aid tracking down failures + Coverity CID 1420610 -Steve Holme (25 Apr 2013) -- TODO: Corrected copy/paste typo +Viktor Szakats (6 Nov 2017) +- src/Makefile.m32: fix typo in brotli lib customization + + Ref cc1f4436099decb9d1a7034b2bb773a9f8379d31 -- TODO: Added new ideas for future SMTP, POP3 and IMAP features +- Makefile.m32: allow to customize brotli libs + + It adds the ability to link against static brotli libs. + + Also fix brotli include path. -- TODO: Updated following the addition of ;auth=<MECH> support +Patrick Monnerat (5 Nov 2017) +- travis: add a job with brotli enabled -- DOCS: Minor rewording / clarification of host name protocol detection +- [Viktor Szakats brought this change] -- RELEASE-NOTES: synced with a8c92cb60890 + Makefile.m32: add brotli support -- DOCS: Added reference to IETF draft for SMTP URL Interface +- HTTP: implement Brotli content encoding - ...when mentioning login options. Additional minor clarification of - "Windows builds" to be "Windows builds with SSPI"as a way of enabling - NTLM as Windows builds may be built with OpenSSL to enable NTLM or - without NTLM support altogether. - -Linus Nielsen Feltzing (23 Apr 2013) -- HISTORY: Fix spelling error. + This uses the brotli external library (https://github.com/google/brotli). + Brotli becomes a feature: additional curl_version_info() bit and + structure fields are provided for it and CURLVERSION_NOW bumped. + + Tests 314 and 315 check Brotli content unencoding with correct and + erroneous data. + + Some tests are updated to accomodate with the now configuration dependent + parameters of the Accept-Encoding header. -Steve Holme (23 Apr 2013) -- DOCS: Reworked the scheme calculation explanation under CURLOPT_URL +- HTTP: support multiple Content-Encodings + + This is implemented as an output streaming stack of unencoders, the last + calling the client write procedure. + + New test 230 checks this feature. + + Bug: https://github.com/curl/curl/pull/2002 + Reported-By: Daniel Bankhead -- url: Added smtp and pop3 hostnames to the protocol detection list +Jay Satiro (4 Nov 2017) +- url: remove arg value check from CURLOPT_SSH_AUTH_TYPES + + Since CURLSSH_AUTH_ANY (aka CURLSSH_AUTH_DEFAULT) is ~0 an arg value + check on this option is incorrect; we have to accept any value. + + Prior to this change since f121575 (7.56.1+) CURLOPT_SSH_AUTH_TYPES + erroneously rejected CURLSSH_AUTH_ANY with CURLE_BAD_FUNCTION_ARGUMENT. + + Bug: https://github.com/curl/curl/commit/f121575#commitcomment-25347120 -Daniel Stenberg (23 Apr 2013) -- HISTORY: correct some years/dates +Daniel Stenberg (4 Nov 2017) +- ntlm: avoid malloc(0) for zero length passwords + + It triggers an assert() when built with memdebug since malloc(0) may + return NULL *or* a valid pointer. - Thanks to archive.org's wayback machine I updated this document with - some facts from the early httpget/urlget web page: + Detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4054 - http://web.archive.org/web/19980216125115/http://www.inf.ufrgs.br/~sagula/urlget.html + Assisted-by: Max Dymond + Closes #2054 -- [Alessandro Ghedini brought this change] +- RELEASE-NOTES: synced with ee8016b3d - tests: add test1511 to check timecond clean-up +- curl: speed up handling of many URLs - Verifies the timecond fix in commit c49ed0b6c0f - -- [Alessandro Ghedini brought this change] + By properly keeping track of the last entry in the list of URLs/uploads + to handle, curl now avoids many meaningless traverses of the list which + speeds up many-URL handling *MASSIVELY* (several magnitudes on 100K + URLs). + + Added test 1291, to verify that it doesn't take ages - but we don't have + any detection of "too slow" command in the test suite. + + Reported-by: arainchik on github + Fixes #1959 + Closes #2052 - getinfo.c: reset timecond when clearing session-info variables +- curl: pass through [] in URLs instead of calling globbing error - Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=705783 - Reported-by: Ludovico Cavedon <cavedon@debian.org> + Assisted-by: Per Lundberg + Fixes #2044 + Closes #2046 + Closes #2048 -Steve Holme (22 Apr 2013) -- DOCS: Added information about login options to CURLOPT_USERPWD +- CURLOPT_INFILESIZE: accept -1 + + Regression since f121575 + + Reported-by: Petr Voytsik + Fixes #2047 -- DOCS: Added information about login options in the URL +Jay Satiro (2 Nov 2017) +- url: fix CURLOPT_DNS_CACHE_TIMEOUT arg value check to allow -1 + + Prior to this change since f121575 (7.56.1+) CURLOPT_DNS_CACHE_TIMEOUT + erroneously rejected -1 with CURLE_BAD_FUNCTION_ARGUMENT. -- url: Fixed missing length check in parse_proxy() +Dan Fandrich (1 Nov 2017) +- http2: Fixed OOM handling in upgrade request - Commit 11332577b3cb removed the length check that was performed by the - old scanf() code. + This caused the torture tests on test 1800 to fail. -- url: Fixed crash when no username or password supplied for proxy +- tests: Fixed torture tests on tests 556 and 650 - Fixed an issue in parse_proxy(), introduced in commit 11332577b3cb, - where an empty username or password (For example: http://:@example.com) - would cause a crash. + Test cleanup after OOM wasn't being consistently performed. -- url: Removed unused text length constants +Daniel Stenberg (1 Nov 2017) +- CURLOPT_MAXREDIRS: allow -1 as a value + + ... which is valid according to documentation. Regression since + f121575c0b5f. + + Verified now in test 501. + + Reported-by: cbartl on github + Fixes #2038 + Closes #2039 -- url: Updated proxy URL parsing to use parse_login_details() +- include: remove conncache.h inclusion from where its not needed -- url: Tidy up of setstropt_userpwd() parameters +Jay Satiro (1 Nov 2017) +- url: fix CURLOPT_POSTFIELDSIZE arg value check to allow -1 - Updated the naming convention of the login parameters to match those of - other functions. - -- url: Tidy up of code and comments following recent changes + .. also add same arg value check to CURLOPT_POSTFIELDSIZE_LARGE. - Tidy up of variable names and comments in setstropt_userpwd() and - parse_login_details(). - -- url: Simplified setstropt_userpwd() following recent changes + Prior to this change since f121575 (7.56.1+) CURLOPT_POSTFIELDSIZE + erroneously rejected -1 value with CURLE_BAD_FUNCTION_ARGUMENT. - There is no need to perform separate clearing of data if a NULL option - pointer is passed in. Instead this operation can be performed by simply - not calling parse_login_details() and letting the rest of the code do - the work. + Bug: https://curl.haxx.se/mail/lib-2017-11/0000.html + Reported-by: Andrew Lambert -- url: Correction to scope of if statements when setting data - -- url: Fixed memory leak in setstropt_userpwd() +Daniel Stenberg (31 Oct 2017) +- cookie: avoid NULL dereference + + ... when expiring old cookies. - setstropt_userpwd() was calling setstropt() in commit fddb7b44a79d to - set each of the login details which would duplicate the strings and - subsequently cause a memory leak. + Reported-by: Pavel Gushchin + Fixes #2032 + Closes #2035 -- RELEASE-NOTES: synced with d535c4a2e1f7 +Marcel Raad (30 Oct 2017) +- memdebug: use send/recv signature for curl_dosend/curl_dorecv + + This avoids build errors and warnings caused by implicit casts. + + Closes https://github.com/curl/curl/pull/2031 -- url: Added overriding of URL login options from CURLOPT_USERPWD +Daniel Stenberg (30 Oct 2017) +- [Juro Bystricky brought this change] -- tool_paramhlp: Fixed options being included in username + mkhelp.pl: support reproducible build - Fix to prevent the options from being displayed when curl requests the - user's password if the following command line is specified: + Do not generate line with the current date, such as: - --user username;options - -- url: Added support for parsing login options from the CURLOPT_USERPWD + * Generation time: Tue Oct-24 18:01:41 2017 + + This will improve reproducibility. The generated string is only + part of a comment, so there should be no adverse consequences. + + Signed-off-by: Juro Bystricky <juro.bystricky@intel.com> - In addition to parsing the optional login options from the URL, added - support for parsing them from CURLOPT_USERPWD, to allow the following - supported command line: + closes #2026 + +Dan Fandrich (30 Oct 2017) +- runtests.pl: Fixed typo in message + +Daniel Stenberg (30 Oct 2017) +- curlx: the timeval functions are no longer provided as curlx_* - --user username:password;options + Pointed-out-by: Dmitri Tikhonov + Bug: #2034 -- url: Added bounds checking to parse_login_details() +- select: update comments - Added bounds checking when searching for the separator characters within - the login string as this string may not be NULL terminated (For example - it is the login part of a URL). We do this in preference to allocating a - new string to copy the login details into which could then be passed to - parse_login_details() for performance reasons. + s/curlx_tvnow/Curl_now -- url: Added size_t cast to pointer based length calculations +- INTERNALS: remove curlx_tv* functions no longer provided -- url: Corrected minor typo in comment +- [Dmitri Tikhonov brought this change] -Daniel Stenberg (18 Apr 2013) -- CURL_CHECK_CA_BUNDLE: don't check for paths when cross-compiling + timeval: use mach time on MacOS - When cross-compiling we can't scan and detect existing files or paths. + If clock_gettime() is not supported, use mach_absolute_time() on MacOS. - Bug: http://curl.haxx.se/mail/lib-2013-04/0294.html + closes #2033 -- [Ishan SinghLevett brought this change] +Patrick Monnerat (29 Oct 2017) +- cli tool: improve ";type=" handling in -F option arguments - usercertinmem.c: add example showing user cert in memory +- cli tool: in -F option arg, comma is a delimiter for files only - Relies on CURLOPT_SSL_CTX_FUNCTION, which is OpenSSL specific - -Steve Holme (18 Apr 2013) -- url: Fix chksrc longer than 79 columns warning + Also upgrade test 1133 to cover this case and clarify man page about + form data quoting. + + Bug: https://github.com/curl/curl/issues/2022 + Reported-By: omau on github -- url: Fix incorrect variable type for result code +Daniel Stenberg (29 Oct 2017) +- timeleft: made two more users of Curl_timeleft use timediff_t -- url: Fix compiler warning +Jakub Zakrzewski (28 Oct 2017) +- cmake: Export libcurl and curl targets to use by other cmake projects - signed and unsigned type in conditional expression - -- url: Moved parsing of login details out of parse_url_login() + The config files define curl and libcurl targets as imported targets + CURL::curl and CURL::libcurl. For backward compatibility with CMake- + provided find-module the CURL_INCLUDE_DIRS and CURL_LIBRARIES are + also set. - Separated the parsing of login details from the processing of them in - parse_url_login() ready for use by setstropt_userpwd(). + Closes #1879 -- url: Re-factored set_userpass() and parse_url_userpass() - - Re-factored these functions to reflect their new behaviour following the - addition of login options. +Daniel Stenberg (28 Oct 2017) +- RELEASE-NOTES: synced with f20cbac97 -- url: Reworked URL parsing to allow overriding by CURLOPT_USERPWD +- [Florin Petriuc brought this change] -Daniel Stenberg (18 Apr 2013) -- maketgz: make bzip2 creation work with Parallel BZIP2 too + auth: Added test cases for RFC7616 - Apparently the previous usage didn't work with that implementation, - while this updated version works with at least both Parallel BZIP2 - v1.1.8 and regular bzip "Version 1.0.6, 6-Sept-2010". + Updated docs to include support for RFC7616 + + Signed-off-by: Florin <petriuc.florin@gmail.com> + + Closes #1934 -Linus Nielsen Feltzing (18 Apr 2013) -- Add tests/http_pipe.py to the tarball build +- [Florin Petriuc brought this change] -Steve Holme (16 Apr 2013) -- smtp: Re-factored all perform based functions + auth: add support for RFC7616 - HTTP Digest access authentication - Standardised the naming of all perform based functions to be in the form - smtp_perform_something(). + Signed-off-by: Florin <petriuc.florin@gmail.com> -- smtp: Added description comments to all perform based functions +- [Daniel Bankhead brought this change] -- smtp: Moved smtp_quit() to be with the other perform functions + TODO: support multiple Content-Encodings + + Closes #2002 -- smtp: Moved smtp_rcpt_to() to be with the other perform functions +- ROADMAP: cleanup + + Removed done stuff. Removed entries no longer considered for the near + term. -- smtp: Moved smtp_mail() to be with the other perform functions +- [Magicansk brought this change] -Daniel Stenberg (16 Apr 2013) -- [Wouter Van Rooy brought this change] + ROADMAP.md: spelling fixes + + Closes #2028 - curl-config: don't output static libs when they are disabled +- Curl_timeleft: change return type to timediff_t - Curl-config outputs static libraries even when they are disabled in - configure. + returning 'time_t' is problematic when that type is unsigned and we + return values less than zero to signal "already expired", used in + several places in the code. - This causes problems with the build of pycurl. + Closes #2021 -- [Dave Reisner brought this change] +- appveyor: add a win32 build - docs/libcurl: fix formatting in manpage +- setopt: fix CURLOPT_SSH_AUTH_TYPES option read - Commit c3ea3eb6 introduced some minor cosmetic errors in - curl_mutli_socket_action(3). - -- [Paul Howarth brought this change] + Regression since f121575c0b5f + + Reported-by: Rob Cotrone - Add extra libs for lib1900 and lib2033 test programs +Marcel Raad (27 Oct 2017) +- resolvers: only include anything if needed + + This avoids warnings about unused stuff. - These are needed in cases where clock_gettime is used, from librt. + Closes https://github.com/curl/curl/pull/2023 -Dan Fandrich (15 Apr 2013) -- FAQ: mention that the network connection can be monitored +Daniel Stenberg (27 Oct 2017) +- HELP-US: rename the subtitle too since the label is changed - Also note the prohibition on sharing handles across threads. + "PR-welcome" was the former name. -Steve Holme (15 Apr 2013) -- pop3: Added missing comment for pop3_state_apop_resp() +- curl_setup.h: oops, shorten the too long line -- smtp: Updated the coding style of smtp_state_servergreet_resp() +- [Martin Storsjo brought this change] + + curl_setup: Improve detection of CURL_WINDOWS_APP + + If WINAPI_FAMILY is defined, it should be safe to try to include + winapifamily.h to check what the define evaluates to. - Updated the coding style, in this function, to be consistant with other - response functions rather then performing a hard return on failure. + This should fix detection of CURL_WINDOWS_APP if building with + _WIN32_WINNT set to 0x0600. + + Closes #2025 -- pop3: Updated the coding style of pop3_state_servergreet_resp() +Jay Satiro (26 Oct 2017) +- transfer: Fix chunked-encoding upload bug + + - When uploading via chunked-encoding don't compare file size to bytes + sent to determine whether the upload has finished. - Updated the coding style, in this function, to be consistent with other - response functions rather then performing a hard return on failure. + Chunked-encoding adds its own overhead which why the bytes sent is not + equal to the file size. Prior to this change if a file was uploaded in + chunked-encoding and its size was known it was possible that the upload + could end prematurely without sending the final few chunks. That would + result in a server hang waiting for the remaining data, likely followed + by a disconnect. + + The scope of this bug is limited to some arbitrary file sizes which have + not been determined. One size that triggers the bug is 475020. + + Bug: https://github.com/curl/curl/issues/2001 + Reported-by: moohoorama@users.noreply.github.com + + Closes https://github.com/curl/curl/pull/2010 -- pop3: Re-factored all perform based functions +Daniel Stenberg (26 Oct 2017) +- timeval: make timediff_t also work on 32bit windows + + ... by using curl_off_t for the typedef if time_t is larger than 4 + bytes. - Standardised the naming of all perform based functions to be in the form - pop3_perform_something() following the changes made to IMAP. + Reported-by: Gisle Vanem + Bug: https://github.com/curl/curl/commit/b9d25f9a6b3ca791385b80a6a3c3fa5ae113e1e0#co + mmitcomment-25205058 + Closes #2019 -- pop3: Added description comments to all perform based functions +- curl_fnmatch: return error on illegal wildcard pattern + + ... instead of doing an infinite loop! + + Added test 1162 to verify. + + Reported-by: Max Dymond + Fixes #2015 + Closes #2017 -- pop3: Moved pop3_quit() to be with the other perform functions +- [Max Dymond brought this change] -- pop3: Moved pop3_command() to be with the other perform functions + wildcards: don't use with non-supported protocols - Started to apply the same tidy up to the POP3 code as applied to the - IMAP code in the 7.30.0 release. - -- RELEASE-NOTES: Removed erroneous spaces + Fixes timeouts in the fuzzing tests for non-FTP protocols. + + Closes #2016 -- RELEASE-NOTES: synced with 8723cade21fb +- [Max Dymond brought this change] -- smtp: Added support for ;auth=<mech> in the URL + multi: allow table handle sizes to be overridden - Added support for specifying the preferred authentication mechanism in - the URL as per Internet-Draft 'draft-earhart-url-smtp-00'. + Allow users to specify their own hash define for + CURL_CONNECTION_HASH_SIZE so that both values can be overridden. + + Closes #1982 -- pop3: Reworked authentication type constants +- time: rename Curl_tvnow to Curl_now + + ... since the 'tv' stood for timeval and this function does not return a + timeval struct anymore. - ... to use left-shifted values, like those defined in curl.h, rather - than 16-bit hexadecimal values. + Also, cleaned up the Curl_timediff*() functions to avoid typecasts and + clean up the descriptive comments. + + Closes #2011 -- pop3: Small consistency tidy up +- ftplistparser: follow-up cleanup to remove PL_ERROR() -- pop3: Added support for ;auth=<mech> in the URL - - Added support for specifying the preferred authentication type and SASL - mechanism in the URL as per RFC-2384. +- [Max Dymond brought this change] -- imap: Added support for ;auth=<mech> in the URL + ftplistparser: free off temporary memory always - Added support for specifying the preferred authentication mechanism in - the URL as per RFC-5092. - -- sasl: Reworked SASL mechanism constants + When using the FTP list parser, ensure that the memory that's + allocated is always freed. - ... to use left-shifted values, like those defined in curl.h, rather - than 16-bit hexadecimal values. + Detected by OSS-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3682 + Closes #2013 -- sasl: Added predefined preferred mechanism values +- timediff: return timediff_t from the time diff functions - In preparation for the upcoming changes to IMAP, POP3 and SMTP added - preferred mechanism values. - -- url: Added support for parsing login options from the URL + ... to cater for systems with unsigned time_t variables. - As well as parsing the username and password from the URL, added support - for parsing the optional options part from the login details, to allow - the following supported URL format: + - Renamed the functions to curlx_timediff and Curl_timediff_us. - schema://username:password;options@example.com/path?q=foobar + - Added overflow protection for both of them in either direction for + both 32 bit and 64 bit time_ts - This will only be used by IMAP, POP3 and SMTP at present but any - protocol that may be given login options in the URL will be able to - add support for them. - -- smtp: Fix compiler warning + - Reprefixed the curlx_time functions to use Curl_* - warning: unused variable 'smtp' introduced in commit 73cbd21b5ee6. + Reported-by: Peter Piekarski + Fixes #2004 + Closes #2005 -- smtp: Moved parsing of url path into separate function +- [Paul Howarth brought this change] -Daniel Stenberg (12 Apr 2013) -- FTP: handle a 230 welcome response + libtest: Add required test libraries for lib1552 and lib1553 - ...instead of the 220 we otherwise expect. + They use $(TESTUTIL) and thus should use $(TESTUTIL_LIBS) too. - Made the ftpserver.pl support sending a custom "welcome" and then - created test 1219 to verify this fix with such a 230 welcome. + This fixes build failures on Fedora 13. - Bug: http://curl.haxx.se/mail/lib-2013-02/0102.html - Reported by: Anders Havn + Closes #2006 -- configure: try pthread_create without -lpthread - - For libc variants without a spearate pthread lib (like bionic), try - using pthreads without the pthreads lib first and only if that fails try - the -lpthread linker flag. +- [Alessandro Ghedini brought this change] + + libcurl-tutorial.3: fix typo - Bug: http://curl.haxx.se/bug/view.cgi?id=1216 - Reported by: Duncan + closes #2008 + +Alessandro Ghedini (23 Oct 2017) +- curl_mime_filedata.3: fix typos + +Daniel Stenberg (23 Oct 2017) +- RELEASE-NOTES: clean slate towards 7.57.0 -- FTP: access files in root dir correctly +- [Max Dymond brought this change] + + travis: exit if any steps fail - Accessing a file with an absolute path in the root dir but with no - directory specified was not handled correctly. This fix comes with four - new test cases that verify it. + We don't expect any steps to fail in travis. Exit the script if they do. - Bug: http://curl.haxx.se/mail/lib-2013-04/0142.html - Reported by: Sam Deane + Closes #1966 + +Version 7.56.1 (23 Oct 2017) -Steve Holme (12 Apr 2013) -- pop3: Reworked the function description for Curl_pop3_write() +Daniel Stenberg (23 Oct 2017) +- RELEASE-NOTES: 7.56.1 -- pop3: Added function description to pop3_parse_custom_request() +- THANKS: update at 7.56.1 release time -- pop3: Moved utility functions to end of pop3.c +- [Jon DeVree brought this change] -Nick Zitzmann (12 Apr 2013) -- darwinssl: add TLS session resumption + mk-ca-bundle: Remove URL for aurora - This ought to speed up additional TLS handshakes, at least in theory. + Aurora is no longer used by Mozilla + https://hacks.mozilla.org/2017/04/simplifying-firefox-release-channels/ -Steve Holme (12 Apr 2013) -- imap: Added function description to imap_parse_custom_request() +- [Jon DeVree brought this change] -- imap: Moved utility functions to end of imap.c (Part 3/3) + mk-ca-bundle: Fix URL for NSS + + The 'tip' is the most recent branch committed to, this should be + 'default' like the URLs for the browser are. - Moved imap_is_bchar() be with the other utility based functions. + Closes #1998 -- imap: Moved utility functions to end of imap.c (Part 2/3) +- imap: if a FETCH response has no size, don't call write callback - Moved imap_parse_url_path() and imap_parse_custom_request() to the end of the - file allowing all utility functions to be grouped together. + CVE-2017-1000257 + + Reported-by: Brian Carpenter and 0xd34db347 + Also detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3586 -- imap: Moved utility functions to end of imap.c (Part 1/3) +- ftp: reject illegal IP/port in PASV 227 response + + ... by using range checks. Among other things, this avoids an undefined + behavior for a left shift that could happen on negative or very large + values. - Moved imap_atom() and imap_sendf() to the end of the file allowing all - utility functions to be grouped together. + Closes #1997 + + Detected by OSS-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3694 -- imap: Corrected function description for imap_connect() +Patrick Monnerat (20 Oct 2017) +- test653: check reuse of easy handle after mime data change + + See issue #1999 -Kamil Dudka (12 Apr 2013) -- tests: prevent test206, test1060, and test1061 from failing +- mime: do not reuse previously computed multipart size - ... in case runtests.pl is invoked with non-default -b option + The contents might have changed: size must be recomputed. + + Reported-by: moteus on github + Fixes #1999 + +- test308: disable if MultiSSL feature enabled - Fixes a regression caused by 1e29d275c643ef6aab7948f0f55a7a9397e56b42. + Even if OpenSSL is enabled, it might not be the default backend when + multi-ssl is enabled, causing the test to fail. -Daniel Stenberg (12 Apr 2013) -- [David Strauss brought this change] +- runtests: support MultiSSL client feature - libcurl-share.3: update what it does and does not share. +- vtls: change struct Curl_ssl `close' field name to `close_one'. - Update sharing interface documentation to provide exhaustive list of - what it does and does not share. + On OS/400, `close' is an ASCII system macro that corrupts the code if + not used in a context not targetting the close() system API. -- THANKS: remove duplicated names +- os400: add missing symbols in config file. + + Also adjust makefile to renamed files and warn about installation dirs mix-up. -- bump: start working towards next release +- test652: curl_mime_data + base64 encoder with large contents -- THANKS: added people from the 7.30.0 RELEASE-NOTES +- mime: limit bas64-encoded lines length to 76 characters -Version 7.30.0 (12 Apr 2013) +Daniel Stenberg (16 Oct 2017) +- RELEASE-NOTES: synced with f121575c0 -Daniel Stenberg (12 Apr 2013) -- RELEASE-NOTES: cleaned up for 7.30 (synced with 5c5e1a1cd20) +- setopt: range check most long options - Most notable the security advisory: - http://curl.haxx.se/docs/adv_20130412.html + ... filter early instead of risking "funny values" having to be dealt + with elsewhere. -- test1218: another cookie tailmatch test +- setopt: avoid integer overflows when setting millsecond values - ... and make 1216 also verify it with a file input + ... that are multiplied by 1000 when stored. - These tests verify commit 3604fde3d3c9b0d, the fix for the "cookie - domain tailmatch" vulnerability. See - http://curl.haxx.se/docs/adv_20130412.html - -- [YAMADA Yasuharu brought this change] + For 32 bit long systems, the max value accepted (2147483 seconds) is > + 596 hours which is unlikely to ever be set by a legitimate application - + and previously it didn't work either, it just caused undefined behavior. + + Also updated the man pages for these timeout options to mention the + return code. + + Closes #1938 - cookie: fix tailmatching to prevent cross-domain leakage +Viktor Szakats (15 Oct 2017) +- makefile.m32: allow to override gcc, ar and ranlib - Cookies set for 'example.com' could accidentaly also be sent by libcurl - to the 'bexample.com' (ie with a prefix to the first domain name). + Allow to ovverride certain build tools, making it possible to + use LLVM/Clang to build curl. The default behavior is unchanged. + To build with clang (as offered by MSYS2), these settings can + be used: - This is a security vulnerabilty, CVE-2013-1944. + CURL_CC=clang + CURL_AR=llvm-ar + CURL_RANLIB=llvm-ranlib - Bug: http://curl.haxx.se/docs/adv_20130412.html + Closes https://github.com/curl/curl/pull/1993 -Guenter Knauf (11 Apr 2013) -- Enabled MinGW sync resolver builds. +- ldap: silence clang warning + + Use memset() to initialize a structure to avoid LLVM/Clang warning: + ldap.c:193:39: warning: missing field 'UserLength' initializer [-Wmissing-field-initializers] + + Closes https://github.com/curl/curl/pull/1992 -Yang Tse (10 Apr 2013) -- if2ip.c: fix compiler warning +Daniel Stenberg (14 Oct 2017) +- runtests: use valgrind for torture as well + + NOTE: it makes them terribly slow. I recommend only using valgrind for + specific torture tests or using lots of patience. -Guenter Knauf (10 Apr 2013) -- Fixed lost OpenSSL output with "-t" - followup. +- memdebug: trace send, recv and socket + + ... to allow them to be included in torture tests too. - The previously applied patch didnt work on Windows; we cant rely - on shell commands like 'echo' since they act diffently on each - platform and each shell. - In order to keep this script platform-independent the code must - only use pure Perl. + closes #1980 -Daniel Stenberg (9 Apr 2013) -- test1217: verify parsing 257 responses with "rubbish" before path +- configure: remove the C++ compiler check - Test 1217 verifies commit e0fb2d86c9f78, and without that change this - test fails. + ... we used it only for the fuzzer, which we now have in a separate git + repo. + + Closes #1990 + +Patrick Monnerat (13 Oct 2017) +- mime: do not call failf() if easy handle is NULL. -- [Bill Middlecamp brought this change] +Daniel Stenberg (13 Oct 2017) +- test651: curl_formadd with huge COPYCONTENTS - FTP: handle "rubbish" in front of directory name in 257 responses +- mime: fix the content reader to handle >16K data properly - When doing PWD, there's a 257 response which apparently some servers - prefix with a comment before the path instead of after it as is - otherwise the norm. + Reported-by: Jeroen Ooms + Closes #1988 + +Patrick Monnerat (12 Oct 2017) +- mime: keep "text/plain" content type if user-specified. - Failing to parse this, several otherwise legitimate use cases break. + Include test cases in 554, 587, 650. - Bug: http://curl.haxx.se/mail/lib-2013-04/0113.html + Fixes https://github.com/curl/curl/issues/1986 -Guenter Knauf (9 Apr 2013) -- Fixed ares-enabled builds with static makefiles. - -- Fixed lost OpenSSL output with "-t". +- cli tool: use file2memory() to buffer stdin in -F option. - The OpenSSL pipe wrote to the final CA bundle file, but the encoded PEM - output wrote to a temporary file. Consequently, the OpenSSL output was - lost when the temp file was renamed to the final file at script finish - (overwriting the final file written earlier by openssl). - Patch posted to the list by Richard Michael (rmichael edgeofthenet org). + Closes PR https://github.com/curl/curl/pull/1985 -Daniel Stenberg (9 Apr 2013) -- test1216: test tailmatching cookie domains +- cli tool: reimplement stdin buffering in -F option. - This test is an attempt to repeat the problem YAMADA Yasuharu reported - at http://curl.haxx.se/mail/lib-2013-04/0108.html - -- RELEASe-NOTES: synced with 29fdb2700f797 + If stdin is not a regular file, its content is memory-buffered to enable + a possible data "rewind". + In all cases, stdin data size is determined before real use to avoid + having an unknown part's size. - added "tcpkeepalive on Mac OS X" + --libcurl generated code is left as an unbuffered stdin fread/fseek callback + part with unknown data size. + + Buffering is not supported in deprecated curl_formadd() API. + +Daniel Stenberg (12 Oct 2017) +- winbuild/BUILD.WINDOWS.txt: mention WITH_NGHTTP2 -Nick Zitzmann (8 Apr 2013) -- darwinssl: disable insecure ciphers by default +- HELP-US: the label "PR-welcome" is now renamed to "help wanted" - I noticed that aria2's SecureTransport code disables insecure ciphers such - as NULL, anonymous, IDEA, and weak-key ciphers used by SSLv3 and later. - That's a good idea, and now we do the same thing in order to prevent curl - from accessing a "secure" site that only negotiates insecure ciphersuites. + following the new github "standard" -Daniel Stenberg (8 Apr 2013) -- [Robert Wruck brought this change] +- RELEASE-NOTES: synced with 5505df7d2 - tcpkeepalive: Support CURLOPT_TCP_KEEPIDLE on OSX +Jay Satiro (11 Oct 2017) +- [Artak Galoyan brought this change] + + url: Update current connection SSL verify params in setopt + + Now VERIFYHOST, VERIFYPEER and VERIFYSTATUS options change during active + connection updates the current connection's (i.e.'connectdata' + structure) appropriate ssl_config (and ssl_proxy_config) structures + variables, making these options effective for ongoing connection. - MacOS X doesn't have TCP_KEEPIDLE/TCP_KEEPINTVL but only a single - TCP_KEEPALIVE (see - http://developer.apple.com/library/mac/#DOCUMENTATION/Darwin/Reference/ManPages/man4/tcp.4.html). - Here is a patch for CURLOPT_TCP_KEEPIDLE on OSX platforms. + This functionality was available before and was broken by the + following change: + "proxy: Support HTTPS proxy and SOCKS+HTTP(s)" + CommitId: cb4e2be7c6d42ca0780f8e0a747cecf9ba45f151. + + Bug: https://github.com/curl/curl/issues/1941 + + Closes https://github.com/curl/curl/pull/1951 + +Daniel Stenberg (11 Oct 2017) +- [David Benjamin brought this change] -- configure: remove CURL_CHECK_FUNC_RECVFROM + openssl: don't use old BORINGSSL_YYYYMM macros - 1 - We don't use the results from the test and we never did. recvfrom() - is only used by the TFTP code and it has not caused any problems. + Those were temporary things we'd add and remove for our own convenience + long ago. The last few stayed around for too long as an oversight but + have since been removed. These days we have a running + BORINGSSL_API_VERSION counter which is bumped when we find it + convenient, but 2015-11-19 was quite some time ago, so just check + OPENSSL_IS_BORINGSSL. - 2 - the CURL_CHECK_FUNC_RECVFROM function is extremely slow + Closes #1979 -Steve Holme (8 Apr 2013) -- RELEASE-NOTES: Corrected duplicate NTLM memory leaks +- test950; verify SMTP with custom request -- RELEASE-NOTES: Removed trailing full stop +- ftpserver: support case insensitive commands -Daniel Stenberg (8 Apr 2013) -- [Fabian Keil brought this change] +- smtp_done: free data before returning (on send failure) + + ... as otherwise it could leak that memory. + + Detected by OSS-fuzz: + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3600 + + Assisted-by: Max Dymond + Closes #1977 - proxy: make ConnectionExists() check credential of proxyconnections too +- FTP: URL decode path for dir listing in nocwd mode - Previously it only compared credentials if the requested needle - connection wasn't using a proxy. This caused NTLM authentication - failures when using proxies as the authentication code wasn't send on - the connection where the challenge arrived. + Reported-by: Zenju on github - Added test 1215 to verify: NTLM server authentication through a proxy - (This is a modified copy of test 67) + Test 244 added to verify + Fixes #1974 + Closes #1976 -- RELEASE-NOTES: sync with 704a5dfca9 +- test298: verify --ftp-method nowcwd with URL encoded path + + Ref: #1974 -- TODO-RELEASE: cleaned up, not really maintained lately +- CURLOPT_XFERINFODATA.3: fix duplicate see also -Marc Hoersken (7 Apr 2013) -- if2ip.c: Fixed another warning: unused parameter 'remote_scope' +- CURLOPT_NOPROGRESS.3: also refer to xferinfofunction -Daniel Stenberg (7 Apr 2013) -- [Marc Hoersken brought this change] +- FAQ: s/CURLOPT_PROGRESSFUNCTION/CURLOPT_XFERINFOFUNCTION - cookie.c: Made cookie sort function more deterministic +- openssl: enable PKCS12 support for !BoringSSL - Since qsort implementations vary with regards to handling the order - of similiar elements, this change makes the internal sort function - more deterministic by comparing path length first, then domain length - and finally the cookie name. Spotted with testcase 62 on Windows. + Enable PKCS12 for all non-boringssl builds without relying on configure + or cmake checks. + + Bug: https://curl.haxx.se/mail/lib-2017-10/0007.html + Reported-by: Christian Schmitz + Closes #1948 -Marc Hoersken (7 Apr 2013) -- curl_schannel.c: Follow up on memory leak fix ae4558d +- [Kristiyan Tsaklev brought this change] -- Revert "getpart.pm: Strip carriage returns to fix Windows support" + curl: don't pass semicolons when parsing Content-Disposition + + Test 1422 updated to verify. - This reverts commit e51b23c925a2721cf7c29b2b376d3d8903cfb067. - As discussed on the mailinglist, this was not the correct approach. + Closes #1964 -- http_negotiate.c: Fixed passing argument from incompatible pointer type +Patrick Monnerat (9 Oct 2017) +- mime: properly unbind mime structure in curl_mime_free(). + + This allows freeing a mime structure bound to the easy handle before + curl_easy_cleanup(). + + Fixes #1970. -- ftp.c: Added missing brackets around ABOR command logic +Daniel Stenberg (9 Oct 2017) +- RTSP: avoid integer overflow on funny RTSP response + + ... like a very large non-existing RTSP version number. + + Added test 577 to verify. + + Detected by OSS-fuzz. + Closes #1969 -- sockfilt.c: Fixed detection of client-side connection close +Patrick Monnerat (8 Oct 2017) +- ftpserver: properly reset $ftptargetdir. + +- test643: verify curl_mime_subparts() rejects cyclic additions. + +- mime: refuse to add subparts to one of their own descendants. - WINSOCK only: - Since FD_CLOSE is only signaled once, it may trigger at the same - time as FD_READ. Data actually being available makes it impossible - to detect that the connection was closed by checking that recv returns - zero. Another recv attempt could block the connection if it was - not closed. This workaround abuses exceptfds in conjunction with - readfds to signal that the connection has actually closed. + Reported-by: Alexey Melnichuk + Fixes #1962 -- curl_schannel.c: Fixed memory leak if connection was not successful +- mime: avoid resetting a part's encoder when part's contents change. -- if2ip.c: Fixed warning: unused parameter 'remote_scope' +- mime: improve unbinding top multipart from easy handle. + + Also avoid dangling pointers in referencing parts. -- runtests.pl: Fixed --verbose parameter passed to http_pipe.py +Daniel Stenberg (8 Oct 2017) +- RELEASE-NOTES: synced with a4c1c75da30af1 -- sockfilt.c: Reduce CPU load while running under a Windows PIPE +- curlver.h: next expected release is 7.57.0 -- tftpd.c: Apply sread timeout to the whole data transfer session +Patrick Monnerat (8 Oct 2017) +- mime: be tolerant about setting twice the same header list in a part. -- getpart.pm: Strip carriage returns to fix Windows support +- docs: clarify form/mime usage of non-regular data files. -Daniel Stenberg (6 Apr 2013) -- ftp tests: libcurl returns CURLE_FTP_ACCEPT_FAILED better now +Daniel Stenberg (8 Oct 2017) +- Revert "multi_done: wait for name resolve to finish if still ongoing" + + This reverts commit f3e03f6c0ac52a1bf396e03f7d7e9b5b3b7165fe. - Since commit 57aeabcc1a20f, it handles errors on the control connection - while waiting for the data connection better. + Caused memory leaks in the fuzzer, needs to be done differently. - Test 591 and 592 are updated accordingly. + Disable test 1553 for now too, as it causes memory leaks without this + commit! -- FTP: wait on both connections during active STOR state +- remove_handle: call multi_done() first, then clear dns cache pointer - When doing PORT and upload (STOR), this function needs to extract the - file descriptor for both connections so that it will respond immediately - when the server eventually connects back. + Closes #1960 + +- multi_done: wait for name resolve to finish if still ongoing + + ... as we must clean up memory. + +- pingpong: return error when trying to send without connection + + When imap_done() got called before a connection is setup, it would try + to "finish up" and dereffed a NULL pointer. - This flaw caused active connections to become unnecessary slow but they - would still often work due to the normal polling on a timeout. The bug - also would not occur if the server connected back very fast, like when - testing on local networks. + Test case 1553 managed to reproduce. I had to actually use a host name + to try to resolve to slow it down, as using the normal local server IP + will make libcurl get a connection in the first curl_multi_perform() + loop and then the bug doesn't trigger. - Bug: http://curl.haxx.se/bug/view.cgi?id=1183 - Reported by: Daniel Theron + Fixes #1953 + Assisted-by: Max Dymond -Marc Hoersken (6 Apr 2013) -- tftpd.c: Follow up cleanup and restore of previous sockopt +Dan Fandrich (6 Oct 2017) +- tests: added flaky keyword to tests 587 and 644 + + These are around 5% flaky in my Linux x86 autobuilds. -Daniel Stenberg (6 Apr 2013) -- [Kim Vandry brought this change] +Marcel Raad (6 Oct 2017) +- vtls: fix warnings with --disable-crypto-auth + + When CURL_DISABLE_CRYPTO_AUTH is defined, Curl_none_md5sum's parameters + are not used. - connect: treat an interface bindlocal() problem as a non-fatal error +Daniel Stenberg (6 Oct 2017) +- multi_cleanup: call DONE on handles that never got that - I am using curl_easy_setopt(CURLOPT_INTERFACE, "if!something") to force - transfers to use a particular interface but the transfer fails with - CURLE_INTERFACE_FAILED, "Failed binding local connection end" if the - interface I specify has no IPv6 address. The cause is as follows: + ... fixes a memory leak with at least IMAP when remove_handle is never + called and the transfer is abruptly just abandoned early. - The remote hostname resolves successfully and has an IPv6 address and an - IPv4 address. + Test 1552 added to verify - cURL attempts to connect to the IPv6 address first. + Detected by OSS-fuzz + Assisted-by: Max Dymond + Closes #1954 + +- [Benbuck Nason brought this change] + + strtoofft: Remove extraneous null check - bindlocal (in lib/connect.c) fails because Curl_if2ip cannot find an - IPv6 address on the interface. + Fixes #1950: curlx_strtoofft() doesn't fully protect against null 'str' + argument. - This is a fatal error in singleipconnect() + Closes #1952 + +- openssl: fix build without HAVE_OPAQUE_EVP_PKEY - This change will make cURL try the next IP address in the list. + Reported-by: Javier Sixto + Fixes #1955 + Closes #1956 + +Viktor Szakats (6 Oct 2017) +- lib/config-win32.h: let SMB/SMBS be enabled with OpenSSL/NSS - Also included are two changes related to IPv6 address scope: + The source code is now prepared to handle the case when both + Win32 Crypto and OpenSSL/NSS crypto backends are enabled + at the same time, making it now possible to enable `USE_WIN32_CRYPTO` + whenever the targeted Windows version supports it. Since this + matches the minimum Windows version supported by curl + (Windows 2000), enable it unconditionally for the Win32 platform. - - Filter the choice of address in Curl_if2ip to only consider addresses - with the same scope ID as the connection address (mismatched scope for - local and remote address does not result in a working connection). + This in turn enables SMB (and SMBS) protocol support whenever + Win32 Crypto is available, regardless of what other crypto backends + are enabled. - - bindlocal was ignoring the scope ID of addresses returned by - Curl_if2ip . Now it uses them. + Ref: https://github.com/curl/curl/pull/1840#issuecomment-325682052 - Bug: http://curl.haxx.se/bug/view.cgi?id=1189 - -Marc Hoersken (6 Apr 2013) -- tftpd.c: Fixed sread timeout on Windows by setting it manually - -- ftp.pm: Added tskill to support Windows XP Home - -- runtests.pl: Modularization of MinGW/Msys compatibility functions + Closes https://github.com/curl/curl/pull/1943 -- ftp.pm: Made Perl testsuite able to handle Windows processes +Daniel Stenberg (5 Oct 2017) +- build: fix --disable-crypto-auth + + Reported-by: Wyatt O'Day + Fixes #1945 + Closes #1947 -- util.c: Revert workaround eeefcdf, 6eb56e7 and e3787e8 +Jay Satiro (5 Oct 2017) +- [Nick Zitzmann brought this change] -- ftp.pm: Made Perl testsuite able to kill Windows processes + darwinssl: add support for TLSv1.3 + + Closes https://github.com/curl/curl/pull/1794 -- util.c: Follow up cleanup on eeefcdf +Daniel Stenberg (4 Oct 2017) +- [Felix Kaiser brought this change] -Daniel Stenberg (6 Apr 2013) -- cpp: use #ifdef __MINGW32__ to avoid compiler complaints + docs: fix typo in curl_mime_data_cb man page - ... instead of just #if + Closes #1946 -Marc Hoersken (6 Apr 2013) -- util.c: Made write_pidfile write the correct PID on MinGW/Msys +Viktor Szakats (4 Oct 2017) +- lib/Makefile.m32: allow customizing dll suffixes - This workaround fixes an issue on MinGW/Msys regarding the Perl - testsuite scripts not being able to signal or control the server - processes. The MinGW Perl runtime only sees the Msys processes and - their corresponding PIDs, but sockfilt (and other servers) wrote the - Windows PID into their PID-files. Since this PID is useless to the - testsuite, the write_pidfile function was changed to search for the - Msys PID and write that into the PID-file. - -Daniel Stenberg (5 Apr 2013) -- RELEASE-NOTES: synced with 5e722b2d09087 + - New `CURL_DLL_SUFFIX` envvar will add a suffix to the generated + libcurl dll name. Useful to add `-x64` to 64-bit builds so that + it can live in the same directory as the 32-bit one. By default + this is empty. - 3 more bug fixes, 6 more contributors - -Marc Hoersken (5 Apr 2013) -- sockfilt.c: Fixed handling of multiple fds being signaled - -Kamil Dudka (5 Apr 2013) -- curl_global_init.3: improve description of CURL_GLOBAL_ALL + - New `CURL_DLL_A_SUFFIX` envvar to customize the suffix of the + generated import library (implib) for libcurl .dll. It defaults + to `dll`, and it's useful to modify that to `.dll` to have the + standard naming scheme for mingw-built .dlls, i.e. `libcurl.dll.a`. - Reported by: Tomas Mlcoch + Closes https://github.com/curl/curl/pull/1942 + +Daniel Stenberg (4 Oct 2017) +- [Max Dymond brought this change] -- examples/multi-single.c: fix the order of destructions + fuzzer: move to using external curl-fuzzer - ... so that it adheres to the API documentation. + Use the external curl-fuzzer repository for fuzzing. - Reported by: Tomas Mlcoch + Closes #1923 -Daniel Stenberg (5 Apr 2013) -- Curl_open: restore default MAXCONNECTS to 5 +- failf: skip the sprintf() if there are no consumers - At some point recently we lost the default value for the easy handle's - connection cache, and this change puts it back to 5 - which is the - former default value and it is documented in the curl_easy_setopt.3 man - page. + Closes #1936 -Marc Hoersken (4 Apr 2013) -- sockfilt.c: Added wrapper functions to fix Windows console issues +- ftp: UBsan fixup 'pointer index expression overflowed' - The new read and write wrapper functions support reading from stdin - and writing to stdout/stderr on Windows by using the appropriate - Windows API functions and data types. + Closes #1939 + +- RELEASE-PROCEDURE: update the release schedule -Yang Tse (4 Apr 2013) -- lib1509.c: fix compiler warnings +Version 7.56.0 (4 Oct 2017) -- easy.c: fix compiler warning +Daniel Stenberg (4 Oct 2017) +- RELEASE-NOTES: curl 7.56.0 -Daniel Stenberg (4 Apr 2013) -- --engine: spellfix the help message +- THANKS: added new 7.56.0 contributors + +Jay Satiro (4 Oct 2017) +- build-openssl.bat: Warn OpenSSL 1.1.0 not yet supported - Reported by: Fredrik Thulin + Ref: https://github.com/curl/curl/issues/1002 -Yang Tse (4 Apr 2013) -- http_negotiate.c: follow-up for commit 3dcc1a9c +Michael Kaufmann (3 Oct 2017) +- idn: fix source code comment -Linus Nielsen Feltzing (4 Apr 2013) -- easy: Fix the broken CURLOPT_MAXCONNECTS option +- vtls: compare and clone ssl configs properly + + Compare these settings in Curl_ssl_config_matches(): + - verifystatus (CURLOPT_SSL_VERIFYSTATUS) + - random_file (CURLOPT_RANDOM_FILE) + - egdsocket (CURLOPT_EGDSOCKET) - Copy the CURLOPT_MAXCONNECTS option to CURLMOPT_MAXCONNECTS in - curl_easy_perform(). + Also copy the setting "verifystatus" in Curl_clone_primary_ssl_config(), + and copy the setting "sessionid" unconditionally. - Bug: http://curl.haxx.se/bug/view.cgi?id=1212 - Reported-by: Steven Gu + This means that reusing connections that are secured with a client + certificate is now possible, and the statement "TLS session resumption + is disabled when a client certificate is used" in the old advisory at + https://curl.haxx.se/docs/adv_20170419.html is obsolete. + + Reviewed-by: Daniel Stenberg + + Closes #1917 -Guenter Knauf (4 Apr 2013) -- Updated copyright date. +- proxy: read the "no_proxy" variable only if necessary + + Reviewed-by: Daniel Stenberg + + Closes #1919 -- Another small output fix for --help and --version. +Patrick Monnerat (3 Oct 2017) +- libcurl-tutorial: add casts in example to avoid compilation warnings. -Yang Tse (4 Apr 2013) -- http_negotiate.c: fix several SPNEGO memory handling issues +Daniel Stenberg (3 Oct 2017) +- examples: bring back curl_formadd-using examples + + ... now with a -formadd suffix. While the new mime API is introduced in + 7.56.0 we must acknowledge that lots of users can't upgrade their curl + versions immediately. -Guenter Knauf (4 Apr 2013) -- Added a cont to specify base64 line wrap. +- test1153: verify quoted double-qoutes in PWD response -- Fixed version output. +- FTP: zero terminate the entry path even on bad input + + ... a single double quote could leave the entry path buffer without a zero + terminating byte. CVE-2017-1000254 + + Test 1152 added to verify. + + Reported-by: Max Dymond + Bug: https://curl.haxx.se/docs/adv_20171004.html -- Added support for --help and --version options. +Jay Satiro (2 Oct 2017) +- [Sergei Nikulov brought this change] -- Added option to specify length of base64 output. + cmake: disable tests and man generation if perl/nroff not found - Based on a patch posted to the list by Richard Michael. + Fixes https://github.com/curl/curl/issues/1500 + Reported-by: Jay Satiro + + Fixes https://github.com/curl/curl/pull/1662 + Assisted-by: Tom Seddon + Assisted-by: dpull@users.noreply.github.com + Assisted-by: elelel@users.noreply.github.com + + Closes https://github.com/curl/curl/pull/1924 -Daniel Stenberg (3 Apr 2013) -- curl_easy_setopt.3: CURLOPT_HTTPGET disables CURLOPT_UPLOAD +Patrick Monnerat (2 Oct 2017) +- libcurl-tutorial: fix two typos. -- [Yasuharu Yamada brought this change] +- TODO: remove deprecated form API items. - Curl_cookie_add: only increase numcookies for new cookies +- libcurl-tutorial: describe MIME API and deprecate form API. - Count up numcookies in Curl_cookie_add() only when cookie is new one + Include a guide to form/mime API conversion. -- SO_SNDBUF: don't set SNDBUF for win32 versions vista or later +Daniel Stenberg (30 Sep 2017) +- cookie: fix memory leak if path was set twice in header - The Microsoft knowledge-base article - http://support.microsoft.com/kb/823764 describes how to use SNDBUF to - overcome a performance shortcoming in winsock, but it doesn't apply to - Windows Vista and later versions. If the described SNDBUF magic is - applied when running on those more recent Windows versions, it seems to - instead have the reversed effect in many cases and thus make libcurl - perform less good on those systems. + ... this will let the second occurance override the first. - This fix thus adds a run-time version-check that does the SNDBUF magic - conditionally depending if it is deemed necessary or not. + Added test 1161 to verify. - Bug: http://curl.haxx.se/bug/view.cgi?id=1188 - Reported by: Andrew Kurushin - Tested by: Christian Hägele + Reported-by: Max Dymond + Fixes #1932 + Closes #1933 -Nick Zitzmann (1 Apr 2013) -- darwinssl: additional descriptive messages of SSL handshake errors +Dan Fandrich (30 Sep 2017) +- test650: Use variable replacement to set the host address and port - (This doesn't need to appear in the release notes.) + Otherwise, the test fails when the -b test option is used to set a + different test port range. -Guenter Knauf (1 Apr 2013) -- Added dns and connect time to output. - -Daniel Stenberg (1 Apr 2013) -- RELEASE-NOTES: synced with 0614b902136 +- Set and use more necessary options when some protocols are disabled + + When curl and libcurl are built with some protocols disabled, they stop + setting and receiving some options that don't make sense with those + protocols. In particular, when HTTP is disabled many options aren't set + that are used only by HTTP. However, some options that appear to be + HTTP-only are actually used by other protocols as well (some despite + having HTTP in the name) and should be set, but weren't. This change now + causes some of these options to be set and used for more (or for all) + protocols. In particular, this fixes tests 646 through 649 in an + HTTP-disabled build, which use the MIME API in the mail protocols. -- code-policed +Daniel Stenberg (29 Sep 2017) +- test1160: verifies cookie leak for large cookies + + The fix done in 20ea22ff735 -- tcpkeepalive: support TCP_KEEPIDLE/TCP_KEEPINTVL on win32 +- cookie: fix memory leak on oversized rejection + + Regression brought by 2bc230de63b - Patch by: Robert Wruck - Bug: http://curl.haxx.se/bug/view.cgi?id=1209 + Detected by OSS-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3513 + Assisted-by: Max Dymond + + Closes #1930 -- BINDINGS: BBHTTP is a cocoa binding, Julia has a binding +- [Anders Bakken brought this change] -- ftp_sendquote: use PPSENDF, not FTPSENDF + connect: fix race condition with happy eyeballs timeout + + The timer should be started after conn->connecttime is set. Otherwise + the timer could expire without this condition being true: - The last remaining code piece that still used FTPSENDF now uses PPSENDF. - In the problematic case, a PREQUOTE series was done on a re-used - connection when Curl_pp_init() hadn't been called so it had messed up - pointers. The init call is done properly from Curl_pp_sendf() so this - change fixes this particular crash. + /* should we try another protocol family? */ + if(i == 0 && conn->tempaddr[1] == NULL && + curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) { - Bug: http://curl.haxx.se/mail/lib-2013-03/0319.html - Reported by: Sam Deane + Ref: #1928 -Steve Holme (27 Mar 2013) -- RELEASE-NOTES: Corrected typo +Michael Kaufmann (28 Sep 2017) +- docs: link CURLOPT_CONNECTTIMEOUT and CURLOPT_CONNECTTIMEOUT_MS + + Closes #1922 -Daniel Stenberg (27 Mar 2013) -- [Clemens Gruber brought this change] +- docs: clarify the use of environment variables for proxy + + Closes #1921 - multi-uv.c: remove unused variable +- http: add custom empty headers to repeated requests + + Closes #1920 -- RELEASE-NOTES: add two references +- reuse_conn: don't copy flags that are known to be equal + + A connection can only be reused if the flags "conn_to_host" and + "conn_to_port" match. Therefore it is not necessary to copy these flags + in reuse_conn(). + + Closes #1918 -- test1509: verify proxy header response headers count +Daniel Stenberg (27 Sep 2017) +- curl.h: include <sys/select.h> on cygwin too - Modified sws to support and use custom CONNECT responses instead of the - previously naive hard-coded version. Made the HTTP test server able to - extract test case number from the host name in a CONNECT request by - finding the number after the last dot. It makes 'machine.moo.123' use - test case 123. + When building with -std=c++14 on cygwin, this header won't be + automatically included as it otherwise is. - Adapted a larger amount of tests to the new <connect> style. + The <sys/select.h> include decision should ideally be reversed and be + avoided where that header file doesn't exist. - Bug: http://curl.haxx.se/bug/view.cgi?id=1204 - Reported by: Martin Jansen - -- [Clemens Gruber brought this change] + Reported-by: Ian Fette + Fixes #1925 - Added libuv example multi-uv.c +- RELEASE-NOTES: synced with d8ab5dc50 -Yang Tse (25 Mar 2013) -- NTLM: fix several NTLM code paths memory leaks +Michael Kaufmann (24 Sep 2017) +- tests: adjust .gitignore for new tests -- WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage +Jay Satiro (23 Sep 2017) +- ntlm: move NTLM_NEEDS_NSS_INIT define into core NTLM header - As of 25-mar-2013 wcsdup() _wcsdup() and _tcsdup() are only used in - WIN32 specific code, so tracking of these has not been extended for - other build targets. Without this fix, memory tracking system on - WIN32 builds, when using these functions, would provide misleading - results. + .. and include the core NTLM header in all NTLM-related source files. - In order to properly extend this support for all targets curl.h - would have to define curl_wcsdup_callback prototype and consequently - wchar_t should be visible before that in curl.h. IOW curl_wchar_t - defined in curlbuild.h and this pulling whatever system header is - required to get wchar_t definition. + Follow up to 6f86022. Since then http_ntlm checks NTLM_NEEDS_NSS_INIT + but did not include vtls.h where it was defined. - Additionally a new curl_global_init_mem() function that also receives - user defined wcsdup() callback would be required. + Closes https://github.com/curl/curl/pull/1911 -- curl_ntlm_msgs.c: revert commit 463082bea4 +Daniel Stenberg (23 Sep 2017) +- file_range: avoid integer overflow when figuring out byte range - reverts unreleased invalid memory leak fix - -Daniel Stenberg (23 Mar 2013) -- RELEASE-NOTES: synced with bc6037ed3ec02 + When trying to bump the value with one and the value is already at max, + it causes an integer overflow. - More changes, bugfixes and contributors! + Closes #1908 + Detected by oss-fuzz: + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3465 + + Assisted-by: Max Dymond -- [Martin Jansen brought this change] +Michael Kaufmann (23 Sep 2017) +- tests: fix a compiler warning in test 643 - Curl_proxyCONNECT: count received headers +Jay Satiro (23 Sep 2017) +- symbols-in-versions: fix CURLSSLSET_NO_BACKENDS entry - Proxy servers tend to add their own headers at the beginning of - responses. The size of these headers was not taken into account by - CURLINFO_HEADER_SIZE before this change. + - Use spaces instead of tabs as the delimiter. - Bug: http://curl.haxx.se/bug/view.cgi?id=1204 + Follow up to 7c52b12 which added the entry. The entry had used tabs but + the symbol-scan parser doesn't recognize tabs and would fail the symbol. -Steve Holme (21 Mar 2013) -- sasl: Corrected a few violations of the curl coding standards +Viktor Szakats (22 Sep 2017) +- metalink: fix NSS issue in MultiSSL builds - Corrected some incorrectly positioned pointer variable declarations to - be "char *" rather than "char* ". - -- multi.c: Corrected a couple of violations of the curl coding standards + In MultiSSL mode (i.e. when more than one SSL backend is compiled + in), we cannot use the compile time flag `USE_NSS` as indicator that + the NSS backend is in use. As far as Metalink is concerned, the SSL + backend is only used for MD5, SHA-1 and SHA-256 calculations, + therefore one of the available SSL backends is selected at compile + time, in a strict order of preference. - Corrected some incorrectly positioned pointer variable declarations to - be "type *" rather than "type* ". - -- imap-tests: Added CRLF to reply data to be compliant with RFC-822 + Let's introduce a new `HAVE_NSS_CONTEXT` constant that can be used + to determine whether the SSL backend used for Metalink is the NSS + backend, and use that to guard the code that wants to de-initialize + the NSS-specific data structure. - Updated the reply data in tests: 800, 801, 802, 804 and 1321 to possess - the CRLF as per RFC-822. + Ref: https://github.com/curl/curl/pull/1848 -- multi.c: Fix compilation warning +- ntlm: use strict order for SSL backend #if branches - warning: an enumerated type is mixed with another type - -- multi.c: fix compilation error + With the recently introduced MultiSSL support multiple SSL backends + can be compiled into cURL That means that now the order of the SSL - warning: conversion from enumeration type to different enumeration type - -- lib1900.c: fix compilation warning + One option would be to use the same SSL backend as was configured + via `curl_global_sslset()`, however, NTLMv2 support would appear + to be available only with some SSL backends. For example, when + eb88d778e (ntlm: Use Windows Crypt API, 2014-12-02) introduced + support for NTLMv1 using Windows' Crypt API, it specifically did + *not* introduce NTLMv2 support using Crypt API at the same time. + + So let's select one specific SSL backend for NTLM support when + compiled with multiple SSL backends, using a priority order such + that we support NTLMv2 even if only one compiled-in SSL backend can + be used for that. - warning: declaration of 'time' shadows a global declaration + Ref: https://github.com/curl/curl/pull/1848 -Yang Tse (20 Mar 2013) -- [John E. Malmberg brought this change] +Daniel Stenberg (22 Sep 2017) +- symbols-in-versions: add CURLSSLSET_NO_BACKENDS + + ...fixup from b8e0fe19ec - build_vms.com: use existing curlbuild.h and parsing fix +- imap: quote atoms properly when escaping characters - This patch removes building curlbuild.h from the build_vms.com procedure - and uses the one in the daily or release tarball instead. + Updates test 800 to verify - packages/vms/build_curlbuild_h.com is obsolete with this change. + Fixes #1902 + Closes #1903 + +- tests: make the imap server not verify user+password - Accessing the library module name "tool_main" needs different handling - when the optional extended parsing is enabled. + ... as the test cases themselves do that and it makes it easier to add + crazy test cases. - Tested on IA64/VMS 8.4 and VAX/VMS 7.3 - -Nick Zitzmann (19 Mar 2013) -- darwinssl: disable ECC ciphers under Mountain Lion by default + Test 800 updated to use user name + password that need quoting. - I found out that ECC doesn't work as of OS X 10.8.3, so those ciphers are - turned off until the next point release of OS X. - -Steve Holme (18 Mar 2013) -- FEATURES: Small tidy up for constancy and grammar - -Daniel Stenberg (18 Mar 2013) -- [Oliver Schindler brought this change] + Test 856 updated to trigger an auth fail differently. + + Ref: #1902 - Curl_proxyCONNECT: clear 'rewindaftersend' on success +- vtls: provide curl_global_sslset() even in non-SSL builds - After having done a POST over a CONNECT request, the 'rewindaftersend' - boolean could be holding the previous value which could lead to badness. + ... it just returns error: - This should be tested for in a new test case! + Bug: https://github.com/curl/curl/commit/1328f69d53f2f2e937696ea954c480412b018451#commitcomment-24470367 + Reported-by: Marcel Raad - Bug: https://groups.google.com/d/msg/msysgit/B31LNftR4BI/KhRTz0iuGmUJ + Closes #1906 -Steve Holme (18 Mar 2013) -- TODO: Reordered the protocol and security sections - - Moved SMTP, POP3, IMAP and New Protocol sections to be listed after the - other protocols (FTP, HTTP and TELNET) and SASL to be after SSL and - GnuTLS as these are all security related. +Patrick Monnerat (22 Sep 2017) +- form/mime: field names are not allowed to contain zero-valued bytes. - Additionally fixed numbering of the SSL and GnuTLS sections as they - weren't consecutive. + Also suppress length argument of curl_mime_name() (names are always + zero-terminated). -Yang Tse (18 Mar 2013) -- tests: specify 'text' mode for some output files in verify section +Daniel Stenberg (21 Sep 2017) +- [Dirk Feytons brought this change] -Steve Holme (17 Mar 2013) -- imap: Fixed incorrect initial response generation for SASL AUTHENTICATE + openssl: only verify RSA private key if supported - Fixed incorrect initial response generation for the NTLM and LOGIN SASL - authentication mechanisms when the SASL-IR was detected. + In some cases the RSA key does not support verifying it because it's + located on a smart card, an engine wants to hide it, ... + Check the flags on the key before trying to verify it. + OpenSSL does the same thing internally; see ssl/ssl_rsa.c - Introduced in commit: 6da7dc026c14. - -- FEATURES: Expanded the supported enhanced IMAP command list - -- TODO: Corrected typo in TOC + Closes #1904 -- TODO: Added IMAP section and removed unused Other protocols section +Marcel Raad (21 Sep 2017) +- examples/post-callback: use long for CURLOPT_POSTFIELDSIZE + + Otherwise, typecheck-gcc.h warns on MinGW-w64. -- TODO: Added graceful base64 decoding failure to SMTP and POP3 +Patrick Monnerat (20 Sep 2017) +- mime: rephrase the multipart output state machine (#1898) ... + + ... in hope coverity will like it much. -- TODO: Corrected typo on section 10.2 heading +- mime: fix an explicit null dereference (#1899) -Yang Tse (16 Mar 2013) -- tests: 96, 558, 1330: strip build subdirectory dependent leading path +Daniel Stenberg (20 Sep 2017) +- curl: check fseek() return code and bail on error + + Detected by coverity. CID 1418137. -Steve Holme (15 Mar 2013) -- TODO: Added section 10.2 Initial response to POP3 to do list +- smtp: fix memory leak in OOM + + Regression since ce0881edee + + Coverity CID 1418139 and CID 1418136 found it, but it was also seen in + torture testing. -- imap-tests: Corrected copy/paste error in test808 reply data +- RELEASE-NOTES: synced with 5fe85587c -Yang Tse (15 Mar 2013) -- unit1330.c: fix date +- [Pavel Pavlov brought this change] -- tests: add #96 #558 and #1330 + cookies: use lock when using CURLINFO_COOKIELIST - These verfy that the 'memory tracking' subsystem is actually doing its - job when using curl tool (#96), a test in libtest (#558) and also a unit - test (#1330), in order to prevent regressions in this functionallity. + Closes #1896 -Steve Holme (15 Mar 2013) -- imap-tests: Added test808 for custom EXAMINE command +- [Max Dymond brought this change] -Daniel Stenberg (15 Mar 2013) -- HTTP proxy: insert slash in URL if missing + ossfuzz: changes before merging the generated corpora - curl has been accepting URLs using slightly wrong syntax for a long - time, such as when completely missing as slash "http://example.org" or - missing a slash when a query part is given - "http://example.org?q=foobar". + Before merging in the oss-fuzz corpora from Google, there are some changes + to the fuzzer. + - Add a read corpus script, to display corpus files nicely. + - Change the behaviour of the fuzzer so that TLV parse failures all now + go down the same execution paths, which should reduce the size of the + corpora. + - Make unknown TLVs a failure to parse, which should decrease the size + of the corpora as well. - curl would translate these into a legitimate HTTP request to servers, - although as was shown in bug #1206 it was not adjusted properly in the - cases where a HTTP proxy was used. - - Test 1213 and 1214 were added to the test suite to verify this fix. - - The test HTTP server was adjusted to allow us to specify test number in - the host name only without using any slashes in a given URL. - - Bug: http://curl.haxx.se/bug/view.cgi?id=1206 - Reported by: ScottJi + Closes #1881 -Steve Holme (14 Mar 2013) -- ftpserver.pl: Added EXAMINE_imap() for IMAP EXAMINE commands +- mime:escape_string minor clarification change - Used hard coded data from RFC-3501 section 6.3.2. - -Yang Tse (14 Mar 2013) -- curl_memory.h: introduce CURLX_NO_MEMORY_CALLBACKS usage possibility + ... as it also removes a warning with old gcc versions. - This commit alone does not fix anything nor modifies existing - interfaces or behaviors, although it is a prerequisite for other - fixes. + Bug: https://curl.haxx.se/mail/lib-2017-09/0049.html + Reported-by: Ben Greear -- Makefile.vc6: add missing files +- [Max Dymond brought this change] -Linus Nielsen Feltzing (14 Mar 2013) -- pipelining: Remove dead code. + ossfuzz: don't write out to stdout + + Don't make the fuzzer write out to stdout - instead write some of the + contents to a memory block so we exercise the data output code but + quietly. + + Closes #1885 -- Multiple pipelines and limiting the number of connections. +- cookies: reject oversized cookies + + ... instead of truncating them. + + There's no fixed limit for acceptable cookie names in RFC 6265, but the + entire cookie is said to be less than 4096 bytes (section 6.1). This is + also what browsers seem to implement. - Introducing a number of options to the multi interface that - allows for multiple pipelines to the same host, in order to - optimize the balance between the penalty for opening new - connections and the potential pipelining latency. + We now allow max 5000 bytes cookie header. Max 4095 bytes length per + cookie name and value. Name + value together may not exceed 4096 bytes. - Two new options for limiting the number of connections: + Added test 1151 to verify - CURLMOPT_MAX_HOST_CONNECTIONS - Limits the number of running connections - to the same host. When adding a handle that exceeds this limit, - that handle will be put in a pending state until another handle is - finished, so we can reuse the connection. + Bug: https://curl.haxx.se/mail/lib-2017-09/0062.html + Reported-by: Kevin Smith - CURLMOPT_MAX_TOTAL_CONNECTIONS - Limits the number of connections in total. - When adding a handle that exceeds this limit, - that handle will be put in a pending state until another handle is - finished. The free connection will then be reused, if possible, or - closed if the pending handle can't reuse it. + Closes #1894 + +- travis: on mac, don't install openssl or libidn - Several new options for pipelining: + - openssl is already installed and causes warnings when trying to + install again - CURLMOPT_MAX_PIPELINE_LENGTH - Limits the pipeling length. If a - pipeline is "full" when a connection is to be reused, a new connection - will be opened if the CURLMOPT_MAX_xxx_CONNECTIONS limits allow it. - If not, the handle will be put in a pending state until a connection is - ready (either free or a pipe got shorter). + - libidn isn't used these days, and homebrew doesn't seem to have a + libidn2 package to replace with easily - CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE - A pipelined connection will not - be reused if it is currently processing a transfer with a content - length that is larger than this. + Closes #1895 + +- curl: make str2udouble not return values on error - CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE - A pipelined connection will not - be reused if it is currently processing a chunk larger than this. + ... previously it would store a return value even when it returned + error, which could make the value get used anyway! - CURLMOPT_PIPELINING_SITE_BL - A blacklist of hosts that don't allow - pipelining. + Reported-by: Brian Carpenter + Closes #1893 + +Jay Satiro (18 Sep 2017) +- socks: fix incorrect port number in SOCKS4 error message - CURLMOPT_PIPELINING_SERVER_BL - A blacklist of server types that don't allow - pipelining. + Prior to this change it appears the SOCKS5 port parsing was erroneously + used for the SOCKS4 error message, and as a result an incorrect port + would be shown in the error message. - See the curl_multi_setopt() man page for details. + Bug: https://github.com/curl/curl/issues/1892 + Reported-by: Jackarain@users.noreply.github.com + +- [Marc Aldorasi brought this change] -Yang Tse (13 Mar 2013) -- tool_main.c: remove redundant vms_show storage-class specifier + schannel: Support partial send for when data is too large - vms_show 'extern' storage-class specifier removed from tool_main.c due to... + Schannel can only encrypt a certain amount of data at once. Instead of + failing when too much data is to be sent at once, send as much data as + we can and let the caller send the remaining data by calling send again. - - Advice from Tor Arntsen: http://curl.haxx.se/mail/lib-2013-03/0164.html + Bug: https://curl.haxx.se/mail/lib-2014-07/0033.html - - HP OpenVMS docs stating that 'Extern is the default storage class for - variables declared outside a function.' - http://h71000.www7.hp.com/commercial/c/docs/dec_c_help_5.html - (Storage_Classes section) + Closes https://github.com/curl/curl/pull/1890 -- test509: libcurl initialization with memory callbacks and actual usage +- [David Benjamin brought this change] -Steve Holme (13 Mar 2013) -- pop3: Removed unnecessary transfer cancellation + openssl: add missing includes - Following commit e450f66a02d8 and the changes in the multi interface - being used internally, from 7.29.0, the transfer cancellation in - pop3_dophase_done() is no longer required. + lib/vtls/openssl.c uses OpenSSL APIs from BUF_MEM and BIO APIs. Include + their headers directly rather than relying on other OpenSSL headers + including things. + + Closes https://github.com/curl/curl/pull/1891 -Yang Tse (13 Mar 2013) -- Makefile.am: add VMS files not being included in tarball +Daniel Stenberg (15 Sep 2017) +- conversions: fix several compiler warnings -- [Tom Grace brought this change] +- server/getpart: provide dummy function to build conversion enabled - build_vms.com: VMS build fixes +- non-ascii: use iconv() with 'char **' argument - Added missing slash in cc_full_list. - Removed unwanted extra quotes inside symbol tool_main - for non-VAX architectures that triggered link failure. - Replaced curl_sys_inc with sys_inc. + Bug: https://curl.haxx.se/mail/lib-2017-09/0031.html + +- escape.c: error: pointer targets differ in signedness + +- docs: clarify the CURLOPT_INTERLEAVE* options behavior -- [Tom Grace brought this change] +- [Max Dymond brought this change] - tool_main.c: fix VMS global variable storage-class specifier + rtsp: Segfault in rtsp.c when using WRITEDATA - An extern submits a psect and a global reference to the linker to point - to it. Using "extern int vms_show = 0" also creates a globaldef. + If the INTERLEAVEFUNCTION is defined, then use that plus the + INTERLEAVEDATA information when writing RTP. Otherwise, use + WRITEFUNCTION and WRITEDATA. - The use of the extern by itself does declare a psect but does not declare - a globalsymbol. It does declare a globalref. But the linker needs one and - only one globaldef or there is an error. + Fixes #1880 + Closes #1884 -Patrick Monnerat (12 Mar 2013) -- OS400: synchronize RPG binding +Marcel Raad (15 Sep 2017) +- [Isaac Boukris brought this change] -Steve Holme (12 Mar 2013) -- pop3: Fixed continuous wait when using --ftp-list + tests: enable gssapi in travis-ci linux build - Don't initiate a transfer when using --ftp-list. + Closes https://github.com/curl/curl/pull/1687 -Kamil Dudka (12 Mar 2013) -- [Zdenek Pavlas brought this change] +- [Isaac Boukris brought this change] - curl_global_init: accept the CURL_GLOBAL_ACK_EINTR flag + tests: add initial gssapi test using stub implementation - The flag can be used in pycurl-based applications where using the multi - interface would not be acceptable because of the performance lost caused - by implementing the select() loop in python. + The stub implementation is pre-loaded using LD_PRELOAD + and emulates common gssapi uses (only builds if curl is + initially built with gssapi support). - Bug: http://curl.haxx.se/bug/view.cgi?id=1168 - Downstream Bug: https://bugzilla.redhat.com/919127 + The initial tests are currently disabled for debug builds + as LD_PRELOAD is not used then. + + Ref: https://github.com/curl/curl/pull/1687 -- easy: do not ignore poll() failures other than EINTR +Daniel Stenberg (15 Sep 2017) +- test1150: verify same host fetch using different ports over proxy + + Closes #1889 -Yang Tse (12 Mar 2013) -- curl.h: stricter CURL_EXTERN linkage decorations logic +- URL: on connection re-use, still pick the new remote port - No API change involved. + ... as when a proxy connection is being re-used, it can still get a + different remote port. - Info: http://curl.haxx.se/mail/lib-2013-02/0234.html + Fixes #1887 + Reported-by: Oli Kingshott -Daniel Stenberg (11 Mar 2013) -- THANKS: Latin-1'ified Jiri's name +- RELEASE-NOTES: synced with 87501e57f -Steve Holme (11 Mar 2013) -- test806: Added CRLF to reply data to be compliant with RFC-822 - -Daniel Stenberg (11 Mar 2013) -- test805: added crlf newlines to make data size match +- code style: remove wrong uses of multiple spaces - since mails sent are supposed to have CRLF line endings I added them and - now the data size after (\Seen) matches again properly - -- test: fix newline for the data check of 807 + Closes #1878 -Yang Tse (11 Mar 2013) -- test801 to test807: fix protocol section line endings +- checksrc: detect and warn for multiple spaces -Steve Holme (10 Mar 2013) -- Makefile.am: Corrected a couple of spurious tab characters - - Corrected a couple of tab characters between test702 and test703, and - between test900 and test901 which should be spaces. +- code style: use space after semicolon -- [Jiri Hruska brought this change] +- checksrc: verify space after semicolons - imap: Added test807 for custom request functionality (STORE) +- code style: use spaces around pluses -- [Jiri Hruska brought this change] +- checksrc: detect and warn for lack of spaces next to plus signs - imap: Added test806 for IMAP (folder) LIST command +- code style: use spaces around equals signs -- [Jiri Hruska brought this change] +- checksrc: verify spaces around equals signs + + ... as the code style mandates. - imap: Added test805 for APPEND functionality +- Curl_checkheaders: make it available for IMAP and SMTP too + + ... not only HTTP uses this now. + + Closes #1875 -- [Jiri Hruska brought this change] +- travis: add build without HTTP/SMTP/IMAP - imap: Added test804 for skipping SELECT if in the same mailbox +Jay Satiro (10 Sep 2017) +- mbedtls: enable CA path processing + + CA path processing was implemented when mbedtls.c was added to libcurl + in fe7590f, but it was never enabled. + + Bug: https://github.com/curl/curl/issues/1877 + Reported-by: SBKarr@users.noreply.github.com -- [Jiri Hruska brought this change] +Daniel Stenberg (8 Sep 2017) +- rtsp: do not call fwrite() with NULL pointer FILE * + + If the default write callback is used and no destination has been set, a + NULL pointer would be passed to fwrite()'s 4th argument. + + OSS-fuzz bug https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3327 + (not publicly open yet) + + Detected by OSS-fuzz + Closes #1874 - imap: Added test802 and test803 for UIDVALIDITY verification +- configure: use -Wno-varargs on clang 3.9[.X] debug builds - Added one test for a request with matching UIDVALIDITY and one which is - a mismatched request that will fail. + ... to avoid a clang bug -- [Jiri Hruska brought this change] +- [Max Dymond brought this change] - imap: Added test801 for UID and SECTION URL parameters + ossfuzz: add some more handled CURL options + + Add support for HEADER, COOKIE, RANGE, CUSTOMREQUEST, MAIL_RECIPIENT, + MAIL_FROM and uploading data. -- [Jiri Hruska brought this change] +- configure: check for C++ compiler after C, to make it non-fatal + + The tests for object file/executable file extensions are presumably only + done for the first of these macros in the configure file. + + Bug: https://github.com/curl/curl/pull/1851#issuecomment-327597515 + Reported-by: Marcel Raad + Closes #1873 + +Patrick Monnerat (7 Sep 2017) +- form API: add new test 650. + + Now that the form API is deprecated and not used anymore in curl tool, + a lot of its features left untested. Test 650 attempts to check all these + features not tested elsewhere. - imap-tests: Accept quoted parameters in ftpserver.pl +Jay Satiro (7 Sep 2017) +- configure: fix curl_off_t check's include order + + - Prepend srcdir include path instead of append. + + Prior to this change it was possible that during the check for the size + of curl_off_t the include path of a user's already installed curl could + come before the include path of the to-be-built curl, resulting in the + system.h of the former being incorrectly included for that check. - Any IMAP parameter can come in escaped and in double quotes. Added a - simple function to unquote the command parameters and applied it to - the IMAP command handlers. + Closes https://github.com/curl/curl/pull/1870 -- [Jiri Hruska brought this change] +Daniel Stenberg (7 Sep 2017) +- [Jakub Zakrzewski brought this change] - tests: Fix ftpserver.pl indentation + KNOWN_BUGS: Remove CMake symbol hiding issue - The whole of FETCH_imap() had one extra space of indentation, whilst - APPEND_imap() used indentation of 2 instead of 4 in places. + It has already been fixed in 6140dfc -- Makefile.am: Corrected end of line filler character +- http-proxy: when not doing CONNECT, that phase is done immediately - The majority of lines, that specify a test file for inclusion, end with - a tab character before the slash whilst some end with a space. Corrected - those that end with a space to end with a tab character as well. + `conn->connect_state` is NULL when doing a regular non-CONNECT request + over the proxy and should therefor be considered complete at once. + + Fixes #1853 + Closes #1862 + Reported-by: Lawrence Wagerfield + +- [Johannes Schindelin brought this change] -- email-tests: Updated the test data that corresponds to the test number + OpenSSL: fix yet another mistake while encapsulating SSL backend data + + Another mistake in my manual fixups of the largely mechanical + search-and-replace ("connssl->" -> "BACKEND->"), just like the previous + commit concerning HTTPS proxies (and hence not caught during my + earlier testing). + + Fixes #1855 + Closes #1871 - Finished segregating the email protocol tests, into their own protocol - based ranges, in preparation of adding more e-mail related tests to the - test suite. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- email-tests: Renamed the IMAP test to be 800 +- [Johannes Schindelin brought this change] + + OpenSSL: fix erroneous SSL backend encapsulation + + In d65e6cc4f (vtls: prepare the SSL backends for encapsulated private + data, 2017-06-21), this developer prepared for a separation of the + private data of the SSL backends from the general connection data. + + This conversion was partially automated (search-and-replace) and + partially manual (e.g. proxy_ssl's backend data). + + Sadly, there was a crucial error in the manual part, where the wrong + handle was used: rather than connecting ssl[sockindex]' BIO to the + proxy_ssl[sockindex]', we reconnected proxy_ssl[sockindex]. The reason + was an incorrect location to paste "BACKEND->"... d'oh. - Continued segregating the email protocol tests, into their own protocol - based ranges, in preparation of adding more e-mail related tests to the - test suite. + Reported by Jay Satiro in https://github.com/curl/curl/issues/1855. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> + +- [Jay Satiro brought this change] -- email-tests: Renamed the SMTP tests to be in the range 900-906 + vtls: fix memory corruption + + Ever since 70f1db321 (vtls: encapsulate SSL backend-specific data, + 2017-07-28), the code handling HTTPS proxies was broken because the + pointer to the SSL backend data was not swapped between + conn->ssl[sockindex] and conn->proxy_ssl[sockindex] as intended, but + instead set to NULL (causing segmentation faults). + + [jes: provided the commit message, tested and verified the patch] - Continued segregating the email protocol tests, into their own protocol - based ranges, in preparation of adding more e-mail related tests to the - test suite. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- email-tests: Renamed the POP3 tests to be in the range 850-857 +- vtls: switch to CURL_SHA256_DIGEST_LENGTH define - Started segregating the email protocol tests, into their own protocol - based ranges, in preparation of adding more e-mail related tests to the - test suite. + ... instead of the prefix-less version since WolfSSL 3.12 now uses an + enum with that name that causes build failures for us. + + Fixes #1865 + Closes #1867 + Reported-by: Gisle Vanem -Daniel Stenberg (10 Mar 2013) -- hiperfifo: updated to use current libevent API +- travis: add c-ares enabled builds linux + osx - Patch by: Myk Taylor + Closes #1868 -Steve Holme (10 Mar 2013) -- imap: Reworked some function descriptions +- HISTORY: added some recent items -- imap: Added some missing comments to imap_sendf() +Jay Satiro (6 Sep 2017) +- SSL: fix unused parameter warnings -- email: Removed hard returns from init functions +Patrick Monnerat (6 Sep 2017) +- mime: drop internal FILE * support. + + - The part kind MIMEKIND_FILE and associated code are suppressed. + - Seek data origin offset not used anymore: suppressed. + - MIMEKIND_NAMEDFILE renamed MIMEKIND_FILE; associated fields/functions + renamed accordingly. + - Curl_getformdata() processes stdin via a callback. -Daniel Stenberg (9 Mar 2013) -- curl_multi_wait: avoid second loop if nothing to do +Daniel Stenberg (6 Sep 2017) +- configure: remove --enable-soname-bump and SONAME_BUMP + + Back in 2008, (and commit 3f3d6ebe665f3) we changed the logic in how we + determine the native type for `curl_off_t`. To really make sure we + didn't break ABI without bumping SONAME, we introduced logic that + attempted to detect that it would use a different size and thus not be + compatible. We also provided a manual switch that allowed users to tell + configure to bump SONAME by force. + + Today, we know of no one who ever got a SONAME bump auto-detected and we + don't know of anyone who's using the manual bump feature. The auto- + detection is also no longer working since we introduced defining + curl_off_t in system.h (7.55.0). + + Finally, this bumping logic is not present in the cmake build. - ... hopefully this will also make clang-analyzer stop warning on - potentional NULL dereferences (which were false positives anyway). + Closes #1861 -- multi_runsingle: avoid NULL dereference +Jay Satiro (6 Sep 2017) +- [Gisle Vanem brought this change] + + vtls: select ssl backend case-insensitive (follow-up) + + - Do a case-insensitive comparison of CURL_SSL_BACKEND env as well. + + - Change Curl_strcasecompare calls to strcasecompare + (maps to the former but shorter). - When Curl_do() returns failure, the connection pointer could be NULL so - the code path following needs to that that into account. + Follow-up to c290b8f. - Bug: http://curl.haxx.se/mail/lib-2013-03/0062.html - Reported by: Eric Hu + Bug: https://github.com/curl/curl/commit/c290b8f#commitcomment-24094313 + + Co-authored-by: Jay Satiro -Steve Holme (9 Mar 2013) -- imap: Re-factored all perform based functions +- openssl: Integrate Peter Wu's SSLKEYLOGFILE implementation + + This is an adaptation of 2 of Peter Wu's SSLKEYLOGFILE implementations. + + The first one, written for old OpenSSL versions: + https://git.lekensteyn.nl/peter/wireshark-notes/tree/src/sslkeylog.c + + The second one, written for BoringSSL and new OpenSSL versions: + https://github.com/curl/curl/pull/1346 + + Note the first one is GPL licensed but the author gave permission to + waive that license for libcurl. + + As of right now this feature is disabled by default, and does not have + a configure option to enable it. To enable this feature define + ENABLE_SSLKEYLOGFILE when building libcurl and set environment + variable SSLKEYLOGFILE to a pathname that will receive the keys. + + And in Wireshark change your preferences to point to that key file: + Edit > Preferences > Protocols > SSL > Master-Secret + + Co-authored-by: Peter Wu - Standardised the naming of all perform based functions to be in the form - imap_perform_something(). + Ref: https://github.com/curl/curl/pull/1030 + Ref: https://github.com/curl/curl/pull/1346 + + Closes https://github.com/curl/curl/pull/1866 -Daniel Stenberg (9 Mar 2013) -- [Cédric Deltheil brought this change] +Patrick Monnerat (5 Sep 2017) +- mime: fix a trivial warning. - examples/getinmemory.c: abort the transfer if not enough memory +- mime: replace 'struct Curl_mimepart' by 'curl_mimepart' in encoder code. - No more use exit(3) but instead tell libcurl that no byte has been - written to let it return a `CURLE_WRITE_ERROR`. In addition, check - curl easy handle return code. + mime_state is now a typedef. -- RELEASE-NOTES: synced with ca3c0ed3a9c +- mime: implement encoders. - 8 more bugfixes, one change and a bunch of contributors + curl_mime_encoder() is operational and documented. + curl tool -F option is extended with ";encoder=". + curl tool --libcurl option generates calls to curl_mime_encoder(). + New encoder tests 648 & 649. + Test 1404 extended with an encoder specification. + +- runtests.pl: support attribute "nonewline" in part verify/upload. -Yang Tse (9 Mar 2013) -- Makefile.am: empty AM_LDFLAGS definition for automake 1.7 compatibility +- [Daniel Stenberg brought this change] -Steve Holme (9 Mar 2013) -- imap: Added description comments to all perform based functions + fixup data/test1135 + +- [Daniel Stenberg brought this change] -- imap: Removed the need for separate custom request functions + mime: unified to use the typedef'd mime structs everywhere - Moved the custom request processing into the LIST command as the logic - is the same. + ... and slightly edited to follow our code style better. -- imap: Corrected typo in comment +- [Daniel Stenberg brought this change] -Yang Tse (9 Mar 2013) -- Makefile.am: empty AM_LDFLAGS definition for automake 1.7 compatibility + curl.h: use lower case curl_mime* as for all public symbols -Steve Holme (9 Mar 2013) -- imap: Moved imap_logout() to be grouped with the other perform functions +- [Daniel Stenberg brought this change] -- email: Updated the function descriptions for the logout / quit functions - - Updated the function description comments following commit 4838d196fdbf. + docs/curl_mime_*.3: use correct variable types in examples -- email: Simplified the logout / quit functions +Kamil Dudka (5 Sep 2017) +- openssl: use OpenSSL's default ciphers by default - Moved the blocking state machine to the disconnect functions so that the - logout / quit functions are only responsible for sending the actual - command needed to logout or quit. + Up2date versions of OpenSSL maintain the default reasonably secure + without breaking compatibility, so it is better not to override the + default by curl. Suggested at https://bugzilla.redhat.com/1483972 - Additionally removed the hard return on failure. + Closes #1846 -- email: Tidied up the *_regular_transfer() functions - - Added comments and simplified convoluted dophase_done comparison. +Viktor Szakats (5 Sep 2017) +- examples/mime: minor example code fixes -- email: Simplified nesting of if statements in *_doing() functions +Daniel Stenberg (5 Sep 2017) +- docs/curl_mime_*.3: added examples -Daniel Stenberg (8 Mar 2013) -- RELEASE-NOTES: mention that krb4 is up for consideration - -Steve Holme (8 Mar 2013) -- imap: Fixed handling of untagged responses for the STORE custom command +- configure: add MultiSSL to FEATURES when enabled - Added an exception, for the STORE command, to the untagged response - processor in imap_endofresp() as servers will back respones containing - the FETCH keyword instead. + ...for curl-config and its corresponding test 1014 -Yang Tse (8 Mar 2013) -- curlbuild.h.dist: enhance non-configure GCC ABI detection logic - - GCC specific adjustments: +- http-proxy: treat all 2xx as CONNECT success - - check __ILP32__ before 32 and 64bit processor architectures in - order to detect ILP32 programming model on 64 bit processors - which, of course, also support LP64 programming model, when using - gcc 4.7 or newer. + Added test 1904 to verify. - - keep 32bit processor architecture checks in order to support gcc - versions older than 4.7 which don't define __ILP32__ - - - check __LP64__ for gcc 3.3 and newer, while keeping 64bit processor - architecture checks for older versions which don't define __LP64__ + Reported-by: Lawrence Wagerfield + Fixes #1859 + Closes #1860 + +- MAIL-ETIQUETTE: added "1.9 Your emails are public" -- curlbuild.h.dist: fix GCC build on ARM systems without configure script +- curl.h: fix "unused checksrc ignore", remove dangling reference - Bug: http://curl.haxx.se/bug/view.cgi?id=1205 - Reported by: technion + ... to a README file that doesn't exist anymore -- [Gisle Vanem brought this change] +Viktor Szakats (4 Sep 2017) +- docs: Update to secure URL versions + +- mime: use CURL_ZERO_TERMINATED in examples + + and some minor whitespace fixes - polarssl.c: fix header filename typo +Daniel Stenberg (4 Sep 2017) +- schannel: return CURLE_SSL_CACERT on failed verification + + ... not *CACERT_BADFILE as it isn't really because of a bad file. + + Bug: https://curl.haxx.se/mail/lib-2017-09/0002.html + Closes #1858 -- configure: use XC_LIBTOOL for portability across libtool versions +- test1135: fixed after bd8070085f9 -- xc-lt-iface.m4: provide XC_LIBTOOL macro +- examples/post-callback: stop returning one byte at a time + + ... since people copy and paste code from this example and thus they get + an inefficient POST operation without a good reason and sometimes + without understanding why. + + Instead this now returns as much data as possible. -Steve Holme (7 Mar 2013) -- imap: Fixed SELECT not being performed for custom requests +- RELEASE-NOTES: fixed the function counter script -- email: Minor code tidy up following recent changes +- curl.h: make the curl_strequal() protos use the same style - Removed unwanted braces and added variable initialisation. + ... as the other functions. Makes it easier to machine-parse! -- DOCS: Corrected the IMAP URL grammar of the UIDVALIDITY parameter +- docs: curl_mime_*.3 man page formatting edits -- FEATURES: Provided a little clarity in some IMAP features +- RELEASE-NOTES: synced with 1ab9e9b50 -- email: Optimised block_statemach() functions - - Optimised the result test in each of the block_statemach() functions. +Patrick Monnerat (4 Sep 2017) +- lib: bump version info (soname). Adapt and reenable test 1135. -- DOCS: Added the list command to the IMAP URL section +Daniel Stenberg (3 Sep 2017) +- headers: move the global_sslset() proto from multi.h to curl.h - Added examples of the list command and clarified existing example URLs - following recent changes. + As it was added to multi.h simply to not break test 1135, which now has + been disabled due to the mime API addition anyway and su we can now move + the sslset stuff to where the other curl_global_* prototypes are. -- FEATURES: Updated for recent imap additions +Patrick Monnerat (3 Sep 2017) +- mime: fix signed/unsigned conversions. - Updated the imap features list, corrected a typo in the smtp features - and clarified a pop3 feature. + Use and generate CURL_ZERO_TERMINATED in curl tool and tests. -Daniel Stenberg (7 Mar 2013) -- version bump: the next release will be 7.30.0 +Jay Satiro (3 Sep 2017) +- tool_formparse: fix some trivial warnings -- checksrc: ban unsafe functions +Patrick Monnerat (3 Sep 2017) +- mime: use size_t instead of ssize_t in public API interface. + + To support telling a string is nul-terminated, symbol CURL_ZERO_TERMINATED + has been introduced. - The list of unsafe functions currently consists of sprintf, vsprintf, - strcat, strncat and gets. + Documentation updated accordingly. - Subsequently, some existing code needed updating to avoid warnings on - this. + symbols in versions updated. Added form API symbols deprecation info. -Steve Holme (7 Mar 2013) -- RELEASE-NOTES: Added missing imap fixes and additions +- mime: remove support "-" stdin pseudo-file name in curl_mime_filedata(). - With all the recent imap changes it wasn't clear what new features and - fixes should be included in the release notes. + This feature is badly supported in Windows: as a replacement, a caller has + to use curl_mime_data_cb() with fread, fseek and possibly fclose + callbacks to process opened files. + + The cli tool and documentation are updated accordingly. + + The feature is however kept internally for form API compatibility, with + the known caveats it always had. + + As a side effect, stdin size is not determined by the cli tool even if + possible and this results in a chunked transfer encoding. Test 173 is + updated accordingly. -Nick Zitzmann (6 Mar 2013) -- RELEASE-NOTES: brought this up-to-date with the latest changes +- mime: fix some implicit curl_off_t --> size_t conversion warnings. -Steve Holme (6 Mar 2013) -- [Jiri Hruska brought this change] +- mime: tests and examples. + + Additional mime-specific tests. + Existing tests updated to reflect small differences (Expect: 100-continue, + data size change due to empty lines, etc). + Option -F headers= keyword added to tests. + test1135 disabled until the entry point order change is resolved. + New example smtp-mime. + Examples postit2 and multi-post converted from form API to mime API. - imap: Fixed test801 and test1321 to specify a message UID +- mime: use in curl cli tool instead of form API. - Just a folder list would be retrieved if UID was not specified now. + Extended -F option syntax to support multipart mail messages. + -F keyword headers= added to include custom headers in parts. + Documentation upgraded. -- [Jiri Hruska brought this change] +- mime: new MIME API. + + Available in HTTP, SMTP and IMAP. + Deprecates the FORM API. + See CURLOPT_MIMEPOST. + Lib code and associated documentation. - imap: Fixed ftpserver.pl to allow verification even through LIST command +- test564: Add a warning comment about shell profile output. - Commit 198012ee inadvertently broke LIST_imap(). + Shell profile output makes the SSH server failing and this problem reason + is not easy to find when no hint is given. -- imap: Tidied up the APPEND and final APPEND response functions +- checksrc: disable SPACEBEFOREPAREN for case statement. - Removed unnecessary state changes on failure and setting of result codes - on success. + The case keyword may be followed by a constant expression and thus should + allow it to start with an open parenthesis. -- imap: Tidied up the final FETCH response function +- runtests.pl: allow <file[1-4]> tags in client section. - Removed unnecessary state change on failure and setting of result code on - success. + This enables tests to create more than one file on the client side. -- imap: Tidied up the LIST response function +- runtests.pl: Apply strippart to upload too. - Reworked comments as they referenced custom commands, removed - unnecessary state change on failure and setting of result code on - success. + This will allow substitution of boundaries in mail messages. -- imap: Removed the custom request response function +- Curl_base64_encode: always call with a real data handle. - Removed imap_state_custom_resp() as imap_state_list_resp() provides the - same functionality. + Some calls in different modules were setting the data handle to NULL, causing + segmentation faults when using builds that enable character code conversions. -- [Jiri Hruska brought this change] +- non-ascii: allow conversion functions to be called with a NULL data handle. - imap: Updated ftpserver.pl to be more compliant, added new commands - - Enriched IMAP capabilities of ftpserver.pl in order to be able to - add tests for the new IMAP features. +- http: fix a memory leakage in checkrtspprefix(). + +Daniel Stenberg (2 Sep 2017) +- [Max Dymond brought this change] + + ossfuzz: Move to C++ for curl_fuzzer. - * Added support for APPEND - Saves uploaded data to log/upload.$testno - * Added support for LIST - Returns the contents of <reply/> section in - the current test, like e.g FETCH. - * Added support for STORE - Returns hardcoded updated flags - * Changed handling of SELECT - Returns much more information in the - usual set of untagged responses; uses hardcoded data from an example - in the IMAP RFC - * Changed handling of FETCH - Fixed response format + Automake gets confused if you want to use C++ static libraries with C + code - basically we need to involve the clang++ linker. The easiest way + of achieving this is to rename the C code as C++ code. This gets us a + bit further along the path and ought to be compatible with Google's + version of clang. -- imap: Added check for empty UID in FETCH command +- curl_global_sslset: select backend by name case insensitively - As the UID has to be specified by the user for the FETCH command to work - correctly, added a check to imap_fetch(), although strictly speaking it - is protected by the call from imap_perform(). + Closes #1849 + +- [Max Dymond brought this change] -Kamil Dudka (6 Mar 2013) -- nss: fix misplaced code enabling non-blocking socket mode + ossfuzz: additional seed corpora - The option needs to be set on the SSL socket. Setting it on the model - takes no effect. Note that the non-blocking mode is still not enabled - for the handshake because the code is not yet ready for that. + Create simple seed corpora for: + - FTP + - telnet + - dict + - tftp + - imap + - pop3 + + based off the tests of the same number. + + Closes #1842 -Daniel Stenberg (6 Mar 2013) -- imap: fix compiler warning +- [Max Dymond brought this change] + + ossfuzz: moving towards the ideal integration - imap.c:694:21: error: unused variable 'imapc' [-Werror=unused-variable] + - Start with the basic code from the ossfuzz project. + - Rewrite fuzz corpora to be binary files full of Type-Length-Value + data, and write a glue layer in the fuzzing function to convert + corpora into CURL options. + - Have supporting functions to generate corpora from existing tests + - Integrate with Makefile.am -Steve Holme (5 Mar 2013) -- imap: Added support for list command +- strcase: corrected comment header for Curl_strcasecompare() -- imap: Added list perform and response handler functions +- unit1301: fix error message on first test -- imap: Introduced IMAP_LIST state +- curl_global_sslset.3: show the struct and enum too + + ... so that users can actually write code based on the man page alone, + not having to read the header file. -- imap: Small tidy up of imap_select() to match imap_append() +Jay Satiro (31 Aug 2017) +- darwinssl: handle long strings in TLS certs (follow-up) - Updated the style of imap_select() before adding the LIST command. + - Fix handling certificate subjects that are already UTF-8 encoded. + + Follow-up to b3b75d1 from two days ago. Since then a copy would be + skipped if the subject was already UTF-8, possibly resulting in a NULL + deref later on. + + Ref: https://github.com/curl/curl/issues/1823 + Ref: https://github.com/curl/curl/pull/1831 + + Closes https://github.com/curl/curl/pull/1836 -- imap: Moved mailbox check from the imap_do() function +Daniel Stenberg (31 Aug 2017) +- cyassl: call it the "WolfSSL" backend - In preparation for the addition of the LIST command, moved the mailbox - check from imap_do() to imap_select() and imap_append(). + ... instead of cyassl, as this is the current name for it. + + Closes #1844 -- curl_setup.h: Added S_IRDIR() macro for compilers that don't support it +- polarssl: fix multissl breakage - Commit 26eaa8383001 introduces the use of S_ISDIR() yet some compilers, - such as MSVC don't support it, so we must define a substitute using - file flags and mask. + Reported-by: Dan Fandrich + Bug: https://curl.haxx.se/mail/lib-2017-08/0121.html + Closes #1843 -Daniel Stenberg (4 Mar 2013) -- AddFormData: prevent only directories from being posted +- configure: remove the leading comma from the backends list + + ... when darwinssl is used. - Commit f4cc54cb4746ae5a6d (shipped as part of the 7.29.0 release) was a - bug fix that introduced a regression in that while trying to avoid - allowing directory names, it also forbade "special" files like character - devices and more. like "/dev/null" as was used by Oliver who reported - this regression. + Reported-by: Viktor Szakats + Bug: https://github.com/curl/curl/commit/b0989cd3abaff4f9a0717b4875022fa79e33b481#commitcomment-23943493 - Reported by: Oliver Gondža - Bug: http://curl.haxx.se/mail/archive-2013-02/0040.html + Closes #1845 -Nick Zitzmann (3 Mar 2013) -- darwinssl: fix infinite loop if server disconnected abruptly +Kamil Dudka (30 Aug 2017) +- examples/sslbackend.c: fix failure of 'make checksrc' - If the server hung up the connection without sending a closure alert, - then we'd keep probing the socket for data even though it's dead. Now - we're ready for this situation. + ./sslbackend.c:58:3: warning: else after closing brace on same line (BRACEELSE) + } else if(isdigit(*name)) { + ^ + ./sslbackend.c:62:3: warning: else after closing brace on same line (BRACEELSE) + } else + ^ + +Viktor Szakats (30 Aug 2017) +- makefile.m32: add multissl support - Bug: http://curl.haxx.se/mail/lib-2013-03/0014.html - Reported by: Aki Koskinen + Closes https://github.com/curl/curl/pull/1840 -Steve Holme (3 Mar 2013) -- imap: Added comments to imap_append() +Daniel Stenberg (30 Aug 2017) +- curl.h: CURLSSLBACKEND_WOLFSSL used wrong value + + The CURLSSLBACKEND_WOLFSSL is supposed to be an alias for + CURLSSLBACKEND_CYASSL, but used an erronous value. To reduce the risk + for a similar mistake, define the backend aliases to use the enum values + instead. + + Reported-by: Gisle Vanem + Bug: https://curl.haxx.se/mail/lib-2017-08/0120.html -- [Jiri Hruska brought this change] +- curl_global_sslset.3: clarify + + it is a one time *set*, not necessarily a one time use... it can be + called again if the first call failed or just listed the alternatives. + + clarify that the available backends are the ones this build supports + + plus add some formatting + + Reported-by: Rich Gray + Bug: https://curl.haxx.se/mail/lib-2017-08/0119.html - imap: Added required mailbox check for FETCH and APPEND commands +- curl/multi.h: remove duplicated closing c++ brace + + Regression since 1328f69d53f2f2e93 + + Fixes #1841 + Reported-by: Andrei Karas -- pingpong.c: Fix enumerated type mixed with another type +- RELEASE-NOTES: synced with 8c33c963a -- smtp: Updated the coding style for state changes after a send operation +- HELP-US.md: spelling + +- HELP-US.md: "How to get started helping out in the curl project" - Some state changes would be performed after a failure test that - performed a hard return, whilst others would be performed within a test - for success. Updated the code, for consistency, so all instances are - performed within a success test. + Closes #1837 -- pop3: Updated the coding style for state changes after a send operation +Dan Fandrich (29 Aug 2017) +- asyn-thread: Fixed cleanup after OOM - Some state changes would be performed after a failure test that - performed a hard return, whilst others would be performed within a test - for success. Updated the code, for consistency, so all instances are - performed within a success test. + destroy_async_data() assumes that if the flag "done" is not set yet, the + thread itself will clean up once the request is complete. But if an + error (generally OOM) occurs before the thread even has a chance to + start, it will never get a chance to clean up and memory will be leaked. + By clearing "done" only just before starting the thread, the correct + cleanup sequence will happen in all cases. + +Daniel Stenberg (28 Aug 2017) +- curl_global_init.3: mention curl_global_sslset(3) -- imap: Fixed typo in variable assignment +Dan Fandrich (28 Aug 2017) +- unit1606: Fixed shadowed variable warning -- [Jiri Hruska brought this change] +- asyn-thread: Improved cleanup after OOM situations - imap: Fixed custom request handling in imap_done() +- asyn-thread: Set errno to the proper value ENOMEM in OOM situation - Fixed imap_done() so that neither the FINAL states are not entered when - a custom command has been performed. + This used to be set in some configurations to EAI_MEMORY which is not a + valid value for errno and caused Curl_strerror to fail an assertion. -- [Jiri Hruska brought this change] +Daniel Stenberg (28 Aug 2017) +- [Johannes Schindelin brought this change] - imap: Enabled custom requests in imap_select_resp() + configure: Handle "MultiSSL" specially When versioning symbols - Changed imap_select_resp() to invoke imap_custom() instead of - imap_fetch() after the mailbox has been selected if a custom - command has been set. + There is a mode in which libcurl is compiled with versioned symbols, + depending on the active SSL backend. + + When multiple SSL backends are active, it does not make sense to favor + one over the others, so let's not: introduce a new prefix for the case + where multiple SSL backends are compiled into cURL. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Enabled custom requests in imap_perform() + configure: allow setting the default SSL backend + + Previously, we used as default SSL backend whatever was first in the + `available_backends` array. + + However, some users may want to override that default without patching + the source code. + + Now they can: with the --with-default-ssl-backend=<backend> option of + the ./configure script. - Modified imap_perform() to start with the custom command instead of - SELECT when a custom command is to be performed and no mailbox has - been given. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added custom request perform and response handler functions + vtls: use Curl_ssl_multi pseudo backend only when needed - Added imap_custom(), which initiates the custom command processing, - and an associated response handler imap_state_custom_resp(), which - handles any responses by sending them to the client as body data. + When only one SSL backend is configured, it is totally unnecessary to + let multissl_init() configure the backend at runtime, we can select the + correct backend at build time already. - All untagged responses with the same name as the first word of the - custom request string are accepted, with the exception of SELECT and - EXAMINE which have responses that cannot be easily identified. An - extra check has been provided for them so that any untagged responses - are accepted for them. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- pop3: Fixed unnecessary parent structure reference +- [Johannes Schindelin brought this change] + + version: if built with more than one SSL backend, report all of them + + To discern the active one from the inactive ones, put the latter into + parentheses. - Updated pop3 code following recent imap changes. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added custom request parsing + version: add the CURL_VERSION_MULTI_SSL feature flag - Added imap_parse_custom_request() for parsing the CURLOPT_CUSTOMREQUEST - parameter which URL decodes the value and separates the request from - any parameters - This makes it easier to filter untagged responses - by the request command. + This new feature flag reports When cURL was built with multiple SSL + backends. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Introduced custom request parameters + metalink: allow compiling with multiple SSL backends - Added custom request parameters to the per-request structure. - -- [Jiri Hruska brought this change] + Previously, the code assumed that at most one of the SSL backends would + be compiled in, emulating OpenSSL's functions if the configured backend + was not OpenSSL itself. + + However, now we allow building with multiple SSL backends and choosing + one at runtime. Therefore, metalink needs to be adjusted to handle this + scenario, too. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> - imap: Introduced IMAP_CUSTOM state +- [Johannes Schindelin brought this change] -- imap: Minor code tidy up + docs/examples: demonstrate how to select SSL backends - Minor tidy up of code layout and comments following recent changes. - -- imap: Simplified the imap_state_append_resp() function + The newly-introduced curl_global_sslset() function deserves to be + show-cased. - Introduced the result code variable to simplify the state changes and - remove the hard returns. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: Changed successful response logic in imap_state_append_resp() - - For consistency changed the logic of the imap_state_append_resp() - function to test for an unsucessful continuation response rather than a - succesful one. +- [Johannes Schindelin brought this change] -- imap: Standardised imapcode condition tests + Add a man page for curl_global_sslset() - For consistency changed two if(constant != imapcode) tests to be - if(imapcode != constant). - -- imap: Moved imap_append() to be with the other perform functions + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Enabled APPEND support in imap_perform() + vtls: introduce curl_global_sslset() + + Let's add a compile time safe API to select an SSL backend. This + function needs to be called *before* curl_global_init(), and can be + called only once. + + Side note: we do not explicitly test that it is called before + curl_global_init(), but we do verify that it is not called multiple times + (even implicitly). + + If SSL is used before the function was called, it will use whatever the + CURL_SSL_BACKEND environment variable says (or default to the first + available SSL backend), and if a subsequent call to + curl_global_sslset() disagrees with the previous choice, it will fail + with CURLSSLSET_TOO_LATE. + + The function also accepts an "avail" parameter to point to a (read-only) + NULL-terminated list of available backends. This comes in real handy if + an application wants to let the user choose between whatever SSL backends + the currently available libcurl has to offer: simply call - Added logic in imap_perform() to perform an APPEND rather than SELECT - and FETCH if an upload has been specified. + curl_global_sslset(-1, NULL, &avail); + + which will return CURLSSLSET_UNKNOWN_BACKEND and populate the avail + variable to point to the relevant information to present to the user. + + Just like with the HTTP/2 push functions, we have to add the function + declaration of curl_global_sslset() function to the header file + *multi.h* because VMS and OS/400 require a stable order of functions + declared in include/curl/*.h (where the header files are sorted + alphabetically). This looks a bit funny, but it cannot be helped. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Implemented APPEND final processing + vtls: refactor out essential information about the SSL backends + + There is information about the compiled-in SSL backends that is really + no concern of any code other than the SSL backend itself, such as which + function (if any) implements SHA-256 summing. + + And there is information that is really interesting to the user, such as + the name, or the curl_sslbackend value. - The APPEND operation needs to be performed in several steps: - 1) We send "<tag> APPEND <mailbox> <flags> {<size>}\r\n" - 2) Server responds with continuation respose "+ ...\r\n" - 3) We start the transfer and send <size> bytes of data - 4) Only now we end the request command line by sending "\r\n" - 5) Server responds with "<tag> OK ...\r\n" + Let's factor out the latter into a publicly visible struct. This + information will be used in the upcoming API to set the SSL backend + globally. - This commit performs steps 4 and 5, in the DONE phase, as more - processing is required after the transfer. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added APPEND perform and response handler functions + vtls: allow selecting which SSL backend to use at runtime + + When building software for the masses, it is sometimes not possible to + decide for all users which SSL backend is appropriate. + + Git for Windows, for example, uses cURL to perform clones, fetches and + pushes via HTTPS, and some users strongly prefer OpenSSL, while other + users really need to use Secure Channel because it offers + enterprise-ready tools to manage credentials via Windows' Credential + Store. + + The current Git for Windows versions use the ugly work-around of + building libcurl once with OpenSSL support and once with Secure Channel + support, and switching out the binaries in the installer depending on + the user's choice. + + Needless to say, this is a super ugly workaround that actually only + works in some cases: Git for Windows also comes in a portable form, and + in a form intended for third-party applications requiring Git + functionality, in which cases this "swap out libcurl-4.dll" simply is + not an option. - Added imap_append() function to initiate upload and imap_append_resp() - to handle the continuation response and start the transfer. + Therefore, the Git for Windows project has a vested interest in teaching + cURL to make the SSL backend a *runtime* option. + + This patch makes that possible. + + By running ./configure with multiple --with-<backend> options, cURL will + be built with multiple backends. + + For the moment, the backend can be configured using the environment + variable CURL_SSL_BACKEND (valid values are e.g. "openssl" and + "schannel"). + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Introduced IMAP_APPEND and IMAP_APPEND_FINAL states + vtls: fold the backend ID into the Curl_ssl structure + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Updated setting of transfer variables in imap_state_fetch_resp() + curl_ntlm_core: don't complain but #include OpenSSL header if needed - Add number of bytes retrieved from the PP cache to req.bytecount and set - req.maxdownload only when starting a proper download. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Improved FETCH response parsing + vtls: encapsulate SSL backend-specific data - Added safer parsing of the untagged FETCH response line and the size of - continuation data. - -- imap: Fixed accidentally lossing the result code + So far, all of the SSL backends' private data has been declared as + part of the ssl_connect_data struct, in one big #if .. #elif .. #endif + block. + + This can only work as long as the SSL backend is a compile-time option, + something we want to change in the next commits. + + Therefore, let's encapsulate the exact data needed by each SSL backend + into a private struct, and let's avoid bleeding any SSL backend-specific + information into urldata.h. This is also necessary to allow multiple SSL + backends to be compiled in at the same time, as e.g. OpenSSL's and + CyaSSL's headers cannot be included in the same .c file. - Accidentally lost the result code in imap_state_capability() and - imap_state_login() with commit b06a78622609. + To avoid too many malloc() calls, we simply append the private structs + to the connectdata struct in allocate_conn(). + + This requires us to take extra care of alignment issues: struct fields + often need to be aligned on certain boundaries e.g. 32-bit values need to + be stored at addresses that divide evenly by 4 (= 32 bit / 8 + bit-per-byte). + + We do that by assuming that no SSL backend's private data contains any + fields that need to be aligned on boundaries larger than `long long` + (typically 64-bit) would need. Under this assumption, we simply add a + dummy field of type `long long` to the `struct connectdata` struct. This + field will never be accessed but acts as a placeholder for the four + instances of ssl_backend_data instead. the size of each ssl_backend_data + struct is stored in the SSL backend-specific metadata, to allow + allocate_conn() to know how much extra space to allocate, and how to + initialize the ssl[sockindex]->backend and proxy_ssl[sockindex]->backend + pointers. + + This would appear to be a little complicated at first, but is really + necessary to encapsulate the private data of each SSL backend correctly. + And we need to encapsulate thusly if we ever want to allow selecting + CyaSSL and OpenSSL at runtime, as their headers cannot be included within + the same .c file (there are just too many conflicting definitions and + declarations for that). + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: Another minor comment addition / tidy up +- [Johannes Schindelin brought this change] -- imap: Updated the coding style for state changes after a send operation + vtls: prepare the SSL backends for encapsulated private data - Some state changes would be performed after a failure test that - performed a hard return, whilst others would be performed within a test - for success. Updated the code, for consistency, so all instances are - performed within a success test. - -- pop3 / smtp: Small comment tidy up + At the moment, cURL's SSL backend needs to be configured at build time. + As such, it is totally okay for them to hard-code their backend-specific + data in the ssl_connect_data struct. - Small tidy up to keep some comments consistant across each of the email - protocols. + In preparation for making the SSL backend a runtime option, let's make + the access of said private data a bit more abstract so that it can be + adjusted later in an easy manner. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: FETCH response handler cleanup before further changes + urldata.h: move SSPI-specific #include to correct location - Removed superfluous NULL assignment after Curl_safefree() and rewrote - some comments and logging messages. - -- pop3: Small tidy up of function arguments + In 86b889485 (sasl_gssapi: Added GSS-API based Kerberos V5 variables, + 2014-12-03), an SSPI-specific field was added to the kerberos5data + struct without moving the #include "curl_sspi.h" later in the same file. + + This broke the build when SSPI was enabled, unless Secure Channel was + used as SSL backend, because it just so happens that Secure Channel also + requires "curl_sspi.h" to be #included. + + In f4739f639 (urldata: include curl_sspi.h when Windows SSPI is enabled, + 2017-02-21), this bug was fixed incorrectly: Instead of moving the + appropriate conditional #include, the Secure Channel-conditional part + was now also SSPI-conditional. + + Fix this problem by moving the correct #include instead. + + This is also required for an upcoming patch that moves all the Secure + Channel-specific stuff out of urldata.h and encapsulates it properly in + vtls/schannel.c instead. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: Small tidy up of function arguments +- [Johannes Schindelin brought this change] -- smtp: Corrected debug message for POP3_AUTH_FINAL constant + urldata.h: remove support for obsolete PolarSSL version - Following commit ad3177da24b8 corrected the debug message in state() - from AUTH to AUTH_FINAL. - -- pop3: Corrected debug message for POP3_AUTH_FINAL constant + Since 5017d5ada (polarssl: now require 1.3.0+, 2014-03-17), we require + a newer PolarSSL version. No need to keep code trying to support any + older version. - Following commit afad1ce753a1 corrected the debug message in state() - from AUTH to AUTH_FINAL. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> + +- [Johannes Schindelin brought this change] -- imap: Corrected debug message for IMAP_AUTHENTICATE_FINAL constant + getinfo: access SSL internals via Curl_ssl - Following commit 13006f3de9ec corrected the debug message in state() - from AUTHENTICATE to AUTHENTICATE_FINAL. + In the ongoing endeavor to abstract out all SSL backend-specific + functionality, this is the next step: Instead of hard-coding how the + different SSL backends access their internal data in getinfo.c, let's + implement backend-specific functions to do that task. + + This will also allow for switching SSL backends as a runtime option. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Fixed error code returned for invalid FETCH response + vtls: move SSL backends' private constants out of their header files - If the FETCH command does not result in an untagged response the the - UID is probably invalid. As such do not return CURLE_OK. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added processing of the final FETCH responses + axtls: use Curl_none_* versions of init() and cleanup() - Not processing the final FETCH responses was not optimal, not only - because the response code would be ignored but it would also leave data - unread on the socket which would prohibit connection reuse. + There are convenient no-op versions of the init/cleanup functions now, + no need to define private ones for axTLS. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Introduced FETCH_FINAL state for processing final fetch responses + vtls: remove obsolete declarations of SSL backend functionality - A typical FETCH response can be broken down into four parts: + These functions are all available via the Curl_ssl struct now, no need + to declare them separately anymore. - 1) "* <uid> FETCH (<what> {<size>}\r\n", using continuation syntax - 2) <size> bytes of the actual message - 3) ")\r\n", finishing the untagged response - 4) "<tag> OK ...", finishing the command + As the global declarations are removed, the corresponding function + definitions are marked as file-local. The only two exceptions here are + Curl_mbedtls_shutdown() and Curl_polarssl_shutdown(): only the + declarations were removed, there are no function definitions to mark + file-local. - Part 1 is read in imap_fetch_resp(), part 2 is consumed in the PERFORM - phase by the transfer subsystem, parts 3 and 4 are currently ignored. - -- imap: fix autobuild warning + Please note that Curl_nss_force_init() is *still* declared globally, as + the only SSL backend-specific function, because it was introduced + specifically for the use case where cURL was compiled with + `--without-ssl --with-nss`. For details, see f3b77e561 (http_ntlm: add + support for NSS, 2010-06-27). - Removed whitespace from imap_perform() + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: fix compiler warning - - error: declaration of 'imap' shadows a previous local +- [Johannes Schindelin brought this change] -- smtp: Re-factored the final SMTP_AUTH constant + schannel: reorder functions topologically - Changed the final SMTP_AUTH constant to SMTP_AUTH_FINAL for consistency - with the response function. - -- pop3: Re-factored the final POP3_AUTH constant + The _shutdown() function calls the _session_free() function; While this + is not a problem now (because schannel.h declares both functions), a + patch looming in the immediate future with make all of these functions + file-local. - Changed the final POP3_AUTH constant to POP3_AUTH_FINAL for consistency - with the response function. - -- imap: Re-factored final IMAP_AUTHENTICATE constant + So let's just move the _session_free() function's definition before it + is called. - Changed the final IMAP_AUTHENTICATE constant to IMAP_AUTHENTICATE_FINAL - for consistency with the response function. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: Updated the coding style of imap_state_servergreet_resp() - - Updated the coding style, in this function, to be consistant with other - response functions rather then performing a hard return on failure. +- [Johannes Schindelin brought this change] -- imap: Reversed the logic of the (un)successful tagged SELECT response + axtls: reorder functions topologically - Reversed the logic of the unsuccessful vs successful tagged SELECT - response in imap_state_select_resp() to be more logical to read. - -- imap: Reversed the logic of the (un)successful tagged CAPABILITY response + The connect_finish() function (like many other functions after it) calls + the Curl_axtls_close() function; While this is not a problem now + (because axtls.h declares the latter function), a patch looming in the + immediate future with make all of these functions file-local. - Reversed the logic of the unsuccessful vs successful tagged CAPABILITY - response in imap_state_capability_resp() to be more logical to read. - -- imap: Corrected char* references with char * + So let's just move the Curl_axtls_close() function's definition before + it is called. - Corrected char* references made in commit: 709b3506cd9b. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added processing of more than one response when sent in same packet + vtls: move the SUPPORT_HTTPS_PROXY flag into the Curl_ssl struct + + That will allow us to choose the SSL backend at runtime. - Added a loop to imap_statemach_act() in which Curl_pp_readresp() is - called until the cache is drained. Without this multiple responses - received in a single packet could result in a hang or delay. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added skipping of SELECT command if already in the same mailbox + vtls: convert the have_curlssl_* constants to runtime flags + + The entire idea of introducing the Curl_ssl struct to describe SSL + backends is to prepare for choosing the SSL backend at runtime. + + To that end, convert all the #ifdef have_curlssl_* style conditionals + to use bit flags instead. - Added storage and checking of the last mailbox userd to prevent - unnecessary switching. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Introduced the mailbox variable + vtls: move sha256sum into the Curl_ssl struct - Added the mailbox variable to the per-connection structure in - preparation for checking for an already selected mailbox. - -- email: Slight reordering of connection based variables + The SHA-256 checksumming is also an SSL backend-specific function. + Let's include it in the struct declaring the functionality of SSL + backends. + + In contrast to MD5, there is no fall-back code. To indicate this, the + respective entries are NULL for those backends that offer no support for + SHA-256 checksumming. - Reordered the state and ssl_done variables in order to provide more - consistency between the email protocols as well as for for an upcoming - change. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: Tidied up comments for connection based variables +- [Johannes Schindelin brought this change] -- DOCS: Added the IMAP UIDVALIDITY property to the CURLOPT_URL section + vtls: move md5sum into the Curl_ssl struct + + The MD5 summing is also an SSL backend-specific function. So let's + include it, offering the previous fall-back code as a separate function + now: Curl_none_md5sum(). To allow for that, the signature had to be + changed so that an error could be returned from the implementation + (Curl_none_md5sum() can run out of memory). + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added verification of UIDVALIDITY mailbox attribute + vtls: use the Curl_ssl struct to access all SSL backends' functionality - Added support for checking the UIDVALIDITY, and aborting the request, if - it has been specified in the URL and the server response is different. + This is the first step to unify the SSL backend handling. Now all the + SSL backend-specific functionality is accessed via a global instance of + the Curl_ssl struct. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added support for parsing the UIDVALIDITY property + vtls: declare Curl_ssl structs for every SSL backend + + The idea of introducing the Curl_ssl struct was to unify how the SSL + backends are declared and called. To this end, we now provide an + instance of the Curl_ssl struct for each and every SSL backend. - Added support for parsing the UIDVALIDITY property from the SELECT - response and storing it in the per-connection structure. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Introduced the mailbox_uidvalidity variable + vtls: introduce a new struct for SSL backends - Added the mailbox_uidvalidity variable to the per-connection structure - in preparation for checking the UIDVALIDITY mailbox attribute. + This new struct is similar in nature to Curl_handler: it will define the + functions and capabilities of all the SSL backends (where Curl_handler + defines the functions and capabilities of protocol handlers). + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- imap: Corrected comment in imap_endofresp() +- [Johannes Schindelin brought this change] -- imap: Corrected whitespace + vtls: make sure every _sha256sum()'s first arg is const + + This patch makes the signature of the _sha256sum() functions consistent + among the SSL backends, in preparation for unifying the way all SSL + backends are accessed. + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added filtering of CAPABILITY and FETCH untagged responses + vtls: make sure all _data_pending() functions return bool + + This patch makes the signature of the _data_pending() functions + consistent among the SSL backends, in preparation for unifying the way + all SSL backends are accessed. - Only responses that contain "CAPABILITY" and "FETCH", respectively, - will be sent to their response handler. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added a helper function for upcoming untagged response filtering + vtls: make sure all _cleanup() functions return void - RFC 3501 states that "the client MUST be prepared to accept any response - at all times" yet we assume anything received with "* " at the beginning - is the untagged response we want. + This patch makes the signature of the _cleanup() functions consistent + among the SSL backends, in preparation for unifying the way all SSL + backends are accessed. - Introduced a helper function that checks whether the input looks like a - response to specified command, so that we may filter the ones we are - interested in according to the current state. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Moved CAPABILITY response handling to imap_state_capability_resp() + vtls: use consistent signature for _random() implementations + + This will make the upcoming multissl backend much easier to implement. - Introduced similar handling to the FETCH responses, where even the - untagged data responses are handled by the response handler of the - individual state. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -Linus Nielsen Feltzing (26 Feb 2013) -- Remove unused variable in smtp_state_data_resp() +- strtooff: fix build for systems with long long but no strtoll option + + Closes #1829 + + Reported-by: Dan Fandrich + Bug: https://github.com/curl/curl/pull/1758#issuecomment-324861615 -Steve Holme (25 Feb 2013) -- email: Small tidy up following recent changes +- darwinssl: handle long strings in TLS certs + + ... as the previous fixed length 128 bytes buffer was sometimes too + small. + + Fixes #1823 + Closes #1831 + + Reported-by: Benjamin Sergeant + Assisted-by: Bill Pyne, Ray Satiro, Nick Zitzmann -- smtp: Removed bytecountp from the per-request structure +- system.h: include sys/poll.h for AIX + + ... to get the event/revent defines that might be used for the poll + struct. - Removed this pointer to a downloaded bytes counter because it was set in - smtp_init() to point to the same variable the transfer functions keep - the count in (k->bytecount), effectively making the code in transfer.c - "*k->bytecountp = k->bytecount" a no-op. + Reported-by: Michael Smith + Fixes #1828 + Closes #1833 -- pop3: Removed bytecountp from the per-request structure +Dan Fandrich (26 Aug 2017) +- tests: Make sure libtests & unittests call curl_global_cleanup() - Removed this pointer to a downloaded bytes counter because it was set in - pop3_init() to point to the same variable the transfer functions keep - the count in (k->bytecount), effectively making the code in transfer.c - "*k->bytecountp = k->bytecount" a no-op. + These were missed in commit c468c27b. -- [Jiri Hruska brought this change] +Jay Satiro (26 Aug 2017) +- [theantigod brought this change] - imap: Removed bytecountp from the per-request structure + winbuild: fix embedded manifest option - Removed this pointer to a downloaded bytes counter because it was set in - imap_init() to point to the same variable the transfer functions keep - the count in (k->bytecount), effectively making the code in transfer.c - "*k->bytecountp = k->bytecount" a no-op. + Embedded manifest option didn't work due to incorrect path. + + Fixes https://github.com/curl/curl/issues/1832 + +Daniel Stenberg (25 Aug 2017) +- fuzz/Makefile.am: remove curlbuild.h leftovers -- [Jiri Hruska brought this change] +- examples/threaded-ssl: mention that this is for openssl before 1.1 - imap: Adjusted SELECT and FETCH function order +- imap: use defined names for response codes + + When working on this code I found the previous setup a bit weird while + using proper defines increases readability. - Moved imap_select() and imap_fetch() to be grouped with the other - perform functions. + Closes #1824 -- [Jiri Hruska brought this change] +- CURLOPT_USERPWD.3: see also CURLOPT_PROXYUSERPWD - imap: Adjusted SELECT and FETCH state order in imap_statemach_act() +- imap: support PREAUTH - Exchanged the position of these states in the switch statements to - match the state enum, execution and function order. - -- imap: Minor tidy up of comments in imap_parse_url_path() + It is a defined possible greeting at server startup that means the + connection is already authenticated. See + https://tools.ietf.org/html/rfc3501#section-7.1.4 + + Test 846 added to verify. - Tidy up of comments before next round of imap changes. + Fixes #1818 + Closes #1820 -- imap: Fixed incorrect comparison for STARTTLS in imap_endofresp() +Jay Satiro (23 Aug 2017) +- config-tpf: define SIZEOF_LONG - Corrected the comparison type in addition to commit 1dac29fa83a9. + Recent changes that replaced CURL_SIZEOF_LONG in the source with + SIZEOF_LONG broke builds that use the premade configuration files and + don't have SIZEOF_LONG defined. + + Bug: https://github.com/curl/curl/issues/1816 + +Dan Fandrich (23 Aug 2017) +- test1453: Fixed <features> + +Daniel Stenberg (22 Aug 2017) +- [Gisle Vanem brought this change] -- DOCS: Corrected IMAP URL examples according to RFC5092 + config-dos: add missing defines, SIZEOF_* and two others - URL examples that included the UID weren't technically correct although - would pass the curl parser. + Bug: #1816 -Nick Zitzmann (24 Feb 2013) -- darwinssl: fix undefined $ssllib warning in runtests.pl +- curl: shorten and clean up CA cert verification error message - I also added --with-darwinssl to the list of SSL options in configure. + The previous message was just too long for ordinary people and it was + encouraging users to use `--insecure` a little too easy. + + Based-on-work-by: Frank Denis + + Closes #1810 + Closes #1817 + +- request-target.d: mention added in 7.55.0 -Steve Holme (24 Feb 2013) -- imap: Added check for new internal imap response code +Marcel Raad (22 Aug 2017) +- tool_main: turn off MinGW CRT's globbing + + By default, the MinGW CRT globs command-line arguments. This prevents + getting a single asterisk into an argument as test 1299 does. Turn off + globbing by setting the global variable _CRT_glob to 0 for MinGW. + + Fixes https://github.com/curl/curl/issues/1751 + Closes https://github.com/curl/curl/pull/1813 -- imap: Changed the order of the response types in imap_endofresp() +Viktor Szakats (22 Aug 2017) +- makefile.m32: add support for libidn2 - From a maintenance point of view the code reads better to view tagged - responses, then untagged followed by continuation responses. + libidn was replaced with libidn2 last year in configure. + Caveat: libidn2 may depend on a list of further libs. + These can be manually specified via CURL_LDFLAG_EXTRAS. - Additionally, this matches the order of responses in POP3. + Closes https://github.com/curl/curl/pull/1815 -- [Jiri Hruska brought this change] +Jay Satiro (22 Aug 2017) +- [Viktor Szakats brought this change] - imap: Added stricter parsing of continuation responses + config-win32: define SIZEOF_LONG - Enhanced the parsing to only allow continuation responses in some - states. + Recent changes that replaced CURL_SIZEOF_LONG in the source with + SIZEOF_LONG broke builds that use the premade configuration files and + don't have SIZEOF_LONG defined. + + Closes https://github.com/curl/curl/pull/1814 -- imap: Simplified memcmp() in tagged response parsing +Daniel Stenberg (20 Aug 2017) +- cmake: enable picky compiler options with clang and gcc + + closes #1799 -- [Jiri Hruska brought this change] +- curl/system.h: fix build for hppa + + Reported-by: John David Anglin + Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872502#10 - imap: Reworked the logic of untagged command responses +- [Even Rouault brought this change] -- imap: Corrected spacing of trailing brace + tftp: fix memory leak on too long filename + + Fixes + + $ valgrind --leak-check=full ~/install-curl-git/bin/curl tftp://localhost/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz + + ==9752== Memcheck, a memory error detector + ==9752== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. + ==9752== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info + ==9752== Command: /home/even/install-curl-git/bin/curl tftp://localhost/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz + ==9752== + curl: (71) TFTP file name too long + + ==9752== + ==9752== HEAP SUMMARY: + ==9752== 505 bytes in 1 blocks are definitely lost in loss record 11 of 11 + ==9752== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) + ==9752== by 0x4E61CED: Curl_urldecode (in /home/even/install-curl-git/lib/libcurl.so.4.4.0) + ==9752== by 0x4E75868: tftp_state_machine (in /home/even/install-curl-git/lib/libcurl.so.4.4.0) + ==9752== by 0x4E761B6: tftp_do (in /home/even/install-curl-git/lib/libcurl.so.4.4.0) + ==9752== by 0x4E711B6: multi_runsingle (in /home/even/install-curl-git/lib/libcurl.so.4.4.0) + ==9752== by 0x4E71D00: curl_multi_perform (in /home/even/install-curl-git/lib/libcurl.so.4.4.0) + ==9752== by 0x4E6950D: curl_easy_perform (in /home/even/install-curl-git/lib/libcurl.so.4.4.0) + ==9752== by 0x40E0B7: operate_do (in /home/even/install-curl-git/bin/curl) + ==9752== by 0x40E849: operate (in /home/even/install-curl-git/bin/curl) + ==9752== by 0x402693: main (in /home/even/install-curl-git/bin/curl) + + Fixes https://oss-fuzz.com/v2/testcase-detail/5232311106797568 + Credit to OSS Fuzz + + Closes #1808 -- [Jiri Hruska brought this change] +Dan Fandrich (19 Aug 2017) +- runtests: fixed case insensitive matching of keywords + + Commit 5c2aac71 didn't work in the case of mixed-case keywords given on + the command-line. - imap: Added stricter parsing of tagged command responses +- tests: Make sure libtests call curl_global_cleanup() - Enhanced the parsing of tagged responses which must start with "OK", - "NO" or "BAD" + This ensures that global data allocations are freed so Valgrind stays + happy. This was a problem with at least PolarSSL and mbedTLS. -- [Jiri Hruska brought this change] +Daniel Stenberg (18 Aug 2017) +- RELEASE-NOTES: synced with 8baead425 - imap: Simplified command response test in imap_endofresp() +- scripts/contri*sh: use "git log --use-mailmap" -- [Jiri Hruska brought this change] +- mailmap: de-duplify some git authors - imap: Corrected comment in imap_endofresp() +- http2_recv: return error better on fatal h2 errors + + Ref #1012 + Figured-out-by: Tatsuhiro Tsujikawa -- DOCS: Corrected layout of POP3 and IMAP URL examples +- KNOWN_BUGS: HTTP test server 'connection-monitor' problems - Corrected layout issues with the POP3 and IMAP URL examples introduced - in commit cb3ae6894fb2. + Closes #868 -- DOCS: Updated CURLOPT_URL section following recent POP3 and IMAP changes +- curl/system.h: check for __ppc__ as well - Updated the POP3 sub-section to refer to message ID rather than mailbox. + ... regression since issue #1774 (commit 10b3df10596a) since obviously + some older gcc doesn't know __powerpc__ while some newer doesn't know + __ppc__ ... - Added an IMAP sub-section with example URLs depicting the specification - of mailbox, uid and section. + Fixes #1797 + Closes #1798 + Reported-by: Ryan Schmidt -- pop3: Refactored the mailbox variable as it didn't reflect it's purpose - - Updated the mailbox variable to correctly reflect it's purpose. The - name mailbox was a leftover from when IMAP and POP3 support was - initially added to curl. +- [Jan Alexander Steffens (heftig) brought this change] -- FEATURES: Updated following recent IMAP changes + http: Don't wait on CONNECT when there is no proxy + + Since curl 7.55.0, NetworkManager almost always failed its connectivity + check by timeout. I bisected this to 5113ad04 (http-proxy: do the HTTP + CONNECT process entirely non-blocking). + + This patch replaces !Curl_connect_complete with Curl_connect_ongoing, + which returns false if the CONNECT state was left uninitialized and lets + the connection continue. + + Closes #1803 + Fixes #1804 + + Also-fixed-by: Gergely Nagy -- [Jiri Hruska brought this change] +- [Johannes Schindelin brought this change] - imap: Added the ability to FETCH a specific UID and SECTION - - Updated the FETCH command to send the UID and SECTION parsed from the - URL. By default the BODY specifier doesn't include a section, BODY[] is - now sent whereas BODY[TEXT] was previously sent. In my opinion - retrieving just the message text is rarely useful when dealing with - emails, as the headers are required for example, so that functionality - is not retained. In can however be simulated by adding SECTION=TEXT to - the URL. + metalink: adjust source code style - Also updated test801 and test1321 due to the BODY change. + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -- email: Additional tidy up of comments following recent changes +- CURL_SIZEOF_LONG: removed, use only SIZEOF_LONG -- smtp: Removed some FTP heritage leftovers +- lib557: no longer use CURL_SIZEOF_* defines + +- config-win32: define SIZEOF_CURL_OFF_T + +- cmake: sizeof curl_off_t, remove unused detections + +- system.h: remove all CURL_SIZEOF_* defines - Removed user and passwd from the SMTP struct as these cannot be set on - a per-request basis and are leftover from legacy FTP code. + ... as they're not used externally and internally we check for the sizes + already in configure etc. - Changed some comments still using FTP terminology. + Closes #1767 -- smtp: Moved the per-request variables to the per-request data structure +- ftp: fix CWD when doing multicwd then nocwd on same connection - Moved the rcpt variable from the per-connection struct smtp_conn to the - new per-request struct and fixed references accordingly. + Fixes #1782 + Closes #1787 + Reported-by: Peter Lamare -- pop3: Introduced a custom SMTP structure for per-request data +- CURLOPT_SSH_COMPRESSION.3: enable with 1L - Created a new SMTP structure and changed the type of the smtp proto - variable in connectdata from FTP* to SMTP*. + (leaves other values reserved for the future) -unknown (23 Feb 2013) -- [Steve Holme brought this change] +- compressed-ssh.d: "Added: 7.56.0" - imap: Minor correction of comments for max line length +- curl/system.h: checksrc compliance -Daniel Stenberg (23 Feb 2013) -- strcasestr: remove check for this unused function +Jay Satiro (17 Aug 2017) +- [Viktor Szakats brought this change] -- pop3: fix compiler warning + ssh: add the ability to enable compression (for SCP/SFTP) + + The required low-level logic was already available as part of + `libssh2` (via `LIBSSH2_FLAG_COMPRESS` `libssh2_session_flag()`[1] + option.) - error: declaration of 'pop3' shadows a previous local + This patch adds the new `libcurl` option `CURLOPT_SSH_COMPRESSION` + (boolean) and the new `curl` command-line option `--compressed-ssh` + to request this `libssh2` feature. To have compression enabled, it + is required that the SSH server supports a (zlib) compatible + compression method and that `libssh2` was built with `zlib` support + enabled. + + [1] https://www.libssh2.org/libssh2_session_flag.html + + Ref: https://github.com/curl/curl/issues/1732 + Closes https://github.com/curl/curl/pull/1735 -Steve Holme (23 Feb 2013) -- [Jiri Hruska brought this change] +- examples/ftpuploadresume: checksrc compliance - imap: Added URL parsing of new variables +- [Maksim Stsepanenka brought this change] + + http_proxy: fix build error for CURL_DOES_CONVERSIONS - Updated the imap_parse_url_path() function to parse uidvalidity, uid and - section parameters based on RFC-5092. + Closes https://github.com/curl/curl/pull/1793 -- [Jiri Hruska brought this change] +GitHub (16 Aug 2017) +- [Nick Zitzmann brought this change] - imap: Introduced imap_is_bchar() function + configure: check for __builtin_available() availability (#1788) - Added imap_is_bchar() for testing if a given character is a valid bchar - or not. + This change does two things: + 1. It un-breaks the build in Xcode 9.0. (Xcode 9.0 is currently + failing trying to compile connectx() in lib/connect.c.) + 2. It finally weak-links the connectx() function, and falls back on + connect() when run on older operating systems. -- [Jiri Hruska brought this change] +Daniel Stenberg (16 Aug 2017) +- travis: add metalink to some osx builds + + Closes #1790 - imap: Introduced new per-request veriables +- [Max Dymond brought this change] + + coverage: Use two coveralls commands to get lib/vtls results - Added uidvalidity, uid and section variables to the per-request IMAP - structure in preparation for upcoming URL parsing. + closes #1747 -- pingpong: Renamed curl_ftptransfer to curl_pp_transfer +- darwinssi: fix error: variable length array used -- pop3: Removed some FTP heritage leftovers +- m4/curl-compilers.m4: use proper quotes around string, not backticks - Removed user and passwd from the POP3 struct as these cannot be set on - a per-request basis and are leftover from legacy FTP code. + ... when setting clang version to assume 3.7 - Changed some comments still using FTP terminology. + Caused a lot of "integer expression expected" warnings by configure. -- pop3: Moved the per-request variables to the per-request data structure - - Moved the mailbox and custom request variables from the per-connection - struct pop3_conn to the new per-request struct and fixed references - accordingly. +- [Benbuck Nason brought this change] -- pop3: Introduced a custom POP3 structure for per-request data + cmake: remove dead code for DISABLED_THREADSAFE - Created a new POP3 structure and changed the type of the pop3 proto - variable in connectdata from FTP* to POP*. + Closes #1786 -- [Jiri Hruska brought this change] +Jay Satiro (15 Aug 2017) +- [Jakub Zakrzewski brought this change] - imap: Fixed escaping of mailbox names + curl-confopts.m4: fix --disable-threaded-resolver - Used imap_atom() to escape mailbox names in imap_select(). + Closes https://github.com/curl/curl/issues/1784 -- pingpong: Moved curl_ftptransfer definition to pingpong.h - - Moved the ftp transfer structure into pingpong.h so other protocols that - require it don't have to include ftp.h. +Daniel Stenberg (15 Aug 2017) +- [Ryan Winograd brought this change] -- urldata.h: Fixed comment for opt_no_body variable + progress: Track total times following redirects + + Update the progress timers `t_nslookup`, `t_connect`, `t_appconnect`, + `t_pretransfer`, and `t_starttransfer` to track the total times for + these activities when a redirect is followed. Previously, only the times + for the most recent request would be tracked. - Corrected comment for opt_no_body variable to CURLOPT_NOBODY. + Related changes: + + - Rename `Curl_pgrsResetTimesSizes` to `Curl_pgrsResetTransferSizes` + now that the function only resets transfer sizes and no longer + modifies any of the progress timers. + + - Add a bool to the `Progress` struct that is used to prevent + double-counting `t_starttransfer` times. + + Added test case 1399. + + Fixes #522 and Known Bug 1.8 + Closes #1602 + Reported-by: joshhe on github -- email: Minor tidy up following IMAP changes +- [Benbuck Nason brought this change] -- [Jiri Hruska brought this change] + cmake: remove dead code for CURL_DISABLE_RTMP + + Closes #1785 - imap: Removed more FTP leftovers +Kamil Dudka (15 Aug 2017) +- zsh.pl: produce a working completion script again - Changed some variables and comments still using FTP terminology. + Commit curl-7_54_0-118-g8b2f22e changed the output format of curl --help + to use <file> and <dir> instead of FILE and DIR, which caused zsh.pl to + produce a broken completion script: + + % curl --<TAB> + _curl:10: no such file or directory: seconds + + Closes #1779 -- [Jiri Hruska brought this change] +Daniel Stenberg (15 Aug 2017) +- curlver: toward 7.56.0? - imap: Removed some FTP heritage leftovers - - Removed user and passwd from the IMAP struct as these cannot be set on - a per-request basis and are leftover from legacy FTP code. +- RELEASE-NOTES: synced with 91c46dc44 -- [Jiri Hruska brought this change] +- test1449: FTP download range with an too large size - imap: Introduced a custom IMAP structure for per-request data +- strtoofft: reduce integer overflow risks globally - Created a new IMAP structure and changed the type of the imap proto - variable in connectdata from FTP* to the new IMAP*. + ... make sure we bail out on overflows. - Moved the mailbox variable from the per-connection struct imap_conn to - the new per-request struct and fixed references accordingly. + Reported-by: Brian Carpenter + Closes #1758 -- pop3: Updated do phrase clean-up comment +- travis: build the examples too - Following commit 65644b833532 for the IMAP module updated the clean-up - comment in POP3. - -- imap: Fixed memory leak when performing multiple selects + to make sure they keep building warning-free - Moved the clean-up of the mailbox variable from imap_disconnect() to - imap_done() as this variable is allocated in the do phase, yet would - have only been freed only once if multiple selects where preformed - on a single connection. + Closes #1777 -Daniel Stenberg (22 Feb 2013) -- [Alexander Klauer brought this change] +- runtests: match keywords case insensitively - Documentation: Typo in docs/CONTRIBUTE +- examples/ftpuploadresume.c: use portable code - Fixes a typo get → git in docs/CONTRIBUTE. + ... converted from the MS specific _snscanf() -- [Alexander Klauer brought this change] +Version 7.55.1 (13 Aug 2017) - repository: ignore patch files generated by git - - Ignores the patch files generated by the 'git format-patch' command. +Daniel Stenberg (13 Aug 2017) +- RELEASE-NOTES/THANKS: curl 7.55.1 release time -- [Alexander Klauer brought this change] +- gitignore: ignore .xz now instead of .lzma - libcurl documentation: clarifications and typos - - * Elaborates on default values of some curl_easy_setopt() options. - * Reminds the user to cast variadic arguments to curl_easy_setopt() to - 'void *' where curl internally interprets them as such. - * Clarifies the working of the CURLOPT_SEEKFUNCTION option for - curl_easy_setopt(). - * Fixes typo 'forth' → 'fourth'. - * Elaborates on CURL_SOCKET_TIMEOUT. - * Adds some missing periods. - * Notes that the return value of curl_version() must not be passed to - free(). +- [Sergei Nikulov brought this change] -- [Alexander Klauer brought this change] + cmake: Threads detection update. ref: #1702 + + Closes #1719 - lib/url.c: Generic read/write data pointers +- ipv6_scope: support unique local addresses - Always interprets the pointer passed with the CURLOPT_WRITEDATA or - CURLOPT_READDATA options of curl_easy_setopt() as a void pointer in - order to avoid problems in environments where FILE and void pointers - have non-trivial conversion. + Fixes #1764 + Closes #1773 + Reported-by: James Slaughter -- [Alexander Klauer brought this change] +- [Alex Potapenko brought this change] - libcurl documentation: updates HTML index + curl/system.h: GCC doesn't define __ppc__ on PowerPC, uses __powerpc__ - * Adds several links to documentation of library functions which were - missing. - * Marks documentation of deprecated library functions "(deprecated)". - * Removes spurious .html suffixes. + Closes #1774 -- ossl_seed: avoid recursive seeding! +- test1448: verify redirect to IDN using URL + + Closes #1772 -Steve Holme (22 Feb 2013) -- [Jiri Hruska brought this change] +- [Salah-Eddin Shaban brought this change] - Fixed checking the socket if there is data waiting in the cache + redirect: skip URL encoding for host names + + This fixes redirects to IDN URLs - Use Curl_pp_moredata() in Curl_pp_multi_statemach() to check if there is - more data to be received, rather than the socket state, as a task could - hang waiting for more data from the socket itself. + Fixes #1441 + Closes #1762 + Reported by: David Lord -- imap.c: Fixed an incorrect variable reference +- test2032: mark as flaky (again) + +- travis: test cmake build on tarball too - Fixed an incorrect variable reference which was introduced in commit - a1701eea289f as a result of a copy and paste from SMTP/POP3. + Could've prevented #1755 -- [Jiri Hruska brought this change] +- [Simon Warta brought this change] - pingpong: Introduce Curl_pp_moredata() + cmake: allow user to override CMAKE_DEBUG_POSTFIX - A simple function to test whether the PP is not sending and there are - still more data in its receiver cache. This will be later utilized to: + Closes #1763 + +- connect-to.d: better language + +- connect-to.d: clarified + +- bagder/Curl_tvdiff_us: fix the math - 1) Change Curl_pp_multi_statemach() and Curl_pp_easy_statemach() to - not test socket state and just call user's statemach_act() function - when there are more data to process, because otherwise the task would - just hang, waiting for more data from the socket. + Regression since adef394ac5 (released in 7.55.0) - 2) Allow PP users to read multiple responses by looping as long as there - are more data available and current phase is not finished. - (Currently needed for correct processing of IMAP SELECT responses.) + Reported-by: Han Qiao + Fixes #1769 + Closes #1771 -Nick Zitzmann (19 Feb 2013) -- FEATURES: why yes, we do support metalink +- curl/system.h: add Oracle Solaris Studio - I just noticed Metalink support wasn't listed as a feature of the tool. + Fixes #1752 -- metalink: fix improbable crash parsing metalink filename +- [Alessandro Ghedini brought this change] + + docs: fix typo funtion -> function - The this_url pointer wasn't being initialized, so if strdup() would return - null when copying the filename in a metalink file, then hilarity would - ensue during the cleanup phase. This change was brought to you by clang, - which noticed this and raised a warning. + Closes #1770 + +Alessandro Ghedini (12 Aug 2017) +- docs: fix grammar in CURL_SSLVERSION_MAX_DEFAULT description -Yang Tse (19 Feb 2013) -- smtp.c: fix enumerated type mixed with another type +- docs: fix typo stuct -> struct -- polarssl threadlock cleanup +Dan Fandrich (12 Aug 2017) +- test1447: require a curl with http support -Nick Zitzmann (18 Feb 2013) -- docs: schannel and darwinssl documentation improvements +Daniel Stenberg (11 Aug 2017) +- [Thomas Petazzoni brought this change] + + curl/system.h: support more architectures + + The long list of architectures in include/curl/system.h is annoying to + maintain, and needs to be extended for each and every architecture to + support. + + Instead, let's rely on the __SIZEOF_LONG__ define of the gcc compiler + (we are in the GNUC condition anyway), which tells us if long is 4 + bytes or 8 bytes. + + This fixes the build of libcurl 7.55.0 on architectures such as + OpenRISC or ARC. - Schannel and darwinssl use the certificates built into the - OS to do vert verification instead of bundles. darwinssl - is thread-safe. Corrected typos in the NSS docs. + Closes #1766 + + Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> -Daniel Stenberg (18 Feb 2013) -- resolver_error: remove wrong error message output +- test2033: this went flaky again - The attempt to use gai_strerror() or alternative function didn't work as - the 'sock_error' field didn't contain the proper error code. But since - this hasn't been reported and thus isn't really a big deal I decided to - just scrap the whole attempt to output the detailed resolver error and - instead remain with just stating that the resolving of the name failed. + Suspicion: when we enabled the threaded resolver by default. -- [Kim Vandry brought this change] +- test1447: verifies the parse proxy fix in 6e0e152ce5c - Curl_resolver_is_resolved: show proper host name on failed resolve +- [Even Rouault brought this change] -- Curl_resolver_is_resolved: fix compiler warning + parse_proxy(): fix memory leak in case of invalid proxy server name + + Fixes the below leak: + + $ valgrind --leak-check=full ~/install-curl-git/bin/curl --proxy "http://a:b@/x" http://127.0.0.1 + curl: (5) Couldn't resolve proxy name + ==5048== + ==5048== HEAP SUMMARY: + ==5048== in use at exit: 532 bytes in 12 blocks + ==5048== total heap usage: 5,288 allocs, 5,276 frees, 445,271 bytes allocated + ==5048== + ==5048== 2 bytes in 1 blocks are definitely lost in loss record 1 of 12 + ==5048== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) + ==5048== by 0x4E6CB79: parse_login_details (url.c:5614) + ==5048== by 0x4E6BA82: parse_proxy (url.c:5091) + ==5048== by 0x4E6C46D: create_conn_helper_init_proxy (url.c:5346) + ==5048== by 0x4E6EA18: create_conn (url.c:6498) + ==5048== by 0x4E6F9B4: Curl_connect (url.c:6967) + ==5048== by 0x4E86D05: multi_runsingle (multi.c:1436) + ==5048== by 0x4E88432: curl_multi_perform (multi.c:2160) + ==5048== by 0x4E7C515: easy_transfer (easy.c:708) + ==5048== by 0x4E7C74A: easy_perform (easy.c:794) + ==5048== by 0x4E7C7B1: curl_easy_perform (easy.c:813) + ==5048== by 0x414025: operate_do (tool_operate.c:1563) + ==5048== + ==5048== 2 bytes in 1 blocks are definitely lost in loss record 2 of 12 + ==5048== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) + ==5048== by 0x4E6CBB6: parse_login_details (url.c:5621) + ==5048== by 0x4E6BA82: parse_proxy (url.c:5091) + ==5048== by 0x4E6C46D: create_conn_helper_init_proxy (url.c:5346) + ==5048== by 0x4E6EA18: create_conn (url.c:6498) + ==5048== by 0x4E6F9B4: Curl_connect (url.c:6967) + ==5048== by 0x4E86D05: multi_runsingle (multi.c:1436) + ==5048== by 0x4E88432: curl_multi_perform (multi.c:2160) + ==5048== by 0x4E7C515: easy_transfer (easy.c:708) + ==5048== by 0x4E7C74A: easy_perform (easy.c:794) + ==5048== by 0x4E7C7B1: curl_easy_perform (easy.c:813) + ==5048== by 0x414025: operate_do (tool_operate.c:1563) - conversion to 'int' from 'long int' may alter its value + Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2984 + Credit to OSS Fuzz for discovery + + Closes #1761 + +- RELEASE-NOTES: synced with 37f2195a9 -- compiler warning fix +- curlver: bump to 7.55.1 + +- openssl: fix "error: this statement may fall through" - follow-up to commit ed7174c6f66, rename 'wait' to 'block' + A gcc7 warning. + +- [David Benjamin brought this change] -- compiler warning fix: declaration of 'wait' shadows a global declaration + openssl: remove CONST_ASN1_BIT_STRING. - It seems older gcc installations (at least) will cause warnings if we - name a variable 'wait'. Now changed to 'block' instead. + Just making the pointer as const works for the pre-1.1.0 path too. - Reported by: Jiřà HruÅ¡ka - Bug: http://curl.haxx.se/mail/lib-2013-02/0247.html + Closes #1759 -Nick Zitzmann (17 Feb 2013) -- MacOSX-Framework: Make script work in Xcode 4.0 and later +- maketgz: remove old *.dist files before making the tarball - Apple made a number of changes to Xcode 4. The SDKs were moved, the entire - Developer folder was moved, and PowerPC support was removed. The script - will now adapt to those changes and should be future-proofed against - additional changes in case Apple moves the Developer folder ever again. - Also, the minimum OS X version compiler option was removed, so that the - framework can be built against the latest SDK but still run in older cats. + To avoid "old crap" unintentionally getting shipped. + + Bug: https://curl.haxx.se/mail/lib-2017-08/0050.html + Reported-by: Christian Weisgerber -Daniel Stenberg (17 Feb 2013) -- docs: refer to CURLOPT_ACCEPT_ENCODING instead of the old name +Jay Satiro (10 Aug 2017) +- mkhelp.pl: allow executing this script directly + + - Enable execute permission (chmod +x) + + - Change interpreter to /usr/bin/env perl + + Ref: https://github.com/curl/curl/issues/1743 -Steve Holme (16 Feb 2013) -- email: Tidied up result code variables +Daniel Stenberg (10 Aug 2017) +- configure: use the threaded resolver backend by default if possible - Tidied up result variables to be consistent in name, declaration order - and default values. + Closes #1647 -Nick Zitzmann (16 Feb 2013) -- ntlm_core: fix compiler warning when building with clang +- cmake: move cmake_uninstall.cmake to CMake/ - Fixed a 64-to-32 compiler warning raised when building with - clang and the --with-darwinssl option. + Closes #1756 -Daniel Stenberg (16 Feb 2013) -- Guile-curl: a new libcurl binding +- metalink: fix error: ‘*’ in boolean context, suggest ‘&&’ instead -- polarsslthreadlock: #include the proper memory and debug includes +- dist: fix the cmake build by shipping cmake_uninstall.cmake.in too - Pointed out by Steve Holme + Fixes #1755 -Steve Holme (16 Feb 2013) -- email: Removed unnecessary forward declaration +- travis: verify "make install" - Due to the reordering of functions in commit 586f5d361474 the forward - declaration to state_upgrade_tls() are no longer required. + Help-by: Jay Satiro + Closes #1753 -- pop3.c: Added reference to RFC-5034 +Marcel Raad (10 Aug 2017) +- build: check out *.sln files with Windows line endings + + Visual Studio doesn't like LF line endings in solution files and always + converts them to CRLF when doing changes to the solution. Notably, this + affects the solutions in the release archive. + + Closes https://github.com/curl/curl/pull/1746 -Daniel Stenberg (15 Feb 2013) -- [Willem Sparreboom brought this change] +- gitignore: ignore top-level .vs folder + + This folder is generated when using the CMake build system from within + Visual Studio. + + Closes https://github.com/curl/curl/pull/1746 - PolarSSL: Change to cURL coding style +Jay Satiro (10 Aug 2017) +- digest_sspi: Don't reuse context if the user/passwd has changed + + Bug: https://github.com/curl/curl/issues/1685 + Reported-by: paulharris@users.noreply.github.com + + Assisted-by: Isaac Boukris - Repaired all curl/lib/checksrc.pl warnings in the previous four patches + Closes https://github.com/curl/curl/pull/1742 -- [Willem Sparreboom brought this change] +Daniel Stenberg (9 Aug 2017) +- [Adam Sampson brought this change] - PolarSSL: WIN32 threading support for entropy + dist: Add dictserver.py/negtelnetserver.py to EXTRA_DIST - Added WIN32 threading support for PolarSSL entropy if - --enable-threaded-resolver config flag is set and process.h can be found. + These weren't included in the 7.55.0 release, but are required in order + to run the full test suite. + + Closes #1744 -- [Willem Sparreboom brought this change] +- [Adam Sampson brought this change] - PolarSSL: pthread support for entropy + curl: do bounds check using a double comparison + + The fix for this in 8661a0aacc01492e0436275ff36a21734f2541bb wasn't + complete: if the parsed number in num is larger than will fit in a long, + the conversion is undefined behaviour (causing test1427 to fail for me + on IA32 with GCC 7.1, although it passes on AMD64 and ARMv7). Getting + rid of the cast means the comparison will be done using doubles. - Added pthread support for polarssl entropy if --enable-threaded-resolver - config flag is set and pthread.h can be found. + It might make more sense for the max argument to also be a double... + + Fixes #1750 + Closes #1749 -- [Willem Sparreboom brought this change] +- make install: add 8 missing man pages to the installation - PolarSSL: changes to entropy/ctr_drbg/HAVEGE_RANDOM +- build: fix 'make install' with configure, install docs/libcurl/* too + + Broken since d24838d4da9faa - Add non-threaded entropy and ctr_drbg and removed HAVEGE_RANDOM define + Reported-by: Bernard Spil -- [Willem Sparreboom brought this change] +Version 7.55.0 (9 Aug 2017) - PolarSSL: added human readable error strings - - Print out human readable error strings for PolarSSL related errors +Daniel Stenberg (9 Aug 2017) +- RELEASE-NOTES: curl 7.55.0 -Steve Holme (15 Feb 2013) -- pop3: Removed unnecessary state changes on failure +- THANKS: 20 new contributors in 7.55.0 -- imap: Removed unnecessary state change on failure +- [Viktor Szakats brought this change] -Daniel Stenberg (15 Feb 2013) -- metalink_cleanup: yet another follow-up fix + docs/comments: Update to secure URL versions + + Closes #1741 -- metalink_cleanup: define it without argument +- configure: fix recv/send/select detection on Android + + ... since they now provide several functions as + __attribute__((overloadable)), the argument detection logic need + updates. + + Patched-by: destman at github - Since the function takes no argument, the macro shouldn't take one as - some compilers will error out on that. + Fixes #1738 + Closes #1739 -- rename "easy" statemachines: call them block instead +Marcel Raad (8 Aug 2017) +- ax_code_coverage.m4: update to latest version - ... since they're not used by the easy interface really, I wanted to - remove the association. Also, I unified the pingpong statemachine driver - into a single function with a 'wait' argument: Curl_pp_statemach. + This updates the script to aad5ad5fedb306b39f901a899b7bd305b66c418d + from August 01, 2017. Notably, this removes the lconv version whitelist. + + Closes https://github.com/curl/curl/pull/1716 -Yang Tse (15 Feb 2013) -- [Gisle Vanem brought this change] +Daniel Stenberg (7 Aug 2017) +- test1427: verify command line parser integer overflow detection - curl_setup_once.h: definition of HAVE_CLOSE_S defines sclose() to close_s() +- curl: detect and bail out early on parameter integer overflows + + Make the number parser aware of the maximum limit curl accepts for a + value and return an error immediately if larger, instead of running an + integer overflow later. + + Fixes #1730 + Closes #1736 -- [Gisle Vanem brought this change] +- glob: do not continue parsing after a strtoul() overflow range + + Added test 1289 to verify. + + CVE-2017-1000101 + + Bug: https://curl.haxx.se/docs/adv_20170809A.html + Reported-by: Brian Carpenter - config-dos.h: define HAVE_CLOSE_S for MSDOS/Watt-32 +- tftp: reject file name lengths that don't fit + + ... and thereby avoid telling send() to send off more bytes than the + size of the buffer! + + CVE-2017-1000100 + + Bug: https://curl.haxx.se/docs/adv_20170809B.html + Reported-by: Even Rouault + + Credit to OSS-Fuzz for the discovery -- [Gisle Vanem brought this change] +- [Even Rouault brought this change] - config-dos.h: define strerror() to strerror_s_() for High-C + file: output the correct buffer to the user + + Regression brought by 7c312f84ea930d8 (April 2017) + + CVE-2017-1000099 + + Bug: https://curl.haxx.se/docs/adv_20170809C.html + + Credit to OSS-Fuzz for the discovery -- [Gisle Vanem brought this change] +- easy_events: make event data static + + First: this function is only used in debug-builds and not in + release/real builds. It is used to drive tests using the event-based + API. + + A pointer to the local struct is passed to CURLMOPT_TIMERDATA, but the + CURLMOPT_TIMERFUNCTION calback can in fact be called even after this + funtion returns, namely when curl_multi_remove_handle() is called. + + Reported-by: Brian Carpenter + +- getparameter: avoid returning uninitialized 'usedarg' + + Fixes #1728 - config-dos.h: define HAVE_TERMIOS_H only for djgpp +Marcel Raad (5 Aug 2017) +- [Isaac Boukris brought this change] -Steve Holme (14 Feb 2013) -- smtp.c: Fixed a trailing whitespace + gssapi: fix memory leak of output token in multi round context - Remove tailing whitespace introduced in commit 7ed689d24a4e. + When multiple rounds are needed to establish a security context + (usually ntlm), we overwrite old token with a new one without free. + Found by proposed gss tests using stub a gss implementation (by + valgrind error), though I have confirmed the leak with a real + gssapi implementation as well. + + Closes https://github.com/curl/curl/pull/1733 -- pop3: Fixed blocking SSL connect when connecting via POP3S +- darwinssl: fix compiler warning + + clang complains: + vtls/darwinssl.c:40:8: error: extra tokens at end of #endif directive + [-Werror,-Wextra-tokens] - A call to Curl_ssl_connect() was accidentally left in when the SSL/TLS - connection layer was reworked in 7.29. Not only would this cause the - connection to block but had the additional overhead of calling the - non-blocking connect a little bit later. + This breaks the darwinssl build on Travis. Fix it by making this token + a comment. + + Closes https://github.com/curl/curl/pull/1734 -- smtp: Refactored the smtp_state_auth_resp() function +- CMake: fix CURL_WERROR for MSVC + + When using CURL_WERROR in MSVC builds, the debug flags were overridden + by the release flags and /WX got added twice in debug mode. - Renamed smtp_state_auth_resp() function to match the implementations in - IMAP and POP3. + Closes https://github.com/curl/curl/pull/1715 -Daniel Stenberg (14 Feb 2013) -- remove ifdefs +Daniel Stenberg (4 Aug 2017) +- RELEASE-NOTES: synced with 561e9217c + +- test1010: verify that #1718 is fixed - Clarify the code by reducing ifdefs + ... by doing two transfers in nocwd mode and check that there's no + superfluous CWD command. -- strlcat: remove function +- FTP: skip unnecessary CWD when in nocwd mode - This function was only used twice, both in places where performance - isn't crucial (socks + if2ip). Removing the use of this function removes - the need to have our private version for systems without it == reduced - amount of code. + ... when reusing a connection. If it didn't do any CWD previously. - Also, in the SOCKS case it is clearly better to fail gracefully rather - than to truncate the results. + Fixes #1718 + +Marcel Raad (4 Aug 2017) +- travis: explicitly specify dist - This work was triggered by a bug report on the strcal prototype in - strequal.h. + This makes the builds more reproducible as travis is currently rolling + out trusty as default dist [1]. Specifically, this avoids coverage + check failures when trusty is used as seen in [2] until we figure out + what's wrong. - strlcat was added in commit db70cd28 in February 2001! + [1] https://blog.travis-ci.com/2017-07-11-trusty-as-default-linux-is-coming + [2] https://github.com/curl/curl/pull/1692 - Bug: http://curl.haxx.se/bug/view.cgi?id=1192 - Reported by: Jeremy Huddleston + Closes https://github.com/curl/curl/pull/1725 -- Curl_FormBoundary: made static +Daniel Stenberg (4 Aug 2017) +- travis: BUILD_TYPE => T - As Curl_FormBoundary() is no longer used outside of this file (since - commit ad7291c1a9d), it is now renamed to formboundary() and is made - static. + (to make the full line appear nicer on travis web UI) -- ossl_seed: fix the last resort PRNG seeding +- travis: add osx build with darwinssl - Instead of just abusing the pseudo-randomizer from Curl_FormBoundary(), - this now uses Curl_ossl_random() to get entropy. + Closes #1706 -Steve Holme (13 Feb 2013) -- email: Tidy up before additional IMAP work +- darwin: silence compiler warnings - Replaced two explicit comparisons of CURLE_OK with boolean alternatives. + With a clang pragma and three type fixes - General tidy up of comments. + Fixes #1722 -- smtp: Removed duplicate pingpong structure initialisation - - The smtp_connect() function was setting the member variables of the - pingpong structure twice, once before calling Curl_pp_init() and once - after! +- BUILD.WINDOWS: mention buildconf.bat for builds off git + +- darwinssl: fix curlssl_sha256sum() compiler warnings on first argument -Yang Tse (13 Feb 2013) -- move msvc IDE related files to 'vs' directory tree +- test130: verify comments in .netrc + +- [Gisle Vanem brought this change] + + netrc: skip lines starting with '#' - Use 'vs' directory tree given that 'vc' intended one clashes - with an already existing build target in file Makefile.dist. + Bug: https://curl.haxx.se/mail/lib-2017-08/0008.html -Daniel Stenberg (13 Feb 2013) -- install-sh: updated to support multiple source files as arguments +Marcel Raad (3 Aug 2017) +- CMake: set MSVC warning level to 4 - Version 7.29.0 uses Makefiles generated with a newer version of the - autotools than the previous 7.28.1. These Makefiles try to install - e.g. header files by calling install-sh with multiple source files as - arguments. The bundled install-sh is to old and does not support this. + The MSVC warning level defaults to 3 in CMake. Change it to 4, which is + consistent with the Visual Studio and NMake builds. Disable level 4 + warning C4127 for the library and additionally C4306 for the test + servers to get a clean CURL_WERROR build as that warning is raised in + some macros in older Visual Studio versions. - The problem only occurs, if install-sh is actually being used, ie. the - platform install executable is to old or not usable. Example: Solaris - 10. + Ref: https://github.com/curl/curl/pull/1667#issuecomment-314082794 + Closes https://github.com/curl/curl/pull/1711 + +Daniel Stenberg (2 Aug 2017) +- CURLOPT_NETRC.3: fix typo in 7e48aa386156f9c2 - The files install-sh and mkinstalldirs are now updated with the automake - 1.11.3 versions. A better fix might be to completely remove them from - git and force the files to be added/created during buildconf. + Reported-by: Viktor Szakats + +- CURLOPT_NETRC.3: mention the file name on windows - Bug: http://curl.haxx.se/bug/view.cgi?id=1195 - Reported by: Rainer Jung + ... and CURLOPT_NETRC_FILE(3). + +- travis: build osx with libressl too + +- travis: build osx with openssl too -Yang Tse (13 Feb 2013) -- move msvc IDE related files to 'vc' directory tree +- tests/server/util: fix curltime mistake from 4dee50b9c80f9 -- msvc IDE 'vc' directory tree preparation +Marcel Raad (1 Aug 2017) +- curl_threads: fix MSVC compiler warning + + Use LongToHandle to convert from long to HANDLE in the Win32 + implementation. + This should fix the following warning when compiling with + MSVC 11 (2012) in 64-bit mode: + lib\curl_threads.c(113): warning C4306: + 'type cast' : conversion from 'long' to 'HANDLE' of greater size + + Closes https://github.com/curl/curl/pull/1717 -Steve Holme (12 Feb 2013) -- imap: Corrected a whitespace issue from previous commit +Daniel Stenberg (1 Aug 2017) +- BUGS: improved phrasing about security bugs - Fixed a small whitespace issue that crept in there in commit - 508cdf4da4d7. + Reported-by: Max Dymond -- email: Another post optimisation of endofresp() tidy up +- BUGS: clarify how to report security related bugs -- sasl: Fixed null pointer reference when decoding empty digest challenge +- [Brad Spencer brought this change] + + multi: fix request timer management - Fixed a null pointer reference when an empty challenge is passed to the - Curl_sasl_create_digest_md5_message() function. + There are some bugs in how timers are managed for a single easy handle + that causes the wrong "next timeout" value to be reported to the + application when a new minimum needs to be recomputed and that new + minimum should be an existing timer that isn't currently set for the + easy handle. When the application drives a set of easy handles via the + `curl_multi_socket_action()` API (for example), it gets told to wait the + wrong amount of time before the next call, which causes requests to + linger for a long time (or, it is my guess, possibly forever). - Bug: http://sourceforge.net/p/curl/bugs/1193/ - Reported by: Saran Neti + Bug: https://curl.haxx.se/mail/lib-2017-07/0033.html -- email: Post optimisation of endofresp() tidy up +Jay Satiro (1 Aug 2017) +- curl_setup: Define CURL_NO_OLDIES for building libcurl + + .. to catch accidental use of deprecated error codes. - Removed unnecessary end of line check and return. + Ref: https://github.com/curl/curl/issues/1688#issuecomment-316764237 -Nick Zitzmann (12 Feb 2013) -- darwinssl: Fix send glitchiness with data > 32 or so KB +Daniel Stenberg (1 Aug 2017) +- [Jeremy Tan brought this change] + + configure: fix the check for IdnToUnicode - An ambiguity in the SSLWrite() documentation lead to a bad inference in the - code where we assumed SSLWrite() returned the amount of bytes written to - the socket, when that is not actually true; it returns the amount of data - that is buffered for writing to the socket if it returns errSSLWouldBlock. - Now darwinssl_send() returns CURLE_AGAIN if data is buffered but not written. + Fixes #1669 + Closes #1713 + +- http: fix response code parser to avoid integer overflow - Reference URL: http://curl.haxx.se/mail/lib-2013-02/0145.html + test 1429 and 1433 were updated to work with the stricter HTTP status line + parser. + + Closes #1714 + Reported-by: Brian Carpenter + +Jay Satiro (31 Jul 2017) +- [Dwarakanath Yadavalli brought this change] -Steve Holme (12 Feb 2013) -- pingpong.h: Fixed line length over 78 characters from b56c9eb48e3c + libcurl: Stop using error codes defined under CURL_NO_OLDIES + + Fixes https://github.com/curl/curl/issues/1688 + Closes https://github.com/curl/curl/pull/1712 -- pingpong: Optimised the endofresp() function +- include.d: clarify --include is only for response headers - Reworked the pp->endofresp() function so that the conndata, line and - line length are passed down to it just as with Curl_client_write() - rather than each implementation of the function having to query - these values. + Follow-up to 171f8de and de6de94. - Additionally changed the int return type to bool as this is more - representative of the function's usage. + Bug: https://github.com/curl/curl/commit/de6de94#commitcomment-23370851 + Reported-by: Daniel Stenberg + +Daniel Stenberg (30 Jul 2017) +- [Jason Juang brought this change] -- email: Post STARTLS capability code tidy up (Part Three) + cmake: support make uninstall - Corrected the order of the upgrade_tls() functions and moved the handler - upgrade and getsock() functions out from the middle of the state related - functions. + Closes #1674 -- email: Post STARTLS capability code tidy up (Part Two) +- RELEASE-NOTES: synced with 001701c47 + +Marcel Raad (29 Jul 2017) +- AppVeyor: now really use CURL_WERROR + + It was misspelled as CURL_ERROR in commit + 2d86e8d1286e0fbe3d811e2e87fa0b5e53722db4. - Corrected the order of the pop3_state_capa() / imap_state_capability() - and the pop3_state_capa_resp() / imap_state_capability_resp() functions - to match the execution order. + Closes https://github.com/curl/curl/pull/1686 -Daniel Stenberg (11 Feb 2013) -- [ulion brought this change] +Jay Satiro (29 Jul 2017) +- tool_help: clarify --include is only for response headers + + Follow-up to 171f8de. + + Ref: https://github.com/curl/curl/issues/1704 - SOCKS: fix socks proxy when noproxy matched +- splay: fix signed/unsigned mismatch warning - Test 1212 added to verify + Follow-up to 4dee50b. - Bug: http://curl.haxx.se/bug/view.cgi?id=1190 + Ref: https://github.com/curl/curl/pull/1693 -Steve Holme (11 Feb 2013) -- ntlm: Updated comments for the addition of SASL support to IMAP in v7.29 +Daniel Stenberg (28 Jul 2017) +- include.d: clarify that it concerns the response headers + + Reported-by: olesteban at github + Fixes #1704 + +- [Johannes Schindelin brought this change] -- RELEASE-NOTES: Updated following the recent imap/pop3/smtp changes + curl_rtmp: fix a compiler warning + + The headers of librtmp declare the socket as `int`, and on Windows, that + disagrees with curl_socket_t. + + Bug: #1652 + + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -Linus Nielsen Feltzing (10 Feb 2013) -- Fix NULL pointer reference when closing an unused multi handle. +- test1323: verify curlx_tvdiff -Steve Holme (10 Feb 2013) -- email: Post STARTLS capability code tidy up (Part One) +- timeval: struct curltime is a struct timeval replacement - Corrected the order of the CAPA / CAPABILITY state machine constants to - match the execution order. + ... to make all libcurl internals able to use the same data types for + the struct members. The timeval struct differs subtly on several + platforms so it makes it cumbersome to use everywhere. + + Ref: #1652 + Closes #1693 -- imap: Fixed memory leak following commit f6010d9a0359 +- darwinssl: fix variable type mistake (regression) + + ... which made --tlsv1.2 not work because it would blank the max tls + version variable. + + Reported-by: Nick Miyake + Bug: #1703 -- smtp: Added support for the STARTTLS capability (Part Two) +- multi: mention integer overflow risk if using > 500 million sockets + + Reported-by: ovidiu-benea@users.noreply.github.com - Added honoring of the tls_supported flag when starting a TLS upgrade - rather than unconditionally attempting it. If the use_ssl flag is set - to CURLUSESSL_TRY and the server doesn't support TLS upgrades then the - connection will continue to authenticate. If this flag is set to - CURLUSESSL_ALL then the connection will complete with a failure as it - did previously. + Closes #1675 + Closes #1683 -- pop3: Added support for the STLS capability (Part Three) +- checksrc: escape open brace in regex - Added honoring of the tls_supported flag when starting a TLS upgrade - rather than unconditionally attempting it. If the use_ssl flag is set - to CURLUSESSL_TRY and the server doesn't support TLS upgrades then the - connection will continue to authenticate. If this flag is set to - CURLUSESSL_ALL then the connection will complete with a failure as it - did previously. + ... to silence warning. -- imap: Added support for the STARTTLS capability (Part Three) +Kamil Dudka (20 Jul 2017) +- nss: fix a possible use-after-free in SelectClientCert() - Added honoring of the tls_supported flag when starting a TLS upgrade - rather than unconditionally attempting it. If the use_ssl flag is set - to CURLUSESSL_TRY and the server doesn't support TLS upgrades then the - connection will continue to authenticate. If this flag is set to - CURLUSESSL_ALL then the connection will complete with a failure as it - did previously. + ... causing a SIGSEGV in showit() in case the handle used to initiate + the connection has already been freed. + + This commit fixes a bug introduced in curl-7_19_5-204-g5f0cae803. + + Reported-by: Rob Sanders + Bug: https://bugzilla.redhat.com/1436158 -Daniel Stenberg (10 Feb 2013) -- [Alessandro Ghedini brought this change] +- nss: unify the coding style of nss_send() and nss_recv() + + No changes in behavior intended by this commit. - htmltitle: fix suggested build command +Marcel Raad (18 Jul 2017) +- tests/server/resolve.c: fix deprecation warning + + MSVC warns that gethostbyname is deprecated. Always use getaddrinfo + instead to fix this when IPv6 is enabled, also for IPv4 resolves. This + is also consistent with what libcurl does. + + Closes https://github.com/curl/curl/pull/1682 -Steve Holme (10 Feb 2013) -- pop3: Added support for the STLS capability (Part Two) +Jay Satiro (17 Jul 2017) +- darwinssl: fix pinnedpubkey build error - Added sending of initial CAPA command before STLS is sent. This allows - for the detection of the capability before trying to upgrade the - connection. + - s/SessionHandle/Curl_easy/ + + Bug: https://github.com/curl/curl/commit/eb16305#commitcomment-23035670 + Reported-by: Gisle Vanem -- imap: Added support for the STARTTLS capability (Part Two) +Marcel Raad (16 Jul 2017) +- rtspd: fix GCC warning after MSVC warning fix + + Older GCC warns: + /tests/server/rtspd.c:1194:10: warning: missing braces around + initializer [-Wmissing-braces] - Added sending of initial CAPABILITY command before STARTTLS is sent. - This allows for the detection of the capability before trying to - upgrade the connection. + Fix this by using memset instead of an initializer. -- smtp: Added support for the STLS capability (Part One) +- libtest: fix MSVC warning C4706 - Introduced detection of the STARTTLS capability, in order to add support - for TLS upgrades without unconditionally sending the STARTTLS command. + With warning level 4, MSVC warns about assignments within conditional + expressions. Change the while loop to a do-while loop to fix this. This + change is also consistent with CODE_STYLE.md. -- pop3: Added support for the STLS capability (Part One) +- sockfilt: suppress conversion warning with explicit cast - Introduced detection of the STLS capability, in order to add support - for TLS upgrades without unconditionally sending the STLS command. + MSVC warns when implicitly casting -1 to unsigned long. -- imap: Added support for the STARTTLS capability (Part One) +- rtspd: fix MSVC level 4 warning - Introduced detection of the STARTTLS capability, in order to add support - for TLS upgrades without unconditionally sending the STARTTLS command. + warning C4701: potentially uninitialized local variable 'req' used diff --git a/libs/libcurl/docs/COPYING b/libs/libcurl/docs/COPYING index 85d122ecf0..560a49dcee 100644 --- a/libs/libcurl/docs/COPYING +++ b/libs/libcurl/docs/COPYING @@ -1,6 +1,7 @@ COPYRIGHT AND PERMISSION NOTICE -Copyright (c) 1996 - 2013, Daniel Stenberg, <daniel@haxx.se>. +Copyright (c) 1996 - 2018, Daniel Stenberg, <daniel@haxx.se>, and many +contributors, see the THANKS file. All rights reserved. diff --git a/libs/libcurl/docs/LICENSE-MIXING b/libs/libcurl/docs/LICENSE-MIXING deleted file mode 100644 index f596546da5..0000000000 --- a/libs/libcurl/docs/LICENSE-MIXING +++ /dev/null @@ -1,130 +0,0 @@ - License Mixing with apps, libcurl and Third Party Libraries - =========================================================== - -libcurl can be built to use a fair amount of various third party libraries, -libraries that are written and provided by other parties that are distributed -using their own licenses. Even libcurl itself contains code that may cause -problems to some. This document attempts to describe what licenses libcurl and -the other libraries use and what possible dilemmas linking and mixing them all -can lead to for end users. - -I am not a lawyer and this is not legal advice! - -One common dilemma is that GPL[1]-licensed code is not allowed to be linked -with code licensed under the Original BSD license (with the announcement -clause). You may still build your own copies that use them all, but -distributing them as binaries would be to violate the GPL license - unless you -accompany your license with an exception[2]. This particular problem was -addressed when the Modified BSD license was created, which does not have the -announcement clause that collides with GPL. - -libcurl http://curl.haxx.se/docs/copyright.html - - Uses an MIT (or Modified BSD)-style license that is as liberal as - possible. Some of the source files that deal with KRB4 have Original - BSD-style announce-clause licenses. You may not distribute binaries - with krb4-enabled libcurl that also link with GPL-licensed code! - -OpenSSL http://www.openssl.org/source/license.html - - (May be used for SSL/TLS support) Uses an Original BSD-style license - with an announcement clause that makes it "incompatible" with GPL. You - are not allowed to ship binaries that link with OpenSSL that includes - GPL code (unless that specific GPL code includes an exception for - OpenSSL - a habit that is growing more and more common). If OpenSSL's - licensing is a problem for you, consider using GnuTLS or yassl - instead. - -GnuTLS http://www.gnutls.org/ - - (May be used for SSL/TLS support) Uses the LGPL[3] license. If this is - a problem for you, consider using OpenSSL instead. Also note that - GnuTLS itself depends on and uses other libs (libgcrypt and - libgpg-error) and they too are LGPL- or GPL-licensed. - -yassl http://www.yassl.com/ - - (May be used for SSL/TLS support) Uses the GPL[1] license. If this is - a problem for you, consider using OpenSSL or GnuTLS instead. - -NSS http://www.mozilla.org/projects/security/pki/nss/ - - (May be used for SSL/TLS support) Is covered by the MPL[4] license, - the GPL[1] license and the LGPL[3] license. You may choose to license - the code under MPL terms, GPL terms, or LGPL terms. These licenses - grant you different permissions and impose different obligations. You - should select the license that best meets your needs. - -axTLS http://axtls.sourceforge.net/ - - (May be used for SSL/TLS support) Uses a Modified BSD-style license. - -c-ares http://daniel.haxx.se/projects/c-ares/license.html - - (Used for asynchronous name resolves) Uses an MIT license that is very - liberal and imposes no restrictions on any other library or part you - may link with. - -zlib http://www.gzip.org/zlib/zlib_license.html - - (Used for compressed Transfer-Encoding support) Uses an MIT-style - license that shouldn't collide with any other library. - -krb4 - - While nothing in particular says that a Kerberos4 library must use any - particular license, the one I've tried and used successfully so far - (kth-krb4) is partly Original BSD-licensed with the announcement - clause. Some of the code in libcurl that is written to deal with - Kerberos4 is Modified BSD-licensed. - -MIT Kerberos http://web.mit.edu/kerberos/www/dist/ - - (May be used for GSS support) MIT licensed, that shouldn't collide - with any other parts. - -Heimdal http://www.pdc.kth.se/heimdal/ - - (May be used for GSS support) Heimdal is Original BSD licensed with - the announcement clause. - -GNU GSS http://www.gnu.org/software/gss/ - - (May be used for GSS support) GNU GSS is GPL licensed. Note that you - may not distribute binary curl packages that uses this if you build - curl to also link and use any Original BSD licensed libraries! - -fbopenssl - - (Used for SPNEGO support) Unclear license. Based on its name, I assume - that it uses the OpenSSL license and thus shares the same issues as - described for OpenSSL above. - -libidn http://josefsson.org/libidn/ - - (Used for IDNA support) Uses the GNU Lesser General Public - License [3]. LGPL is a variation of GPL with slightly less aggressive - "copyleft". This license requires more requirements to be met when - distributing binaries, see the license for details. Also note that if - you distribute a binary that includes this library, you must also - include the full LGPL license text. Please properly point out what - parts of the distributed package that the license addresses. - -OpenLDAP http://www.openldap.org/software/release/license.html - - (Used for LDAP support) Uses a Modified BSD-style license. Since - libcurl uses OpenLDAP as a shared library only, I have not heard of - anyone that ships OpenLDAP linked with libcurl in an app. - -libssh2 http://www.libssh2.org/ - - (Used for scp and sftp support) libssh2 uses a Modified BSD-style - license. - -[1] = GPL - GNU General Public License: http://www.gnu.org/licenses/gpl.html -[2] = http://www.fsf.org/licenses/gpl-faq.html#GPLIncompatibleLibs details on - how to write such an exception to the GPL -[3] = LGPL - GNU Lesser General Public License: - http://www.gnu.org/licenses/lgpl.html -[4] = MPL - Mozilla Public License: - http://www.mozilla.org/MPL/ diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index 693139bf73..540a59fc49 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -4,53 +4,88 @@ If you have contributed but are missing here, please let us know! +"Captain Basil" +"Spoon Man" +Aaro Koskinen Aaron Oneal Aaron Orenstein +Abram Pousada +Adam Brown Adam D. Moss +Adam Langley Adam Light +Adam Marcionek Adam Piggott +Adam Sampson Adam Tkac Adrian Schuur Adriano Meirelles Ajit Dhumale +Akhil Kedia Aki Koskinen Akos Pasztory +Akshay Vernekar +Alain Danteny +Alan Jenkins Alan Pinstein Albert Chin-A-Young Albert Choy Ale Vesely -Alejandro Alvarez +Alejandro Alvarez Ayllon Aleksandar Milivojevic Aleksey Tulinov +Ales Mlakar +Ales Novak Alessandro Ghedini Alessandro Vesely +Alex Baines Alex Bligh +Alex Chan Alex Fishman Alex Gruz +Alex Malinovich +Alex McLellan Alex Neblett +Alex Nichols +Alex Potapenko +Alex Rousskov Alex Suykov Alex Vinnik Alex aka WindEagle Alexander Beedie +Alexander Dyagilev +Alexander Elgert Alexander Klauer Alexander Kourakos Alexander Krasnostavsky Alexander Lazic +Alexander Pepper +Alexander Peslyak +Alexander Sinditskiy +Alexander Traud Alexander Zhuravlev Alexey Borzov +Alexey Melnichuk Alexey Pesternikov Alexey Simak Alexey Zakhlestin Alexis Carvalho +Alexis La Goutte +Alfonso Martone Alfred Gebert Allen Pulsifer +Alona Rossen Amol Pattekar Amr Shahin +Anatol Belski Anatoli Tubman +Anders Bakken Anders Gustafsson Anders Havn +Anders Roxell Andi Jahja Andre Guibert de Bruet +Andre Heinecke Andreas Damm Andreas Faerber Andreas Farber @@ -58,47 +93,74 @@ Andreas Malzahn Andreas Ntaflos Andreas Olsson Andreas Rieke +Andreas Roth +Andreas Schneider Andreas Schuldei +Andreas Streichardt Andreas Wurf Andrei Benea Andrei Cipu -Andres Garcia +Andrei Karas +Andrei Kurushin +Andrei Sedoi +Andrej E Baranov Andrew Benham Andrew Biggs Andrew Bushnell Andrew Francis Andrew Fuller +Andrew Krieger Andrew Kurushin +Andrew Lambert Andrew Moise +Andrew Robbins Andrew Wansink Andrew de los Reyes +Andrey Labunets Andrii Moiseiev Andrés GarcÃa Andy Cedilnik Andy Serpa Andy Tsouladze Angus Mackay +Anthon Pang +Anthony Avina Anthony Bryan Anthony G. Basile +Antoine Aubert Antoine Calando Anton Bychkov Anton Kalmykov Anton Malov Anton Yabchinskiy +Antonio Larrosa +Antony74 on github +Antti Hätälä Arkadiusz Miskiewicz Armel Asselin Arnaud Compan Arnaud Ebalard +Aron Bergman +Artak Galoyan Arthur Murray Arve Knudsen +Arvid Norberg +Ashish Shukla +Ask Bjørn Hansen +Askar Safin Ates Goral Augustus Saunders Avery Fay Axel Tillequin Balaji Parasuram +Balaji Salunke Balint Szilakszi +Barry Abrahamson Bart Whiteley Bas Mevissen +Bas van Schaik +Basuke Suzuki +Ben Boeckel Ben Darnell Ben Greear Ben Madsen @@ -109,12 +171,23 @@ Benbuck Nason Benjamin Gerard Benjamin Gilbert Benjamin Johnson +Benjamin Kircher +Benjamin Sergeant +Benoit Neil +Benoit Sigoure Bernard Leak +Bernard Spil +Bernhard M. Wiedemann Bernhard Reutner-Fischer +Bert Huijben Bertrand Demiddelaer +Bertrand Simonnet +Bill Doyle Bill Egert Bill Hoffman Bill Middlecamp +Bill Nagel +Bill Pyne Bjoern Sikora Bjorn Augustsson Bjorn Reese @@ -125,48 +198,74 @@ Bob Richmond Bob Schader Bogdan Nicula Brad Burdick +Brad Fitzpatrick +Brad Harder Brad Hards Brad King +Brad Spencer Bradford Bruce +Brandon Casey Brandon Wang Brendan Jurd Brent Beardsley Brian Akins +Brian Carpenter +Brian Childs +Brian Chrisman Brian Dessent Brian J. Murrell +Brian Prodoehl Brian R Duffy Brian Ulm Brock Noland +Bru Rom Bruce Mitchener +Bruce Stephens +Bruno Grasselli +Bruno Thomsen Bruno de Carvalho Bryan Henderson Bryan Kemp Byrial Jensen Cameron Kaiser +Cameron MacMinn Camille Moncelier Caolan McNamara +Carlo Cannas +Carlo Teubner +Carlo Wood Carsten Lange Casey O'Donnell -Cedric Deltheil +Catalin Patulea Chad Monroe Chandrakant Bagul Charles Kerr +Charles Romestant +Chen Prog +Chester Liu Chih-Chung Chang Chris "Bob Bob" +Chris Araman +Chris Carlmar Chris Combes -Chris Conroy +Chris Conlon Chris Deidun +Chris Faherty Chris Flerackers Chris Gaukroger Chris Maltby Chris Mumford Chris Smowton +Chris Young +Christian Fillion Christian Grothoff +Christian Heimes Christian Hägele Christian Krause Christian Kurz Christian Robottom Reis Christian Schmitz +Christian Stewart Christian Vogt Christian Weisgerber Christophe Demory @@ -175,153 +274,263 @@ Christopher Conroy Christopher Palow Christopher R. Palmer Christopher Stone +Chungtsun Li Ciprian Badescu Claes Jakobsson Clarence Gardner Clemens Gruber Clifford Wolf +Clint Clayton Cody Jones +Cody Mack +Colby Ranger +Colin Blair Colin Hogben Colin Watson Colm Buckley Constantine Sapuntzakis +Cory Benfield Cory Nelson Craig A West Craig Davison Craig Markwardt +Craig de Stigter Cris Bailiff Cristian RodrÃguez Curt Bogmine +Cyril B Cyrill Osterwalder +Cédric Connes Cédric Deltheil +D. Flinkmann +Da-Yoon Chung Dag Ekengren Dagobert Michelsen +Dair Grant +Dambaev Alexander +Damian Dixon Damien Adant +Damien Vielpeau Dan Becker Dan C +Dan Cristian +Dan Donahue Dan Fandrich +Dan Jacobson +Dan Johnson Dan Locks +Dan McNulty Dan Nelson Dan Petitt Dan Torop Dan Zitter +Daniel Bankhead Daniel Black Daniel Cater Daniel Egger +Daniel Gustafsson +Daniel Hwang Daniel Johnson +Daniel Kahn Gillmor +Daniel Krügler +Daniel Lee Hwang +Daniel Melani Daniel Mentz +Daniel Romero +Daniel Schauenberg +Daniel Seither +Daniel Shahaf Daniel Steinberg Daniel Stenberg Daniel Theron Daniel at touchtunes +Daphne Luong +Dario Weisser Darryl House Darshan Mody +DarÃo Hereñú Dave Dribin Dave Halbakken Dave Hamilton Dave May Dave Reisner +Dave Thompson Dave Vasilevsky +Davey Shafik David Bau +David Benjamin David Binderman David Blaikie David Byron David Cohen +David E. Narváez David Eriksson +David Garske David Houlder David Hull David J Meyer David James +David Kalnischkies David Kierznowski David Kimdon +David L. David Lang David LeBlanc +David Lord David McCreedy +David Meyer David Odin David Phillips David Rosenstrauch +David Ryskalczyk +David Schweikert David Shaw David Strauss David Tarendash David Thiel +David Walser +David Woodhouse David Wright David Yan Dengminwen +Denis Feklushkin +Denis Ollier +Dennis Clarke +Derek Higgins +Desmond O. Chang Detlef Schmier Didier Brisebourg +Diego Bes Diego Casorran +Dilyan Palauzov Dima Barsky +Dima Tisnek +Dimitar Boevski Dimitre Dimitrov +Dimitrios Apostolou +Dimitrios Siganos Dimitris Sarris Dinar Dirk Eddelbuettel +Dirk Feytons Dirk Manske Dmitri Shubin +Dmitri Tikhonov Dmitriy Sergeyev Dmitry Bartsevich +Dmitry Eremin-Solenikov +Dmitry Falko +Dmitry Kostjuchenko Dmitry Kurochkin +Dmitry Mikhirev Dmitry Popov Dmitry Rechkin +Dmitry S. Baikov Dolbneff A.V Domenico Andreoli Dominick Meglio +Dominik Hölzl Dominique Leuenberger +Don J Olmstead +Dongliang Mu Doug Kaufman Doug Porter +Douglas Creager Douglas E. Wegscheid Douglas Kilpatrick +Douglas Mencken Douglas R. Horner Douglas Steinwand Dov Murik +Drake Arconis Duane Cathey -Duncan Duncan Mac-Vicar Prett Dustin Boswell +Dusty Mabe +Duy Phan Thanh +Dwarakanath Yadavalli Dylan Ellicott Dylan Salisbury +Dániel Bakai Early Ehlinger +Earnestly on github Ebenezer Ikonne +Ed Morley Edin Kadribasic Eduard Bloch +Edward Kimmel Edward Rudd Edward Sheldrake +Edward Thomson Eelco Dolstra Eetu Ojanen +Egon Eckert Eldar Zaitov +Elliot Saba Ellis Pritchard +Elmira A Semenova Emanuele Bovisio +Emil Lerner Emil Romanus Emiliano Ida +Emmanuel Tychon Enrico Scholz Enrik Berkhan +Eramoto Masaya Eric Cooper +Eric Gallager Eric Hu Eric Landes Eric Lavigne +Eric Lubin Eric Melville Eric Mertens Eric Rautman +Eric Rescorla +Eric Ridge Eric S. Raymond Eric Thelin Eric Vergnaud Eric Wong Eric Young Erick Nuwendam +Erik Janssen Erik Johansson +Ernest Beinrohr +Ernst Sjöstrand Erwan Legrand Erwin Authried +Ethan Glasser Camp Eugene Kotlyarov Evan Jordan +Even Rouault +Evert Pot +Evgeny Grin Evgeny Turnaev Eygene Ryabinkin +Fabian Frank Fabian Hiernaux Fabian Keil +Fabian Ruff Fabrizio Ammollo +Fahim Chandurwala Fedor Karpelevitch +Feist Josselin +Felix Kaiser +Felix Yan Felix von Leitner Feng Tu +Fernando Muñoz +Flavio Medeiros Florian Schoppmann +Florian Weimer +Florin Petriuc Forrest Cahoon +Francisco Moraes +Francisco Sedano +Francois Petitjean +Frank Denis +Frank Gevaerts Frank Hempel Frank Keeney Frank McGeough @@ -329,24 +538,32 @@ Frank Meier Frank Ticheler Frank Van Uffelen FrantiÅ¡ek KuÄera +François Charlier Fred Machado Fred New Fred Noz +Fred Stluka Frederic Lepied +Frederik B Fredrik Thulin Gabriel Kuri Gabriel Sjoberg Garrett Holmstrom Gary Maxwell +Gaurav Malhotra Gautam Kachroo Gautam Mani Gavrie Philipson Gaz Iqbal +Gaël Portay +Geeknik Labs +Geoff Beier Georg Horn Georg Huettenegger Georg Lippitsch Georg Wicherski Gerd v. Egidy +Gergely Nagy Gerhard Herre Gerrit Bruchhäuser Ghennadi Procopciuc @@ -359,44 +576,71 @@ Gilles Blanc Gisle Vanem Giuseppe Attardi Giuseppe D'Ambrosio +Giuseppe Persico +Glen A Johnson Jr. Glen Nakamura Glen Scott -Gokhan Sengun +Glenn Sheridan +Google Inc. +Gordon Marler +Gorilla Maguila +Gou Lingfeng Grant Erickson +Grant Pannell Greg Hewgill Greg Morse Greg Onufer +Greg Pratt +Greg Rowe Greg Zavertnik +Gregory Szorc Grigory Entin Guenole Bescon Guenter Knauf Guido Berhoerster Guillaume Arluison +Gunter Knauf Gustaf Hui +Gustavo Grieco +GwanYeong Kim Gwenole Beauchesne +Gökhan Åžengün Götz Babin-Ebell Hamish Mackenzie +Han Qiao Hang Kin Lau Hang Su +Hannes Magnusson +Hanno Böck Hanno Kranzhoff Hans Steegers Hans-Jurgen May Hardeep Singh +Haris Okanovic +Harold Stuart Harshal Pradhan Hauke Duden +He Qin Heikki Korpela Heinrich Ko +Heinrich Schaefer +Helmut K. C. Tessarek +Helwing Lutz Hendrik Visage +Henrik Gaßmann Henrik Storner Henry Ludemann +Henry Roeland Herve Amblard Hidemoto Nakada Ho-chi Chen Hoi-Ho Chan Hongli Lai Howard Chu +Hubert Kario Hzhijun Ian D Allen +Ian Fette Ian Ford Ian Gulliver Ian Lynagh @@ -406,144 +650,219 @@ Ignacio Vazquez-Abrams Igor Franchuk Igor Novoseltsev Igor Polyakov +Iida Yosiaki Ilguiz Latypov Ilja van Sprundel Immanuel Gregoire +Inca R Ingmar Runge Ingo Ralf Blum Ingo Wilken +Irfan Adilovic +Isaac Boukris Ishan SinghLevett +Ivan Avdeev +Ivo Bellin Salarin Jack Zhang +Jackarain on github Jacky Lam Jacob Meuser Jacob Moshenko +Jactry Zeng Jad Chamcham +Jaime Fullaondo +Jakub Wilk +Jakub Zakrzewski +James Atwill James Bursa James Cheng James Clancy James Cone +James Dury James Gallagher James Griffiths James Housley James MacMillan +James Slaughter Jamie Lokier Jamie Newton Jamie Wilkinson +Jan Alexander Steffens Jan Ehrhardt Jan Koen Annot Jan Kunder Jan Schaumann +Jan Schmidt Jan Van Boghout Jared Jennings Jared Lundell +Jari Aalto Jari Sundell Jason Glasgow +Jason Juang Jason Liu Jason McDonald Jason S. Priebe +Javier Barroso +Javier G. Sogo +Javier Sixto Jay Austin Jayesh A Shah Jaz Fresh +Jean Gressmann Jean Jacques Drouin Jean-Claude Chauve Jean-Francois Bertrand +Jean-Francois Durand Jean-Louis Lemaire Jean-Marc Ranger -Jean-Noel Rouvignac +Jean-Noël Rouvignac Jean-Philippe Barrette-LaPierre Jeff Connelly +Jeff Hodges Jeff Johnson +Jeff King Jeff Lawson Jeff Phillips Jeff Pohlmeyer Jeff Weber -Jeffrey Pohlmeyer +Jeffrey Walton +Jens Rantil Jeremy Friesner Jeremy Huddleston +Jeremy Lin +Jeremy Pearson +Jeremy Tan +Jeroen Koekkoek +Jeroen Ooms Jerome Muffat-Meridol +Jerome Robert Jerome Vouillon +Jerry Krinock Jerry Wu Jes Badwal Jesper Jensen +Jesse Chisholm Jesse Noller +Jesse Tan Jie He Jim Drash Jim Freeman Jim Hollinger Jim Meyering +Jiri Dvorak Jiri Hruska Jiri Jaburek +Jiřà Malák Jocelyn Jaubert Joe Halpin Joe Malicki Joe Mason Joel Chen +Joel Depooter Jofell Gallardo Johan Anderson +Johan Lantz Johan Nilsson Johan van Selst Johannes Bauer +Johannes Ernst +Johannes Schindelin John Bradshaw +John Coffey John Crow +John David Anglin +John DeHelian John Dennis +John Dunn John E. Malmberg John Gardiner Myers +John Hascall John Janssen John Joseph Bachir John Kelly +John Kohl John Lask +John Levon John Lightsey John Marino +John Marshall John McGowan John P. McCaskey +John Starks John Suprock +John Wanghui John Wilkinson John-Mark Bell Johnny Luong +Jon DeVree Jon Grubbs Jon Nelson Jon Sargeant +Jon Seymour +Jon Spencer +Jon Torrey Jon Travis Jon Turner Jonas Forsman +Jonas Minnberg Jonas Schnelli Jonatan Lander +Jonatan Vela +Jonathan Cardoso Machado +Jonathan Cardoso Machado Machado Jonathan Hseu Jonathan Nieder Jongki Suwandi +Joonas Kuorilehto +Jose Alf Jose Kahan Josef Wolf Josh Kapell Joshua Kwan Josue Andrade Gomes +Jozef Kralik Juan Barreto Juan F. Codagnone Juan Ignacio Hervás +Juan RP Judson Bishop Juergen Wilke Jukka Pihl Julian Noble +Julian Ospald Julian Taylor Julien Chaffraix +Julien Nabet Julien Royer Jun-ichiro itojun Hagino Jurij Smakov +Juro Bystricky +Justin Clift +Justin Ehlert Justin Fletcher Justin Karneges +Justin Maggard +János Fekete Jörg Mueller-Tolk Jörn Hartroth +K. R. Walker Kai Engert +Kai Noda Kai Sommerfeld Kai-Uwe Rommel Kalle Vahlman Kamil Dudka +Kang Lin Kang-Jin Lee -Karl M Karl Moerder Karol Pietrzak +Kartik Mahajan Kaspar Brand Katie Wang +Kazuho Oku Kees Cook +Kees Dekker Keith MacDonald Keith McGuigan Keith Mok @@ -554,25 +873,38 @@ Kent Boortz Keshav Krity Kevin Baughman Kevin Fisk +Kevin Ji Kevin Lussier Kevin Reed Kevin Roth +Kevin Smith +Kim Minjoong Kim Rinnewitz Kim Vandry Kimmo Kinnunen Kjell Ericson Kjetil Jacobsen +Klaus Stein Klevtsov Vadim +Kobi Gurkan Konstantin Isakov Kris Kennaway Krishnendu Majumdar Krister Johansen Kristian Gunstone Kristian Köhntopp +Kristiyan Tsaklev +Kurt Fankhauser +Kyle J. McKay +Kyle L. Huff Kyle Sallee +Kyselgov E.N Lachlan O'Dea Larry Campbell Larry Fahnoe +Larry Lin +Larry Stefani +Larry Stone Lars Buitinck Lars Gustafsson Lars J. Aas @@ -581,46 +913,83 @@ Lars Nilsson Lars Torben Wilson Lau Hang Kin Laurent Rabret +Lauri Kasanen +Laurie Clark-Michalek +Lawrence Matthews +Lawrence Wagerfield Legoff Vincent Lehel Bernadt +Leif W +Leith Bade Len Krause Lenaic Lefever Lenny Rachitsky +Leon Winter +Leonardo Rosati Liam Healy Lijo Antony Linas Vepstas +Lindley French Ling Thio Linus Nielsen Feltzing +Linus Nordberg +Lior Kaplan Lisa Xu +Liviu Chircu Liza Alenchery +Lloyd Fournier LluÃs Batlle i Rossell Loic Dachary Loren Kirkby +Luan Cestari Luca Altea -Luca Alteas +Luca Boccassi Lucas Adamski +Lucas Pardue +Ludek Finstrle Ludovico Cavedon +Ludwig Nussel +Lukas Ruzicka Lukasz Czekierda Luke Amery Luke Call +Luke Dashjr +Luo Jinghua Luong Dinh Dung +Luz Paz +Luáºt Nguyá»…n +Lyndon Hill Maciej Karpiuk +Maciej Puzio Maciej W. Rozycki +Mahmoud Samir Fayed +Maks Naumov +Maksim Kuzevanov +Maksim Stsepanenka Mamoru Tasaka Mandy Wu Manfred Schwarb Manuel Massing +Marc Aldorasi Marc Boucher +Marc Deslauriers Marc Doughty -Marc Hoersken +Marc Hesse +Marc Hörsken Marc Kleine-Budde +Marc Renault +Marc-Antoine Perennou Marcel Raad Marcel Roelofs +Marcelo Echeverria Marcelo Juchem Marcin Adamski +Marcin Gryszkalis Marcin Konicki +Marco Deckel Marco G. Salvagno Marco Maggi +Marcus Hoffmann Marcus Sundberg Marcus Webster Mario Schroeder @@ -628,25 +997,35 @@ Mark Brand Mark Butler Mark Davies Mark Eichin +Mark Hamilton Mark Incley Mark Karpeles Mark Lentczner +Mark Nottingham Mark Salisbury Mark Snelling Mark Tully Markus Duft +Markus Elfring Markus Koetter Markus Moeller Markus Oberhumer +Markus Westerlind +Marquis de Muesli Martijn Koster Martin C. Martin Martin Drasar +Martin Dreher +Martin Frodl +Martin Galvan Martin Hager Martin Hedenfalk Martin Jansen +Martin Kepplinger Martin Lemke Martin Skinner -Martin Storsjo +Martin Storsjö +Martin Vejnár Marty Kuhrt Maruko Massimiliano Ziccardi @@ -655,150 +1034,241 @@ Mateusz Loskot Mathias Axelsson Mats Lidell Matt Arsenault +Matt Ford Matt Kraai Matt Veenstra Matt Witherspoon Matt Wixson +Matteo B. Matteo Rocco Matthew Blain Matthew Clarke +Matthew Hall +Matthew Kerwin Matthias Bolte +Mattias Fornander Maurice Barnum Mauro Iorio +Mauro Rappa +Max Dymond Max Katsev +Max Khon Maxim Ivanov Maxim Perenesenko Maxim Prohorov Maxime Larocque Mehmet Bozkurt Mekonikum +Melissa Mears Mettgut Jamalla Michael Benedict Michael Calmer Michael Cronenworth Michael Curtis Michael Day +Michael Felt +Michael Gmelin Michael Goffioul Michael Jahn Michael Jerris +Michael Kalinin +Michael Kaufmann +Michael Kilburn +Michael König +Michael Maltese Michael Mealling Michael Mueller +Michael Osipov Michael Smith +Michael Stapelberg Michael Stillwell Michael Wallner Michal Bonino -Michal Gorny -Michal Kowalczyk Michal Marek +Michal Trybus +MichaÅ‚ Fita +MichaÅ‚ Górny +MichaÅ‚ Janiszewski +MichaÅ‚ Kowalczyk +MichaÅ‚ Piechowski +Michel Promonet Michele Bini Miguel Angel +Miguel Diaz Mihai Ionescu Mikael Johansson Mikael Sennerholm +Mikalai Ananenka Mike Bytnar Mike Crowe Mike Dobbs Mike Giancola +Mike Hasselberg +Mike Henshaw Mike Hommey +Mike Mio Mike Power Mike Protts Mike Revi Miklos Nemeth +MiloÅ¡ Ljumović +Mingliang Zhu +Miroslav Franc +Miroslav Spousta Mitz Wark Mohamed Lrhazi +Mohammad AlSaleh Mohun Biswas -Moonesamy +Mostyn Bramley-Moore +Moti Avrahami +Muz Dima Myk Taylor Nach M. S. +Nagai H Nathan Coulter Nathan O'Sullivan Nathanael Nerode +Nathaniel Waisbrot Naveen Chandran Naveen Noel +Neal Poole +Nehal J Wani Neil Bowers Neil Dunbar +Neil Kolban Neil Spring Nic Roets Nicholas Maniscalco +Nick Draffen Nick Gimbrone Nick Humfrey +Nick Miyake Nick Zitzmann Nico Baggus Nicolas Berloquin Nicolas Croiset Nicolas François +Nicolas Morey-Chaisemartin Niels van Tongeren Nikita Schmidt Nikitinskit Dmitriy Niklas Angebrand Nikolai Kondrashov Nikos Mavrogiannopoulos +Nikos Tsipinakis Ning Dong Nir Soffer Nis Jorgensen +Nobuhiro Ban Nodak Sodak Norbert Frese +Norbert Kett Norbert Novotny +Octavio Schroeder Ofer +Okhin Vasilij +Ola Mork Olaf Flebbe -Olaf Stueben Olaf Stüben +Oleg Pudeyev +Oli Kingshott Oliver Gondža +Oliver Graute +Oliver Kuckertz +Oliver Schindler Olivier Berger +Olivier Brunel +Orange Tsai +Oren Souroujon Oren Tirosh +Orgad Shaneh Ori Avtalion Oscar Koeroo Oscar Norlander +Oumph on github P R Schaffner +Palo Markovic Paolo Piacentini +Paras Sethia +Pascal Gaudette Pascal Terjan Pasha Kuznetsov +Pasi Karkkainen Pat Ray Patrice Guerin Patricia Muscalu Patrick Bihan-Faou +Patrick Dawson +Patrick McManus Patrick Monnerat +Patrick Rapin +Patrick Schlangen Patrick Scott Patrick Smith +Patrick Watson Patrik Thunstrom Pau Garcia i Quiles +Paul Donohue Paul Harrington +Paul Harris Paul Howarth +Paul Joyce +Paul Marks Paul Marquis Paul Moore Paul Nolan +Paul Oliver Paul Querna +Paul Saab Pavel Cenek +Pavel Gushchin Pavel Orehov +Pavel Pavlov Pavel Raiskup +Pavel Rochnyak +Pavol Markovic Pawel A. Gajda Pawel Kierski Pedro Larroy Pedro Neves -Pete Su +Per Lundberg +Per Malmberg +Pete Lomax Peter Bray Peter Forret +Peter Frühberger Peter Gal Peter Heuchert Peter Hjalmarsson Peter Korsgaard +Peter Lamare Peter Lamberg +Peter Laser Peter O'Gorman Peter Pentchev +Peter Piekarski Peter Silva Peter Su Peter Sylvester Peter Todd Peter Verhas +Peter Wang +Peter Wu Peter Wullinger Peteris Krumins +Petr Bahula +Petr Novak +Petr Pisar +Petr Voytsik Phil Blundell +Phil Crump Phil Karn Phil Lisiecki Phil Pellouchoud Philip Craig Philip Gladstone Philip Langdale +Philip Prindeville Philippe Hameau Philippe Raoult Philippe Vaucher @@ -807,51 +1277,85 @@ Pierre Brico Pierre Chapuis Pierre Joye Pierre Ynard +Piotr Dobrogost Pooyan McSporran Pramod Sharma +Prash Dush +Praveen Pvs +Priyanka Shah Puneet Pawaia Quagmire Quanah Gibson-Mount Quinn Slack +R. Dennis Steed +Radu Simionescu Rafa Muyo +Rafael Antonio Rafael Sagula +Rafayel Mkrtchyan +Rafaël Carré Rainer Canavan Rainer Jung Rainer Koenig +Rainer Müller Rajesh Naganathan +Rajkumar Mandal Ralf S. Engelschall Ralph Beckmann Ralph Mitchell Ramana Mokkapati +Randall S. Becker +Randy Armstrong Randy McMurchy Ravi Pratap Ray Dassen Ray Pekowski +Ray Satiro +Razvan Cojocaru +Reinhard Max Reinout van Schouwen +Remi Gacogne +Remo E Renato Botelho Renaud Chaillat Renaud Duhaut Renaud Guillard +Renaud Lehoux Rene Bernhardt Rene Rebe Reuven Wachtfogel Reza Arbab Ricardo Cadime +Rich Burridge Rich Gray Rich Rauenzahn +Richard Alcock Richard Archer Richard Atterer Richard Bramante Richard Clayton Richard Cooper Richard Gorton +Richard Gray +Richard Hosking +Richard Hsu Richard Michael +Richard Moore Richard Prescott Richard Silverman +Richard van den Berg +Richy Kim +Rick Deist Rick Jones Rick Richardson +Ricki Hirner +Rider Linden +Rikard Falkeborn +Rob Cotrone Rob Crittenden +Rob Davies Rob Jones +Rob Sanders Rob Stanzel Rob Ward Robert A. Monat @@ -859,6 +1363,7 @@ Robert B. Harris Robert D. Young Robert Foreman Robert Iakobashvili +Robert Kolcun Robert Olson Robert Schumann Robert Weaver @@ -867,28 +1372,46 @@ Robin Cornelius Robin Johnson Robin Kay Robson Braga Araujo +Rod Widdowson Rodney Simmons +Rodric Glaser Rodrigo Silva +Roger Leigh Roland Blom Roland Krikava Roland Zimmermann Rolland Dudemaine +Romain Coltel Roman Koifman Roman Mamedov +Romulo A. Ceccon +Ron Eldor +Ron Parker Ron Zapp +Ronnie Mose Rosimildo da Silva Roy Shan Rune Kleveland Ruslan Gazizov Rutger Hofman +Ruurd Beerstra +Ryan Braud Ryan Chan Ryan Nelson Ryan Schmidt +Ryan Scott +Ryan Winograd +Ryuichi KAWAMATA +Rémy Léone S. Moonesamy +SBKarr on github +Salah-Eddin Shaban Salvador Dávila Salvatore Sorrentino Sam Deane -Sam Listopad +Sam Hurst +Sam Roth +Sam Schanken Sampo Kellomaki Samuel DÃaz GarcÃa Samuel Listopad @@ -899,49 +1422,82 @@ Santhana Todatry Saqib Ali Sara Golemon Saran Neti +Sascha Swiercy Saul good +Saurav Babu Scott Bailey Scott Barrett Scott Cantor Scott Davis Scott McCreary +Sean Boudreau +Sean Burford +Sean MacLennan +Sebastian Mundry +Sebastian Pohlschmidt Sebastian Rasmussen -Sebastien Willemijns Senthil Raja Velu +Sergei Kuzmin Sergei Nikulov +Sergey Tatarincev +Sergii Kavunenko +Sergii Pylypenko Sergio Ballestrero +Sergio Borghese +Serj Kalichev Seshubabu Pasam +Seth Mos Sh Diao +Shachaf Ben-Kiki +Shao Shuchao Sharad Gupta Shard +Shawn Landden Shawn Poulson +Shine Fan Shmulik Regev Siddhartha Prakash Jain -Sidney San Martin +Sidney San MartÃn Siegfried Gyuricsko Simon Dick +Simon H. Simon Josefsson Simon Liu +Simon Warta +Somnath Kundu Song Ma Sonia Subramanian Spacen Jasset Spiridonoff A.V +Spork Schivago Stadler Stephan Stan van de Burgt Stanislav Ivochkin +Stanislav Zidek +Stefan Agner +Stefan Bühler +Stefan Eissing Stefan Esser +Stefan Kanthak Stefan Krause Stefan Neis Stefan Teleman Stefan Tomanek Stefan Ulrich +Steinar H. Gunderson +Stepan Broz Stephan Bergmann +Stephan Mühlstrasser +Stephen Brokenshire Stephen Collyer Stephen Kick Stephen More +Stephen Toub Sterling Hughes +Steve Brokenshire Steve Green Steve H Truong +Steve Havelka Steve Holme Steve Lhomme Steve Little @@ -954,22 +1510,42 @@ Steven Gu Steven M. Schweda Steven Parkes Stoned Elipot +Stuart Henderson +Sune Ahlgren +Sunny Purushe Sven Anders Sven Neuhaus Sven Wegener +Svyatoslav Mishyn +Sylvestre Ledru +Symeon Paraschoudis Sébastien Willemijns T. Bharath T. Yamada -Taneli Vahakangas +TJ Saunders +Tae Hyoung Ahn +Taneli Vähäkangas Tanguy Fautre Tatsuhiro Tsujikawa Temprimus +Terri Oda +Terry Wu +TheAssassin on github +Theodore Dubois +Thomas Braun +Thomas Glanzmann Thomas J. Moore Thomas Klausner Thomas L. Shinnick Thomas Lopatic +Thomas Petazzoni +Thomas Ruecker Thomas Schwinge Thomas Tonino +Thomas van Hesteren +Thorsten Schöning +Tiit Pikma +Till Maas Tim Ansell Tim Baker Tim Bartley @@ -977,15 +1553,24 @@ Tim Chen Tim Costello Tim Harder Tim Heckman +Tim Mcdonough Tim Newsome +Tim Rühsen Tim Sneddon +Tim Stack +Tim Starling Timo Sirainen +Timotej Lazar +Timothe Litt +Timothy Polich Tinus van den Berg +Tobias Markus Tobias Rundström +Tobias Stoeckmann Toby Peterson Todd A Ouska Todd Kulesza -Todd Ouska +Todd Short Todd Vierling Tom Benoist Tom Donovan @@ -995,32 +1580,54 @@ Tom Mattison Tom Moers Tom Mueller Tom Regner +Tom Seddon +Tom Sparrow Tom Wright Tom Zerucha +Tomas Hoger +Tomas Jakobsson Tomas Mlcoch +Tomas Mraz Tomas Pospisek Tomas Szepe +Tomas Tomecek +Tomasz Kojm Tomasz Lacki Tommie Gannert Tommy Tam Ton Voon Toni Moreno +Tony Kelman Toon Verwaest Tor Arntsen +Torben Dannhauer Torsten Foertsch Toshio Kuratomi Toshiyuki Maezawa Traian Nicolescu +Travis Burtrum +Travis Obenhaus Troels Walsted Hansen Troy Engel Tupone Alfredo +Tyler Hall +Török Edwin Ulf Härnhammar +Ulf Samuelsson Ulrich Doehner +Ulrich Telle Ulrich Zadow +Valentin David +Vasy Okhin Venkat Akella +Venkataramana Mokkapati Victor Snezhko +Vijay Panghal Vikram Saxena +Viktor Szakats +Ville Skyttä Vilmos Nebehaj +Vincas Razma Vincent Bronner Vincent Le Normand Vincent Penquerc'h @@ -1032,32 +1639,109 @@ Vladimir Grishchenko Vladimir Lazarenko Vojtech Janota Vojtech Minarik +VojtÄ›ch Král Vsevolod Novikov +W. Mark Kubacki +Waldek Kozba Walter J. Mack Ward Willats +Warp Kawada +Warren Menzer Wayne Haigh Werner Koch Wesley Laxton Wesley Miaw Wez Furlong +Wham Bang Wilfredo Sanchez +Will Dietz Willem Sparreboom +William Ahern Wojciech Zwiefka Wouter Van Rooy Wu Yongzheng +Wyatt O'Day Xavier Bouchoux +XhstormR on github +Xiangbin Li +Yaakov Selkowitz Yamada Yasuharu Yang Tse Yarram Sunil +Yasuharu Yamada +Yehezkel Horowitz Yehoshua Hershberg +Yi Huang +Yingwei Liu +Yonggang Luo +Yousuke Kimoto Yukihiro Kawada +Yun SangHo Yuriy Sosov Yves Arrouye Yves Lejeune +Zachary Seguin Zdenek Pavlas Zekun Ni +Zenju on github +Zhouyihai Ding Zmey Petroff Zvi Har'El +afrind on github +ahodesuka on github +anshnd on github +arainchik on github +asavah on github +baumanj on github +bsammon on github +cbartl on github +cmfrolick on github +dasimx on github +destman on github +dkjjr89 on github +dpull on github +eXeC64 on github +elelel on github +guitared on github +hsiao yi +imilli on github +iz8mbw on github +jonrumsey on github +joshhe on github +jungle-boogie on github +jveazey on github +ka7 on github +kreshano on github +lijian996 on github +lukaszgn on github +madblobfish on github +marc-groundctl on github +mccormickt12 on github +mkzero on github +moohoorama on github +neex on github +neheb on github nk +nopjmp on github +olesteban on github +omau on github +ovidiu-benea on github +patelvivekv1993 on github +paulharris on github +silveja1 on github +steelman on github +steini2000 on github +stootill on github swalkaus at yahoo.com +tarek112 on github tommink[at]post.pl +vanillajonathan on github +wmsch on github +wncboy on github +wyattoday on github +youngchopin on github +zelinchen on github +Ä°smail Dönmez +Åukasz Domeradzki +Å tefan Kremeň +Ðикита Дорохин diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h index 9ad5c20dfe..3fd4ca87d3 100644 --- a/libs/libcurl/include/curl/curl.h +++ b/libs/libcurl/include/curl/curl.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -245,7 +245,9 @@ typedef size_t (*curl_write_callback)(char *buffer, size_t nitems, void *outstream); - +/* This callback will be called when a new resolver request is made */ +typedef int (*curl_resolver_start_callback)(void *resolver_state, + void *reserved, void *userdata); /* enumeration of file types */ typedef enum { @@ -577,6 +579,8 @@ typedef enum { CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer */ + CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from + inside a callback */ CURL_LAST /* never use! */ } CURLcode; @@ -715,6 +719,7 @@ typedef enum { #define CURLSSH_AUTH_HOST (1<<2) /* host key files */ #define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ #define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ #define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY #define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ @@ -727,7 +732,9 @@ enum curl_khtype { CURLKHTYPE_UNKNOWN, CURLKHTYPE_RSA1, CURLKHTYPE_RSA, - CURLKHTYPE_DSS + CURLKHTYPE_DSS, + CURLKHTYPE_ECDSA, + CURLKHTYPE_ED25519 }; struct curl_khkey { @@ -786,6 +793,11 @@ typedef enum { SSL backends where such behavior is present. */ #define CURLSSLOPT_NO_REVOKE (1<<1) +/* The default connection attempt delay in milliseconds for happy eyeballs. + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document + this value, keep them in sync. */ +#define CURL_HET_DEFAULT 200L + #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all the obsolete stuff removed! */ @@ -935,7 +947,7 @@ typedef enum { CINIT(READDATA, OBJECTPOINT, 9), /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. If this is not used, error messages go to stderr instead: */ + * bytes big. */ CINIT(ERRORBUFFER, OBJECTPOINT, 10), /* Function that will be called to store the output (instead of fwrite). The @@ -1659,7 +1671,7 @@ typedef enum { * Only supported by the c-ares DNS backend */ CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), - /* Set the local IPv4 address to use for outgoing DNS requests. + /* Set the local IPv6 address to use for outgoing DNS requests. * Only supported by the c-ares DNS backend */ CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), @@ -1816,6 +1828,25 @@ typedef enum { /* Post MIME data. */ CINIT(MIMEPOST, OBJECTPOINT, 269), + /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of + seconds since 1 Jan 1970. */ + CINIT(TIMEVALUE_LARGE, OFF_T, 270), + + /* Head start in milliseconds to give happy eyeballs. */ + CINIT(HAPPY_EYEBALLS_TIMEOUT_MS, LONG, 271), + + /* Function that will be called before a resolver request is made */ + CINIT(RESOLVER_START_FUNCTION, FUNCTIONPOINT, 272), + + /* User data to pass to the resolver start callback. */ + CINIT(RESOLVER_START_DATA, OBJECTPOINT, 273), + + /* send HAProxy PROXY protocol header? */ + CINIT(HAPROXYPROTOCOL, LONG, 274), + + /* shuffle addresses before use when DNS returns multiple */ + CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -2456,6 +2487,7 @@ typedef enum { CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index 30b1463078..17831025c8 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,16 +26,16 @@ a script at release-time. This was made its own header file in 7.11.2 */ /* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel@haxx.se>." +#define LIBCURL_COPYRIGHT "1996 - 2018 Daniel Stenberg, <daniel@haxx.se>." /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.57.0" +#define LIBCURL_VERSION "7.60.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 57 +#define LIBCURL_VERSION_MINOR 60 #define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier @@ -57,7 +57,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x073900 +#define LIBCURL_VERSION_NUM 0x073c00 /* * This is the date and time when the full source package was created. The @@ -68,7 +68,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2017-11-29" +#define LIBCURL_TIMESTAMP "2018-05-16" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/libs/libcurl/include/curl/multi.h b/libs/libcurl/include/curl/multi.h index 911c91dd1a..b19dbaf791 100644 --- a/libs/libcurl/include/curl/multi.h +++ b/libs/libcurl/include/curl/multi.h @@ -70,6 +70,8 @@ typedef enum { CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was attempted to get added - again */ + CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a + callback */ CURLM_LAST } CURLMcode; @@ -184,8 +186,8 @@ CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, * * Returns: CURLMcode type, general multi error code. *NOTE* that this only * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. + * still have occurred problems on individual transfers even when + * this returns OK. */ CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles); diff --git a/libs/libcurl/include/curl/system.h b/libs/libcurl/include/curl/system.h index 39dae754cd..eac4cfeb66 100644 --- a/libs/libcurl/include/curl/system.h +++ b/libs/libcurl/include/curl/system.h @@ -300,7 +300,9 @@ #elif defined(__SUNPRO_C) /* Oracle Solaris Studio */ # if !defined(__LP64) && (defined(__ILP32) || \ - defined(__i386) || defined(__sparcv8)) + defined(__i386) || \ + defined(__sparcv8) || \ + defined(__sparcv8plus)) # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -348,7 +350,8 @@ defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ defined(__XTENSA__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4)) + (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ + (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -356,7 +359,8 @@ # define CURL_SUFFIX_CURL_OFF_TU ULL # elif defined(__LP64__) || \ defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) + (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ + (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) # define CURL_TYPEOF_CURL_OFF_T long # define CURL_FORMAT_CURL_OFF_T "ld" # define CURL_FORMAT_CURL_OFF_TU "lu" diff --git a/libs/libcurl/include/curl/typecheck-gcc.h b/libs/libcurl/include/curl/typecheck-gcc.h index 10c74c764c..3a0f253f61 100644 --- a/libs/libcurl/include/curl/typecheck-gcc.h +++ b/libs/libcurl/include/curl/typecheck-gcc.h @@ -54,6 +54,9 @@ __extension__ ({ \ if(_curl_is_write_cb_option(_curl_opt)) \ if(!_curl_is_write_cb(value)) \ _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \ + if(!_curl_is_resolver_start_callback(value)) \ + _curl_easy_setopt_err_resolver_start_callback(); \ if((_curl_opt) == CURLOPT_READFUNCTION) \ if(!_curl_is_read_cb(value)) \ _curl_easy_setopt_err_read_cb(); \ @@ -170,6 +173,10 @@ _CURL_WARNING(_curl_easy_setopt_err_string, ) _CURL_WARNING(_curl_easy_setopt_err_write_callback, "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_resolver_start_callback, + "curl_easy_setopt expects a " + "curl_resolver_start_callback argument for this option" + ) _CURL_WARNING(_curl_easy_setopt_err_read_cb, "curl_easy_setopt expects a curl_read_callback argument for this option") _CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, @@ -354,6 +361,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, (option) == CURLOPT_SSH_KEYDATA || \ (option) == CURLOPT_SSL_CTX_DATA || \ (option) == CURLOPT_WRITEDATA || \ + (option) == CURLOPT_RESOLVER_START_DATA || \ 0) /* evaluates to true if option takes a POST data argument (void* or char*) */ @@ -504,6 +512,11 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, (__builtin_types_compatible_p(__typeof__(func), type) || \ __builtin_types_compatible_p(__typeof__(func) *, type)) +/* evaluates to true if expr is of type curl_resolver_start_callback */ +#define _curl_is_resolver_start_callback(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_resolver_start_callback)) + /* evaluates to true if expr is of type curl_read_callback or "similar" */ #define _curl_is_read_cb(expr) \ (_curl_is_NULL(expr) || \ diff --git a/libs/libcurl/src/Makefile.am b/libs/libcurl/src/Makefile.am index 151c2615e5..87c64f3a8e 100644 --- a/libs/libcurl/src/Makefile.am +++ b/libs/libcurl/src/Makefile.am @@ -106,6 +106,8 @@ endif if CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS libcurl_la_LDFLAGS_EXTRA += -Wl,--version-script=libcurl.vers +else +libcurl_la_LDFLAGS_EXTRA += -export-symbols-regex '^curl_.*' endif if USE_CPPFLAG_CURL_STATICLIB diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index 545b630d37..93a55307b7 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -21,7 +21,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -117,9 +117,10 @@ host_triplet = @host@ @CURL_LT_SHLIB_USE_NO_UNDEFINED_TRUE@am__append_3 = -no-undefined @CURL_LT_SHLIB_USE_MIMPURE_TEXT_TRUE@am__append_4 = -mimpure-text @CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_TRUE@am__append_5 = -Wl,--version-script=libcurl.vers -@USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_6 = -DCURL_STATICLIB -@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_7 = -DCURL_HIDDEN_SYMBOLS -@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_8 = $(CFLAG_CURL_SYMBOL_HIDING) +@CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_FALSE@am__append_6 = -export-symbols-regex '^curl_.*' +@USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_7 = -DCURL_STATICLIB +@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_8 = -DCURL_HIDDEN_SYMBOLS +@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_9 = $(CFLAG_CURL_SYMBOL_HIDING) subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ @@ -203,7 +204,7 @@ am__objects_1 = libcurl_la-file.lo libcurl_la-timeval.lo \ libcurl_la-hostsyn.lo libcurl_la-inet_ntop.lo \ libcurl_la-parsedate.lo libcurl_la-select.lo \ libcurl_la-tftp.lo libcurl_la-splay.lo libcurl_la-strdup.lo \ - libcurl_la-socks.lo libcurl_la-ssh.lo \ + libcurl_la-socks.lo libcurl_la-ssh.lo libcurl_la-ssh-libssh.lo \ libcurl_la-curl_addrinfo.lo libcurl_la-socks_gssapi.lo \ libcurl_la-socks_sspi.lo libcurl_la-curl_sspi.lo \ libcurl_la-slist.lo libcurl_la-nonblock.lo \ @@ -224,7 +225,9 @@ am__objects_1 = libcurl_la-file.lo libcurl_la-timeval.lo \ libcurl_la-x509asn1.lo libcurl_la-http2.lo libcurl_la-smb.lo \ libcurl_la-curl_endian.lo libcurl_la-curl_des.lo \ libcurl_la-system_win32.lo libcurl_la-mime.lo \ - libcurl_la-sha256.lo libcurl_la-setopt.lo + libcurl_la-sha256.lo libcurl_la-setopt.lo \ + libcurl_la-curl_path.lo libcurl_la-curl_ctype.lo \ + libcurl_la-curl_range.lo am__dirstamp = $(am__leading_dot)dirstamp am__objects_2 = vauth/libcurl_la-vauth.lo \ vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \ @@ -238,8 +241,9 @@ am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.lo \ vtls/libcurl_la-polarssl.lo \ vtls/libcurl_la-polarssl_threadlock.lo \ vtls/libcurl_la-axtls.lo vtls/libcurl_la-cyassl.lo \ - vtls/libcurl_la-schannel.lo vtls/libcurl_la-darwinssl.lo \ - vtls/libcurl_la-gskit.lo vtls/libcurl_la-mbedtls.lo + vtls/libcurl_la-schannel.lo vtls/libcurl_la-schannel_verify.lo \ + vtls/libcurl_la-darwinssl.lo vtls/libcurl_la-gskit.lo \ + vtls/libcurl_la-mbedtls.lo am__objects_4 = $(am__objects_1) $(am__objects_2) $(am__objects_3) am__objects_5 = am__objects_6 = $(am__objects_5) $(am__objects_5) $(am__objects_5) @@ -281,11 +285,11 @@ am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \ libcurlu_la-inet_ntop.lo libcurlu_la-parsedate.lo \ libcurlu_la-select.lo libcurlu_la-tftp.lo libcurlu_la-splay.lo \ libcurlu_la-strdup.lo libcurlu_la-socks.lo libcurlu_la-ssh.lo \ - libcurlu_la-curl_addrinfo.lo libcurlu_la-socks_gssapi.lo \ - libcurlu_la-socks_sspi.lo libcurlu_la-curl_sspi.lo \ - libcurlu_la-slist.lo libcurlu_la-nonblock.lo \ - libcurlu_la-curl_memrchr.lo libcurlu_la-imap.lo \ - libcurlu_la-pop3.lo libcurlu_la-smtp.lo \ + libcurlu_la-ssh-libssh.lo libcurlu_la-curl_addrinfo.lo \ + libcurlu_la-socks_gssapi.lo libcurlu_la-socks_sspi.lo \ + libcurlu_la-curl_sspi.lo libcurlu_la-slist.lo \ + libcurlu_la-nonblock.lo libcurlu_la-curl_memrchr.lo \ + libcurlu_la-imap.lo libcurlu_la-pop3.lo libcurlu_la-smtp.lo \ libcurlu_la-pingpong.lo libcurlu_la-rtsp.lo \ libcurlu_la-curl_threads.lo libcurlu_la-warnless.lo \ libcurlu_la-hmac.lo libcurlu_la-curl_rtmp.lo \ @@ -302,7 +306,9 @@ am__objects_7 = libcurlu_la-file.lo libcurlu_la-timeval.lo \ libcurlu_la-http2.lo libcurlu_la-smb.lo \ libcurlu_la-curl_endian.lo libcurlu_la-curl_des.lo \ libcurlu_la-system_win32.lo libcurlu_la-mime.lo \ - libcurlu_la-sha256.lo libcurlu_la-setopt.lo + libcurlu_la-sha256.lo libcurlu_la-setopt.lo \ + libcurlu_la-curl_path.lo libcurlu_la-curl_ctype.lo \ + libcurlu_la-curl_range.lo am__objects_8 = vauth/libcurlu_la-vauth.lo \ vauth/libcurlu_la-cleartext.lo vauth/libcurlu_la-cram.lo \ vauth/libcurlu_la-digest.lo vauth/libcurlu_la-digest_sspi.lo \ @@ -316,8 +322,10 @@ am__objects_9 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \ vtls/libcurlu_la-polarssl.lo \ vtls/libcurlu_la-polarssl_threadlock.lo \ vtls/libcurlu_la-axtls.lo vtls/libcurlu_la-cyassl.lo \ - vtls/libcurlu_la-schannel.lo vtls/libcurlu_la-darwinssl.lo \ - vtls/libcurlu_la-gskit.lo vtls/libcurlu_la-mbedtls.lo + vtls/libcurlu_la-schannel.lo \ + vtls/libcurlu_la-schannel_verify.lo \ + vtls/libcurlu_la-darwinssl.lo vtls/libcurlu_la-gskit.lo \ + vtls/libcurlu_la-mbedtls.lo am__objects_10 = $(am__objects_7) $(am__objects_8) $(am__objects_9) am_libcurlu_la_OBJECTS = $(am__objects_10) $(am__objects_6) libcurlu_la_OBJECTS = $(am_libcurlu_la_OBJECTS) @@ -516,6 +524,7 @@ REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SSL_BACKENDS = @SSL_BACKENDS@ SSL_ENABLED = @SSL_ENABLED@ SSL_LIBS = @SSL_LIBS@ STRIP = @STRIP@ @@ -528,6 +537,7 @@ USE_DARWINSSL = @USE_DARWINSSL@ USE_GNUTLS = @USE_GNUTLS@ USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ USE_LIBRTMP = @USE_LIBRTMP@ +USE_LIBSSH = @USE_LIBSSH@ USE_LIBSSH2 = @USE_LIBSSH2@ USE_MBEDTLS = @USE_MBEDTLS@ USE_NGHTTP2 = @USE_NGHTTP2@ @@ -660,10 +670,11 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ VERSIONINFO = -version-info 9:0:5 AM_LDFLAGS = AM_CFLAGS = -libcurl_la_CPPFLAGS_EXTRA = $(am__append_6) $(am__append_7) +libcurl_la_CPPFLAGS_EXTRA = $(am__append_7) $(am__append_8) libcurl_la_LDFLAGS_EXTRA = $(CODE_COVERAGE_LDFLAGS) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) -libcurl_la_CFLAGS_EXTRA = $(CODE_COVERAGE_CFLAGS) $(am__append_8) + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) +libcurl_la_CFLAGS_EXTRA = $(CODE_COVERAGE_CFLAGS) $(am__append_9) libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS) libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) @@ -678,8 +689,8 @@ LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \ - vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c \ - vtls/mbedtls.c + vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \ + vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \ @@ -695,7 +706,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \ strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \ inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \ - ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ + ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \ pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \ openldap.c curl_gethostname.c gopher.c idn_win32.c \ @@ -703,7 +714,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \ curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \ x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ - mime.c sha256.c setopt.c + mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ @@ -722,7 +733,8 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \ curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \ x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ - curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h + curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ + curl_path.h curl_ctype.h curl_range.h LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) @@ -883,6 +895,8 @@ vtls/libcurl_la-cyassl.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-schannel.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-schannel_verify.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-darwinssl.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-gskit.lo: vtls/$(am__dirstamp) \ @@ -934,6 +948,8 @@ vtls/libcurlu_la-cyassl.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-schannel.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-schannel_verify.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-darwinssl.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-gskit.lo: vtls/$(am__dirstamp) \ @@ -963,6 +979,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-content_encoding.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-cookie.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ctype.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_des.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_endian.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo@am__quote@ @@ -972,6 +989,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_multibyte.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ntlm_core.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ntlm_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_path.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_range.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_rtmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_sasl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_sspi.Plo@am__quote@ @@ -1042,6 +1061,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-socks_sspi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-speedcheck.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-splay.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ssh-libssh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ssh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strcase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-strdup.Plo@am__quote@ @@ -1067,6 +1087,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-content_encoding.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-cookie.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ctype.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_des.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_endian.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo@am__quote@ @@ -1076,6 +1097,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_multibyte.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ntlm_core.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ntlm_wb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_path.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_range.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_rtmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_sasl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_sspi.Plo@am__quote@ @@ -1146,6 +1169,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-socks_sspi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-speedcheck.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-splay.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ssh-libssh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ssh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strcase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-strdup.Plo@am__quote@ @@ -1197,6 +1221,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-polarssl_threadlock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-vtls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-axtls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-cyassl.Plo@am__quote@ @@ -1209,6 +1234,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-polarssl_threadlock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-vtls.Plo@am__quote@ .c.o: @@ -1655,6 +1681,13 @@ libcurl_la-ssh.lo: ssh.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c +libcurl_la-ssh-libssh.lo: ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ssh-libssh.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ssh-libssh.Tpo -c -o libcurl_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ssh-libssh.Tpo $(DEPDIR)/libcurl_la-ssh-libssh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssh-libssh.c' object='libcurl_la-ssh-libssh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c + libcurl_la-curl_addrinfo.lo: curl_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_addrinfo.Tpo -c -o libcurl_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_addrinfo.Tpo $(DEPDIR)/libcurl_la-curl_addrinfo.Plo @@ -1963,6 +1996,27 @@ libcurl_la-setopt.lo: setopt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-setopt.lo `test -f 'setopt.c' || echo '$(srcdir)/'`setopt.c +libcurl_la-curl_path.lo: curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_path.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_path.Tpo -c -o libcurl_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_path.Tpo $(DEPDIR)/libcurl_la-curl_path.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_path.c' object='libcurl_la-curl_path.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c + +libcurl_la-curl_ctype.lo: curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_ctype.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_ctype.Tpo -c -o libcurl_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_ctype.Tpo $(DEPDIR)/libcurl_la-curl_ctype.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ctype.c' object='libcurl_la-curl_ctype.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c + +libcurl_la-curl_range.lo: curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_range.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_range.Tpo -c -o libcurl_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_range.Tpo $(DEPDIR)/libcurl_la-curl_range.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_range.c' object='libcurl_la-curl_range.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c + vauth/libcurl_la-vauth.lo: vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-vauth.Tpo -c -o vauth/libcurl_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-vauth.Tpo vauth/$(DEPDIR)/libcurl_la-vauth.Plo @@ -2110,6 +2164,13 @@ vtls/libcurl_la-schannel.lo: vtls/schannel.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c +vtls/libcurl_la-schannel_verify.lo: vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-schannel_verify.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-schannel_verify.Tpo -c -o vtls/libcurl_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-schannel_verify.Tpo vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/schannel_verify.c' object='vtls/libcurl_la-schannel_verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurl_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c + vtls/libcurl_la-darwinssl.lo: vtls/darwinssl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vtls/libcurl_la-darwinssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-darwinssl.Tpo -c -o vtls/libcurl_la-darwinssl.lo `test -f 'vtls/darwinssl.c' || echo '$(srcdir)/'`vtls/darwinssl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-darwinssl.Tpo vtls/$(DEPDIR)/libcurl_la-darwinssl.Plo @@ -2551,6 +2612,13 @@ libcurlu_la-ssh.lo: ssh.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ssh.lo `test -f 'ssh.c' || echo '$(srcdir)/'`ssh.c +libcurlu_la-ssh-libssh.lo: ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ssh-libssh.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ssh-libssh.Tpo -c -o libcurlu_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ssh-libssh.Tpo $(DEPDIR)/libcurlu_la-ssh-libssh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ssh-libssh.c' object='libcurlu_la-ssh-libssh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ssh-libssh.lo `test -f 'ssh-libssh.c' || echo '$(srcdir)/'`ssh-libssh.c + libcurlu_la-curl_addrinfo.lo: curl_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_addrinfo.Tpo -c -o libcurlu_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_addrinfo.Tpo $(DEPDIR)/libcurlu_la-curl_addrinfo.Plo @@ -2859,6 +2927,27 @@ libcurlu_la-setopt.lo: setopt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-setopt.lo `test -f 'setopt.c' || echo '$(srcdir)/'`setopt.c +libcurlu_la-curl_path.lo: curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_path.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_path.Tpo -c -o libcurlu_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_path.Tpo $(DEPDIR)/libcurlu_la-curl_path.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_path.c' object='libcurlu_la-curl_path.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_path.lo `test -f 'curl_path.c' || echo '$(srcdir)/'`curl_path.c + +libcurlu_la-curl_ctype.lo: curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_ctype.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_ctype.Tpo -c -o libcurlu_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_ctype.Tpo $(DEPDIR)/libcurlu_la-curl_ctype.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ctype.c' object='libcurlu_la-curl_ctype.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c + +libcurlu_la-curl_range.lo: curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_range.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_range.Tpo -c -o libcurlu_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_range.Tpo $(DEPDIR)/libcurlu_la-curl_range.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_range.c' object='libcurlu_la-curl_range.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_range.lo `test -f 'curl_range.c' || echo '$(srcdir)/'`curl_range.c + vauth/libcurlu_la-vauth.lo: vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-vauth.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo -c -o vauth/libcurlu_la-vauth.lo `test -f 'vauth/vauth.c' || echo '$(srcdir)/'`vauth/vauth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-vauth.Tpo vauth/$(DEPDIR)/libcurlu_la-vauth.Plo @@ -3006,6 +3095,13 @@ vtls/libcurlu_la-schannel.lo: vtls/schannel.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c +vtls/libcurlu_la-schannel_verify.lo: vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-schannel_verify.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Tpo -c -o vtls/libcurlu_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Tpo vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/schannel_verify.c' object='vtls/libcurlu_la-schannel_verify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o vtls/libcurlu_la-schannel_verify.lo `test -f 'vtls/schannel_verify.c' || echo '$(srcdir)/'`vtls/schannel_verify.c + vtls/libcurlu_la-darwinssl.lo: vtls/darwinssl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vtls/libcurlu_la-darwinssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-darwinssl.Tpo -c -o vtls/libcurlu_la-darwinssl.lo `test -f 'vtls/darwinssl.c' || echo '$(srcdir)/'`vtls/darwinssl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-darwinssl.Tpo vtls/$(DEPDIR)/libcurlu_la-darwinssl.Plo diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index 0a88b8eb80..61c23411df 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -29,8 +29,8 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \ - vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c \ - vtls/mbedtls.c + vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \ + vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \ @@ -46,7 +46,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \ strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \ inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \ - ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ + ssh.c ssh-libssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \ curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \ pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \ openldap.c curl_gethostname.c gopher.c idn_win32.c \ @@ -54,7 +54,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \ curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \ x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ - mime.c sha256.c setopt.c + mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ @@ -73,7 +73,8 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \ curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \ x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ - curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h + curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ + curl_path.h curl_ctype.h curl_range.h LIB_RCFILES = libcurl.rc diff --git a/libs/libcurl/src/Makefile.netware b/libs/libcurl/src/Makefile.netware index a4ec4c8f38..f4b6528eb9 100644 --- a/libs/libcurl/src/Makefile.netware +++ b/libs/libcurl/src/Makefile.netware @@ -589,7 +589,6 @@ endif @echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@ @echo $(DL)#define HAVE_IOCTL 1$(DL) >> $@ @echo $(DL)#define HAVE_IOCTL_FIONBIO 1$(DL) >> $@ - @echo $(DL)#define HAVE_LIMITS_H 1$(DL) >> $@ @echo $(DL)#define HAVE_LL 1$(DL) >> $@ @echo $(DL)#define HAVE_LOCALE_H 1$(DL) >> $@ @echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@ diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c index 38ede999ce..aa581a49a0 100644 --- a/libs/libcurl/src/asyn-ares.c +++ b/libs/libcurl/src/asyn-ares.c @@ -30,9 +30,7 @@ #ifdef CURLRES_ARES -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index 1ac3fc809f..b11fab2468 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -79,6 +79,10 @@ #include "curl_memory.h" #include "memdebug.h" +struct resdata { + struct curltime start; +}; + /* * Curl_resolver_global_init() * Called from curl_global_init() to initialize global resolver environment. @@ -102,11 +106,13 @@ void Curl_resolver_global_cleanup(void) * Curl_resolver_init() * Called from curl_easy_init() -> Curl_open() to initialize resolver * URL-state specific environment ('resolver' member of the UrlState - * structure). Does nothing here. + * structure). */ CURLcode Curl_resolver_init(void **resolver) { - (void)resolver; + *resolver = calloc(1, sizeof(struct resdata)); + if(!*resolver) + return CURLE_OUT_OF_MEMORY; return CURLE_OK; } @@ -114,24 +120,22 @@ CURLcode Curl_resolver_init(void **resolver) * Curl_resolver_cleanup() * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver * URL-state specific environment ('resolver' member of the UrlState - * structure). Does nothing here. + * structure). */ void Curl_resolver_cleanup(void *resolver) { - (void)resolver; + free(resolver); } /* * Curl_resolver_duphandle() * Called from curl_easy_duphandle() to duplicate resolver URL state-specific - * environment ('resolver' member of the UrlState structure). Does nothing - * here. + * environment ('resolver' member of the UrlState structure). */ int Curl_resolver_duphandle(void **to, void *from) { - (void)to; (void)from; - return CURLE_OK; + return Curl_resolver_init(to); } static void destroy_async_data(struct Curl_async *); @@ -561,9 +565,22 @@ int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) { - (void)conn; + time_t milli; + timediff_t ms; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; (void)socks; (void)numsocks; + ms = Curl_timediff(Curl_now(), reslv->start); + if(ms < 10) + milli = ms/3; + else if(ms <= 50) + milli = 10; + else if(ms <= 250) + milli = 50; + else + milli = 200; + Curl_expire(data, milli, EXPIRE_ASYNC_NAME); return 0; } @@ -577,6 +594,8 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, int *waitp) { struct in_addr in; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; *waitp = 0; /* default to synchronous response */ @@ -584,14 +603,17 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, /* This is a dotted IP address 123.123.123.123-style */ return Curl_ip2addr(AF_INET, &in, hostname, port); + reslv->start = Curl_now(); + /* fire up a new resolver thread! */ if(init_resolve_thread(conn, hostname, port, NULL)) { *waitp = 1; /* expect asynchronous response */ return NULL; } - /* fall-back to blocking version */ - return Curl_ipv4_resolve_r(hostname, port); + failf(conn->data, "getaddrinfo() thread failed\n"); + + return NULL; } #else /* !HAVE_GETADDRINFO */ @@ -605,10 +627,10 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, int *waitp) { struct addrinfo hints; - Curl_addrinfo *res; - int error; char sbuf[12]; int pf = PF_INET; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; *waitp = 0; /* default to synchronous response */ @@ -658,27 +680,16 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, snprintf(sbuf, sizeof(sbuf), "%d", port); + reslv->start = Curl_now(); /* fire up a new resolver thread! */ if(init_resolve_thread(conn, hostname, port, &hints)) { *waitp = 1; /* expect asynchronous response */ return NULL; } - /* fall-back to blocking version */ - infof(conn->data, "init_resolve_thread() failed for %s; %s\n", - hostname, Curl_strerror(conn, errno)); - - error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res); - if(error) { - infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n", - hostname, port, Curl_strerror(conn, SOCKERRNO)); - return NULL; - } - else { - Curl_addrinfo_set_port(res, port); - } + failf(data, "getaddrinfo() thread failed to start\n"); + return NULL; - return res; } #endif /* !HAVE_GETADDRINFO */ diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl index c1f74bebf3..c90e245eee 100644 --- a/libs/libcurl/src/checksrc.pl +++ b/libs/libcurl/src/checksrc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl #*************************************************************************** # _ _ ____ _ # Project ___| | | | _ \| | @@ -6,7 +6,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 2011 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -26,7 +26,7 @@ my $indent = 2; my $warnings; my $errors; -my $supressed; # whitelisted problems +my $suppressed; # whitelisted problems my $file; my $dir="."; my $wlist; @@ -35,10 +35,10 @@ my $verbose; my %whitelist; my %warnings = ( - 'LONGLINE' => "Line longer than $max_column", - 'TABS' => 'TAB characters not allowed', - 'TRAILINGSPACE' => 'Trailing white space on the line', - 'CPPCOMMENTS' => '// comment detected', + 'LONGLINE' => "Line longer than $max_column", + 'TABS' => 'TAB characters not allowed', + 'TRAILINGSPACE' => 'Trailing white space on the line', + 'CPPCOMMENTS' => '// comment detected', 'SPACEBEFOREPAREN' => 'space before an open parenthesis', 'SPACEAFTERPAREN' => 'space after open parenthesis', 'SPACEBEFORECLOSE' => 'space before a close parenthesis', @@ -47,7 +47,7 @@ my %warnings = ( 'COMMANOSPACE' => 'comma without following space', 'BRACEELSE' => '} else on the same line', 'PARENBRACE' => '){ without sufficient space', - 'SPACESEMILCOLON' => 'space before semicolon', + 'SPACESEMICOLON' => 'space before semicolon', 'BANNEDFUNC' => 'a banned function was used', 'FOPENMODE' => 'fopen needs a macro for the mode string', 'BRACEPOS' => 'wrong position for an open brace', @@ -58,9 +58,9 @@ my %warnings = ( 'OPENCOMMENT' => 'file ended with a /* comment still "open"', 'ASTERISKSPACE' => 'pointer declared with space after asterisk', 'ASTERISKNOSPACE' => 'pointer declared without space before asterisk', - 'ASSIGNWITHINCONDITION' => 'assignment within conditional expression', + 'ASSIGNWITHINCONDITION' => 'assignment within conditional expression', 'EQUALSNOSPACE' => 'equals sign without following space', - 'NOSPACEEQUALS' => 'equals sign without preceeding space', + 'NOSPACEEQUALS' => 'equals sign without preceding space', 'SEMINOSPACE' => 'semicolon without following space', 'MULTISPACE' => 'multiple spaces used when not suitable', ); @@ -101,7 +101,7 @@ sub checkwarn { } if($nowarn) { - $supressed++; + $suppressed++; if($w) { $swarnings++; } @@ -142,6 +142,16 @@ while(1) { $file = shift @ARGV; next; } + elsif($file =~ /-i([1-9])/) { + $indent = $1 + 0; + $file = shift @ARGV; + next; + } + elsif($file =~ /-m([0-9]+)/) { + $max_column = $1 + 0; + $file = shift @ARGV; + next; + } elsif($file =~ /^(-h|--help)/) { undef $file; last; @@ -156,6 +166,8 @@ if(!$file) { print " -D[DIR] Directory to prepend file names\n"; print " -h Show help output\n"; print " -W[file] Whitelist the given file - ignore all its flaws\n"; + print " -i<n> Indent spaces. Default: 2\n"; + print " -m<n> Maximum line length. Default: 79\n"; print "\nDetects and warns for these problems:\n"; for(sort keys %warnings) { printf (" %-18s: %s\n", $_, $warnings{$_}); @@ -422,7 +434,7 @@ sub scanfile { # There is a quote here, figure out whether the comma is # within a string or '' or not. if($pref =~ /\"/) { - # withing a string + # within a string } elsif($pref =~ /\'$/) { # a single letter @@ -450,14 +462,14 @@ sub scanfile { # check for space before the semicolon last in a line if($l =~ /^(.*[^ ].*) ;$/) { - checkwarn("SPACESEMILCOLON", + checkwarn("SPACESEMICOLON", $line, length($1), $file, $ol, "space before last semicolon"); } # scan for use of banned functions if($l =~ /^(.*\W) (gets| - strtok| + strtok| v?sprintf| (str|_mbs|_tcs|_wcs)n?cat| LoadLibrary(Ex)?(A|W)?) @@ -487,9 +499,9 @@ sub scanfile { } # if the previous line starts with if/while/for AND ends with an open - # brace, check that this line is indented $indent more steps, if not - # a cpp line - if($prevl =~ /^( *)(if|while|for)\(.*\{\z/) { + # brace, or an else statement, check that this line is indented $indent + # more steps, if not a cpp line + if($prevl =~ /^( *)((if|while|for)\(.*\{|else)\z/) { my $first = length($1); # this line has some character besides spaces @@ -499,7 +511,7 @@ sub scanfile { if($expect != $second) { my $diff = $second - $first; checkwarn("INDENTATION", $line, length($1), $file, $ol, - "not indented $indent steps, uses $diff)"); + "not indented $indent steps (uses $diff)"); } } @@ -561,7 +573,7 @@ sub scanfile { if($nostr =~ /(.*)\;[a-z0-9]/i) { checkwarn("SEMINOSPACE", $line, length($1)+1, $file, $ol, - "no space after semilcolon"); + "no space after semicolon"); } # check for more than one consecutive space before open brace or @@ -596,7 +608,7 @@ sub scanfile { if($errors || $warnings || $verbose) { printf "checksrc: %d errors and %d warnings\n", $errors, $warnings; - if($supressed) { + if($suppressed) { printf "checksrc: %d errors and %d warnings suppressed\n", $serrors, $swarnings; diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h index eec7af9888..ff1ea15581 100644 --- a/libs/libcurl/src/config-dos.h +++ b/libs/libcurl/src/config-dos.h @@ -53,7 +53,6 @@ #define HAVE_IOCTL_FIONBIO 1 #define HAVE_IOCTLSOCKET 1 #define HAVE_IOCTLSOCKET_FIONBIO 1 -#define HAVE_LIMITS_H 1 #define HAVE_LOCALE_H 1 #define HAVE_LONGLONG 1 #define HAVE_MEMORY_H 1 diff --git a/libs/libcurl/src/config-symbian.h b/libs/libcurl/src/config-symbian.h index 92983d2421..d23de33255 100644 --- a/libs/libcurl/src/config-symbian.h +++ b/libs/libcurl/src/config-symbian.h @@ -318,9 +318,6 @@ /* Define to 1 if you have the `ssl' library (-lssl). */ /*#define HAVE_LIBSSL 1*/ -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - /* if your compiler supports LL */ #define HAVE_LL 1 diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h index d1eb3d9062..778d9833fe 100644 --- a/libs/libcurl/src/config-tpf.h +++ b/libs/libcurl/src/config-tpf.h @@ -284,9 +284,6 @@ /* if zlib is available */ /* #undef HAVE_LIBZ */ -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - /* if your compiler supports LL */ #define HAVE_LL 1 diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h index 780a4a225f..19f2d2354d 100644 --- a/libs/libcurl/src/config-vxworks.h +++ b/libs/libcurl/src/config-vxworks.h @@ -384,9 +384,6 @@ /* if zlib is available */ #define HAVE_LIBZ 1 -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - /* if your compiler supports LL */ #define HAVE_LL 1 diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 309f701a94..fdac6f9a2c 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -61,9 +61,6 @@ /* Define if you have the <io.h> header file. */ #define HAVE_IO_H 1 -/* Define if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - /* Define if you have the <locale.h> header file. */ #define HAVE_LOCALE_H 1 @@ -711,6 +708,11 @@ Vista /* Define to use the Windows crypto library. */ #define USE_WIN32_CRYPTO +/* Define to use Unix sockets. */ +#if defined(_MSC_VER) && _MSC_VER >= 1900 +/* #define USE_UNIX_SOCKETS */ +#endif + /* ---------------------------------------------------------------- */ /* ADDITIONAL DEFINITIONS */ /* ---------------------------------------------------------------- */ diff --git a/libs/libcurl/src/config-win32ce.h b/libs/libcurl/src/config-win32ce.h index 28a15f2a1b..182052290e 100644 --- a/libs/libcurl/src/config-win32ce.h +++ b/libs/libcurl/src/config-win32ce.h @@ -54,9 +54,6 @@ /* Define if you have the <io.h> header file. */ #define HAVE_IO_H 1 -/* Define if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - /* Define if you need the malloc.h header header file even with stdlib.h */ #define NEED_MALLOC_H 1 diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c index f8ef2e88b5..b8f5444856 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -40,11 +40,26 @@ #include "curl_memory.h" #include "memdebug.h" +#ifdef CURLDEBUG +/* the debug versions of these macros make extra certain that the lock is + never doubly locked or unlocked */ +#define CONN_LOCK(x) if((x)->share) { \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ + DEBUGASSERT(!(x)->state.conncache_lock); \ + (x)->state.conncache_lock = TRUE; \ + } + +#define CONN_UNLOCK(x) if((x)->share) { \ + DEBUGASSERT((x)->state.conncache_lock); \ + (x)->state.conncache_lock = FALSE; \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ + } +#else #define CONN_LOCK(x) if((x)->share) \ Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) #define CONN_UNLOCK(x) if((x)->share) \ Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) - +#endif static void conn_llist_dtor(void *user, void *element) { @@ -165,18 +180,48 @@ static void hashkey(struct connectdata *conn, char *buf, snprintf(buf, len, "%ld%s", conn->port, hostname); } +void Curl_conncache_unlock(struct connectdata *conn) +{ + CONN_UNLOCK(conn->data); +} + +/* Returns number of connections currently held in the connection cache. + Locks/unlocks the cache itself! +*/ +size_t Curl_conncache_size(struct Curl_easy *data) +{ + size_t num; + CONN_LOCK(data); + num = data->state.conn_cache->num_conn; + CONN_UNLOCK(data); + return num; +} + +/* Returns number of connections currently held in the connections's bundle + Locks/unlocks the cache itself! +*/ +size_t Curl_conncache_bundle_size(struct connectdata *conn) +{ + size_t num; + CONN_LOCK(conn->data); + num = conn->bundle->num_connections; + CONN_UNLOCK(conn->data); + return num; +} + /* Look up the bundle with all the connections to the same host this - connectdata struct is setup to use. */ + connectdata struct is setup to use. + + **NOTE**: When it returns, it holds the connection cache lock! */ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, struct conncache *connc) { struct connectbundle *bundle = NULL; + CONN_LOCK(conn->data); if(connc) { char key[128]; hashkey(conn, key, sizeof(key)); - CONN_LOCK(conn->data); bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); - CONN_UNLOCK(conn->data); } return bundle; @@ -223,77 +268,89 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectbundle *new_bundle = NULL; struct Curl_easy *data = conn->data; + /* *find_bundle() locks the connection cache */ bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); if(!bundle) { int rc; char key[128]; result = bundle_create(data, &new_bundle); - if(result) - return result; + if(result) { + goto unlock; + } hashkey(conn, key, sizeof(key)); - CONN_LOCK(data); rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle); - CONN_UNLOCK(data); if(!rc) { bundle_destroy(new_bundle); - return CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; + goto unlock; } bundle = new_bundle; } - CONN_LOCK(data); result = bundle_add_conn(bundle, conn); if(result) { if(new_bundle) conncache_remove_bundle(data->state.conn_cache, new_bundle); - CONN_UNLOCK(data); - return result; + goto unlock; } - CONN_UNLOCK(data); conn->connection_id = connc->next_connection_id++; - connc->num_connections++; + connc->num_conn++; DEBUGF(infof(conn->data, "Added connection %ld. " "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n", - conn->connection_id, (curl_off_t) connc->num_connections)); + conn->connection_id, (curl_off_t) connc->num_conn)); - return CURLE_OK; + unlock: + CONN_UNLOCK(data); + + return result; } -void Curl_conncache_remove_conn(struct conncache *connc, - struct connectdata *conn) +void Curl_conncache_remove_conn(struct connectdata *conn, bool lock) { + struct Curl_easy *data = conn->data; struct connectbundle *bundle = conn->bundle; + struct conncache *connc = data->state.conn_cache; /* The bundle pointer can be NULL, since this function can be called due to a failed connection attempt, before being added to a bundle */ if(bundle) { - CONN_LOCK(conn->data); + if(lock) { + CONN_LOCK(conn->data); + } bundle_remove_conn(bundle, conn); if(bundle->num_connections == 0) conncache_remove_bundle(connc, bundle); - CONN_UNLOCK(conn->data); + conn->bundle = NULL; /* removed from it */ if(connc) { - connc->num_connections--; - + connc->num_conn--; DEBUGF(infof(conn->data, "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n", - (curl_off_t) connc->num_connections)); + (curl_off_t) connc->num_conn)); + } + if(lock) { + CONN_UNLOCK(conn->data); } } } -/* This function iterates the entire connection cache and calls the - function func() with the connection pointer as the first argument - and the supplied 'param' argument as the other, +/* This function iterates the entire connection cache and calls the function + func() with the connection pointer as the first argument and the supplied + 'param' argument as the other. + + The conncache lock is still held when the callback is called. It needs it, + so that it can safely continue traversing the lists once the callback + returns. + + Returns 1 if the loop was aborted due to the callback's return code. Return 0 from func() to continue the loop, return 1 to abort it. */ -void Curl_conncache_foreach(struct Curl_easy *data, +bool Curl_conncache_foreach(struct Curl_easy *data, struct conncache *connc, void *param, int (*func)(struct connectdata *conn, void *param)) @@ -303,7 +360,7 @@ void Curl_conncache_foreach(struct Curl_easy *data, struct curl_hash_element *he; if(!connc) - return; + return FALSE; CONN_LOCK(data); Curl_hash_start_iterate(&connc->hash, &iter); @@ -324,11 +381,12 @@ void Curl_conncache_foreach(struct Curl_easy *data, if(1 == func(conn, param)) { CONN_UNLOCK(data); - return; + return TRUE; } } } CONN_UNLOCK(data); + return FALSE; } /* Return the first connection found in the cache. Used when closing all @@ -363,16 +421,104 @@ Curl_conncache_find_first_connection(struct conncache *connc) } /* - * This function finds the connection in the connection - * cache that has been unused for the longest time. + * Give ownership of a connection back to the connection cache. Might + * disconnect the oldest existing in there to make space. + * + * Return TRUE if stored, FALSE if closed. + */ +bool Curl_conncache_return_conn(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + + /* data->multi->maxconnects can be negative, deal with it. */ + size_t maxconnects = + (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: + data->multi->maxconnects; + struct connectdata *conn_candidate = NULL; + + if(maxconnects > 0 && + Curl_conncache_size(data) > maxconnects) { + infof(data, "Connection cache is full, closing the oldest one.\n"); + + conn_candidate = Curl_conncache_extract_oldest(data); + + if(conn_candidate) { + /* Set the connection's owner correctly */ + conn_candidate->data = data; + + /* the winner gets the honour of being disconnected */ + (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); + } + } + CONN_LOCK(data); + conn->inuse = FALSE; /* Mark the connection unused */ + CONN_UNLOCK(data); + + return (conn_candidate == conn) ? FALSE : TRUE; + +} + +/* + * This function finds the connection in the connection bundle that has been + * unused for the longest time. + * + * Does not lock the connection cache! * * Returns the pointer to the oldest idle connection, or NULL if none was * found. */ struct connectdata * -Curl_conncache_oldest_idle(struct Curl_easy *data) +Curl_conncache_extract_bundle(struct Curl_easy *data, + struct connectbundle *bundle) { - struct conncache *bc = data->state.conn_cache; + struct curl_llist_element *curr; + timediff_t highscore = -1; + timediff_t score; + struct curltime now; + struct connectdata *conn_candidate = NULL; + struct connectdata *conn; + + (void)data; + + now = Curl_now(); + + curr = bundle->conn_list.head; + while(curr) { + conn = curr->ptr; + + if(!conn->inuse) { + /* Set higher score for the age passed since the connection was used */ + score = Curl_timediff(now, conn->now); + + if(score > highscore) { + highscore = score; + conn_candidate = conn; + } + } + curr = curr->next; + } + if(conn_candidate) { + /* remove it to prevent another thread from nicking it */ + bundle_remove_conn(bundle, conn_candidate); + data->state.conn_cache->num_conn--; + DEBUGF(infof(data, "The cache now contains %" + CURL_FORMAT_CURL_OFF_TU " members\n", + (curl_off_t) data->state.conn_cache->num_conn)); + } + + return conn_candidate; +} + +/* + * This function finds the connection in the connection cache that has been + * unused for the longest time and extracts that from the bundle. + * + * Returns the pointer to the connection, or NULL if none was found. + */ +struct connectdata * +Curl_conncache_extract_oldest(struct Curl_easy *data) +{ + struct conncache *connc = data->state.conn_cache; struct curl_hash_iterator iter; struct curl_llist_element *curr; struct curl_hash_element *he; @@ -381,11 +527,12 @@ Curl_conncache_oldest_idle(struct Curl_easy *data) struct curltime now; struct connectdata *conn_candidate = NULL; struct connectbundle *bundle; + struct connectbundle *bundle_candidate = NULL; now = Curl_now(); CONN_LOCK(data); - Curl_hash_start_iterate(&bc->hash, &iter); + Curl_hash_start_iterate(&connc->hash, &iter); he = Curl_hash_next_element(&iter); while(he) { @@ -404,6 +551,7 @@ Curl_conncache_oldest_idle(struct Curl_easy *data) if(score > highscore) { highscore = score; conn_candidate = conn; + bundle_candidate = bundle; } } curr = curr->next; @@ -411,6 +559,14 @@ Curl_conncache_oldest_idle(struct Curl_easy *data) he = Curl_hash_next_element(&iter); } + if(conn_candidate) { + /* remove it to prevent another thread from nicking it */ + bundle_remove_conn(bundle_candidate, conn_candidate); + connc->num_conn--; + DEBUGF(infof(data, "The cache now contains %" + CURL_FORMAT_CURL_OFF_TU " members\n", + (curl_off_t) connc->num_conn)); + } CONN_UNLOCK(data); return conn_candidate; diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h index 0d97a6cefd..d8ad80f963 100644 --- a/libs/libcurl/src/conncache.h +++ b/libs/libcurl/src/conncache.h @@ -23,9 +23,15 @@ * ***************************************************************************/ +/* + * All accesses to struct fields and changing of data in the connection cache + * and connectbundles must be done with the conncache LOCKED. The cache might + * be shared. + */ + struct conncache { struct curl_hash hash; - size_t num_connections; + size_t num_conn; long next_connection_id; struct curltime last_cleanup; /* handle used for closing cached connections */ @@ -50,14 +56,17 @@ void Curl_conncache_destroy(struct conncache *connc); /* return the correct bundle, to a host or a proxy */ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, struct conncache *connc); +void Curl_conncache_unlock(struct connectdata *conn); +/* returns number of connections currently held in the connection cache */ +size_t Curl_conncache_size(struct Curl_easy *data); +size_t Curl_conncache_bundle_size(struct connectdata *conn); +bool Curl_conncache_return_conn(struct connectdata *conn); CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectdata *conn); - -void Curl_conncache_remove_conn(struct conncache *connc, - struct connectdata *conn); - -void Curl_conncache_foreach(struct Curl_easy *data, +void Curl_conncache_remove_conn(struct connectdata *conn, + bool lock); +bool Curl_conncache_foreach(struct Curl_easy *data, struct conncache *connc, void *param, int (*func)(struct connectdata *conn, @@ -67,7 +76,10 @@ struct connectdata * Curl_conncache_find_first_connection(struct conncache *connc); struct connectdata * -Curl_conncache_oldest_idle(struct Curl_easy *data); +Curl_conncache_extract_bundle(struct Curl_easy *data, + struct connectbundle *bundle); +struct connectdata * +Curl_conncache_extract_oldest(struct Curl_easy *data); void Curl_conncache_close_all_connections(struct conncache *connc); void Curl_conncache_print(struct conncache *connc); diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 3edb71eb72..1a27ae1353 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -619,8 +619,8 @@ void Curl_persistconninfo(struct connectdata *conn) /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ -static bool getaddressinfo(struct sockaddr *sa, char *addr, - long *port) +bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, + long *port) { unsigned short us_port; struct sockaddr_in *si = NULL; @@ -700,16 +700,16 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) return; } - if(!getaddressinfo((struct sockaddr*)&ssrem, - conn->primary_ip, &conn->primary_port)) { + if(!Curl_getaddressinfo((struct sockaddr*)&ssrem, + conn->primary_ip, &conn->primary_port)) { failf(data, "ssrem inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); return; } memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); - if(!getaddressinfo((struct sockaddr*)&ssloc, - conn->local_ip, &conn->local_port)) { + if(!Curl_getaddressinfo((struct sockaddr*)&ssloc, + conn->local_ip, &conn->local_port)) { failf(data, "ssloc inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); return; @@ -783,7 +783,8 @@ CURLcode Curl_is_connected(struct connectdata *conn, /* should we try another protocol family? */ if(i == 0 && conn->tempaddr[1] == NULL && - Curl_timediff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) { + (Curl_timediff(now, conn->connecttime) >= + data->set.happy_eyeballs_timeout)) { trynextip(conn, sockindex, 1); } } @@ -1005,8 +1006,8 @@ static CURLcode singleipconnect(struct connectdata *conn, return CURLE_OK; /* store remote address and port used in this connection attempt */ - if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, - ipaddress, &port)) { + if(!Curl_getaddressinfo((struct sockaddr*)&addr.sa_addr, + ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", errno, Curl_strerror(conn, errno)); @@ -1033,9 +1034,11 @@ static CURLcode singleipconnect(struct connectdata *conn, if(data->set.fsockopt) { /* activate callback for setting socket options */ + Curl_set_in_callback(data, true); error = data->set.fsockopt(data->set.sockopt_client, sockfd, CURLSOCKTYPE_IPCXN); + Curl_set_in_callback(data, false); if(error == CURL_SOCKOPT_ALREADY_CONNECTED) isconnected = TRUE; @@ -1204,7 +1207,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ } data->info.numconnects++; /* to track the number of connections made */ - Curl_expire(conn->data, HAPPY_EYEBALLS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS); + Curl_expire(conn->data, data->set.happy_eyeballs_timeout, + EXPIRE_HAPPY_EYEBALLS); return CURLE_OK; } @@ -1311,8 +1315,12 @@ int Curl_closesocket(struct connectdata *conn, status */ conn->sock_accepted[SECONDARYSOCKET] = FALSE; else { + int rc; Curl_multi_closed(conn, sock); - return conn->fclosesocket(conn->closesocket_client, sock); + Curl_set_in_callback(conn->data, true); + rc = conn->fclosesocket(conn->closesocket_client, sock); + Curl_set_in_callback(conn->data, false); + return rc; } } @@ -1363,7 +1371,7 @@ CURLcode Curl_socket(struct connectdata *conn, addr->addrlen = sizeof(struct Curl_sockaddr_storage); memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen); - if(data->set.fopensocket) + if(data->set.fopensocket) { /* * If the opensocket callback is set, all the destination address * information is passed to the callback. Depending on this information the @@ -1373,9 +1381,12 @@ CURLcode Curl_socket(struct connectdata *conn, * might have been changed and this 'new' address will actually be used * here to connect. */ + Curl_set_in_callback(data, true); *sockfd = data->set.fopensocket(data->set.opensocket_client, CURLSOCKTYPE_IPCXN, (struct curl_sockaddr *)addr); + Curl_set_in_callback(data, false); + } else /* opensocket callback not set, so simply create the socket now */ *sockfd = socket(addr->family, addr->socktype, addr->protocol); diff --git a/libs/libcurl/src/connect.h b/libs/libcurl/src/connect.h index 3974486364..193dc63978 100644 --- a/libs/libcurl/src/connect.h +++ b/libs/libcurl/src/connect.h @@ -41,8 +41,6 @@ timediff_t Curl_timeleft(struct Curl_easy *data, bool duringconnect); #define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ -#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between - IPv4/IPv6 connection attempts */ /* * Used to extract socket and connectdata struct for the most recent @@ -78,6 +76,11 @@ void Curl_persistconninfo(struct connectdata *conn); int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); /* + * Get presentation format IP address and port from a sockaddr. + */ +bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port); + +/* * The Curl_sockaddr_ex structure is basically libcurl's external API * curl_sockaddr structure with enough space available to directly hold any * protocol-specific address structures. The variable declared here will be diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c index 3d061375c5..7c979efcc3 100644 --- a/libs/libcurl/src/content_encoding.c +++ b/libs/libcurl/src/content_encoding.c @@ -73,14 +73,17 @@ typedef enum { ZLIB_UNINIT, /* uninitialized */ ZLIB_INIT, /* initialized */ + ZLIB_INFLATING, /* Inflating started. */ ZLIB_GZIP_HEADER, /* reading gzip header */ + ZLIB_GZIP_TRAILER, /* reading gzip trailer */ ZLIB_GZIP_INFLATING, /* inflating gzip stream */ ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ } zlibInitState; /* Writer parameters. */ typedef struct { - zlibInitState zlib_init; /* zlib init state */ + zlibInitState zlib_init; /* zlib init state */ + uInt trailerlen; /* Remaining trailer byte count. */ z_stream z; /* State structure for zlib. */ } zlib_params; @@ -130,80 +133,120 @@ exit_zlib(struct connectdata *conn, return result; } -static CURLcode -inflate_stream(struct connectdata *conn, contenc_writer *writer) +static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp) +{ + z_stream *z = &zp->z; + CURLcode result = CURLE_OK; + uInt len = z->avail_in < zp->trailerlen? z->avail_in: zp->trailerlen; + + /* Consume expected trailer bytes. Terminate stream if exhausted. + Issue an error if unexpected bytes follow. */ + + zp->trailerlen -= len; + z->avail_in -= len; + z->next_in += len; + if(z->avail_in) + result = CURLE_WRITE_ERROR; + if(result || !zp->trailerlen) + result = exit_zlib(conn, z, &zp->zlib_init, result); + else { + /* Only occurs for gzip with zlib < 1.2.0.4. */ + zp->zlib_init = ZLIB_GZIP_TRAILER; + } + return result; +} + +static CURLcode inflate_stream(struct connectdata *conn, + contenc_writer *writer, zlibInitState started) { zlib_params *zp = (zlib_params *) &writer->params; - int allow_restart = 1; z_stream *z = &zp->z; /* zlib state structure */ uInt nread = z->avail_in; Bytef *orig_in = z->next_in; int status; /* zlib status */ + bool done = FALSE; CURLcode result = CURLE_OK; /* Curl_client_write status */ char *decomp; /* Put the decompressed data here. */ + /* Check state. */ + if(zp->zlib_init != ZLIB_INIT && + zp->zlib_init != ZLIB_INFLATING && + zp->zlib_init != ZLIB_INIT_GZIP && + zp->zlib_init != ZLIB_GZIP_INFLATING) + return exit_zlib(conn, z, &zp->zlib_init, CURLE_WRITE_ERROR); + /* Dynamically allocate a buffer for decompression because it's uncommonly large to hold on the stack */ decomp = malloc(DSIZ); - if(decomp == NULL) { + if(decomp == NULL) return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); - } /* because the buffer size is fixed, iteratively decompress and transfer to - the client via client_write. */ - for(;;) { - if(z->avail_in == 0) { - free(decomp); - return result; - } + the client via downstream_write function. */ + while(!done) { + done = TRUE; /* (re)set buffer for decompressed output for every iteration */ z->next_out = (Bytef *) decomp; z->avail_out = DSIZ; - status = inflate(z, Z_SYNC_FLUSH); - if(status == Z_OK || status == Z_STREAM_END) { - allow_restart = 0; - result = Curl_unencode_write(conn, writer->downstream, decomp, - DSIZ - z->avail_out); - /* if !CURLE_OK, clean up, return */ - if(result) { - free(decomp); - return exit_zlib(conn, z, &zp->zlib_init, result); + status = inflate(z, Z_BLOCK); + + /* Flush output data if some. */ + if(z->avail_out != DSIZ) { + if(status == Z_OK || status == Z_STREAM_END) { + zp->zlib_init = started; /* Data started. */ + result = Curl_unencode_write(conn, writer->downstream, decomp, + DSIZ - z->avail_out); + if(result) { + exit_zlib(conn, z, &zp->zlib_init, result); + break; + } } - - /* Done? clean up, return */ - if(status == Z_STREAM_END) { - free(decomp); - return exit_zlib(conn, z, &zp->zlib_init, result); - } - - /* Done with these bytes, exit */ - - /* status is always Z_OK at this point! */ - continue; } - else if(allow_restart && status == Z_DATA_ERROR) { + + /* Dispatch by inflate() status. */ + switch(status) { + case Z_OK: + /* Always loop: there may be unflushed latched data in zlib state. */ + done = FALSE; + break; + case Z_BUF_ERROR: + /* No more data to flush: just exit loop. */ + break; + case Z_STREAM_END: + result = process_trailer(conn, zp); + break; + case Z_DATA_ERROR: /* some servers seem to not generate zlib headers, so this is an attempt to fix and continue anyway */ - - (void) inflateEnd(z); /* don't care about the return code */ - if(inflateInit2(z, -MAX_WBITS) != Z_OK) { - free(decomp); - zp->zlib_init = ZLIB_UNINIT; /* inflateEnd() already called. */ - return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z)); + if(zp->zlib_init == ZLIB_INIT) { + /* Do not use inflateReset2(): only available since zlib 1.2.3.4. */ + (void) inflateEnd(z); /* don't care about the return code */ + if(inflateInit2(z, -MAX_WBITS) == Z_OK) { + z->next_in = orig_in; + z->avail_in = nread; + zp->zlib_init = ZLIB_INFLATING; + done = FALSE; + break; + } + zp->zlib_init = ZLIB_UNINIT; /* inflateEnd() already called. */ } - z->next_in = orig_in; - z->avail_in = nread; - allow_restart = 0; - continue; - } - else { /* Error; exit loop, handle below */ - free(decomp); - return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z)); + /* FALLTHROUGH */ + default: + result = exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z)); + break; } } - /* UNREACHED */ + free(decomp); + + /* We're about to leave this call so the `nread' data bytes won't be seen + again. If we are in a state that would wrongly allow restart in raw mode + at the next call, assume output has already started. */ + if(nread && zp->zlib_init == ZLIB_INIT) + zp->zlib_init = started; /* Cannot restart anymore. */ + + return result; } @@ -239,7 +282,7 @@ static CURLcode deflate_unencode_write(struct connectdata *conn, z->avail_in = (uInt) nbytes; /* Now uncompress the data */ - return inflate_stream(conn, writer); + return inflate_stream(conn, writer, ZLIB_INFLATING); } static void deflate_close_writer(struct connectdata *conn, @@ -283,11 +326,12 @@ static CURLcode gzip_init_writer(struct connectdata *conn, zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ } else { - /* we must parse the gzip header ourselves */ + /* we must parse the gzip header and trailer ourselves */ if(inflateInit2(z, -MAX_WBITS) != Z_OK) { return process_zlib_error(conn, z); } - zp->zlib_init = ZLIB_INIT; /* Initial call state */ + zp->trailerlen = 8; /* A CRC-32 and a 32-bit input size (RFC 1952, 2.2) */ + zp->zlib_init = ZLIB_INIT; /* Initial call state */ } return CURLE_OK; @@ -389,7 +433,7 @@ static CURLcode gzip_unencode_write(struct connectdata *conn, z->next_in = (Bytef *) buf; z->avail_in = (uInt) nbytes; /* Now uncompress the data */ - return inflate_stream(conn, writer); + return inflate_stream(conn, writer, ZLIB_INIT_GZIP); } #ifndef OLD_ZLIB_SUPPORT @@ -482,6 +526,11 @@ static CURLcode gzip_unencode_write(struct connectdata *conn, } break; + case ZLIB_GZIP_TRAILER: + z->next_in = (Bytef *) buf; + z->avail_in = (uInt) nbytes; + return process_trailer(conn, zp); + case ZLIB_GZIP_INFLATING: default: /* Inflating stream state */ @@ -496,7 +545,7 @@ static CURLcode gzip_unencode_write(struct connectdata *conn, } /* We've parsed the header, now uncompress the data */ - return inflate_stream(conn, writer); + return inflate_stream(conn, writer, ZLIB_GZIP_INFLATING); #endif } @@ -546,8 +595,12 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be) case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: case BROTLI_DECODER_ERROR_FORMAT_PADDING_1: case BROTLI_DECODER_ERROR_FORMAT_PADDING_2: +#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY: +#endif +#ifdef BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: +#endif case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: return CURLE_BAD_CONTENT_ENCODING; case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: @@ -587,6 +640,7 @@ static CURLcode brotli_unencode_write(struct connectdata *conn, uint8_t *dst; size_t dstleft; CURLcode result = CURLE_OK; + BrotliDecoderResult r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; if(!bp->br) return CURLE_WRITE_ERROR; /* Stream already ended. */ @@ -595,9 +649,8 @@ static CURLcode brotli_unencode_write(struct connectdata *conn, if(!decomp) return CURLE_OUT_OF_MEMORY; - while(nbytes && result == CURLE_OK) { - BrotliDecoderResult r; - + while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) && + result == CURLE_OK) { dst = (uint8_t *) decomp; dstleft = DSIZ; r = BrotliDecoderDecompressStream(bp->br, @@ -673,7 +726,7 @@ static void identity_close_writer(struct connectdata *conn, static const content_encoding identity_encoding = { "identity", - NULL, + "none", identity_init_writer, identity_unencode_write, identity_close_writer, @@ -820,10 +873,9 @@ static contenc_writer *new_unencoding_writer(struct connectdata *conn, contenc_writer *downstream) { size_t sz = offsetof(contenc_writer, params) + handler->paramsize; - contenc_writer *writer = (contenc_writer *) malloc(sz); + contenc_writer *writer = (contenc_writer *) calloc(1, sz); if(writer) { - memset(writer, 0, sz); writer->handler = handler; writer->downstream = downstream; if(handler->init_writer(conn, writer)) { diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index c7afc7ae34..4310994d41 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -143,6 +143,28 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) } /* + * Return true if the given string is an IP(v4|v6) address. + */ +static bool isip(const char *domain) +{ + struct in_addr addr; +#ifdef ENABLE_IPV6 + struct in6_addr addr6; +#endif + + if(Curl_inet_pton(AF_INET, domain, &addr) +#ifdef ENABLE_IPV6 + || Curl_inet_pton(AF_INET6, domain, &addr6) +#endif + ) { + /* domain name given as IP address */ + return TRUE; + } + + return FALSE; +} + +/* * matching cookie path and url path * RFC6265 5.1.4 Paths and Path-Match */ @@ -218,6 +240,62 @@ pathmatched: } /* + * Return the top-level domain, for optimal hashing. + */ +static const char *get_top_domain(const char * const domain, size_t *outlen) +{ + size_t len; + const char *first = NULL, *last; + + if(!domain) + return NULL; + + len = strlen(domain); + last = memrchr(domain, '.', len); + if(last) { + first = memrchr(domain, '.', (size_t) (last - domain)); + if(first) + len -= (size_t) (++first - domain); + } + + if(outlen) + *outlen = len; + + return first? first: domain; +} + +/* + * A case-insensitive hash for the cookie domains. + */ +static size_t cookie_hash_domain(const char *domain, const size_t len) +{ + const char *end = domain + len; + size_t h = 5381; + + while(domain < end) { + h += h << 5; + h ^= Curl_raw_toupper(*domain++); + } + + return (h % COOKIE_HASH_SIZE); +} + +/* + * Hash this domain. + */ +static size_t cookiehash(const char * const domain) +{ + const char *top; + size_t len; + + if(!domain || isip(domain)) + return 0; + + top = get_top_domain(domain, &len); + return cookie_hash_domain(top, len); +} + +/* * cookie path sanitize */ static char *sanitize_cookie_path(const char *cookie_path) @@ -303,48 +381,29 @@ static void remove_expired(struct CookieInfo *cookies) { struct Cookie *co, *nx, *pv; curl_off_t now = (curl_off_t)time(NULL); - - co = cookies->cookies; - pv = NULL; - while(co) { - nx = co->next; - if(co->expires && co->expires < now) { - if(!pv) { - cookies->cookies = co->next; + unsigned int i; + + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + co = cookies->cookies[i]; + pv = NULL; + while(co) { + nx = co->next; + if(co->expires && co->expires < now) { + if(!pv) { + cookies->cookies[i] = co->next; + } + else { + pv->next = co->next; + } + cookies->numcookies--; + freecookie(co); } else { - pv->next = co->next; + pv = co; } - cookies->numcookies--; - freecookie(co); - } - else { - pv = co; + co = nx; } - co = nx; - } -} - -/* - * Return true if the given string is an IP(v4|v6) address. - */ -static bool isip(const char *domain) -{ - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - - if(Curl_inet_pton(AF_INET, domain, &addr) -#ifdef ENABLE_IPV6 - || Curl_inet_pton(AF_INET6, domain, &addr6) -#endif - ) { - /* domain name given as IP address */ - return TRUE; } - - return FALSE; } /**************************************************************************** @@ -368,6 +427,7 @@ Curl_cookie_add(struct Curl_easy *data, struct CookieInfo *c, bool httpheader, /* TRUE if HTTP header-style line */ + bool noexpire, /* if TRUE, skip remove_expired() */ char *lineptr, /* first character of the line */ const char *domain, /* default domain */ const char *path) /* full path used when this cookie is set, @@ -380,6 +440,7 @@ Curl_cookie_add(struct Curl_easy *data, time_t now = time(NULL); bool replace_old = FALSE; bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */ + size_t myhash; #ifdef USE_LIBPSL const psl_ctx_t *psl; @@ -430,9 +491,6 @@ Curl_cookie_add(struct Curl_easy *data, size_t nlen = strlen(name); const char *endofn = &ptr[ nlen ]; - infof(data, "cookie size: name/val %d + %d bytes\n", - nlen, len); - if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) || ((nlen + len) > MAX_NAME)) { /* too long individual name or contents, or too long combination of @@ -470,10 +528,16 @@ Curl_cookie_add(struct Curl_easy *data, while(*whatptr && ISBLANK(*whatptr)) whatptr++; - if(!co->name && sep) { + if(!co->name) { /* The very first name/value pair is the actual cookie name */ + if(!sep) { + /* Bad name/value pair. */ + badcookie = TRUE; + break; + } co->name = strdup(name); co->value = strdup(whatptr); + done = TRUE; if(!co->name || !co->value) { badcookie = TRUE; break; @@ -732,7 +796,7 @@ Curl_cookie_add(struct Curl_easy *data, break; case 1: /* This field got its explanation on the 23rd of May 2001 by - Andrés García: + Andrйs Garcнa: flag: A TRUE/FALSE value indicating if all machines within a given domain can access the variable. This value is set automatically by @@ -746,7 +810,7 @@ Curl_cookie_add(struct Curl_easy *data, case 2: /* It turns out, that sometimes the file format allows the path field to remain not filled in, we try to detect this and work - around it! Andrés García made us aware of this... */ + around it! Andrйs Garcнa made us aware of this... */ if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) { /* only if the path doesn't look like a boolean option! */ co->path = strdup(ptr); @@ -822,7 +886,8 @@ Curl_cookie_add(struct Curl_easy *data, the same domain and path as this */ /* at first, remove expired cookies */ - remove_expired(c); + if(!noexpire) + remove_expired(c); #ifdef USE_LIBPSL /* Check if the domain is a Public Suffix and if yes, ignore the cookie. @@ -839,7 +904,8 @@ Curl_cookie_add(struct Curl_easy *data, } #endif - clist = c->cookies; + myhash = cookiehash(co->domain); + clist = c->cookies[myhash]; replace_old = FALSE; while(clist) { if(strcasecompare(clist->name, co->name)) { @@ -925,7 +991,7 @@ Curl_cookie_add(struct Curl_easy *data, if(lastc) lastc->next = co; else - c->cookies = co; + c->cookies[myhash] = co; c->numcookies++; /* one more cookie in the jar */ } @@ -1029,9 +1095,10 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, while(*lineptr && ISBLANK(*lineptr)) lineptr++; - Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL); + Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL); } free(line); /* free the line buffer */ + remove_expired(c); /* run this once, not on every cookie */ if(fromfile) fclose(fp); @@ -1137,8 +1204,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, struct Cookie *mainco = NULL; size_t matches = 0; bool is_ip; + const size_t myhash = cookiehash(host); - if(!c || !c->cookies) + if(!c || !c->cookies[myhash]) return NULL; /* no cookie struct or no cookies in the struct */ /* at first, remove expired cookies */ @@ -1147,7 +1215,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, /* check if host is an IP(v4|v6) address */ is_ip = isip(host); - co = c->cookies; + co = c->cookies[myhash]; while(co) { /* only process this cookie if it is not expired or had no expire @@ -1235,8 +1303,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, void Curl_cookie_clearall(struct CookieInfo *cookies) { if(cookies) { - Curl_cookie_freelist(cookies->cookies); - cookies->cookies = NULL; + unsigned int i; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + Curl_cookie_freelist(cookies->cookies[i]); + cookies->cookies[i] = NULL; + } cookies->numcookies = 0; } } @@ -1270,31 +1341,37 @@ void Curl_cookie_freelist(struct Cookie *co) void Curl_cookie_clearsess(struct CookieInfo *cookies) { struct Cookie *first, *curr, *next, *prev = NULL; + unsigned int i; - if(!cookies || !cookies->cookies) + if(!cookies) return; - first = curr = prev = cookies->cookies; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + if(!cookies->cookies[i]) + continue; - for(; curr; curr = next) { - next = curr->next; - if(!curr->expires) { - if(first == curr) - first = next; + first = curr = prev = cookies->cookies[i]; - if(prev == curr) - prev = next; - else - prev->next = next; + for(; curr; curr = next) { + next = curr->next; + if(!curr->expires) { + if(first == curr) + first = next; + + if(prev == curr) + prev = next; + else + prev->next = next; - freecookie(curr); - cookies->numcookies--; + freecookie(curr); + cookies->numcookies--; + } + else + prev = curr; } - else - prev = curr; - } - cookies->cookies = first; + cookies->cookies[i] = first; + } } @@ -1307,9 +1384,12 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies) ****************************************************************************/ void Curl_cookie_cleanup(struct CookieInfo *c) { + unsigned int i; + if(c) { free(c->filename); - Curl_cookie_freelist(c->cookies); + for(i = 0; i < COOKIE_HASH_SIZE; i++) + Curl_cookie_freelist(c->cookies[i]); free(c); /* free the base struct as well */ } } @@ -1358,6 +1438,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) FILE *out; bool use_stdout = FALSE; char *format_ptr; + unsigned int i; if((NULL == c) || (0 == c->numcookies)) /* If there are no known cookies, we don't write or even create any @@ -1367,6 +1448,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) /* at first, remove expired cookies */ remove_expired(c); + /* make sure we still have cookies after expiration */ + if(0 == c->numcookies) + return 0; + if(!strcmp("-", dumphere)) { /* use stdout */ out = stdout; @@ -1383,18 +1468,20 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) "# This file was generated by libcurl! Edit at your own risk.\n\n", out); - for(co = c->cookies; co; co = co->next) { - if(!co->domain) - continue; - format_ptr = get_netscape_format(co); - if(format_ptr == NULL) { - fprintf(out, "#\n# Fatal libcurl error\n"); - if(!use_stdout) - fclose(out); - return 1; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + for(co = c->cookies[i]; co; co = co->next) { + if(!co->domain) + continue; + format_ptr = get_netscape_format(co); + if(format_ptr == NULL) { + fprintf(out, "#\n# Fatal libcurl error\n"); + if(!use_stdout) + fclose(out); + return 1; + } + fprintf(out, "%s\n", format_ptr); + free(format_ptr); } - fprintf(out, "%s\n", format_ptr); - free(format_ptr); } if(!use_stdout) @@ -1409,26 +1496,29 @@ static struct curl_slist *cookie_list(struct Curl_easy *data) struct curl_slist *beg; struct Cookie *c; char *line; + unsigned int i; if((data->cookies == NULL) || (data->cookies->numcookies == 0)) return NULL; - for(c = data->cookies->cookies; c; c = c->next) { - if(!c->domain) - continue; - line = get_netscape_format(c); - if(!line) { - curl_slist_free_all(list); - return NULL; - } - beg = Curl_slist_append_nodup(list, line); - if(!beg) { - free(line); - curl_slist_free_all(list); - return NULL; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { + for(c = data->cookies->cookies[i]; c; c = c->next) { + if(!c->domain) + continue; + line = get_netscape_format(c); + if(!line) { + curl_slist_free_all(list); + return NULL; + } + beg = Curl_slist_append_nodup(list, line); + if(!beg) { + free(line); + curl_slist_free_all(list); + return NULL; + } + list = beg; } - list = beg; } return list; diff --git a/libs/libcurl/src/cookie.h b/libs/libcurl/src/cookie.h index cb50b71c6a..79b5928dc2 100644 --- a/libs/libcurl/src/cookie.h +++ b/libs/libcurl/src/cookie.h @@ -45,9 +45,11 @@ struct Cookie { bool httponly; /* true if the httponly directive is present */ }; +#define COOKIE_HASH_SIZE 256 + struct CookieInfo { /* linked list of cookies we know of */ - struct Cookie *cookies; + struct Cookie *cookies[COOKIE_HASH_SIZE]; char *filename; /* file we read from/write to */ bool running; /* state info, for cookie adding information */ @@ -67,7 +69,6 @@ struct CookieInfo { */ #define MAX_COOKIE_LINE 5000 -#define MAX_COOKIE_LINE_TXT "4999" /* This is the maximum length of a cookie name or content we deal with: */ #define MAX_NAME 4096 @@ -80,7 +81,8 @@ struct Curl_easy; */ struct Cookie *Curl_cookie_add(struct Curl_easy *data, - struct CookieInfo *, bool header, char *lineptr, + struct CookieInfo *, bool header, bool noexpiry, + char *lineptr, const char *domain, const char *path); struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *, diff --git a/libs/libcurl/src/curl_addrinfo.c b/libs/libcurl/src/curl_addrinfo.c index 6eb28bbcb6..55d5a3942d 100644 --- a/libs/libcurl/src/curl_addrinfo.c +++ b/libs/libcurl/src/curl_addrinfo.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,6 +27,9 @@ #ifdef HAVE_NETINET_IN_H # include <netinet/in.h> #endif +#ifdef HAVE_NETINET_IN6_H +# include <netinet/in6.h> +#endif #ifdef HAVE_NETDB_H # include <netdb.h> #endif @@ -47,6 +50,10 @@ # define in_addr_t unsigned long #endif +#if defined(WIN32) && defined(USE_UNIX_SOCKETS) +#include <afunix.h> +#endif + #include <stddef.h> #include "curl_addrinfo.h" @@ -338,7 +345,7 @@ Curl_he2ai(const struct hostent *he, int port) addr = (void *)ai->ai_addr; /* storage area for this info */ memcpy(&addr->sin_addr, curr, sizeof(struct in_addr)); - addr->sin_family = (unsigned short)(he->h_addrtype); + addr->sin_family = (CURL_SA_FAMILY_T)(he->h_addrtype); addr->sin_port = htons((unsigned short)port); break; @@ -347,7 +354,7 @@ Curl_he2ai(const struct hostent *he, int port) addr6 = (void *)ai->ai_addr; /* storage area for this info */ memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr)); - addr6->sin6_family = (unsigned short)(he->h_addrtype); + addr6->sin6_family = (CURL_SA_FAMILY_T)(he->h_addrtype); addr6->sin6_port = htons((unsigned short)port); break; #endif diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index e4d14c784b..4b12083f29 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -398,8 +398,8 @@ /* if zlib is available */ #cmakedefine HAVE_LIBZ 1 -/* Define to 1 if you have the <limits.h> header file. */ -#cmakedefine HAVE_LIMITS_H 1 +/* if brotli is available */ +#cmakedefine HAVE_BROTLI 1 /* if your compiler supports LL */ #cmakedefine HAVE_LL 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index 3a3368b9b7..f60321521a 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -1,5 +1,8 @@ /* lib/curl_config.h.in. Generated from configure.ac by autoheader. */ +/* to enable curl debug memory tracking */ +#undef CURLDEBUG + /* Location of default ca bundle */ #undef CURL_CA_BUNDLE @@ -75,9 +78,15 @@ /* Definition to make a library symbol externally visible. */ #undef CURL_EXTERN_SYMBOL +/* IP address type in sockaddr */ +#undef CURL_SA_FAMILY_T + /* built with multiple SSL backends */ #undef CURL_WITH_MULTI_SSL +/* enable debug build options */ +#undef DEBUGBUILD + /* your Entropy Gathering Daemon socket pathname */ #undef EGD_SOCKET @@ -413,21 +422,24 @@ /* Define to 1 if you have the <librtmp/rtmp.h> header file. */ #undef HAVE_LIBRTMP_RTMP_H +/* Define to 1 if you have the `ssh' library (-lssh). */ +#undef HAVE_LIBSSH + /* Define to 1 if you have the `ssh2' library (-lssh2). */ #undef HAVE_LIBSSH2 /* Define to 1 if you have the <libssh2.h> header file. */ #undef HAVE_LIBSSH2_H +/* Define to 1 if you have the <libssh/libssh.h> header file. */ +#undef HAVE_LIBSSH_LIBSSH_H + /* Define to 1 if you have the `ssl' library (-lssl). */ #undef HAVE_LIBSSL /* if zlib is available */ #undef HAVE_LIBZ -/* Define to 1 if you have the <limits.h> header file. */ -#undef HAVE_LIMITS_H - /* Define to 1 if you have the <linux/tcp.h> header file. */ #undef HAVE_LINUX_TCP_H @@ -461,6 +473,9 @@ /* Define to 1 if you have the <netdb.h> header file. */ #undef HAVE_NETDB_H +/* Define to 1 if you have the <netinet/in6.h> header file. */ +#undef HAVE_NETINET_IN6_H + /* Define to 1 if you have the <netinet/in.h> header file. */ #undef HAVE_NETINET_IN_H @@ -510,6 +525,9 @@ /* Define to 1 if you have the `pipe' function. */ #undef HAVE_PIPE +/* if you have the PK11_CreateManagedGenericObject function */ +#undef HAVE_PK11_CREATEMANAGEDGENERICOBJECT + /* Define to 1 if you have a working poll function. */ #undef HAVE_POLL @@ -723,6 +741,9 @@ /* Define to 1 if you have the <time.h> header file. */ #undef HAVE_TIME_H +/* Define this if time_t is unsigned */ +#undef HAVE_TIME_T_UNSIGNED + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H @@ -942,6 +963,9 @@ /* if librtmp is in use */ #undef USE_LIBRTMP +/* if libSSH is in use */ +#undef USE_LIBSSH + /* if libSSH2 is in use */ #undef USE_LIBSSH2 diff --git a/libs/libcurl/src/curl_ctype.c b/libs/libcurl/src/curl_ctype.c new file mode 100644 index 0000000000..1a47fb5e68 --- /dev/null +++ b/libs/libcurl/src/curl_ctype.c @@ -0,0 +1,133 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DOES_CONVERSIONS + +#undef _U +#define _U (1<<0) /* upper case */ +#undef _L +#define _L (1<<1) /* lower case */ +#undef _N +#define _N (1<<2) /* decimal numerical digit */ +#undef _S +#define _S (1<<3) /* space */ +#undef _P +#define _P (1<<4) /* punctuation */ +#undef _C +#define _C (1<<5) /* control */ +#undef _X +#define _X (1<<6) /* hexadecimal letter */ +#undef _B +#define _B (1<<7) /* blank */ + +static const unsigned char ascii[128] = { + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _S|_B, _P, _P, _P, _P, _P, _P, _P, + _P, _P, _P, _P, _P, _P, _P, _P, + _N, _N, _N, _N, _N, _N, _N, _N, + _N, _N, _P, _P, _P, _P, _P, _P, + _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _P, _P, _P, _P, _P, + _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _P, _P, _P, _P, _C +}; + +int Curl_isspace(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & _S); +} + +int Curl_isdigit(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & _N); +} + +int Curl_isalnum(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_N|_U|_L)); +} + +int Curl_isxdigit(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_N|_X)); +} + +int Curl_isgraph(int c) +{ + if((c < 0) || (c >= 0x80) || (c == ' ')) + return FALSE; + return (ascii[c] & (_N|_X|_U|_L|_P|_S)); +} + +int Curl_isprint(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_N|_X|_U|_L|_P|_S)); +} + +int Curl_isalpha(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_U|_L)); +} + +int Curl_isupper(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_U)); +} + +int Curl_islower(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_L)); +} + +int Curl_iscntrl(int c) +{ + if((c < 0) || (c >= 0x80)) + return FALSE; + return (ascii[c] & (_C)); +} + +#endif /* !CURL_DOES_CONVERSIONS */ diff --git a/libs/libcurl/src/curl_ctype.h b/libs/libcurl/src/curl_ctype.h new file mode 100644 index 0000000000..6e94bb1b43 --- /dev/null +++ b/libs/libcurl/src/curl_ctype.h @@ -0,0 +1,81 @@ +#ifndef HEADER_CURL_CTYPE_H +#define HEADER_CURL_CTYPE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef CURL_DOES_CONVERSIONS + +/* + * Uppercase macro versions of ANSI/ISO is*() functions/macros which + * avoid negative number inputs with argument byte codes > 127. + * + * For non-ASCII platforms the C library character classification routines + * are used despite being locale-dependent, because this is better than + * not to work at all. + */ +#include <ctype.h> + +#define ISSPACE(x) (isspace((int) ((unsigned char)x))) +#define ISDIGIT(x) (isdigit((int) ((unsigned char)x))) +#define ISALNUM(x) (isalnum((int) ((unsigned char)x))) +#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) +#define ISGRAPH(x) (isgraph((int) ((unsigned char)x))) +#define ISALPHA(x) (isalpha((int) ((unsigned char)x))) +#define ISPRINT(x) (isprint((int) ((unsigned char)x))) +#define ISUPPER(x) (isupper((int) ((unsigned char)x))) +#define ISLOWER(x) (islower((int) ((unsigned char)x))) +#define ISCNTRL(x) (iscntrl((int) ((unsigned char)x))) +#define ISASCII(x) (isascii((int) ((unsigned char)x))) + +#else + +int Curl_isspace(int c); +int Curl_isdigit(int c); +int Curl_isalnum(int c); +int Curl_isxdigit(int c); +int Curl_isgraph(int c); +int Curl_isprint(int c); +int Curl_isalpha(int c); +int Curl_isupper(int c); +int Curl_islower(int c); +int Curl_iscntrl(int c); + +#define ISSPACE(x) (Curl_isspace((int) ((unsigned char)x))) +#define ISDIGIT(x) (Curl_isdigit((int) ((unsigned char)x))) +#define ISALNUM(x) (Curl_isalnum((int) ((unsigned char)x))) +#define ISXDIGIT(x) (Curl_isxdigit((int) ((unsigned char)x))) +#define ISGRAPH(x) (Curl_isgraph((int) ((unsigned char)x))) +#define ISALPHA(x) (Curl_isalpha((int) ((unsigned char)x))) +#define ISPRINT(x) (Curl_isprint((int) ((unsigned char)x))) +#define ISUPPER(x) (Curl_isupper((int) ((unsigned char)x))) +#define ISLOWER(x) (Curl_islower((int) ((unsigned char)x))) +#define ISCNTRL(x) (Curl_iscntrl((int) ((unsigned char)x))) +#define ISASCII(x) (((x) >= 0) && ((x) <= 0x80)) + +#endif + +#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \ + (((unsigned char)x) == '\t')) + +#endif /* HEADER_CURL_CTYPE_H */ diff --git a/libs/libcurl/src/curl_fnmatch.c b/libs/libcurl/src/curl_fnmatch.c index 8a1e106c45..0179a4f717 100644 --- a/libs/libcurl/src/curl_fnmatch.c +++ b/libs/libcurl/src/curl_fnmatch.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,14 +47,7 @@ #define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10) typedef enum { - CURLFNM_LOOP_DEFAULT = 0, - CURLFNM_LOOP_BACKSLASH -} loop_state; - -typedef enum { CURLFNM_SCHS_DEFAULT = 0, - CURLFNM_SCHS_MAYRANGE, - CURLFNM_SCHS_MAYRANGE2, CURLFNM_SCHS_RIGHTBR, CURLFNM_SCHS_RIGHTBRLEFTBR } setcharset_state; @@ -64,6 +57,13 @@ typedef enum { CURLFNM_PKW_DDOT } parsekey_state; +typedef enum { + CCLASS_OTHER = 0, + CCLASS_DIGIT, + CCLASS_UPPER, + CCLASS_LOWER +} char_class; + #define SETCHARSET_OK 1 #define SETCHARSET_FAIL 0 @@ -81,12 +81,12 @@ static int parsekeyword(unsigned char **pattern, unsigned char *charset) return SETCHARSET_FAIL; switch(state) { case CURLFNM_PKW_INIT: - if(ISALPHA(c) && ISLOWER(c)) + if(ISLOWER(c)) keyword[i] = c; else if(c == ':') state = CURLFNM_PKW_DDOT; else - return 0; + return SETCHARSET_FAIL; break; case CURLFNM_PKW_DDOT: if(c == ']') @@ -123,14 +123,48 @@ static int parsekeyword(unsigned char **pattern, unsigned char *charset) return SETCHARSET_OK; } +/* Return the character class. */ +static char_class charclass(unsigned char c) +{ + if(ISUPPER(c)) + return CCLASS_UPPER; + if(ISLOWER(c)) + return CCLASS_LOWER; + if(ISDIGIT(c)) + return CCLASS_DIGIT; + return CCLASS_OTHER; +} + +/* Include a character or a range in set. */ +static void setcharorrange(unsigned char **pp, unsigned char *charset) +{ + unsigned char *p = (*pp)++; + unsigned char c = *p++; + + charset[c] = 1; + if(ISALNUM(c) && *p++ == '-') { + char_class cc = charclass(c); + unsigned char endrange = *p++; + + if(endrange == '\\') + endrange = *p++; + if(endrange >= c && charclass(endrange) == cc) { + while(c++ != endrange) + if(charclass(c) == cc) /* Chars in class may be not consecutive. */ + charset[c] = 1; + *pp = p; + } + } +} + /* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */ static int setcharset(unsigned char **p, unsigned char *charset) { setcharset_state state = CURLFNM_SCHS_DEFAULT; - unsigned char rangestart = 0; - unsigned char lastchar = 0; bool something_found = FALSE; unsigned char c; + + memset(charset, 0, CURLFNM_CHSET_SIZE); for(;;) { c = **p; if(!c) @@ -138,14 +172,7 @@ static int setcharset(unsigned char **p, unsigned char *charset) switch(state) { case CURLFNM_SCHS_DEFAULT: - if(ISALNUM(c)) { /* ASCII value */ - rangestart = c; - charset[c] = 1; - (*p)++; - state = CURLFNM_SCHS_MAYRANGE; - something_found = TRUE; - } - else if(c == ']') { + if(c == ']') { if(something_found) return SETCHARSET_OK; something_found = TRUE; @@ -154,26 +181,16 @@ static int setcharset(unsigned char **p, unsigned char *charset) (*p)++; } else if(c == '[') { - char c2 = *((*p) + 1); - if(c2 == ':') { /* there has to be a keyword */ - (*p) += 2; - if(parsekeyword(p, charset)) { - state = CURLFNM_SCHS_DEFAULT; - } - else - return SETCHARSET_FAIL; - } + unsigned char *pp = *p + 1; + + if(*pp++ == ':' && parsekeyword(&pp, charset)) + *p = pp; else { charset[c] = 1; (*p)++; } something_found = TRUE; } - else if(c == '?' || c == '*') { - something_found = TRUE; - charset[c] = 1; - (*p)++; - } else if(c == '^' || c == '!') { if(!something_found) { if(charset[CURLFNM_NEGATE]) { @@ -189,82 +206,17 @@ static int setcharset(unsigned char **p, unsigned char *charset) } else if(c == '\\') { c = *(++(*p)); - if(ISPRINT((c))) { - something_found = TRUE; - state = CURLFNM_SCHS_MAYRANGE; - charset[c] = 1; - rangestart = c; - (*p)++; - } + if(c) + setcharorrange(p, charset); else - return SETCHARSET_FAIL; + charset['\\'] = 1; + something_found = TRUE; } else { - charset[c] = 1; - (*p)++; + setcharorrange(p, charset); something_found = TRUE; } break; - case CURLFNM_SCHS_MAYRANGE: - if(c == '-') { - charset[c] = 1; - (*p)++; - lastchar = '-'; - state = CURLFNM_SCHS_MAYRANGE2; - } - else if(c == '[') { - state = CURLFNM_SCHS_DEFAULT; - } - else if(ISALNUM(c)) { - charset[c] = 1; - (*p)++; - } - else if(c == '\\') { - c = *(++(*p)); - if(ISPRINT(c)) { - charset[c] = 1; - (*p)++; - } - else - return SETCHARSET_FAIL; - } - else if(c == ']') { - return SETCHARSET_OK; - } - else - return SETCHARSET_FAIL; - break; - case CURLFNM_SCHS_MAYRANGE2: - if(c == ']') { - return SETCHARSET_OK; - } - else if(c == '\\') { - c = *(++(*p)); - if(ISPRINT(c)) { - charset[c] = 1; - state = CURLFNM_SCHS_DEFAULT; - (*p)++; - } - else - return SETCHARSET_FAIL; - } - else if(c >= rangestart) { - if((ISLOWER(c) && ISLOWER(rangestart)) || - (ISDIGIT(c) && ISDIGIT(rangestart)) || - (ISUPPER(c) && ISUPPER(rangestart))) { - charset[lastchar] = 0; - rangestart++; - while(rangestart++ <= c) - charset[rangestart-1] = 1; - (*p)++; - state = CURLFNM_SCHS_DEFAULT; - } - else - return SETCHARSET_FAIL; - } - else - return SETCHARSET_FAIL; - break; case CURLFNM_SCHS_RIGHTBR: if(c == '[') { state = CURLFNM_SCHS_RIGHTBRLEFTBR; @@ -286,14 +238,11 @@ static int setcharset(unsigned char **p, unsigned char *charset) goto fail; break; case CURLFNM_SCHS_RIGHTBRLEFTBR: - if(c == ']') { + if(c == ']') return SETCHARSET_OK; - } - else { - state = CURLFNM_SCHS_DEFAULT; - charset[c] = 1; - (*p)++; - } + state = CURLFNM_SCHS_DEFAULT; + charset[c] = 1; + (*p)++; break; } } @@ -301,104 +250,96 @@ fail: return SETCHARSET_FAIL; } -static int loop(const unsigned char *pattern, const unsigned char *string) +static int loop(const unsigned char *pattern, const unsigned char *string, + int maxstars) { - loop_state state = CURLFNM_LOOP_DEFAULT; unsigned char *p = (unsigned char *)pattern; unsigned char *s = (unsigned char *)string; unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 }; - int rc = 0; for(;;) { - switch(state) { - case CURLFNM_LOOP_DEFAULT: - if(*p == '*') { - while(*(p + 1) == '*') /* eliminate multiple stars */ - p++; - if(*s == '\0' && *(p + 1) == '\0') - return CURL_FNMATCH_MATCH; - rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */ - if(rc == CURL_FNMATCH_MATCH) + unsigned char *pp; + + switch(*p) { + case '*': + if(!maxstars) + return CURL_FNMATCH_NOMATCH; + /* Regroup consecutive stars and question marks. This can be done because + '*?*?*' can be expressed as '??*'. */ + for(;;) { + if(*++p == '\0') return CURL_FNMATCH_MATCH; - if(*s) /* let the star eat up one character */ - s++; - else - return CURL_FNMATCH_NOMATCH; - } - else if(*p == '?') { - if(ISPRINT(*s)) { - s++; - p++; + if(*p == '?') { + if(!*s++) + return CURL_FNMATCH_NOMATCH; } - else if(*s == '\0') - return CURL_FNMATCH_NOMATCH; - else - return CURL_FNMATCH_FAIL; /* cannot deal with other character */ + else if(*p != '*') + break; } - else if(*p == '\0') { - if(*s == '\0') + /* Skip string characters until we find a match with pattern suffix. */ + for(maxstars--; *s; s++) { + if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH) return CURL_FNMATCH_MATCH; - return CURL_FNMATCH_NOMATCH; } - else if(*p == '\\') { - state = CURLFNM_LOOP_BACKSLASH; + return CURL_FNMATCH_NOMATCH; + case '?': + if(!*s) + return CURL_FNMATCH_NOMATCH; + s++; + p++; + break; + case '\0': + return *s? CURL_FNMATCH_NOMATCH: CURL_FNMATCH_MATCH; + case '\\': + if(p[1]) p++; - } - else if(*p == '[') { - unsigned char *pp = p + 1; /* cannot handle with pointer to register */ - if(setcharset(&pp, charset)) { - int found = FALSE; - if(charset[(unsigned int)*s]) - found = TRUE; - else if(charset[CURLFNM_ALNUM]) - found = ISALNUM(*s); - else if(charset[CURLFNM_ALPHA]) - found = ISALPHA(*s); - else if(charset[CURLFNM_DIGIT]) - found = ISDIGIT(*s); - else if(charset[CURLFNM_XDIGIT]) - found = ISXDIGIT(*s); - else if(charset[CURLFNM_PRINT]) - found = ISPRINT(*s); - else if(charset[CURLFNM_SPACE]) - found = ISSPACE(*s); - else if(charset[CURLFNM_UPPER]) - found = ISUPPER(*s); - else if(charset[CURLFNM_LOWER]) - found = ISLOWER(*s); - else if(charset[CURLFNM_BLANK]) - found = ISBLANK(*s); - else if(charset[CURLFNM_GRAPH]) - found = ISGRAPH(*s); + if(*s++ != *p++) + return CURL_FNMATCH_NOMATCH; + break; + case '[': + pp = p + 1; /* Copy in case of syntax error in set. */ + if(setcharset(&pp, charset)) { + int found = FALSE; + if(!*s) + return CURL_FNMATCH_NOMATCH; + if(charset[(unsigned int)*s]) + found = TRUE; + else if(charset[CURLFNM_ALNUM]) + found = ISALNUM(*s); + else if(charset[CURLFNM_ALPHA]) + found = ISALPHA(*s); + else if(charset[CURLFNM_DIGIT]) + found = ISDIGIT(*s); + else if(charset[CURLFNM_XDIGIT]) + found = ISXDIGIT(*s); + else if(charset[CURLFNM_PRINT]) + found = ISPRINT(*s); + else if(charset[CURLFNM_SPACE]) + found = ISSPACE(*s); + else if(charset[CURLFNM_UPPER]) + found = ISUPPER(*s); + else if(charset[CURLFNM_LOWER]) + found = ISLOWER(*s); + else if(charset[CURLFNM_BLANK]) + found = ISBLANK(*s); + else if(charset[CURLFNM_GRAPH]) + found = ISGRAPH(*s); - if(charset[CURLFNM_NEGATE]) - found = !found; + if(charset[CURLFNM_NEGATE]) + found = !found; - if(found) { - p = pp + 1; - s++; - memset(charset, 0, CURLFNM_CHSET_SIZE); - } - else - return CURL_FNMATCH_NOMATCH; - } - else - return CURL_FNMATCH_FAIL; - } - else { - if(*p++ != *s++) + if(!found) return CURL_FNMATCH_NOMATCH; + p = pp + 1; + s++; + break; } - break; - case CURLFNM_LOOP_BACKSLASH: - if(ISPRINT(*p)) { - if(*p++ == *s++) - state = CURLFNM_LOOP_DEFAULT; - else - return CURL_FNMATCH_NOMATCH; - } - else - return CURL_FNMATCH_FAIL; + + /* Syntax error in set: this must be taken as a regular character. */ + /* FALLTHROUGH */ + default: + if(*p++ != *s++) + return CURL_FNMATCH_NOMATCH; break; } } @@ -414,5 +355,5 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string) if(!pattern || !string) { return CURL_FNMATCH_FAIL; } - return loop((unsigned char *)pattern, (unsigned char *)string); + return loop((unsigned char *)pattern, (unsigned char *)string, 5); } diff --git a/libs/libcurl/src/curl_gssapi.c b/libs/libcurl/src/curl_gssapi.c index 83f3fa0c43..f007986c0d 100644 --- a/libs/libcurl/src/curl_gssapi.c +++ b/libs/libcurl/src/curl_gssapi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,6 +27,11 @@ #include "curl_gssapi.h" #include "sendf.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02"; gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes }; static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"; diff --git a/libs/libcurl/src/curl_memrchr.c b/libs/libcurl/src/curl_memrchr.c index c521497b21..eeb3044a90 100644 --- a/libs/libcurl/src/curl_memrchr.c +++ b/libs/libcurl/src/curl_memrchr.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,17 +44,18 @@ void * Curl_memrchr(const void *s, int c, size_t n) { - const unsigned char *p = s; - const unsigned char *q = s; + if(n > 0) { + const unsigned char *p = s; + const unsigned char *q = s; - p += n - 1; + p += n - 1; - while(p >= q) { - if(*p == (unsigned char)c) - return (void *)p; - p--; + while(p >= q) { + if(*p == (unsigned char)c) + return (void *)p; + p--; + } } - return NULL; } diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c index e8962769ca..e27cab353c 100644 --- a/libs/libcurl/src/curl_ntlm_core.c +++ b/libs/libcurl/src/curl_ntlm_core.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -646,15 +646,6 @@ CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, return CURLE_OK; } -#ifndef SIZE_T_MAX -/* some limits.h headers have this defined, some don't */ -#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) -#define SIZE_T_MAX 18446744073709551615U -#else -#define SIZE_T_MAX 4294967295U -#endif -#endif - /* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode * (uppercase UserName + Domain) as the data */ @@ -754,12 +745,10 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN; /* Allocate the response */ - ptr = malloc(len); + ptr = calloc(1, len); if(!ptr) return CURLE_OUT_OF_MEMORY; - memset(ptr, 0, len); - /* Create the BLOB structure */ snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN, "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */ diff --git a/libs/libcurl/src/curl_ntlm_wb.c b/libs/libcurl/src/curl_ntlm_wb.c index 03f47a3a52..353a656458 100644 --- a/libs/libcurl/src/curl_ntlm_wb.c +++ b/libs/libcurl/src/curl_ntlm_wb.c @@ -364,7 +364,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, case NTLMSTATE_TYPE1: default: /* Use Samba's 'winbind' daemon to support NTLM authentication, - * by delegating the NTLM challenge/response protocal to a helper + * by delegating the NTLM challenge/response protocol to a helper * in ntlm_auth. * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html * https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c new file mode 100644 index 0000000000..e843deac7c --- /dev/null +++ b/libs/libcurl/src/curl_path.c @@ -0,0 +1,195 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#include <curl/curl.h> +#include "curl_memory.h" +#include "curl_path.h" +#include "escape.h" +#include "memdebug.h" + +/* figure out the path to work with in this particular request */ +CURLcode Curl_getworkingpath(struct connectdata *conn, + char *homedir, /* when SFTP is used */ + char **path) /* returns the allocated + real path to work with */ +{ + struct Curl_easy *data = conn->data; + char *real_path = NULL; + char *working_path; + size_t working_path_len; + CURLcode result = + Curl_urldecode(data, data->state.path, 0, &working_path, + &working_path_len, FALSE); + if(result) + return result; + + /* Check for /~/, indicating relative to the user's home directory */ + if(conn->handler->protocol & CURLPROTO_SCP) { + real_path = malloc(working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) + /* It is referenced to the home directory, so strip the leading '/~/' */ + memcpy(real_path, working_path + 3, 4 + working_path_len-3); + else + memcpy(real_path, working_path, 1 + working_path_len); + } + else if(conn->handler->protocol & CURLPROTO_SFTP) { + if((working_path_len > 1) && (working_path[1] == '~')) { + size_t homelen = strlen(homedir); + real_path = malloc(homelen + working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + /* It is referenced to the home directory, so strip the + leading '/' */ + memcpy(real_path, homedir, homelen); + real_path[homelen] = '/'; + real_path[homelen + 1] = '\0'; + if(working_path_len > 3) { + memcpy(real_path + homelen + 1, working_path + 3, + 1 + working_path_len -3); + } + } + else { + real_path = malloc(working_path_len + 1); + if(real_path == NULL) { + free(working_path); + return CURLE_OUT_OF_MEMORY; + } + memcpy(real_path, working_path, 1 + working_path_len); + } + } + + free(working_path); + + /* store the pointer for the caller to receive */ + *path = real_path; + + return CURLE_OK; +} + +/* The get_pathname() function is being borrowed from OpenSSH sftp.c + version 4.6p1. */ +/* + * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> + * + * 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" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) +{ + const char *cp = *cpp, *end; + char quot; + unsigned int i, j; + size_t fullPathLength, pathLength; + bool relativePath = false; + static const char WHITESPACE[] = " \t\r\n"; + + if(!*cp) { + *cpp = NULL; + *path = NULL; + return CURLE_QUOTE_ERROR; + } + /* Ignore leading whitespace */ + cp += strspn(cp, WHITESPACE); + /* Allocate enough space for home directory and filename + separator */ + fullPathLength = strlen(cp) + strlen(homedir) + 2; + *path = malloc(fullPathLength); + if(*path == NULL) + return CURLE_OUT_OF_MEMORY; + + /* Check for quoted filenames */ + if(*cp == '\"' || *cp == '\'') { + quot = *cp++; + + /* Search for terminating quote, unescape some chars */ + for(i = j = 0; i <= strlen(cp); i++) { + if(cp[i] == quot) { /* Found quote */ + i++; + (*path)[j] = '\0'; + break; + } + if(cp[i] == '\0') { /* End of string */ + /*error("Unterminated quote");*/ + goto fail; + } + if(cp[i] == '\\') { /* Escaped characters */ + i++; + if(cp[i] != '\'' && cp[i] != '\"' && + cp[i] != '\\') { + /*error("Bad escaped character '\\%c'", + cp[i]);*/ + goto fail; + } + } + (*path)[j++] = cp[i]; + } + + if(j == 0) { + /*error("Empty quotes");*/ + goto fail; + } + *cpp = cp + i + strspn(cp + i, WHITESPACE); + } + else { + /* Read to end of filename - either to white space or terminator */ + end = strpbrk(cp, WHITESPACE); + if(end == NULL) + end = strchr(cp, '\0'); + /* return pointer to second parameter if it exists */ + *cpp = end + strspn(end, WHITESPACE); + pathLength = 0; + relativePath = (cp[0] == '/' && cp[1] == '~' && cp[2] == '/'); + /* Handling for relative path - prepend home directory */ + if(relativePath) { + strcpy(*path, homedir); + pathLength = strlen(homedir); + (*path)[pathLength++] = '/'; + (*path)[pathLength] = '\0'; + cp += 3; + } + /* Copy path name up until first "white space" */ + memcpy(&(*path)[pathLength], cp, (int)(end - cp)); + pathLength += (int)(end - cp); + (*path)[pathLength] = '\0'; + } + return CURLE_OK; + + fail: + Curl_safefree(*path); + return CURLE_QUOTE_ERROR; +} diff --git a/libs/libcurl/src/curl_path.h b/libs/libcurl/src/curl_path.h new file mode 100644 index 0000000000..5ee4ff3676 --- /dev/null +++ b/libs/libcurl/src/curl_path.h @@ -0,0 +1,47 @@ +#ifndef HEADER_CURL_PATH_H +#define HEADER_CURL_PATH_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include <curl/curl.h> +#include "urldata.h" + +#ifdef WIN32 +# undef PATH_MAX +# define PATH_MAX MAX_PATH +# ifndef R_OK +# define R_OK 4 +# endif +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 /* just an extra precaution since there are systems that + have their definition hidden well */ +#endif + +CURLcode Curl_getworkingpath(struct connectdata *conn, + char *homedir, + char **path); + +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir); +#endif diff --git a/libs/libcurl/src/curl_range.c b/libs/libcurl/src/curl_range.c new file mode 100644 index 0000000000..aa3c493321 --- /dev/null +++ b/libs/libcurl/src/curl_range.c @@ -0,0 +1,95 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include <curl/curl.h> +#include "curl_range.h" +#include "sendf.h" +#include "strtoofft.h" + +/* Only include this function if one or more of FTP, FILE are enabled. */ +#if !defined(CURL_DISABLE_FTP) || !defined(CURL_DISABLE_FILE) + + /* + Check if this is a range download, and if so, set the internal variables + properly. + */ +CURLcode Curl_range(struct connectdata *conn) +{ + curl_off_t from, to; + char *ptr; + char *ptr2; + struct Curl_easy *data = conn->data; + + if(data->state.use_range && data->state.range) { + CURLofft from_t; + CURLofft to_t; + from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + if((to_t == CURL_OFFT_INVAL) && !from_t) { + /* X - */ + data->state.resume_from = from; + DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", + from)); + } + else if((from_t == CURL_OFFT_INVAL) && !to_t) { + /* -Y */ + data->req.maxdownload = to; + data->state.resume_from = -to; + DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n", + to)); + } + else { + /* X-Y */ + curl_off_t totalsize; + + /* Ensure the range is sensible - to should follow from. */ + if(from > to) + return CURLE_RANGE_ERROR; + + totalsize = to - from; + if(totalsize == CURL_OFF_T_MAX) + return CURLE_RANGE_ERROR; + + data->req.maxdownload = totalsize + 1; /* include last byte */ + data->state.resume_from = from; + DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T + " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", + from, data->req.maxdownload)); + } + DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T + " to %" CURL_FORMAT_CURL_OFF_T ", totally %" + CURL_FORMAT_CURL_OFF_T " bytes\n", + from, to, data->req.maxdownload)); + } + else + data->req.maxdownload = -1; + return CURLE_OK; +} + +#endif diff --git a/libs/libcurl/src/curl_range.h b/libs/libcurl/src/curl_range.h new file mode 100644 index 0000000000..2350df9929 --- /dev/null +++ b/libs/libcurl/src/curl_range.h @@ -0,0 +1,30 @@ +#ifndef HEADER_CURL_RANGE_H +#define HEADER_CURL_RANGE_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "urldata.h" + +CURLcode Curl_range(struct connectdata *conn); + +#endif /* HEADER_CURL_RANGE_H */ diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c index 550433d674..e54e4875e2 100644 --- a/libs/libcurl/src/curl_sasl.c +++ b/libs/libcurl/src/curl_sasl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -265,7 +265,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#if defined(USE_KERBEROS5) +#if defined(USE_KERBEROS5) || defined(USE_NTLM) const char *service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : sasl->params->service; @@ -333,7 +333,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, if(force_ir || data->set.sasl_ir) result = Curl_auth_create_ntlm_type1_message(data, conn->user, conn->passwd, - &conn->ntlm, &resp, &len); + service, + hostname, + &conn->ntlm, &resp, + &len); } else #endif @@ -361,15 +364,6 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, conn->oauth_bearer, &resp, &len); } - else if(enabledmechs & SASL_MECH_LOGIN) { - mech = SASL_MECH_STRING_LOGIN; - state1 = SASL_LOGIN; - state2 = SASL_LOGIN_PASSWD; - sasl->authused = SASL_MECH_LOGIN; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_login_message(data, conn->user, &resp, &len); - } else if(enabledmechs & SASL_MECH_PLAIN) { mech = SASL_MECH_STRING_PLAIN; state1 = SASL_PLAIN; @@ -379,6 +373,15 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, result = Curl_auth_create_plain_message(data, conn->user, conn->passwd, &resp, &len); } + else if(enabledmechs & SASL_MECH_LOGIN) { + mech = SASL_MECH_STRING_LOGIN; + state1 = SASL_LOGIN; + state2 = SASL_LOGIN_PASSWD; + sasl->authused = SASL_MECH_LOGIN; + + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_login_message(data, conn->user, &resp, &len); + } } if(!result && mech) { @@ -419,13 +422,11 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, char *chlg = NULL; size_t chlglen = 0; #endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) +#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ + defined(USE_NTLM) const char *service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : sasl->params->service; -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ - defined(USE_NTLM) char *serverdata; #endif size_t len = 0; @@ -496,6 +497,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, /* Create the type-1 message */ result = Curl_auth_create_ntlm_type1_message(data, conn->user, conn->passwd, + service, hostname, &conn->ntlm, &resp, &len); newstate = SASL_NTLM_TYPE2MSG; break; diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 72b6de98eb..5593a3b5c2 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,9 +22,6 @@ * ***************************************************************************/ -#define USE_SSLEAY -#define USE_OPENSSL - #if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES) #define CURL_NO_OLDIES #endif @@ -392,6 +389,11 @@ # define LSEEK_ERROR (off_t)-1 #endif +#ifndef SIZEOF_TIME_T +/* assume default size of time_t to be 32 bit */ +#define SIZEOF_TIME_T 4 +#endif + /* * Default sizeof(off_t) in case it hasn't been defined in config file. */ @@ -419,6 +421,41 @@ # endif #endif +#if (SIZEOF_CURL_OFF_T == 4) +# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF) +#else + /* assume CURL_SIZEOF_CURL_OFF_T == 8 */ +# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) +#endif +#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) + +#if (SIZEOF_TIME_T == 4) +# ifdef HAVE_TIME_T_UNSIGNED +# define TIME_T_MAX UINT_MAX +# define TIME_T_MIN 0 +# else +# define TIME_T_MAX INT_MAX +# define TIME_T_MIN INT_MIN +# endif +#else +# ifdef HAVE_TIME_T_UNSIGNED +# define TIME_T_MAX 0xFFFFFFFFFFFFFFFF +# define TIME_T_MIN 0 +# else +# define TIME_T_MAX 0x7FFFFFFFFFFFFFFF +# define TIME_T_MIN (-TIME_T_MAX - 1) +# endif +#endif + +#ifndef SIZE_T_MAX +/* some limits.h headers have this defined, some don't */ +#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) +#define SIZE_T_MAX 18446744073709551615U +#else +#define SIZE_T_MAX 4294967295U +#endif +#endif + /* * Arg 2 type for gethostname in case it hasn't been defined in config file. */ @@ -602,11 +639,6 @@ int netware_init(void); #error "Both libidn2 and WinIDN are enabled, choose one." #endif -#ifndef SIZEOF_TIME_T -/* assume default size of time_t to be 32 bit */ -#define SIZEOF_TIME_T 4 -#endif - #define LIBIDN_REQUIRED_VERSION "0.4.1" #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ @@ -746,11 +778,11 @@ endings either CRLF or LF so 't' is appropriate. # if defined(WIN32) || defined(__CYGWIN__) # define USE_RECV_BEFORE_SEND_WORKAROUND # endif -#else /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */ +#else /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ # ifdef USE_RECV_BEFORE_SEND_WORKAROUND # undef USE_RECV_BEFORE_SEND_WORKAROUND # endif -#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */ +#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ /* Detect Windows App environment which has a restricted access * to the Win32 APIs. */ @@ -763,4 +795,9 @@ endings either CRLF or LF so 't' is appropriate. # endif # endif +/* for systems that don't detect this in configure, use a sensible default */ +#ifndef CURL_SA_FAMILY_T +#define CURL_SA_FAMILY_T unsigned short +#endif + #endif /* HEADER_CURL_SETUP_H */ diff --git a/libs/libcurl/src/curl_setup_once.h b/libs/libcurl/src/curl_setup_once.h index a5b542c6ee..6d01ea156a 100644 --- a/libs/libcurl/src/curl_setup_once.h +++ b/libs/libcurl/src/curl_setup_once.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -101,7 +101,6 @@ # endif #endif - /* * Definition of timeval struct for platforms that don't have it. */ @@ -274,25 +273,6 @@ struct timeval { # define sfcntl fcntl #endif -/* - * Uppercase macro versions of ANSI/ISO is*() functions/macros which - * avoid negative number inputs with argument byte codes > 127. - */ - -#define ISSPACE(x) (isspace((int) ((unsigned char)x))) -#define ISDIGIT(x) (isdigit((int) ((unsigned char)x))) -#define ISALNUM(x) (isalnum((int) ((unsigned char)x))) -#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) -#define ISGRAPH(x) (isgraph((int) ((unsigned char)x))) -#define ISALPHA(x) (isalpha((int) ((unsigned char)x))) -#define ISPRINT(x) (isprint((int) ((unsigned char)x))) -#define ISUPPER(x) (isupper((int) ((unsigned char)x))) -#define ISLOWER(x) (islower((int) ((unsigned char)x))) -#define ISASCII(x) (isascii((int) ((unsigned char)x))) - -#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \ - (((unsigned char)x) == '\t')) - #define TOLOWER(x) (tolower((int) ((unsigned char)x))) @@ -347,6 +327,7 @@ struct timeval { #define FALSE false #endif +#include "curl_ctype.h" /* * Macro WHILE_FALSE may be used to build single-iteration do-while loops, diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 5917db36af..6b914353de 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -61,10 +61,12 @@ #include "strdup.h" #include "progress.h" #include "easyif.h" +#include "multiif.h" #include "select.h" #include "sendf.h" /* for failf function prototype */ #include "connect.h" /* for Curl_getconnectinfo */ #include "slist.h" +#include "mime.h" #include "amigaos.h" #include "non-ascii.h" #include "warnless.h" @@ -72,6 +74,7 @@ #include "sigpipe.h" #include "ssh.h" #include "setopt.h" +#include "http_digest.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -253,6 +256,13 @@ static CURLcode global_init(long flags, bool memoryfuncs) } #endif +#if defined(USE_LIBSSH) + if(ssh_init()) { + DEBUGF(fprintf(stderr, "Error: libssh_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif + if(flags & CURL_GLOBAL_ACK_EINTR) Curl_ack_eintr = 1; @@ -330,6 +340,10 @@ void curl_global_cleanup(void) (void)libssh2_exit(); #endif +#if defined(USE_LIBSSH) + (void)ssh_finalize(); +#endif + init_flags = 0; } @@ -732,6 +746,10 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) if(!data) return CURLE_BAD_FUNCTION_ARGUMENT; + if(data->set.errorbuffer) + /* clear this as early as possible */ + data->set.errorbuffer[0] = 0; + if(data->multi) { failf(data, "easy handle already used in multi handle"); return CURLE_FAILED_INIT; @@ -748,6 +766,9 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) data->multi_easy = multi; } + if(multi->in_callback) + return CURLE_RECURSIVE_API_CALL; + /* Copy the MAXCONNECTS option to the multi handle */ curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects); @@ -844,6 +865,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) /* Copy src->set into dst->set first, then deal with the strings afterwards */ dst->set = src->set; + Curl_mime_initpart(&dst->set.mimepost, dst); /* clear all string pointers first */ memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); @@ -867,7 +889,13 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) dst->set.postfields = dst->set.str[i]; } - return CURLE_OK; + /* Duplicate mime data. */ + result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost); + + if(src->set.resolve) + dst->change.resolve = dst->set.resolve; + + return result; } /* @@ -987,7 +1015,7 @@ void curl_easy_reset(struct Curl_easy *data) /* zero out UserDefined data: */ Curl_freeset(data); memset(&data->set, 0, sizeof(struct UserDefined)); - (void)Curl_init_userdefined(&data->set); + (void)Curl_init_userdefined(data); /* zero out Progress data: */ memset(&data->progress, 0, sizeof(struct Progress)); @@ -1001,6 +1029,7 @@ void curl_easy_reset(struct Curl_easy *data) /* zero out authentication data: */ memset(&data->state.authhost, 0, sizeof(struct auth)); memset(&data->state.authproxy, 0, sizeof(struct auth)); + Curl_digest_cleanup(data); } /* @@ -1012,6 +1041,9 @@ void curl_easy_reset(struct Curl_easy *data) * the pausing, you may get your write callback called at this point. * * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h + * + * NOTE: This is one of few API functions that are allowed to be called from + * within a callback. */ CURLcode curl_easy_pause(struct Curl_easy *data, int action) { @@ -1034,6 +1066,8 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) unsigned int i; unsigned int count = data->state.tempcount; struct tempbuf writebuf[3]; /* there can only be three */ + struct connectdata *conn = data->easy_conn; + struct Curl_easy *saved_data = NULL; /* copy the structs to allow for immediate re-pausing */ for(i = 0; i < data->state.tempcount; i++) { @@ -1042,16 +1076,25 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) } data->state.tempcount = 0; + /* set the connection's current owner */ + if(conn->data != data) { + saved_data = conn->data; + conn->data = data; + } + for(i = 0; i < count; i++) { /* even if one function returns error, this loops through and frees all buffers */ if(!result) - result = Curl_client_chop_write(data->easy_conn, - writebuf[i].type, - writebuf[i].buf, - writebuf[i].len); + result = Curl_client_write(conn, writebuf[i].type, writebuf[i].buf, + writebuf[i].len); free(writebuf[i].buf); } + + /* recover previous owner of the connection */ + if(saved_data) + conn->data = saved_data; + if(result) return result; } @@ -1063,6 +1106,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) ) Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ + /* This transfer may have been moved in or out of the bundle, update + the corresponding socket callback, if used */ + Curl_updatesocket(data); + return result; } @@ -1103,6 +1150,9 @@ CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen, ssize_t n1; struct connectdata *c; + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + result = easy_connection(data, &sfd, &c); if(result) return result; @@ -1130,6 +1180,9 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, ssize_t n1; struct connectdata *c = NULL; + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + result = easy_connection(data, &sfd, &c); if(result) return result; diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c index 0bbc0e1800..db04cc2daf 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -61,6 +61,7 @@ #include "url.h" #include "parsedate.h" /* for the week day and month names */ #include "warnless.h" +#include "curl_range.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -125,65 +126,6 @@ static CURLcode file_setup_connection(struct connectdata *conn) return CURLE_OK; } - /* - Check if this is a range download, and if so, set the internal variables - properly. This code is copied from the FTP implementation and might as - well be factored out. - */ -static CURLcode file_range(struct connectdata *conn) -{ - curl_off_t from, to; - curl_off_t totalsize = -1; - char *ptr; - char *ptr2; - struct Curl_easy *data = conn->data; - - if(data->state.use_range && data->state.range) { - CURLofft from_t; - CURLofft to_t; - from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); - if(from_t == CURL_OFFT_FLOW) - return CURLE_RANGE_ERROR; - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) - ptr++; - to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); - if(to_t == CURL_OFFT_FLOW) - return CURLE_RANGE_ERROR; - if((to_t == CURL_OFFT_INVAL) && !from_t) { - /* X - */ - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", - from)); - } - else if((from_t == CURL_OFFT_INVAL) && !to_t) { - /* -Y */ - data->req.maxdownload = to; - data->state.resume_from = -to; - DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n", - to)); - } - else { - /* X-Y */ - totalsize = to-from; - if(totalsize == CURL_OFF_T_MAX) - /* this is too big to increase, so bail out */ - return CURLE_RANGE_ERROR; - data->req.maxdownload = totalsize + 1; /* include last byte */ - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T - " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", - from, data->req.maxdownload)); - } - DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T - " to %" CURL_FORMAT_CURL_OFF_T ", totally %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - from, to, data->req.maxdownload)); - } - else - data->req.maxdownload = -1; - return CURLE_OK; -} - /* * file_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. We emulate a @@ -461,12 +403,12 @@ static CURLcode file_do(struct connectdata *conn, bool *done) /* we could stat it, then read out the size */ expected_size = statbuf.st_size; /* and store the modification time */ - data->info.filetime = (long)statbuf.st_mtime; + data->info.filetime = statbuf.st_mtime; fstated = TRUE; } if(fstated && !data->state.range && data->set.timecondition) { - if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) { + if(!Curl_meets_timecondition(data, data->info.filetime)) { *done = TRUE; return CURLE_OK; } @@ -514,7 +456,9 @@ static CURLcode file_do(struct connectdata *conn, bool *done) } /* Check whether file range has been specified */ - file_range(conn); + result = Curl_range(conn); + if(result) + return result; /* Adjust the start offset in case we want to get the N last bytes * of the stream iff the filesize could be determined */ diff --git a/libs/libcurl/src/fileinfo.c b/libs/libcurl/src/fileinfo.c index 3872988474..4e72e1eba0 100644 --- a/libs/libcurl/src/fileinfo.c +++ b/libs/libcurl/src/fileinfo.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -33,14 +33,11 @@ struct fileinfo *Curl_fileinfo_alloc(void) return calloc(1, sizeof(struct fileinfo)); } -void Curl_fileinfo_dtor(void *user, void *element) +void Curl_fileinfo_cleanup(struct fileinfo *finfo) { - struct fileinfo *finfo = element; - (void) user; if(!finfo) return; Curl_safefree(finfo->info.b_data); - free(finfo); } diff --git a/libs/libcurl/src/fileinfo.h b/libs/libcurl/src/fileinfo.h index c5d0ee5b64..f4d8f3b90e 100644 --- a/libs/libcurl/src/fileinfo.h +++ b/libs/libcurl/src/fileinfo.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010, 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,7 +31,6 @@ struct fileinfo { }; struct fileinfo *Curl_fileinfo_alloc(void); - -void Curl_fileinfo_dtor(void *, void *); +void Curl_fileinfo_cleanup(struct fileinfo *finfo); #endif /* HEADER_CURL_FILEINFO_H */ diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c index d0579c52fe..f912410526 100644 --- a/libs/libcurl/src/formdata.c +++ b/libs/libcurl/src/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -155,60 +155,6 @@ static FormInfo * AddFormInfo(char *value, /*************************************************************************** * - * ContentTypeForFilename() - * - * Provides content type for filename if one of the known types (else - * (either the prevtype or the default is returned). - * - * Returns some valid contenttype for filename. - * - ***************************************************************************/ -static const char *ContentTypeForFilename(const char *filename, - const char *prevtype) -{ - const char *contenttype = NULL; - unsigned int i; - /* - * No type was specified, we scan through a few well-known - * extensions and pick the first we match! - */ - struct ContentType { - const char *extension; - const char *type; - }; - static const struct ContentType ctts[]={ - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".jpeg", "image/jpeg"}, - {".txt", "text/plain"}, - {".html", "text/html"}, - {".xml", "application/xml"} - }; - - if(prevtype) - /* default to the previously set/used! */ - contenttype = prevtype; - else - contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; - - if(filename) { /* in case a NULL was passed in */ - for(i = 0; i<sizeof(ctts)/sizeof(ctts[0]); i++) { - if(strlen(filename) >= strlen(ctts[i].extension)) { - if(strcasecompare(filename + - strlen(filename) - strlen(ctts[i].extension), - ctts[i].extension)) { - contenttype = ctts[i].type; - break; - } - } - } - } - /* we have a contenttype by now */ - return contenttype; -} - -/*************************************************************************** - * * FormAdd() * * Stores a formpost parameter and builds the appropriate linked list. @@ -627,9 +573,15 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, !form->contenttype) { char *f = form->flags & HTTPPOST_BUFFER? form->showfilename : form->value; + char const *type; + type = Curl_mime_contenttype(f); + if(!type) + type = prevtype; + if(!type) + type = FILE_CONTENTTYPE_DEFAULT; /* our contenttype is missing */ - form->contenttype = strdup(ContentTypeForFilename(f, prevtype)); + form->contenttype = strdup(type); if(!form->contenttype) { return_value = CURL_FORMADD_MEMORY; break; diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index 8042edf488..4e074a111a 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -59,6 +59,7 @@ #include "ftp.h" #include "fileinfo.h" #include "ftplistparser.h" +#include "curl_range.h" #include "curl_sec.h" #include "strtoofft.h" #include "strcase.h" @@ -310,9 +311,11 @@ static CURLcode AcceptServerConnect(struct connectdata *conn) int error = 0; /* activate callback for setting socket options */ + Curl_set_in_callback(data, true); error = data->set.fsockopt(data->set.sockopt_client, s, CURLSOCKTYPE_ACCEPT); + Curl_set_in_callback(data, false); if(error) { close_secondarysocket(conn); @@ -1471,7 +1474,7 @@ static CURLcode ftp_state_list(struct connectdata *conn) slashPos = strrchr(inpath, '/'); n = slashPos - inpath; } - result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE); + result = Curl_urldecode(data, inpath, n, &lstArg, NULL, TRUE); if(result) return result; } @@ -1535,7 +1538,7 @@ static CURLcode ftp_state_type(struct connectdata *conn) date. */ if(data->set.opt_no_body && ftpc->file && ftp_need_type(conn, data->set.prefer_ascii)) { - /* The SIZE command is _not_ RFC 959 specified, and therefor many servers + /* The SIZE command is _not_ RFC 959 specified, and therefore many servers may not support it! It is however the only way we have to get a file's size! */ @@ -1615,8 +1618,10 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, /* Let's read off the proper amount of bytes from the input. */ if(conn->seek_func) { + Curl_set_in_callback(data, true); seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, SEEK_SET); + Curl_set_in_callback(data, false); } if(seekerr != CURL_SEEKFUNC_OK) { @@ -1783,7 +1788,7 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn) { CURLcode result = CURLE_OK; - if(conn->bits.ipv6) { + if(conn->bits.ipv6 && !(conn->bits.tunnel_proxy || conn->bits.socksproxy)) { /* We can't disable EPSV when doing IPv6, so this is instead a fail */ failf(conn->data, "Failed EPSV attempt, exiting\n"); return CURLE_WEIRD_SERVER_REPLY; @@ -1905,13 +1910,13 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, if(data->set.ftp_skip_ip) { /* told to ignore the remotely given IP but instead use the host we used for the control connection */ - infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n", + infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead\n", ip[0], ip[1], ip[2], ip[3], conn->host.name); ftpc->newhost = strdup(control_address(conn)); } else - ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + ftpc->newhost = aprintf("%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); if(!ftpc->newhost) return CURLE_OUT_OF_MEMORY; @@ -2060,7 +2065,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, "%04d%02d%02d %02d:%02d:%02d GMT", year, month, day, hour, minute, second); /* now, convert this into a time() value: */ - data->info.filetime = (long)curl_getdate(timebuf, &secs); + data->info.filetime = curl_getdate(timebuf, &secs); } #ifdef CURL_FTP_HTTPSTYLE_HEAD @@ -2072,7 +2077,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, data->set.get_filetime && (data->info.filetime >= 0) ) { char headerbuf[128]; - time_t filetime = (time_t)data->info.filetime; + time_t filetime = data->info.filetime; struct tm buffer; const struct tm *tm = &buffer; @@ -3180,14 +3185,16 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, if(data->state.wildcardmatch) { if(data->set.chunk_end && ftpc->file) { + Curl_set_in_callback(data, true); data->set.chunk_end(data->wildcard.customptr); + Curl_set_in_callback(data, false); } ftpc->known_filesize = -1; } if(!result) /* get the "raw" path */ - result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE); + result = Curl_urldecode(data, path_to_use, 0, &path, NULL, TRUE); if(result) { /* We can limp along anyway (and should try to since we may already be in * the error path) */ @@ -3463,62 +3470,6 @@ ftp_pasv_verbose(struct connectdata *conn, #endif /* - Check if this is a range download, and if so, set the internal variables - properly. - */ - -static CURLcode ftp_range(struct connectdata *conn) -{ - curl_off_t from, to; - char *ptr; - struct Curl_easy *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if(data->state.use_range && data->state.range) { - CURLofft from_t; - CURLofft to_t; - from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); - if(from_t == CURL_OFFT_FLOW) - return CURLE_RANGE_ERROR; - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) - ptr++; - to_t = curlx_strtoofft(ptr, NULL, 0, &to); - if(to_t == CURL_OFFT_FLOW) - return CURLE_RANGE_ERROR; - if((to_t == CURL_OFFT_INVAL) && !from_t) { - /* X - */ - data->state.resume_from = from; - DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T - " to end of file\n", from)); - } - else if(!to_t && (from_t == CURL_OFFT_INVAL)) { - /* -Y */ - data->req.maxdownload = to; - data->state.resume_from = -to; - DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T - " bytes\n", to)); - } - else { - /* X-Y */ - data->req.maxdownload = (to - from) + 1; /* include last byte */ - data->state.resume_from = from; - DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T - " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", - from, data->req.maxdownload)); - } - DEBUGF(infof(conn->data, "range-download from %" CURL_FORMAT_CURL_OFF_T - " to %" CURL_FORMAT_CURL_OFF_T ", totally %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - from, to, data->req.maxdownload)); - ftpc->dont_check = TRUE; /* don't check for successful transfer */ - } - else - data->req.maxdownload = -1; - return CURLE_OK; -} - - -/* * ftp_do_more() * * This function shall be called when the second FTP (data) connection is @@ -3640,7 +3591,13 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep) /* download */ ftp->downloadsize = -1; /* unknown as of yet */ - result = ftp_range(conn); + result = Curl_range(conn); + + if(result == CURLE_OK && data->req.maxdownload >= 0) { + /* Don't check for successful transfer */ + ftpc->dont_check = TRUE; + } + if(result) ; else if(data->set.ftp_list_only || !ftpc->file) { @@ -3730,10 +3687,10 @@ CURLcode ftp_perform(struct connectdata *conn, static void wc_data_dtor(void *ptr) { - struct ftp_wc_tmpdata *tmp = ptr; - if(tmp) - Curl_ftp_parselist_data_free(&tmp->parser); - free(tmp); + struct ftp_wc *ftpwc = ptr; + if(ftpwc && ftpwc->parser) + Curl_ftp_parselist_data_free(&ftpwc->parser); + free(ftpwc); } static CURLcode init_wc_data(struct connectdata *conn) @@ -3742,7 +3699,7 @@ static CURLcode init_wc_data(struct connectdata *conn) char *path = conn->data->state.path; struct WildcardData *wildcard = &(conn->data->wildcard); CURLcode result = CURLE_OK; - struct ftp_wc_tmpdata *ftp_tmp; + struct ftp_wc *ftpwc = NULL; last_slash = strrchr(conn->data->state.path, '/'); if(last_slash) { @@ -3774,23 +3731,22 @@ static CURLcode init_wc_data(struct connectdata *conn) /* program continues only if URL is not ending with slash, allocate needed resources for wildcard transfer */ - /* allocate ftp protocol specific temporary wildcard data */ - ftp_tmp = calloc(1, sizeof(struct ftp_wc_tmpdata)); - if(!ftp_tmp) { - Curl_safefree(wildcard->pattern); - return CURLE_OUT_OF_MEMORY; + /* allocate ftp protocol specific wildcard data */ + ftpwc = calloc(1, sizeof(struct ftp_wc)); + if(!ftpwc) { + result = CURLE_OUT_OF_MEMORY; + goto fail; } /* INITIALIZE parselist structure */ - ftp_tmp->parser = Curl_ftp_parselist_data_alloc(); - if(!ftp_tmp->parser) { - Curl_safefree(wildcard->pattern); - free(ftp_tmp); - return CURLE_OUT_OF_MEMORY; + ftpwc->parser = Curl_ftp_parselist_data_alloc(); + if(!ftpwc->parser) { + result = CURLE_OUT_OF_MEMORY; + goto fail; } - wildcard->tmp = ftp_tmp; /* put it to the WildcardData tmp pointer */ - wildcard->tmp_dtor = wc_data_dtor; + wildcard->protdata = ftpwc; /* put it to the WildcardData tmp pointer */ + wildcard->dtor = wc_data_dtor; /* wildcard does not support NOCWD option (assert it?) */ if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD) @@ -3799,33 +3755,36 @@ static CURLcode init_wc_data(struct connectdata *conn) /* try to parse ftp url */ result = ftp_parse_url_path(conn); if(result) { - Curl_safefree(wildcard->pattern); - wildcard->tmp_dtor(wildcard->tmp); - wildcard->tmp_dtor = ZERO_NULL; - wildcard->tmp = NULL; - return result; + goto fail; } wildcard->path = strdup(conn->data->state.path); if(!wildcard->path) { - Curl_safefree(wildcard->pattern); - wildcard->tmp_dtor(wildcard->tmp); - wildcard->tmp_dtor = ZERO_NULL; - wildcard->tmp = NULL; - return CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; + goto fail; } /* backup old write_function */ - ftp_tmp->backup.write_function = conn->data->set.fwrite_func; + ftpwc->backup.write_function = conn->data->set.fwrite_func; /* parsing write function */ conn->data->set.fwrite_func = Curl_ftp_parselist; /* backup old file descriptor */ - ftp_tmp->backup.file_descriptor = conn->data->set.out; + ftpwc->backup.file_descriptor = conn->data->set.out; /* let the writefunc callback know what curl pointer is working with */ conn->data->set.out = conn; infof(conn->data, "Wildcard - Parsing started\n"); return CURLE_OK; + + fail: + if(ftpwc) { + Curl_ftp_parselist_data_free(&ftpwc->parser); + free(ftpwc); + } + Curl_safefree(wildcard->pattern); + wildcard->dtor = ZERO_NULL; + wildcard->protdata = NULL; + return result; } /* This is called recursively */ @@ -3846,14 +3805,14 @@ static CURLcode wc_statemach(struct connectdata *conn) case CURLWC_MATCHING: { /* In this state is LIST response successfully parsed, so lets restore previous WRITEFUNCTION callback and WRITEDATA pointer */ - struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp; - conn->data->set.fwrite_func = ftp_tmp->backup.write_function; - conn->data->set.out = ftp_tmp->backup.file_descriptor; - ftp_tmp->backup.write_function = ZERO_NULL; - ftp_tmp->backup.file_descriptor = NULL; + struct ftp_wc *ftpwc = wildcard->protdata; + conn->data->set.fwrite_func = ftpwc->backup.write_function; + conn->data->set.out = ftpwc->backup.file_descriptor; + ftpwc->backup.write_function = ZERO_NULL; + ftpwc->backup.file_descriptor = NULL; wildcard->state = CURLWC_DOWNLOADING; - if(Curl_ftp_parselist_geterror(ftp_tmp->parser)) { + if(Curl_ftp_parselist_geterror(ftpwc->parser)) { /* error found in LIST parsing */ wildcard->state = CURLWC_CLEAN; return wc_statemach(conn); @@ -3883,8 +3842,11 @@ static CURLcode wc_statemach(struct connectdata *conn) infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); if(conn->data->set.chunk_bgn) { - long userresponse = conn->data->set.chunk_bgn( + long userresponse; + Curl_set_in_callback(conn->data, true); + userresponse = conn->data->set.chunk_bgn( finfo, wildcard->customptr, (int)wildcard->filelist.size); + Curl_set_in_callback(conn->data, false); switch(userresponse) { case CURL_CHUNK_BGN_FUNC_SKIP: infof(conn->data, "Wildcard - \"%s\" skipped by user\n", @@ -3920,8 +3882,11 @@ static CURLcode wc_statemach(struct connectdata *conn) } break; case CURLWC_SKIP: { - if(conn->data->set.chunk_end) + if(conn->data->set.chunk_end) { + Curl_set_in_callback(conn->data, true); conn->data->set.chunk_end(conn->data->wildcard.customptr); + Curl_set_in_callback(conn->data, false); + } Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); wildcard->state = (wildcard->filelist.size == 0) ? CURLWC_CLEAN : CURLWC_DOWNLOADING; @@ -3929,10 +3894,10 @@ static CURLcode wc_statemach(struct connectdata *conn) } case CURLWC_CLEAN: { - struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp; + struct ftp_wc *ftpwc = wildcard->protdata; result = CURLE_OK; - if(ftp_tmp) - result = Curl_ftp_parselist_geterror(ftp_tmp->parser); + if(ftpwc) + result = Curl_ftp_parselist_geterror(ftpwc->parser); wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; } break; @@ -3940,6 +3905,8 @@ static CURLcode wc_statemach(struct connectdata *conn) case CURLWC_DONE: case CURLWC_ERROR: case CURLWC_CLEAR: + if(wildcard->dtor) + wildcard->dtor(wildcard->protdata); break; } @@ -4192,7 +4159,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/", slash_pos ? dirlen : 1, &ftpc->dirs[0], NULL, - FALSE); + TRUE); if(result) { freedirs(ftpc); return result; @@ -4299,7 +4266,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) size_t dlen; char *path; CURLcode result = - Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE); + Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, TRUE); if(result) { freedirs(ftpc); return result; diff --git a/libs/libcurl/src/ftp.h b/libs/libcurl/src/ftp.h index e4aa63f178..7ec339118e 100644 --- a/libs/libcurl/src/ftp.h +++ b/libs/libcurl/src/ftp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -81,7 +81,7 @@ typedef enum { struct ftp_parselist_data; /* defined later in ftplistparser.c */ -struct ftp_wc_tmpdata { +struct ftp_wc { struct ftp_parselist_data *parser; struct { diff --git a/libs/libcurl/src/ftplistparser.c b/libs/libcurl/src/ftplistparser.c index 262ac03062..249fe09c84 100644 --- a/libs/libcurl/src/ftplistparser.c +++ b/libs/libcurl/src/ftplistparser.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -49,6 +49,7 @@ #include "ftplistparser.h" #include "curl_fnmatch.h" #include "curl_memory.h" +#include "multiif.h" /* The last #include file should be: */ #include "memdebug.h" @@ -184,10 +185,13 @@ struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void) } -void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data) +void Curl_ftp_parselist_data_free(struct ftp_parselist_data **parserp) { - free(*pl_data); - *pl_data = NULL; + struct ftp_parselist_data *parser = *parserp; + if(parser) + Curl_fileinfo_cleanup(parser->file_data); + free(parser); + *parserp = NULL; } @@ -269,9 +273,9 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, { curl_fnmatch_callback compare; struct WildcardData *wc = &conn->data->wildcard; - struct ftp_wc_tmpdata *tmpdata = wc->tmp; + struct ftp_wc *ftpwc = wc->protdata; struct curl_llist *llist = &wc->filelist; - struct ftp_parselist_data *parser = tmpdata->parser; + struct ftp_parselist_data *parser = ftpwc->parser; bool add = TRUE; struct curl_fileinfo *finfo = &infop->info; @@ -294,6 +298,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, compare = Curl_fnmatch; /* filter pattern-corresponding filenames */ + Curl_set_in_callback(conn->data, true); if(compare(conn->data->set.fnmatch_data, wc->pattern, finfo->filename) == 0) { /* discard symlink which is containing multiple " -> " */ @@ -305,15 +310,16 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, else { add = FALSE; } + Curl_set_in_callback(conn->data, false); if(add) { Curl_llist_insert_next(llist, llist->tail, finfo, &infop->list); } else { - Curl_fileinfo_dtor(NULL, finfo); + Curl_fileinfo_cleanup(infop); } - tmpdata->parser->file_data = NULL; + ftpwc->parser->file_data = NULL; return CURLE_OK; } @@ -322,8 +328,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, { size_t bufflen = size*nmemb; struct connectdata *conn = (struct connectdata *)connptr; - struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp; - struct ftp_parselist_data *parser = tmpdata->parser; + struct ftp_wc *ftpwc = conn->data->wildcard.protdata; + struct ftp_parselist_data *parser = ftpwc->parser; struct fileinfo *infop; struct curl_fileinfo *finfo; unsigned long i = 0; @@ -378,7 +384,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, finfo->b_data = tmp; } else { - Curl_fileinfo_dtor(NULL, parser->file_data); + Curl_fileinfo_cleanup(parser->file_data); parser->file_data = NULL; parser->error = CURLE_OUT_OF_MEMORY; goto fail; @@ -1000,12 +1006,13 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, i++; } + return retsize; fail: /* Clean up any allocated memory. */ if(parser->file_data) { - Curl_fileinfo_dtor(NULL, parser->file_data); + Curl_fileinfo_cleanup(parser->file_data); parser->file_data = NULL; } diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c index 862ced0194..d280eebfaf 100644 --- a/libs/libcurl/src/getinfo.c +++ b/libs/libcurl/src/getinfo.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -156,7 +156,12 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, *param_longp = data->info.httpproxycode; break; case CURLINFO_FILETIME: - *param_longp = data->info.filetime; + if(data->info.filetime > LONG_MAX) + *param_longp = LONG_MAX; + else if(data->info.filetime < LONG_MIN) + *param_longp = LONG_MIN; + else + *param_longp = (long)data->info.filetime; break; case CURLINFO_HEADER_SIZE: *param_longp = data->info.header_size; @@ -253,6 +258,9 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info, curl_off_t *param_offt) { switch(info) { + case CURLINFO_FILETIME_T: + *param_offt = (curl_off_t)data->info.filetime; + break; case CURLINFO_SIZE_UPLOAD_T: *param_offt = data->progress.uploaded; break; diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c index c99b1b6994..15a128fecc 100644 --- a/libs/libcurl/src/hash.c +++ b/libs/libcurl/src/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -261,11 +261,11 @@ size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num) { const char *key_str = (const char *) key; const char *end = key_str + key_length; - unsigned long h = 5381; + size_t h = 5381; while(key_str < end) { h += h << 5; - h ^= (unsigned long) *key_str++; + h ^= *key_str++; } return (h % slots_num); diff --git a/libs/libcurl/src/hostcheck.c b/libs/libcurl/src/hostcheck.c index 23dc3d2a7c..c9d8112d86 100644 --- a/libs/libcurl/src/hostcheck.c +++ b/libs/libcurl/src/hostcheck.c @@ -25,12 +25,15 @@ #if defined(USE_OPENSSL) \ || defined(USE_AXTLS) \ || defined(USE_GSKIT) \ - || (defined(USE_SCHANNEL) && defined(_WIN32_WCE)) + || defined(USE_SCHANNEL) /* these backends use functions from this file */ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#ifdef HAVE_NETINET_IN6_H +#include <netinet/in6.h> +#endif #include "hostcheck.h" #include "strcase.h" diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index 7f010a0379..c2f9defd94 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -25,6 +25,9 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#ifdef HAVE_NETINET_IN6_H +#include <netinet/in6.h> +#endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif @@ -51,10 +54,12 @@ #include "sendf.h" #include "hostip.h" #include "hash.h" +#include "rand.h" #include "share.h" #include "strerror.h" #include "url.h" #include "inet_ntop.h" +#include "multiif.h" #include "warnless.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -363,6 +368,70 @@ Curl_fetch_addr(struct connectdata *conn, } /* + * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' + * struct by re-linking its linked list. + * + * The addr argument should be the address of a pointer to the head node of a + * `Curl_addrinfo` list and it will be modified to point to the new head after + * shuffling. + * + * Not declared static only to make it easy to use in a unit test! + * + * @unittest: 1608 + */ +CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr) +{ + CURLcode result = CURLE_OK; + const int num_addrs = Curl_num_addresses(*addr); + + if(num_addrs > 1) { + Curl_addrinfo **nodes; + infof(data, "Shuffling %i addresses", num_addrs); + + nodes = malloc(num_addrs*sizeof(*nodes)); + if(nodes) { + int i; + unsigned int *rnd; + const size_t rnd_size = num_addrs * sizeof(*rnd); + + /* build a plain array of Curl_addrinfo pointers */ + nodes[0] = *addr; + for(i = 1; i < num_addrs; i++) { + nodes[i] = nodes[i-1]->ai_next; + } + + rnd = malloc(rnd_size); + if(rnd) { + /* Fisher-Yates shuffle */ + if(Curl_rand(data, (unsigned char *)rnd, rnd_size) == CURLE_OK) { + Curl_addrinfo *swap_tmp; + for(i = num_addrs - 1; i > 0; i--) { + swap_tmp = nodes[rnd[i] % (i + 1)]; + nodes[rnd[i] % (i + 1)] = nodes[i]; + nodes[i] = swap_tmp; + } + + /* relink list in the new order */ + for(i = 1; i < num_addrs; i++) { + nodes[i-1]->ai_next = nodes[i]; + } + + nodes[num_addrs-1]->ai_next = NULL; + *addr = nodes[0]; + } + free(rnd); + } + else + result = CURLE_OUT_OF_MEMORY; + free(nodes); + } + else + result = CURLE_OUT_OF_MEMORY; + } + return result; +} + +/* * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. * * When calling Curl_resolv() has resulted in a response with a returned @@ -382,6 +451,13 @@ Curl_cache_addr(struct Curl_easy *data, struct Curl_dns_entry *dns; struct Curl_dns_entry *dns2; + /* shuffle addresses if requested */ + if(data->set.dns_shuffle_addresses) { + CURLcode result = Curl_shuffle_addr(data, &addr); + if(!result) + return NULL; + } + /* Create an entry id, based upon the hostname and port */ entry_id = create_hostcache_id(hostname, port); /* If we can't create the entry id, fail */ @@ -478,6 +554,17 @@ int Curl_resolv(struct connectdata *conn, if(!Curl_ipvalid(conn)) return CURLRESOLV_ERROR; + /* notify the resolver start callback */ + if(data->set.resolver_start) { + int st; + Curl_set_in_callback(data, true); + st = data->set.resolver_start(data->state.resolver, NULL, + data->set.resolver_start_client); + Curl_set_in_callback(data, false); + if(st) + return CURLRESOLV_ERROR; + } + /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a non-zero value indicating that we need to wait for the response to the resolve call */ @@ -778,7 +865,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) { struct curl_slist *hostp; char hostname[256]; - int port; + int port = 0; for(hostp = data->change.resolve; hostp; hostp = hostp->next) { if(!hostp->data) @@ -816,32 +903,95 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) } else { struct Curl_dns_entry *dns; - Curl_addrinfo *addr; + Curl_addrinfo *head = NULL, *tail = NULL; char *entry_id; size_t entry_len; - char buffer[256]; - char *address = &buffer[0]; + char address[64]; + char *addresses = NULL; + char *addr_begin; + char *addr_end; + char *port_ptr; + char *end_ptr; + char *host_end; + unsigned long tmp_port; + bool error = true; + + host_end = strchr(hostp->data, ':'); + if(!host_end || + ((host_end - hostp->data) >= (ptrdiff_t)sizeof(hostname))) + goto err; + + memcpy(hostname, hostp->data, host_end - hostp->data); + hostname[host_end - hostp->data] = '\0'; + + port_ptr = host_end + 1; + tmp_port = strtoul(port_ptr, &end_ptr, 10); + if(tmp_port > USHRT_MAX || end_ptr == port_ptr || *end_ptr != ':') + goto err; + + port = (int)tmp_port; + addresses = end_ptr + 1; + + while(*end_ptr) { + size_t alen; + Curl_addrinfo *ai; + + addr_begin = end_ptr + 1; + addr_end = strchr(addr_begin, ','); + if(!addr_end) + addr_end = addr_begin + strlen(addr_begin); + end_ptr = addr_end; + + /* allow IP(v6) address within [brackets] */ + if(*addr_begin == '[') { + if(addr_end == addr_begin || *(addr_end - 1) != ']') + goto err; + ++addr_begin; + --addr_end; + } - if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port, - address)) { - infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", - hostp->data); - continue; - } + alen = addr_end - addr_begin; + if(!alen) + continue; + + if(alen >= sizeof(address)) + goto err; + + memcpy(address, addr_begin, alen); + address[alen] = '\0'; - /* allow IP(v6) address within [brackets] */ - if(address[0] == '[') { - size_t alen = strlen(address); - if(address[alen-1] != ']') - /* it needs to also end with ] to be valid */ +#ifndef ENABLE_IPV6 + if(strchr(address, ':')) { + infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n", + address); continue; - address[alen-1] = 0; /* zero terminate there */ - address++; /* pass the open bracket */ + } +#endif + + ai = Curl_str2addr(address, port); + if(!ai) { + infof(data, "Resolve address '%s' found illegal!\n", address); + goto err; + } + + if(tail) { + tail->ai_next = ai; + tail = tail->ai_next; + } + else { + head = tail = ai; + } } - addr = Curl_str2addr(address, port); - if(!addr) { - infof(data, "Address in '%s' found illegal!\n", hostp->data); + if(!head) + goto err; + + error = false; + err: + if(error) { + infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", + hostp->data); + Curl_freeaddrinfo(head); continue; } @@ -849,10 +999,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) entry_id = create_hostcache_id(hostname, port); /* If we can't create the entry id, fail */ if(!entry_id) { - Curl_freeaddrinfo(addr); + Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } - entry_len = strlen(entry_id); if(data->share) @@ -866,7 +1015,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) if(!dns) { /* if not in the cache already, put this host in the cache */ - dns = Curl_cache_addr(data, addr, hostname, port); + dns = Curl_cache_addr(data, head, hostname, port); if(dns) { dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */ /* release the returned reference; the cache itself will keep the @@ -874,19 +1023,22 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) dns->inuse--; } } - else + else { /* this is a duplicate, free it again */ - Curl_freeaddrinfo(addr); + infof(data, "RESOLVE %s:%d is already cached, %s not stored!\n", + hostname, port, addresses); + Curl_freeaddrinfo(head); + } if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); if(!dns) { - Curl_freeaddrinfo(addr); + Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } infof(data, "Added %s:%d:%s to DNS cache\n", - hostname, port, address); + hostname, port, addresses); } } data->change.resolve = NULL; /* dealt with now */ diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h index 298eeeee3b..1de4bee8d6 100644 --- a/libs/libcurl/src/hostip.h +++ b/libs/libcurl/src/hostip.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -182,6 +182,17 @@ struct Curl_dns_entry * Curl_fetch_addr(struct connectdata *conn, const char *hostname, int port); + +/* + * Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo' + * struct by re-linking its linked list. + * + * The addr argument should be the address of a pointer to the head node of a + * `Curl_addrinfo` list and it will be modified to point to the new head after + * shuffling. + */ +CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr); + /* * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. * diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index def51abc37..ff1d6813a0 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -92,6 +92,8 @@ static int http_getsock_do(struct connectdata *conn, int numsocks); static int http_should_fail(struct connectdata *conn); +static CURLcode add_haproxy_protocol_header(struct connectdata *conn); + #ifdef USE_SSL static CURLcode https_connecting(struct connectdata *conn, bool *done); static int https_getsock(struct connectdata *conn, @@ -177,9 +179,9 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn) * if proxy headers are not available, then it will lookup into http header * link list * - * It takes a connectdata struct as input instead of the Curl_easy simply - * to know if this is a proxy request or not, as it then might check a - * different header list. + * It takes a connectdata struct as input instead of the Curl_easy simply to + * know if this is a proxy request or not, as it then might check a different + * header list. Provide the header prefix without colon!. */ char *Curl_checkProxyheaders(const struct connectdata *conn, const char *thisheader) @@ -191,7 +193,8 @@ char *Curl_checkProxyheaders(const struct connectdata *conn, for(head = (conn->bits.proxy && data->set.sep_headers) ? data->set.proxyheaders : data->set.headers; head; head = head->next) { - if(strncasecompare(head->data, thisheader, thislen)) + if(strncasecompare(head->data, thisheader, thislen) && + Curl_headersep(head->data[thislen])) return head->data; } @@ -211,8 +214,6 @@ char *Curl_copy_header_value(const char *header) char *value; size_t len; - DEBUGASSERT(header); - /* Find the end of the header name */ while(*header && (*header != ':')) ++header; @@ -432,7 +433,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn) data left to send, keep on sending. */ /* rewind data when completely done sending! */ - if(!conn->bits.authneg) { + if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { conn->bits.rewindaftersend = TRUE; infof(data, "Rewind stream after send\n"); } @@ -614,9 +615,9 @@ output_auth_headers(struct connectdata *conn, if(authstatus->picked == CURLAUTH_BASIC) { /* Basic */ if((proxy && conn->bits.proxy_user_passwd && - !Curl_checkProxyheaders(conn, "Proxy-authorization:")) || + !Curl_checkProxyheaders(conn, "Proxy-authorization")) || (!proxy && conn->bits.user_passwd && - !Curl_checkheaders(conn, "Authorization:"))) { + !Curl_checkheaders(conn, "Authorization"))) { auth = "Basic"; result = http_output_basic(conn, proxy); if(result) @@ -714,7 +715,7 @@ Curl_http_output_auth(struct connectdata *conn, if(!data->state.this_is_a_follow || conn->bits.netrc || !data->state.first_host || - data->set.http_disable_hostname_check_before_authentication || + data->set.allow_auth_to_other_hosts || strcasecompare(data->state.first_host, conn->host.name)) { result = output_auth_headers(conn, authhost, request, path, FALSE); } @@ -1357,6 +1358,13 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done) /* nothing else to do except wait right now - we're not done here. */ return CURLE_OK; + if(conn->data->set.haproxyprotocol) { + /* add HAProxy PROXY protocol header */ + result = add_haproxy_protocol_header(conn); + if(result) + return result; + } + if(conn->given->protocol & CURLPROTO_HTTPS) { /* perform SSL initialization */ result = https_connecting(conn, done); @@ -1382,6 +1390,47 @@ static int http_getsock_do(struct connectdata *conn, return GETSOCK_WRITESOCK(0); } +static CURLcode add_haproxy_protocol_header(struct connectdata *conn) +{ + char proxy_header[128]; + Curl_send_buffer *req_buffer; + CURLcode result; + char tcp_version[5]; + + /* Emit the correct prefix for IPv6 */ + if(conn->bits.ipv6) { + strcpy(tcp_version, "TCP6"); + } + else { + strcpy(tcp_version, "TCP4"); + } + + snprintf(proxy_header, + sizeof proxy_header, + "PROXY %s %s %s %li %li\r\n", + tcp_version, + conn->data->info.conn_local_ip, + conn->data->info.conn_primary_ip, + conn->data->info.conn_local_port, + conn->data->info.conn_primary_port); + + req_buffer = Curl_add_buffer_init(); + if(!req_buffer) + return CURLE_OUT_OF_MEMORY; + + result = Curl_add_bufferf(req_buffer, proxy_header); + if(result) + return result; + + result = Curl_add_buffer_send(req_buffer, + conn, + &conn->data->info.request_size, + 0, + FIRSTSOCKET); + + return result; +} + #ifdef USE_SSL static CURLcode https_connecting(struct connectdata *conn, bool *done) { @@ -1533,7 +1582,7 @@ static CURLcode expect100(struct Curl_easy *data, /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an Expect: 100-continue to the headers which actually speeds up post operations (as there is one packet coming back from the web server) */ - ptr = Curl_checkheaders(conn, "Expect:"); + ptr = Curl_checkheaders(conn, "Expect"); if(ptr) { data->state.expect100header = Curl_compareheader(ptr, "Expect:", "100-continue"); @@ -1598,7 +1647,32 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, headers = h[i]; while(headers) { + char *semicolonp = NULL; ptr = strchr(headers->data, ':'); + if(!ptr) { + char *optr; + /* no colon, semicolon? */ + ptr = strchr(headers->data, ';'); + if(ptr) { + optr = ptr; + ptr++; /* pass the semicolon */ + while(*ptr && ISSPACE(*ptr)) + ptr++; + + if(*ptr) { + /* this may be used for something else in the future */ + optr = NULL; + } + else { + if(*(--ptr) == ';') { + /* send no-value custom header if terminated by semicolon */ + *ptr = ':'; + semicolonp = ptr; + } + } + ptr = optr; + } + } if(ptr) { /* we require a colon for this to be a true header */ @@ -1606,8 +1680,9 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, while(*ptr && ISSPACE(*ptr)) ptr++; - if(*ptr) { - /* only send this if the contents was non-blank */ + if(*ptr || semicolonp) { + /* only send this if the contents was non-blank or done special */ + CURLcode result = CURLE_OK; if(conn->allocptr.host && /* a Host: header was sent already, don't pass on any custom Host: @@ -1636,41 +1711,21 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, checkprefix("Transfer-Encoding:", headers->data)) /* HTTP/2 doesn't support chunked requests */ ; + else if(checkprefix("Authorization:", headers->data) && + /* be careful of sending this potentially sensitive header to + other hosts */ + (data->state.this_is_a_follow && + data->state.first_host && + !data->set.allow_auth_to_other_hosts && + !strcasecompare(data->state.first_host, conn->host.name))) + ; else { - CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n", - headers->data); - if(result) - return result; - } - } - } - else { - ptr = strchr(headers->data, ';'); - if(ptr) { - - ptr++; /* pass the semicolon */ - while(*ptr && ISSPACE(*ptr)) - ptr++; - - if(*ptr) { - /* this may be used for something else in the future */ - } - else { - if(*(--ptr) == ';') { - CURLcode result; - - /* send no-value custom header if terminated by semicolon */ - *ptr = ':'; - result = Curl_add_bufferf(req_buffer, "%s\r\n", - headers->data); - - /* restore the previous value */ - *ptr = ';'; - - if(result) - return result; - } + result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data); } + if(semicolonp) + *semicolonp = ';'; /* put back the semicolon */ + if(result) + return result; } } headers = headers->next; @@ -1861,7 +1916,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) it might have been used in the proxy connect, but if we have got a header with the user-agent string specified, we erase the previously made string here. */ - if(Curl_checkheaders(conn, "User-Agent:")) { + if(Curl_checkheaders(conn, "User-Agent")) { free(conn->allocptr.uagent); conn->allocptr.uagent = NULL; } @@ -1882,7 +1937,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) conn->bits.authneg = FALSE; Curl_safefree(conn->allocptr.ref); - if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) { + if(data->change.referer && !Curl_checkheaders(conn, "Referer")) { conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); if(!conn->allocptr.ref) return CURLE_OUT_OF_MEMORY; @@ -1891,11 +1946,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) conn->allocptr.ref = NULL; #if !defined(CURL_DISABLE_COOKIES) - if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:")) + if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie")) addcookies = data->set.str[STRING_COOKIE]; #endif - if(!Curl_checkheaders(conn, "Accept-Encoding:") && + if(!Curl_checkheaders(conn, "Accept-Encoding") && data->set.str[STRING_ENCODING]) { Curl_safefree(conn->allocptr.accept_encoding); conn->allocptr.accept_encoding = @@ -1911,22 +1966,29 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) #ifdef HAVE_LIBZ /* we only consider transfer-encoding magic if libz support is built-in */ - if(!Curl_checkheaders(conn, "TE:") && + if(!Curl_checkheaders(conn, "TE") && data->set.http_transfer_encoding) { /* When we are to insert a TE: header in the request, we must also insert TE in a Connection: header, so we need to merge the custom provided Connection: header and prevent the original to get sent. Note that if the user has inserted his/hers own TE: header we don't do this magic but then assume that the user will handle it all! */ - char *cptr = Curl_checkheaders(conn, "Connection:"); + char *cptr = Curl_checkheaders(conn, "Connection"); #define TE_HEADER "TE: gzip\r\n" Curl_safefree(conn->allocptr.te); + if(cptr) { + cptr = Curl_copy_header_value(cptr); + if(!cptr) + return CURLE_OUT_OF_MEMORY; + } + /* Create the (updated) Connection: header */ - conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr): - strdup("Connection: TE\r\n" TE_HEADER); + conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER, + cptr ? cptr : "", (cptr && *cptr) ? ", ":""); + free(cptr); if(!conn->allocptr.te) return CURLE_OUT_OF_MEMORY; } @@ -1950,7 +2012,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } if(http->sendit) { - const char *cthdr = Curl_checkheaders(conn, "Content-Type:"); + const char *cthdr = Curl_checkheaders(conn, "Content-Type"); /* Read and seek body only. */ http->sendit->flags |= MIME_BODY_ONLY; @@ -1974,7 +2036,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) http->postsize = Curl_mime_size(http->sendit); } - ptr = Curl_checkheaders(conn, "Transfer-Encoding:"); + ptr = Curl_checkheaders(conn, "Transfer-Encoding"); if(ptr) { /* Some kind of TE is requested, check if 'chunked' is chosen */ data->req.upload_chunky = @@ -2008,7 +2070,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) Curl_safefree(conn->allocptr.host); - ptr = Curl_checkheaders(conn, "Host:"); + ptr = Curl_checkheaders(conn, "Host"); if(ptr && (!data->state.this_is_a_follow || strcasecompare(data->state.first_host, conn->host.name))) { #if !defined(CURL_DISABLE_COOKIES) @@ -2047,7 +2109,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) #endif if(strcmp("Host:", ptr)) { - conn->allocptr.host = aprintf("%s\r\n", ptr); + conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]); if(!conn->allocptr.host) return CURLE_OUT_OF_MEMORY; } @@ -2070,7 +2132,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) host, conn->bits.ipv6_ip?"]":""); else - conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n", + conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n", conn->bits.ipv6_ip?"[":"", host, conn->bits.ipv6_ip?"]":"", @@ -2156,7 +2218,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } #endif /* CURL_DISABLE_PROXY */ - http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n"; + http->p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n"; if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) && data->state.resume_from) { @@ -2183,8 +2245,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) /* Now, let's read off the proper amount of bytes from the input. */ if(conn->seek_func) { + Curl_set_in_callback(data, true); seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, SEEK_SET); + Curl_set_in_callback(data, false); } if(seekerr != CURL_SEEKFUNC_OK) { @@ -2235,14 +2299,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) * ones if any such are specified. */ if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) && - !Curl_checkheaders(conn, "Range:")) { + !Curl_checkheaders(conn, "Range")) { /* if a line like this was already allocated, free the previous one */ free(conn->allocptr.rangeline); conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->state.range); } else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) && - !Curl_checkheaders(conn, "Content-Range:")) { + !Curl_checkheaders(conn, "Content-Range")) { /* if a line like this was already allocated, free the previous one */ free(conn->allocptr.rangeline); @@ -2344,7 +2408,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) conn->allocptr.ref:"" /* Referer: <data> */, (conn->bits.httpproxy && !conn->bits.tunnel_proxy && - !Curl_checkProxyheaders(conn, "Proxy-Connection:"))? + !Curl_checkProxyheaders(conn, "Proxy-Connection"))? "Proxy-Connection: Keep-Alive\r\n":"", te ); @@ -2445,7 +2509,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) postsize = data->state.infilesize; if((postsize != -1) && !data->req.upload_chunky && - (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) { + (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* only add Content-Length if not uploading chunked */ result = Curl_add_bufferf(req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T @@ -2507,7 +2571,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) we don't upload data chunked, as RFC2616 forbids us to set both kinds of headers (Transfer-Encoding: chunked and Content-Length) */ if(postsize != -1 && !data->req.upload_chunky && - (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) { + (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* we allow replacing this header if not during auth negotiation, although it isn't very wise to actually set your own */ result = Curl_add_bufferf(req_buffer, @@ -2532,7 +2596,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) the somewhat bigger ones we allow the app to disable it. Just make sure that the expect100header is always set to the preferred value here. */ - ptr = Curl_checkheaders(conn, "Expect:"); + ptr = Curl_checkheaders(conn, "Expect"); if(ptr) { data->state.expect100header = Curl_compareheader(ptr, "Expect:", "100-continue"); @@ -2586,7 +2650,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) we don't upload data chunked, as RFC2616 forbids us to set both kinds of headers (Transfer-Encoding: chunked and Content-Length) */ if((postsize != -1) && !data->req.upload_chunky && - (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) { + (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) { /* we allow replacing this header if not during auth negotiation, although it isn't very wise to actually set your own */ result = Curl_add_bufferf(req_buffer, @@ -2596,7 +2660,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return result; } - if(!Curl_checkheaders(conn, "Content-Type:")) { + if(!Curl_checkheaders(conn, "Content-Type")) { result = Curl_add_bufferf(req_buffer, "Content-Type: application/" "x-www-form-urlencoded\r\n"); @@ -2608,7 +2672,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) the somewhat bigger ones we allow the app to disable it. Just make sure that the expect100header is always set to the preferred value here. */ - ptr = Curl_checkheaders(conn, "Expect:"); + ptr = Curl_checkheaders(conn, "Expect"); if(ptr) { data->state.expect100header = Curl_compareheader(ptr, "Expect:", "100-continue"); @@ -2870,20 +2934,19 @@ static CURLcode header_append(struct Curl_easy *data, struct SingleRequest *k, size_t length) { - if(k->hbuflen + length >= data->state.headersize) { + size_t newsize = k->hbuflen + length; + if(newsize > CURL_MAX_HTTP_HEADER) { + /* The reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause + reallocs infinitely */ + failf(data, "Rejected %zd bytes header (max is %d)!", newsize, + CURL_MAX_HTTP_HEADER); + return CURLE_OUT_OF_MEMORY; + } + if(newsize >= data->state.headersize) { /* We enlarge the header buffer as it is too small */ char *newbuff; size_t hbufp_index; - size_t newsize; - - if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) { - /* The reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause - reallocs infinitely */ - failf(data, "Avoided giant realloc for header (max is %d)!", - CURL_MAX_HTTP_HEADER); - return CURLE_OUT_OF_MEMORY; - } newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2); hbufp_index = k->hbufp - data->state.headerbuff; @@ -2951,6 +3014,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, { CURLcode result; struct SingleRequest *k = &data->req; + ssize_t onread = *nread; + char *ostr = k->str; /* header line within buffer loop */ do { @@ -3015,7 +3080,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, else { /* this was all we read so it's all a bad header */ k->badheader = HEADER_ALLBAD; - *nread = (ssize_t)rest_length; + *nread = onread; + k->str = ostr; + return CURLE_OK; } break; } @@ -3505,31 +3572,35 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(!k->ignorecl && !data->set.ignorecl && checkprefix("Content-Length:", k->p)) { curl_off_t contentlength; - if(!curlx_strtoofft(k->p + 15, NULL, 10, &contentlength)) { + CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength); + + if(offt == CURL_OFFT_OK) { if(data->set.max_filesize && contentlength > data->set.max_filesize) { failf(data, "Maximum file size exceeded"); return CURLE_FILESIZE_EXCEEDED; } - if(contentlength >= 0) { - k->size = contentlength; - k->maxdownload = k->size; - /* we set the progress download size already at this point - just to make it easier for apps/callbacks to extract this - info as soon as possible */ - Curl_pgrsSetDownloadSize(data, k->size); - } - else { - /* Negative Content-Length is really odd, and we know it - happens for example when older Apache servers send large - files */ - streamclose(conn, "negative content-length"); - infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T - ", closing after transfer\n", contentlength); + k->size = contentlength; + k->maxdownload = k->size; + /* we set the progress download size already at this point + just to make it easier for apps/callbacks to extract this + info as soon as possible */ + Curl_pgrsSetDownloadSize(data, k->size); + } + else if(offt == CURL_OFFT_FLOW) { + /* out of range */ + if(data->set.max_filesize) { + failf(data, "Maximum file size exceeded"); + return CURLE_FILESIZE_EXCEEDED; } + streamclose(conn, "overflow content-length"); + infof(data, "Overflow Content-Length: value!\n"); + } + else { + /* negative or just rubbish - bad HTTP */ + failf(data, "Invalid Content-Length: value"); + return CURLE_WEIRD_SERVER_REPLY; } - else - infof(data, "Illegal Content-Length: header\n"); } /* check for Content-Type: header lines to get the MIME-type */ else if(checkprefix("Content-Type:", k->p)) { @@ -3665,7 +3736,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); Curl_cookie_add(data, - data->cookies, TRUE, k->p + 11, + data->cookies, TRUE, FALSE, k->p + 11, /* If there is a custom-set Host: name, use it here, or else use real peer host name. */ conn->allocptr.cookiehost? @@ -3680,7 +3751,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"), &secs); if(data->set.get_filetime) - data->info.filetime = (long)k->timeofdoc; + data->info.filetime = k->timeofdoc; } else if((checkprefix("WWW-Authenticate:", k->p) && (401 == k->httpcode)) || diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index d2781bc0f0..1d373e8f4e 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -104,7 +104,7 @@ CURLcode Curl_http_perhapsrewind(struct connectdata *conn); This value used to be fairly big (100K), but we must take into account that if the server rejects the POST due for authentication reasons, this data - will always be uncondtionally sent and thus it may not be larger than can + will always be unconditionally sent and thus it may not be larger than can always be afforded to send twice. It must not be greater than 64K to work on VMS. @@ -172,8 +172,6 @@ struct HTTP { size_t pauselen; /* the number of bytes left in data */ bool closed; /* TRUE on HTTP2 stream close */ bool close_handled; /* TRUE if stream closure is handled by libcurl */ - uint32_t error_code; /* HTTP/2 error code */ - char *mem; /* points to a buffer in memory to store received data */ size_t len; /* size of the buffer 'mem' points to */ size_t memlen; /* size of data copied to mem */ @@ -188,9 +186,6 @@ struct HTTP { #endif }; -typedef int (*sending)(void); /* Curl_send */ -typedef int (*recving)(void); /* Curl_recv */ - #ifdef USE_NGHTTP2 /* h2 settings for this connection */ struct h2settings { @@ -199,15 +194,14 @@ struct h2settings { }; #endif - struct http_conn { #ifdef USE_NGHTTP2 #define H2_BINSETTINGS_LEN 80 nghttp2_session *h2; uint8_t binsettings[H2_BINSETTINGS_LEN]; size_t binlen; /* length of the binsettings data */ - sending send_underlying; /* underlying send Curl_send callback */ - recving recv_underlying; /* underlying recv Curl_recv callback */ + Curl_send *send_underlying; /* underlying send Curl_send callback */ + Curl_recv *recv_underlying; /* underlying recv Curl_recv callback */ char *inbuf; /* buffer to receive data from underlying socket */ size_t inbuflen; /* number of bytes filled in inbuf */ size_t nread_inbuf; /* number of bytes read from in inbuf */ @@ -226,6 +220,7 @@ struct http_conn { /* list of settings that will be sent */ nghttp2_settings_entry local_settings[3]; size_t local_settings_num; + uint32_t error_code; /* HTTP/2 error code */ #else int unused; /* prevent a compiler warning */ #endif diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index 8e2fc71996..da001dfd09 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -41,6 +41,7 @@ #include "curl_memory.h" #include "memdebug.h" +#define H2_BUFSIZE 32768 #define MIN(x,y) ((x)<(y)?(x):(y)) #if (NGHTTP2_VERSION_NUM < 0x010000) @@ -65,6 +66,22 @@ #define HTTP2_HUGE_WINDOW_SIZE (1 << 30) +#ifdef DEBUG_HTTP2 +#define H2BUGF(x) x +#else +#define H2BUGF(x) do { } WHILE_FALSE +#endif + + +static ssize_t http2_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err); +static bool http2_connisdead(struct connectdata *conn); +static int h2_session_send(struct Curl_easy *data, + nghttp2_session *h2); +static int h2_process_pending_input(struct connectdata *conn, + struct http_conn *httpc, + CURLcode *err); + /* * Curl_http2_init_state() is called when the easy handle is created and * allows for HTTP/2 specific init of state. @@ -91,6 +108,7 @@ static int http2_perform_getsock(const struct connectdata *conn, int numsocks) { const struct http_conn *c = &conn->proto.httpc; + struct SingleRequest *k = &conn->data->req; int bitmap = GETSOCK_BLANK; (void)numsocks; @@ -102,7 +120,9 @@ static int http2_perform_getsock(const struct connectdata *conn, always be ready for one */ bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - if(nghttp2_session_want_write(c->h2)) + /* we're still uploading or the HTTP/2 layer wants to send data */ + if(((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) || + nghttp2_session_want_write(c->h2)) bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); return bitmap; @@ -140,13 +160,14 @@ static CURLcode http2_disconnect(struct connectdata *conn, struct http_conn *c = &conn->proto.httpc; (void)dead_connection; - DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n")); + H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n")); nghttp2_session_del(c->h2); Curl_safefree(c->inbuf); http2_stream_free(conn->data->req.protop); + conn->data->state.drain = 0; - DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n")); + H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n")); return CURLE_OK; } @@ -158,29 +179,54 @@ static CURLcode http2_disconnect(struct connectdata *conn, * Instead, if it is readable, run Curl_connalive() to peek at the socket * and distinguish between closed and data. */ -static bool http2_connisdead(struct connectdata *check) +static bool http2_connisdead(struct connectdata *conn) { int sval; - bool ret_val = TRUE; + bool dead = TRUE; - sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0); + if(conn->bits.close) + return TRUE; + + sval = SOCKET_READABLE(conn->sock[FIRSTSOCKET], 0); if(sval == 0) { /* timeout */ - ret_val = FALSE; + dead = FALSE; } else if(sval & CURL_CSELECT_ERR) { /* socket is in an error state */ - ret_val = TRUE; + dead = TRUE; } else if(sval & CURL_CSELECT_IN) { /* readable with no error. could still be closed */ - ret_val = !Curl_connalive(check); + dead = !Curl_connalive(conn); + if(!dead) { + /* This happens before we've sent off a request and the connection is + not in use by any other thransfer, there shouldn't be any data here, + only "protocol frames" */ + CURLcode result; + struct http_conn *httpc = &conn->proto.httpc; + ssize_t nread = -1; + if(httpc->recv_underlying) + /* if called "too early", this pointer isn't setup yet! */ + nread = ((Curl_recv *)httpc->recv_underlying)( + conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); + if(nread != -1) { + infof(conn->data, + "%d bytes stray data read before trying h2 connection\n", + (int)nread); + httpc->nread_inbuf = 0; + httpc->inbuflen = nread; + (void)h2_process_pending_input(conn, httpc, &result); + } + else + /* the read failed so let's say this is dead anyway */ + dead = TRUE; + } } - return ret_val; + return dead; } - static unsigned int http2_conncheck(struct connectdata *check, unsigned int checks_to_perform) { @@ -204,7 +250,6 @@ void Curl_http2_setup_req(struct Curl_easy *data) http->status_code = -1; http->pausedata = NULL; http->pauselen = 0; - http->error_code = NGHTTP2_NO_ERROR; http->closed = FALSE; http->close_handled = FALSE; http->mem = data->state.buffer; @@ -217,6 +262,7 @@ void Curl_http2_setup_conn(struct connectdata *conn) { conn->proto.httpc.settings.max_concurrent_streams = DEFAULT_MAX_CONCURRENT_STREAMS; + conn->proto.httpc.error_code = NGHTTP2_NO_ERROR; } /* @@ -428,7 +474,7 @@ static int push_promise(struct Curl_easy *data, const nghttp2_push_promise *frame) { int rv; - DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n", + H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n", frame->promised_stream_id)); if(data->multi->push_cb) { struct HTTP *stream; @@ -448,7 +494,7 @@ static int push_promise(struct Curl_easy *data, heads.data = data; heads.frame = frame; /* ask the application */ - DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); + H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); stream = data->req.protop; if(!stream) { @@ -458,9 +504,11 @@ static int push_promise(struct Curl_easy *data, goto fail; } + Curl_set_in_callback(data, true); rv = data->multi->push_cb(data, newhandle, stream->push_headers_used, &heads, data->multi->push_userp); + Curl_set_in_callback(data, false); /* free the headers again */ for(i = 0; i<stream->push_headers_used; i++) @@ -497,7 +545,7 @@ static int push_promise(struct Curl_easy *data, frame->promised_stream_id, newhandle); } else { - DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); + H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); rv = 1; } fail: @@ -511,7 +559,6 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, struct http_conn *httpc = &conn->proto.httpc; struct Curl_easy *data_s = NULL; struct HTTP *stream = NULL; - static int lastStream = -1; int rv; size_t left, ncopy; int32_t stream_id = frame->hd.stream_id; @@ -520,32 +567,30 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, /* stream ID zero is for connection-oriented stuff */ if(frame->hd.type == NGHTTP2_SETTINGS) { uint32_t max_conn = httpc->settings.max_concurrent_streams; - DEBUGF(infof(conn->data, "Got SETTINGS\n")); + H2BUGF(infof(conn->data, "Got SETTINGS\n")); httpc->settings.max_concurrent_streams = nghttp2_session_get_remote_settings( session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); httpc->settings.enable_push = nghttp2_session_get_remote_settings( session, NGHTTP2_SETTINGS_ENABLE_PUSH); - DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n", + H2BUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n", httpc->settings.max_concurrent_streams)); - DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n", + H2BUGF(infof(conn->data, "ENABLE_PUSH == %s\n", httpc->settings.enable_push?"TRUE":"false")); if(max_conn != httpc->settings.max_concurrent_streams) { /* only signal change if the value actually changed */ infof(conn->data, - "Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n"); + "Connection state changed (MAX_CONCURRENT_STREAMS == %d)!\n", + httpc->settings.max_concurrent_streams); Curl_multi_connchanged(conn->data->multi); } } return 0; } data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(lastStream != stream_id) { - lastStream = stream_id; - } if(!data_s) { - DEBUGF(infof(conn->data, + H2BUGF(infof(conn->data, "No Curl_easy associated with stream: %x\n", stream_id)); return 0; @@ -553,12 +598,12 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, stream = data_s->req.protop; if(!stream) { - DEBUGF(infof(conn->data, "No proto pointer for stream: %x\n", + H2BUGF(infof(data_s, "No proto pointer for stream: %x\n", stream_id)); return NGHTTP2_ERR_CALLBACK_FAILURE; } - DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n", + H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x\n", frame->hd.type, stream_id)); switch(frame->hd.type) { @@ -581,8 +626,10 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, } /* nghttp2 guarantees that :status is received, and we store it to - stream->status_code */ - DEBUGASSERT(stream->status_code != -1); + stream->status_code. Fuzzing has proven this can still be reached + without status code having been set. */ + if(stream->status_code == -1) + return NGHTTP2_ERR_CALLBACK_FAILURE; /* Only final status code signals the end of header */ if(stream->status_code / 100 != 1) { @@ -600,7 +647,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, ncopy); stream->nread_header_recvbuf += ncopy; - DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n", + H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n", ncopy, stream_id, stream->mem)); stream->len -= ncopy; @@ -629,7 +676,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, } break; default: - DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n", + H2BUGF(infof(data_s, "Got frame type %x for stream %u!\n", frame->hd.type, stream_id)); break; } @@ -642,13 +689,13 @@ static int on_invalid_frame_recv(nghttp2_session *session, { struct Curl_easy *data_s = NULL; (void)userp; -#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS) +#if !defined(DEBUG_HTTP2) || defined(CURL_DISABLE_VERBOSE_STRINGS) (void)lib_error_code; #endif data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); if(data_s) { - DEBUGF(infof(data_s, + H2BUGF(infof(data_s, "on_invalid_frame_recv() was called, error=%d:%s\n", lib_error_code, nghttp2_strerror(lib_error_code))); } @@ -693,7 +740,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, if(conn->data != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - DEBUGF(infof(data_s, "%zu data received for stream %u " + H2BUGF(infof(data_s, "%zu data received for stream %u " "(%zu left in buffer %p, total %zu)\n", nread, stream_id, stream->len, stream->mem, @@ -702,7 +749,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, if(nread < len) { stream->pausedata = data + nread; stream->pauselen = len - nread; - DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" + H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" ", stream %u\n", len - nread, stream_id)); data_s->easy_conn->proto.httpc.pause_stream_id = stream_id; @@ -730,7 +777,7 @@ static int before_frame_send(nghttp2_session *session, data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); if(data_s) { - DEBUGF(infof(data_s, "before_frame_send() was called\n")); + H2BUGF(infof(data_s, "before_frame_send() was called\n")); } return 0; @@ -744,7 +791,7 @@ static int on_frame_send(nghttp2_session *session, data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); if(data_s) { - DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n", + H2BUGF(infof(data_s, "on_frame_send() was called, length = %zd\n", frame->hd.length)); } return 0; @@ -755,13 +802,13 @@ static int on_frame_not_send(nghttp2_session *session, { struct Curl_easy *data_s; (void)userp; -#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS) +#if !defined(DEBUG_HTTP2) || defined(CURL_DISABLE_VERBOSE_STRINGS) (void)lib_error_code; #endif data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); if(data_s) { - DEBUGF(infof(data_s, + H2BUGF(infof(data_s, "on_frame_not_send() was called, lib_error_code = %d\n", lib_error_code)); } @@ -777,6 +824,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, (void)stream_id; if(stream_id) { + struct http_conn *httpc; /* get the stream from the hash based on Stream ID, stream ID zero is for connection-oriented stuff */ data_s = nghttp2_session_get_stream_user_data(session, stream_id); @@ -785,20 +833,21 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, decided to reject stream (e.g., PUSH_PROMISE). */ return 0; } - DEBUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n", + H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n", Curl_http2_strerror(error_code), error_code, stream_id)); stream = data_s->req.protop; if(!stream) return NGHTTP2_ERR_CALLBACK_FAILURE; - stream->error_code = error_code; stream->closed = TRUE; data_s->state.drain++; - conn->proto.httpc.drain_total++; + httpc = &conn->proto.httpc; + httpc->drain_total++; + httpc->error_code = error_code; /* remove the entry from the hash as the stream is now gone */ nghttp2_session_set_stream_user_data(session, stream_id, 0); - DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id)); + H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id)); } return 0; } @@ -815,7 +864,7 @@ static int on_begin_headers(nghttp2_session *session, return 0; } - DEBUGF(infof(data_s, "on_begin_headers() was called\n")); + H2BUGF(infof(data_s, "on_begin_headers() was called\n")); if(frame->hd.type != NGHTTP2_HEADERS) { return 0; @@ -826,16 +875,12 @@ static int on_begin_headers(nghttp2_session *session, return 0; } - /* This is trailer HEADERS started. Allocate buffer for them. */ - DEBUGF(infof(data_s, "trailer field started\n")); - - DEBUGASSERT(stream->trailer_recvbuf == NULL); - - stream->trailer_recvbuf = Curl_add_buffer_init(); if(!stream->trailer_recvbuf) { - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + stream->trailer_recvbuf = Curl_add_buffer_init(); + if(!stream->trailer_recvbuf) { + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + } } - return 0; } @@ -925,10 +970,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(stream->bodystarted) { /* This is trailer fields. */ - /* 3 is for ":" and "\r\n". */ - uint32_t n = (uint32_t)(namelen + valuelen + 3); + /* 4 is for ": " and "\r\n". */ + uint32_t n = (uint32_t)(namelen + valuelen + 4); - DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen, + H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen, value)); Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n)); @@ -956,7 +1001,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(conn->data != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n", + H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n", stream->status_code, data_s)); return 0; } @@ -972,7 +1017,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(conn->data != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen, + H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen, value)); return 0; /* 0 is successful */ @@ -1021,15 +1066,13 @@ static ssize_t data_source_read_callback(nghttp2_session *session, else if(nread == 0) return NGHTTP2_ERR_DEFERRED; - DEBUGF(infof(data_s, "data_source_read_callback: " + H2BUGF(infof(data_s, "data_source_read_callback: " "returns %zu bytes stream %u\n", nread, stream_id)); return nread; } -#define H2_BUFSIZE 32768 - #ifdef NGHTTP2_HAS_ERROR_CALLBACK static int error_callback(nghttp2_session *session, const char *msg, @@ -1067,7 +1110,6 @@ void Curl_http2_done(struct connectdata *conn, bool premature) struct http_conn *httpc = &conn->proto.httpc; if(http->header_recvbuf) { - DEBUGF(infof(data, "free header_recvbuf!!\n")); Curl_add_buffer_free(http->header_recvbuf); http->header_recvbuf = NULL; /* clear the pointer */ Curl_add_buffer_free(http->trailer_recvbuf); @@ -1216,22 +1258,20 @@ static int should_close_session(struct http_conn *httpc) !nghttp2_session_want_write(httpc->h2); } -static int h2_session_send(struct Curl_easy *data, - nghttp2_session *h2); - /* * h2_process_pending_input() processes pending input left in * httpc->inbuf. Then, call h2_session_send() to send pending data. * This function returns 0 if it succeeds, or -1 and error code will * be assigned to *err. */ -static int h2_process_pending_input(struct Curl_easy *data, +static int h2_process_pending_input(struct connectdata *conn, struct http_conn *httpc, CURLcode *err) { ssize_t nread; char *inbuf; ssize_t rv; + struct Curl_easy *data = conn->data; nread = httpc->inbuflen - httpc->nread_inbuf; inbuf = httpc->inbuf + httpc->nread_inbuf; @@ -1246,7 +1286,7 @@ static int h2_process_pending_input(struct Curl_easy *data, } if(nread == rv) { - DEBUGF(infof(data, + H2BUGF(infof(data, "h2_process_pending_input: All data in connection buffer " "processed\n")); httpc->inbuflen = 0; @@ -1254,7 +1294,7 @@ static int h2_process_pending_input(struct Curl_easy *data, } else { httpc->nread_inbuf += rv; - DEBUGF(infof(data, + H2BUGF(infof(data, "h2_process_pending_input: %zu bytes left in connection " "buffer\n", httpc->inbuflen - httpc->nread_inbuf)); @@ -1267,9 +1307,15 @@ static int h2_process_pending_input(struct Curl_easy *data, } if(should_close_session(httpc)) { - DEBUGF(infof(data, + H2BUGF(infof(data, "h2_process_pending_input: nothing to do in this session\n")); - *err = CURLE_HTTP2; + if(httpc->error_code) + *err = CURLE_HTTP2; + else { + /* not an error per se, but should still close the connection */ + connclose(conn, "GOAWAY received"); + *err = CURLE_OK; + } return -1; } @@ -1300,7 +1346,7 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn) that it can signal EOF to nghttp2 */ (void)nghttp2_session_resume_data(h2, stream->stream_id); - (void)h2_process_pending_input(conn->data, httpc, &result); + (void)h2_process_pending_input(conn, httpc, &result); } } return result; @@ -1324,7 +1370,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, data->state.drain = 0; if(httpc->pause_stream_id == 0) { - if(h2_process_pending_input(data, httpc, err) != 0) { + if(h2_process_pending_input(conn, httpc, err) != 0) { return -1; } } @@ -1333,17 +1379,25 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, /* Reset to FALSE to prevent infinite loop in readwrite_data function. */ stream->closed = FALSE; - if(stream->error_code != NGHTTP2_NO_ERROR) { + if(httpc->error_code == NGHTTP2_REFUSED_STREAM) { + H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n", + stream->stream_id)); + connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */ + data->state.refused_stream = TRUE; + *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ + return -1; + } + else if(httpc->error_code != NGHTTP2_NO_ERROR) { failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)", - stream->stream_id, Curl_http2_strerror(stream->error_code), - stream->error_code); + stream->stream_id, Curl_http2_strerror(httpc->error_code), + httpc->error_code); *err = CURLE_HTTP2_STREAM; return -1; } if(!stream->bodystarted) { failf(data, "HTTP/2 stream %u was closed cleanly, but before getting " - " all response header fields, teated as error", + " all response header fields, treated as error", stream->stream_id); *err = CURLE_HTTP2_STREAM; return -1; @@ -1370,7 +1424,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, stream->close_handled = TRUE; - DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n")); + H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n")); return 0; } @@ -1411,7 +1465,7 @@ static int h2_session_send(struct Curl_easy *data, h2_pri_spec(data, &pri_spec); - DEBUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n", + H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n", stream->stream_id, data)); rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id, &pri_spec); @@ -1435,7 +1489,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, (void)sockindex; /* we always do HTTP2 on sockindex 0 */ if(should_close_session(httpc)) { - DEBUGF(infof(data, + H2BUGF(infof(data, "http2_recv: nothing to do in this session\n")); *err = CURLE_HTTP2; return -1; @@ -1461,16 +1515,16 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, ncopy); stream->nread_header_recvbuf += ncopy; - DEBUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n", + H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n", (int)ncopy)); return ncopy; } - DEBUGF(infof(data, "http2_recv: easy %p (stream %u)\n", + H2BUGF(infof(data, "http2_recv: easy %p (stream %u)\n", data, stream->stream_id)); if((data->state.drain) && stream->memlen) { - DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n", + H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n", stream->memlen, stream->stream_id, stream->mem, mem)); if(mem != stream->mem) { @@ -1484,7 +1538,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, /* We have paused nghttp2, but we have no pause data (see on_data_chunk_recv). */ httpc->pause_stream_id = 0; - if(h2_process_pending_input(data, httpc, &result) != 0) { + if(h2_process_pending_input(conn, httpc, &result) != 0) { *err = result; return -1; } @@ -1500,7 +1554,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, infof(data, "%zu data bytes written\n", nread); if(stream->pauselen == 0) { - DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id)); + H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id)); DEBUGASSERT(httpc->pause_stream_id == stream->stream_id); httpc->pause_stream_id = 0; @@ -1514,12 +1568,12 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, frames, then we have to call it again with 0-length data. Without this, on_stream_close callback will not be called, and stream could be hanged. */ - if(h2_process_pending_input(data, httpc, &result) != 0) { + if(h2_process_pending_input(conn, httpc, &result) != 0) { *err = result; return -1; } } - DEBUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n", + H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n", nread, stream->stream_id)); return nread; } @@ -1532,7 +1586,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, socket is not read. But it seems that usually streams are notified with its drain property, and socket is read again quickly. */ - DEBUGF(infof(data, "stream %x is paused, pause id: %x\n", + H2BUGF(infof(data, "stream %x is paused, pause id: %x\n", stream->stream_id, httpc->pause_stream_id)); *err = CURLE_AGAIN; return -1; @@ -1561,12 +1615,12 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, } if(nread == 0) { - failf(data, "Unexpected EOF"); - *err = CURLE_RECV_ERROR; - return -1; + H2BUGF(infof(data, "end of stream\n")); + *err = CURLE_OK; + return 0; } - DEBUGF(infof(data, "nread=%zd\n", nread)); + H2BUGF(infof(data, "nread=%zd\n", nread)); httpc->inbuflen = nread; inbuf = httpc->inbuf; @@ -1575,7 +1629,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, nread = httpc->inbuflen - httpc->nread_inbuf; inbuf = httpc->inbuf + httpc->nread_inbuf; - DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", + H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", nread)); } rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); @@ -1586,15 +1640,15 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, *err = CURLE_RECV_ERROR; return -1; } - DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv)); + H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv)); if(nread == rv) { - DEBUGF(infof(data, "All data in connection buffer processed\n")); + H2BUGF(infof(data, "All data in connection buffer processed\n")); httpc->inbuflen = 0; httpc->nread_inbuf = 0; } else { httpc->nread_inbuf += rv; - DEBUGF(infof(data, "%zu bytes left in connection buffer\n", + H2BUGF(infof(data, "%zu bytes left in connection buffer\n", httpc->inbuflen - httpc->nread_inbuf)); } /* Always send pending frames in nghttp2 session, because @@ -1606,21 +1660,21 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, } if(should_close_session(httpc)) { - DEBUGF(infof(data, "http2_recv: nothing to do in this session\n")); + H2BUGF(infof(data, "http2_recv: nothing to do in this session\n")); *err = CURLE_HTTP2; return -1; } } if(stream->memlen) { ssize_t retlen = stream->memlen; - DEBUGF(infof(data, "http2_recv: returns %zd for stream %u\n", + H2BUGF(infof(data, "http2_recv: returns %zd for stream %u\n", retlen, stream->stream_id)); stream->memlen = 0; if(httpc->pause_stream_id == stream->stream_id) { /* data for this stream is returned now, but this stream caused a pause already so we need it called again asap */ - DEBUGF(infof(data, "Data returned for PAUSED stream %u\n", + H2BUGF(infof(data, "Data returned for PAUSED stream %u\n", stream->stream_id)); } else if(!stream->closed) { @@ -1637,7 +1691,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, return http2_handle_stream_close(conn, data, stream, err); } *err = CURLE_AGAIN; - DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", + H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", stream->stream_id)); return -1; } @@ -1739,7 +1793,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, (void)sockindex; - DEBUGF(infof(conn->data, "http2_send len=%zu\n", len)); + H2BUGF(infof(conn->data, "http2_send len=%zu\n", len)); if(stream->stream_id != -1) { if(stream->close_handled) { @@ -1768,7 +1822,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, stream->upload_len = 0; if(should_close_session(httpc)) { - DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); + H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); *err = CURLE_HTTP2; return -1; } @@ -1781,7 +1835,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, nghttp2_session_resume_data(h2, stream->stream_id); } - DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len, + H2BUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len, stream->stream_id)); return len; } @@ -1809,8 +1863,11 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, return -1; } - /* Extract :method, :path from request line */ - line_end = strstr(hdbuf, "\r\n"); + /* Extract :method, :path from request line + We do line endings with CRLF so checking for CR is enough */ + line_end = memchr(hdbuf, '\r', len); + if(!line_end) + goto fail; /* Method does not contain spaces */ end = memchr(hdbuf, ' ', line_end - hdbuf); @@ -1868,8 +1925,10 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, hdbuf = line_end + 2; - line_end = strstr(hdbuf, "\r\n"); - if(line_end == hdbuf) + /* check for next CR, but only within the piece of data left in the given + buffer */ + line_end = memchr(hdbuf, '\r', len - (hdbuf - (char *)mem)); + if(!line_end || (line_end == hdbuf)) goto fail; /* header continuation lines are not supported */ @@ -1937,7 +1996,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, for(i = 0; i < nheader; ++i) { acc += nva[i].namelen + nva[i].valuelen; - DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n", + H2BUGF(infof(conn->data, "h2 header: %.*s:%.*s\n", nva[i].namelen, nva[i].name, nva[i].valuelen, nva[i].value)); } @@ -1975,7 +2034,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, Curl_safefree(nva); if(stream_id < 0) { - DEBUGF(infof(conn->data, "http2_send() send error\n")); + H2BUGF(infof(conn->data, "http2_send() send error\n")); *err = CURLE_SEND_ERROR; return -1; } @@ -1994,7 +2053,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex, } if(should_close_session(httpc)) { - DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); + H2BUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); *err = CURLE_HTTP2; return -1; } @@ -2078,8 +2137,8 @@ CURLcode Curl_http2_switched(struct connectdata *conn, if(result) return result; - httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET]; - httpc->send_underlying = (sending)conn->send[FIRSTSOCKET]; + httpc->recv_underlying = conn->recv[FIRSTSOCKET]; + httpc->send_underlying = conn->send[FIRSTSOCKET]; conn->recv[FIRSTSOCKET] = http2_recv; conn->send[FIRSTSOCKET] = http2_send; @@ -2152,7 +2211,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn, return CURLE_HTTP2; } - DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); + H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); if((ssize_t)nread == nproc) { httpc->inbuflen = 0; @@ -2172,7 +2231,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn, } if(should_close_session(httpc)) { - DEBUGF(infof(data, + H2BUGF(infof(data, "nghttp2_session_send(): nothing to do in this session\n")); return CURLE_HTTP2; } diff --git a/libs/libcurl/src/http_chunks.c b/libs/libcurl/src/http_chunks.c index 1616429693..18dfcb2824 100644 --- a/libs/libcurl/src/http_chunks.c +++ b/libs/libcurl/src/http_chunks.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -74,14 +74,18 @@ */ +#ifdef CURL_DOES_CONVERSIONS /* Check for an ASCII hex digit. - We avoid the use of isxdigit to accommodate non-ASCII hosts. */ -static bool Curl_isxdigit(char digit) + We avoid the use of ISXDIGIT to accommodate non-ASCII hosts. */ +static bool Curl_isxdigit_ascii(char digit) { - return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */ + return (digit >= 0x30 && digit <= 0x39) /* 0-9 */ || (digit >= 0x41 && digit <= 0x46) /* A-F */ - || (digit >= 0x61 && digit <= 0x66) /* a-f */) ? TRUE : FALSE; + || (digit >= 0x61 && digit <= 0x66); /* a-f */ } +#else +#define Curl_isxdigit_ascii(x) Curl_isxdigit(x) +#endif void Curl_httpchunk_init(struct connectdata *conn) { @@ -128,7 +132,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, while(length) { switch(ch->state) { case CHUNK_HEX: - if(Curl_isxdigit(*datap)) { + if(Curl_isxdigit_ascii(*datap)) { if(ch->hexindex < MAXNUM_SIZE) { ch->hexbuffer[ch->hexindex] = *datap; datap++; @@ -187,15 +191,15 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize); /* Write the data portion available */ - if(conn->data->set.http_ce_skip || !k->writer_stack) { - if(!k->ignorebody) + if(!conn->data->set.http_te_skip && !k->ignorebody) { + if(!conn->data->set.http_ce_skip && k->writer_stack) + result = Curl_unencode_write(conn, k->writer_stack, datap, piece); + else result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece); - } - else - result = Curl_unencode_write(conn, k->writer_stack, datap, piece); - if(result) - return CHUNKE_WRITE_ERROR; + if(result) + return CHUNKE_WRITE_ERROR; + } *wrote += piece; ch->datasize -= piece; /* decrease amount left to expect */ diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c index 51375e81d1..ddcd65b3b9 100644 --- a/libs/libcurl/src/http_negotiate.c +++ b/libs/libcurl/src/http_negotiate.c @@ -89,7 +89,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, } } - /* Initilise the security context and decode our challenge */ + /* Initialize the security context and decode our challenge */ result = Curl_auth_decode_spnego_message(data, userp, passwdp, service, host, header, neg_ctx); diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c index 0f1edcf65d..fd5540b5d0 100644 --- a/libs/libcurl/src/http_ntlm.c +++ b/libs/libcurl/src/http_ntlm.c @@ -121,9 +121,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) server, which is for a plain host or for a HTTP proxy */ char **allocuserpwd; - /* point to the name and password for this */ + /* point to the username, password, service and host */ const char *userp; const char *passwdp; + const char *service = NULL; + const char *hostname = NULL; /* point to the correct struct with this */ struct ntlmdata *ntlm; @@ -141,6 +143,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) allocuserpwd = &conn->allocptr.proxyuserpwd; userp = conn->http_proxy.user; passwdp = conn->http_proxy.passwd; + service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ? + conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; + hostname = conn->http_proxy.host.name; ntlm = &conn->proxyntlm; authp = &conn->data->state.authproxy; } @@ -148,6 +153,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) allocuserpwd = &conn->allocptr.userpwd; userp = conn->user; passwdp = conn->passwd; + service = conn->data->set.str[STRING_SERVICE_NAME] ? + conn->data->set.str[STRING_SERVICE_NAME] : "HTTP"; + hostname = conn->host.name; ntlm = &conn->ntlm; authp = &conn->data->state.authhost; } @@ -174,7 +182,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) default: /* for the weird cases we (re)start here */ /* Create a type-1 message */ result = Curl_auth_create_ntlm_type1_message(conn->data, userp, passwdp, - ntlm, &base64, &len); + service, hostname, + ntlm, &base64, + &len); if(result) return result; diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index 0283c1f3fa..e10a488294 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -167,6 +167,7 @@ static CURLcode connect_init(struct connectdata *conn, bool reinit) s->line_start = s->connect_buffer; s->ptr = s->line_start; s->cl = 0; + s->close_connection = FALSE; return CURLE_OK; } @@ -187,7 +188,6 @@ static CURLcode CONNECT(struct connectdata *conn, struct SingleRequest *k = &data->req; CURLcode result; curl_socket_t tunnelsocket = conn->sock[sockindex]; - bool closeConnection = FALSE; timediff_t check; struct http_connect_state *s = conn->connect_state; @@ -221,7 +221,7 @@ static CURLcode CONNECT(struct connectdata *conn, if(!req_buffer) return CURLE_OUT_OF_MEMORY; - host_port = aprintf("%s:%hu", hostname, remote_port); + host_port = aprintf("%s:%d", hostname, remote_port); if(!host_port) { Curl_add_buffer_free(req_buffer); return CURLE_OUT_OF_MEMORY; @@ -245,14 +245,14 @@ static CURLcode CONNECT(struct connectdata *conn, if(hostname != conn->host.name) ipv6_ip = (strchr(hostname, ':') != NULL); hostheader = /* host:port with IPv6 support */ - aprintf("%s%s%s:%hu", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", + aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", remote_port); if(!hostheader) { Curl_add_buffer_free(req_buffer); return CURLE_OUT_OF_MEMORY; } - if(!Curl_checkProxyheaders(conn, "Host:")) { + if(!Curl_checkProxyheaders(conn, "Host")) { host = aprintf("Host: %s\r\n", hostheader); if(!host) { free(hostheader); @@ -260,10 +260,10 @@ static CURLcode CONNECT(struct connectdata *conn, return CURLE_OUT_OF_MEMORY; } } - if(!Curl_checkProxyheaders(conn, "Proxy-Connection:")) + if(!Curl_checkProxyheaders(conn, "Proxy-Connection")) proxyconn = "Proxy-Connection: Keep-Alive\r\n"; - if(!Curl_checkProxyheaders(conn, "User-Agent:") && + if(!Curl_checkProxyheaders(conn, "User-Agent") && data->set.str[STRING_USERAGENT]) useragent = conn->allocptr.uagent; @@ -529,7 +529,7 @@ static CURLcode CONNECT(struct connectdata *conn, } } else if(Curl_compareheader(s->line_start, "Connection:", "close")) - closeConnection = TRUE; + s->close_connection = TRUE; else if(checkprefix("Transfer-Encoding:", s->line_start)) { if(k->httpcode/100 == 2) { /* A client MUST ignore any Content-Length or Transfer-Encoding @@ -548,7 +548,7 @@ static CURLcode CONNECT(struct connectdata *conn, } else if(Curl_compareheader(s->line_start, "Proxy-Connection:", "close")) - closeConnection = TRUE; + s->close_connection = TRUE; else if(2 == sscanf(s->line_start, "HTTP/1.%d %d", &subversion, &k->httpcode)) { @@ -578,10 +578,10 @@ static CURLcode CONNECT(struct connectdata *conn, /* the connection has been marked for closure, most likely in the Curl_http_auth_act() function and thus we can kill it at once below */ - closeConnection = TRUE; + s->close_connection = TRUE; } - if(closeConnection && data->req.newurl) { + if(s->close_connection && data->req.newurl) { /* Connection closed by server. Don't use it anymore */ Curl_closesocket(conn, conn->sock[sockindex]); conn->sock[sockindex] = CURL_SOCKET_BAD; @@ -599,7 +599,7 @@ static CURLcode CONNECT(struct connectdata *conn, } while(data->req.newurl); if(data->info.httpproxycode/100 != 2) { - if(closeConnection && data->req.newurl) { + if(s->close_connection && data->req.newurl) { conn->bits.proxy_connect_closed = TRUE; infof(data, "Connect me again please\n"); connect_done(conn); diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c index 1b52f73a41..cf278a22ba 100644 --- a/libs/libcurl/src/imap.c +++ b/libs/libcurl/src/imap.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -344,23 +344,30 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len, */ static void imap_get_message(char *buffer, char **outptr) { - size_t len = 0; + size_t len = strlen(buffer); char *message = NULL; - /* Find the start of the message */ - for(message = buffer + 2; *message == ' ' || *message == '\t'; message++) - ; - - /* Find the end of the message */ - for(len = strlen(message); len--;) - if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && - message[len] != '\t') - break; + if(len > 2) { + /* Find the start of the message */ + len -= 2; + for(message = buffer + 2; *message == ' ' || *message == '\t'; + message++, len--) + ; + + /* Find the end of the message */ + for(; len--;) + if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && + message[len] != '\t') + break; - /* Terminate the message */ - if(++len) { - message[len] = '\0'; + /* Terminate the message */ + if(++len) { + message[len] = '\0'; + } } + else + /* junk input => zero length output */ + message = &buffer[len]; *outptr = message; } diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c index 69a35979a8..55b96e4e58 100644 --- a/libs/libcurl/src/krb5.c +++ b/libs/libcurl/src/krb5.c @@ -1,8 +1,8 @@ /* GSSAPI/krb5 support for FTP - loosely based on old krb4.c * - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Hцgskolan * (Royal Institute of Technology, Stockholm, Sweden). - * Copyright (c) 2004 - 2016 Daniel Stenberg + * Copyright (c) 2004 - 2017 Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ krb5_decode(void *app_data, void *buf, int len, enc.value = buf; enc.length = len; - maj = gss_unseal(&min, *context, &enc, &dec, NULL, NULL); + maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL); if(maj != GSS_S_COMPLETE) { if(len >= 4) strcpy(buf, "599 "); @@ -119,11 +119,11 @@ krb5_encode(void *app_data, const void *from, int length, int level, void **to) int len; /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal - * libraries modify the input buffer in gss_seal() + * libraries modify the input buffer in gss_wrap() */ dec.value = (void *)from; dec.length = length; - maj = gss_seal(&min, *context, + maj = gss_wrap(&min, *context, level == PROT_PRIVATE, GSS_C_QOP_DEFAULT, &dec, &state, &enc); @@ -282,6 +282,7 @@ krb5_auth(void *app_data, struct connectdata *conn) break; } + _gssresp.value = NULL; /* make sure it is initialized */ p = data->state.buffer + 4; p = strstr(p, "ADAT="); if(p) { diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index 2e377865b2..0410ad19fe 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ <string>se.haxx.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.57.0</string> + <string>7.60.0</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.57.0</string> + <string>libcurl 7.60.0</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.57.0</string> + <string>libcurl.plist 7.60.0</string> </dict> </plist> diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c index 80301a1412..3096602b7e 100644 --- a/libs/libcurl/src/md5.c +++ b/libs/libcurl/src/md5.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -484,6 +484,11 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx) #endif /* CRYPTO LIBS */ +/* Disable this picky gcc-8 compiler warning */ +#if defined(__GNUC__) && (__GNUC__ >= 8) +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + const HMAC_params Curl_HMAC_MD5[] = { { (HMAC_hinit_func) MD5_Init, /* Hash initialization function. */ diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c index 457000a0b5..4c0d2eebab 100644 --- a/libs/libcurl/src/mime.c +++ b/libs/libcurl/src/mime.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -51,10 +51,6 @@ #endif -#define FILE_CONTENTTYPE_DEFAULT "application/octet-stream" -#define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed" -#define DISPOSITION_DEFAULT "attachment" - #define READ_ERROR ((size_t) -1) /* Encoders. */ @@ -245,7 +241,7 @@ static FILE * vmsfopenread(const char *file, const char *mode) static char *Curl_basename(char *path) { /* Ignore all the details above for now and make a quick and simple - implementaion here */ + implementation here */ char *s1; char *s2; @@ -1140,6 +1136,81 @@ void curl_mime_free(curl_mime *mime) } } +CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src) +{ + curl_mime *mime; + curl_mimepart *d; + const curl_mimepart *s; + CURLcode res = CURLE_OK; + + /* Duplicate content. */ + switch(src->kind) { + case MIMEKIND_NONE: + break; + case MIMEKIND_DATA: + res = curl_mime_data(dst, src->data, (size_t) src->datasize); + break; + case MIMEKIND_FILE: + res = curl_mime_filedata(dst, src->data); + /* Do not abort duplication if file is not readable. */ + if(res == CURLE_READ_ERROR) + res = CURLE_OK; + break; + case MIMEKIND_CALLBACK: + res = curl_mime_data_cb(dst, src->datasize, src->readfunc, + src->seekfunc, src->freefunc, src->arg); + break; + case MIMEKIND_MULTIPART: + /* No one knows about the cloned subparts, thus always attach ownership + to the part. */ + mime = curl_mime_init(dst->easy); + res = mime? curl_mime_subparts(dst, mime): CURLE_OUT_OF_MEMORY; + + /* Duplicate subparts. */ + for(s = ((curl_mime *) src->arg)->firstpart; !res && s; s = s->nextpart) { + d = curl_mime_addpart(mime); + res = d? Curl_mime_duppart(d, s): CURLE_OUT_OF_MEMORY; + } + break; + default: /* Invalid kind: should not occur. */ + res = CURLE_BAD_FUNCTION_ARGUMENT; /* Internal error? */ + break; + } + + /* Duplicate headers. */ + if(!res && src->userheaders) { + struct curl_slist *hdrs = Curl_slist_duplicate(src->userheaders); + + if(!hdrs) + res = CURLE_OUT_OF_MEMORY; + else { + /* No one but this procedure knows about the new header list, + so always take ownership. */ + res = curl_mime_headers(dst, hdrs, TRUE); + if(res) + curl_slist_free_all(hdrs); + } + } + + /* Duplicate other fields. */ + if(dst != NULL) + dst->encoder = src->encoder; + else + res = CURLE_WRITE_ERROR; + if(!res) + res = curl_mime_type(dst, src->mimetype); + if(!res) + res = curl_mime_name(dst, src->name); + if(!res) + res = curl_mime_filename(dst, src->filename); + + /* If an error occurred, rollback. */ + if(res && dst) + Curl_mime_cleanpart(dst); + + return res; +} + /* * Mime build functions. */ @@ -1570,8 +1641,7 @@ static CURLcode add_content_type(struct curl_slist **slp, boundary? boundary: ""); } - -static const char *ContentTypeForFilename(const char *filename) +const char *Curl_mime_contenttype(const char *filename) { unsigned int i; @@ -1643,14 +1713,14 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part, contenttype = MULTIPART_CONTENTTYPE_DEFAULT; break; case MIMEKIND_FILE: - contenttype = ContentTypeForFilename(part->filename); + contenttype = Curl_mime_contenttype(part->filename); if(!contenttype) - contenttype = ContentTypeForFilename(part->data); + contenttype = Curl_mime_contenttype(part->data); if(!contenttype && part->filename) contenttype = FILE_CONTENTTYPE_DEFAULT; break; default: - contenttype = ContentTypeForFilename(part->filename); + contenttype = Curl_mime_contenttype(part->filename); break; } } @@ -1855,6 +1925,13 @@ void Curl_mime_cleanpart(curl_mimepart *part) (void) part; } +CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src) +{ + (void) dst; + (void) src; + return CURLE_OK; /* Nothing to duplicate: always succeed. */ +} + CURLcode Curl_mime_set_subparts(curl_mimepart *part, curl_mime *subparts, int take_ownership) { diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h index 7827f74126..4d5c70404d 100644 --- a/libs/libcurl/src/mime.h +++ b/libs/libcurl/src/mime.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,6 +30,10 @@ #define MIME_USERHEADERS_OWNER (1 << 0) #define MIME_BODY_ONLY (1 << 1) +#define FILE_CONTENTTYPE_DEFAULT "application/octet-stream" +#define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed" +#define DISPOSITION_DEFAULT "attachment" + /* Part source kinds. */ enum mimekind { MIMEKIND_NONE = 0, /* Part not set. */ @@ -122,6 +126,7 @@ struct curl_mimepart_s { /* Prototypes. */ void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy); void Curl_mime_cleanpart(curl_mimepart *part); +CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src); CURLcode Curl_mime_set_subparts(curl_mimepart *part, curl_mime *subparts, int take_ownership); CURLcode Curl_mime_prepare_headers(curl_mimepart *part, @@ -133,5 +138,6 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream); CURLcode Curl_mime_rewind(curl_mimepart *part); CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...); +const char *Curl_mime_contenttype(const char *filename); #endif /* HEADER_CURL_MIME_H */ diff --git a/libs/libcurl/src/mk-ca-bundle.pl b/libs/libcurl/src/mk-ca-bundle.pl index dcfec0bb66..5a84f6b0b1 100644 --- a/libs/libcurl/src/mk-ca-bundle.pl +++ b/libs/libcurl/src/mk-ca-bundle.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl # *************************************************************************** # * _ _ ____ _ # * Project ___| | | | _ \| | @@ -34,6 +34,7 @@ use Encode; use Getopt::Std; use MIME::Base64; use strict; +use warnings; use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w); use List::Util; use Text::Wrap; diff --git a/libs/libcurl/src/mk-ca-bundle.vbs b/libs/libcurl/src/mk-ca-bundle.vbs index da7a577ea7..bd4e4a35e6 100644 --- a/libs/libcurl/src/mk-ca-bundle.vbs +++ b/libs/libcurl/src/mk-ca-bundle.vbs @@ -314,7 +314,7 @@ Function RegExprFirst(SearchPattern, TheString) Set objRegExp = New RegExp ' create a regular expression. objRegExp.Pattern = SearchPattern ' sets the search pattern. objRegExp.IgnoreCase = TRUE ' set to ignores case. - objRegExp.Global = TRUE ' set to gloabal search. + objRegExp.Global = TRUE ' set to global search. Set Matches = objRegExp.Execute(TheString) ' do the search. If (Matches.Count) Then RegExprFirst = Matches(0).SubMatches(0) ' return first match. diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 9728e5a2f2..f852846952 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -77,6 +77,7 @@ static CURLMcode add_next_timeout(struct curltime now, struct Curl_easy *d); static CURLMcode multi_timeout(struct Curl_multi *multi, long *timeout_ms); +static void process_pending_handles(struct Curl_multi *multi); #ifdef DEBUGBUILD static const char * const statename[]={ @@ -366,6 +367,9 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, if(data->multi) return CURLM_ADDED_ALREADY; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + /* Initialize timeout list for this handle */ Curl_llist_init(&data->state.timeoutlist, NULL); @@ -375,6 +379,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, * potential multi's connection cache growing which won't be undone in this * function no matter what. */ + if(data->set.errorbuffer) + data->set.errorbuffer[0] = 0; /* set the easy handle */ multistate(data, CURLM_STATE_INIT); @@ -479,38 +485,6 @@ static void debug_print_sock_hash(void *p) } #endif -/* Mark the connection as 'idle', or close it if the cache is full. - Returns TRUE if the connection is kept, or FALSE if it was closed. */ -static bool -ConnectionDone(struct Curl_easy *data, struct connectdata *conn) -{ - /* data->multi->maxconnects can be negative, deal with it. */ - size_t maxconnects = - (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: - data->multi->maxconnects; - struct connectdata *conn_candidate = NULL; - - /* Mark the current connection as 'unused' */ - conn->inuse = FALSE; - - if(maxconnects > 0 && - data->state.conn_cache->num_connections > maxconnects) { - infof(data, "Connection cache is full, closing the oldest one.\n"); - - conn_candidate = Curl_conncache_oldest_idle(data); - - if(conn_candidate) { - /* Set the connection's owner correctly */ - conn_candidate->data = data; - - /* the winner gets the honour of being disconnected */ - (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); - } - } - - return (conn_candidate == conn) ? FALSE : TRUE; -} - static CURLcode multi_done(struct connectdata **connp, CURLcode status, /* an error if this is called after an error was detected */ @@ -567,13 +541,14 @@ static CURLcode multi_done(struct connectdata **connp, result = CURLE_ABORTED_BY_CALLBACK; } - if(conn->send_pipe.size + conn->recv_pipe.size != 0 && - !data->set.reuse_forbid && - !conn->bits.close) { - /* Stop if pipeline is not empty and we do not have to close - connection. */ + process_pending_handles(data->multi); /* connection / multiplex */ + + if(conn->send_pipe.size || conn->recv_pipe.size) { + /* Stop if pipeline is not empty . */ data->easy_conn = NULL; - DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n")); + DEBUGF(infof(data, "Connection still in use %d/%d, " + "no more multi_done now!\n", + conn->send_pipe.size, conn->recv_pipe.size)); return CURLE_OK; } @@ -584,6 +559,7 @@ static CURLcode multi_done(struct connectdata **connp, Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ conn->dns_entry = NULL; } + Curl_hostcache_prune(data); /* if the transfer was completed in a paused state there can be buffered data left to free */ @@ -612,7 +588,8 @@ static CURLcode multi_done(struct connectdata **connp, && !(conn->ntlm.state == NTLMSTATE_TYPE2 || conn->proxyntlm.state == NTLMSTATE_TYPE2) #endif - ) || conn->bits.close || premature) { + ) || conn->bits.close + || (premature && !(conn->handler->flags & PROTOPT_STREAM))) { CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ /* If we had an error already, make sure we return that one. But @@ -621,17 +598,21 @@ static CURLcode multi_done(struct connectdata **connp, result = res2; } else { + char buffer[256]; + /* create string before returning the connection */ + snprintf(buffer, sizeof(buffer), + "Connection #%ld to host %s left intact", + conn->connection_id, + conn->bits.socksproxy ? conn->socks_proxy.host.dispname : + conn->bits.httpproxy ? conn->http_proxy.host.dispname : + conn->bits.conn_to_host ? conn->conn_to_host.dispname : + conn->host.dispname); + /* the connection is no longer in use */ - if(ConnectionDone(data, conn)) { + if(Curl_conncache_return_conn(conn)) { /* remember the most recently used connection */ data->state.lastconnect = conn; - - infof(data, "Connection #%ld to host %s left intact\n", - conn->connection_id, - conn->bits.socksproxy ? conn->socks_proxy.host.dispname : - conn->bits.httpproxy ? conn->http_proxy.host.dispname : - conn->bits.conn_to_host ? conn->conn_to_host.dispname : - conn->host.dispname); + infof(data, "%s\n", buffer); } else data->state.lastconnect = NULL; @@ -666,6 +647,9 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, if(!data->multi) return CURLM_OK; /* it is already removed so let's say it is fine! */ + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE; easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ? TRUE : FALSE; @@ -676,10 +660,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, /* this handle is "alive" so we need to count down the total number of alive connections when this is removed */ multi->num_alive--; - - /* When this handle gets removed, other handles may be able to get the - connection */ - Curl_multi_process_pending_handles(multi); } if(data->easy_conn && @@ -929,6 +909,9 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + data = multi->easyp; while(data) { bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); @@ -982,6 +965,9 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + /* If the internally desired timeout is actually shorter than requested from the outside, then use the shorter time! But only if the internal timer is actually larger than -1! */ @@ -1147,6 +1133,9 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, { CURLMcode rc; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + rc = curl_multi_add_handle(multi, data); if(!rc) { struct SingleRequest *k = &data->req; @@ -1353,20 +1342,20 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(multi_ischanged(multi, TRUE)) { DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n")); - Curl_multi_process_pending_handles(multi); + process_pending_handles(multi); /* pipelined/multiplexed */ } if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_COMPLETED) + data->mstate < CURLM_STATE_COMPLETED) { /* Make sure we set the connection's current owner */ data->easy_conn->data = data; + } if(data->easy_conn && (data->mstate >= CURLM_STATE_CONNECT) && (data->mstate < CURLM_STATE_COMPLETED)) { /* we need to wait for the connect state as only then is the start time stored, but we must not check already completed handles */ - timeout_ms = Curl_timeleft(data, &now, (data->mstate <= CURLM_STATE_WAITDO)? TRUE:FALSE); @@ -1799,16 +1788,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case CURLM_STATE_DO_DONE: /* Move ourselves from the send to recv pipeline */ Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn); - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); + + if(data->easy_conn->bits.multiplex || data->easy_conn->send_pipe.size) + /* Check if we can move pending requests to send pipe */ + process_pending_handles(multi); /* pipelined/multiplexed */ /* Only perform the transfer if there's a good socket to work with. Having both BAD is a signal to skip immediately to DONE */ if((data->easy_conn->sockfd != CURL_SOCKET_BAD) || (data->easy_conn->writesockfd != CURL_SOCKET_BAD)) multistate(data, CURLM_STATE_WAITPERFORM); - else - { + else { if(data->state.wildcardmatch && ((data->easy_conn->handler->flags & PROTOPT_WILDCARD) == 0)) { data->wildcard.state = CURLWC_DONE; @@ -1837,22 +1827,26 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(!result) { send_timeout_ms = 0; if(data->set.max_send_speed > 0) - send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, - data->progress.ul_limit_size, - data->set.max_send_speed, - data->progress.ul_limit_start, - now); + send_timeout_ms = + Curl_pgrsLimitWaitTime(data->progress.uploaded, + data->progress.ul_limit_size, + data->set.max_send_speed, + data->progress.ul_limit_start, + now); recv_timeout_ms = 0; if(data->set.max_recv_speed > 0) - recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, - data->progress.dl_limit_size, - data->set.max_recv_speed, - data->progress.dl_limit_start, - now); - - if(send_timeout_ms <= 0 && recv_timeout_ms <= 0) + recv_timeout_ms = + Curl_pgrsLimitWaitTime(data->progress.downloaded, + data->progress.dl_limit_size, + data->set.max_recv_speed, + data->progress.dl_limit_start, + now); + + if(!send_timeout_ms && !recv_timeout_ms) { multistate(data, CURLM_STATE_PERFORM); + Curl_ratelimit(data, now); + } else if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); else @@ -1884,7 +1878,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->progress.dl_limit_start, now); - if(send_timeout_ms > 0 || recv_timeout_ms > 0) { + if(send_timeout_ms || recv_timeout_ms) { + Curl_ratelimit(data, now); multistate(data, CURLM_STATE_TOOFAST); if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); @@ -1952,9 +1947,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(data->easy_conn->recv_pipe.head) Curl_expire(data->easy_conn->recv_pipe.head->ptr, 0, EXPIRE_RUN_NOW); - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); - /* When we follow redirects or is set to retry the connection, we must to go back to the CONNECT state */ if(data->req.newurl || retry) { @@ -2011,8 +2003,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* Remove ourselves from the receive pipeline, if we are there. */ Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe); - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); + + if(data->easy_conn->bits.multiplex || data->easy_conn->send_pipe.size) + /* Check if we can move pending requests to connection */ + process_pending_handles(multi); /* pipelined/multiplexing */ /* post-transfer command */ res = multi_done(&data->easy_conn, result, FALSE); @@ -2080,7 +2074,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->state.pipe_broke = FALSE; /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); + process_pending_handles(multi); /* connection */ if(data->easy_conn) { /* if this has a connection, unsubscribe from the pipelines */ @@ -2153,6 +2147,9 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + data = multi->easyp; while(data) { CURLMcode result; @@ -2200,6 +2197,9 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) struct Curl_easy *nextdata; if(GOOD_MULTI_HANDLE(multi)) { + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + multi->type = 0; /* not good anymore */ /* Firsrt remove all remaining easy handles */ @@ -2260,7 +2260,9 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue) *msgs_in_queue = 0; /* default to none */ - if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(&multi->msglist)) { + if(GOOD_MULTI_HANDLE(multi) && + !multi->in_callback && + Curl_llist_count(&multi->msglist)) { /* there is one or more messages in the list */ struct curl_llist_element *e; @@ -2422,6 +2424,12 @@ static void singlesocket(struct Curl_multi *multi, data->numsocks = num; } +void Curl_updatesocket(struct Curl_easy *data) +{ + singlesocket(data->multi, data); +} + + /* * Curl_multi_closed() * @@ -2650,6 +2658,9 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + va_start(param, option); switch(option) { @@ -2714,7 +2725,10 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi, CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, int *running_handles) { - CURLMcode result = multi_socket(multi, FALSE, s, 0, running_handles); + CURLMcode result; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + result = multi_socket(multi, FALSE, s, 0, running_handles); if(CURLM_OK >= result) update_timer(multi); return result; @@ -2723,8 +2737,10 @@ CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s, CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, int ev_bitmask, int *running_handles) { - CURLMcode result = multi_socket(multi, FALSE, s, - ev_bitmask, running_handles); + CURLMcode result; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles); if(CURLM_OK >= result) update_timer(multi); return result; @@ -2733,8 +2749,10 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles) { - CURLMcode result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, - running_handles); + CURLMcode result; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles); if(CURLM_OK >= result) update_timer(multi); return result; @@ -2786,6 +2804,9 @@ CURLMcode curl_multi_timeout(struct Curl_multi *multi, if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + return multi_timeout(multi, timeout_ms); } @@ -3018,6 +3039,9 @@ CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s, { struct Curl_sh_entry *there = NULL; + if(multi->in_callback) + return CURLM_RECURSIVE_API_CALL; + there = sh_getentry(&multi->sockhash, s); if(!there) @@ -3058,28 +3082,38 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi) return &multi->pipelining_server_bl; } -void Curl_multi_process_pending_handles(struct Curl_multi *multi) +static void process_pending_handles(struct Curl_multi *multi) { struct curl_llist_element *e = multi->pending.head; - - while(e) { + if(e) { struct Curl_easy *data = e->ptr; - struct curl_llist_element *next = e->next; - if(data->mstate == CURLM_STATE_CONNECT_PEND) { - multistate(data, CURLM_STATE_CONNECT); + DEBUGASSERT(data->mstate == CURLM_STATE_CONNECT_PEND); - /* Remove this node from the list */ - Curl_llist_remove(&multi->pending, e, NULL); + multistate(data, CURLM_STATE_CONNECT); - /* Make sure that the handle will be processed soonish. */ - Curl_expire(data, 0, EXPIRE_RUN_NOW); - } + /* Remove this node from the list */ + Curl_llist_remove(&multi->pending, e, NULL); - e = next; /* operate on next handle */ + /* Make sure that the handle will be processed soonish. */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); } } +void Curl_set_in_callback(struct Curl_easy *easy, bool value) +{ + if(easy->multi_easy) + easy->multi_easy->in_callback = value; + else if(easy->multi) + easy->multi->in_callback = value; +} + +bool Curl_is_in_callback(struct Curl_easy *easy) +{ + return ((easy->multi && easy->multi->in_callback) || + (easy->multi_easy && easy->multi_easy->in_callback)); +} + #ifdef DEBUGBUILD void Curl_multi_dump(struct Curl_multi *multi) { diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index de9a7cf59c..1a5017f4a0 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.h @@ -146,6 +146,7 @@ struct Curl_multi { void *timer_userp; struct curltime timer_lastcall; /* the fixed time for the timeout for the previous callback */ + bool in_callback; /* true while executing a callback */ }; #endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/libs/libcurl/src/multiif.h b/libs/libcurl/src/multiif.h index a877571a00..c8fb5ca0d1 100644 --- a/libs/libcurl/src/multiif.h +++ b/libs/libcurl/src/multiif.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,11 +26,14 @@ * Prototypes for library-wide functions provided by multi.c */ +void Curl_updatesocket(struct Curl_easy *data); void Curl_expire(struct Curl_easy *data, time_t milli, expire_id); void Curl_expire_clear(struct Curl_easy *data); void Curl_expire_done(struct Curl_easy *data, expire_id id); bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits); void Curl_multi_handlePipeBreak(struct Curl_easy *data); +void Curl_set_in_callback(struct Curl_easy *data, bool value); +bool Curl_is_in_callback(struct Curl_easy *easy); /* Internal version of curl_multi_init() accepts size parameters for the socket and connection hashes */ @@ -56,8 +59,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize); void Curl_multi_dump(struct Curl_multi *multi); #endif -void Curl_multi_process_pending_handles(struct Curl_multi *multi); - /* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */ size_t Curl_multi_max_host_connections(struct Curl_multi *multi); diff --git a/libs/libcurl/src/non-ascii.c b/libs/libcurl/src/non-ascii.c index 92b2f8d732..14143248fb 100644 --- a/libs/libcurl/src/non-ascii.c +++ b/libs/libcurl/src/non-ascii.c @@ -30,6 +30,7 @@ #include "formdata.h" #include "sendf.h" #include "urldata.h" +#include "multiif.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -84,7 +85,10 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data, { if(data && data->set.convtonetwork) { /* use translation callback */ - CURLcode result = data->set.convtonetwork(buffer, length); + CURLcode result; + Curl_set_in_callback(data, true); + result = data->set.convtonetwork(buffer, length); + Curl_set_in_callback(data, false); if(result) { failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s", @@ -147,7 +151,10 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data, { if(data && data->set.convfromnetwork) { /* use translation callback */ - CURLcode result = data->set.convfromnetwork(buffer, length); + CURLcode result; + Curl_set_in_callback(data, true); + result = data->set.convfromnetwork(buffer, length); + Curl_set_in_callback(data, false); if(result) { failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s", @@ -210,7 +217,10 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data, { if(data && data->set.convfromutf8) { /* use translation callback */ - CURLcode result = data->set.convfromutf8(buffer, length); + CURLcode result; + Curl_set_in_callback(data, true); + result = data->set.convfromutf8(buffer, length); + Curl_set_in_callback(data, false); if(result) { failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s", diff --git a/libs/libcurl/src/nwlib.c b/libs/libcurl/src/nwlib.c index 290cbe31f4..215d933acb 100644 --- a/libs/libcurl/src/nwlib.c +++ b/libs/libcurl/src/nwlib.c @@ -186,11 +186,9 @@ int GetOrSetUpData(int id, libdata_t **appData, app_data = (libdata_t *) get_app_data(id); if(!app_data) { - app_data = malloc(sizeof(libdata_t)); + app_data = calloc(1, sizeof(libdata_t)); if(app_data) { - memset(app_data, 0, sizeof(libdata_t)); - app_data->tenbytes = malloc(10); app_data->lock = NXMutexAlloc(0, 0, &liblock); diff --git a/libs/libcurl/src/objnames.inc b/libs/libcurl/src/objnames.inc index 6a5b2a8378..e362f6e8e1 100644 --- a/libs/libcurl/src/objnames.inc +++ b/libs/libcurl/src/objnames.inc @@ -86,7 +86,7 @@ curl_10char_object_name() { # curl_8char_object_name # # Same as curl_10char_object_name() description and details above, except -# that object name is limited to 8 charcters maximum. +# that object name is limited to 8 characters maximum. # curl_8char_object_name() { diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c index ac356d098c..c6cb794343 100644 --- a/libs/libcurl/src/openldap.c +++ b/libs/libcurl/src/openldap.c @@ -5,8 +5,8 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010, 2017, Howard Chu, <hyc@openldap.org> - * Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010, Howard Chu, <hyc@openldap.org> + * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -51,6 +51,25 @@ #include "curl_memory.h" #include "memdebug.h" +/* + * Uncommenting this will enable the built-in debug logging of the openldap + * library. The debug log level can be set using the CURL_OPENLDAP_TRACE + * environment variable. The debug output is written to stderr. + * + * The library supports the following debug flags: + * LDAP_DEBUG_NONE 0x0000 + * LDAP_DEBUG_TRACE 0x0001 + * LDAP_DEBUG_CONSTRUCT 0x0002 + * LDAP_DEBUG_DESTROY 0x0004 + * LDAP_DEBUG_PARAMETER 0x0008 + * LDAP_DEBUG_ANY 0xffff + * + * For example, use CURL_OPENLDAP_TRACE=0 for no debug, + * CURL_OPENLDAP_TRACE=2 for LDAP_DEBUG_CONSTRUCT messages only, + * CURL_OPENLDAP_TRACE=65535 for all debug message levels. + */ +/* #define CURL_OPENLDAP_DEBUG */ + #ifndef _LDAP_PVT_H extern int ldap_pvt_url_scheme2proto(const char *); extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, @@ -202,7 +221,16 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done) if(conn->handler->flags & PROTOPT_SSL) *ptr++ = 's'; snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d", - conn->host.name, conn->remote_port); + conn->host.name, conn->remote_port); + +#ifdef CURL_OPENLDAP_DEBUG + static int do_trace = 0; + const char *env = getenv("CURL_OPENLDAP_TRACE"); + do_trace = (env && strtol(env, NULL, 10) > 0); + if(do_trace) { + ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace); + } +#endif rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld); if(rc) { @@ -258,7 +286,7 @@ static CURLcode ldap_connecting(struct connectdata *conn, bool *done) tvp = &tv; -retry: + retry: if(!li->didbind) { char *binddn; struct berval passwd; @@ -444,8 +472,8 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, return ret; for(ent = ldap_first_message(li->ld, msg); ent; - ent = ldap_next_message(li->ld, ent)) { - struct berval bv, *bvals, **bvp = &bvals; + ent = ldap_next_message(li->ld, ent)) { + struct berval bv, *bvals; int binary = 0, msgtype; CURLcode writeerr; @@ -507,18 +535,40 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, } data->req.bytecount += bv.bv_len + 5; - for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp); - rc == LDAP_SUCCESS; - rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) { + for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals); + rc == LDAP_SUCCESS; + rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) { int i; - if(bv.bv_val == NULL) break; + if(bv.bv_val == NULL) + break; if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) binary = 1; else binary = 0; + if(bvals == NULL) { + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); + if(writeerr) { + *err = writeerr; + return -1; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, + bv.bv_len); + if(writeerr) { + *err = writeerr; + return -1; + } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":\n", 2); + if(writeerr) { + *err = writeerr; + return -1; + } + data->req.bytecount += bv.bv_len + 3; + continue; + } + for(i = 0; bvals[i].bv_val != NULL; i++) { int binval = 0; writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); @@ -527,24 +577,24 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, return -1; } - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, - bv.bv_len); - if(writeerr) { - *err = writeerr; - return -1; - } + writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, + bv.bv_len); + if(writeerr) { + *err = writeerr; + return -1; + } writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); - if(writeerr) { - *err = writeerr; - return -1; - } + if(writeerr) { + *err = writeerr; + return -1; + } data->req.bytecount += bv.bv_len + 2; if(!binary) { /* check for leading or trailing whitespace */ if(ISSPACE(bvals[i].bv_val[0]) || - ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) + ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) binval = 1; else { /* check for unprintable characters */ @@ -582,7 +632,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, data->req.bytecount += 2; if(val_b64_sz > 0) { writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, - val_b64_sz); + val_b64_sz); if(writeerr) { *err = writeerr; return -1; diff --git a/libs/libcurl/src/parsedate.c b/libs/libcurl/src/parsedate.c index b82605bbe3..3d3c00b4f1 100644 --- a/libs/libcurl/src/parsedate.c +++ b/libs/libcurl/src/parsedate.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -75,9 +75,7 @@ #include "curl_setup.h" -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #include <curl/curl.h> #include "strcase.h" @@ -121,6 +119,7 @@ static int parsedate(const char *date, time_t *output); #define tDAYZONE -60 /* offset for daylight savings time */ static const struct tzinfo tz[]= { {"GMT", 0}, /* Greenwich Mean */ + {"UT", 0}, /* Universal Time */ {"UTC", 0}, /* Universal (Coordinated) */ {"WET", 0}, /* Western European */ {"BST", 0 tDAYZONE}, /* British Summer */ @@ -278,26 +277,23 @@ struct my_tm { int tm_hour; int tm_mday; int tm_mon; - int tm_year; + int tm_year; /* full year */ }; /* struct tm to time since epoch in GMT time zone. * This is similar to the standard mktime function but for GMT only, and * doesn't suffer from the various bugs and portability problems that * some systems' implementations have. + * + * Returns 0 on success, otherwise non-zero. */ -static time_t my_timegm(struct my_tm *tm) +static void my_timegm(struct my_tm *tm, time_t *t) { static const int month_days_cumulative [12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; int month, year, leap_days; - if(tm->tm_year < 70) - /* we don't support years before 1970 as they will cause this function - to return a negative value */ - return -1; - - year = tm->tm_year + 1900; + year = tm->tm_year; month = tm->tm_mon; if(month < 0) { year += (11 - month) / 12; @@ -312,9 +308,9 @@ static time_t my_timegm(struct my_tm *tm) leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400) - (1969 / 4) + (1969 / 100) - (1969 / 400)); - return ((((time_t) (year - 1970) * 365 - + leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24 - + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; + *t = ((((time_t) (year - 1970) * 365 + + leap_days + month_days_cumulative[month] + tm->tm_mday - 1) * 24 + + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; } /* @@ -438,7 +434,7 @@ static int parsedate(const char *date, time_t *output) tzoff = (val/100 * 60 + val%100)*60; /* the + and - prefix indicates the local time compared to GMT, - this we need ther reversed math to get what we want */ + this we need their reversed math to get what we want */ tzoff = date[-1]=='+'?-tzoff:tzoff; } @@ -464,7 +460,7 @@ static int parsedate(const char *date, time_t *output) if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) { yearnum = val; found = TRUE; - if(yearnum < 1900) { + if(yearnum < 100) { if(yearnum > 70) yearnum += 1900; else @@ -493,18 +489,39 @@ static int parsedate(const char *date, time_t *output) /* lacks vital info, fail */ return PARSEDATE_FAIL; -#if SIZEOF_TIME_T < 5 - /* 32 bit time_t can only hold dates to the beginning of 2038 */ - if(yearnum > 2037) { - *output = 0x7fffffff; - return PARSEDATE_LATER; +#ifdef HAVE_TIME_T_UNSIGNED + if(yearnum < 1970) { + /* only positive numbers cannot return earlier */ + *output = TIME_T_MIN; + return PARSEDATE_SOONER; } #endif - if(yearnum < 1970) { - *output = 0; +#if (SIZEOF_TIME_T < 5) + +#ifdef HAVE_TIME_T_UNSIGNED + /* an unsigned 32 bit time_t can only hold dates to 2106 */ + if(yearnum > 2105) { + *output = TIME_T_MAX; + return PARSEDATE_LATER; + } +#else + /* a signed 32 bit time_t can only hold dates to the beginning of 2038 */ + if(yearnum > 2037) { + *output = TIME_T_MAX; + return PARSEDATE_LATER; + } + if(yearnum < 1903) { + *output = TIME_T_MIN; return PARSEDATE_SOONER; } +#endif + +#else + /* The Gregorian calendar was introduced 1582 */ + if(yearnum < 1583) + return PARSEDATE_FAIL; +#endif if((mdaynum > 31) || (monnum > 11) || (hournum > 23) || (minnum > 59) || (secnum > 60)) @@ -515,31 +532,25 @@ static int parsedate(const char *date, time_t *output) tm.tm_hour = hournum; tm.tm_mday = mdaynum; tm.tm_mon = monnum; - tm.tm_year = yearnum - 1900; - - /* my_timegm() returns a time_t. time_t is often 32 bits, even on many - architectures that feature 64 bit 'long'. + tm.tm_year = yearnum; - Some systems have 64 bit time_t and deal with years beyond 2038. However, - even on some of the systems with 64 bit time_t mktime() returns -1 for - dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06) + /* my_timegm() returns a time_t. time_t is often 32 bits, sometimes even on + architectures that feature 64 bit 'long' but ultimately time_t is the + correct data type to use. */ - t = my_timegm(&tm); - - /* time zone adjust (cast t to int to compare to negative one) */ - if(-1 != (int)t) { + my_timegm(&tm, &t); - /* Add the time zone diff between local time zone and GMT. */ - long delta = (long)(tzoff!=-1?tzoff:0); + /* Add the time zone diff between local time zone and GMT. */ + if(tzoff == -1) + tzoff = 0; - if((delta>0) && (t > LONG_MAX - delta)) { - *output = 0x7fffffff; - return PARSEDATE_LATER; /* time_t overflow */ - } - - t += delta; + if((tzoff > 0) && (t > TIME_T_MAX - tzoff)) { + *output = TIME_T_MAX; + return PARSEDATE_LATER; /* time_t overflow */ } + t += tzoff; + *output = t; return PARSEDATE_OK; @@ -551,10 +562,10 @@ time_t curl_getdate(const char *p, const time_t *now) int rc = parsedate(p, &parsed); (void)now; /* legacy argument from the past that we ignore */ - switch(rc) { - case PARSEDATE_OK: - case PARSEDATE_LATER: - case PARSEDATE_SOONER: + if(rc == PARSEDATE_OK) { + if(parsed == -1) + /* avoid returning -1 for a working scenario */ + parsed++; return parsed; } /* everything else is fail */ diff --git a/libs/libcurl/src/pingpong.c b/libs/libcurl/src/pingpong.c index 438856a991..ad370ee829 100644 --- a/libs/libcurl/src/pingpong.c +++ b/libs/libcurl/src/pingpong.c @@ -304,7 +304,10 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, * it would have been populated with something of size int to begin * with, even though its datatype may be larger than an int. */ - DEBUGASSERT((ptr + pp->cache_size) <= (buf + data->set.buffer_size + 1)); + if((ptr + pp->cache_size) > (buf + data->set.buffer_size + 1)) { + failf(data, "cached response data too big to handle"); + return CURLE_RECV_ERROR; + } memcpy(ptr, pp->cache, pp->cache_size); gotbytes = (ssize_t)pp->cache_size; free(pp->cache); /* free the cache */ diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c index 5792a4a6fd..78f6afef1f 100644 --- a/libs/libcurl/src/pop3.c +++ b/libs/libcurl/src/pop3.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -243,23 +243,30 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len, */ static void pop3_get_message(char *buffer, char **outptr) { - size_t len = 0; + size_t len = strlen(buffer); char *message = NULL; - /* Find the start of the message */ - for(message = buffer + 2; *message == ' ' || *message == '\t'; message++) - ; - - /* Find the end of the message */ - for(len = strlen(message); len--;) - if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && - message[len] != '\t') - break; - - /* Terminate the message */ - if(++len) { - message[len] = '\0'; + if(len > 2) { + /* Find the start of the message */ + len -= 2; + for(message = buffer + 2; *message == ' ' || *message == '\t'; + message++, len--) + ; + + /* Find the end of the message */ + for(; len--;) + if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && + message[len] != '\t') + break; + + /* Terminate the message */ + if(++len) { + message[len] = '\0'; + } } + else + /* junk input => zero length output */ + message = &buffer[len]; *outptr = message; } diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c index 72c518a149..f59faa3d3f 100644 --- a/libs/libcurl/src/progress.c +++ b/libs/libcurl/src/progress.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,9 +24,13 @@ #include "urldata.h" #include "sendf.h" +#include "multiif.h" #include "progress.h" #include "curl_printf.h" +/* check rate limits within this many recent milliseconds, at minimum. */ +#define MIN_RATE_LIMIT_PERIOD 3000 + /* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero byte) */ static void time2str(char *r, curl_off_t seconds) @@ -234,11 +238,12 @@ void Curl_pgrsStartNow(struct Curl_easy *data) data->progress.dl_limit_start.tv_usec = 0; /* clear all bits except HIDE and HEADERS_OUT */ data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT; + Curl_ratelimit(data, data->progress.start); } /* - * This is used to handle speed limits, calculating how much milliseconds we - * need to wait until we're back under the speed limit, if needed. + * This is used to handle speed limits, calculating how many milliseconds to + * wait until we're back under the speed limit, if needed. * * The way it works is by having a "starting point" (time & amount of data * transferred by then) used in the speed computation, to be used instead of @@ -250,73 +255,87 @@ void Curl_pgrsStartNow(struct Curl_easy *data) * the starting point, the limit (in bytes/s), the time of the starting point * and the current time. * - * Returns -1 if no waiting is needed (not enough data transferred since - * starting point yet), 0 when no waiting is needed but the starting point - * should be reset (to current), or the number of milliseconds to wait to get - * back under the speed limit. + * Returns 0 if no waiting is needed or when no waiting is needed but the + * starting point should be reset (to current); or the number of milliseconds + * to wait to get back under the speed limit. */ -long Curl_pgrsLimitWaitTime(curl_off_t cursize, - curl_off_t startsize, - curl_off_t limit, - struct curltime start, - struct curltime now) +timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, + curl_off_t startsize, + curl_off_t limit, + struct curltime start, + struct curltime now) { curl_off_t size = cursize - startsize; time_t minimum; time_t actual; - /* we don't have a starting point yet -- return 0 so it gets (re)set */ - if(start.tv_sec == 0 && start.tv_usec == 0) + if(!limit || !size) return 0; - /* not enough data yet */ - if(size < limit) - return -1; + /* + * 'minimum' is the number of milliseconds 'size' should take to download to + * stay below 'limit'. + */ + if(size < CURL_OFF_T_MAX/1000) + minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit); + else { + minimum = (time_t) (size / limit); + if(minimum < TIME_T_MAX/1000) + minimum *= 1000; + else + minimum = TIME_T_MAX; + } - minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit); + /* + * 'actual' is the time in milliseconds it took to actually download the + * last 'size' bytes. + */ actual = Curl_timediff(now, start); - - if(actual < minimum) - /* this is a conversion on some systems (64bit time_t => 32bit long) */ - return (long)(minimum - actual); + if(actual < minimum) { + /* if it downloaded the data faster than the limit, make it wait the + difference */ + return (minimum - actual); + } return 0; } +/* + * Set the number of downloaded bytes so far. + */ void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size) { - struct curltime now = Curl_now(); - data->progress.downloaded = size; +} - /* download speed limit */ - if((data->set.max_recv_speed > 0) && - (Curl_pgrsLimitWaitTime(data->progress.downloaded, - data->progress.dl_limit_size, - data->set.max_recv_speed, - data->progress.dl_limit_start, - now) == 0)) { - data->progress.dl_limit_start = now; - data->progress.dl_limit_size = size; +/* + * Update the timestamp and sizestamp to use for rate limit calculations. + */ +void Curl_ratelimit(struct Curl_easy *data, struct curltime now) +{ + /* don't set a new stamp unless the time since last update is long enough */ + if(data->set.max_recv_speed > 0) { + if(Curl_timediff(now, data->progress.dl_limit_start) >= + MIN_RATE_LIMIT_PERIOD) { + data->progress.dl_limit_start = now; + data->progress.dl_limit_size = data->progress.downloaded; + } + } + if(data->set.max_send_speed > 0) { + if(Curl_timediff(now, data->progress.ul_limit_start) >= + MIN_RATE_LIMIT_PERIOD) { + data->progress.ul_limit_start = now; + data->progress.ul_limit_size = data->progress.uploaded; + } } } +/* + * Set the number of uploaded bytes so far. + */ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size) { - struct curltime now = Curl_now(); - data->progress.uploaded = size; - - /* upload speed limit */ - if((data->set.max_send_speed > 0) && - (Curl_pgrsLimitWaitTime(data->progress.uploaded, - data->progress.ul_limit_size, - data->set.max_send_speed, - data->progress.ul_limit_start, - now) == 0)) { - data->progress.ul_limit_start = now; - data->progress.ul_limit_size = size; - } } void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size) @@ -358,6 +377,7 @@ int Curl_pgrsUpdate(struct connectdata *conn) curl_off_t total_transfer; curl_off_t total_expected_transfer; curl_off_t timespent; + curl_off_t timespent_ms; /* milliseconds */ struct Curl_easy *data = conn->data; int nowindex = data->progress.speeder_c% CURR_TIME; int checkindex; @@ -369,22 +389,27 @@ int Curl_pgrsUpdate(struct connectdata *conn) curl_off_t dlestimate = 0; curl_off_t total_estimate; bool shownow = FALSE; + curl_off_t dl = data->progress.downloaded; + curl_off_t ul = data->progress.uploaded; now = Curl_now(); /* what time is it */ /* The time spent so far (from the start) */ data->progress.timespent = Curl_timediff_us(now, data->progress.start); timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */ + timespent_ms = (curl_off_t)data->progress.timespent/1000; /* ms */ /* The average download speed this far */ - data->progress.dlspeed = (curl_off_t) - (data->progress.downloaded/ - (timespent>0?timespent:1)); + if(dl < CURL_OFF_T_MAX/1000) + data->progress.dlspeed = (dl * 1000 / (timespent_ms>0?timespent_ms:1)); + else + data->progress.dlspeed = (dl / (timespent>0?timespent:1)); /* The average upload speed this far */ - data->progress.ulspeed = (curl_off_t) - (data->progress.uploaded/ - (timespent>0?timespent:1)); + if(ul < CURL_OFF_T_MAX/1000) + data->progress.ulspeed = (ul * 1000 / (timespent_ms>0?timespent_ms:1)); + else + data->progress.ulspeed = (ul / (timespent>0?timespent:1)); /* Calculations done at most once a second, unless end is reached */ if(data->progress.lastshow != now.tv_sec) { @@ -455,22 +480,26 @@ int Curl_pgrsUpdate(struct connectdata *conn) if(data->set.fxferinfo) { /* There's a callback set, call that */ + Curl_set_in_callback(data, true); result = data->set.fxferinfo(data->set.progress_client, data->progress.size_dl, data->progress.downloaded, data->progress.size_ul, data->progress.uploaded); + Curl_set_in_callback(data, false); if(result) failf(data, "Callback aborted"); return result; } if(data->set.fprogress) { /* The older deprecated callback is set, call that */ + Curl_set_in_callback(data, true); result = data->set.fprogress(data->set.progress_client, (double)data->progress.size_dl, (double)data->progress.downloaded, (double)data->progress.size_ul, (double)data->progress.uploaded); + Curl_set_in_callback(data, false); if(result) failf(data, "Callback aborted"); return result; diff --git a/libs/libcurl/src/progress.h b/libs/libcurl/src/progress.h index 9333ab25c2..2baa925db2 100644 --- a/libs/libcurl/src/progress.h +++ b/libs/libcurl/src/progress.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -46,14 +46,15 @@ void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size); void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size); void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size); void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size); +void Curl_ratelimit(struct Curl_easy *data, struct curltime now); int Curl_pgrsUpdate(struct connectdata *); void Curl_pgrsResetTransferSizes(struct Curl_easy *data); void Curl_pgrsTime(struct Curl_easy *data, timerid timer); -long Curl_pgrsLimitWaitTime(curl_off_t cursize, - curl_off_t startsize, - curl_off_t limit, - struct curltime start, - struct curltime now); +timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize, + curl_off_t startsize, + curl_off_t limit, + struct curltime start, + struct curltime now); /* Don't show progress for sizes smaller than: */ #define LEAST_SIZE_PROGRESS BUFSIZE diff --git a/libs/libcurl/src/rand.c b/libs/libcurl/src/rand.c index 2670af9d97..0769ed1512 100644 --- a/libs/libcurl/src/rand.c +++ b/libs/libcurl/src/rand.c @@ -157,6 +157,12 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, unsigned char *bufp = buffer; DEBUGASSERT(num > 1); +#ifdef __clang_analyzer__ + /* This silences a scan-build warning about accesssing this buffer with + uninitialized memory. */ + memset(buffer, 0, sizeof(buffer)); +#endif + if((num/2 >= sizeof(buffer)) || !(num&1)) /* make sure it fits in the local buffer and that it is an odd number! */ return CURLE_BAD_FUNCTION_ARGUMENT; diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c index 925da2c1a9..41f3000139 100644 --- a/libs/libcurl/src/rtsp.c +++ b/libs/libcurl/src/rtsp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,7 +47,7 @@ * -incoming server requests * -server CSeq counter * -digest authentication - * -connect thru proxy + * -connect through proxy * -pipelining? */ @@ -357,7 +357,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) } /* Transport Header for SETUP requests */ - p_transport = Curl_checkheaders(conn, "Transport:"); + p_transport = Curl_checkheaders(conn, "Transport"); if(rtspreq == RTSPREQ_SETUP && !p_transport) { /* New Transport: setting? */ if(data->set.str[STRING_RTSP_TRANSPORT]) { @@ -381,11 +381,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) /* Accept Headers for DESCRIBE requests */ if(rtspreq == RTSPREQ_DESCRIBE) { /* Accept Header */ - p_accept = Curl_checkheaders(conn, "Accept:")? + p_accept = Curl_checkheaders(conn, "Accept")? NULL:"Accept: application/sdp\r\n"; /* Accept-Encoding header */ - if(!Curl_checkheaders(conn, "Accept-Encoding:") && + if(!Curl_checkheaders(conn, "Accept-Encoding") && data->set.str[STRING_ENCODING]) { Curl_safefree(conn->allocptr.accept_encoding); conn->allocptr.accept_encoding = @@ -402,11 +402,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) it might have been used in the proxy connect, but if we have got a header with the user-agent string specified, we erase the previously made string here. */ - if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) { + if(Curl_checkheaders(conn, "User-Agent") && conn->allocptr.uagent) { Curl_safefree(conn->allocptr.uagent); conn->allocptr.uagent = NULL; } - else if(!Curl_checkheaders(conn, "User-Agent:") && + else if(!Curl_checkheaders(conn, "User-Agent") && data->set.str[STRING_USERAGENT]) { p_uagent = conn->allocptr.uagent; } @@ -421,7 +421,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) /* Referrer */ Curl_safefree(conn->allocptr.ref); - if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) + if(data->change.referer && !Curl_checkheaders(conn, "Referer")) conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); else conn->allocptr.ref = NULL; @@ -438,7 +438,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) (rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) { /* Check to see if there is a range set in the custom headers */ - if(!Curl_checkheaders(conn, "Range:") && data->state.range) { + if(!Curl_checkheaders(conn, "Range") && data->state.range) { Curl_safefree(conn->allocptr.rangeline); conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range); p_range = conn->allocptr.rangeline; @@ -448,11 +448,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) /* * Sanity check the custom headers */ - if(Curl_checkheaders(conn, "CSeq:")) { + if(Curl_checkheaders(conn, "CSeq")) { failf(data, "CSeq cannot be set as a custom header."); return CURLE_RTSP_CSEQ_ERROR; } - if(Curl_checkheaders(conn, "Session:")) { + if(Curl_checkheaders(conn, "Session")) { failf(data, "Session ID cannot be set as a custom header."); return CURLE_BAD_FUNCTION_ARGUMENT; } @@ -542,7 +542,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) if(putsize > 0 || postsize > 0) { /* As stated in the http comments, it is probably not wise to * actually set a custom Content-Length in the headers */ - if(!Curl_checkheaders(conn, "Content-Length:")) { + if(!Curl_checkheaders(conn, "Content-Length")) { result = Curl_add_bufferf(req_buffer, "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", (data->set.upload ? putsize : postsize)); @@ -552,7 +552,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) if(rtspreq == RTSPREQ_SET_PARAMETER || rtspreq == RTSPREQ_GET_PARAMETER) { - if(!Curl_checkheaders(conn, "Content-Type:")) { + if(!Curl_checkheaders(conn, "Content-Type")) { result = Curl_add_bufferf(req_buffer, "Content-Type: text/parameters\r\n"); if(result) @@ -561,7 +561,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done) } if(rtspreq == RTSPREQ_ANNOUNCE) { - if(!Curl_checkheaders(conn, "Content-Type:")) { + if(!Curl_checkheaders(conn, "Content-Type")) { result = Curl_add_bufferf(req_buffer, "Content-Type: application/sdp\r\n"); if(result) @@ -764,13 +764,14 @@ CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len) writeit = data->set.fwrite_rtp; user_ptr = data->set.rtp_out; } - else - { + else { writeit = data->set.fwrite_func; user_ptr = data->set.out; } + Curl_set_in_callback(data, true); wrote = writeit(ptr, 1, len, user_ptr); + Curl_set_in_callback(data, false); if(CURL_WRITEFUNC_PAUSE == wrote) { failf(data, "Cannot pause RTP"); diff --git a/libs/libcurl/src/security.c b/libs/libcurl/src/security.c index 9b989681f3..ac39dae091 100644 --- a/libs/libcurl/src/security.c +++ b/libs/libcurl/src/security.c @@ -50,9 +50,7 @@ #include <netdb.h> #endif -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #include "urldata.h" #include "curl_base64.h" diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index a1cb8e4788..27c0ccc730 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,6 +22,10 @@ #include "curl_setup.h" +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + #ifdef HAVE_LINUX_TCP_H #include <linux/tcp.h> #endif @@ -33,6 +37,7 @@ #include "connect.h" #include "vtls/vtls.h" #include "ssh.h" +#include "easyif.h" #include "multiif.h" #include "non-ascii.h" #include "strerror.h" @@ -384,7 +389,7 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num, (WSAEWOULDBLOCK == err) #else /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefor + due to its inability to send off data without blocking. We therefore treat both error codes the same here */ (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) || (EINPROGRESS == err) @@ -451,7 +456,7 @@ ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, (WSAEWOULDBLOCK == err) #else /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefor + due to its inability to send off data without blocking. We therefore treat both error codes the same here */ (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) #endif @@ -536,18 +541,20 @@ static CURLcode pausewrite(struct Curl_easy *data, } -/* Curl_client_chop_write() writes chunks of data not larger than - * CURL_MAX_WRITE_SIZE via client write callback(s) and - * takes care of pause requests from the callbacks. +/* chop_write() writes chunks of data not larger than CURL_MAX_WRITE_SIZE via + * client write callback(s) and takes care of pause requests from the + * callbacks. */ -CURLcode Curl_client_chop_write(struct connectdata *conn, - int type, - char *ptr, - size_t len) +static CURLcode chop_write(struct connectdata *conn, + int type, + char *optr, + size_t olen) { struct Curl_easy *data = conn->data; curl_write_callback writeheader = NULL; curl_write_callback writebody = NULL; + char *ptr = optr; + size_t len = olen; if(!len) return CURLE_OK; @@ -593,25 +600,30 @@ CURLcode Curl_client_chop_write(struct connectdata *conn, } } - if(writeheader) { - size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader); - - if(CURL_WRITEFUNC_PAUSE == wrote) - /* here we pass in the HEADER bit only since if this was body as well - then it was passed already and clearly that didn't trigger the - pause, so this is saved for later with the HEADER bit only */ - return pausewrite(data, CLIENTWRITE_HEADER, ptr, len); - - if(wrote != chunklen) { - failf(data, "Failed writing header"); - return CURLE_WRITE_ERROR; - } - } - ptr += chunklen; len -= chunklen; } + if(writeheader) { + size_t wrote; + ptr = optr; + len = olen; + Curl_set_in_callback(data, true); + wrote = writeheader(ptr, 1, len, data->set.writeheader); + Curl_set_in_callback(data, false); + + if(CURL_WRITEFUNC_PAUSE == wrote) + /* here we pass in the HEADER bit only since if this was body as well + then it was passed already and clearly that didn't trigger the + pause, so this is saved for later with the HEADER bit only */ + return pausewrite(data, CLIENTWRITE_HEADER, ptr, len); + + if(wrote != len) { + failf(data, "Failed writing header"); + return CURLE_WRITE_ERROR; + } + } + return CURLE_OK; } @@ -653,7 +665,7 @@ CURLcode Curl_client_write(struct connectdata *conn, #endif /* CURL_DO_LINEEND_CONV */ } - return Curl_client_chop_write(conn, type, ptr, len); + return chop_write(conn, type, ptr, len); } CURLcode Curl_read_plain(curl_socket_t sockfd, @@ -794,8 +806,11 @@ static int showit(struct Curl_easy *data, curl_infotype type, } #endif /* CURL_DOES_CONVERSIONS */ - if(data->set.fdebug) + if(data->set.fdebug) { + Curl_set_in_callback(data, true); rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); + Curl_set_in_callback(data, false); + } else { switch(type) { case CURLINFO_TEXT: diff --git a/libs/libcurl/src/sendf.h b/libs/libcurl/src/sendf.h index fbe4f99c87..7c9134decc 100644 --- a/libs/libcurl/src/sendf.h +++ b/libs/libcurl/src/sendf.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -51,8 +51,6 @@ void Curl_failf(struct Curl_easy *, const char *fmt, ...); #define CLIENTWRITE_HEADER (1<<1) #define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER) -CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr, - size_t len) WARN_UNUSED_RESULT; CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len) WARN_UNUSED_RESULT; diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 70466bffb8..af53ee3efa 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,8 +22,10 @@ #include "curl_setup.h" -#ifdef HAVE_LIMITS_H #include <limits.h> + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> #endif #ifdef HAVE_LINUX_TCP_H @@ -41,6 +43,7 @@ #include "sendf.h" #include "http2.h" #include "setopt.h" +#include "multiif.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -108,8 +111,8 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) #define C_SSLVERSION_VALUE(x) (x & 0xffff) #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000) -static CURLcode setopt(struct Curl_easy *data, CURLoption option, - va_list param) +CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + va_list param) { char *argptr; CURLcode result = CURLE_OK; @@ -273,7 +276,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * before it is considered failure. For pingpong protocols. */ arg = va_arg(param, long); - if((arg >= 0) && (arg < (INT_MAX/1000))) + if((arg >= 0) && (arg <= (INT_MAX/1000))) data->set.server_response_timeout = arg * 1000; else return CURLE_BAD_FUNCTION_ARGUMENT; @@ -358,32 +361,42 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, */ data->set.timevalue = (time_t)va_arg(param, long); break; - case CURLOPT_SSLVERSION: + + case CURLOPT_TIMEVALUE_LARGE: /* - * Set explicit SSL version to try to connect with, as some SSL - * implementations are lame. + * This is the value to compare with the remote document with the + * method set with CURLOPT_TIMECONDITION */ -#ifdef USE_SSL - arg = va_arg(param, long); - if((arg < CURL_SSLVERSION_DEFAULT) || (arg > CURL_SSLVERSION_TLSv1_3)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.ssl.primary.version = C_SSLVERSION_VALUE(arg); - data->set.ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg); -#else - result = CURLE_UNKNOWN_OPTION; -#endif + data->set.timevalue = (time_t)va_arg(param, curl_off_t); break; + + case CURLOPT_SSLVERSION: case CURLOPT_PROXY_SSLVERSION: /* - * Set explicit SSL version to try to connect with for proxy, as some SSL + * Set explicit SSL version to try to connect with, as some SSL * implementations are lame. */ #ifdef USE_SSL - arg = va_arg(param, long); - if((arg < CURL_SSLVERSION_DEFAULT) || (arg > CURL_SSLVERSION_TLSv1_3)) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.proxy_ssl.primary.version = C_SSLVERSION_VALUE(arg); - data->set.proxy_ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg); + { + long version, version_max; + struct ssl_primary_config *primary = (option == CURLOPT_SSLVERSION ? + &data->set.ssl.primary : + &data->set.proxy_ssl.primary); + + arg = va_arg(param, long); + + version = C_SSLVERSION_VALUE(arg); + version_max = C_SSLVERSION_MAX_VALUE(arg); + + if(version < CURL_SSLVERSION_DEFAULT || + version >= CURL_SSLVERSION_LAST || + version_max < CURL_SSLVERSION_MAX_NONE || + version_max >= CURL_SSLVERSION_MAX_LAST) + return CURLE_BAD_FUNCTION_ARGUMENT; + + primary->version = version; + primary->version_max = version_max; + } #else result = CURLE_UNKNOWN_OPTION; #endif @@ -438,7 +451,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * Send authentication (user+password) when following locations, even when * hostname changed. */ - data->set.http_disable_hostname_check_before_authentication = + data->set.allow_auth_to_other_hosts = (0 != va_arg(param, long)) ? TRUE : FALSE; break; @@ -768,11 +781,13 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, if(checkprefix("Set-Cookie:", argptr)) /* HTTP Header format line */ - Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL); + Curl_cookie_add(data, data->cookies, TRUE, FALSE, argptr + 11, NULL, + NULL); else /* Netscape format line */ - Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL); + Curl_cookie_add(data, data->cookies, FALSE, FALSE, argptr, NULL, + NULL); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); free(argptr); @@ -1024,6 +1039,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, */ data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE; break; +#endif case CURLOPT_SOCKS5_GSSAPI_SERVICE: case CURLOPT_PROXY_SERVICE_NAME: @@ -1033,10 +1049,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], va_arg(param, char *)); break; -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ - defined(USE_SPNEGO) case CURLOPT_SERVICE_NAME: /* * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO @@ -1045,8 +1058,6 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, va_arg(param, char *)); break; -#endif - case CURLOPT_HEADERDATA: /* * Custom pointer to pass the header write callback function @@ -1198,7 +1209,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * operation. */ arg = va_arg(param, long); - if((arg >= 0) && (arg < (INT_MAX/1000))) + if((arg >= 0) && (arg <= (INT_MAX/1000))) data->set.timeout = arg * 1000; else return CURLE_BAD_FUNCTION_ARGUMENT; @@ -1216,7 +1227,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * The maximum time you allow curl to use to connect. */ arg = va_arg(param, long); - if((arg >= 0) && (arg < (INT_MAX/1000))) + if((arg >= 0) && (arg <= (INT_MAX/1000))) data->set.connecttimeout = arg * 1000; else return CURLE_BAD_FUNCTION_ARGUMENT; @@ -1590,6 +1601,13 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE; break; + case CURLOPT_HAPROXYPROTOCOL: + /* + * Set to send the HAProxy Proxy Protocol header + */ + data->set.haproxyprotocol = (0 != va_arg(param, long)) ? TRUE : FALSE; + break; + case CURLOPT_INTERFACE: /* * Set what interface or address/hostname to bind the socket to when @@ -1730,7 +1748,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * Set a SSL_CTX callback */ #ifdef USE_SSL - if(Curl_ssl->have_ssl_ctx) + if(Curl_ssl->supports & SSLSUPP_SSL_CTX) data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); else #endif @@ -1741,7 +1759,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * Set a SSL_CTX callback parameter pointer */ #ifdef USE_SSL - if(Curl_ssl->have_ssl_ctx) + if(Curl_ssl->supports & SSLSUPP_SSL_CTX) data->set.ssl.fsslctxp = va_arg(param, void *); else #endif @@ -1760,7 +1778,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, break; case CURLOPT_CERTINFO: #ifdef USE_SSL - if(Curl_ssl->have_certinfo) + if(Curl_ssl->supports & SSLSUPP_CERTINFO) data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; else #endif @@ -1772,7 +1790,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * Specify file name of the public key in DER format. */ #ifdef USE_SSL - if(Curl_ssl->have_pinnedpubkey) + if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], va_arg(param, char *)); else @@ -1785,7 +1803,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * Specify file name of the public key in DER format. */ #ifdef USE_SSL - if(Curl_ssl->have_pinnedpubkey) + if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY], va_arg(param, char *)); else @@ -1813,7 +1831,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * certificates which have been prepared using openssl c_rehash utility. */ #ifdef USE_SSL - if(Curl_ssl->have_ca_path) + if(Curl_ssl->supports & SSLSUPP_CA_PATH) /* This does not work on windows. */ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], va_arg(param, char *)); @@ -1827,7 +1845,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, * CA certificates which have been prepared using openssl c_rehash utility. */ #ifdef USE_SSL - if(Curl_ssl->have_ca_path) + if(Curl_ssl->supports & SSLSUPP_CA_PATH) /* This does not work on windows. */ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY], va_arg(param, char *)); @@ -2097,6 +2115,21 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, data->set.fclosesocket = va_arg(param, curl_closesocket_callback); break; + case CURLOPT_RESOLVER_START_FUNCTION: + /* + * resolver start callback function: called before a new resolver request + * is started + */ + data->set.resolver_start = va_arg(param, curl_resolver_start_callback); + break; + + case CURLOPT_RESOLVER_START_DATA: + /* + * resolver start callback data pointer. Might be NULL. + */ + data->set.resolver_start_client = va_arg(param, void *); + break; + case CURLOPT_CLOSESOCKETDATA: /* * socket callback data pointer. Might be NULL. @@ -2110,7 +2143,7 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid; break; -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) /* we only include SSH options if explicitly built to support SSH */ case CURLOPT_SSH_AUTH_TYPES: data->set.ssh_auth_types = va_arg(param, long); @@ -2161,7 +2194,6 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, data->set.ssh_keyfunc_userp = va_arg(param, void *); break; #endif /* HAVE_LIBSSH2_KNOWNHOST_API */ - #endif /* USE_LIBSSH2 */ case CURLOPT_HTTP_TRANSFER_DECODING: @@ -2521,6 +2553,15 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, case CURLOPT_SSH_COMPRESSION: data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE; break; + case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: + arg = va_arg(param, long); + if(arg < 0) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.happy_eyeballs_timeout = arg; + break; + case CURLOPT_DNS_SHUFFLE_ADDRESSES: + data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE; + break; default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; @@ -2533,6 +2574,9 @@ static CURLcode setopt(struct Curl_easy *data, CURLoption option, /* * curl_easy_setopt() is the external interface for setting options on an * easy handle. + * + * NOTE: This is one of few API functions that are allowed to be called from + * within a callback. */ #undef curl_easy_setopt @@ -2546,9 +2590,8 @@ CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...) va_start(arg, tag); - result = setopt(data, tag, arg); + result = Curl_vsetopt(data, tag, arg); va_end(arg); return result; } - diff --git a/libs/libcurl/src/setopt.h b/libs/libcurl/src/setopt.h index 35769440fa..c658e04aeb 100644 --- a/libs/libcurl/src/setopt.h +++ b/libs/libcurl/src/setopt.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,5 +23,7 @@ ***************************************************************************/ CURLcode Curl_setstropt(char **charp, const char *s); +CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + va_list arg); #endif /* HEADER_CURL_SETOPT_H */ diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c index cd81c02541..55716c63b0 100644 --- a/libs/libcurl/src/sha256.c +++ b/libs/libcurl/src/sha256.c @@ -29,9 +29,17 @@ #if defined(USE_OPENSSL) +#include <openssl/opensslv.h> + +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) +#define USE_OPENSSL_SHA256 +#endif + +#endif + +#ifdef USE_OPENSSL_SHA256 /* When OpenSSL is available we use the SHA256-function from OpenSSL */ #include <openssl/sha.h> - #else /* When no other crypto library is available we use this code segment */ @@ -234,7 +242,7 @@ static int SHA256_Final(unsigned char *out, sha256_compress(md, md->buf); md->curlen = 0; } - /* pad upto 56 bytes of zeroes */ + /* pad up to 56 bytes of zeroes */ while(md->curlen < 56) { md->buf[md->curlen++] = (unsigned char)0; } diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c index efcfd2da24..9ac61505cf 100644 --- a/libs/libcurl/src/smb.c +++ b/libs/libcurl/src/smb.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies - * Copyright (C) 2016-2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2016-2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -146,19 +146,12 @@ static unsigned int smb_swap32(unsigned int x) ((x >> 24) & 0xff); } -#ifdef HAVE_LONGLONG -static unsigned long long smb_swap64(unsigned long long x) +static curl_off_t smb_swap64(curl_off_t x) { - return ((unsigned long long) smb_swap32((unsigned int) x) << 32) | + return ((curl_off_t) smb_swap32((unsigned int) x) << 32) | smb_swap32((unsigned int) (x >> 32)); } -#else -static unsigned __int64 smb_swap64(unsigned __int64 x) -{ - return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) | - smb_swap32((unsigned int) (x >> 32)); -} -#endif + #else # define smb_swap16(x) (x) # define smb_swap32(x) (x) @@ -716,20 +709,21 @@ static CURLcode smb_connection_state(struct connectdata *conn, bool *done) } /* - * Convert a timestamp from the Windows world (100 nsec units from - * 1 Jan 1601) to Posix time. + * Convert a timestamp from the Windows world (100 nsec units from 1 Jan 1601) + * to Posix time. Cap the output to fit within a time_t. */ -static void get_posix_time(long *_out, const void *_in) +static void get_posix_time(time_t *out, curl_off_t timestamp) { -#ifdef HAVE_LONGLONG - long long timestamp = *(long long *) _in; -#else - unsigned __int64 timestamp = *(unsigned __int64 *) _in; -#endif - - timestamp -= 116444736000000000ULL; + timestamp -= 116444736000000000; timestamp /= 10000000; - *_out = (long) timestamp; +#if SIZEOF_TIME_T < SIZEOF_CURL_OFF_T + if(timestamp > TIME_T_MAX) + *out = TIME_T_MAX; + else if(timestamp < TIME_T_MIN) + *out = TIME_T_MIN; + else +#endif + *out = (time_t) timestamp; } static CURLcode smb_request_state(struct connectdata *conn, bool *done) @@ -796,10 +790,16 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done) else { smb_m = (const struct smb_nt_create_response*) msg; conn->data->req.size = smb_swap64(smb_m->end_of_file); - Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size); - if(conn->data->set.get_filetime) - get_posix_time(&conn->data->info.filetime, &smb_m->last_change_time); - next_state = SMB_DOWNLOAD; + if(conn->data->req.size < 0) { + req->result = CURLE_WEIRD_SERVER_REPLY; + next_state = SMB_CLOSE; + } + else { + Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size); + if(conn->data->set.get_filetime) + get_posix_time(&conn->data->info.filetime, smb_m->last_change_time); + next_state = SMB_DOWNLOAD; + } } break; diff --git a/libs/libcurl/src/smb.h b/libs/libcurl/src/smb.h index 1a4f66e5a8..c3ee7ae039 100644 --- a/libs/libcurl/src/smb.h +++ b/libs/libcurl/src/smb.h @@ -8,6 +8,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies + * Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -165,11 +166,7 @@ struct smb_nt_create { unsigned int flags; unsigned int root_fid; unsigned int access; -#ifdef HAVE_LONGLONG - unsigned long long allocation_size; -#else - unsigned __int64 allocation_size; -#endif + curl_off_t allocation_size; unsigned int ext_file_attributes; unsigned int share_access; unsigned int create_disposition; @@ -187,25 +184,15 @@ struct smb_nt_create_response { unsigned char op_lock_level; unsigned short fid; unsigned int create_disposition; -#ifdef HAVE_LONGLONG - unsigned long long create_time; - unsigned long long last_access_time; - unsigned long long last_write_time; - unsigned long long last_change_time; -#else - unsigned __int64 create_time; - unsigned __int64 last_access_time; - unsigned __int64 last_write_time; - unsigned __int64 last_change_time; -#endif + + curl_off_t create_time; + curl_off_t last_access_time; + curl_off_t last_write_time; + curl_off_t last_change_time; unsigned int ext_file_attributes; -#ifdef HAVE_LONGLONG - unsigned long long allocation_size; - unsigned long long end_of_file; -#else - unsigned __int64 allocation_size; - unsigned __int64 end_of_file; -#endif + curl_off_t allocation_size; + curl_off_t end_of_file; + } PACK; struct smb_read { diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c index 44ee2e9f8f..3f3b45a954 100644 --- a/libs/libcurl/src/smtp.c +++ b/libs/libcurl/src/smtp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -232,23 +232,30 @@ static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, */ static void smtp_get_message(char *buffer, char **outptr) { - size_t len = 0; + size_t len = strlen(buffer); char *message = NULL; - /* Find the start of the message */ - for(message = buffer + 4; *message == ' ' || *message == '\t'; message++) - ; - - /* Find the end of the message */ - for(len = strlen(message); len--;) - if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && - message[len] != '\t') - break; - - /* Terminate the message */ - if(++len) { - message[len] = '\0'; + if(len > 4) { + /* Find the start of the message */ + len -= 4; + for(message = buffer + 4; *message == ' ' || *message == '\t'; + message++, len--) + ; + + /* Find the end of the message */ + for(; len--;) + if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && + message[len] != '\t') + break; + + /* Terminate the message */ + if(++len) { + message[len] = '\0'; + } } + else + /* junk input => zero length output */ + message = &buffer[len]; *outptr = message; } @@ -1282,6 +1289,11 @@ static CURLcode smtp_perform(struct connectdata *conn, bool *connected, /* Store the first recipient (or NULL if not specified) */ smtp->rcpt = data->set.mail_rcpt; + /* Initial data character is the first character in line: it is implicitly + preceded by a virtual CRLF. */ + smtp->trailing_crlf = TRUE; + smtp->eob = 2; + /* Start the first command in the DO phase */ if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt) /* MAIL transfer */ diff --git a/libs/libcurl/src/ssh-libssh.c b/libs/libcurl/src/ssh-libssh.c new file mode 100644 index 0000000000..34ef490c4e --- /dev/null +++ b/libs/libcurl/src/ssh-libssh.c @@ -0,0 +1,2736 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2017 - 2018 Red Hat, Inc. + * + * Authors: Nikos Mavrogiannopoulos, Tomas Mraz, Stanislav Zidek, + * Robert Kolcun, Andreas Schneider + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_LIBSSH + +#include <limits.h> + +#include <libssh/libssh.h> +#include <libssh/sftp.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_UTSNAME_H +#include <sys/utsname.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef __VMS +#include <in.h> +#include <inet.h> +#endif + +#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) +#undef in_addr_t +#define in_addr_t unsigned long +#endif + +#include <curl/curl.h> +#include "urldata.h" +#include "sendf.h" +#include "hostip.h" +#include "progress.h" +#include "transfer.h" +#include "escape.h" +#include "http.h" /* for HTTP proxy tunnel stuff */ +#include "ssh.h" +#include "url.h" +#include "speedcheck.h" +#include "getinfo.h" +#include "strdup.h" +#include "strcase.h" +#include "vtls/vtls.h" +#include "connect.h" +#include "strerror.h" +#include "inet_ntop.h" +#include "parsedate.h" /* for the week day and month names */ +#include "sockaddr.h" /* required for Curl_sockaddr_storage */ +#include "strtoofft.h" +#include "multiif.h" +#include "select.h" +#include "warnless.h" + +/* for permission and open flags */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" +#include "curl_path.h" + +/* Local functions: */ +static CURLcode myssh_connect(struct connectdata *conn, bool *done); +static CURLcode myssh_multi_statemach(struct connectdata *conn, + bool *done); +static CURLcode myssh_do_it(struct connectdata *conn, bool *done); + +static CURLcode scp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done); +static CURLcode scp_disconnect(struct connectdata *conn, + bool dead_connection); + +static CURLcode sftp_done(struct connectdata *conn, + CURLcode, bool premature); +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done); +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done); + +static void sftp_quote(struct connectdata *conn); +static void sftp_quote_stat(struct connectdata *conn); + +static int myssh_getsock(struct connectdata *conn, curl_socket_t *sock, + int numsocks); + +static int myssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, + int numsocks); + +static CURLcode myssh_setup_connection(struct connectdata *conn); + +/* + * SCP protocol handler. + */ + +const struct Curl_handler Curl_handler_scp = { + "SCP", /* scheme */ + myssh_setup_connection, /* setup_connection */ + myssh_do_it, /* do_it */ + scp_done, /* done */ + ZERO_NULL, /* do_more */ + myssh_connect, /* connect_it */ + myssh_multi_statemach, /* connecting */ + scp_doing, /* doing */ + myssh_getsock, /* proto_getsock */ + myssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + myssh_perform_getsock, /* perform_getsock */ + scp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SCP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ +}; + +/* + * SFTP protocol handler. + */ + +const struct Curl_handler Curl_handler_sftp = { + "SFTP", /* scheme */ + myssh_setup_connection, /* setup_connection */ + myssh_do_it, /* do_it */ + sftp_done, /* done */ + ZERO_NULL, /* do_more */ + myssh_connect, /* connect_it */ + myssh_multi_statemach, /* connecting */ + sftp_doing, /* doing */ + myssh_getsock, /* proto_getsock */ + myssh_getsock, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + myssh_perform_getsock, /* perform_getsock */ + sftp_disconnect, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + PORT_SSH, /* defport */ + CURLPROTO_SFTP, /* protocol */ + PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION + | PROTOPT_NOURLQUERY /* flags */ +}; + +static CURLcode sftp_error_to_CURLE(int err) +{ + switch(err) { + case SSH_FX_OK: + return CURLE_OK; + + case SSH_FX_NO_SUCH_FILE: + case SSH_FX_NO_SUCH_PATH: + return CURLE_REMOTE_FILE_NOT_FOUND; + + case SSH_FX_PERMISSION_DENIED: + case SSH_FX_WRITE_PROTECT: + return CURLE_REMOTE_ACCESS_DENIED; + + case SSH_FX_FILE_ALREADY_EXISTS: + return CURLE_REMOTE_FILE_EXISTS; + + default: + break; + } + + return CURLE_SSH; +} + +/* + * SSH State machine related code + */ +/* This is the ONLY way to change SSH state! */ +static void state(struct connectdata *conn, sshstate nowstate) +{ + struct ssh_conn *sshc = &conn->proto.sshc; +#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) + /* for debug purposes */ + static const char *const names[] = { + "SSH_STOP", + "SSH_INIT", + "SSH_S_STARTUP", + "SSH_HOSTKEY", + "SSH_AUTHLIST", + "SSH_AUTH_PKEY_INIT", + "SSH_AUTH_PKEY", + "SSH_AUTH_PASS_INIT", + "SSH_AUTH_PASS", + "SSH_AUTH_AGENT_INIT", + "SSH_AUTH_AGENT_LIST", + "SSH_AUTH_AGENT", + "SSH_AUTH_HOST_INIT", + "SSH_AUTH_HOST", + "SSH_AUTH_KEY_INIT", + "SSH_AUTH_KEY", + "SSH_AUTH_GSSAPI", + "SSH_AUTH_DONE", + "SSH_SFTP_INIT", + "SSH_SFTP_REALPATH", + "SSH_SFTP_QUOTE_INIT", + "SSH_SFTP_POSTQUOTE_INIT", + "SSH_SFTP_QUOTE", + "SSH_SFTP_NEXT_QUOTE", + "SSH_SFTP_QUOTE_STAT", + "SSH_SFTP_QUOTE_SETSTAT", + "SSH_SFTP_QUOTE_SYMLINK", + "SSH_SFTP_QUOTE_MKDIR", + "SSH_SFTP_QUOTE_RENAME", + "SSH_SFTP_QUOTE_RMDIR", + "SSH_SFTP_QUOTE_UNLINK", + "SSH_SFTP_QUOTE_STATVFS", + "SSH_SFTP_GETINFO", + "SSH_SFTP_FILETIME", + "SSH_SFTP_TRANS_INIT", + "SSH_SFTP_UPLOAD_INIT", + "SSH_SFTP_CREATE_DIRS_INIT", + "SSH_SFTP_CREATE_DIRS", + "SSH_SFTP_CREATE_DIRS_MKDIR", + "SSH_SFTP_READDIR_INIT", + "SSH_SFTP_READDIR", + "SSH_SFTP_READDIR_LINK", + "SSH_SFTP_READDIR_BOTTOM", + "SSH_SFTP_READDIR_DONE", + "SSH_SFTP_DOWNLOAD_INIT", + "SSH_SFTP_DOWNLOAD_STAT", + "SSH_SFTP_CLOSE", + "SSH_SFTP_SHUTDOWN", + "SSH_SCP_TRANS_INIT", + "SSH_SCP_UPLOAD_INIT", + "SSH_SCP_DOWNLOAD_INIT", + "SSH_SCP_DOWNLOAD", + "SSH_SCP_DONE", + "SSH_SCP_SEND_EOF", + "SSH_SCP_WAIT_EOF", + "SSH_SCP_WAIT_CLOSE", + "SSH_SCP_CHANNEL_FREE", + "SSH_SESSION_DISCONNECT", + "SSH_SESSION_FREE", + "QUIT" + }; + + + if(sshc->state != nowstate) { + infof(conn->data, "SSH %p state change from %s to %s\n", + (void *) sshc, names[sshc->state], names[nowstate]); + } +#endif + + sshc->state = nowstate; +} + +/* Multiple options: + * 1. data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] is set with an MD5 + * hash (90s style auth, not sure we should have it here) + * 2. data->set.ssh_keyfunc callback is set. Then we do trust on first + * use. We even save on knownhosts if CURLKHSTAT_FINE_ADD_TO_FILE + * is returned by it. + * 3. none of the above. We only accept if it is present on known hosts. + * + * Returns SSH_OK or SSH_ERROR. + */ +static int myssh_is_known(struct connectdata *conn) +{ + int rc; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + ssh_key pubkey; + size_t hlen; + unsigned char *hash = NULL; + char *base64 = NULL; + int vstate; + enum curl_khmatch keymatch; + struct curl_khkey foundkey; + curl_sshkeycallback func = + data->set.ssh_keyfunc; + + rc = ssh_get_publickey(sshc->ssh_session, &pubkey); + if(rc != SSH_OK) + return rc; + + if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { + rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, + &hash, &hlen); + if(rc != SSH_OK) + goto cleanup; + + if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) || + memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) { + rc = SSH_ERROR; + goto cleanup; + } + + rc = SSH_OK; + goto cleanup; + } + + if(data->set.ssl.primary.verifyhost != TRUE) { + rc = SSH_OK; + goto cleanup; + } + + vstate = ssh_is_server_known(sshc->ssh_session); + switch(vstate) { + case SSH_SERVER_KNOWN_OK: + keymatch = CURLKHMATCH_OK; + break; + case SSH_SERVER_FILE_NOT_FOUND: + /* fallthrough */ + case SSH_SERVER_NOT_KNOWN: + keymatch = CURLKHMATCH_MISSING; + break; + default: + keymatch = CURLKHMATCH_MISMATCH; + break; + } + + if(func) { /* use callback to determine action */ + rc = ssh_pki_export_pubkey_base64(pubkey, &base64); + if(rc != SSH_OK) + goto cleanup; + + foundkey.key = base64; + foundkey.len = strlen(base64); + + switch(ssh_key_type(pubkey)) { + case SSH_KEYTYPE_RSA: + foundkey.keytype = CURLKHTYPE_RSA; + break; + case SSH_KEYTYPE_RSA1: + foundkey.keytype = CURLKHTYPE_RSA1; + break; + case SSH_KEYTYPE_ECDSA: + foundkey.keytype = CURLKHTYPE_ECDSA; + break; +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0) + case SSH_KEYTYPE_ED25519: + foundkey.keytype = CURLKHTYPE_ED25519; + break; +#endif + case SSH_KEYTYPE_DSS: + foundkey.keytype = CURLKHTYPE_DSS; + break; + default: + rc = SSH_ERROR; + goto cleanup; + } + + /* we don't have anything equivalent to knownkey. Always NULL */ + Curl_set_in_callback(data, true); + rc = func(data, NULL, &foundkey, /* from the remote host */ + keymatch, data->set.ssh_keyfunc_userp); + Curl_set_in_callback(data, false); + + switch(rc) { + case CURLKHSTAT_FINE_ADD_TO_FILE: + rc = ssh_write_knownhost(sshc->ssh_session); + if(rc != SSH_OK) { + goto cleanup; + } + break; + case CURLKHSTAT_FINE: + break; + default: /* REJECT/DEFER */ + rc = SSH_ERROR; + goto cleanup; + } + } + else { + if(keymatch != CURLKHMATCH_OK) { + rc = SSH_ERROR; + goto cleanup; + } + } + rc = SSH_OK; + +cleanup: + if(hash) + ssh_clean_pubkey_hash(&hash); + ssh_key_free(pubkey); + return rc; +} + +#define MOVE_TO_ERROR_STATE(_r) { \ + state(conn, SSH_SESSION_FREE); \ + sshc->actualcode = _r; \ + rc = SSH_ERROR; \ + break; \ +} + +#define MOVE_TO_SFTP_CLOSE_STATE() { \ + state(conn, SSH_SFTP_CLOSE); \ + sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ + rc = SSH_ERROR; \ + break; \ +} + +#define MOVE_TO_LAST_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_PASS_INIT); \ + break; \ + } \ + else { \ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ + } + +#define MOVE_TO_TERTIARY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_KEY_INIT); \ + break; \ + } \ + else { \ + MOVE_TO_LAST_AUTH; \ + } + +#define MOVE_TO_SECONDARY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_GSSAPI); \ + break; \ + } \ + else { \ + MOVE_TO_TERTIARY_AUTH; \ + } + +static +int myssh_auth_interactive(struct connectdata *conn) +{ + int rc; + struct ssh_conn *sshc = &conn->proto.sshc; + int nprompts; + +restart: + switch(sshc->kbd_state) { + case 0: + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + + if(rc != SSH_AUTH_INFO) + return SSH_ERROR; + + nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); + if(nprompts == SSH_ERROR || nprompts != 1) + return SSH_ERROR; + + rc = ssh_userauth_kbdint_setanswer(sshc->ssh_session, 0, conn->passwd); + if(rc < 0) + return SSH_ERROR; + + /* fallthrough */ + case 1: + sshc->kbd_state = 1; + + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) + rc = SSH_OK; + else if(rc == SSH_AUTH_INFO) { + nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); + if(nprompts != 0) + return SSH_ERROR; + + sshc->kbd_state = 2; + goto restart; + } + else + rc = SSH_ERROR; + break; + case 2: + sshc->kbd_state = 2; + + rc = ssh_userauth_kbdint(sshc->ssh_session, NULL, NULL); + if(rc == SSH_AUTH_AGAIN) + return SSH_AGAIN; + else if(rc == SSH_AUTH_SUCCESS) + rc = SSH_OK; + else + rc = SSH_ERROR; + + break; + default: + return SSH_ERROR; + } + + sshc->kbd_state = 0; + return rc; +} + +/* + * ssh_statemach_act() runs the SSH state machine as far as it can without + * blocking and without reaching the end. The data the pointer 'block' points + * to will be set to TRUE if the libssh function returns SSH_AGAIN + * meaning it wants to be called again when the socket is ready + */ +static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) +{ + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + struct SSHPROTO *protop = data->req.protop; + struct ssh_conn *sshc = &conn->proto.sshc; + int rc = SSH_NO_ERROR, err; + char *new_readdir_line; + int seekerr = CURL_SEEKFUNC_OK; + const char *err_msg; + *block = 0; /* we're not blocking by default */ + + do { + + switch(sshc->state) { + case SSH_INIT: + sshc->secondCreateDirs = 0; + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_OK; + +#if 0 + ssh_set_log_level(SSH_LOG_PROTOCOL); +#endif + + /* Set libssh to non-blocking, since everything internally is + non-blocking */ + ssh_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_S_STARTUP); + /* fall-through */ + + case SSH_S_STARTUP: + rc = ssh_connect(sshc->ssh_session); + if(rc == SSH_AGAIN) + break; + + if(rc != SSH_OK) { + failf(data, "Failure establishing ssh session"); + MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); + } + + state(conn, SSH_HOSTKEY); + + /* fall-through */ + case SSH_HOSTKEY: + + rc = myssh_is_known(conn); + if(rc != SSH_OK) { + MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); + } + + state(conn, SSH_AUTHLIST); + /* fall through */ + case SSH_AUTHLIST:{ + sshc->authed = FALSE; + + rc = ssh_userauth_none(sshc->ssh_session, NULL); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Authenticated with none\n"); + state(conn, SSH_AUTH_DONE); + break; + } + else if(rc == SSH_AUTH_ERROR) { + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + + sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); + if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { + state(conn, SSH_AUTH_PKEY_INIT); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { + state(conn, SSH_AUTH_GSSAPI); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { + state(conn, SSH_AUTH_KEY_INIT); + } + else if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { + state(conn, SSH_AUTH_PASS_INIT); + } + else { /* unsupported authentication method */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + + break; + } + case SSH_AUTH_PKEY_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { + MOVE_TO_SECONDARY_AUTH; + } + + /* Two choices, (1) private key was given on CMD, + * (2) use the "default" keys. */ + if(data->set.str[STRING_SSH_PRIVATE_KEY]) { + if(sshc->pubkey && !data->set.ssl.key_passwd) { + rc = ssh_userauth_try_publickey(sshc->ssh_session, NULL, + sshc->pubkey); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc != SSH_OK) { + MOVE_TO_SECONDARY_AUTH; + } + } + + rc = ssh_pki_import_privkey_file(data-> + set.str[STRING_SSH_PRIVATE_KEY], + data->set.ssl.key_passwd, NULL, + NULL, &sshc->privkey); + if(rc != SSH_OK) { + failf(data, "Could not load private key file %s", + data->set.str[STRING_SSH_PRIVATE_KEY]); + break; + } + + state(conn, SSH_AUTH_PKEY); + break; + + } + else { + infof(data, "Authentication using SSH public key file\n"); + + rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL, + data->set.ssl.key_passwd); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + if(rc == SSH_AUTH_SUCCESS) { + rc = SSH_OK; + sshc->authed = TRUE; + infof(data, "Completed public key authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + + MOVE_TO_SECONDARY_AUTH; + } + break; + case SSH_AUTH_PKEY: + rc = ssh_userauth_publickey(sshc->ssh_session, NULL, sshc->privkey); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed public key authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + else { + infof(data, "Failed public key authentication (rc: %d)\n", rc); + MOVE_TO_SECONDARY_AUTH; + } + break; + + case SSH_AUTH_GSSAPI: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { + MOVE_TO_TERTIARY_AUTH; + } + + rc = ssh_userauth_gssapi(sshc->ssh_session); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + rc = SSH_OK; + sshc->authed = TRUE; + infof(data, "Completed gssapi authentication\n"); + state(conn, SSH_AUTH_DONE); + break; + } + + MOVE_TO_TERTIARY_AUTH; + break; + + case SSH_AUTH_KEY_INIT: + if(data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) { + state(conn, SSH_AUTH_KEY); + } + else { + MOVE_TO_LAST_AUTH; + } + break; + + case SSH_AUTH_KEY: + + /* Authentication failed. Continue with keyboard-interactive now. */ + rc = myssh_auth_interactive(conn); + if(rc == SSH_AGAIN) { + break; + } + if(rc == SSH_OK) { + sshc->authed = TRUE; + infof(data, "completed keyboard interactive authentication\n"); + } + state(conn, SSH_AUTH_DONE); + break; + + case SSH_AUTH_PASS_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { + /* Host key authentication is intentionally not implemented */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + state(conn, SSH_AUTH_PASS); + /* fall through */ + + case SSH_AUTH_PASS: + rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd); + if(rc == SSH_AUTH_AGAIN) { + rc = SSH_AGAIN; + break; + } + + if(rc == SSH_AUTH_SUCCESS) { + sshc->authed = TRUE; + infof(data, "Completed password authentication\n"); + state(conn, SSH_AUTH_DONE); + } + else { + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + break; + + case SSH_AUTH_DONE: + if(!sshc->authed) { + failf(data, "Authentication failure"); + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; + } + + /* + * At this point we have an authenticated ssh session. + */ + infof(data, "Authentication complete\n"); + + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + + conn->sockfd = ssh_get_fd(sshc->ssh_session); + conn->writesockfd = CURL_SOCKET_BAD; + + if(conn->handler->protocol == CURLPROTO_SFTP) { + state(conn, SSH_SFTP_INIT); + break; + } + infof(data, "SSH CONNECT phase done\n"); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_INIT: + ssh_set_blocking(sshc->ssh_session, 1); + + sshc->sftp_session = sftp_new(sshc->ssh_session); + if(!sshc->sftp_session) { + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; + } + + rc = sftp_init(sshc->sftp_session); + if(rc != SSH_OK) { + rc = sftp_get_error(sshc->sftp_session); + failf(data, "Failure initializing sftp session: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc)); + break; + } + state(conn, SSH_SFTP_REALPATH); + /* fall through */ + case SSH_SFTP_REALPATH: + /* + * Get the "home" directory + */ + sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); + if(sshc->homedir == NULL) { + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + } + conn->data->state.most_recent_ftp_entrypath = sshc->homedir; + + /* This is the last step in the SFTP connect phase. Do note that while + we get the homedir here, we get the "workingpath" in the DO action + since the homedir will remain the same between request but the + working path will not. */ + DEBUGF(infof(data, "SSH CONNECT phase done\n")); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_QUOTE_INIT: + + result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + if(data->set.quote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.quote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_SFTP_GETINFO); + } + break; + + case SSH_SFTP_POSTQUOTE_INIT: + if(data->set.postquote) { + infof(data, "Sending quote commands\n"); + sshc->quote_item = data->set.postquote; + state(conn, SSH_SFTP_QUOTE); + } + else { + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_QUOTE: + /* Send any quote commands */ + sftp_quote(conn); + break; + + case SSH_SFTP_NEXT_QUOTE: + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + sshc->quote_item = sshc->quote_item->next; + + if(sshc->quote_item) { + state(conn, SSH_SFTP_QUOTE); + } + else { + if(sshc->nextstate != SSH_NO_STATE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_NO_STATE; + } + else { + state(conn, SSH_SFTP_GETINFO); + } + } + break; + + case SSH_SFTP_QUOTE_STAT: + sftp_quote_stat(conn); + break; + + case SSH_SFTP_QUOTE_SETSTAT: + rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, + sshc->quote_attrs); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to set SFTP stats failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + /* sshc->actualcode = sftp_error_to_CURLE(err); + * we do not send the actual error; we return + * the error the libssh2 backend is returning */ + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_SYMLINK: + rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, + sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "symlink command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_MKDIR: + rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, + (mode_t)data->set.new_directory_perms); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "mkdir command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RENAME: + rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, + sshc->quote_path2); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "rename command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_RMDIR: + rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "rmdir command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_UNLINK: + rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); + if(rc != 0 && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "rm command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + + case SSH_SFTP_QUOTE_STATVFS: + { + sftp_statvfs_t statvfs; + + statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1); + if(!statvfs && !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + failf(data, "statvfs command failed: %s", + ssh_get_error(sshc->ssh_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + break; + } + else if(statvfs) { + char *tmp = aprintf("statvfs:\n" + "f_bsize: %llu\n" "f_frsize: %llu\n" + "f_blocks: %llu\n" "f_bfree: %llu\n" + "f_bavail: %llu\n" "f_files: %llu\n" + "f_ffree: %llu\n" "f_favail: %llu\n" + "f_fsid: %llu\n" "f_flag: %llu\n" + "f_namemax: %llu\n", + statvfs->f_bsize, statvfs->f_frsize, + statvfs->f_blocks, statvfs->f_bfree, + statvfs->f_bavail, statvfs->f_files, + statvfs->f_ffree, statvfs->f_favail, + statvfs->f_fsid, statvfs->f_flag, + statvfs->f_namemax); + sftp_statvfs_free(statvfs); + + if(!tmp) { + result = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + break; + } + + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + } + state(conn, SSH_SFTP_NEXT_QUOTE); + break; + } + + case SSH_SFTP_GETINFO: + if(data->set.get_filetime) { + state(conn, SSH_SFTP_FILETIME); + } + else { + state(conn, SSH_SFTP_TRANS_INIT); + } + break; + + case SSH_SFTP_FILETIME: + { + sftp_attributes attrs; + + attrs = sftp_stat(sshc->sftp_session, protop->path); + if(attrs != 0) { + data->info.filetime = attrs->mtime; + sftp_attributes_free(attrs); + } + + state(conn, SSH_SFTP_TRANS_INIT); + break; + } + + case SSH_SFTP_TRANS_INIT: + if(data->set.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(protop->path[strlen(protop->path)-1] == '/') + state(conn, SSH_SFTP_READDIR_INIT); + else + state(conn, SSH_SFTP_DOWNLOAD_INIT); + } + break; + + case SSH_SFTP_UPLOAD_INIT: + { + int flags; + + if(data->state.resume_from != 0) { + sftp_attributes attrs; + + if(data->state.resume_from < 0) { + attrs = sftp_stat(sshc->sftp_session, protop->path); + if(attrs != 0) { + curl_off_t size = attrs->size; + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + } + data->state.resume_from = attrs->size; + + sftp_attributes_free(attrs); + } + else { + data->state.resume_from = 0; + } + } + } + + if(data->set.ftp_append) + /* Try to open for append, but create if nonexisting */ + flags = O_WRONLY|O_CREAT|O_APPEND; + else if(data->state.resume_from > 0) + /* If we have restart position then open for append */ + flags = O_WRONLY|O_APPEND; + else + /* Clear file before writing (normal behaviour) */ + flags = O_WRONLY|O_APPEND|O_CREAT|O_TRUNC; + + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + sshc->sftp_file = + sftp_open(sshc->sftp_session, protop->path, + flags, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + err = sftp_get_error(sshc->sftp_session); + + if(((err == SSH_FX_NO_SUCH_FILE || err == SSH_FX_FAILURE || + err == SSH_FX_NO_SUCH_PATH)) && + (data->set.ftp_create_missing_dirs && + (strlen(protop->path) > 1))) { + /* try to create the path remotely */ + rc = 0; + sshc->secondCreateDirs = 1; + state(conn, SSH_SFTP_CREATE_DIRS_INIT); + break; + } + else { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + + /* If we have a restart point then we need to seek to the correct + position. */ + if(data->state.resume_from > 0) { + /* Let's read off the proper amount of bytes from the input. */ + if(conn->seek_func) { + Curl_set_in_callback(data, true); + seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, + SEEK_SET); + Curl_set_in_callback(data, false); + } + + if(seekerr != CURL_SEEKFUNC_OK) { + curl_off_t passed = 0; + + if(seekerr != CURL_SEEKFUNC_CANTSEEK) { + failf(data, "Could not seek stream"); + return CURLE_FTP_COULDNT_USE_REST; + } + /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? + (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->state.fread_func(data->state.buffer, 1, + readthisamountnow, data->state.in); + + passed += actuallyread; + if((actuallyread == 0) || (actuallyread > readthisamountnow)) { + /* this checks for greater-than only to make sure that the + CURL_READFUNC_ABORT return code still aborts */ + failf(data, "Failed to read data"); + MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + } + } while(passed < data->state.resume_from); + } + + /* now, decrease the size of the read */ + if(data->state.infilesize > 0) { + data->state.infilesize -= data->state.resume_from; + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + + rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + if(data->state.infilesize > 0) { + data->req.size = data->state.infilesize; + Curl_pgrsSetUploadSize(data, data->state.infilesize); + } + /* upload data */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh sftp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + /* since we don't really wait for anything at this point, we want the + state machine to move on as soon as possible so we set a very short + timeout here */ + Curl_expire(data, 0, EXPIRE_RUN_NOW); + + state(conn, SSH_STOP); + break; + } + + case SSH_SFTP_CREATE_DIRS_INIT: + if(strlen(protop->path) > 1) { + sshc->slash_pos = protop->path + 1; /* ignore the leading '/' */ + state(conn, SSH_SFTP_CREATE_DIRS); + } + else { + state(conn, SSH_SFTP_UPLOAD_INIT); + } + break; + + case SSH_SFTP_CREATE_DIRS: + sshc->slash_pos = strchr(sshc->slash_pos, '/'); + if(sshc->slash_pos) { + *sshc->slash_pos = 0; + + infof(data, "Creating directory '%s'\n", protop->path); + state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); + break; + } + state(conn, SSH_SFTP_UPLOAD_INIT); + break; + + case SSH_SFTP_CREATE_DIRS_MKDIR: + /* 'mode' - parameter is preliminary - default to 0644 */ + rc = sftp_mkdir(sshc->sftp_session, protop->path, + (mode_t)data->set.new_directory_perms); + *sshc->slash_pos = '/'; + ++sshc->slash_pos; + if(rc < 0) { + /* + * Abort if failure wasn't that the dir already exists or the + * permission was denied (creation might succeed further down the + * path) - retry on unspecific FAILURE also + */ + err = sftp_get_error(sshc->sftp_session); + if((err != SSH_FX_FILE_ALREADY_EXISTS) && + (err != SSH_FX_FAILURE) && + (err != SSH_FX_PERMISSION_DENIED)) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + rc = 0; /* clear rc and continue */ + } + state(conn, SSH_SFTP_CREATE_DIRS); + break; + + case SSH_SFTP_READDIR_INIT: + Curl_pgrsSetDownloadSize(data, -1); + if(data->set.opt_no_body) { + state(conn, SSH_STOP); + break; + } + + /* + * This is a directory that we are trying to get, so produce a directory + * listing + */ + sshc->sftp_dir = sftp_opendir(sshc->sftp_session, + protop->path); + if(!sshc->sftp_dir) { + failf(data, "Could not open directory for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + } + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR: + + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + sshc->readdir_attrs = sftp_readdir(sshc->sftp_session, sshc->sftp_dir); + if(sshc->readdir_attrs) { + sshc->readdir_filename = sshc->readdir_attrs->name; + sshc->readdir_longentry = sshc->readdir_attrs->longname; + sshc->readdir_len = (int)strlen(sshc->readdir_filename); + + if(data->set.ftp_list_only) { + char *tmpLine; + + tmpLine = aprintf("%s\n", sshc->readdir_filename); + if(tmpLine == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + result = Curl_client_write(conn, CLIENTWRITE_BODY, + tmpLine, sshc->readdir_len + 1); + free(tmpLine); + + if(result) { + state(conn, SSH_STOP); + break; + } + /* since this counts what we send to the client, we include the + newline in this counter */ + data->req.bytecount += sshc->readdir_len + 1; + + /* output debug output if that is requested */ + if(data->set.verbose) { + Curl_debug(data, CURLINFO_DATA_OUT, + (char *)sshc->readdir_filename, + sshc->readdir_len, conn); + } + } + else { + sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry); + sshc->readdir_totalLen = 80 + sshc->readdir_currLen; + sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); + if(!sshc->readdir_line) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + memcpy(sshc->readdir_line, sshc->readdir_longentry, + sshc->readdir_currLen); + if((sshc->readdir_attrs->flags & SSH_FILEXFER_ATTR_PERMISSIONS) && + ((sshc->readdir_attrs->permissions & S_IFMT) == + S_IFLNK)) { + sshc->readdir_linkPath = malloc(PATH_MAX + 1); + if(sshc->readdir_linkPath == NULL) { + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + + snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", protop->path, + sshc->readdir_filename); + + state(conn, SSH_SFTP_READDIR_LINK); + break; + } + state(conn, SSH_SFTP_READDIR_BOTTOM); + break; + } + } + else if(sshc->readdir_attrs == NULL && sftp_dir_eof(sshc->sftp_dir)) { + state(conn, SSH_SFTP_READDIR_DONE); + break; + } + else { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + break; + } + break; + + case SSH_SFTP_READDIR_LINK: + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + sshc->readdir_link_attrs = sftp_lstat(sshc->sftp_session, + sshc->readdir_linkPath); + if(sshc->readdir_link_attrs == 0) { + failf(data, "Could not read symlink for reading: %s", + ssh_get_error(sshc->ssh_session)); + MOVE_TO_SFTP_CLOSE_STATE(); + } + + if(sshc->readdir_link_attrs->name == NULL) { + sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, + sshc->readdir_linkPath); + if(sshc->readdir_filename == NULL) + sshc->readdir_len = 0; + else + sshc->readdir_len = (int)strlen(sshc->readdir_tmp); + sshc->readdir_longentry = NULL; + sshc->readdir_filename = sshc->readdir_tmp; + } + else { + sshc->readdir_len = (int)strlen(sshc->readdir_link_attrs->name); + sshc->readdir_filename = sshc->readdir_link_attrs->name; + sshc->readdir_longentry = sshc->readdir_link_attrs->longname; + } + + Curl_safefree(sshc->readdir_linkPath); + + /* get room for the filename and extra output */ + sshc->readdir_totalLen += 4 + sshc->readdir_len; + new_readdir_line = Curl_saferealloc(sshc->readdir_line, + sshc->readdir_totalLen); + if(!new_readdir_line) { + sshc->readdir_line = NULL; + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = CURLE_OUT_OF_MEMORY; + break; + } + sshc->readdir_line = new_readdir_line; + + sshc->readdir_currLen += snprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, + " -> %s", + sshc->readdir_filename); + + sftp_attributes_free(sshc->readdir_link_attrs); + sshc->readdir_link_attrs = NULL; + sshc->readdir_filename = NULL; + sshc->readdir_longentry = NULL; + + state(conn, SSH_SFTP_READDIR_BOTTOM); + /* fall through */ + case SSH_SFTP_READDIR_BOTTOM: + sshc->readdir_currLen += snprintf(sshc->readdir_line + + sshc->readdir_currLen, + sshc->readdir_totalLen - + sshc->readdir_currLen, "\n"); + result = Curl_client_write(conn, CLIENTWRITE_BODY, + sshc->readdir_line, + sshc->readdir_currLen); + + if(!result) { + + /* output debug output if that is requested */ + if(data->set.verbose) { + Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line, + sshc->readdir_currLen, conn); + } + data->req.bytecount += sshc->readdir_currLen; + } + Curl_safefree(sshc->readdir_line); + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + + if(result) { + state(conn, SSH_STOP); + } + else + state(conn, SSH_SFTP_READDIR); + break; + + case SSH_SFTP_READDIR_DONE: + sftp_closedir(sshc->sftp_dir); + sshc->sftp_dir = NULL; + + /* no data to transfer */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + state(conn, SSH_STOP); + break; + + case SSH_SFTP_DOWNLOAD_INIT: + /* + * Work on getting the specified file + */ + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); + + sshc->sftp_file = sftp_open(sshc->sftp_session, protop->path, + O_RDONLY, (mode_t)data->set.new_file_perms); + if(!sshc->sftp_file) { + failf(data, "Could not open remote file for reading: %s", + ssh_get_error(sshc->ssh_session)); + + MOVE_TO_SFTP_CLOSE_STATE(); + } + + state(conn, SSH_SFTP_DOWNLOAD_STAT); + break; + + case SSH_SFTP_DOWNLOAD_STAT: + { + sftp_attributes attrs; + curl_off_t size; + + attrs = sftp_fstat(sshc->sftp_file); + if(!attrs || + !(attrs->flags & SSH_FILEXFER_ATTR_SIZE) || + (attrs->size == 0)) { + /* + * sftp_fstat didn't return an error, so maybe the server + * just doesn't support stat() + * OR the server doesn't return a file size with a stat() + * OR file size is 0 + */ + data->req.size = -1; + data->req.maxdownload = -1; + Curl_pgrsSetDownloadSize(data, -1); + size = 0; + } + else { + size = attrs->size; + + sftp_attributes_free(attrs); + + if(size < 0) { + failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(conn->data->state.use_range) { + curl_off_t from, to; + char *ptr; + char *ptr2; + CURLofft to_t; + CURLofft from_t; + + from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) { + return CURLE_RANGE_ERROR; + } + while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + ptr++; + to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); + if(to_t == CURL_OFFT_FLOW) { + return CURLE_RANGE_ERROR; + } + if((to_t == CURL_OFFT_INVAL) /* no "to" value given */ + || (to >= size)) { + to = size - 1; + } + if(from_t) { + /* from is relative to end of file */ + from = size - to; + to = size - 1; + } + if(from > size) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + if(from > to) { + from = to; + size = 0; + } + else { + size = to - from + 1; + } + + rc = sftp_seek64(sshc->sftp_file, from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + data->req.size = size; + data->req.maxdownload = size; + Curl_pgrsSetDownloadSize(data, size); + } + + /* We can resume if we can seek to the resume position */ + if(data->state.resume_from) { + if(data->state.resume_from < 0) { + /* We're supposed to download the last abs(from) bytes */ + if((curl_off_t)size < -data->state.resume_from) { + failf(data, "Offset (%" + CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" + CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + /* download from where? */ + data->state.resume_from += size; + } + else { + if((curl_off_t)size < data->state.resume_from) { + failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T + ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", + data->state.resume_from, size); + return CURLE_BAD_DOWNLOAD_RESUME; + } + } + /* Does a completed file need to be seeked and started or closed ? */ + /* Now store the number of bytes we are expected to download */ + data->req.size = size - data->state.resume_from; + data->req.maxdownload = size - data->state.resume_from; + Curl_pgrsSetDownloadSize(data, + size - data->state.resume_from); + + rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); + if(rc != 0) { + MOVE_TO_SFTP_CLOSE_STATE(); + } + } + } + + /* Setup the actual download */ + if(data->req.size == 0) { + /* no data to transfer */ + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); + infof(data, "File already completely downloaded\n"); + state(conn, SSH_STOP); + break; + } + Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size, + FALSE, NULL, -1, NULL); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + if(result) { + /* this should never occur; the close state should be entered + at the time the error occurs */ + state(conn, SSH_SFTP_CLOSE); + sshc->actualcode = result; + } + else { + sshc->sftp_recv_state = 0; + state(conn, SSH_STOP); + } + break; + + case SSH_SFTP_CLOSE: + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + Curl_safefree(protop->path); + + DEBUGF(infof(data, "SFTP DONE done\n")); + + /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT + After nextstate is executed, the control should come back to + SSH_SFTP_CLOSE to pass the correct result back */ + if(sshc->nextstate != SSH_NO_STATE && + sshc->nextstate != SSH_SFTP_CLOSE) { + state(conn, sshc->nextstate); + sshc->nextstate = SSH_SFTP_CLOSE; + } + else { + state(conn, SSH_STOP); + result = sshc->actualcode; + } + break; + + case SSH_SFTP_SHUTDOWN: + /* during times we get here due to a broken transfer and then the + sftp_handle might not have been taken down so make sure that is done + before we proceed */ + + if(sshc->sftp_file) { + sftp_close(sshc->sftp_file); + sshc->sftp_file = NULL; + } + + if(sshc->sftp_session) { + sftp_free(sshc->sftp_session); + sshc->sftp_session = NULL; + } + + Curl_safefree(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_DISCONNECT); + break; + + + case SSH_SCP_TRANS_INIT: + result = Curl_getworkingpath(conn, sshc->homedir, &protop->path); + if(result) { + sshc->actualcode = result; + state(conn, SSH_STOP); + break; + } + + /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ + ssh_set_blocking(sshc->ssh_session, 1); + + if(data->set.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + sshc->scp_session = + ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, protop->path); + state(conn, SSH_SCP_UPLOAD_INIT); + } + else { + sshc->scp_session = + ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, protop->path); + state(conn, SSH_SCP_DOWNLOAD_INIT); + } + + if(!sshc->scp_session) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + break; + + case SSH_SCP_UPLOAD_INIT: + + rc = ssh_scp_init(sshc->scp_session); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + rc = ssh_scp_push_file(sshc->scp_session, protop->path, + data->state.infilesize, + (int)data->set.new_file_perms); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + } + + /* upload data */ + Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL, + FIRSTSOCKET, NULL); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->sockfd = conn->writesockfd; + + /* store this original bitmask setup to use later on if we can't + figure out a "real" bitmask */ + sshc->orig_waitfor = data->req.keepon; + + /* we want to use the _sending_ function even when the socket turns + out readable as the underlying libssh scp send function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_OUT; + + state(conn, SSH_STOP); + + break; + + case SSH_SCP_DOWNLOAD_INIT: + + rc = ssh_scp_init(sshc->scp_session); + if(rc != SSH_OK) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + } + state(conn, SSH_SCP_DOWNLOAD); + /* fall through */ + + case SSH_SCP_DOWNLOAD:{ + curl_off_t bytecount; + + rc = ssh_scp_pull_request(sshc->scp_session); + if(rc != SSH_SCP_REQUEST_NEWFILE) { + err_msg = ssh_get_error(sshc->ssh_session); + failf(conn->data, "%s", err_msg); + MOVE_TO_ERROR_STATE(CURLE_REMOTE_FILE_NOT_FOUND); + break; + } + + /* download data */ + bytecount = ssh_scp_request_get_size(sshc->scp_session); + data->req.maxdownload = (curl_off_t) bytecount; + Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, + NULL); + + /* not set by Curl_setup_transfer to preserve keepon bits */ + conn->writesockfd = conn->sockfd; + + /* we want to use the _receiving_ function even when the socket turns + out writableable as the underlying libssh recv function will deal + with both accordingly */ + conn->cselect_bits = CURL_CSELECT_IN; + + state(conn, SSH_STOP); + break; + } + case SSH_SCP_DONE: + if(data->set.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_SEND_EOF: + if(sshc->scp_session) { + rc = ssh_scp_close(sshc->scp_session); + if(rc == SSH_AGAIN) { + /* Currently the ssh_scp_close handles waiting for EOF in + * blocking way. + */ + break; + } + if(rc != SSH_OK) { + infof(data, "Failed to close libssh scp channel: %s\n", + ssh_get_error(sshc->ssh_session)); + } + } + + state(conn, SSH_SCP_CHANNEL_FREE); + break; + + case SSH_SCP_CHANNEL_FREE: + if(sshc->scp_session) { + ssh_scp_free(sshc->scp_session); + sshc->scp_session = NULL; + } + DEBUGF(infof(data, "SCP DONE phase complete\n")); + + ssh_set_blocking(sshc->ssh_session, 0); + + state(conn, SSH_SESSION_DISCONNECT); + /* fall through */ + + case SSH_SESSION_DISCONNECT: + /* during weird times when we've been prematurely aborted, the channel + is still alive when we reach this state and we MUST kill the channel + properly first */ + if(sshc->scp_session) { + ssh_scp_free(sshc->scp_session); + sshc->scp_session = NULL; + } + + ssh_disconnect(sshc->ssh_session); + + Curl_safefree(sshc->homedir); + conn->data->state.most_recent_ftp_entrypath = NULL; + + state(conn, SSH_SESSION_FREE); + /* fall through */ + case SSH_SESSION_FREE: + if(sshc->ssh_session) { + ssh_free(sshc->ssh_session); + sshc->ssh_session = NULL; + } + + /* worst-case scenario cleanup */ + + DEBUGASSERT(sshc->ssh_session == NULL); + DEBUGASSERT(sshc->scp_session == NULL); + + if(sshc->readdir_tmp) { + ssh_string_free_char(sshc->readdir_tmp); + sshc->readdir_tmp = NULL; + } + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + + if(sshc->readdir_attrs) + sftp_attributes_free(sshc->readdir_attrs); + + if(sshc->readdir_link_attrs) + sftp_attributes_free(sshc->readdir_link_attrs); + + if(sshc->privkey) + ssh_key_free(sshc->privkey); + if(sshc->pubkey) + ssh_key_free(sshc->pubkey); + + Curl_safefree(sshc->rsa_pub); + Curl_safefree(sshc->rsa); + + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + + Curl_safefree(sshc->homedir); + + Curl_safefree(sshc->readdir_line); + Curl_safefree(sshc->readdir_linkPath); + + /* the code we are about to return */ + result = sshc->actualcode; + + memset(sshc, 0, sizeof(struct ssh_conn)); + + connclose(conn, "SSH session free"); + sshc->state = SSH_SESSION_FREE; /* current */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + case SSH_QUIT: + /* fallthrough, just stop! */ + default: + /* internal error */ + sshc->nextstate = SSH_NO_STATE; + state(conn, SSH_STOP); + break; + + } + } while(!rc && (sshc->state != SSH_STOP)); + + + if(rc == SSH_AGAIN) { + /* we would block, we need to wait for the socket to be ready (in the + right direction too)! */ + *block = TRUE; + } + + return result; +} + + +/* called by the multi interface to figure out what socket(s) to wait for and + for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ +static int myssh_perform_getsock(const struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks) +{ + int bitmap = GETSOCK_BLANK; + (void) numsocks; + + sock[0] = conn->sock[FIRSTSOCKET]; + + if(conn->waitfor & KEEP_RECV) + bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); + + if(conn->waitfor & KEEP_SEND) + bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); + + return bitmap; +} + +/* Generic function called by the multi interface to figure out what socket(s) + to wait for and for what actions during the DOING and PROTOCONNECT states*/ +static int myssh_getsock(struct connectdata *conn, + curl_socket_t *sock, /* points to numsocks + number of sockets */ + int numsocks) +{ + /* if we know the direction we can use the generic *_getsock() function even + for the protocol_connect and doing states */ + return myssh_perform_getsock(conn, sock, numsocks); +} + +static void myssh_block2waitfor(struct connectdata *conn, bool block) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + int dir; + + /* If it didn't block, or nothing was returned by ssh_get_poll_flags + * have the original set */ + conn->waitfor = sshc->orig_waitfor; + + if(block) { + dir = ssh_get_poll_flags(sshc->ssh_session); + if(dir & SSH_READ_PENDING) { + /* translate the libssh define bits into our own bit defines */ + conn->waitfor = KEEP_RECV; + } + else if(dir & SSH_WRITE_PENDING) { + conn->waitfor = KEEP_SEND; + } + } +} + +/* called repeatedly until done from multi.c */ +static CURLcode myssh_multi_statemach(struct connectdata *conn, + bool *done) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + bool block; /* we store the status and use that to provide a ssh_getsock() + implementation */ + + result = myssh_statemach_act(conn, &block); + *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; + myssh_block2waitfor(conn, block); + + return result; +} + +static CURLcode myssh_block_statemach(struct connectdata *conn, + bool disconnect) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; + + while((sshc->state != SSH_STOP) && !result) { + bool block; + timediff_t left = 1000; + struct curltime now = Curl_now(); + + result = myssh_statemach_act(conn, &block); + if(result) + break; + + if(!disconnect) { + if(Curl_pgrsUpdate(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + result = Curl_speedcheck(data, now); + if(result) + break; + + left = Curl_timeleft(data, NULL, FALSE); + if(left < 0) { + failf(data, "Operation timed out"); + return CURLE_OPERATION_TIMEDOUT; + } + } + + if(!result && block) { + curl_socket_t sock = conn->sock[FIRSTSOCKET]; + curl_socket_t fd_read = CURL_SOCKET_BAD; + fd_read = sock; + /* wait for the socket to become ready */ + (void) Curl_socket_check(fd_read, CURL_SOCKET_BAD, + CURL_SOCKET_BAD, left > 1000 ? 1000 : left); + } + + } + + return result; +} + +/* + * SSH setup connection + */ +static CURLcode myssh_setup_connection(struct connectdata *conn) +{ + struct SSHPROTO *ssh; + + conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO)); + if(!ssh) + return CURLE_OUT_OF_MEMORY; + + return CURLE_OK; +} + +static Curl_recv scp_recv, sftp_recv; +static Curl_send scp_send, sftp_send; + +/* + * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to + * do protocol-specific actions at connect-time. + */ +static CURLcode myssh_connect(struct connectdata *conn, bool *done) +{ + struct ssh_conn *ssh; + CURLcode result; + struct Curl_easy *data = conn->data; + int rc; + + /* initialize per-handle data if not already */ + if(!data->req.protop) + myssh_setup_connection(conn); + + /* We default to persistent connections. We set this already in this connect + function to make the re-use checks properly be able to check this bit. */ + connkeep(conn, "SSH default"); + + if(conn->handler->protocol & CURLPROTO_SCP) { + conn->recv[FIRSTSOCKET] = scp_recv; + conn->send[FIRSTSOCKET] = scp_send; + } + else { + conn->recv[FIRSTSOCKET] = sftp_recv; + conn->send[FIRSTSOCKET] = sftp_send; + } + + ssh = &conn->proto.sshc; + + ssh->ssh_session = ssh_new(); + if(ssh->ssh_session == NULL) { + failf(data, "Failure initialising ssh session"); + return CURLE_FAILED_INIT; + } + + if(conn->user) { + infof(data, "User: %s\n", conn->user); + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user); + } + + if(data->set.str[STRING_SSH_KNOWNHOSTS]) { + infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]); + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS, + data->set.str[STRING_SSH_KNOWNHOSTS]); + } + + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name); + if(conn->remote_port) + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_PORT, + &conn->remote_port); + + if(data->set.ssh_compression) { + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_COMPRESSION, + "zlib,zlib@openssh.com,none"); + } + + ssh->privkey = NULL; + ssh->pubkey = NULL; + + if(data->set.str[STRING_SSH_PUBLIC_KEY]) { + rc = ssh_pki_import_pubkey_file(data->set.str[STRING_SSH_PUBLIC_KEY], + &ssh->pubkey); + if(rc != SSH_OK) { + failf(data, "Could not load public key file"); + /* ignore */ + } + } + + /* we do not verify here, we do it at the state machine, + * after connection */ + + state(conn, SSH_INIT); + + result = myssh_multi_statemach(conn, done); + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode scp_doing(struct connectdata *conn, bool *dophase_done) +{ + CURLcode result; + + result = myssh_multi_statemach(conn, dophase_done); + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* + *********************************************************************** + * + * scp_perform() + * + * This is the actual DO function for SCP. Get a file according to + * the options previously setup. + */ + +static +CURLcode scp_perform(struct connectdata *conn, + bool *connected, bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SCP_TRANS_INIT); + + result = myssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +static CURLcode myssh_do_it(struct connectdata *conn, bool *done) +{ + CURLcode result; + bool connected = 0; + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + + *done = FALSE; /* default to false */ + + data->req.size = -1; /* make sure this is unknown at this point */ + + sshc->actualcode = CURLE_OK; /* reset error code */ + sshc->secondCreateDirs = 0; /* reset the create dir attempt state + variable */ + + Curl_pgrsSetUploadCounter(data, 0); + Curl_pgrsSetDownloadCounter(data, 0); + Curl_pgrsSetUploadSize(data, -1); + Curl_pgrsSetDownloadSize(data, -1); + + if(conn->handler->protocol & CURLPROTO_SCP) + result = scp_perform(conn, &connected, done); + else + result = sftp_perform(conn, &connected, done); + + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode scp_disconnect(struct connectdata *conn, + bool dead_connection) +{ + CURLcode result = CURLE_OK; + struct ssh_conn *ssh = &conn->proto.sshc; + (void) dead_connection; + + if(ssh->ssh_session) { + /* only if there's a session still around to use! */ + + state(conn, SSH_SESSION_DISCONNECT); + + result = myssh_block_statemach(conn, TRUE); + } + + return result; +} + +/* generic done function for both SCP and SFTP called from their specific + done functions */ +static CURLcode myssh_done(struct connectdata *conn, CURLcode status) +{ + CURLcode result = CURLE_OK; + struct SSHPROTO *protop = conn->data->req.protop; + + if(!status) { + /* run the state-machine + + TODO: when the multi interface is used, this _really_ should be using + the ssh_multi_statemach function but we have no general support for + non-blocking DONE operations! + */ + result = myssh_block_statemach(conn, FALSE); + } + else + result = status; + + if(protop) + Curl_safefree(protop->path); + if(Curl_pgrsDone(conn)) + return CURLE_ABORTED_BY_CALLBACK; + + conn->data->req.keepon = 0; /* clear all bits */ + return result; +} + + +static CURLcode scp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + (void) premature; /* not used */ + + if(!status) + state(conn, SSH_SCP_DONE); + + return myssh_done(conn, status); + +} + +static ssize_t scp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + int rc; + (void) sockindex; /* we only support SCP on the fixed known primary socket */ + (void) err; + + rc = ssh_scp_write(conn->proto.sshc.scp_session, mem, len); + +#if 0 + /* The following code is misleading, mostly added as wishful thinking + * that libssh at some point will implement non-blocking ssh_scp_write/read. + * Currently rc can only be number of bytes read or SSH_ERROR. */ + myssh_block2waitfor(conn, (rc == SSH_AGAIN) ? TRUE : FALSE); + + if(rc == SSH_AGAIN) { + *err = CURLE_AGAIN; + return 0; + } + else +#endif + if(rc != SSH_OK) { + *err = CURLE_SSH; + return -1; + } + + return len; +} + +static ssize_t scp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void) err; + (void) sockindex; /* we only support SCP on the fixed known primary socket */ + + /* libssh returns int */ + nread = ssh_scp_read(conn->proto.sshc.scp_session, mem, len); + +#if 0 + /* The following code is misleading, mostly added as wishful thinking + * that libssh at some point will implement non-blocking ssh_scp_write/read. + * Currently rc can only be SSH_OK or SSH_ERROR. */ + + myssh_block2waitfor(conn, (nread == SSH_AGAIN) ? TRUE : FALSE); + if(nread == SSH_AGAIN) { + *err = CURLE_AGAIN; + nread = -1; + } +#endif + + return nread; +} + +/* + * =============== SFTP =============== + */ + +/* + *********************************************************************** + * + * sftp_perform() + * + * This is the actual DO function for SFTP. Get a file/directory according to + * the options previously setup. + */ + +static +CURLcode sftp_perform(struct connectdata *conn, + bool *connected, + bool *dophase_done) +{ + CURLcode result = CURLE_OK; + + DEBUGF(infof(conn->data, "DO phase starts\n")); + + *dophase_done = FALSE; /* not done yet */ + + /* start the first command in the DO phase */ + state(conn, SSH_SFTP_QUOTE_INIT); + + /* run the state-machine */ + result = myssh_multi_statemach(conn, dophase_done); + + *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + + return result; +} + +/* called from multi.c while DOing */ +static CURLcode sftp_doing(struct connectdata *conn, + bool *dophase_done) +{ + CURLcode result = myssh_multi_statemach(conn, dophase_done); + if(*dophase_done) { + DEBUGF(infof(conn->data, "DO phase is complete\n")); + } + return result; +} + +/* BLOCKING, but the function is using the state machine so the only reason + this is still blocking is that the multi interface code has no support for + disconnecting operations that takes a while */ +static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) +{ + CURLcode result = CURLE_OK; + (void) dead_connection; + + DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); + + if(conn->proto.sshc.ssh_session) { + /* only if there's a session still around to use! */ + state(conn, SSH_SFTP_SHUTDOWN); + result = myssh_block_statemach(conn, TRUE); + } + + DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); + + return result; + +} + +static CURLcode sftp_done(struct connectdata *conn, CURLcode status, + bool premature) +{ + struct ssh_conn *sshc = &conn->proto.sshc; + + if(!status) { + /* Post quote commands are executed after the SFTP_CLOSE state to avoid + errors that could happen due to open file handles during POSTQUOTE + operation */ + if(!status && !premature && conn->data->set.postquote) { + sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; + state(conn, SSH_SFTP_CLOSE); + } + else + state(conn, SSH_SFTP_CLOSE); + } + return myssh_done(conn, status); +} + +/* return number of sent bytes */ +static ssize_t sftp_send(struct connectdata *conn, int sockindex, + const void *mem, size_t len, CURLcode *err) +{ + ssize_t nwrite; + (void)sockindex; + + nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len); + + myssh_block2waitfor(conn, FALSE); + +#if 0 /* not returned by libssh on write */ + if(nwrite == SSH_AGAIN) { + *err = CURLE_AGAIN; + nwrite = 0; + } + else +#endif + if(nwrite < 0) { + *err = CURLE_SSH; + nwrite = -1; + } + + return nwrite; +} + +/* + * Return number of received (decrypted) bytes + * or <0 on error + */ +static ssize_t sftp_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) +{ + ssize_t nread; + (void)sockindex; + + DEBUGASSERT(len < CURL_MAX_READ_SIZE); + + switch(conn->proto.sshc.sftp_recv_state) { + case 0: + conn->proto.sshc.sftp_file_index = + sftp_async_read_begin(conn->proto.sshc.sftp_file, + (uint32_t)len); + if(conn->proto.sshc.sftp_file_index < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + + /* fall-through */ + case 1: + conn->proto.sshc.sftp_recv_state = 1; + + nread = sftp_async_read(conn->proto.sshc.sftp_file, + mem, (uint32_t)len, + conn->proto.sshc.sftp_file_index); + + myssh_block2waitfor(conn, (nread == SSH_AGAIN)?TRUE:FALSE); + + if(nread == SSH_AGAIN) { + *err = CURLE_AGAIN; + return -1; + } + else if(nread < 0) { + *err = CURLE_RECV_ERROR; + return -1; + } + + conn->proto.sshc.sftp_recv_state = 0; + return nread; + + default: + /* we never reach here */ + return -1; + } +} + +static void sftp_quote(struct connectdata *conn) +{ + const char *cp; + struct Curl_easy *data = conn->data; + struct SSHPROTO *protop = data->req.protop; + struct ssh_conn *sshc = &conn->proto.sshc; + CURLcode result; + + /* + * Support some of the "FTP" commands + */ + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + if(strcasecompare("pwd", cmd)) { + /* output debug output if that is requested */ + char *tmp = aprintf("257 \"%s\" is current directory.\n", + protop->path); + if(!tmp) { + sshc->actualcode = CURLE_OUT_OF_MEMORY; + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + return; + } + if(data->set.verbose) { + Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4, conn); + Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn); + } + /* this sends an FTP-like "header" to the header callback so that the + current directory can be read very similar to how it is read when + using ordinary FTP. */ + result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + free(tmp); + if(result) { + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + } + else + state(conn, SSH_SFTP_NEXT_QUOTE); + return; + } + + /* + * the arguments following the command must be separated from the + * command with a space so we can check for it unconditionally + */ + cp = strchr(cmd, ' '); + if(cp == NULL) { + failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + + /* + * also, every command takes at least one argument so we get that + * first argument right now + */ + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error: Bad first parameter"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + + /* + * SFTP is a binary protocol, so we don't send text commands + * to the server. Instead, we scan for commands used by + * OpenSSH's sftp program and call the appropriate libssh + * functions. + */ + if(strncasecompare(cmd, "chgrp ", 6) || + strncasecompare(cmd, "chmod ", 6) || + strncasecompare(cmd, "chown ", 6)) { + /* attribute change */ + + /* sshc->quote_path1 contains the mode to set */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in chgrp/chmod/chown: " + "Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + sshc->quote_attrs = NULL; + state(conn, SSH_SFTP_QUOTE_STAT); + return; + } + if(strncasecompare(cmd, "ln ", 3) || + strncasecompare(cmd, "symlink ", 8)) { + /* symbolic linking */ + /* sshc->quote_path1 is the source */ + /* get the destination */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in ln/symlink: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + state(conn, SSH_SFTP_QUOTE_SYMLINK); + return; + } + else if(strncasecompare(cmd, "mkdir ", 6)) { + /* create dir */ + state(conn, SSH_SFTP_QUOTE_MKDIR); + return; + } + else if(strncasecompare(cmd, "rename ", 7)) { + /* rename file */ + /* first param is the source path */ + /* second param is the dest. path */ + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); + if(result) { + if(result == CURLE_OUT_OF_MEMORY) + failf(data, "Out of memory"); + else + failf(data, "Syntax error in rename: Bad second parameter"); + Curl_safefree(sshc->quote_path1); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = result; + return; + } + state(conn, SSH_SFTP_QUOTE_RENAME); + return; + } + else if(strncasecompare(cmd, "rmdir ", 6)) { + /* delete dir */ + state(conn, SSH_SFTP_QUOTE_RMDIR); + return; + } + else if(strncasecompare(cmd, "rm ", 3)) { + state(conn, SSH_SFTP_QUOTE_UNLINK); + return; + } +#ifdef HAS_STATVFS_SUPPORT + else if(strncasecompare(cmd, "statvfs ", 8)) { + state(conn, SSH_SFTP_QUOTE_STATVFS); + return; + } +#endif + + failf(data, "Unknown SFTP command"); + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; +} + +static void sftp_quote_stat(struct connectdata *conn) +{ + struct Curl_easy *data = conn->data; + struct ssh_conn *sshc = &conn->proto.sshc; + char *cmd = sshc->quote_item->data; + sshc->acceptfail = FALSE; + + /* if a command starts with an asterisk, which a legal SFTP command never + can, the command will be allowed to fail without it causing any + aborts or cancels etc. It will cause libcurl to act as if the command + is successful, whatever the server reponds. */ + + if(cmd[0] == '*') { + cmd++; + sshc->acceptfail = TRUE; + } + + /* We read the file attributes, store them in sshc->quote_attrs + * and modify them accordingly to command. Then we switch to + * QUOTE_SETSTAT state to write new ones. + */ + + if(sshc->quote_attrs) + sftp_attributes_free(sshc->quote_attrs); + sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); + if(sshc->quote_attrs == NULL) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Attempt to get SFTP stats failed: %d", + sftp_get_error(sshc->sftp_session)); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + + /* Now set the new attributes... */ + if(strncasecompare(cmd, "chgrp", 5)) { + sshc->quote_attrs->gid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); + if(sshc->quote_attrs->gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chgrp gid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + else if(strncasecompare(cmd, "chmod", 5)) { + mode_t perms; + perms = (mode_t)strtoul(sshc->quote_path1, NULL, 8); + /* permissions are octal */ + if(perms == 0 && !ISDIGIT(sshc->quote_path1[0])) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chmod permissions not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->permissions = perms; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_PERMISSIONS; + } + else if(strncasecompare(cmd, "chown", 5)) { + sshc->quote_attrs->uid = (uint32_t)strtoul(sshc->quote_path1, NULL, 10); + if(sshc->quote_attrs->uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + !sshc->acceptfail) { + Curl_safefree(sshc->quote_path1); + Curl_safefree(sshc->quote_path2); + failf(data, "Syntax error: chown uid not a number"); + state(conn, SSH_SFTP_CLOSE); + sshc->nextstate = SSH_NO_STATE; + sshc->actualcode = CURLE_QUOTE_ERROR; + return; + } + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; + } + + /* Now send the completed structure... */ + state(conn, SSH_SFTP_QUOTE_SETSTAT); + return; +} + + +#endif /* USE_LIBSSH */ diff --git a/libs/libcurl/src/ssh.c b/libs/libcurl/src/ssh.c index 2496e7cff3..bf7bd54f90 100644 --- a/libs/libcurl/src/ssh.c +++ b/libs/libcurl/src/ssh.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,9 +26,7 @@ #ifdef USE_LIBSSH2 -#ifdef HAVE_LIMITS_H -# include <limits.h> -#endif +#include <limits.h> #include <libssh2.h> #include <libssh2_sftp.h> @@ -87,21 +85,9 @@ /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" +#include "curl_path.h" #include "memdebug.h" -#ifdef WIN32 -# undef PATH_MAX -# define PATH_MAX MAX_PATH -# ifndef R_OK -# define R_OK 4 -# endif -#endif - -#ifndef PATH_MAX -#define PATH_MAX 1024 /* just an extra precaution since there are systems that - have their definition hidden well */ -#endif - #if LIBSSH2_VERSION_NUM >= 0x010206 /* libssh2_sftp_statvfs and friends were added in 1.2.6 */ #define HAS_STATVFS_SUPPORT 1 @@ -120,16 +106,10 @@ static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); static LIBSSH2_FREE_FUNC(my_libssh2_free); -static CURLcode get_pathname(const char **cpp, char **path); - static CURLcode ssh_connect(struct connectdata *conn, bool *done); static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done); static CURLcode ssh_do(struct connectdata *conn, bool *done); -static CURLcode ssh_getworkingpath(struct connectdata *conn, - char *homedir, /* when SFTP is used */ - char **path); - static CURLcode scp_done(struct connectdata *conn, CURLcode, bool premature); static CURLcode scp_doing(struct connectdata *conn, @@ -279,6 +259,11 @@ static CURLcode libssh2_session_error_to_CURLE(int err) case LIBSSH2_ERROR_NONE: return CURLE_OK; + /* This is the error returned by libssh2_scp_recv2 + * on unknown file */ + case LIBSSH2_ERROR_SCP_PROTOCOL: + return CURLE_REMOTE_FILE_NOT_FOUND; + case LIBSSH2_ERROR_SOCKET_NONE: return CURLE_COULDNT_CONNECT; @@ -357,6 +342,7 @@ static void state(struct connectdata *conn, sshstate nowstate) "SSH_AUTH_HOST", "SSH_AUTH_KEY_INIT", "SSH_AUTH_KEY", + "SSH_AUTH_GSSAPI", "SSH_AUTH_DONE", "SSH_SFTP_INIT", "SSH_SFTP_REALPATH", @@ -391,6 +377,7 @@ static void state(struct connectdata *conn, sshstate nowstate) "SSH_SCP_TRANS_INIT", "SSH_SCP_UPLOAD_INIT", "SSH_SCP_DOWNLOAD_INIT", + "SSH_SCP_DOWNLOAD", "SSH_SCP_DONE", "SSH_SCP_SEND_EOF", "SSH_SCP_WAIT_EOF", @@ -401,6 +388,9 @@ static void state(struct connectdata *conn, sshstate nowstate) "QUIT" }; + /* a precaution to make sure the lists are in sync */ + DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); + if(sshc->state != nowstate) { infof(conn->data, "SFTP %p state change from %s to %s\n", (void *)sshc, names[sshc->state], names[nowstate]); @@ -410,70 +400,6 @@ static void state(struct connectdata *conn, sshstate nowstate) sshc->state = nowstate; } -/* figure out the path to work with in this particular request */ -static CURLcode ssh_getworkingpath(struct connectdata *conn, - char *homedir, /* when SFTP is used */ - char **path) /* returns the allocated - real path to work with */ -{ - struct Curl_easy *data = conn->data; - char *real_path = NULL; - char *working_path; - size_t working_path_len; - CURLcode result = - Curl_urldecode(data, data->state.path, 0, &working_path, - &working_path_len, FALSE); - if(result) - return result; - - /* Check for /~/, indicating relative to the user's home directory */ - if(conn->handler->protocol & CURLPROTO_SCP) { - real_path = malloc(working_path_len + 1); - if(real_path == NULL) { - free(working_path); - return CURLE_OUT_OF_MEMORY; - } - if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) - /* It is referenced to the home directory, so strip the leading '/~/' */ - memcpy(real_path, working_path + 3, 4 + working_path_len-3); - else - memcpy(real_path, working_path, 1 + working_path_len); - } - else if(conn->handler->protocol & CURLPROTO_SFTP) { - if((working_path_len > 1) && (working_path[1] == '~')) { - size_t homelen = strlen(homedir); - real_path = malloc(homelen + working_path_len + 1); - if(real_path == NULL) { - free(working_path); - return CURLE_OUT_OF_MEMORY; - } - /* It is referenced to the home directory, so strip the - leading '/' */ - memcpy(real_path, homedir, homelen); - real_path[homelen] = '/'; - real_path[homelen + 1] = '\0'; - if(working_path_len > 3) { - memcpy(real_path + homelen + 1, working_path + 3, - 1 + working_path_len -3); - } - } - else { - real_path = malloc(working_path_len + 1); - if(real_path == NULL) { - free(working_path); - return CURLE_OUT_OF_MEMORY; - } - memcpy(real_path, working_path, 1 + working_path_len); - } - } - - free(working_path); - - /* store the pointer for the caller to receive */ - *path = real_path; - - return CURLE_OK; -} #ifdef HAVE_LIBSSH2_KNOWNHOST_API static int sshkeycallback(struct Curl_easy *easy, @@ -602,9 +528,11 @@ static CURLcode ssh_knownhost(struct connectdata *conn) keymatch = (enum curl_khmatch)keycheck; /* Ask the callback how to behave */ + Curl_set_in_callback(data, true); rc = func(data, knownkeyp, /* from the knownhosts file */ &foundkey, /* from the remote host */ keymatch, data->set.ssh_keyfunc_userp); + Curl_set_in_callback(data, false); } else /* no remotekey means failure! */ @@ -856,8 +784,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * This is done by simply passing sshc->rsa_pub = NULL. */ if(data->set.str[STRING_SSH_PUBLIC_KEY] - /* treat empty string the same way as NULL */ - && data->set.str[STRING_SSH_PUBLIC_KEY][0]) { + /* treat empty string the same way as NULL */ + && data->set.str[STRING_SSH_PUBLIC_KEY][0]) { sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]); if(!sshc->rsa_pub) out_of_memory = TRUE; @@ -911,7 +839,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) state(conn, SSH_AUTH_DONE); } else { - char *err_msg; + char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); infof(data, "SSH public key authentication failed: %s\n", err_msg); @@ -1034,11 +962,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->sshagent_identity); if(rc < 0) { - if(rc != LIBSSH2_ERROR_EAGAIN) + if(rc != LIBSSH2_ERROR_EAGAIN) { /* tried and failed? go to next identity */ sshc->sshagent_prev_identity = sshc->sshagent_identity; - else - break; + } + break; } } @@ -1118,7 +1046,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) */ sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session); if(!sshc->sftp_session) { - char *err_msg; + char *err_msg = NULL; if(libssh2_session_last_errno(sshc->ssh_session) == LIBSSH2_ERROR_EAGAIN) { rc = LIBSSH2_ERROR_EAGAIN; @@ -1184,7 +1112,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) case SSH_SFTP_QUOTE_INIT: - result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); if(result) { sshc->actualcode = result; state(conn, SSH_STOP); @@ -1219,6 +1147,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* * Support some of the "FTP" commands + * + * 'sshc->quote_item' is already verified to be non-NULL before it + * switched to this state. */ char *cmd = sshc->quote_item->data; sshc->acceptfail = FALSE; @@ -1261,7 +1192,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) state(conn, SSH_SFTP_NEXT_QUOTE); break; } - if(cmd) { + { /* * the arguments following the command must be separated from the * command with a space so we can check for it unconditionally @@ -1279,7 +1210,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * also, every command takes at least one argument so we get that * first argument right now */ - result = get_pathname(&cp, &sshc->quote_path1); + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1304,7 +1235,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* sshc->quote_path1 contains the mode to set */ /* get the destination */ - result = get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1322,11 +1253,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(strncasecompare(cmd, "ln ", 3) || - strncasecompare(cmd, "symlink ", 8)) { + strncasecompare(cmd, "symlink ", 8)) { /* symbolic linking */ /* sshc->quote_path1 is the source */ /* get the destination */ - result = get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1351,7 +1282,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* rename file */ /* first param is the source path */ /* second param is the dest. path */ - result = get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1391,9 +1322,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } } - if(!sshc->quote_item) { - state(conn, SSH_SFTP_GETINFO); - } break; case SSH_SFTP_NEXT_QUOTE: @@ -1706,7 +1634,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc == 0) { - data->info.filetime = (long)attrs.mtime; + data->info.filetime = attrs.mtime; } state(conn, SSH_SFTP_TRANS_INIT); @@ -1826,8 +1754,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(data->state.resume_from > 0) { /* Let's read off the proper amount of bytes from the input. */ if(conn->seek_func) { + Curl_set_in_callback(data, true); seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, SEEK_SET); + Curl_set_in_callback(data, false); } if(seekerr != CURL_SEEKFUNC_OK) { @@ -1844,9 +1774,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) (size_t)data->set.buffer_size : curlx_sotouz(data->state.resume_from - passed); - size_t actuallyread = - data->state.fread_func(data->state.buffer, 1, - readthisamountnow, data->state.in); + size_t actuallyread; + Curl_set_in_callback(data, true); + actuallyread = data->state.fread_func(data->state.buffer, 1, + readthisamountnow, + data->state.in); + Curl_set_in_callback(data, false); passed += actuallyread; if((actuallyread == 0) || (actuallyread > readthisamountnow)) { @@ -2210,8 +2143,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc || - !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || - (attrs.filesize == 0)) { + !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || + (attrs.filesize == 0)) { /* * libssh2_sftp_open() didn't return an error, so maybe the server * just doesn't support stat() @@ -2343,7 +2276,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to close libssh2 file\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); } sshc->sftp_handle = NULL; } @@ -2377,7 +2313,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to close libssh2 file\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, + NULL, 0); + infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); } sshc->sftp_handle = NULL; } @@ -2399,7 +2338,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; case SSH_SCP_TRANS_INIT: - result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); if(result) { sshc->actualcode = result; state(conn, SSH_STOP); @@ -2432,7 +2371,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) data->state.infilesize); if(!sshc->ssh_channel) { int ssh_err; - char *err_msg; + char *err_msg = NULL; if(libssh2_session_last_errno(sshc->ssh_session) == LIBSSH2_ERROR_EAGAIN) { @@ -2445,6 +2384,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(conn->data, "%s", err_msg); state(conn, SSH_SCP_CHANNEL_FREE); sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); + /* Map generic errors to upload failed */ + if(sshc->actualcode == CURLE_SSH || + sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND) + sshc->actualcode = CURLE_UPLOAD_FAILED; break; } @@ -2482,9 +2425,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * be set in sb */ - /* - * If support for >2GB files exists, use it. - */ + /* + * If support for >2GB files exists, use it. + */ /* get a fresh new channel from the ssh layer */ #if LIBSSH2_VERSION_NUM < 0x010700 @@ -2501,7 +2444,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(!sshc->ssh_channel) { int ssh_err; - char *err_msg; + char *err_msg = NULL; if(libssh2_session_last_errno(sshc->ssh_session) == LIBSSH2_ERROR_EAGAIN) { @@ -2554,7 +2497,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc) { - infof(data, "Failed to send libssh2 channel EOF\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to send libssh2 channel EOF: %d %s\n", + rc, err_msg); } } state(conn, SSH_SCP_WAIT_EOF); @@ -2567,7 +2514,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc) { - infof(data, "Failed to get channel EOF: %d\n", rc); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg); } } state(conn, SSH_SCP_WAIT_CLOSE); @@ -2580,7 +2530,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc) { - infof(data, "Channel failed to close: %d\n", rc); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Channel failed to close: %d %s\n", rc, err_msg); } } state(conn, SSH_SCP_CHANNEL_FREE); @@ -2593,7 +2546,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to free libssh2 scp subsystem\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + rc, err_msg); } sshc->ssh_channel = NULL; } @@ -2615,7 +2572,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to free libssh2 scp subsystem\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + rc, err_msg); } sshc->ssh_channel = NULL; } @@ -2626,7 +2587,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to disconnect libssh2 session\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect libssh2 session: %d %s\n", + rc, err_msg); } } @@ -2651,7 +2616,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to disconnect from libssh2 agent\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to disconnect from libssh2 agent: %d %s\n", + rc, err_msg); } libssh2_agent_free(sshc->ssh_agent); sshc->ssh_agent = NULL; @@ -2669,7 +2638,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } if(rc < 0) { - infof(data, "Failed to free libssh2 session\n"); + char *err_msg = NULL; + (void)libssh2_session_last_error(sshc->ssh_session, + &err_msg, NULL, 0); + infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg); } sshc->ssh_session = NULL; } @@ -3307,93 +3279,6 @@ static ssize_t sftp_recv(struct connectdata *conn, int sockindex, return nread; } -/* The get_pathname() function is being borrowed from OpenSSH sftp.c - version 4.6p1. */ -/* - * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> - * - * 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" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -static CURLcode -get_pathname(const char **cpp, char **path) -{ - const char *cp = *cpp, *end; - char quot; - unsigned int i, j; - static const char WHITESPACE[] = " \t\r\n"; - - cp += strspn(cp, WHITESPACE); - if(!*cp) { - *cpp = cp; - *path = NULL; - return CURLE_QUOTE_ERROR; - } - - *path = malloc(strlen(cp) + 1); - if(*path == NULL) - return CURLE_OUT_OF_MEMORY; - - /* Check for quoted filenames */ - if(*cp == '\"' || *cp == '\'') { - quot = *cp++; - - /* Search for terminating quote, unescape some chars */ - for(i = j = 0; i <= strlen(cp); i++) { - if(cp[i] == quot) { /* Found quote */ - i++; - (*path)[j] = '\0'; - break; - } - if(cp[i] == '\0') { /* End of string */ - /*error("Unterminated quote");*/ - goto fail; - } - if(cp[i] == '\\') { /* Escaped characters */ - i++; - if(cp[i] != '\'' && cp[i] != '\"' && - cp[i] != '\\') { - /*error("Bad escaped character '\\%c'", - cp[i]);*/ - goto fail; - } - } - (*path)[j++] = cp[i]; - } - - if(j == 0) { - /*error("Empty quotes");*/ - goto fail; - } - *cpp = cp + i + strspn(cp + i, WHITESPACE); - } - else { - /* Read to end of filename */ - end = strpbrk(cp, WHITESPACE); - if(end == NULL) - end = strchr(cp, '\0'); - *cpp = end + strspn(end, WHITESPACE); - - memcpy(*path, cp, end - cp); - (*path)[end - cp] = '\0'; - } - return CURLE_OK; - - fail: - Curl_safefree(*path); - return CURLE_QUOTE_ERROR; -} - - static const char *sftp_libssh2_strerror(int err) { switch(err) { diff --git a/libs/libcurl/src/ssh.h b/libs/libcurl/src/ssh.h index b350dcf3a5..1c13550774 100644 --- a/libs/libcurl/src/ssh.h +++ b/libs/libcurl/src/ssh.h @@ -24,9 +24,12 @@ #include "curl_setup.h" -#ifdef HAVE_LIBSSH2_H +#if defined(HAVE_LIBSSH2_H) #include <libssh2.h> #include <libssh2_sftp.h> +#elif defined(HAVE_LIBSSH_LIBSSH_H) +#include <libssh/libssh.h> +#include <libssh/sftp.h> #endif /* HAVE_LIBSSH2_H */ /**************************************************************************** @@ -51,6 +54,7 @@ typedef enum { SSH_AUTH_HOST, SSH_AUTH_KEY_INIT, SSH_AUTH_KEY, + SSH_AUTH_GSSAPI, SSH_AUTH_DONE, SSH_SFTP_INIT, SSH_SFTP_REALPATH, /* Last state in SSH-CONNECT */ @@ -86,6 +90,7 @@ typedef enum { SSH_SCP_TRANS_INIT, /* First state in SCP-DO */ SSH_SCP_UPLOAD_INIT, SSH_SCP_DOWNLOAD_INIT, + SSH_SCP_DOWNLOAD, SSH_SCP_DONE, SSH_SCP_SEND_EOF, SSH_SCP_WAIT_EOF, @@ -109,7 +114,8 @@ struct SSHPROTO { struct */ struct ssh_conn { const char *authlist; /* List of auth. methods, managed by libssh2 */ -#ifdef USE_LIBSSH2 + + /* common */ const char *passphrase; /* pass-phrase to use */ char *rsa_pub; /* path name */ char *rsa; /* path name */ @@ -120,16 +126,11 @@ struct ssh_conn { struct curl_slist *quote_item; /* for the quote option */ char *quote_path1; /* two generic pointers for the QUOTE stuff */ char *quote_path2; - LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */ + bool acceptfail; /* used by the SFTP_QUOTE (continue if quote command fails) */ char *homedir; /* when doing SFTP we figure out home dir in the connect phase */ - - /* Here's a set of struct members used by the SFTP_READDIR state */ - LIBSSH2_SFTP_ATTRIBUTES readdir_attrs; - char *readdir_filename; - char *readdir_longentry; int readdir_len, readdir_totalLen, readdir_currLen; char *readdir_line; char *readdir_linkPath; @@ -139,11 +140,42 @@ struct ssh_conn { second attempt has been made to change to/create a directory */ char *slash_pos; /* used by the SFTP_CREATE_DIRS state */ + + int orig_waitfor; /* default READ/WRITE bits wait for */ + +#if defined(USE_LIBSSH) +/* our variables */ + unsigned kbd_state; /* 0 or 1 */ + ssh_key privkey; + ssh_key pubkey; + int auth_methods; + ssh_session ssh_session; + ssh_scp scp_session; + sftp_session sftp_session; + sftp_file sftp_file; + sftp_dir sftp_dir; + + unsigned sftp_recv_state; /* 0 or 1 */ + int sftp_file_index; /* for async read */ + sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */ + sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */ + sftp_attributes quote_attrs; /* used by the SFTP_QUOTE state */ + + const char *readdir_filename; /* points within readdir_attrs */ + const char *readdir_longentry; + char *readdir_tmp; +#elif defined(USE_LIBSSH2) + char *readdir_filename; + char *readdir_longentry; + + LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */ + + /* Here's a set of struct members used by the SFTP_READDIR state */ + LIBSSH2_SFTP_ATTRIBUTES readdir_attrs; LIBSSH2_SESSION *ssh_session; /* Secure Shell session */ LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */ LIBSSH2_SFTP *sftp_session; /* SFTP handle */ LIBSSH2_SFTP_HANDLE *sftp_handle; - int orig_waitfor; /* default READ/WRITE bits wait for */ #ifdef HAVE_LIBSSH2_AGENT_API LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */ @@ -156,10 +188,17 @@ struct ssh_conn { #ifdef HAVE_LIBSSH2_KNOWNHOST_API LIBSSH2_KNOWNHOSTS *kh; #endif -#endif /* USE_LIBSSH2 */ +#endif /* USE_LIBSSH */ }; -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH) + +#define CURL_LIBSSH_VERSION ssh_version(0) + +extern const struct Curl_handler Curl_handler_scp; +extern const struct Curl_handler Curl_handler_sftp; + +#elif defined(USE_LIBSSH2) /* Feature detection based on version numbers to better work with non-configure platforms */ @@ -190,6 +229,14 @@ struct ssh_conn { #define HAVE_LIBSSH2_SESSION_HANDSHAKE 1 #endif +#ifdef HAVE_LIBSSH2_VERSION +/* get it run-time if possible */ +#define CURL_LIBSSH2_VERSION libssh2_version(0) +#else +/* use build-time if run-time not possible */ +#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION +#endif + extern const struct Curl_handler Curl_handler_scp; extern const struct Curl_handler Curl_handler_sftp; diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c index 83a96dda19..0295d6c27d 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -312,6 +312,9 @@ curl_easy_strerror(CURLcode error) case CURLE_HTTP2_STREAM: return "Stream error in the HTTP/2 framing layer"; + case CURLE_RECURSIVE_API_CALL: + return "API function called from within callback"; + /* error codes not used by current libcurl */ case CURLE_OBSOLETE20: case CURLE_OBSOLETE24: @@ -380,6 +383,9 @@ curl_multi_strerror(CURLMcode error) case CURLM_ADDED_ALREADY: return "The easy handle is already added to a multi handle"; + case CURLM_RECURSIVE_API_CALL: + return "API function called from within callback"; + case CURLM_LAST: break; } diff --git a/libs/libcurl/src/strtoofft.c b/libs/libcurl/src/strtoofft.c index 363647737f..546a3ff75d 100644 --- a/libs/libcurl/src/strtoofft.c +++ b/libs/libcurl/src/strtoofft.c @@ -220,8 +220,6 @@ CURLofft curlx_strtoofft(const char *str, char **endp, int base, errno = 0; *num = 0; /* clear by default */ - DEBUGASSERT(str); - while(*str && ISSPACE(*str)) str++; if('-' == *str) { diff --git a/libs/libcurl/src/strtoofft.h b/libs/libcurl/src/strtoofft.h index 244411a870..be19cd716b 100644 --- a/libs/libcurl/src/strtoofft.h +++ b/libs/libcurl/src/strtoofft.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -40,14 +40,6 @@ * of 'long' the conversion function to use is strtol(). */ -#if (SIZEOF_CURL_OFF_T == 4) -# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF) -#else - /* assume CURL_SIZEOF_CURL_OFF_T == 8 */ -# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) -#endif -#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) - typedef enum { CURL_OFFT_OK, /* parsed fine */ CURL_OFFT_FLOW, /* over or underflow */ diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c index 48b134ee34..d71c8e067a 100644 --- a/libs/libcurl/src/telnet.c +++ b/libs/libcurl/src/telnet.c @@ -1203,8 +1203,7 @@ CURLcode telrcv(struct connectdata *conn, CURL_SB_ACCUM(tn, c); tn->telrcv_state = CURL_TS_SB; } - else - { + else { CURL_SB_ACCUM(tn, CURL_IAC); CURL_SB_ACCUM(tn, CURL_SE); tn->subpointer -= 2; @@ -1460,7 +1459,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) if(n == 0) /* no bytes */ break; - readfile_read = (DWORD)n; /* fall thru with number of bytes read */ + /* fall through with number of bytes read */ + readfile_read = (DWORD)n; } else { /* read from stdin */ diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c index 20dc600409..b32960f82b 100644 --- a/libs/libcurl/src/tftp.c +++ b/libs/libcurl/src/tftp.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1010,7 +1010,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) state->requested_blksize = blksize; ((struct sockaddr *)&state->local_addr)->sa_family = - (unsigned short)(conn->ip_addr->ai_family); + (CURL_SA_FAMILY_T)(conn->ip_addr->ai_family); tftp_set_timeouts(state); diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c index 66f923a8ee..f4bf83531f 100644 --- a/libs/libcurl/src/timeval.c +++ b/libs/libcurl/src/timeval.c @@ -110,7 +110,7 @@ struct curltime Curl_now(void) usecs /= 1000; cnow.tv_sec = usecs / 1000000; - cnow.tv_usec = usecs % 1000000; + cnow.tv_usec = (int)(usecs % 1000000); return cnow; } @@ -128,7 +128,7 @@ struct curltime Curl_now(void) struct curltime ret; (void)gettimeofday(&now, NULL); ret.tv_sec = now.tv_sec; - ret.tv_usec = now.tv_usec; + ret.tv_usec = (int)now.tv_usec; return ret; } diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 8f15b1a152..131f2dc7c0 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -85,7 +85,7 @@ !defined(CURL_DISABLE_IMAP) /* * checkheaders() checks the linked list of custom headers for a - * particular header (prefix). + * particular header (prefix). Provide the prefix without colon! * * Returns a pointer to the first matching header or NULL if none matched. */ @@ -97,7 +97,8 @@ char *Curl_checkheaders(const struct connectdata *conn, struct Curl_easy *data = conn->data; for(head = data->set.headers; head; head = head->next) { - if(strncasecompare(head->data, thisheader, thislen)) + if(strncasecompare(head->data, thisheader, thislen) && + Curl_headersep(head->data[thislen]) ) return head->data; } @@ -135,8 +136,10 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) /* this function returns a size_t, so we typecast to int to prevent warnings with picky compilers */ + Curl_set_in_callback(data, true); nread = (int)data->state.fread_func(data->req.upload_fromhere, 1, buffersize, data->state.in); + Curl_set_in_callback(data, false); if(nread == CURL_READFUNC_ABORT) { failf(data, "operation aborted by callback"); @@ -302,7 +305,9 @@ CURLcode Curl_readrewind(struct connectdata *conn) if(data->set.seek_func) { int err; + Curl_set_in_callback(data, true); err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET); + Curl_set_in_callback(data, false); if(err) { failf(data, "seek callback returned error %d", (int)err); return CURLE_SEND_FAIL_REWIND; @@ -311,8 +316,10 @@ CURLcode Curl_readrewind(struct connectdata *conn) else if(data->set.ioctl_func) { curlioerr err; + Curl_set_in_callback(data, true); err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, data->set.ioctl_client); + Curl_set_in_callback(data, false); infof(data, "the ioctl callback returned %d\n", (int)err); if(err) { @@ -710,7 +717,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, #endif /* CURL_DISABLE_HTTP */ /* Account for body content stored in the header buffer */ - if(k->badheader && !k->ignorebody) { + if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) { DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n", k->hbuflen)); k->bytecount += k->hbuflen; @@ -801,10 +808,15 @@ static CURLcode readwrite_data(struct Curl_easy *data, } /* if(!header and data to read) */ - if(conn->handler->readwrite && - (excess > 0 && !conn->bits.stream_was_rewound)) { + if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) { /* Parse the excess data */ k->str += nread; + + if(&k->str[excess] > &k->buf[data->set.buffer_size]) { + /* the excess amount was too excessive(!), make sure + it doesn't read out of buffer */ + excess = &k->buf[data->set.buffer_size] - k->str; + } nread = (ssize_t)excess; result = conn->handler->readwrite(data, conn, &nread, &readmore); @@ -1435,6 +1447,16 @@ static const char *find_host_sep(const char *url) } /* + * Decide in an encoding-independent manner whether a character in an + * URL must be escaped. The same criterion must be used in strlen_url() + * and strcpy_url(). + */ +static bool urlchar_needs_escaping(int c) +{ + return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); +} + +/* * strlen_url() returns the length of the given URL if the spaces within the * URL were properly URL encoded. * URL encoding should be skipped for host names, otherwise IDN resolution @@ -1462,7 +1484,7 @@ static size_t strlen_url(const char *url, bool relative) left = FALSE; /* fall through */ default: - if(*ptr >= 0x80) + if(urlchar_needs_escaping(*ptr)) newlen += 2; newlen++; break; @@ -1507,7 +1529,7 @@ static void strcpy_url(char *output, const char *url, bool relative) left = FALSE; /* fall through */ default: - if(*iptr >= 0x80) { + if(urlchar_needs_escaping(*iptr)) { snprintf(optr, 4, "%%%02x", *iptr); optr += 3; } @@ -1914,7 +1936,7 @@ CURLcode Curl_retry_request(struct connectdata *conn, char **url) { struct Curl_easy *data = conn->data; - + bool retry = FALSE; *url = NULL; /* if we're talking upload, we can't do the checks below, unless the protocol @@ -1927,7 +1949,7 @@ CURLcode Curl_retry_request(struct connectdata *conn, conn->bits.reuse && (!data->set.opt_no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP)) && - (data->set.rtspreq != RTSPREQ_RECEIVE)) { + (data->set.rtspreq != RTSPREQ_RECEIVE)) /* We got no data, we attempted to re-use a connection. For HTTP this can be a retry so we try again regardless if we expected a body. For other protocols we only try again only if we expected a body. @@ -1935,6 +1957,19 @@ CURLcode Curl_retry_request(struct connectdata *conn, This might happen if the connection was left alive when we were done using it before, but that was closed when we wanted to read from it again. Bad luck. Retry the same request on a fresh connect! */ + retry = TRUE; + else if(data->state.refused_stream && + (data->req.bytecount + data->req.headerbytecount == 0) ) { + /* This was sent on a refused stream, safe to rerun. A refused stream + error can typically only happen on HTTP/2 level if the stream is safe + to issue again, but the nghttp2 API can deliver the message to other + streams as well, which is why this adds the check the data counters + too. */ + infof(conn->data, "REFUSED_STREAM, retrying a fresh connect\n"); + data->state.refused_stream = FALSE; /* clear again */ + retry = TRUE; + } + if(retry) { infof(conn->data, "Connection died, retrying a fresh connect\n"); *url = strdup(conn->data->change.url); if(!*url) @@ -1983,11 +2018,19 @@ Curl_setup_transfer( DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); - /* now copy all input parameters */ - conn->sockfd = sockindex == -1 ? + if(conn->bits.multiplex || conn->httpversion == 20) { + /* when multiplexing, the read/write sockets need to be the same! */ + conn->sockfd = sockindex == -1 ? + ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : + conn->sock[sockindex]; + conn->writesockfd = conn->sockfd; + } + else { + conn->sockfd = sockindex == -1 ? CURL_SOCKET_BAD : conn->sock[sockindex]; - conn->writesockfd = writesockindex == -1 ? + conn->writesockfd = writesockindex == -1 ? CURL_SOCKET_BAD:conn->sock[writesockindex]; + } k->getheader = getheader; k->size = size; @@ -2006,10 +2049,10 @@ Curl_setup_transfer( /* we want header and/or body, if neither then don't do this! */ if(k->getheader || !data->set.opt_no_body) { - if(conn->sockfd != CURL_SOCKET_BAD) + if(sockindex != -1) k->keepon |= KEEP_RECV; - if(conn->writesockfd != CURL_SOCKET_BAD) { + if(writesockindex != -1) { struct HTTP *http = data->req.protop; /* HTTP 1.1 magic: @@ -2040,7 +2083,7 @@ Curl_setup_transfer( /* enable the write bit when we're not waiting for continue */ k->keepon |= KEEP_SEND; } - } /* if(conn->writesockfd != CURL_SOCKET_BAD) */ + } /* if(writesockindex != -1) */ } /* if(k->getheader || !data->set.opt_no_body) */ } diff --git a/libs/libcurl/src/transfer.h b/libs/libcurl/src/transfer.h index 72526a8348..9ba398d27d 100644 --- a/libs/libcurl/src/transfer.h +++ b/libs/libcurl/src/transfer.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -22,6 +22,7 @@ * ***************************************************************************/ +#define Curl_headersep(x) ((((x)==':') || ((x)==';'))) char *Curl_checkheaders(const struct connectdata *conn, const char *thisheader); diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 47f69c9f14..701f83ab3b 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -55,9 +55,7 @@ #error "We can't compile without socket() support!" #endif -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #ifdef USE_LIBIDN2 #include <idn2.h> @@ -127,10 +125,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "curl_memory.h" #include "memdebug.h" -/* Local static prototypes */ -static struct connectdata * -find_oldest_idle_connection_in_bundle(struct Curl_easy *data, - struct connectbundle *bundle); static void conn_free(struct connectdata *conn); static void free_fixed_hostname(struct hostname *host); static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); @@ -196,8 +190,11 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_tftp, #endif -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) &Curl_handler_scp, +#endif + +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) &Curl_handler_sftp, #endif @@ -294,6 +291,8 @@ void Curl_freeset(struct Curl_easy *data) data->change.url_alloc = FALSE; } data->change.url = NULL; + + Curl_mime_cleanpart(&data->set.mimepost); } /* @@ -383,8 +382,6 @@ CURLcode Curl_close(struct Curl_easy *data) Curl_http2_cleanup_dependencies(data); Curl_convert_close(data); - Curl_mime_cleanpart(&data->set.mimepost); - /* No longer a dirty share, if it exists */ if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); @@ -403,8 +400,9 @@ CURLcode Curl_close(struct Curl_easy *data) * Initialize the UserDefined fields within a Curl_easy. * This may be safely called on a new or existing Curl_easy. */ -CURLcode Curl_init_userdefined(struct UserDefined *set) +CURLcode Curl_init_userdefined(struct Curl_easy *data) { + struct UserDefined *set = &data->set; CURLcode result = CURLE_OK; set->out = stdout; /* default output to stdout */ @@ -454,6 +452,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) /* make libcurl quiet by default: */ set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ + Curl_mime_initpart(&set->mimepost, data); + /* * libcurl 7.10 introduced SSL verification *by default*! This needs to be * switched off unless wanted. @@ -488,25 +488,33 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->socks5_gssapi_nec = FALSE; #endif - /* This is our preferred CA cert bundle/path since install time */ + /* Set the default CA cert bundle/path detected/specified at build time. + * + * If Schannel (WinSSL) is the selected SSL backend then these locations + * are ignored. We allow setting CA location for schannel only when + * explicitly specified by the user via CURLOPT_CAINFO / --cacert. + */ + if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { #if defined(CURL_CA_BUNDLE) - result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); - if(result) - return result; + result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); + if(result) + return result; - result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE); - if(result) - return result; + result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], + CURL_CA_BUNDLE); + if(result) + return result; #endif #if defined(CURL_CA_PATH) - result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH); - if(result) - return result; + result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH); + if(result) + return result; - result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH); - if(result) - return result; + result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH); + if(result) + return result; #endif + } set->wildcard_enabled = FALSE; set->chunk_bgn = ZERO_NULL; @@ -527,6 +535,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->expect_100_timeout = 1000L; /* Wait for a second by default. */ set->sep_headers = TRUE; /* separated header lists by default */ set->buffer_size = READBUFFER_SIZE; + set->happy_eyeballs_timeout = CURL_HET_DEFAULT; Curl_http2_init_userset(set); return result; @@ -570,15 +579,13 @@ CURLcode Curl_open(struct Curl_easy **curl) result = CURLE_OUT_OF_MEMORY; } else { - Curl_mime_initpart(&data->set.mimepost, data); - data->state.headerbuff = malloc(HEADERSIZE); if(!data->state.headerbuff) { DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); result = CURLE_OUT_OF_MEMORY; } else { - result = Curl_init_userdefined(&data->set); + result = Curl_init_userdefined(data); data->state.headersize = HEADERSIZE; Curl_convert_init(data); @@ -716,6 +723,9 @@ static void conn_free(struct connectdata *conn) Curl_safefree(conn->unix_domain_socket); #endif +#ifdef USE_SSL + Curl_safefree(conn->ssl_extra); +#endif free(conn); /* free all the connection oriented data */ } @@ -770,7 +780,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) /* unlink ourselves! */ infof(data, "Closing connection %ld\n", conn->connection_id); - Curl_conncache_remove_conn(data->state.conn_cache, conn); + Curl_conncache_remove_conn(conn, TRUE); free_fixed_hostname(&conn->host); free_fixed_hostname(&conn->conn_to_host); @@ -936,56 +946,17 @@ proxy_info_matches(const struct proxy_info* data, return FALSE; } - /* - * This function finds the connection in the connection - * bundle that has been unused for the longest time. + * This function checks if the given connection is dead and extracts it from + * the connection cache if so. * - * Returns the pointer to the oldest idle connection, or NULL if none was - * found. - */ -static struct connectdata * -find_oldest_idle_connection_in_bundle(struct Curl_easy *data, - struct connectbundle *bundle) -{ - struct curl_llist_element *curr; - timediff_t highscore = -1; - timediff_t score; - struct curltime now; - struct connectdata *conn_candidate = NULL; - struct connectdata *conn; - - (void)data; - - now = Curl_now(); - - curr = bundle->conn_list.head; - while(curr) { - conn = curr->ptr; - - if(!conn->inuse) { - /* Set higher score for the age passed since the connection was used */ - score = Curl_timediff(now, conn->now); - - if(score > highscore) { - highscore = score; - conn_candidate = conn; - } - } - curr = curr->next; - } - - return conn_candidate; -} - -/* - * This function checks if given connection is dead and disconnects if so. - * (That also removes it from the connection cache.) + * When this is called as a Curl_conncache_foreach() callback, the connection + * cache lock is held! * - * Returns TRUE if the connection actually was dead and disconnected. + * Returns TRUE if the connection was dead and extracted. */ -static bool disconnect_if_dead(struct connectdata *conn, - struct Curl_easy *data) +static bool extract_if_dead(struct connectdata *conn, + struct Curl_easy *data) { size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size; if(!pipeLen && !conn->inuse) { @@ -1010,25 +981,30 @@ static bool disconnect_if_dead(struct connectdata *conn, if(dead) { conn->data = data; infof(data, "Connection %ld seems to be dead!\n", conn->connection_id); - - /* disconnect resources */ - Curl_disconnect(conn, /* dead_connection */TRUE); + Curl_conncache_remove_conn(conn, FALSE); return TRUE; } } return FALSE; } +struct prunedead { + struct Curl_easy *data; + struct connectdata *extracted; +}; + /* - * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach() + * Wrapper to use extract_if_dead() function in Curl_conncache_foreach() * - * Returns always 0. */ -static int call_disconnect_if_dead(struct connectdata *conn, - void *param) +static int call_extract_if_dead(struct connectdata *conn, void *param) { - struct Curl_easy* data = (struct Curl_easy*)param; - disconnect_if_dead(conn, data); + struct prunedead *p = (struct prunedead *)param; + if(extract_if_dead(conn, p->data)) { + /* stop the iteration here, pass back the connection that was extracted */ + p->extracted = conn; + return 1; + } return 0; /* continue iteration */ } @@ -1043,8 +1019,14 @@ static void prune_dead_connections(struct Curl_easy *data) time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup); if(elapsed >= 1000L) { - Curl_conncache_foreach(data, data->state.conn_cache, data, - call_disconnect_if_dead); + struct prunedead prune; + prune.data = data; + prune.extracted = NULL; + while(Curl_conncache_foreach(data, data->state.conn_cache, &prune, + call_extract_if_dead)) { + /* disconnect it */ + (void)Curl_disconnect(prune.extracted, /* dead_connection */TRUE); + } data->state.conn_cache->last_cleanup = now; } } @@ -1099,8 +1081,8 @@ ConnectionExists(struct Curl_easy *data, Curl_pipeline_site_blacklisted(data, needle)) canpipe &= ~ CURLPIPE_HTTP1; - /* Look up the bundle with all the connections to this - particular host */ + /* Look up the bundle with all the connections to this particular host. + Locks the connection cache, beware of early returns! */ bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache); if(bundle) { /* Max pipe length is zero (unlimited) for multiplexed connections */ @@ -1123,6 +1105,7 @@ ConnectionExists(struct Curl_easy *data, if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) { infof(data, "Server doesn't support multi-use yet, wait\n"); *waitpipe = TRUE; + Curl_conncache_unlock(needle); return FALSE; /* no re-use */ } @@ -1154,8 +1137,11 @@ ConnectionExists(struct Curl_easy *data, check = curr->ptr; curr = curr->next; - if(disconnect_if_dead(check, data)) + if(extract_if_dead(check, data)) { + /* disconnect it */ + (void)Curl_disconnect(check, /* dead_connection */TRUE); continue; + } pipeLen = check->send_pipe.size + check->recv_pipe.size; @@ -1286,6 +1272,11 @@ ConnectionExists(struct Curl_easy *data, already in use so we skip it */ continue; + if((check->inuse) && (check->data->multi != needle->data->multi)) + /* this could be subject for pipeline/multiplex use, but only + if they belong to the same multi handle */ + continue; + if(needle->localdev || needle->localport) { /* If we are bound to a specific local end (IP+port), we must not re-use a random other one, although if we didn't ask for a @@ -1472,9 +1463,13 @@ ConnectionExists(struct Curl_easy *data, } if(chosen) { + /* mark it as used before releasing the lock */ + chosen->inuse = TRUE; + Curl_conncache_unlock(needle); *usethis = chosen; return TRUE; /* yes, we found one to use! */ } + Curl_conncache_unlock(needle); if(foundPendingCandidate && data->set.pipewait) { infof(data, @@ -1793,38 +1788,27 @@ static void llist_dtor(void *user, void *element) */ static struct connectdata *allocate_conn(struct Curl_easy *data) { - struct connectdata *conn; - size_t connsize = sizeof(struct connectdata); - -#ifdef USE_SSL -/* SSLBK_MAX_ALIGN: The max byte alignment a CPU would use */ -#define SSLBK_MAX_ALIGN 32 - /* The SSL backend-specific data (ssl_backend_data) objects are allocated as - part of connectdata at the end. To ensure suitable alignment we will - assume a maximum of SSLBK_MAX_ALIGN for alignment. Since calloc returns a - pointer suitably aligned for any variable this will ensure the - ssl_backend_data array has proper alignment, even if that alignment turns - out to be less than SSLBK_MAX_ALIGN. */ - size_t paddingsize = sizeof(struct connectdata) % SSLBK_MAX_ALIGN; - size_t alignsize = paddingsize ? (SSLBK_MAX_ALIGN - paddingsize) : 0; - size_t sslbksize = Curl_ssl->sizeof_ssl_backend_data; - connsize += alignsize + (4 * sslbksize); -#endif - - conn = calloc(1, connsize); + struct connectdata *conn = calloc(1, sizeof(struct connectdata)); if(!conn) return NULL; #ifdef USE_SSL - /* Point to the ssl_backend_data objects at the end of connectdata. + /* The SSL backend-specific data (ssl_backend_data) objects are allocated as + a separate array to ensure suitable alignment. Note that these backend pointers can be swapped by vtls (eg ssl backend data becomes proxy backend data). */ { - char *end = (char *)conn + connsize; - conn->ssl[0].backend = ((void *)(end - (4 * sslbksize))); - conn->ssl[1].backend = ((void *)(end - (3 * sslbksize))); - conn->proxy_ssl[0].backend = ((void *)(end - (2 * sslbksize))); - conn->proxy_ssl[1].backend = ((void *)(end - (1 * sslbksize))); + size_t sslsize = Curl_ssl->sizeof_ssl_backend_data; + char *ssl = calloc(4, sslsize); + if(!ssl) { + free(conn); + return NULL; + } + conn->ssl_extra = ssl; + conn->ssl[0].backend = (void *)ssl; + conn->ssl[1].backend = (void *)(ssl + sslsize); + conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize); + conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize); } #endif @@ -1953,6 +1937,9 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) free(conn->master_buffer); free(conn->localdev); +#ifdef USE_SSL + free(conn->ssl_extra); +#endif free(conn); return NULL; } @@ -2054,7 +2041,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, ((('a' <= (str)[0] && (str)[0] <= 'z') || \ ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ ((str)[1] == ':' || (str)[1] == '|') && \ - ((str)[2] == '/' || (str)[2] == 0)) + ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) /* Don't mistake a drive letter for a scheme if the default protocol is file. curld --proto-default file c:/foo/bar.txt */ @@ -2088,15 +2075,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return CURLE_URL_MALFORMAT; } - if(url_has_scheme && path[0] == '/' && path[1] == '/' && - path[2] == '/' && path[3] == '/') { - /* This appears to be a UNC string (usually indicating a SMB share). - * We don't do SMB in file: URLs. (TODO?) - */ - failf(data, "SMB shares are not supported in file: URLs."); - return CURLE_URL_MALFORMAT; - } - /* Extra handling URLs with an authority component (i.e. that start with * "file://") * @@ -2135,25 +2113,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, ptr += 9; /* now points to the slash after the host */ } - /* - * RFC 8089, Appendix D, Section D.1, says: - * - * > In a POSIX file system, the root of the file system is represented - * > as a directory with a zero-length name, usually written as "/"; the - * > presence of this root in a file URI can be taken as given by the - * > initial slash in the "path-absolute" rule. - * - * i.e. the first slash is part of the path. - * - * However in RFC 1738 the "/" between the host (or port) and the - * URL-path was NOT part of the URL-path. Any agent that followed the - * older spec strictly, and wanted to refer to a file with an absolute - * path, would have included a second slash. So if there are two - * slashes, swallow one. - */ - if('/' == ptr[1]) /* note: the only way ptr[0]!='/' is if ptr[1]==':' */ - ptr++; - /* This cannot be done with strcpy, as the memory chunks overlap! */ memmove(path, ptr, strlen(ptr) + 1); } @@ -2595,7 +2554,15 @@ static bool check_noproxy(const char *name, const char *no_proxy) /* NO_PROXY was specified and it wasn't just an asterisk */ no_proxy_len = strlen(no_proxy); - endptr = strchr(name, ':'); + if(name[0] == '[') { + /* IPv6 numerical address */ + endptr = strchr(name, ']'); + if(!endptr) + return FALSE; + name++; + } + else + endptr = strchr(name, ':'); if(endptr) namelen = endptr - name; else @@ -2703,13 +2670,20 @@ static char *detect_proxy(struct connectdata *conn) prox = curl_getenv(proxy_env); } - if(prox) + envp = proxy_env; + if(prox) { proxy = prox; /* use this */ + } else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) - proxy = curl_getenv("ALL_PROXY"); + envp = (char *)"all_proxy"; + proxy = curl_getenv(envp); /* default proxy to use */ + if(!proxy) { + envp = (char *)"ALL_PROXY"; + proxy = curl_getenv(envp); + } } + if(proxy) + infof(conn->data, "Uses proxy env variable %s == '%s'\n", envp, proxy); return proxy; } @@ -2766,7 +2740,7 @@ static CURLcode parse_proxy(struct Curl_easy *data, proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */ #ifdef USE_SSL - if(!Curl_ssl->support_https_proxy) + if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)) #endif if(proxytype == CURLPROXY_HTTPS) { failf(data, "Unsupported proxy \'%s\', libcurl is built without the " @@ -2994,9 +2968,15 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) } if(!data->set.str[STRING_NOPROXY]) { - no_proxy = curl_getenv("no_proxy"); - if(!no_proxy) - no_proxy = curl_getenv("NO_PROXY"); + const char *p = "no_proxy"; + no_proxy = curl_getenv(p); + if(!no_proxy) { + p = "NO_PROXY"; + no_proxy = curl_getenv(p); + } + if(no_proxy) { + infof(conn->data, "Uses proxy env variable %s == '%s'\n", p, no_proxy); + } } if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ? @@ -3439,7 +3419,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data, * stripped off. It would be better to work directly from the original * URL and simply replace the port part of it. */ - url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme, + url = aprintf("%s://%s%s%s:%d%s%s%s", conn->given->scheme, conn->bits.ipv6_ip?"[":"", conn->host.name, conn->bits.ipv6_ip?"]":"", conn->remote_port, data->state.slash_removed?"/":"", data->state.path, @@ -3634,6 +3614,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, /* detect and extract RFC6874-style IPv6-addresses */ if(*hostptr == '[') { +#ifdef ENABLE_IPV6 char *ptr = ++hostptr; /* advance beyond the initial bracket */ while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) ptr++; @@ -3657,6 +3638,11 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, * hostptr first, but I can't see anything wrong with that as no host * name nor a numeric can legally start with a bracket. */ +#else + failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in!"); + free(host_dup); + return CURLE_NOT_BUILT_IN; +#endif } /* Get port number off server.com:1080 */ @@ -4132,7 +4118,7 @@ static CURLcode create_conn(struct Curl_easy *data, *************************************************************/ if(prot_missing) { /* We're guessing prefixes here and if we're told to use a proxy or if - we're gonna follow a Location: later or... then we need the protocol + we're going to follow a Location: later or... then we need the protocol part added so that we have a valid URL. */ char *reurl; char *ch_lower; @@ -4410,20 +4396,21 @@ static CURLcode create_conn(struct Curl_easy *data, else reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); - /* If we found a reusable connection, we may still want to - open a new connection if we are pipelining. */ + /* If we found a reusable connection that is now marked as in use, we may + still want to open a new connection if we are pipelining. */ if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) { size_t pipelen = conn_temp->send_pipe.size + conn_temp->recv_pipe.size; if(pipelen > 0) { infof(data, "Found connection %ld, with requests in the pipe (%zu)\n", conn_temp->connection_id, pipelen); - if(conn_temp->bundle->num_connections < max_host_connections && - data->state.conn_cache->num_connections < max_total_connections) { + if(Curl_conncache_bundle_size(conn_temp) < max_host_connections && + Curl_conncache_size(data) < max_total_connections) { /* We want a new connection anyway */ reuse = FALSE; infof(data, "We can reuse, but we want a new connection anyway\n"); + Curl_conncache_return_conn(conn_temp); } } } @@ -4435,9 +4422,10 @@ static CURLcode create_conn(struct Curl_easy *data, * just allocated before we can move along and use the previously * existing one. */ - conn_temp->inuse = TRUE; /* mark this as being in use so that no other - handle in a multi stack may nick it */ reuse_conn(conn, conn_temp); +#ifdef USE_SSL + free(conn->ssl_extra); +#endif free(conn); /* we don't need this anymore */ conn = conn_temp; *in_connect = conn; @@ -4453,7 +4441,6 @@ static CURLcode create_conn(struct Curl_easy *data, /* We have decided that we want a new connection. However, we may not be able to do that if we have reached the limit of how many connections we are allowed to open. */ - struct connectbundle *bundle = NULL; if(conn->handler->flags & PROTOPT_ALPN_NPN) { /* The protocol wants it, so set the bits if enabled in the easy handle @@ -4468,35 +4455,42 @@ static CURLcode create_conn(struct Curl_easy *data, /* There is a connection that *might* become usable for pipelining "soon", and we wait for that */ connections_available = FALSE; - else - bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); - - if(max_host_connections > 0 && bundle && - (bundle->num_connections >= max_host_connections)) { - struct connectdata *conn_candidate; - - /* The bundle is full. Let's see if we can kill a connection. */ - conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle); - - if(conn_candidate) { - /* Set the connection's owner correctly, then kill it */ - conn_candidate->data = data; - (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); - } - else { - infof(data, "No more connections allowed to host: %d\n", - max_host_connections); - connections_available = FALSE; + else { + /* this gets a lock on the conncache */ + struct connectbundle *bundle = + Curl_conncache_find_bundle(conn, data->state.conn_cache); + + if(max_host_connections > 0 && bundle && + (bundle->num_connections >= max_host_connections)) { + struct connectdata *conn_candidate; + + /* The bundle is full. Extract the oldest connection. */ + conn_candidate = Curl_conncache_extract_bundle(data, bundle); + Curl_conncache_unlock(conn); + + if(conn_candidate) { + /* Set the connection's owner correctly, then kill it */ + conn_candidate->data = data; + (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); + } + else { + infof(data, "No more connections allowed to host: %d\n", + max_host_connections); + connections_available = FALSE; + } } + else + Curl_conncache_unlock(conn); + } if(connections_available && (max_total_connections > 0) && - (data->state.conn_cache->num_connections >= max_total_connections)) { + (Curl_conncache_size(data) >= max_total_connections)) { struct connectdata *conn_candidate; /* The cache is full. Let's see if we can kill a connection. */ - conn_candidate = Curl_conncache_oldest_idle(data); + conn_candidate = Curl_conncache_extract_oldest(data); if(conn_candidate) { /* Set the connection's owner correctly, then kill it */ @@ -4519,6 +4513,9 @@ static CURLcode create_conn(struct Curl_easy *data, goto out; } else { + /* Mark the connection as used, before we add it */ + conn->inuse = TRUE; + /* * This is a brand new connection, so let's store it in the connection * cache of ours! @@ -4546,9 +4543,6 @@ static CURLcode create_conn(struct Curl_easy *data, #endif } - /* Mark the connection as used */ - conn->inuse = TRUE; - /* Setup and init stuff before DO starts, in preparing for the transfer. */ Curl_init_do(data, conn); @@ -4648,22 +4642,8 @@ CURLcode Curl_setup_conn(struct connectdata *conn, Curl_verboseconnect(conn); } - conn->now = Curl_now(); /* time this *after* the connect is done, we - set this here perhaps a second time */ - -#ifdef __EMX__ - /* - * This check is quite a hack. We're calling _fsetmode to fix the problem - * with fwrite converting newline characters (you get mangled text files, - * and corrupted binary files when you download to stdout and redirect it to - * a file). - */ - - if((data->set.out)->_handle == NULL) { - _fsetmode(stdout, "b"); - } -#endif - + conn->now = Curl_now(); /* time this *after* the connect is done, we set + this here perhaps a second time */ return result; } diff --git a/libs/libcurl/src/url.h b/libs/libcurl/src/url.h index 5dd04fdff7..a70bd5466a 100644 --- a/libs/libcurl/src/url.h +++ b/libs/libcurl/src/url.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -33,9 +33,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn); CURLcode Curl_open(struct Curl_easy **curl); -CURLcode Curl_init_userdefined(struct UserDefined *set); -CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, - va_list arg); +CURLcode Curl_init_userdefined(struct Curl_easy *data); CURLcode Curl_dupset(struct Curl_easy * dst, struct Curl_easy * src); void Curl_freeset(struct Curl_easy * data); CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */ diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index edd1fd9ac0..7fae00fd96 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -85,6 +85,9 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#ifdef HAVE_NETINET_IN6_H +#include <netinet/in6.h> +#endif #include "timeval.h" @@ -95,6 +98,20 @@ #include "hash.h" #include "splay.h" +/* return the count of bytes sent, or -1 on error */ +typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + const void *buf, /* data to write */ + size_t len, /* max amount to write */ + CURLcode *err); /* error to return */ + +/* return the count of bytes read, or -1 on error */ +typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ + int sockindex, /* socketindex */ + char *buf, /* store data here */ + size_t len, /* max amount to read */ + CURLcode *err); /* error to return */ + #include "mime.h" #include "imap.h" #include "pop3.h" @@ -325,6 +342,7 @@ struct ntlmdata { BYTE *output_token; BYTE *input_token; size_t input_token_len; + TCHAR *spn; #else unsigned int flags; unsigned char nonce[8]; @@ -700,20 +718,6 @@ struct Curl_handler { #define CONNRESULT_NONE 0 /* No extra information. */ #define CONNRESULT_DEAD (1<<0) /* The connection is dead. */ -/* return the count of bytes sent, or -1 on error */ -typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */ - int sockindex, /* socketindex */ - const void *buf, /* data to write */ - size_t len, /* max amount to write */ - CURLcode *err); /* error to return */ - -/* return the count of bytes read, or -1 on error */ -typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ - int sockindex, /* socketindex */ - char *buf, /* store data here */ - size_t len, /* max amount to read */ - CURLcode *err); /* error to return */ - #ifdef USE_RECV_BEFORE_SEND_WORKAROUND struct postponed_data { char *buffer; /* Temporal store for received data during @@ -752,6 +756,7 @@ struct http_connect_state { TUNNEL_CONNECT, /* CONNECT has been sent off */ TUNNEL_COMPLETE /* CONNECT response received completely */ } tunnel_state; + bool close_connection; }; /* @@ -775,9 +780,10 @@ struct connectdata { void *closesocket_client; bool inuse; /* This is a marker for the connection cache logic. If this is - TRUE this handle is being used by an easy handle and cannot - be used by any other easy handle without careful - consideration (== only for pipelining). */ + TRUE this handle is being used by one or more easy handles + and can only used by any other easy handle without careful + consideration (== only for pipelining/multiplexing) and it + cannot be used by another multi handle! */ /**** Fields set when inited and not modified again */ long connection_id; /* Contains a unique number to make it easier to @@ -860,6 +866,9 @@ struct connectdata { #endif /* USE_RECV_BEFORE_SEND_WORKAROUND */ struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */ struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */ +#ifdef USE_SSL + void *ssl_extra; /* separately allocated backend-specific data */ +#endif struct ssl_primary_config ssl_config; struct ssl_primary_config proxy_ssl_config; bool tls_upgraded; @@ -887,7 +896,7 @@ struct connectdata { well be the same we read from. CURL_SOCKET_BAD disables */ - /** Dynamicly allocated strings, MUST be freed before this **/ + /** Dynamically allocated strings, MUST be freed before this **/ /** struct is killed. **/ struct dynamically_allocated_data { char *proxyuserpwd; @@ -1016,10 +1025,8 @@ struct PureInfo { int httpcode; /* Recent HTTP, FTP, RTSP or SMTP response code */ int httpproxycode; /* response code from proxy when received separate */ int httpversion; /* the http version number X.Y = X*10+Y */ - long filetime; /* If requested, this is might get set. Set to -1 if the time - was unretrievable. We cannot have this of type time_t, - since time_t is unsigned on several platforms such as - OpenVMS. */ + time_t filetime; /* If requested, this is might get set. Set to -1 if the + time was unretrievable. */ bool timecond; /* set to TRUE if the time condition didn't match, which thus made the document NOT get fetched */ long header_size; /* size of read header(s) in bytes */ @@ -1160,7 +1167,7 @@ struct Curl_http2_dep { }; /* - * This struct is for holding data that was attemped to get sent to the user's + * This struct is for holding data that was attempted to get sent to the user's * callback but is held due to pausing. One instance per type (BOTH, HEADER, * BODY). */ @@ -1219,7 +1226,7 @@ struct UrlState { curl_off_t current_speed; /* the ProgressShow() function sets this, bytes / second */ bool this_is_a_follow; /* this is a followed Location: request */ - + bool refused_stream; /* this was refused, try again */ char *first_host; /* host name of the first (not followed) request. if set, this should be the host name that we will sent authorization to, no else. Used to make Location: @@ -1322,6 +1329,9 @@ struct UrlState { struct Curl_easy *stream_depends_on; bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; +#ifdef CURLDEBUG + bool conncache_lock; +#endif }; @@ -1407,19 +1417,14 @@ enum dupstring { STRING_RTSP_SESSION_ID, /* Session ID to use */ STRING_RTSP_STREAM_URI, /* Stream URI for this request */ STRING_RTSP_TRANSPORT, /* Transport for this session */ -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */ STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */ STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */ STRING_SSH_KNOWNHOSTS, /* file name of knownhosts file */ #endif -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) STRING_PROXY_SERVICE_NAME, /* Proxy service name */ -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ - defined(USE_SPNEGO) || defined(HAVE_GSSAPI) STRING_SERVICE_NAME, /* Service name */ -#endif STRING_MAIL_FROM, STRING_MAIL_AUTH, @@ -1511,6 +1516,7 @@ struct UserDefined { long timeout; /* in milliseconds, 0 means no timeout */ long connecttimeout; /* in milliseconds, 0 means no timeout */ long accepttimeout; /* in milliseconds, 0 means no timeout */ + long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */ long server_response_timeout; /* in milliseconds, 0 means no timeout */ long tftp_blksize; /* in bytes, 0 means use default */ bool tftp_no_options; /* do not send TFTP options requests */ @@ -1588,7 +1594,7 @@ struct UserDefined { bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */ bool http_follow_location; /* follow HTTP redirects */ bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */ - bool http_disable_hostname_check_before_authentication; + bool allow_auth_to_other_hosts; bool include_header; /* include received protocol headers in data output */ bool http_set_referer; /* is a custom referer used */ bool http_auto_referer; /* set "correct" referer when following location: */ @@ -1664,13 +1670,21 @@ struct UserDefined { bool suppress_connect_headers; /* suppress proxy CONNECT response headers from user callbacks */ + bool dns_shuffle_addresses; /* whether to shuffle addresses before use */ + struct Curl_easy *stream_depends_on; bool stream_depends_e; /* set or don't set the Exclusive bit */ int stream_weight; + bool haproxyprotocol; /* whether to send HAProxy PROXY protocol header */ + struct Curl_http2_dep *stream_dependents; bool abstract_unix_socket; + + curl_resolver_start_callback resolver_start; /* optional callback called + before resolver start */ + void *resolver_start_client; /* pointer to pass to resolver start callback */ }; struct Names { diff --git a/libs/libcurl/src/vauth/cleartext.c b/libs/libcurl/src/vauth/cleartext.c index a761ae7846..5d61ce6dc2 100644 --- a/libs/libcurl/src/vauth/cleartext.c +++ b/libs/libcurl/src/vauth/cleartext.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -73,16 +73,10 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, ulen = strlen(userp); plen = strlen(passwdp); - /* Compute binary message length, checking for overflows. */ - plainlen = 2 * ulen; - if(plainlen < ulen) - return CURLE_OUT_OF_MEMORY; - plainlen += plen; - if(plainlen < plen) - return CURLE_OUT_OF_MEMORY; - plainlen += 2; - if(plainlen < 2) + /* Compute binary message length. Check for overflows. */ + if((ulen > SIZE_T_MAX/2) || (plen > (SIZE_T_MAX/2 - 2))) return CURLE_OUT_OF_MEMORY; + plainlen = 2 * ulen + plen + 2; plainauth = malloc(plainlen); if(!plainauth) diff --git a/libs/libcurl/src/vauth/krb5_sspi.c b/libs/libcurl/src/vauth/krb5_sspi.c index 1b4cef486d..9afb971fcd 100644 --- a/libs/libcurl/src/vauth/krb5_sspi.c +++ b/libs/libcurl/src/vauth/krb5_sspi.c @@ -135,7 +135,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, } if(!krb5->credentials) { - /* Do we have credientials to use or are we using single sign-on? */ + /* Do we have credentials to use or are we using single sign-on? */ if(userp && *userp) { /* Populate our identity structure */ result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity); @@ -150,12 +150,10 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, krb5->p_identity = NULL; /* Allocate our credentials handle */ - krb5->credentials = malloc(sizeof(CredHandle)); + krb5->credentials = calloc(1, sizeof(CredHandle)); if(!krb5->credentials) return CURLE_OUT_OF_MEMORY; - memset(krb5->credentials, 0, sizeof(CredHandle)); - /* Acquire our credentials handle */ status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) @@ -167,11 +165,9 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, return CURLE_LOGIN_DENIED; /* Allocate our new context handle */ - krb5->context = malloc(sizeof(CtxtHandle)); + krb5->context = calloc(1, sizeof(CtxtHandle)); if(!krb5->context) return CURLE_OUT_OF_MEMORY; - - memset(krb5->context, 0, sizeof(CtxtHandle)); } if(chlg64 && *chlg64) { diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c index 1e0d4792e7..cdb8d8f0d9 100644 --- a/libs/libcurl/src/vauth/ntlm.c +++ b/libs/libcurl/src/vauth/ntlm.c @@ -63,9 +63,9 @@ /* "NTLMSSP" signature is always in ASCII regardless of the platform */ #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" -#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff) -#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \ - (((x) >> 16) & 0xff), (((x) >> 24) & 0xff) +#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)) +#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \ + ((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff)) #if DEBUG_ME # define DEBUG_OUT(x) x @@ -355,6 +355,8 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. * passdwp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -365,6 +367,8 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *userp, const char *passwdp, + const char *service, + const char *hostname, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { @@ -394,6 +398,8 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, domain are empty */ (void)userp; (void)passwdp; + (void)service, + (void)hostname, /* Clean up any former leftovers and initialise to defaults */ Curl_auth_ntlm_cleanup(ntlm); diff --git a/libs/libcurl/src/vauth/ntlm.h b/libs/libcurl/src/vauth/ntlm.h index f906a3c7a7..1136b0f8d3 100644 --- a/libs/libcurl/src/vauth/ntlm.h +++ b/libs/libcurl/src/vauth/ntlm.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_NTLM_H -#define HEADER_CURL_NTLM_H +#ifndef HEADER_VAUTH_NTLM_H +#define HEADER_VAUTH_NTLM_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -140,4 +140,4 @@ #endif /* USE_NTLM */ -#endif /* HEADER_CURL_NTLM_H */ +#endif /* HEADER_VAUTH_NTLM_H */ diff --git a/libs/libcurl/src/vauth/ntlm_sspi.c b/libs/libcurl/src/vauth/ntlm_sspi.c index e748ce3b67..089c1a6d4b 100644 --- a/libs/libcurl/src/vauth/ntlm_sspi.c +++ b/libs/libcurl/src/vauth/ntlm_sspi.c @@ -70,6 +70,8 @@ bool Curl_auth_is_ntlm_supported(void) * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. * passdwp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -80,6 +82,8 @@ bool Curl_auth_is_ntlm_supported(void) CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *userp, const char *passwdp, + const char *service, + const char *host, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { @@ -125,12 +129,10 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, ntlm->p_identity = NULL; /* Allocate our credentials handle */ - ntlm->credentials = malloc(sizeof(CredHandle)); + ntlm->credentials = calloc(1, sizeof(CredHandle)); if(!ntlm->credentials) return CURLE_OUT_OF_MEMORY; - memset(ntlm->credentials, 0, sizeof(CredHandle)); - /* Acquire our credentials handle */ status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_NTLM), @@ -141,11 +143,13 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, return CURLE_LOGIN_DENIED; /* Allocate our new context handle */ - ntlm->context = malloc(sizeof(CtxtHandle)); + ntlm->context = calloc(1, sizeof(CtxtHandle)); if(!ntlm->context) return CURLE_OUT_OF_MEMORY; - memset(ntlm->context, 0, sizeof(CtxtHandle)); + ntlm->spn = Curl_auth_build_spn(service, host, NULL); + if(!ntlm->spn) + return CURLE_OUT_OF_MEMORY; /* Setup the type-1 "output" security buffer */ type_1_desc.ulVersion = SECBUFFER_VERSION; @@ -157,7 +161,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, /* Generate our type-1 message */ status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, - (TCHAR *) TEXT(""), + ntlm->spn, 0, 0, SECURITY_NETWORK_DREP, NULL, 0, ntlm->context, &type_1_desc, @@ -275,7 +279,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, /* Generate our type-3 message */ status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, ntlm->context, - (TCHAR *) TEXT(""), + ntlm->spn, 0, 0, SECURITY_NETWORK_DREP, &type_2_desc, 0, ntlm->context, @@ -333,6 +337,8 @@ void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm) /* Reset any variables */ ntlm->token_max = 0; + + Curl_safefree(ntlm->spn); } #endif /* USE_WINDOWS_SSPI && USE_NTLM */ diff --git a/libs/libcurl/src/vauth/spnego_sspi.c b/libs/libcurl/src/vauth/spnego_sspi.c index a6797cdaff..1fe19e3f97 100644 --- a/libs/libcurl/src/vauth/spnego_sspi.c +++ b/libs/libcurl/src/vauth/spnego_sspi.c @@ -138,7 +138,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, } if(!nego->credentials) { - /* Do we have credientials to use or are we using single sign-on? */ + /* Do we have credentials to use or are we using single sign-on? */ if(user && *user) { /* Populate our identity structure */ result = Curl_create_sspi_identity(user, password, &nego->identity); @@ -153,12 +153,10 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, nego->p_identity = NULL; /* Allocate our credentials handle */ - nego->credentials = malloc(sizeof(CredHandle)); + nego->credentials = calloc(1, sizeof(CredHandle)); if(!nego->credentials) return CURLE_OUT_OF_MEMORY; - memset(nego->credentials, 0, sizeof(CredHandle)); - /* Acquire our credentials handle */ nego->status = s_pSecFn->AcquireCredentialsHandle(NULL, @@ -170,11 +168,9 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, return CURLE_LOGIN_DENIED; /* Allocate our new context handle */ - nego->context = malloc(sizeof(CtxtHandle)); + nego->context = calloc(1, sizeof(CtxtHandle)); if(!nego->context) return CURLE_OUT_OF_MEMORY; - - memset(nego->context, 0, sizeof(CtxtHandle)); } if(chlg64 && *chlg64) { diff --git a/libs/libcurl/src/vauth/vauth.c b/libs/libcurl/src/vauth/vauth.c index b995f34e27..502d443ab7 100644 --- a/libs/libcurl/src/vauth/vauth.c +++ b/libs/libcurl/src/vauth/vauth.c @@ -115,8 +115,8 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host, * User@Domain (User Principal Name) * * Note: The user name may be empty when using a GSS-API library or Windows SSPI -* as the user and domain are either obtained from the credientals cache when -* using GSS-API or via the currently logged in user's credientals when using +* as the user and domain are either obtained from the credentials cache when +* using GSS-API or via the currently logged in user's credentials when using * Windows SSPI. * * Parameters: @@ -138,7 +138,7 @@ bool Curl_auth_user_contains_domain(const char *user) } #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) else - /* User and domain are obtained from the GSS-API credientials cache or the + /* User and domain are obtained from the GSS-API credentials cache or the currently logged in user from Windows */ valid = TRUE; #endif diff --git a/libs/libcurl/src/vauth/vauth.h b/libs/libcurl/src/vauth/vauth.h index dfaf985c60..f43064211f 100644 --- a/libs/libcurl/src/vauth/vauth.h +++ b/libs/libcurl/src/vauth/vauth.h @@ -122,6 +122,8 @@ bool Curl_auth_is_ntlm_supported(void); CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *userp, const char *passwdp, + const char *service, + const char *host, struct ntlmdata *ntlm, char **outptr, size_t *outlen); diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index 79cc0bba47..5b0d05a150 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,6 +26,7 @@ #include "urldata.h" #include "vtls/vtls.h" #include "http2.h" +#include "ssh.h" #include "curl_printf.h" #ifdef USE_ARES @@ -176,6 +177,11 @@ char *curl_version(void) left -= len; ptr += len; #endif +#ifdef USE_LIBSSH + len = snprintf(ptr, left, " libssh/%s", CURL_LIBSSH_VERSION); + left -= len; + ptr += len; +#endif #ifdef USE_NGHTTP2 len = Curl_http2_ver(ptr, left); left -= len; @@ -264,10 +270,8 @@ static const char * const protocols[] = { #ifndef CURL_DISABLE_RTSP "rtsp", #endif -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH) || defined(USE_LIBSSH2) "scp", -#endif -#ifdef USE_LIBSSH2 "sftp", #endif #if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ @@ -379,7 +383,7 @@ static curl_version_info_data version_info = { curl_version_info_data *curl_version_info(CURLversion stamp) { static bool initialized; -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH) || defined(USE_LIBSSH2) static char ssh_buffer[80]; #endif #ifdef USE_SSL @@ -395,7 +399,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp) #ifdef USE_SSL Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); version_info.ssl_version = ssl_buffer; - if(Curl_ssl->support_https_proxy) + if(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY) version_info.features |= CURL_VERSION_HTTPS_PROXY; else version_info.features &= ~CURL_VERSION_HTTPS_PROXY; @@ -431,9 +435,12 @@ curl_version_info_data *curl_version_info(CURLversion stamp) #endif /* _LIBICONV_VERSION */ #endif -#ifdef USE_LIBSSH2 +#if defined(USE_LIBSSH2) snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION); version_info.libssh_version = ssh_buffer; +#elif defined(USE_LIBSSH) + snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh/%s", CURL_LIBSSH_VERSION); + version_info.libssh_version = ssh_buffer; #endif #ifdef HAVE_BROTLI diff --git a/libs/libcurl/src/vtls/axtls.c b/libs/libcurl/src/vtls/axtls.c index 9294f49edc..5ed898b4f4 100644 --- a/libs/libcurl/src/vtls/axtls.c +++ b/libs/libcurl/src/vtls/axtls.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>. - * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -703,13 +703,7 @@ static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_axtls = { { CURLSSLBACKEND_AXTLS, "axtls" }, /* info */ - - 0, /* have_ca_path */ - 0, /* have_certinfo */ - 0, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - 0, /* support_https_proxy */ - + 0, /* no fancy stuff */ sizeof(struct ssl_backend_data), /* diff --git a/libs/libcurl/src/vtls/cyassl.c b/libs/libcurl/src/vtls/cyassl.c index e06522304b..20ce460e83 100644 --- a/libs/libcurl/src/vtls/cyassl.c +++ b/libs/libcurl/src/vtls/cyassl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -76,9 +76,7 @@ and that's a problem since options.h hasn't been included yet. */ #endif #endif -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #include "urldata.h" #include "sendf.h" @@ -189,8 +187,13 @@ cyassl_connect_step1(struct connectdata *conn, use_sni(TRUE); break; case CURL_SSLVERSION_TLSv1_0: +#ifdef WOLFSSL_ALLOW_TLSV10 req_method = TLSv1_client_method(); use_sni(TRUE); +#else + failf(data, "CyaSSL does not support TLS 1.0"); + return CURLE_NOT_BUILT_IN; +#endif break; case CURL_SSLVERSION_TLSv1_1: req_method = TLSv1_1_client_method(); @@ -201,8 +204,14 @@ cyassl_connect_step1(struct connectdata *conn, use_sni(TRUE); break; case CURL_SSLVERSION_TLSv1_3: +#ifdef WOLFSSL_TLS13 + req_method = wolfTLSv1_3_client_method(); + use_sni(TRUE); + break; +#else failf(data, "CyaSSL: TLS 1.3 is not yet supported"); return CURLE_SSL_CONNECT_ERROR; +#endif case CURL_SSLVERSION_SSLv3: #ifdef WOLFSSL_ALLOW_SSLV3 req_method = SSLv3_client_method(); @@ -247,7 +256,11 @@ cyassl_connect_step1(struct connectdata *conn, */ if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) && (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) && - (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1)) { + (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1) +#ifdef WOLFSSL_TLS13 + && (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_3) != 1) +#endif + ) { failf(data, "SSL: couldn't set the minimum protocol version"); return CURLE_SSL_CONNECT_ERROR; } @@ -958,7 +971,7 @@ static CURLcode Curl_cyassl_random(struct Curl_easy *data, return CURLE_OK; } -static void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ +static CURLcode Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum /* output */, size_t unused) @@ -968,6 +981,7 @@ static void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ InitSha256(&SHA256pw); Sha256Update(&SHA256pw, tmp, (word32)tmplen); Sha256Final(&SHA256pw, sha256sum); + return CURLE_OK; } static void *Curl_cyassl_get_internals(struct ssl_connect_data *connssl, @@ -980,15 +994,10 @@ static void *Curl_cyassl_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_cyassl = { { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */ - 0, /* have_ca_path */ - 0, /* have_certinfo */ #ifdef KEEP_PEER_CERT - 1, /* have_pinnedpubkey */ -#else - 0, /* have_pinnedpubkey */ + SSLSUPP_PINNEDPUBKEY | #endif - 1, /* have_ssl_ctx */ - 0, /* support_https_proxy */ + SSLSUPP_SSL_CTX, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/darwinssl.c b/libs/libcurl/src/vtls/darwinssl.c index 3169042240..45fe49d82b 100644 --- a/libs/libcurl/src/vtls/darwinssl.c +++ b/libs/libcurl/src/vtls/darwinssl.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>. - * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -39,9 +39,7 @@ #pragma clang diagnostic ignored "-Wtautological-pointer-compare" #endif /* __clang__ */ -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #include <Security/Security.h> /* For some reason, when building for iOS, the omnibus header above does @@ -1137,28 +1135,79 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath, raise linker errors when used on that cat for some reason. */ #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data, - NULL, NULL, &status)) { + NULL, NULL, &status)) { + CFArrayRef items = NULL; + + /* On iOS SecPKCS12Import will never add the client certificate to the + * Keychain. + * + * It gives us back a SecIdentityRef that we can use directly. */ +#if CURL_BUILD_IOS const void *cKeys[] = {kSecImportExportPassphrase}; const void *cValues[] = {password}; CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues, password ? 1L : 0L, NULL, NULL); - CFArrayRef items = NULL; - /* Here we go: */ - status = SecPKCS12Import(pkcs_data, options, &items); - if(status == errSecSuccess && items && CFArrayGetCount(items)) { - CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L); - const void *temp_identity = CFDictionaryGetValue(identity_and_trust, - kSecImportItemIdentity); + if(options != NULL) { + status = SecPKCS12Import(pkcs_data, options, &items); + CFRelease(options); + } + + + /* On macOS SecPKCS12Import will always add the client certificate to + * the Keychain. + * + * As this doesn't match iOS, and apps may not want to see their client + * certificate saved in the the user's keychain, we use SecItemImport + * with a NULL keychain to avoid importing it. + * + * This returns a SecCertificateRef from which we can construct a + * SecIdentityRef. + */ +#elif CURL_BUILD_MAC_10_7 + SecItemImportExportKeyParameters keyParams; + SecExternalFormat inputFormat = kSecFormatPKCS12; + SecExternalItemType inputType = kSecItemTypeCertificate; - /* Retain the identity; we don't care about any other data... */ - CFRetain(temp_identity); - *out_cert_and_key = (SecIdentityRef)temp_identity; + memset(&keyParams, 0x00, sizeof(keyParams)); + keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; + keyParams.passphrase = password; + + status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType, + 0, &keyParams, NULL, &items); +#endif + + + /* Extract the SecIdentityRef */ + if(status == errSecSuccess && items && CFArrayGetCount(items)) { + CFIndex i, count; + count = CFArrayGetCount(items); + + for(i = 0; i < count; i++) { + CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i); + CFTypeID itemID = CFGetTypeID(item); + + if(itemID == CFDictionaryGetTypeID()) { + CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue( + (CFDictionaryRef) item, + kSecImportItemIdentity); + CFRetain(identity); + *out_cert_and_key = (SecIdentityRef) identity; + break; + } +#if CURL_BUILD_MAC_10_7 + else if(itemID == SecCertificateGetTypeID()) { + status = SecIdentityCreateWithCertificate(NULL, + (SecCertificateRef) item, + out_cert_and_key); + break; + } +#endif + } } if(items) CFRelease(items); - CFRelease(options); CFRelease(pkcs_data); } #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ @@ -1342,7 +1391,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, #endif /* CURL_BUILD_MAC */ #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLCreateContext != NULL) { /* use the newer API if avaialble */ + if(SSLCreateContext != NULL) { /* use the newer API if available */ if(BACKEND->ssl_ctx) CFRelease(BACKEND->ssl_ctx); BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); @@ -2845,13 +2894,14 @@ static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ return CURLE_OK; } -static void Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */ +static CURLcode Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum, /* output */ size_t sha256len) { assert(sha256len >= CURL_SHA256_DIGEST_LENGTH); (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum); + return CURLE_OK; } static bool Curl_darwinssl_false_start(void) @@ -2979,15 +3029,11 @@ static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_darwinssl = { { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */ - 0, /* have_ca_path */ - 0, /* have_certinfo */ #ifdef DARWIN_SSL_PINNEDPUBKEY - 1, /* have_pinnedpubkey */ + SSLSUPP_PINNEDPUBKEY, #else - 0, /* have_pinnedpubkey */ + 0, #endif /* DARWIN_SSL_PINNEDPUBKEY */ - 0, /* have_ssl_ctx */ - 0, /* support_https_proxy */ sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c index de496dd125..b0856cdf44 100644 --- a/libs/libcurl/src/vtls/gskit.c +++ b/libs/libcurl/src/vtls/gskit.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -61,9 +61,7 @@ #endif -#ifdef HAVE_LIMITS_H -# include <limits.h> -#endif +#include <limits.h> #include <curl/curl.h> #include "urldata.h" @@ -1355,12 +1353,8 @@ static void *Curl_gskit_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_gskit = { { CURLSSLBACKEND_GSKIT, "gskit" }, /* info */ - 0, /* have_ca_path */ - 1, /* have_certinfo */ - 0, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - /* TODO: convert to 1 and fix test #1014 (if need) */ - 0, /* support_https_proxy */ + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c index 30b255b81a..207b0fd1bd 100644 --- a/libs/libcurl/src/vtls/gtls.c +++ b/libs/libcurl/src/vtls/gtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -60,15 +60,6 @@ /* The last #include file should be: */ #include "memdebug.h" -#ifndef GNUTLS_POINTER_TO_SOCKET_CAST -#define GNUTLS_POINTER_TO_SOCKET_CAST(p) \ - ((curl_socket_t) ((char *)(p) - (char *)NULL)) -#endif -#ifndef GNUTLS_SOCKET_TO_POINTER_CAST -#define GNUTLS_SOCKET_TO_POINTER_CAST(s) \ - ((void *) ((char *)NULL + (s))) -#endif - /* Enable GnuTLS debugging by defining GTLSDEBUG */ /*#define GTLSDEBUG */ @@ -161,7 +152,8 @@ static int gtls_mapped_sockerrno(void) static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) { - ssize_t ret = swrite(GNUTLS_POINTER_TO_SOCKET_CAST(s), buf, len); + curl_socket_t sock = *(curl_socket_t *)s; + ssize_t ret = swrite(sock, buf, len); #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) if(ret < 0) gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); @@ -171,7 +163,8 @@ static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len) { - ssize_t ret = sread(GNUTLS_POINTER_TO_SOCKET_CAST(s), buf, len); + curl_socket_t sock = *(curl_socket_t *)s; + ssize_t ret = sread(sock, buf, len); #if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) if(ret < 0) gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); @@ -857,7 +850,7 @@ gtls_connect_step1(struct connectdata *conn, } else { /* file descriptor for the socket */ - transport_ptr = GNUTLS_SOCKET_TO_POINTER_CAST(conn->sock[sockindex]); + transport_ptr = &conn->sock[sockindex]; gnutls_transport_push = Curl_gtls_push; gnutls_transport_pull = Curl_gtls_pull; } @@ -1770,7 +1763,7 @@ static CURLcode Curl_gtls_md5sum(unsigned char *tmp, /* input */ return CURLE_OK; } -static void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ +static CURLcode Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum, /* output */ size_t sha256len) @@ -1787,6 +1780,7 @@ static void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ memcpy(sha256sum, gcry_md_read(SHA256pw, 0), sha256len); gcry_md_close(SHA256pw); #endif + return CURLE_OK; } static bool Curl_gtls_cert_status_request(void) @@ -1808,11 +1802,10 @@ static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_gnutls = { { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */ - 1, /* have_ca_path */ - 1, /* have_certinfo */ - 1, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - 1, /* support_https_proxy */ + SSLSUPP_CA_PATH | + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_HTTPS_PROXY, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c index 28251a3888..d7759dc849 100644 --- a/libs/libcurl/src/vtls/mbedtls.c +++ b/libs/libcurl/src/vtls/mbedtls.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> - * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -815,7 +815,7 @@ static void Curl_mbedtls_session_free(void *ptr) static size_t Curl_mbedtls_version(char *buffer, size_t size) { unsigned int version = mbedtls_version_get_number(); - return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24, + return snprintf(buffer, size, "mbedTLS/%u.%u.%u", version>>24, (version>>16)&0xff, (version>>8)&0xff); } @@ -1023,13 +1023,20 @@ static bool Curl_mbedtls_data_pending(const struct connectdata *conn, return mbedtls_ssl_get_bytes_avail(&BACKEND->ssl) != 0; } -static void Curl_mbedtls_sha256sum(const unsigned char *input, +static CURLcode Curl_mbedtls_sha256sum(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256len UNUSED_PARAM) { (void)sha256len; +#if MBEDTLS_VERSION_NUMBER < 0x02070000 mbedtls_sha256(input, inputlen, sha256sum, 0); +#else + /* returns 0 on success, otherwise failure */ + if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0) + return CURLE_BAD_FUNCTION_ARGUMENT; +#endif + return CURLE_OK; } static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl, @@ -1042,11 +1049,9 @@ static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_mbedtls = { { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */ - 1, /* have_ca_path */ - 0, /* have_certinfo */ - 1, /* have_pinnedpubkey */ - 1, /* have_ssl_ctx */ - 0, /* support_https_proxy */ + SSLSUPP_CA_PATH | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_SSL_CTX, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index a3ef37a12c..7cd450cda9 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -440,7 +440,17 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl, PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval)); } - obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE); + /* PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because + * PK11_DestroyGenericObject() does not release resources allocated by + * PK11_CreateGenericObject() early enough. */ + obj = +#ifdef HAVE_PK11_CREATEMANAGEDGENERICOBJECT + PK11_CreateManagedGenericObject +#else + PK11_CreateGenericObject +#endif + (slot, attrs, attr_cnt, PR_FALSE); + PK11_FreeSlot(slot); if(!obj) return result; @@ -2304,7 +2314,7 @@ static CURLcode Curl_nss_md5sum(unsigned char *tmp, /* input */ return CURLE_OK; } -static void Curl_nss_sha256sum(const unsigned char *tmp, /* input */ +static CURLcode Curl_nss_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum, /* output */ size_t sha256len) @@ -2315,6 +2325,8 @@ static void Curl_nss_sha256sum(const unsigned char *tmp, /* input */ PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen)); PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len)); PK11_DestroyContext(SHA256pw, PR_TRUE); + + return CURLE_OK; } static bool Curl_nss_cert_status_request(void) @@ -2345,11 +2357,10 @@ static void *Curl_nss_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_nss = { { CURLSSLBACKEND_NSS, "nss" }, /* info */ - 1, /* have_ca_path */ - 1, /* have_certinfo */ - 1, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - 1, /* support_https_proxy */ + SSLSUPP_CA_PATH | + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_HTTPS_PROXY, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 7b04edfd6b..f6a4bd3fbf 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -34,9 +34,7 @@ #ifdef USE_OPENSSL -#ifdef HAVE_LIMITS_H #include <limits.h> -#endif #include "urldata.h" #include "sendf.h" @@ -68,12 +66,7 @@ #include <openssl/rsa.h> #include <openssl/bio.h> #include <openssl/buffer.h> - -#ifndef OPENSSL_IS_BORINGSSL -/* BoringSSL does not support PKCS12 */ -#define HAVE_PKCS12_SUPPORT 1 #include <openssl/pkcs12.h> -#endif #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) #include <openssl/ocsp.h> @@ -111,13 +104,22 @@ #endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \ - !defined(LIBRESSL_VERSION_NUMBER) + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x20700000L) #define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER #define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */ #define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */ #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ #define CONST_EXTS const #define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1 + +/* funny typecast define due to difference in API */ +#ifdef LIBRESSL_VERSION_NUMBER +#define ARG2_X509_signature_print (X509_ALGOR *) +#else +#define ARG2_X509_signature_print +#endif + #else /* For OpenSSL before 1.1.0 */ #define ASN1_STRING_get0_data(x) ASN1_STRING_data(x) @@ -135,7 +137,8 @@ static unsigned long OpenSSL_version_num(void) #endif #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ - !defined(LIBRESSL_VERSION_NUMBER) + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x20700000L) #define HAVE_X509_GET0_SIGNATURE 1 #endif @@ -154,7 +157,7 @@ static unsigned long OpenSSL_version_num(void) * Whether SSL_CTX_set_keylog_callback is available. * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287 * BoringSSL: supported since d28f59c27bac (committed 2015-11-19) - * LibreSSL: unsupported in at least 2.5.1 (explicitly check for it since it + * LibreSSL: unsupported in at least 2.7.2 (explicitly check for it since it * lies and pretends to be OpenSSL 2.0.0). */ #if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \ @@ -182,6 +185,8 @@ static unsigned long OpenSSL_version_num(void) "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH" #endif +#define ENABLE_SSLKEYLOGFILE + #ifdef ENABLE_SSLKEYLOGFILE typedef struct ssl_tap_state { int master_key_length; @@ -264,11 +269,13 @@ static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state) if(!session || !keylog_file_fp) return; -#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !(defined(LIBRESSL_VERSION_NUMBER) && \ + LIBRESSL_VERSION_NUMBER < 0x20700000L) /* ssl->s3 is not checked in openssl 1.1.0-pre6, but let's assume that * we have a valid SSL context if we have a non-NULL session. */ SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE); - master_key_length = + master_key_length = (int) SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH); #else if(ssl->s3 && session->master_key_length > 0) { @@ -654,19 +661,28 @@ int cert_stuff(struct connectdata *conn, case SSL_FILETYPE_PKCS12: { -#ifdef HAVE_PKCS12_SUPPORT - FILE *f; - PKCS12 *p12; + BIO *fp = NULL; + PKCS12 *p12 = NULL; EVP_PKEY *pri; STACK_OF(X509) *ca = NULL; - f = fopen(cert_file, "rb"); - if(!f) { + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + return 0; + } + + if(BIO_read_filename(fp, cert_file) <= 0) { failf(data, "could not open PKCS12 file '%s'", cert_file); + BIO_free(fp); return 0; } - p12 = d2i_PKCS12_fp(f, NULL); - fclose(f); + p12 = d2i_PKCS12_bio(fp, NULL); + BIO_free(fp); if(!p12) { failf(data, "error reading PKCS12 file '%s'", cert_file); @@ -741,10 +757,6 @@ int cert_stuff(struct connectdata *conn, if(!cert_done) return 0; /* failure! */ break; -#else - failf(data, "file type P12 for certificate not supported"); - return 0; -#endif } default: failf(data, "not supported file type '%s' for certificate", cert_type); @@ -914,7 +926,7 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) static int Curl_ossl_init(void) { #ifdef ENABLE_SSLKEYLOGFILE - const char *keylog_file_name; + char *keylog_file_name; #endif OPENSSL_load_builtin_modules(); @@ -954,14 +966,22 @@ static int Curl_ossl_init(void) #endif #ifdef ENABLE_SSLKEYLOGFILE - keylog_file_name = curl_getenv("SSLKEYLOGFILE"); - if(keylog_file_name && !keylog_file_fp) { - keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); - if(keylog_file_fp) { - if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) { - fclose(keylog_file_fp); - keylog_file_fp = NULL; + if(!keylog_file_fp) { + keylog_file_name = curl_getenv("SSLKEYLOGFILE"); + if(keylog_file_name) { + keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT); + if(keylog_file_fp) { +#ifdef WIN32 + if(setvbuf(keylog_file_fp, NULL, _IONBF, 0)) +#else + if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) +#endif + { + fclose(keylog_file_fp); + keylog_file_fp = NULL; + } } + Curl_safefree(keylog_file_name); } } #endif @@ -1313,6 +1333,51 @@ static void Curl_ossl_close_all(struct Curl_easy *data) /* ====================================================== */ +/* + * Match subjectAltName against the host name. This requires a conversion + * in CURL_DOES_CONVERSIONS builds. + */ +static bool subj_alt_hostcheck(struct Curl_easy *data, + const char *match_pattern, const char *hostname, + const char *dispname) +#ifdef CURL_DOES_CONVERSIONS +{ + bool res = FALSE; + + /* Curl_cert_hostcheck uses host encoding, but we get ASCII from + OpenSSl. + */ + char *match_pattern2 = strdup(match_pattern); + + if(match_pattern2) { + if(Curl_convert_from_network(data, match_pattern2, + strlen(match_pattern2)) == CURLE_OK) { + if(Curl_cert_hostcheck(match_pattern2, hostname)) { + res = TRUE; + infof(data, + " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + dispname, match_pattern2); + } + } + free(match_pattern2); + } + else { + failf(data, + "SSL: out of memory when allocating temporary for subjectAltName"); + } + return res; +} +#else +{ + if(Curl_cert_hostcheck(match_pattern, hostname)) { + infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + dispname, match_pattern); + return TRUE; + } + return FALSE; +} +#endif + /* Quote from RFC2818 section 3.1 "Server Identity" @@ -1412,11 +1477,8 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) if((altlen == strlen(altptr)) && /* if this isn't true, there was an embedded zero in the name string and we cannot match it. */ - Curl_cert_hostcheck(altptr, hostname)) { + subj_alt_hostcheck(data, altptr, hostname, dispname)) { dnsmatched = TRUE; - infof(data, - " subjectAltName: host \"%s\" matched cert's \"%s\"\n", - dispname, altptr); } break; @@ -1727,13 +1789,40 @@ static const char *ssl_msg_type(int ssl_ver, int msg) case SSL3_MT_CERTIFICATE_STATUS: return "Certificate Status"; #endif +#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS + case SSL3_MT_ENCRYPTED_EXTENSIONS: + return "Encrypted Extensions"; +#endif +#ifdef SSL3_MT_END_OF_EARLY_DATA + case SSL3_MT_END_OF_EARLY_DATA: + return "End of early data"; +#endif +#ifdef SSL3_MT_KEY_UPDATE + case SSL3_MT_KEY_UPDATE: + return "Key update"; +#endif +#ifdef SSL3_MT_NEXT_PROTO + case SSL3_MT_NEXT_PROTO: + return "Next protocol"; +#endif +#ifdef SSL3_MT_MESSAGE_HASH + case SSL3_MT_MESSAGE_HASH: + return "Message hash"; +#endif } } return "Unknown"; } -static const char *tls_rt_type(int type) +static const char *tls_rt_type(int type, const void *buf, size_t buflen) { + (void)buf; + (void)buflen; +#ifdef SSL3_RT_INNER_CONTENT_TYPE + if(type == SSL3_RT_INNER_CONTENT_TYPE && buf && buflen >= 1) + type = *(unsigned char *)buf; +#endif + switch(type) { #ifdef SSL3_RT_HEADER case SSL3_RT_HEADER: @@ -1761,10 +1850,7 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type, void *userp) { struct Curl_easy *data; - const char *msg_name, *tls_rt_name; - char ssl_buf[1024]; char unknown[32]; - int msg_type, txt_len; const char *verstr = NULL; struct connectdata *conn = userp; @@ -1812,6 +1898,10 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type, } if(ssl_ver) { + const char *msg_name, *tls_rt_name; + char ssl_buf[1024]; + int msg_type, txt_len; + /* the info given when the version is zero is not that useful for us */ ssl_ver >>= 8; /* check the upper 8 bits only below */ @@ -1821,17 +1911,28 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type, * is at 'buf[0]'. */ if(ssl_ver == SSL3_VERSION_MAJOR && content_type) - tls_rt_name = tls_rt_type(content_type); + tls_rt_name = tls_rt_type(content_type, buf, len); else tls_rt_name = ""; - msg_type = *(char *)buf; - msg_name = ssl_msg_type(ssl_ver, msg_type); +#ifdef SSL3_RT_INNER_CONTENT_TYPE + if(content_type == SSL3_RT_INNER_CONTENT_TYPE) { + msg_type = 0; + msg_name = "[no content]"; + } + else +#endif + { + msg_type = *(char *)buf; + msg_name = ssl_msg_type(ssl_ver, msg_type); + } txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n", verstr, direction?"OUT":"IN", tls_rt_name, msg_name, msg_type); - Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL); + if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) { + Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL); + } } Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : @@ -2084,8 +2185,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) case CURL_SSLVERSION_TLSv1_2: case CURL_SSLVERSION_TLSv1_3: /* it will be handled later with the context options */ -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ - !defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) req_method = TLS_client_method(); #else req_method = SSLv23_client_method(); @@ -2415,8 +2515,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */ #if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK) - if(keylog_file) { - SSL_CTX_set_keylog_callback(connssl->ctx, ossl_keylog_callback); + if(keylog_file_fp) { + SSL_CTX_set_keylog_callback(BACKEND->ctx, ossl_keylog_callback); } #endif @@ -2802,7 +2902,7 @@ static CURLcode get_cert_chain(struct connectdata *conn, ASN1_STRING *a = ASN1_STRING_new(); if(a) { X509_get0_signature(&psig, &palg, x); - X509_signature_print(mem, palg, a); + X509_signature_print(mem, ARG2_X509_signature_print palg, a); ASN1_STRING_free(a); if(palg) { @@ -3037,7 +3137,8 @@ static CURLcode servercert(struct connectdata *conn, long lerr, len; struct Curl_easy *data = conn->data; X509 *issuer; - FILE *fp; + BIO *fp = NULL; + char error_buffer[256]=""; char buffer[2048]; const char *ptr; long * const certverifyresult = SSL_IS_PROXY() ? @@ -3048,8 +3149,20 @@ static CURLcode servercert(struct connectdata *conn, /* we've been asked to gather certificate info! */ (void)get_cert_chain(conn, connssl); + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { + failf(data, + "BIO_new return NULL, " OSSL_PACKAGE + " error %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer)) ); + BIO_free(mem); + return 0; + } + BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle); if(!BACKEND->server_cert) { + BIO_free(fp); BIO_free(mem); if(!strict) return CURLE_OK; @@ -3079,6 +3192,7 @@ static CURLcode servercert(struct connectdata *conn, if(SSL_CONN_CONFIG(verifyhost)) { result = verifyhost(conn, BACKEND->server_cert); if(result) { + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return result; @@ -3100,35 +3214,35 @@ static CURLcode servercert(struct connectdata *conn, /* e.g. match issuer name with provided issuer certificate */ if(SSL_SET_OPTION(issuercert)) { - fp = fopen(SSL_SET_OPTION(issuercert), FOPEN_READTEXT); - if(!fp) { + if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { if(strict) failf(data, "SSL: Unable to open issuer cert (%s)", SSL_SET_OPTION(issuercert)); + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } - issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL); + issuer = PEM_read_bio_X509(fp, NULL, ZERO_NULL, NULL); if(!issuer) { if(strict) failf(data, "SSL: Unable to read issuer cert (%s)", SSL_SET_OPTION(issuercert)); - X509_free(BACKEND->server_cert); + BIO_free(fp); X509_free(issuer); - fclose(fp); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } - fclose(fp); - if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) { if(strict) failf(data, "SSL: Certificate issuer check failed (%s)", SSL_SET_OPTION(issuercert)); - X509_free(BACKEND->server_cert); + BIO_free(fp); X509_free(issuer); + X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return CURLE_SSL_ISSUER_ERROR; } @@ -3163,6 +3277,7 @@ static CURLcode servercert(struct connectdata *conn, if(SSL_CONN_CONFIG(verifystatus)) { result = verifystatus(conn, connssl); if(result) { + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; return result; @@ -3182,6 +3297,7 @@ static CURLcode servercert(struct connectdata *conn, failf(data, "SSL: public key does not match pinned public key!"); } + BIO_free(fp); X509_free(BACKEND->server_cert); BACKEND->server_cert = NULL; connssl->connecting_state = ssl_connect_done; @@ -3393,12 +3509,13 @@ static bool Curl_ossl_data_pending(const struct connectdata *conn, { const struct ssl_connect_data *connssl = &conn->ssl[connindex]; const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex]; - if(BACKEND->handle) - /* SSL is in use */ - return (0 != SSL_pending(BACKEND->handle) || - (proxyssl->backend->handle && - 0 != SSL_pending(proxyssl->backend->handle))) ? - TRUE : FALSE; + + if(connssl->backend->handle && SSL_pending(connssl->backend->handle)) + return TRUE; + + if(proxyssl->backend->handle && SSL_pending(proxyssl->backend->handle)) + return TRUE; + return FALSE; } @@ -3581,25 +3698,34 @@ static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */ unsigned char *md5sum /* output */, size_t unused) { - MD5_CTX MD5pw; - (void)unused; - MD5_Init(&MD5pw); - MD5_Update(&MD5pw, tmp, tmplen); - MD5_Final(md5sum, &MD5pw); + EVP_MD_CTX *mdctx; + unsigned int len = 0; + (void) unused; + + mdctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdctx, EVP_md5(), NULL); + EVP_DigestUpdate(mdctx, tmp, tmplen); + EVP_DigestFinal_ex(mdctx, md5sum, &len); + EVP_MD_CTX_destroy(mdctx); return CURLE_OK; } #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) -static void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ +static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum /* output */, size_t unused) { - SHA256_CTX SHA256pw; - (void)unused; - SHA256_Init(&SHA256pw); - SHA256_Update(&SHA256pw, tmp, tmplen); - SHA256_Final(sha256sum, &SHA256pw); + EVP_MD_CTX *mdctx; + unsigned int len = 0; + (void) unused; + + mdctx = EVP_MD_CTX_create(); + EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); + EVP_DigestUpdate(mdctx, tmp, tmplen); + EVP_DigestFinal_ex(mdctx, sha256sum, &len); + EVP_MD_CTX_destroy(mdctx); + return CURLE_OK; } #endif @@ -3624,11 +3750,11 @@ static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_openssl = { { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ - 1, /* have_ca_path */ - 1, /* have_certinfo */ - 1, /* have_pinnedpubkey */ - 1, /* have_ssl_ctx */ - 1, /* support_https_proxy */ + SSLSUPP_CA_PATH | + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_SSL_CTX | + SSLSUPP_HTTPS_PROXY, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/polarssl.c b/libs/libcurl/src/vtls/polarssl.c index df29fa945e..604cb4c862 100644 --- a/libs/libcurl/src/vtls/polarssl.c +++ b/libs/libcurl/src/vtls/polarssl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> * * This software is licensed as described in the file COPYING, which @@ -620,12 +620,10 @@ polarssl_connect_step3(struct connectdata *conn, ssl_session *our_ssl_sessionid; void *old_ssl_sessionid = NULL; - our_ssl_sessionid = malloc(sizeof(ssl_session)); + our_ssl_sessionid = calloc(1, sizeof(ssl_session)); if(!our_ssl_sessionid) return CURLE_OUT_OF_MEMORY; - memset(our_ssl_sessionid, 0, sizeof(ssl_session)); - ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid); if(ret) { failf(data, "ssl_get_session returned -0x%x", -ret); @@ -882,13 +880,14 @@ static bool Curl_polarssl_data_pending(const struct connectdata *conn, return ssl_get_bytes_avail(&BACKEND->ssl) != 0; } -static void Curl_polarssl_sha256sum(const unsigned char *input, +static CURLcode Curl_polarssl_sha256sum(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256len UNUSED_PARAM) { (void)sha256len; sha256(input, inputlen, sha256sum, 0); + return CURLE_OK; } static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl, @@ -901,11 +900,8 @@ static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_polarssl = { { CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */ - 1, /* have_ca_path */ - 0, /* have_certinfo */ - 1, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - 0, /* support_https_proxy */ + SSLSUPP_CA_PATH | + SSLSUPP_PINNEDPUBKEY, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index 85c64cf446..2cfd5c19f5 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -7,7 +7,7 @@ * * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> - * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -42,13 +42,12 @@ #ifdef USE_SCHANNEL +#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS + #ifndef USE_WINDOWS_SSPI # error "Can't compile SCHANNEL support without SSPI." #endif -#include <schnlsp.h> -#include <schannel.h> -#include "curl_sspi.h" #include "schannel.h" #include "vtls.h" #include "sendf.h" @@ -61,7 +60,6 @@ #include "x509asn1.h" #include "curl_printf.h" #include "system_win32.h" -#include "hostcheck.h" /* The last #include file should be: */ #include "curl_memory.h" @@ -92,6 +90,12 @@ #endif #endif +#ifdef UNICODE +#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_W +#else +#define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_A +#endif + #ifndef SP_PROT_SSL2_CLIENT #define SP_PROT_SSL2_CLIENT 0x00000008 #endif @@ -124,50 +128,25 @@ #define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096 #define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024 +#define CERT_THUMBPRINT_STR_LEN 40 +#define CERT_THUMBPRINT_DATA_LEN 20 + /* Uncomment to force verbose output * #define infof(x, y, ...) printf(y, __VA_ARGS__) * #define failf(x, y, ...) printf(y, __VA_ARGS__) */ -/* Structs to store Schannel handles */ -struct curl_schannel_cred { - CredHandle cred_handle; - TimeStamp time_stamp; - int refcount; -}; - -struct curl_schannel_ctxt { - CtxtHandle ctxt_handle; - TimeStamp time_stamp; -}; - -struct ssl_backend_data { - struct curl_schannel_cred *cred; - struct curl_schannel_ctxt *ctxt; - SecPkgContext_StreamSizes stream_sizes; - size_t encdata_length, decdata_length; - size_t encdata_offset, decdata_offset; - unsigned char *encdata_buffer, *decdata_buffer; - /* encdata_is_incomplete: if encdata contains only a partial record that - can't be decrypted without another Curl_read_plain (that is, status is - SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes - more bytes into encdata then set this back to false. */ - bool encdata_is_incomplete; - unsigned long req_flags, ret_flags; - CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ - bool recv_sspi_close_notify; /* true if connection closed by close_notify */ - bool recv_connection_closed; /* true if connection closed, regardless how */ - bool use_alpn; /* true if ALPN is used for this connection */ -}; +#ifndef CALG_SHA_256 +# define CALG_SHA_256 0x0000800c +#endif #define BACKEND connssl->backend static Curl_recv schannel_recv; static Curl_send schannel_send; -#ifdef _WIN32_WCE -static CURLcode verify_certificate(struct connectdata *conn, int sockindex); -#endif +static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, + const char *pinnedpubkey); static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType, void *BufDataPtr, unsigned long BufByteSize) @@ -221,6 +200,56 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn) } static CURLcode +get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, + TCHAR **thumbprint) +{ + TCHAR *sep; + size_t store_name_len; + + sep = _tcschr(path, TEXT('\\')); + if(sep == NULL) + return CURLE_SSL_CONNECT_ERROR; + + store_name_len = sep - path; + + if(_tcsnccmp(path, TEXT("CurrentUser"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_CURRENT_USER; + else if(_tcsnccmp(path, TEXT("LocalMachine"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE; + else if(_tcsnccmp(path, TEXT("CurrentService"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_CURRENT_SERVICE; + else if(_tcsnccmp(path, TEXT("Services"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_SERVICES; + else if(_tcsnccmp(path, TEXT("Users"), store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_USERS; + else if(_tcsnccmp(path, TEXT("CurrentUserGroupPolicy"), + store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY; + else if(_tcsnccmp(path, TEXT("LocalMachineGroupPolicy"), + store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY; + else if(_tcsnccmp(path, TEXT("LocalMachineEnterprise"), + store_name_len) == 0) + *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE; + else + return CURLE_SSL_CONNECT_ERROR; + + *store_path = sep + 1; + + sep = _tcschr(*store_path, TEXT('\\')); + if(sep == NULL) + return CURLE_SSL_CONNECT_ERROR; + + *sep = 0; + + *thumbprint = sep + 1; + if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) + return CURLE_SSL_CONNECT_ERROR; + + return CURLE_OK; +} + +static CURLcode schannel_connect_step1(struct connectdata *conn, int sockindex) { ssize_t written = -1; @@ -234,6 +263,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) unsigned char alpn_buffer[128]; #endif SCHANNEL_CRED schannel_cred; + PCCERT_CONTEXT client_certs[1] = { NULL }; SECURITY_STATUS sspi_status = SEC_E_OK; struct curl_schannel_cred *old_cred = NULL; struct in_addr addr; @@ -268,6 +298,26 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) BACKEND->use_alpn = false; #endif +#ifdef _WIN32_WCE + /* certificate validation on CE doesn't seem to work right; we'll + * do it following a more manual process. */ + BACKEND->use_manual_cred_validation = true; +#else + if(SSL_CONN_CONFIG(CAfile)) { + if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + BACKEND->use_manual_cred_validation = true; + } + else { + failf(data, "schannel: this version of Windows is too old to support " + "certificate verification via CA bundle file."); + return CURLE_SSL_CACERT_BADFILE; + } + } + else + BACKEND->use_manual_cred_validation = false; +#endif + BACKEND->cred = NULL; /* check for an existing re-usable credential handle */ @@ -291,26 +341,23 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; if(conn->ssl_config.verifypeer) { -#ifdef _WIN32_WCE - /* certificate validation on CE doesn't seem to work right; we'll - do it following a more manual process. */ - schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | - SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; -#else - schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; + if(BACKEND->use_manual_cred_validation) + schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION; + else + schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; + /* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */ - if(data->set.ssl.no_revoke) + if(data->set.ssl.no_revoke) { schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - else - schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; -#endif - if(data->set.ssl.no_revoke) + SCH_CRED_IGNORE_REVOCATION_OFFLINE; + infof(data, "schannel: disabled server certificate revocation " "checks\n"); - else + } + else { + schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; infof(data, "schannel: checking server certificate revocation\n"); + } } else { schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | @@ -354,14 +401,70 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) return CURLE_SSL_CONNECT_ERROR; } + /* client certificate */ + if(data->set.ssl.cert) { + DWORD cert_store_name; + TCHAR *cert_store_path; + TCHAR *cert_thumbprint_str; + CRYPT_HASH_BLOB cert_thumbprint; + BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN]; + HCERTSTORE cert_store; + + TCHAR *cert_path = Curl_convert_UTF8_to_tchar(data->set.ssl.cert); + if(!cert_path) + return CURLE_OUT_OF_MEMORY; + + result = get_cert_location(cert_path, &cert_store_name, + &cert_store_path, &cert_thumbprint_str); + if(result != CURLE_OK) { + Curl_unicodefree(cert_path); + return result; + } + + cert_store = CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, + (HCRYPTPROV)NULL, + cert_store_name, cert_store_path); + if(!cert_store) { + Curl_unicodefree(cert_path); + return CURLE_SSL_CONNECT_ERROR; + } + + cert_thumbprint.pbData = cert_thumbprint_data; + cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; + + if(!CryptStringToBinary(cert_thumbprint_str, CERT_THUMBPRINT_STR_LEN, + CRYPT_STRING_HEX, + cert_thumbprint_data, &cert_thumbprint.cbData, + NULL, NULL)) { + Curl_unicodefree(cert_path); + return CURLE_SSL_CONNECT_ERROR; + } + + client_certs[0] = CertFindCertificateInStore( + cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, + CERT_FIND_HASH, &cert_thumbprint, NULL); + + Curl_unicodefree(cert_path); + + if(client_certs[0]) { + schannel_cred.cCreds = 1; + schannel_cred.paCred = client_certs; + } + + CertCloseStore(cert_store, 0); + } + /* allocate memory for the re-usable credential handle */ BACKEND->cred = (struct curl_schannel_cred *) - malloc(sizeof(struct curl_schannel_cred)); + calloc(1, sizeof(struct curl_schannel_cred)); if(!BACKEND->cred) { failf(data, "schannel: unable to allocate memory"); + + if(client_certs[0]) + CertFreeCertificateContext(client_certs[0]); + return CURLE_OUT_OF_MEMORY; } - memset(BACKEND->cred, 0, sizeof(struct curl_schannel_cred)); BACKEND->cred->refcount = 1; /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx @@ -373,6 +476,9 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) &BACKEND->cred->cred_handle, &BACKEND->cred->time_stamp); + if(client_certs[0]) + CertFreeCertificateContext(client_certs[0]); + if(sspi_status != SEC_E_OK) { if(sspi_status == SEC_E_WRONG_PRINCIPAL) failf(data, "schannel: SNI or certificate check failed: %s", @@ -438,8 +544,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur); InitSecBufferDesc(&inbuf_desc, &inbuf, 1); } - else - { + else { InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&inbuf_desc, &inbuf, 1); } @@ -459,12 +564,11 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) /* allocate memory for the security context handle */ BACKEND->ctxt = (struct curl_schannel_ctxt *) - malloc(sizeof(struct curl_schannel_ctxt)); + calloc(1, sizeof(struct curl_schannel_ctxt)); if(!BACKEND->ctxt) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } - memset(BACKEND->ctxt, 0, sizeof(struct curl_schannel_ctxt)); host_name = Curl_convert_UTF8_to_tchar(hostname); if(!host_name) @@ -542,6 +646,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) bool doread; char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; + const char *pubkey_ptr; doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; @@ -761,12 +866,20 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) infof(data, "schannel: SSL/TLS handshake complete\n"); } -#ifdef _WIN32_WCE - /* Windows CE doesn't do any server certificate validation. - We have to do it manually. */ - if(conn->ssl_config.verifypeer) + pubkey_ptr = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : + data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + if(pubkey_ptr) { + result = pkp_pin_peer_pubkey(conn, sockindex, pubkey_ptr); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; + } + } + + if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) { return verify_certificate(conn, sockindex); -#endif + } return CURLE_OK; } @@ -1669,145 +1782,136 @@ static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM, return CURLE_OK; } -#ifdef _WIN32_WCE -static CURLcode verify_certificate(struct connectdata *conn, int sockindex) +static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, + const char *pinnedpubkey) { SECURITY_STATUS status; struct Curl_easy *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - CURLcode result = CURLE_OK; CERT_CONTEXT *pCertContextServer = NULL; - const CERT_CHAIN_CONTEXT *pChainContext = NULL; - const char * const conn_hostname = SSL_IS_PROXY() ? - conn->http_proxy.host.name : - conn->host.name; + const char *x509_der; + DWORD x509_der_len; + curl_X509certificate x509_parsed; + curl_asn1Element *pubkey; - status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); + /* Result is returned to caller */ + CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - if((status != SEC_E_OK) || (pCertContextServer == NULL)) { - failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(conn, status)); - result = CURLE_PEER_FAILED_VERIFICATION; - } + /* if a path wasn't specified, don't pin */ + if(!pinnedpubkey) + return CURLE_OK; - if(result == CURLE_OK) { - CERT_CHAIN_PARA ChainPara; - memset(&ChainPara, 0, sizeof(ChainPara)); - ChainPara.cbSize = sizeof(ChainPara); - - if(!CertGetCertificateChain(NULL, - pCertContextServer, - NULL, - pCertContextServer->hCertStore, - &ChainPara, - (data->set.ssl.no_revoke ? 0 : - CERT_CHAIN_REVOCATION_CHECK_CHAIN), - NULL, - &pChainContext)) { - failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_sspi_strerror(conn, GetLastError())); - pChainContext = NULL; - result = CURLE_PEER_FAILED_VERIFICATION; - } + do { + status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); - if(result == CURLE_OK) { - CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; - DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED); - dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; - if(dwTrustErrorMask) { - if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_REVOKED"); - else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_PARTIAL_CHAIN"); - else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_UNTRUSTED_ROOT"); - else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_NOT_TIME_VALID"); - else - failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x", - dwTrustErrorMask); - result = CURLE_PEER_FAILED_VERIFICATION; - } + if((status != SEC_E_OK) || (pCertContextServer == NULL)) { + failf(data, "schannel: Failed to read remote certificate context: %s", + Curl_sspi_strerror(conn, status)); + break; /* failed */ } - } - if(result == CURLE_OK) { - if(conn->ssl_config.verifyhost) { - TCHAR cert_hostname_buff[256]; - DWORD len; - - /* TODO: Fix this for certificates with multiple alternative names. - Right now we're only asking for the first preferred alternative name. - Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG - (if WinCE supports that?) and run this section in a loop for each. - https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx - curl: (51) schannel: CertGetNameString() certificate hostname - (.google.com) did not match connection (google.com) - */ - len = CertGetNameString(pCertContextServer, - CERT_NAME_DNS_TYPE, - CERT_NAME_DISABLE_IE4_UTF8_FLAG, - NULL, - cert_hostname_buff, - 256); - if(len > 0) { - const char *cert_hostname; - - /* Comparing the cert name and the connection hostname encoded as UTF-8 - * is acceptable since both values are assumed to use ASCII - * (or some equivalent) encoding - */ - cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname_buff); - if(!cert_hostname) { - result = CURLE_OUT_OF_MEMORY; - } - else{ - int match_result; - - match_result = Curl_cert_hostcheck(cert_hostname, conn->host.name); - if(match_result == CURL_HOST_MATCH) { - infof(data, - "schannel: connection hostname (%s) validated " - "against certificate name (%s)\n", - conn->host.name, - cert_hostname); - result = CURLE_OK; - } - else{ - failf(data, - "schannel: connection hostname (%s) " - "does not match certificate name (%s)", - conn->host.name, - cert_hostname); - result = CURLE_PEER_FAILED_VERIFICATION; - } - Curl_unicodefree(cert_hostname); - } - } - else { - failf(data, - "schannel: CertGetNameString did not provide any " - "certificate name information"); - result = CURLE_PEER_FAILED_VERIFICATION; - } + + if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) && + (pCertContextServer->cbCertEncoded > 0))) + break; + + x509_der = (const char *)pCertContextServer->pbCertEncoded; + x509_der_len = pCertContextServer->cbCertEncoded; + memset(&x509_parsed, 0, sizeof x509_parsed); + if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) + break; + + pubkey = &x509_parsed.subjectPublicKeyInfo; + if(!pubkey->header || pubkey->end <= pubkey->header) { + failf(data, "SSL: failed retrieving public key from server certificate"); + break; } - } - if(pChainContext) - CertFreeCertificateChain(pChainContext); + result = Curl_pin_peer_pubkey(data, + pinnedpubkey, + (const unsigned char *)pubkey->header, + (size_t)(pubkey->end - pubkey->header)); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + } + } while(0); if(pCertContextServer) CertFreeCertificateContext(pCertContextServer); return result; } -#endif /* _WIN32_WCE */ + +static void Curl_schannel_checksum(const unsigned char *input, + size_t inputlen, + unsigned char *checksum, + size_t checksumlen, + DWORD provType, + const unsigned int algId) +{ + HCRYPTPROV hProv = 0; + HCRYPTHASH hHash = 0; + DWORD cbHashSize = 0; + DWORD dwHashSizeLen = (DWORD)sizeof(cbHashSize); + DWORD dwChecksumLen = (DWORD)checksumlen; + + /* since this can fail in multiple ways, zero memory first so we never + * return old data + */ + memset(checksum, 0, checksumlen); + + if(!CryptAcquireContext(&hProv, NULL, NULL, provType, + CRYPT_VERIFYCONTEXT)) + return; /* failed */ + + do { + if(!CryptCreateHash(hProv, algId, 0, 0, &hHash)) + break; /* failed */ + + if(!CryptHashData(hHash, (const BYTE*)input, (DWORD)inputlen, 0)) + break; /* failed */ + + /* get hash size */ + if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashSize, + &dwHashSizeLen, 0)) + break; /* failed */ + + /* check hash size */ + if(checksumlen < cbHashSize) + break; /* failed */ + + if(CryptGetHashParam(hHash, HP_HASHVAL, checksum, &dwChecksumLen, 0)) + break; /* failed */ + } while(0); + + if(hHash) + CryptDestroyHash(hHash); + + if(hProv) + CryptReleaseContext(hProv, 0); +} + +static CURLcode Curl_schannel_md5sum(unsigned char *input, + size_t inputlen, + unsigned char *md5sum, + size_t md5len) +{ + Curl_schannel_checksum(input, inputlen, md5sum, md5len, + PROV_RSA_FULL, CALG_MD5); + return CURLE_OK; +} + +static CURLcode Curl_schannel_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len) +{ + Curl_schannel_checksum(input, inputlen, sha256sum, sha256len, + PROV_RSA_AES, CALG_SHA_256); + return CURLE_OK; +} static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) @@ -1819,11 +1923,8 @@ static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_schannel = { { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ - 0, /* have_ca_path */ - 1, /* have_certinfo */ - 0, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - 0, /* support_https_proxy */ + SSLSUPP_CERTINFO | + SSLSUPP_PINNEDPUBKEY, sizeof(struct ssl_backend_data), @@ -1845,8 +1946,8 @@ const struct Curl_ssl Curl_ssl_schannel = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - Curl_none_md5sum, /* md5sum */ - NULL /* sha256sum */ + Curl_schannel_md5sum, /* md5sum */ + Curl_schannel_sha256sum /* sha256sum */ }; #endif /* USE_SCHANNEL */ diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h index 932103da47..4476900270 100644 --- a/libs/libcurl/src/vtls/schannel.h +++ b/libs/libcurl/src/vtls/schannel.h @@ -26,9 +26,49 @@ #ifdef USE_SCHANNEL +#include <schnlsp.h> +#include <schannel.h> +#include "curl_sspi.h" + #include "urldata.h" extern const struct Curl_ssl Curl_ssl_schannel; +CURLcode verify_certificate(struct connectdata *conn, int sockindex); + +/* structs to expose only in schannel.c and schannel_verify.c */ +#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS +struct curl_schannel_cred { + CredHandle cred_handle; + TimeStamp time_stamp; + int refcount; +}; + +struct curl_schannel_ctxt { + CtxtHandle ctxt_handle; + TimeStamp time_stamp; +}; + +struct ssl_backend_data { + struct curl_schannel_cred *cred; + struct curl_schannel_ctxt *ctxt; + SecPkgContext_StreamSizes stream_sizes; + size_t encdata_length, decdata_length; + size_t encdata_offset, decdata_offset; + unsigned char *encdata_buffer, *decdata_buffer; + /* encdata_is_incomplete: if encdata contains only a partial record that + can't be decrypted without another Curl_read_plain (that is, status is + SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes + more bytes into encdata then set this back to false. */ + bool encdata_is_incomplete; + unsigned long req_flags, ret_flags; + CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ + bool recv_sspi_close_notify; /* true if connection closed by close_notify */ + bool recv_connection_closed; /* true if connection closed, regardless how */ + bool use_alpn; /* true if ALPN is used for this connection */ + bool use_manual_cred_validation; /* true if manual cred validation is used */ +}; +#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */ + #endif /* USE_SCHANNEL */ #endif /* HEADER_CURL_SCHANNEL_H */ diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c new file mode 100644 index 0000000000..db187dd6bf --- /dev/null +++ b/libs/libcurl/src/vtls/schannel_verify.c @@ -0,0 +1,551 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> + * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> + * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Source file for SChannel-specific certificate verification. This code should + * only be invoked by code in schannel.c. + */ + +#include "curl_setup.h" + +#ifdef USE_SCHANNEL + +#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS + +#ifndef USE_WINDOWS_SSPI +# error "Can't compile SCHANNEL support without SSPI." +#endif + +#include "schannel.h" +#include "vtls.h" +#include "sendf.h" +#include "strerror.h" +#include "curl_multibyte.h" +#include "curl_printf.h" +#include "hostcheck.h" +#include "system_win32.h" + +/* The last #include file should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#define BACKEND connssl->backend + +#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */ +#define BEGIN_CERT "-----BEGIN CERTIFICATE-----\n" +#define END_CERT "\n-----END CERTIFICATE-----" + +typedef struct { + DWORD cbSize; + HCERTSTORE hRestrictedRoot; + HCERTSTORE hRestrictedTrust; + HCERTSTORE hRestrictedOther; + DWORD cAdditionalStore; + HCERTSTORE *rghAdditionalStore; + DWORD dwFlags; + DWORD dwUrlRetrievalTimeout; + DWORD MaximumCachedCertificates; + DWORD CycleDetectionModulus; + HCERTSTORE hExclusiveRoot; + HCERTSTORE hExclusiveTrustedPeople; +} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7; + + +static CURLcode add_certs_to_store(HCERTSTORE trust_store, + const char *ca_file, + struct connectdata *conn) +{ + CURLcode result; + struct Curl_easy *data = conn->data; + HANDLE ca_file_handle = INVALID_HANDLE_VALUE; + LARGE_INTEGER file_size; + char *ca_file_buffer = NULL; + char *current_ca_file_ptr = NULL; + const TCHAR *ca_file_tstr = NULL; + size_t ca_file_bufsize = 0; + DWORD total_bytes_read = 0; + bool more_certs = 0; + int num_certs = 0; + size_t END_CERT_LEN; + + ca_file_tstr = Curl_convert_UTF8_to_tchar(ca_file); + if(!ca_file_tstr) { + failf(data, + "schannel: invalid path name for CA file '%s': %s", + ca_file, Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + /* + * Read the CA file completely into memory before parsing it. This + * optimizes for the common case where the CA file will be relatively + * small ( < 1 MiB ). + */ + ca_file_handle = CreateFile(ca_file_tstr, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if(ca_file_handle == INVALID_HANDLE_VALUE) { + failf(data, + "schannel: failed to open CA file '%s': %s", + ca_file, Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + if(!GetFileSizeEx(ca_file_handle, &file_size)) { + failf(data, + "schannel: failed to determine size of CA file '%s': %s", + ca_file, Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + + if(file_size.QuadPart > MAX_CAFILE_SIZE) { + failf(data, + "schannel: CA file exceeds max size of %u bytes", + MAX_CAFILE_SIZE); + result = CURLE_OUT_OF_MEMORY; + goto cleanup; + } + + ca_file_bufsize = (size_t)file_size.QuadPart; + ca_file_buffer = (char *)malloc(ca_file_bufsize + 1); + if(!ca_file_buffer) { + result = CURLE_OUT_OF_MEMORY; + goto cleanup; + } + + result = CURLE_OK; + while(total_bytes_read < ca_file_bufsize) { + DWORD bytes_to_read = (DWORD)(ca_file_bufsize - total_bytes_read); + DWORD bytes_read = 0; + + if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read, + bytes_to_read, &bytes_read, NULL)) { + + failf(data, + "schannel: failed to read from CA file '%s': %s", + ca_file, Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + goto cleanup; + } + if(bytes_read == 0) { + /* Premature EOF -- adjust the bufsize to the new value */ + ca_file_bufsize = total_bytes_read; + } + else { + total_bytes_read += bytes_read; + } + } + + /* Null terminate the buffer */ + ca_file_buffer[ca_file_bufsize] = '\0'; + + if(result != CURLE_OK) { + goto cleanup; + } + + END_CERT_LEN = strlen(END_CERT); + + more_certs = 1; + current_ca_file_ptr = ca_file_buffer; + while(more_certs && *current_ca_file_ptr != '\0') { + char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT); + if(!begin_cert_ptr) { + more_certs = 0; + } + else { + char *end_cert_ptr = strstr(begin_cert_ptr, END_CERT); + if(!end_cert_ptr) { + failf(data, + "schannel: CA file '%s' is not correctly formatted", + ca_file); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + CERT_BLOB cert_blob; + CERT_CONTEXT *cert_context = NULL; + BOOL add_cert_result = FALSE; + DWORD actual_content_type = 0; + DWORD cert_size = (DWORD) + ((end_cert_ptr + END_CERT_LEN) - begin_cert_ptr); + + cert_blob.pbData = (BYTE *)begin_cert_ptr; + cert_blob.cbData = cert_size; + if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, + &cert_blob, + CERT_QUERY_CONTENT_FLAG_CERT, + CERT_QUERY_FORMAT_FLAG_ALL, + 0, + NULL, + &actual_content_type, + NULL, + NULL, + NULL, + &cert_context)) { + + failf(data, + "schannel: failed to extract certificate from CA file " + "'%s': %s", + ca_file, Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + current_ca_file_ptr = begin_cert_ptr + cert_size; + + /* Sanity check that the cert_context object is the right type */ + if(CERT_QUERY_CONTENT_CERT != actual_content_type) { + failf(data, + "schannel: unexpected content type '%d' when extracting " + "certificate from CA file '%s'", + actual_content_type, ca_file); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + add_cert_result = + CertAddCertificateContextToStore(trust_store, + cert_context, + CERT_STORE_ADD_ALWAYS, + NULL); + CertFreeCertificateContext(cert_context); + if(!add_cert_result) { + failf(data, + "schannel: failed to add certificate from CA file '%s'" + "to certificate store: %s", + ca_file, Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + num_certs++; + } + } + } + } + } + } + + if(result == CURLE_OK) { + if(!num_certs) { + infof(data, + "schannel: did not add any certificates from CA file '%s'\n", + ca_file); + } + else { + infof(data, + "schannel: added %d certificate(s) from CA file '%s'\n", + num_certs, ca_file); + } + } + +cleanup: + if(ca_file_handle != INVALID_HANDLE_VALUE) { + CloseHandle(ca_file_handle); + } + Curl_safefree(ca_file_buffer); + Curl_unicodefree(ca_file_tstr); + + return result; +} + +static CURLcode verify_host(struct Curl_easy *data, + CERT_CONTEXT *pCertContextServer, + const char * const conn_hostname) +{ + CURLcode result = CURLE_PEER_FAILED_VERIFICATION; + TCHAR *cert_hostname_buff = NULL; + size_t cert_hostname_buff_index = 0; + DWORD len = 0; + DWORD actual_len = 0; + + /* CertGetNameString will provide the 8-bit character string without + * any decoding */ + DWORD name_flags = CERT_NAME_DISABLE_IE4_UTF8_FLAG; + +#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG + name_flags |= CERT_NAME_SEARCH_ALL_NAMES_FLAG; +#endif + + /* Determine the size of the string needed for the cert hostname */ + len = CertGetNameString(pCertContextServer, + CERT_NAME_DNS_TYPE, + name_flags, + NULL, + NULL, + 0); + if(len == 0) { + failf(data, + "schannel: CertGetNameString() returned no " + "certificate name information"); + result = CURLE_PEER_FAILED_VERIFICATION; + goto cleanup; + } + + /* CertGetNameString guarantees that the returned name will not contain + * embedded null bytes. This appears to be undocumented behavior. + */ + cert_hostname_buff = (LPTSTR)malloc(len * sizeof(TCHAR)); + actual_len = CertGetNameString(pCertContextServer, + CERT_NAME_DNS_TYPE, + name_flags, + NULL, + (LPTSTR) cert_hostname_buff, + len); + + /* Sanity check */ + if(actual_len != len) { + failf(data, + "schannel: CertGetNameString() returned certificate " + "name information of unexpected size"); + result = CURLE_PEER_FAILED_VERIFICATION; + goto cleanup; + } + + /* If HAVE_CERT_NAME_SEARCH_ALL_NAMES is available, the output + * will contain all DNS names, where each name is null-terminated + * and the last DNS name is double null-terminated. Due to this + * encoding, use the length of the buffer to iterate over all names. + */ + result = CURLE_PEER_FAILED_VERIFICATION; + while(cert_hostname_buff_index < len && + cert_hostname_buff[cert_hostname_buff_index] != TEXT('\0') && + result == CURLE_PEER_FAILED_VERIFICATION) { + + char *cert_hostname; + + /* Comparing the cert name and the connection hostname encoded as UTF-8 + * is acceptable since both values are assumed to use ASCII + * (or some equivalent) encoding + */ + cert_hostname = Curl_convert_tchar_to_UTF8( + &cert_hostname_buff[cert_hostname_buff_index]); + if(!cert_hostname) { + result = CURLE_OUT_OF_MEMORY; + } + else { + int match_result; + + match_result = Curl_cert_hostcheck(cert_hostname, conn_hostname); + if(match_result == CURL_HOST_MATCH) { + infof(data, + "schannel: connection hostname (%s) validated " + "against certificate name (%s)\n", + conn_hostname, cert_hostname); + result = CURLE_OK; + } + else { + size_t cert_hostname_len; + + infof(data, + "schannel: connection hostname (%s) did not match " + "against certificate name (%s)\n", + conn_hostname, cert_hostname); + + cert_hostname_len = _tcslen( + &cert_hostname_buff[cert_hostname_buff_index]); + + /* Move on to next cert name */ + cert_hostname_buff_index += cert_hostname_len + 1; + + result = CURLE_PEER_FAILED_VERIFICATION; + } + Curl_unicodefree(cert_hostname); + } + } + + if(result == CURLE_PEER_FAILED_VERIFICATION) { + failf(data, + "schannel: CertGetNameString() failed to match " + "connection hostname (%s) against server certificate names", + conn_hostname); + } + else if(result != CURLE_OK) + failf(data, "schannel: server certificate name verification failed"); + +cleanup: + Curl_unicodefree(cert_hostname_buff); + + return result; +} + +CURLcode verify_certificate(struct connectdata *conn, int sockindex) +{ + SECURITY_STATUS status; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode result = CURLE_OK; + CERT_CONTEXT *pCertContextServer = NULL; + const CERT_CHAIN_CONTEXT *pChainContext = NULL; + HCERTCHAINENGINE cert_chain_engine = NULL; + HCERTSTORE trust_store = NULL; + const char * const conn_hostname = SSL_IS_PROXY() ? + conn->http_proxy.host.name : + conn->host.name; + + status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &pCertContextServer); + + if((status != SEC_E_OK) || (pCertContextServer == NULL)) { + failf(data, "schannel: Failed to read remote certificate context: %s", + Curl_sspi_strerror(conn, status)); + result = CURLE_PEER_FAILED_VERIFICATION; + } + + if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) && + BACKEND->use_manual_cred_validation) { + /* + * Create a chain engine that uses the certificates in the CA file as + * trusted certificates. This is only supported on Windows 7+. + */ + + if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) { + failf(data, "schannel: this version of Windows is too old to support " + "certificate verification via CA bundle file."); + result = CURLE_SSL_CACERT_BADFILE; + } + else { + /* Open the certificate store */ + trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY, + 0, + (HCRYPTPROV)NULL, + CERT_STORE_CREATE_NEW_FLAG, + NULL); + if(!trust_store) { + failf(data, "schannel: failed to create certificate store: %s", + Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + } + else { + result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile), + conn); + } + } + + if(result == CURLE_OK) { + CERT_CHAIN_ENGINE_CONFIG_WIN7 engine_config; + BOOL create_engine_result; + + memset(&engine_config, 0, sizeof(engine_config)); + engine_config.cbSize = sizeof(engine_config); + engine_config.hExclusiveRoot = trust_store; + + /* CertCreateCertificateChainEngine will check the expected size of the + * CERT_CHAIN_ENGINE_CONFIG structure and fail if the specified size + * does not match the expected size. When this occurs, it indicates that + * CAINFO is not supported on the version of Windows in use. + */ + create_engine_result = + CertCreateCertificateChainEngine( + (CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine); + if(!create_engine_result) { + failf(data, + "schannel: failed to create certificate chain engine: %s", + Curl_strerror(conn, GetLastError())); + result = CURLE_SSL_CACERT_BADFILE; + } + } + } + + if(result == CURLE_OK) { + CERT_CHAIN_PARA ChainPara; + + memset(&ChainPara, 0, sizeof(ChainPara)); + ChainPara.cbSize = sizeof(ChainPara); + + if(!CertGetCertificateChain(cert_chain_engine, + pCertContextServer, + NULL, + pCertContextServer->hCertStore, + &ChainPara, + (data->set.ssl.no_revoke ? 0 : + CERT_CHAIN_REVOCATION_CHECK_CHAIN), + NULL, + &pChainContext)) { + failf(data, "schannel: CertGetCertificateChain failed: %s", + Curl_sspi_strerror(conn, GetLastError())); + pChainContext = NULL; + result = CURLE_PEER_FAILED_VERIFICATION; + } + + if(result == CURLE_OK) { + CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; + DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED); + dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; + if(dwTrustErrorMask) { + if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_REVOKED"); + else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_PARTIAL_CHAIN"); + else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_UNTRUSTED_ROOT"); + else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_IS_NOT_TIME_VALID"); + else if(dwTrustErrorMask & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) + failf(data, "schannel: CertGetCertificateChain trust error" + " CERT_TRUST_REVOCATION_STATUS_UNKNOWN"); + else + failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x", + dwTrustErrorMask); + result = CURLE_PEER_FAILED_VERIFICATION; + } + } + } + + if(result == CURLE_OK) { + if(SSL_CONN_CONFIG(verifyhost)) { + result = verify_host(conn->data, pCertContextServer, conn_hostname); + } + } + + if(cert_chain_engine) { + CertFreeCertificateChainEngine(cert_chain_engine); + } + + if(trust_store) { + CertCloseStore(trust_store, 0); + } + + if(pChainContext) + CertFreeCertificateChain(pChainContext); + + if(pCertContextServer) + CertFreeCertificateContext(pCertContextServer); + + return result; +} + +#endif /* USE_SCHANNEL */ diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index 56e6317713..ee5bc7a0a6 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -211,7 +211,7 @@ ssl_connect_init_proxy(struct connectdata *conn, int sockindex) !conn->proxy_ssl[sockindex].use) { struct ssl_backend_data *pbdata; - if(!Curl_ssl->support_https_proxy) + if(!(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)) return CURLE_NOT_BUILT_IN; /* The pointers to the ssl backend data, which is opaque here, are swapped @@ -511,7 +511,7 @@ void Curl_ssl_close_all(struct Curl_easy *data) #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \ - defined(USE_MBEDTLS) + defined(USE_MBEDTLS) || defined(USE_CYASSL) int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks) { @@ -831,8 +831,12 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, sha256sumdigest = malloc(CURL_SHA256_DIGEST_LENGTH); if(!sha256sumdigest) return CURLE_OUT_OF_MEMORY; - Curl_ssl->sha256sum(pubkey, pubkeylen, + encode = Curl_ssl->sha256sum(pubkey, pubkeylen, sha256sumdigest, CURL_SHA256_DIGEST_LENGTH); + + if(encode != CURLE_OK) + return encode; + encode = Curl_base64_encode(data, (char *)sha256sumdigest, CURL_SHA256_DIGEST_LENGTH, &encoded, &encodedlen); @@ -1127,13 +1131,7 @@ static void Curl_multissl_close(struct connectdata *conn, int sockindex) static const struct Curl_ssl Curl_ssl_multi = { { CURLSSLBACKEND_NONE, "multi" }, /* info */ - - 0, /* have_ca_path */ - 0, /* have_certinfo */ - 0, /* have_pinnedpubkey */ - 0, /* have_ssl_ctx */ - 0, /* support_https_proxy */ - + 0, /* supports nothing */ (size_t)-1, /* something insanely large to be on the safe side */ Curl_multissl_init, /* init */ @@ -1260,6 +1258,7 @@ static size_t Curl_multissl_version(char *buffer, size_t size) static int multissl_init(const struct Curl_ssl *backend) { const char *env; + char *env_tmp; int i; if(Curl_ssl != &Curl_ssl_multi) @@ -1273,7 +1272,7 @@ static int multissl_init(const struct Curl_ssl *backend) if(!available_backends[0]) return 1; - env = getenv("CURL_SSL_BACKEND"); + env = env_tmp = curl_getenv("CURL_SSL_BACKEND"); #ifdef CURL_DEFAULT_SSL_BACKEND if(!env) env = CURL_DEFAULT_SSL_BACKEND; @@ -1282,6 +1281,7 @@ static int multissl_init(const struct Curl_ssl *backend) for(i = 0; available_backends[i]; i++) { if(strcasecompare(env, available_backends[i]->info.name)) { Curl_ssl = available_backends[i]; + curl_free(env_tmp); return 0; } } @@ -1289,6 +1289,7 @@ static int multissl_init(const struct Curl_ssl *backend) /* Fall back to first available backend */ Curl_ssl = available_backends[0]; + curl_free(env_tmp); return 0; } @@ -1297,6 +1298,9 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, { int i; + if(avail) + *avail = (const curl_ssl_backend **)&available_backends; + if(Curl_ssl != &Curl_ssl_multi) return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE; @@ -1308,8 +1312,6 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, } } - if(avail) - *avail = (const curl_ssl_backend **)&available_backends; return CURLSSLSET_UNKNOWN_BACKEND; } diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index c5f9d4a3fa..e7b87c4d3f 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,20 +26,19 @@ struct connectdata; struct ssl_connect_data; +#define SSLSUPP_CA_PATH (1<<0) /* supports CAPATH */ +#define SSLSUPP_CERTINFO (1<<1) /* supports CURLOPT_CERTINFO */ +#define SSLSUPP_PINNEDPUBKEY (1<<2) /* supports CURLOPT_PINNEDPUBLICKEY */ +#define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */ +#define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */ + struct Curl_ssl { /* * This *must* be the first entry to allow returning the list of available * backends in curl_global_sslset(). */ curl_ssl_backend info; - - unsigned have_ca_path:1; /* supports CAPATH */ - unsigned have_certinfo:1; /* supports CURLOPT_CERTINFO */ - unsigned have_pinnedpubkey:1; /* supports CURLOPT_PINNEDPUBLICKEY */ - unsigned have_ssl_ctx:1; /* supports CURLOPT_SSL_CTX_* */ - - unsigned support_https_proxy:1; /* supports access via HTTPS proxies */ - + unsigned int supports; /* bitfield, see above */ size_t sizeof_ssl_backend_data; int (*init)(void); @@ -72,7 +71,7 @@ struct Curl_ssl { CURLcode (*md5sum)(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5sumlen); - void (*sha256sum)(const unsigned char *input, size_t inputlen, + CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256sumlen); }; @@ -113,8 +112,10 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #endif #ifndef MD5_DIGEST_LENGTH +#ifndef LIBWOLFSSL_VERSION_HEX /* because WolfSSL borks this */ #define MD5_DIGEST_LENGTH 16 /* fixed size */ #endif +#endif #ifndef CURL_SHA256_DIGEST_LENGTH #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ diff --git a/libs/libcurl/src/warnless.h b/libs/libcurl/src/warnless.h index ab6d29998d..f6a2d744b7 100644 --- a/libs/libcurl/src/warnless.h +++ b/libs/libcurl/src/warnless.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/wildcard.c b/libs/libcurl/src/wildcard.c index af45c79bd3..8ba0989b4a 100644 --- a/libs/libcurl/src/wildcard.c +++ b/libs/libcurl/src/wildcard.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,9 +30,15 @@ #include "curl_memory.h" #include "memdebug.h" +static void fileinfo_dtor(void *user, void *element) +{ + (void)user; + Curl_fileinfo_cleanup(element); +} + CURLcode Curl_wildcard_init(struct WildcardData *wc) { - Curl_llist_init(&wc->filelist, Curl_fileinfo_dtor); + Curl_llist_init(&wc->filelist, fileinfo_dtor); wc->state = CURLWC_INIT; return CURLE_OK; @@ -43,12 +49,12 @@ void Curl_wildcard_dtor(struct WildcardData *wc) if(!wc) return; - if(wc->tmp_dtor) { - wc->tmp_dtor(wc->tmp); - wc->tmp_dtor = ZERO_NULL; - wc->tmp = NULL; + if(wc->dtor) { + wc->dtor(wc->protdata); + wc->dtor = ZERO_NULL; + wc->protdata = NULL; } - DEBUGASSERT(wc->tmp == NULL); + DEBUGASSERT(wc->protdata == NULL); Curl_llist_destroy(&wc->filelist, NULL); diff --git a/libs/libcurl/src/wildcard.h b/libs/libcurl/src/wildcard.h index 8a5e4b769b..b7826123ad 100644 --- a/libs/libcurl/src/wildcard.h +++ b/libs/libcurl/src/wildcard.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -40,7 +40,7 @@ typedef enum { will end */ } curl_wildcard_states; -typedef void (*curl_wildcard_tmp_dtor)(void *ptr); +typedef void (*curl_wildcard_dtor)(void *ptr); /* struct keeping information about wildcard download process */ struct WildcardData { @@ -48,8 +48,8 @@ struct WildcardData { char *path; /* path to the directory, where we trying wildcard-match */ char *pattern; /* wildcard pattern */ struct curl_llist filelist; /* llist with struct Curl_fileinfo */ - void *tmp; /* pointer to protocol specific temporary data */ - curl_wildcard_tmp_dtor tmp_dtor; + void *protdata; /* pointer to protocol specific temporary data */ + curl_wildcard_dtor dtor; void *customptr; /* for CURLOPT_CHUNK_DATA pointer */ }; |