rugged 0.27.9 → 0.27.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/CMakeLists.txt +98 -54
- data/vendor/libgit2/COPYING +28 -0
- data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +15 -1
- data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +9 -8
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +2 -2
- data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +1 -1
- data/vendor/libgit2/cmake/Modules/FindGSSFramework.cmake +28 -0
- data/vendor/libgit2/cmake/Modules/FindPCRE.cmake +38 -0
- data/vendor/libgit2/cmake/Modules/FindPCRE2.cmake +37 -0
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +2 -2
- data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +6 -0
- data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
- data/vendor/libgit2/cmake/Modules/PkgBuildConfig.cmake +110 -0
- data/vendor/libgit2/cmake/Modules/SelectGSSAPI.cmake +53 -0
- data/vendor/libgit2/cmake/Modules/SelectHTTPSBackend.cmake +124 -0
- data/vendor/libgit2/cmake/Modules/SelectHashes.cmake +66 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +2 -0
- data/vendor/libgit2/deps/http-parser/{LICENSE-MIT → COPYING} +0 -0
- data/vendor/libgit2/deps/http-parser/http_parser.c +11 -6
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +21 -0
- data/vendor/libgit2/deps/ntlmclient/compat.h +33 -0
- data/vendor/libgit2/deps/ntlmclient/crypt.h +64 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +120 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +18 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +145 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +18 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +130 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +21 -0
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +1420 -0
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +174 -0
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +320 -0
- data/vendor/libgit2/deps/ntlmclient/unicode.h +36 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +445 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +201 -0
- data/vendor/libgit2/deps/ntlmclient/utf8.h +1257 -0
- data/vendor/libgit2/deps/ntlmclient/util.c +21 -0
- data/vendor/libgit2/deps/ntlmclient/util.h +14 -0
- data/vendor/libgit2/deps/pcre/CMakeLists.txt +140 -0
- data/vendor/libgit2/deps/pcre/COPYING +5 -0
- data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +22 -0
- data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +17 -0
- data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +58 -0
- data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +29 -0
- data/vendor/libgit2/deps/pcre/config.h.in +57 -0
- data/vendor/libgit2/deps/pcre/pcre.h +641 -0
- data/vendor/libgit2/deps/pcre/pcre_byte_order.c +319 -0
- data/vendor/libgit2/deps/pcre/pcre_chartables.c +198 -0
- data/vendor/libgit2/deps/pcre/pcre_compile.c +9800 -0
- data/vendor/libgit2/deps/pcre/pcre_config.c +190 -0
- data/vendor/libgit2/deps/pcre/pcre_dfa_exec.c +3676 -0
- data/vendor/libgit2/deps/pcre/pcre_exec.c +7173 -0
- data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +245 -0
- data/vendor/libgit2/deps/pcre/pcre_get.c +669 -0
- data/vendor/libgit2/deps/pcre/pcre_globals.c +86 -0
- data/vendor/libgit2/deps/pcre/pcre_internal.h +2787 -0
- data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +11913 -0
- data/vendor/libgit2/deps/pcre/pcre_maketables.c +156 -0
- data/vendor/libgit2/deps/pcre/pcre_newline.c +210 -0
- data/vendor/libgit2/deps/pcre/pcre_ord2utf8.c +94 -0
- data/vendor/libgit2/deps/pcre/pcre_printint.c +834 -0
- data/vendor/libgit2/deps/pcre/pcre_refcount.c +92 -0
- data/vendor/libgit2/deps/pcre/pcre_string_utils.c +211 -0
- data/vendor/libgit2/deps/pcre/pcre_study.c +1686 -0
- data/vendor/libgit2/deps/pcre/pcre_tables.c +727 -0
- data/vendor/libgit2/deps/pcre/pcre_ucd.c +3644 -0
- data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +301 -0
- data/vendor/libgit2/deps/pcre/pcre_version.c +98 -0
- data/vendor/libgit2/deps/pcre/pcre_xclass.c +268 -0
- data/vendor/libgit2/deps/pcre/pcreposix.c +421 -0
- data/vendor/libgit2/deps/pcre/pcreposix.h +117 -0
- data/vendor/libgit2/deps/pcre/ucp.h +224 -0
- data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
- data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +1 -0
- data/vendor/libgit2/deps/zlib/COPYING +27 -0
- data/vendor/libgit2/deps/zlib/adler32.c +0 -7
- data/vendor/libgit2/deps/zlib/crc32.c +0 -7
- data/vendor/libgit2/include/git2.h +5 -0
- data/vendor/libgit2/include/git2/annotated_commit.h +9 -0
- data/vendor/libgit2/include/git2/apply.h +149 -0
- data/vendor/libgit2/include/git2/attr.h +38 -20
- data/vendor/libgit2/include/git2/blame.h +42 -25
- data/vendor/libgit2/include/git2/blob.h +45 -13
- data/vendor/libgit2/include/git2/branch.h +1 -1
- data/vendor/libgit2/include/git2/buffer.h +22 -16
- data/vendor/libgit2/include/git2/cert.h +135 -0
- data/vendor/libgit2/include/git2/checkout.h +65 -32
- data/vendor/libgit2/include/git2/cherrypick.h +9 -7
- data/vendor/libgit2/include/git2/clone.h +12 -10
- data/vendor/libgit2/include/git2/commit.h +53 -3
- data/vendor/libgit2/include/git2/common.h +60 -8
- data/vendor/libgit2/include/git2/config.h +30 -19
- data/vendor/libgit2/include/git2/cred.h +308 -0
- data/vendor/libgit2/include/git2/deprecated.h +493 -0
- data/vendor/libgit2/include/git2/describe.h +32 -9
- data/vendor/libgit2/include/git2/diff.h +208 -156
- data/vendor/libgit2/include/git2/errors.h +54 -46
- data/vendor/libgit2/include/git2/filter.h +8 -0
- data/vendor/libgit2/include/git2/ignore.h +2 -2
- data/vendor/libgit2/include/git2/index.h +74 -52
- data/vendor/libgit2/include/git2/indexer.h +76 -6
- data/vendor/libgit2/include/git2/mailmap.h +115 -0
- data/vendor/libgit2/include/git2/merge.h +35 -18
- data/vendor/libgit2/include/git2/net.h +0 -5
- data/vendor/libgit2/include/git2/notes.h +1 -1
- data/vendor/libgit2/include/git2/object.h +17 -29
- data/vendor/libgit2/include/git2/odb.h +12 -11
- data/vendor/libgit2/include/git2/odb_backend.h +10 -9
- data/vendor/libgit2/include/git2/oid.h +2 -2
- data/vendor/libgit2/include/git2/pack.h +14 -3
- data/vendor/libgit2/include/git2/proxy.h +14 -8
- data/vendor/libgit2/include/git2/rebase.h +53 -6
- data/vendor/libgit2/include/git2/refs.h +33 -15
- data/vendor/libgit2/include/git2/refspec.h +17 -0
- data/vendor/libgit2/include/git2/remote.h +123 -24
- data/vendor/libgit2/include/git2/repository.h +76 -39
- data/vendor/libgit2/include/git2/revert.h +6 -4
- data/vendor/libgit2/include/git2/revwalk.h +7 -7
- data/vendor/libgit2/include/git2/signature.h +2 -2
- data/vendor/libgit2/include/git2/stash.h +15 -12
- data/vendor/libgit2/include/git2/status.h +33 -20
- data/vendor/libgit2/include/git2/submodule.h +30 -12
- data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
- data/vendor/libgit2/include/git2/sys/commit.h +1 -1
- data/vendor/libgit2/include/git2/sys/config.h +13 -13
- data/vendor/libgit2/include/git2/sys/cred.h +90 -0
- data/vendor/libgit2/include/git2/sys/filter.h +6 -6
- data/vendor/libgit2/include/git2/sys/index.h +3 -0
- data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
- data/vendor/libgit2/include/git2/sys/merge.h +9 -4
- data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -22
- data/vendor/libgit2/include/git2/sys/path.h +64 -0
- data/vendor/libgit2/include/git2/sys/refdb_backend.h +76 -40
- data/vendor/libgit2/include/git2/sys/repository.h +5 -1
- data/vendor/libgit2/include/git2/sys/stream.h +92 -12
- data/vendor/libgit2/include/git2/sys/transport.h +129 -83
- data/vendor/libgit2/include/git2/tag.h +13 -4
- data/vendor/libgit2/include/git2/trace.h +2 -2
- data/vendor/libgit2/include/git2/transaction.h +1 -0
- data/vendor/libgit2/include/git2/transport.h +11 -311
- data/vendor/libgit2/include/git2/tree.h +4 -4
- data/vendor/libgit2/include/git2/types.h +33 -111
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +48 -13
- data/vendor/libgit2/src/CMakeLists.txt +96 -164
- data/vendor/libgit2/src/alloc.c +43 -0
- data/vendor/libgit2/src/alloc.h +40 -0
- data/vendor/libgit2/src/allocators/stdalloc.c +119 -0
- data/vendor/libgit2/src/{streams/curl.h → allocators/stdalloc.h} +5 -5
- data/vendor/libgit2/src/allocators/win32_crtdbg.c +118 -0
- data/vendor/libgit2/src/{transports/cred.h → allocators/win32_crtdbg.h} +5 -4
- data/vendor/libgit2/src/annotated_commit.c +15 -8
- data/vendor/libgit2/src/apply.c +537 -31
- data/vendor/libgit2/src/apply.h +3 -1
- data/vendor/libgit2/src/array.h +2 -2
- data/vendor/libgit2/src/attr.c +81 -75
- data/vendor/libgit2/src/attr_file.c +207 -121
- data/vendor/libgit2/src/attr_file.h +9 -9
- data/vendor/libgit2/src/attrcache.c +51 -53
- data/vendor/libgit2/src/attrcache.h +2 -1
- data/vendor/libgit2/src/blame.c +47 -20
- data/vendor/libgit2/src/blame.h +2 -1
- data/vendor/libgit2/src/blame_git.c +37 -20
- data/vendor/libgit2/src/blob.c +128 -42
- data/vendor/libgit2/src/blob.h +19 -2
- data/vendor/libgit2/src/branch.c +67 -43
- data/vendor/libgit2/src/buf_text.c +7 -6
- data/vendor/libgit2/src/buffer.c +69 -57
- data/vendor/libgit2/src/buffer.h +1 -1
- data/vendor/libgit2/src/cache.c +38 -45
- data/vendor/libgit2/src/cache.h +3 -3
- data/vendor/libgit2/src/cc-compat.h +20 -3
- data/vendor/libgit2/src/checkout.c +109 -90
- data/vendor/libgit2/src/cherrypick.c +15 -9
- data/vendor/libgit2/src/clone.c +49 -27
- data/vendor/libgit2/src/clone.h +4 -0
- data/vendor/libgit2/src/commit.c +117 -49
- data/vendor/libgit2/src/commit.h +7 -0
- data/vendor/libgit2/src/commit_list.c +30 -78
- data/vendor/libgit2/src/commit_list.h +2 -2
- data/vendor/libgit2/src/common.h +27 -91
- data/vendor/libgit2/src/config.c +194 -176
- data/vendor/libgit2/src/config.h +8 -20
- data/vendor/libgit2/src/config_backend.h +96 -0
- data/vendor/libgit2/src/config_cache.c +41 -35
- data/vendor/libgit2/src/config_entries.c +229 -0
- data/vendor/libgit2/src/config_entries.h +24 -0
- data/vendor/libgit2/src/config_file.c +439 -753
- data/vendor/libgit2/src/config_mem.c +220 -0
- data/vendor/libgit2/src/config_parse.c +114 -63
- data/vendor/libgit2/src/config_parse.h +17 -16
- data/vendor/libgit2/src/config_snapshot.c +206 -0
- data/vendor/libgit2/src/crlf.c +219 -190
- data/vendor/libgit2/src/delta.c +25 -18
- data/vendor/libgit2/src/describe.c +42 -41
- data/vendor/libgit2/src/diff.c +53 -68
- data/vendor/libgit2/src/diff.h +2 -1
- data/vendor/libgit2/src/diff_driver.c +47 -49
- data/vendor/libgit2/src/diff_file.c +19 -17
- data/vendor/libgit2/src/diff_file.h +1 -1
- data/vendor/libgit2/src/diff_generate.c +162 -106
- data/vendor/libgit2/src/diff_generate.h +3 -3
- data/vendor/libgit2/src/diff_parse.c +4 -4
- data/vendor/libgit2/src/diff_print.c +42 -30
- data/vendor/libgit2/src/diff_stats.c +22 -7
- data/vendor/libgit2/src/diff_tform.c +16 -16
- data/vendor/libgit2/src/diff_xdiff.c +15 -3
- data/vendor/libgit2/src/errors.c +51 -39
- data/vendor/libgit2/src/errors.h +81 -0
- data/vendor/libgit2/src/features.h.in +11 -3
- data/vendor/libgit2/src/fetch.c +10 -5
- data/vendor/libgit2/src/fetchhead.c +17 -17
- data/vendor/libgit2/src/filebuf.c +32 -36
- data/vendor/libgit2/src/filebuf.h +2 -2
- data/vendor/libgit2/src/filter.c +46 -38
- data/vendor/libgit2/src/filter.h +0 -10
- data/vendor/libgit2/src/{fileops.c → futils.c} +80 -73
- data/vendor/libgit2/src/{fileops.h → futils.h} +6 -6
- data/vendor/libgit2/src/global.c +48 -63
- data/vendor/libgit2/src/global.h +0 -2
- data/vendor/libgit2/src/hash.c +61 -0
- data/vendor/libgit2/src/hash.h +20 -19
- data/vendor/libgit2/src/hash/sha1.h +38 -0
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +48 -0
- data/vendor/libgit2/src/hash/sha1/collisiondetect.h +19 -0
- data/vendor/libgit2/src/hash/{hash_common_crypto.h → sha1/common_crypto.c} +17 -17
- data/vendor/libgit2/src/hash/sha1/common_crypto.h +19 -0
- data/vendor/libgit2/src/hash/{hash_generic.c → sha1/generic.c} +22 -10
- data/vendor/libgit2/src/hash/{hash_generic.h → sha1/generic.h} +4 -10
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +46 -0
- data/vendor/libgit2/src/hash/sha1/mbedtls.h +19 -0
- data/vendor/libgit2/src/hash/sha1/openssl.c +59 -0
- data/vendor/libgit2/src/hash/sha1/openssl.h +19 -0
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.c +14 -3
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.h +0 -0
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.c +0 -0
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.h +0 -0
- data/vendor/libgit2/src/hash/{hash_win32.c → sha1/win32.c} +47 -37
- data/vendor/libgit2/src/hash/{hash_win32.h → sha1/win32.h} +6 -19
- data/vendor/libgit2/src/hashsig.c +5 -5
- data/vendor/libgit2/src/idxmap.c +107 -61
- data/vendor/libgit2/src/idxmap.h +153 -31
- data/vendor/libgit2/src/ignore.c +43 -47
- data/vendor/libgit2/src/index.c +337 -232
- data/vendor/libgit2/src/index.h +17 -1
- data/vendor/libgit2/src/indexer.c +346 -175
- data/vendor/libgit2/src/integer.h +71 -26
- data/vendor/libgit2/src/iterator.c +142 -70
- data/vendor/libgit2/src/iterator.h +15 -0
- data/vendor/libgit2/src/khash.h +3 -1
- data/vendor/libgit2/src/mailmap.c +485 -0
- data/vendor/libgit2/src/mailmap.h +35 -0
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +144 -100
- data/vendor/libgit2/src/merge_driver.c +11 -11
- data/vendor/libgit2/src/merge_file.c +2 -2
- data/vendor/libgit2/src/mwindow.c +24 -29
- data/vendor/libgit2/src/mwindow.h +4 -4
- data/vendor/libgit2/src/net.c +184 -0
- data/vendor/libgit2/src/net.h +36 -0
- data/vendor/libgit2/src/netops.c +55 -156
- data/vendor/libgit2/src/netops.h +3 -23
- data/vendor/libgit2/src/notes.c +16 -11
- data/vendor/libgit2/src/object.c +120 -69
- data/vendor/libgit2/src/object.h +22 -9
- data/vendor/libgit2/src/object_api.c +8 -8
- data/vendor/libgit2/src/odb.c +116 -93
- data/vendor/libgit2/src/odb.h +8 -7
- data/vendor/libgit2/src/odb_loose.c +62 -55
- data/vendor/libgit2/src/odb_mempack.c +21 -34
- data/vendor/libgit2/src/odb_pack.c +18 -14
- data/vendor/libgit2/src/offmap.c +53 -35
- data/vendor/libgit2/src/offmap.h +108 -21
- data/vendor/libgit2/src/oid.c +12 -7
- data/vendor/libgit2/src/oidmap.c +49 -47
- data/vendor/libgit2/src/oidmap.h +101 -24
- data/vendor/libgit2/src/pack-objects.c +88 -87
- data/vendor/libgit2/src/pack-objects.h +2 -8
- data/vendor/libgit2/src/pack.c +99 -101
- data/vendor/libgit2/src/pack.h +17 -19
- data/vendor/libgit2/src/parse.c +10 -0
- data/vendor/libgit2/src/parse.h +3 -3
- data/vendor/libgit2/src/patch.c +4 -4
- data/vendor/libgit2/src/patch_generate.c +20 -20
- data/vendor/libgit2/src/patch_parse.c +151 -63
- data/vendor/libgit2/src/path.c +169 -125
- data/vendor/libgit2/src/path.h +3 -71
- data/vendor/libgit2/src/pathspec.c +19 -19
- data/vendor/libgit2/src/pool.c +26 -22
- data/vendor/libgit2/src/pool.h +7 -7
- data/vendor/libgit2/src/posix.c +10 -10
- data/vendor/libgit2/src/posix.h +12 -1
- data/vendor/libgit2/src/proxy.c +8 -3
- data/vendor/libgit2/src/push.c +37 -31
- data/vendor/libgit2/src/push.h +2 -1
- data/vendor/libgit2/src/reader.c +265 -0
- data/vendor/libgit2/src/reader.h +107 -0
- data/vendor/libgit2/src/rebase.c +115 -59
- data/vendor/libgit2/src/refdb.c +15 -3
- data/vendor/libgit2/src/refdb_fs.c +381 -254
- data/vendor/libgit2/src/reflog.c +13 -15
- data/vendor/libgit2/src/refs.c +118 -88
- data/vendor/libgit2/src/refs.h +5 -3
- data/vendor/libgit2/src/refspec.c +56 -37
- data/vendor/libgit2/src/refspec.h +1 -1
- data/vendor/libgit2/src/regexp.c +221 -0
- data/vendor/libgit2/src/regexp.h +97 -0
- data/vendor/libgit2/src/remote.c +266 -215
- data/vendor/libgit2/src/remote.h +11 -2
- data/vendor/libgit2/src/repository.c +280 -225
- data/vendor/libgit2/src/repository.h +52 -40
- data/vendor/libgit2/src/reset.c +8 -8
- data/vendor/libgit2/src/revert.c +14 -9
- data/vendor/libgit2/src/revparse.c +47 -48
- data/vendor/libgit2/src/revwalk.c +120 -57
- data/vendor/libgit2/src/revwalk.h +22 -1
- data/vendor/libgit2/src/settings.c +47 -10
- data/vendor/libgit2/src/signature.c +11 -11
- data/vendor/libgit2/src/sortedcache.c +22 -36
- data/vendor/libgit2/src/sortedcache.h +1 -1
- data/vendor/libgit2/src/stash.c +125 -99
- data/vendor/libgit2/src/status.c +28 -22
- data/vendor/libgit2/src/stream.h +17 -2
- data/vendor/libgit2/src/streams/mbedtls.c +483 -0
- data/vendor/libgit2/src/streams/mbedtls.h +23 -0
- data/vendor/libgit2/src/streams/openssl.c +224 -114
- data/vendor/libgit2/src/streams/openssl.h +4 -108
- data/vendor/libgit2/src/streams/registry.c +118 -0
- data/vendor/libgit2/src/streams/registry.h +19 -0
- data/vendor/libgit2/src/streams/socket.c +55 -30
- data/vendor/libgit2/src/streams/stransport.c +57 -32
- data/vendor/libgit2/src/streams/stransport.h +5 -0
- data/vendor/libgit2/src/streams/tls.c +50 -19
- data/vendor/libgit2/src/streams/tls.h +12 -4
- data/vendor/libgit2/src/strmap.c +47 -74
- data/vendor/libgit2/src/strmap.h +108 -33
- data/vendor/libgit2/src/submodule.c +272 -216
- data/vendor/libgit2/src/submodule.h +1 -1
- data/vendor/libgit2/src/sysdir.c +29 -19
- data/vendor/libgit2/src/tag.c +41 -28
- data/vendor/libgit2/src/tag.h +2 -1
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +3 -3
- data/vendor/libgit2/src/trailer.c +52 -38
- data/vendor/libgit2/src/transaction.c +30 -29
- data/vendor/libgit2/src/transport.c +5 -5
- data/vendor/libgit2/src/transports/auth.c +15 -11
- data/vendor/libgit2/src/transports/auth.h +10 -3
- data/vendor/libgit2/src/transports/auth_negotiate.c +33 -18
- data/vendor/libgit2/src/transports/auth_negotiate.h +2 -2
- data/vendor/libgit2/src/transports/auth_ntlm.c +223 -0
- data/vendor/libgit2/src/transports/auth_ntlm.h +35 -0
- data/vendor/libgit2/src/transports/cred.c +24 -24
- data/vendor/libgit2/src/transports/git.c +26 -31
- data/vendor/libgit2/src/transports/http.c +881 -348
- data/vendor/libgit2/src/transports/http.h +2 -0
- data/vendor/libgit2/src/transports/local.c +35 -35
- data/vendor/libgit2/src/transports/smart.c +70 -47
- data/vendor/libgit2/src/transports/smart.h +3 -4
- data/vendor/libgit2/src/transports/smart_pkt.c +43 -40
- data/vendor/libgit2/src/transports/smart_protocol.c +96 -116
- data/vendor/libgit2/src/transports/ssh.c +77 -66
- data/vendor/libgit2/src/transports/winhttp.c +318 -314
- data/vendor/libgit2/src/tree-cache.c +19 -12
- data/vendor/libgit2/src/tree.c +103 -142
- data/vendor/libgit2/src/tree.h +1 -12
- data/vendor/libgit2/src/unix/map.c +3 -3
- data/vendor/libgit2/src/unix/posix.h +1 -11
- data/vendor/libgit2/src/userdiff.h +3 -1
- data/vendor/libgit2/src/util.c +70 -56
- data/vendor/libgit2/src/util.h +28 -156
- data/vendor/libgit2/src/vector.c +4 -4
- data/vendor/libgit2/src/wildmatch.c +320 -0
- data/vendor/libgit2/src/wildmatch.h +23 -0
- data/vendor/libgit2/src/win32/dir.c +3 -3
- data/vendor/libgit2/src/win32/findfile.c +3 -3
- data/vendor/libgit2/src/win32/map.c +9 -11
- data/vendor/libgit2/src/win32/msvc-compat.h +6 -0
- data/vendor/libgit2/src/win32/path_w32.c +113 -9
- data/vendor/libgit2/src/win32/path_w32.h +18 -29
- data/vendor/libgit2/src/win32/posix.h +1 -4
- data/vendor/libgit2/src/win32/posix_w32.c +70 -45
- data/vendor/libgit2/src/win32/precompiled.h +0 -2
- data/vendor/libgit2/src/win32/thread.c +5 -10
- data/vendor/libgit2/src/win32/w32_buffer.c +9 -5
- data/vendor/libgit2/src/win32/w32_common.h +39 -0
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +3 -2
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +26 -75
- data/vendor/libgit2/src/win32/w32_stack.c +6 -11
- data/vendor/libgit2/src/win32/w32_stack.h +3 -3
- data/vendor/libgit2/src/win32/w32_util.c +27 -64
- data/vendor/libgit2/src/win32/w32_util.h +5 -49
- data/vendor/libgit2/src/worktree.c +95 -60
- data/vendor/libgit2/src/worktree.h +2 -0
- data/vendor/libgit2/src/xdiff/xdiffi.c +7 -5
- data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
- data/vendor/libgit2/src/xdiff/xmerge.c +27 -15
- data/vendor/libgit2/src/xdiff/xpatience.c +3 -0
- data/vendor/libgit2/src/zstream.c +4 -4
- metadata +122 -33
- data/vendor/libgit2/deps/regex/CMakeLists.txt +0 -2
- data/vendor/libgit2/deps/regex/config.h +0 -7
- data/vendor/libgit2/deps/regex/regcomp.c +0 -3857
- data/vendor/libgit2/deps/regex/regex.c +0 -92
- data/vendor/libgit2/deps/regex/regex.h +0 -582
- data/vendor/libgit2/deps/regex/regex_internal.c +0 -1744
- data/vendor/libgit2/deps/regex/regex_internal.h +0 -819
- data/vendor/libgit2/deps/regex/regexec.c +0 -4369
- data/vendor/libgit2/include/git2/inttypes.h +0 -309
- data/vendor/libgit2/include/git2/sys/time.h +0 -31
- data/vendor/libgit2/libgit2.pc.in +0 -13
- data/vendor/libgit2/src/config_file.h +0 -73
- data/vendor/libgit2/src/fnmatch.c +0 -248
- data/vendor/libgit2/src/fnmatch.h +0 -48
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +0 -47
- data/vendor/libgit2/src/hash/hash_openssl.h +0 -59
- data/vendor/libgit2/src/streams/curl.c +0 -385
@@ -0,0 +1,18 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Edward Thomson. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of ntlmclient, distributed under the MIT license.
|
5
|
+
* For full terms and copyright information, and for third-party
|
6
|
+
* copyright information, see the included LICENSE.txt file.
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef PRIVATE_CRYPT_MBEDTLS_H__
|
10
|
+
#define PRIVATE_CRYPT_MBEDTLS_H__
|
11
|
+
|
12
|
+
#include "mbedtls/md.h"
|
13
|
+
|
14
|
+
typedef struct {
|
15
|
+
mbedtls_md_context_t mbed;
|
16
|
+
} ntlm_hmac_ctx;
|
17
|
+
|
18
|
+
#endif /* PRIVATE_CRYPT_MBEDTLS_H__ */
|
@@ -0,0 +1,130 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Edward Thomson. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of ntlmclient, distributed under the MIT license.
|
5
|
+
* For full terms and copyright information, and for third-party
|
6
|
+
* copyright information, see the included LICENSE.txt file.
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <string.h>
|
11
|
+
|
12
|
+
#include <openssl/rand.h>
|
13
|
+
#include <openssl/des.h>
|
14
|
+
#include <openssl/md4.h>
|
15
|
+
#include <openssl/hmac.h>
|
16
|
+
#include <openssl/err.h>
|
17
|
+
|
18
|
+
#include "ntlm.h"
|
19
|
+
#include "compat.h"
|
20
|
+
#include "util.h"
|
21
|
+
#include "crypt.h"
|
22
|
+
|
23
|
+
bool ntlm_random_bytes(
|
24
|
+
ntlm_client *ntlm,
|
25
|
+
unsigned char *out,
|
26
|
+
size_t len)
|
27
|
+
{
|
28
|
+
int rc = RAND_bytes(out, len);
|
29
|
+
|
30
|
+
if (rc != 1) {
|
31
|
+
ntlm_client_set_errmsg(ntlm, ERR_lib_error_string(ERR_get_error()));
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
bool ntlm_des_encrypt(
|
39
|
+
ntlm_des_block *out,
|
40
|
+
ntlm_des_block *plaintext,
|
41
|
+
ntlm_des_block *key)
|
42
|
+
{
|
43
|
+
DES_key_schedule keysched;
|
44
|
+
|
45
|
+
memset(out, 0, sizeof(ntlm_des_block));
|
46
|
+
|
47
|
+
DES_set_key(key, &keysched);
|
48
|
+
DES_ecb_encrypt(plaintext, out, &keysched, DES_ENCRYPT);
|
49
|
+
|
50
|
+
return true;
|
51
|
+
}
|
52
|
+
|
53
|
+
bool ntlm_md4_digest(
|
54
|
+
unsigned char out[CRYPT_MD4_DIGESTSIZE],
|
55
|
+
const unsigned char *in,
|
56
|
+
size_t in_len)
|
57
|
+
{
|
58
|
+
MD4(in, in_len, out);
|
59
|
+
return true;
|
60
|
+
}
|
61
|
+
|
62
|
+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
63
|
+
static inline void HMAC_CTX_free(HMAC_CTX *ctx)
|
64
|
+
{
|
65
|
+
if (ctx)
|
66
|
+
HMAC_CTX_cleanup(ctx);
|
67
|
+
|
68
|
+
free(ctx);
|
69
|
+
}
|
70
|
+
|
71
|
+
static inline int HMAC_CTX_reset(HMAC_CTX *ctx)
|
72
|
+
{
|
73
|
+
HMAC_CTX_cleanup(ctx);
|
74
|
+
memzero(ctx, sizeof(HMAC_CTX));
|
75
|
+
return 1;
|
76
|
+
}
|
77
|
+
|
78
|
+
static inline HMAC_CTX *HMAC_CTX_new(void)
|
79
|
+
{
|
80
|
+
return calloc(1, sizeof(HMAC_CTX));
|
81
|
+
}
|
82
|
+
#endif
|
83
|
+
|
84
|
+
ntlm_hmac_ctx *ntlm_hmac_ctx_init(void)
|
85
|
+
{
|
86
|
+
return HMAC_CTX_new();
|
87
|
+
}
|
88
|
+
|
89
|
+
bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx)
|
90
|
+
{
|
91
|
+
return HMAC_CTX_reset(ctx);
|
92
|
+
}
|
93
|
+
|
94
|
+
bool ntlm_hmac_md5_init(
|
95
|
+
ntlm_hmac_ctx *ctx,
|
96
|
+
const unsigned char *key,
|
97
|
+
size_t key_len)
|
98
|
+
{
|
99
|
+
return HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL);
|
100
|
+
}
|
101
|
+
|
102
|
+
bool ntlm_hmac_md5_update(
|
103
|
+
ntlm_hmac_ctx *ctx,
|
104
|
+
const unsigned char *in,
|
105
|
+
size_t in_len)
|
106
|
+
{
|
107
|
+
return HMAC_Update(ctx, in, in_len);
|
108
|
+
}
|
109
|
+
|
110
|
+
bool ntlm_hmac_md5_final(
|
111
|
+
unsigned char *out,
|
112
|
+
size_t *out_len,
|
113
|
+
ntlm_hmac_ctx *ctx)
|
114
|
+
{
|
115
|
+
unsigned int len;
|
116
|
+
|
117
|
+
if (*out_len < CRYPT_MD5_DIGESTSIZE)
|
118
|
+
return false;
|
119
|
+
|
120
|
+
if (!HMAC_Final(ctx, out, &len))
|
121
|
+
return false;
|
122
|
+
|
123
|
+
*out_len = len;
|
124
|
+
return true;
|
125
|
+
}
|
126
|
+
|
127
|
+
void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx)
|
128
|
+
{
|
129
|
+
HMAC_CTX_free(ctx);
|
130
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Edward Thomson. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of ntlmclient, distributed under the MIT license.
|
5
|
+
* For full terms and copyright information, and for third-party
|
6
|
+
* copyright information, see the included LICENSE.txt file.
|
7
|
+
*/
|
8
|
+
|
9
|
+
#ifndef PRIVATE_CRYPT_OPENSSL_H__
|
10
|
+
#define PRIVATE_CRYPT_OPENSSL_H__
|
11
|
+
|
12
|
+
#include <openssl/hmac.h>
|
13
|
+
|
14
|
+
/* OpenSSL 1.1.0 uses opaque structs, we'll reuse these. */
|
15
|
+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
16
|
+
typedef struct hmac_ctx_st ntlm_hmac_ctx;
|
17
|
+
#else
|
18
|
+
# define ntlm_hmac_ctx HMAC_CTX
|
19
|
+
#endif
|
20
|
+
|
21
|
+
#endif /* PRIVATE_CRYPT_OPENSSL_H__ */
|
@@ -0,0 +1,1420 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) Edward Thomson. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of ntlmclient, distributed under the MIT license.
|
5
|
+
* For full terms and copyright information, and for third-party
|
6
|
+
* copyright information, see the included LICENSE.txt file.
|
7
|
+
*/
|
8
|
+
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <stdint.h>
|
11
|
+
#include <string.h>
|
12
|
+
#include <assert.h>
|
13
|
+
#include <errno.h>
|
14
|
+
#include <ctype.h>
|
15
|
+
#include <unistd.h>
|
16
|
+
#include <fcntl.h>
|
17
|
+
#include <time.h>
|
18
|
+
#include <arpa/inet.h>
|
19
|
+
|
20
|
+
#include "ntlm.h"
|
21
|
+
#include "unicode.h"
|
22
|
+
#include "utf8.h"
|
23
|
+
#include "crypt.h"
|
24
|
+
#include "compat.h"
|
25
|
+
#include "util.h"
|
26
|
+
|
27
|
+
unsigned char ntlm_client_signature[] = NTLM_SIGNATURE;
|
28
|
+
|
29
|
+
static bool supports_unicode(ntlm_client *ntlm)
|
30
|
+
{
|
31
|
+
return (ntlm->flags & NTLM_CLIENT_DISABLE_UNICODE) ?
|
32
|
+
false : true;
|
33
|
+
}
|
34
|
+
|
35
|
+
static inline bool increment_size(size_t *out, size_t incr)
|
36
|
+
{
|
37
|
+
if (SIZE_MAX - *out < incr) {
|
38
|
+
*out = (size_t)-1;
|
39
|
+
return false;
|
40
|
+
}
|
41
|
+
|
42
|
+
*out = *out + incr;
|
43
|
+
return true;
|
44
|
+
}
|
45
|
+
|
46
|
+
ntlm_client *ntlm_client_init(ntlm_client_flags flags)
|
47
|
+
{
|
48
|
+
ntlm_client *ntlm = NULL;
|
49
|
+
|
50
|
+
if ((ntlm = malloc(sizeof(ntlm_client))) == NULL)
|
51
|
+
return NULL;
|
52
|
+
|
53
|
+
memset(ntlm, 0, sizeof(ntlm_client));
|
54
|
+
|
55
|
+
ntlm->flags = flags;
|
56
|
+
|
57
|
+
if ((ntlm->hmac_ctx = ntlm_hmac_ctx_init()) == NULL ||
|
58
|
+
(ntlm->unicode_ctx = ntlm_unicode_ctx_init(ntlm)) == NULL) {
|
59
|
+
ntlm_hmac_ctx_free(ntlm->hmac_ctx);
|
60
|
+
ntlm_unicode_ctx_free(ntlm->unicode_ctx);
|
61
|
+
free(ntlm);
|
62
|
+
return NULL;
|
63
|
+
}
|
64
|
+
|
65
|
+
return ntlm;
|
66
|
+
}
|
67
|
+
|
68
|
+
void ntlm_client_set_errmsg(ntlm_client *ntlm, const char *errmsg)
|
69
|
+
{
|
70
|
+
ntlm->state = NTLM_STATE_ERROR;
|
71
|
+
ntlm->errmsg = errmsg;
|
72
|
+
}
|
73
|
+
|
74
|
+
const char *ntlm_client_errmsg(ntlm_client *ntlm)
|
75
|
+
{
|
76
|
+
assert(ntlm);
|
77
|
+
return ntlm->errmsg ? ntlm->errmsg : "no error";
|
78
|
+
}
|
79
|
+
|
80
|
+
int ntlm_client_set_version(
|
81
|
+
ntlm_client *ntlm,
|
82
|
+
uint8_t major,
|
83
|
+
uint8_t minor,
|
84
|
+
uint16_t build)
|
85
|
+
{
|
86
|
+
assert(ntlm);
|
87
|
+
|
88
|
+
ntlm->host_version.major = major;
|
89
|
+
ntlm->host_version.minor = minor;
|
90
|
+
ntlm->host_version.build = build;
|
91
|
+
ntlm->host_version.reserved = 0x0f000000;
|
92
|
+
|
93
|
+
ntlm->flags |= NTLM_ENABLE_HOSTVERSION;
|
94
|
+
|
95
|
+
return 0;
|
96
|
+
}
|
97
|
+
|
98
|
+
int ntlm_client_set_hostname(
|
99
|
+
ntlm_client *ntlm,
|
100
|
+
const char *hostname,
|
101
|
+
const char *domain)
|
102
|
+
{
|
103
|
+
assert(ntlm);
|
104
|
+
|
105
|
+
free(ntlm->hostname);
|
106
|
+
free(ntlm->hostdomain);
|
107
|
+
free(ntlm->hostname_utf16);
|
108
|
+
|
109
|
+
ntlm->hostname = NULL;
|
110
|
+
ntlm->hostdomain = NULL;
|
111
|
+
ntlm->hostname_utf16 = NULL;
|
112
|
+
|
113
|
+
if (hostname && (ntlm->hostname = strdup(hostname)) == NULL) {
|
114
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
115
|
+
return -1;
|
116
|
+
}
|
117
|
+
|
118
|
+
if (domain && (ntlm->hostdomain = strdup(domain)) == NULL) {
|
119
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
120
|
+
return -1;
|
121
|
+
}
|
122
|
+
|
123
|
+
if (hostname && supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16(
|
124
|
+
&ntlm->hostname_utf16,
|
125
|
+
&ntlm->hostname_utf16_len,
|
126
|
+
ntlm->unicode_ctx,
|
127
|
+
hostname,
|
128
|
+
strlen(hostname)))
|
129
|
+
return -1;
|
130
|
+
|
131
|
+
return 0;
|
132
|
+
}
|
133
|
+
|
134
|
+
static void free_credentials(ntlm_client *ntlm)
|
135
|
+
{
|
136
|
+
if (ntlm->password)
|
137
|
+
memzero(ntlm->password, strlen(ntlm->password));
|
138
|
+
|
139
|
+
if (ntlm->password_utf16)
|
140
|
+
memzero(ntlm->password_utf16, ntlm->password_utf16_len);
|
141
|
+
|
142
|
+
free(ntlm->username);
|
143
|
+
free(ntlm->username_upper);
|
144
|
+
free(ntlm->userdomain);
|
145
|
+
free(ntlm->password);
|
146
|
+
|
147
|
+
free(ntlm->username_utf16);
|
148
|
+
free(ntlm->username_upper_utf16);
|
149
|
+
free(ntlm->userdomain_utf16);
|
150
|
+
free(ntlm->password_utf16);
|
151
|
+
|
152
|
+
ntlm->username = NULL;
|
153
|
+
ntlm->username_upper = NULL;
|
154
|
+
ntlm->userdomain = NULL;
|
155
|
+
ntlm->password = NULL;
|
156
|
+
|
157
|
+
ntlm->username_utf16 = NULL;
|
158
|
+
ntlm->username_upper_utf16 = NULL;
|
159
|
+
ntlm->userdomain_utf16 = NULL;
|
160
|
+
ntlm->password_utf16 = NULL;
|
161
|
+
}
|
162
|
+
|
163
|
+
int ntlm_client_set_credentials(
|
164
|
+
ntlm_client *ntlm,
|
165
|
+
const char *username,
|
166
|
+
const char *domain,
|
167
|
+
const char *password)
|
168
|
+
{
|
169
|
+
assert(ntlm);
|
170
|
+
|
171
|
+
free_credentials(ntlm);
|
172
|
+
|
173
|
+
if ((username && (ntlm->username = strdup(username)) == NULL) ||
|
174
|
+
(domain && (ntlm->userdomain = strdup(domain)) == NULL) ||
|
175
|
+
(password && (ntlm->password = strdup(password)) == NULL)) {
|
176
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
177
|
+
return -1;
|
178
|
+
}
|
179
|
+
|
180
|
+
if (username && supports_unicode(ntlm)) {
|
181
|
+
if ((ntlm->username_upper = strdup(username)) == NULL) {
|
182
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
183
|
+
return -1;
|
184
|
+
}
|
185
|
+
utf8upr(ntlm->username_upper);
|
186
|
+
|
187
|
+
if (!ntlm_unicode_utf8_to_16(
|
188
|
+
&ntlm->username_utf16,
|
189
|
+
&ntlm->username_utf16_len,
|
190
|
+
ntlm->unicode_ctx,
|
191
|
+
ntlm->username,
|
192
|
+
strlen(ntlm->username)))
|
193
|
+
return -1;
|
194
|
+
|
195
|
+
if (!ntlm_unicode_utf8_to_16(
|
196
|
+
&ntlm->username_upper_utf16,
|
197
|
+
&ntlm->username_upper_utf16_len,
|
198
|
+
ntlm->unicode_ctx,
|
199
|
+
ntlm->username_upper,
|
200
|
+
strlen(ntlm->username_upper)))
|
201
|
+
return -1;
|
202
|
+
}
|
203
|
+
|
204
|
+
if (domain && supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16(
|
205
|
+
&ntlm->userdomain_utf16,
|
206
|
+
&ntlm->userdomain_utf16_len,
|
207
|
+
ntlm->unicode_ctx,
|
208
|
+
ntlm->userdomain,
|
209
|
+
strlen(ntlm->userdomain)))
|
210
|
+
return -1;
|
211
|
+
|
212
|
+
return 0;
|
213
|
+
}
|
214
|
+
|
215
|
+
int ntlm_client_set_target(ntlm_client *ntlm, const char *target)
|
216
|
+
{
|
217
|
+
assert(ntlm);
|
218
|
+
|
219
|
+
free(ntlm->target);
|
220
|
+
free(ntlm->target_utf16);
|
221
|
+
|
222
|
+
ntlm->target = NULL;
|
223
|
+
ntlm->target_utf16 = NULL;
|
224
|
+
|
225
|
+
if (target) {
|
226
|
+
if ((ntlm->target = strdup(target)) == NULL) {
|
227
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
228
|
+
return -1;
|
229
|
+
}
|
230
|
+
|
231
|
+
if (supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16(
|
232
|
+
&ntlm->target_utf16,
|
233
|
+
&ntlm->target_utf16_len,
|
234
|
+
ntlm->unicode_ctx,
|
235
|
+
ntlm->target,
|
236
|
+
strlen(ntlm->target)))
|
237
|
+
return -1;
|
238
|
+
}
|
239
|
+
|
240
|
+
return 0;
|
241
|
+
}
|
242
|
+
|
243
|
+
int ntlm_client_set_nonce(ntlm_client *ntlm, uint64_t nonce)
|
244
|
+
{
|
245
|
+
assert(ntlm);
|
246
|
+
ntlm->nonce = nonce;
|
247
|
+
return 0;
|
248
|
+
}
|
249
|
+
|
250
|
+
int ntlm_client_set_timestamp(ntlm_client *ntlm, uint64_t timestamp)
|
251
|
+
{
|
252
|
+
assert(ntlm);
|
253
|
+
ntlm->timestamp = timestamp;
|
254
|
+
return 0;
|
255
|
+
}
|
256
|
+
|
257
|
+
static inline bool write_buf(
|
258
|
+
ntlm_client *ntlm,
|
259
|
+
ntlm_buf *out,
|
260
|
+
const unsigned char *buf,
|
261
|
+
size_t len)
|
262
|
+
{
|
263
|
+
if (out->len - out->pos < len) {
|
264
|
+
ntlm_client_set_errmsg(ntlm, "out of buffer space");
|
265
|
+
return false;
|
266
|
+
}
|
267
|
+
|
268
|
+
memcpy(&out->buf[out->pos], buf, len);
|
269
|
+
out->pos += len;
|
270
|
+
return true;
|
271
|
+
}
|
272
|
+
|
273
|
+
static inline bool write_byte(
|
274
|
+
ntlm_client *ntlm,
|
275
|
+
ntlm_buf *out,
|
276
|
+
uint8_t value)
|
277
|
+
{
|
278
|
+
if (out->len - out->pos < 1) {
|
279
|
+
ntlm_client_set_errmsg(ntlm, "out of buffer space");
|
280
|
+
return false;
|
281
|
+
}
|
282
|
+
|
283
|
+
out->buf[out->pos++] = value;
|
284
|
+
return true;
|
285
|
+
}
|
286
|
+
|
287
|
+
static inline bool write_int16(
|
288
|
+
ntlm_client *ntlm,
|
289
|
+
ntlm_buf *out,
|
290
|
+
uint16_t value)
|
291
|
+
{
|
292
|
+
if (out->len - out->pos < 2) {
|
293
|
+
ntlm_client_set_errmsg(ntlm, "out of buffer space");
|
294
|
+
return false;
|
295
|
+
}
|
296
|
+
|
297
|
+
out->buf[out->pos++] = (value & 0x000000ff);
|
298
|
+
out->buf[out->pos++] = (value & 0x0000ff00) >> 8;
|
299
|
+
return true;
|
300
|
+
}
|
301
|
+
|
302
|
+
static inline bool write_int32(
|
303
|
+
ntlm_client *ntlm,
|
304
|
+
ntlm_buf *out,
|
305
|
+
uint32_t value)
|
306
|
+
{
|
307
|
+
if (out->len - out->pos < 2) {
|
308
|
+
ntlm_client_set_errmsg(ntlm, "out of buffer space");
|
309
|
+
return false;
|
310
|
+
}
|
311
|
+
|
312
|
+
out->buf[out->pos++] = (value & 0x000000ff);
|
313
|
+
out->buf[out->pos++] = (value & 0x0000ff00) >> 8;
|
314
|
+
out->buf[out->pos++] = (value & 0x00ff0000) >> 16;
|
315
|
+
out->buf[out->pos++] = (value & 0xff000000) >> 24;
|
316
|
+
return true;
|
317
|
+
}
|
318
|
+
|
319
|
+
static inline bool write_version(
|
320
|
+
ntlm_client *ntlm,
|
321
|
+
ntlm_buf *out,
|
322
|
+
ntlm_version *version)
|
323
|
+
{
|
324
|
+
return write_byte(ntlm, out, version->major) &&
|
325
|
+
write_byte(ntlm, out, version->minor) &&
|
326
|
+
write_int16(ntlm, out, version->build) &&
|
327
|
+
write_int32(ntlm, out, version->reserved);
|
328
|
+
}
|
329
|
+
|
330
|
+
static inline bool write_bufinfo(
|
331
|
+
ntlm_client *ntlm,
|
332
|
+
ntlm_buf *out,
|
333
|
+
size_t len,
|
334
|
+
size_t offset)
|
335
|
+
{
|
336
|
+
if (len > UINT16_MAX) {
|
337
|
+
ntlm_client_set_errmsg(ntlm, "invalid string, too long");
|
338
|
+
return false;
|
339
|
+
}
|
340
|
+
|
341
|
+
if (offset > UINT32_MAX) {
|
342
|
+
ntlm_client_set_errmsg(ntlm, "invalid string, invalid offset");
|
343
|
+
return false;
|
344
|
+
}
|
345
|
+
|
346
|
+
return write_int16(ntlm, out, (uint16_t)len) &&
|
347
|
+
write_int16(ntlm, out, (uint16_t)len) &&
|
348
|
+
write_int32(ntlm, out, (uint32_t)offset);
|
349
|
+
}
|
350
|
+
|
351
|
+
static inline bool read_buf(
|
352
|
+
unsigned char *out,
|
353
|
+
ntlm_client *ntlm,
|
354
|
+
ntlm_buf *message,
|
355
|
+
size_t len)
|
356
|
+
{
|
357
|
+
if (message->len - message->pos < len) {
|
358
|
+
ntlm_client_set_errmsg(ntlm, "truncated message");
|
359
|
+
return false;
|
360
|
+
}
|
361
|
+
|
362
|
+
memcpy(out, &message->buf[message->pos], len);
|
363
|
+
message->pos += len;
|
364
|
+
|
365
|
+
return true;
|
366
|
+
}
|
367
|
+
|
368
|
+
static inline bool read_byte(
|
369
|
+
uint8_t *out,
|
370
|
+
ntlm_client *ntlm,
|
371
|
+
ntlm_buf *message)
|
372
|
+
{
|
373
|
+
if (message->len - message->pos < 1) {
|
374
|
+
ntlm_client_set_errmsg(ntlm, "truncated message");
|
375
|
+
return false;
|
376
|
+
}
|
377
|
+
|
378
|
+
*out = message->buf[message->pos++];
|
379
|
+
return true;
|
380
|
+
}
|
381
|
+
|
382
|
+
static inline bool read_int16(
|
383
|
+
uint16_t *out,
|
384
|
+
ntlm_client *ntlm,
|
385
|
+
ntlm_buf *message)
|
386
|
+
{
|
387
|
+
if (message->len - message->pos < 2) {
|
388
|
+
ntlm_client_set_errmsg(ntlm, "truncated message");
|
389
|
+
return false;
|
390
|
+
}
|
391
|
+
|
392
|
+
*out =
|
393
|
+
((message->buf[message->pos] & 0xff)) |
|
394
|
+
((message->buf[message->pos+1] & 0xff) << 8);
|
395
|
+
|
396
|
+
message->pos += 2;
|
397
|
+
return true;
|
398
|
+
}
|
399
|
+
|
400
|
+
static inline bool read_int32(
|
401
|
+
uint32_t *out,
|
402
|
+
ntlm_client *ntlm,
|
403
|
+
ntlm_buf *message)
|
404
|
+
{
|
405
|
+
if (message->len - message->pos < 4) {
|
406
|
+
ntlm_client_set_errmsg(ntlm, "truncated message");
|
407
|
+
return false;
|
408
|
+
}
|
409
|
+
|
410
|
+
*out =
|
411
|
+
((message->buf[message->pos] & 0xff)) |
|
412
|
+
((message->buf[message->pos+1] & 0xff) << 8) |
|
413
|
+
((message->buf[message->pos+2] & 0xff) << 16) |
|
414
|
+
((message->buf[message->pos+3] & 0xff) << 24);
|
415
|
+
|
416
|
+
message->pos += 4;
|
417
|
+
return true;
|
418
|
+
}
|
419
|
+
|
420
|
+
static inline bool read_int64(
|
421
|
+
uint64_t *out,
|
422
|
+
ntlm_client *ntlm,
|
423
|
+
ntlm_buf *message)
|
424
|
+
{
|
425
|
+
if (message->len - message->pos < 8) {
|
426
|
+
ntlm_client_set_errmsg(ntlm, "truncated message");
|
427
|
+
return false;
|
428
|
+
}
|
429
|
+
|
430
|
+
*out =
|
431
|
+
((uint64_t)(message->buf[message->pos] & 0xff)) |
|
432
|
+
((uint64_t)(message->buf[message->pos+1] & 0xff) << 8) |
|
433
|
+
((uint64_t)(message->buf[message->pos+2] & 0xff) << 16) |
|
434
|
+
((uint64_t)(message->buf[message->pos+3] & 0xff) << 24) |
|
435
|
+
((uint64_t)(message->buf[message->pos+4] & 0xff) << 32) |
|
436
|
+
((uint64_t)(message->buf[message->pos+5] & 0xff) << 40) |
|
437
|
+
((uint64_t)(message->buf[message->pos+6] & 0xff) << 48) |
|
438
|
+
((uint64_t)(message->buf[message->pos+7] & 0xff) << 56);
|
439
|
+
|
440
|
+
message->pos += 8;
|
441
|
+
return true;
|
442
|
+
}
|
443
|
+
|
444
|
+
static inline bool read_version(
|
445
|
+
ntlm_version *out,
|
446
|
+
ntlm_client *ntlm,
|
447
|
+
ntlm_buf *message)
|
448
|
+
{
|
449
|
+
return read_byte(&out->major, ntlm, message) &&
|
450
|
+
read_byte(&out->minor, ntlm, message) &&
|
451
|
+
read_int16(&out->build, ntlm, message) &&
|
452
|
+
read_int32(&out->reserved, ntlm, message);
|
453
|
+
}
|
454
|
+
|
455
|
+
static inline bool read_bufinfo(
|
456
|
+
uint16_t *out_len,
|
457
|
+
uint32_t *out_offset,
|
458
|
+
ntlm_client *ntlm,
|
459
|
+
ntlm_buf *message)
|
460
|
+
{
|
461
|
+
uint16_t allocated;
|
462
|
+
|
463
|
+
return read_int16(out_len, ntlm, message) &&
|
464
|
+
read_int16(&allocated, ntlm, message) &&
|
465
|
+
read_int32(out_offset, ntlm, message);
|
466
|
+
}
|
467
|
+
|
468
|
+
static inline bool read_string_unicode(
|
469
|
+
char **out,
|
470
|
+
ntlm_client *ntlm,
|
471
|
+
ntlm_buf *message,
|
472
|
+
uint8_t string_len)
|
473
|
+
{
|
474
|
+
size_t out_len;
|
475
|
+
int ret = ntlm_unicode_utf16_to_8(out,
|
476
|
+
&out_len,
|
477
|
+
ntlm->unicode_ctx,
|
478
|
+
(char *)&message->buf[message->pos],
|
479
|
+
string_len);
|
480
|
+
|
481
|
+
message->pos += string_len;
|
482
|
+
|
483
|
+
return ret;
|
484
|
+
}
|
485
|
+
|
486
|
+
static inline bool read_string_ascii(
|
487
|
+
char **out,
|
488
|
+
ntlm_client *ntlm,
|
489
|
+
ntlm_buf *message,
|
490
|
+
uint8_t string_len)
|
491
|
+
{
|
492
|
+
char *str;
|
493
|
+
|
494
|
+
if ((str = malloc(string_len + 1)) == NULL) {
|
495
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
496
|
+
return false;
|
497
|
+
}
|
498
|
+
|
499
|
+
memcpy(str, &message->buf[message->pos], string_len);
|
500
|
+
str[string_len] = '\0';
|
501
|
+
|
502
|
+
message->pos += string_len;
|
503
|
+
|
504
|
+
*out = str;
|
505
|
+
return true;
|
506
|
+
}
|
507
|
+
|
508
|
+
static inline bool read_string(
|
509
|
+
char **out,
|
510
|
+
ntlm_client *ntlm,
|
511
|
+
ntlm_buf *message,
|
512
|
+
uint8_t string_len,
|
513
|
+
bool unicode)
|
514
|
+
{
|
515
|
+
if (unicode)
|
516
|
+
return read_string_unicode(out, ntlm, message, string_len);
|
517
|
+
else
|
518
|
+
return read_string_ascii(out, ntlm, message, string_len);
|
519
|
+
}
|
520
|
+
|
521
|
+
static inline bool read_target_info(
|
522
|
+
char **server_out,
|
523
|
+
char **domain_out,
|
524
|
+
char **server_dns_out,
|
525
|
+
char **domain_dns_out,
|
526
|
+
ntlm_client *ntlm,
|
527
|
+
ntlm_buf *message,
|
528
|
+
bool unicode)
|
529
|
+
{
|
530
|
+
uint16_t block_type, block_len;
|
531
|
+
bool done = false;
|
532
|
+
|
533
|
+
*server_out = NULL;
|
534
|
+
*domain_out = NULL;
|
535
|
+
*server_dns_out = NULL;
|
536
|
+
*domain_dns_out = NULL;
|
537
|
+
|
538
|
+
while (!done && (message->len - message->pos) >= 4) {
|
539
|
+
if (!read_int16(&block_type, ntlm, message) ||
|
540
|
+
!read_int16(&block_len, ntlm, message)) {
|
541
|
+
ntlm_client_set_errmsg(ntlm, "truncated target info block");
|
542
|
+
return false;
|
543
|
+
}
|
544
|
+
|
545
|
+
if (!block_type && block_len) {
|
546
|
+
ntlm_client_set_errmsg(ntlm, "invalid target info block");
|
547
|
+
return -1;
|
548
|
+
}
|
549
|
+
|
550
|
+
switch (block_type) {
|
551
|
+
case NTLM_TARGET_INFO_DOMAIN:
|
552
|
+
if (!read_string(domain_out, ntlm, message, block_len, unicode))
|
553
|
+
return -1;
|
554
|
+
break;
|
555
|
+
case NTLM_TARGET_INFO_SERVER:
|
556
|
+
if (!read_string(server_out, ntlm, message, block_len, unicode))
|
557
|
+
return -1;
|
558
|
+
break;
|
559
|
+
case NTLM_TARGET_INFO_DOMAIN_DNS:
|
560
|
+
if (!read_string(domain_dns_out, ntlm, message, block_len, unicode))
|
561
|
+
return -1;
|
562
|
+
break;
|
563
|
+
case NTLM_TARGET_INFO_SERVER_DNS:
|
564
|
+
if (!read_string(server_dns_out, ntlm, message, block_len, unicode))
|
565
|
+
return -1;
|
566
|
+
break;
|
567
|
+
case NTLM_TARGET_INFO_END:
|
568
|
+
done = true;
|
569
|
+
break;
|
570
|
+
default:
|
571
|
+
ntlm_client_set_errmsg(ntlm, "unknown target info block type");
|
572
|
+
return -1;
|
573
|
+
}
|
574
|
+
}
|
575
|
+
|
576
|
+
if (message->len != message->pos) {
|
577
|
+
ntlm_client_set_errmsg(ntlm,
|
578
|
+
"invalid extra data in target info section");
|
579
|
+
return false;
|
580
|
+
}
|
581
|
+
|
582
|
+
return true;
|
583
|
+
}
|
584
|
+
|
585
|
+
int ntlm_client_negotiate(
|
586
|
+
const unsigned char **out,
|
587
|
+
size_t *out_len,
|
588
|
+
ntlm_client *ntlm)
|
589
|
+
{
|
590
|
+
size_t hostname_len, hostname_offset, domain_len, domain_offset;
|
591
|
+
uint32_t flags = 0;
|
592
|
+
|
593
|
+
assert(out && out_len && ntlm);
|
594
|
+
|
595
|
+
*out = NULL;
|
596
|
+
*out_len = 0;
|
597
|
+
|
598
|
+
if (ntlm->state != NTLM_STATE_NEGOTIATE) {
|
599
|
+
ntlm_client_set_errmsg(ntlm, "ntlm handle in invalid state");
|
600
|
+
return -1;
|
601
|
+
}
|
602
|
+
|
603
|
+
flags |= NTLM_NEGOTIATE_OEM;
|
604
|
+
|
605
|
+
if (supports_unicode(ntlm))
|
606
|
+
flags |= NTLM_NEGOTIATE_UNICODE;
|
607
|
+
|
608
|
+
if (!(ntlm->flags & NTLM_CLIENT_DISABLE_NTLM2) ||
|
609
|
+
(ntlm->flags & NTLM_CLIENT_ENABLE_NTLM))
|
610
|
+
flags |= NTLM_NEGOTIATE_NTLM;
|
611
|
+
|
612
|
+
if (!(ntlm->flags & NTLM_CLIENT_DISABLE_REQUEST_TARGET))
|
613
|
+
flags |= NTLM_NEGOTIATE_REQUEST_TARGET;
|
614
|
+
|
615
|
+
hostname_len = ntlm->hostname ? strlen(ntlm->hostname) : 0;
|
616
|
+
domain_len = ntlm->hostdomain ? strlen(ntlm->hostdomain) : 0;
|
617
|
+
|
618
|
+
/* Minimum header size */
|
619
|
+
ntlm->negotiate.len = 16;
|
620
|
+
|
621
|
+
/* Include space for security buffer descriptors */
|
622
|
+
if (domain_len)
|
623
|
+
increment_size(&ntlm->negotiate.len, 8);
|
624
|
+
|
625
|
+
if (hostname_len)
|
626
|
+
increment_size(&ntlm->negotiate.len, 8);
|
627
|
+
|
628
|
+
if (ntlm->flags & NTLM_ENABLE_HOSTVERSION)
|
629
|
+
increment_size(&ntlm->negotiate.len, 8);
|
630
|
+
|
631
|
+
/* Location of security buffers */
|
632
|
+
if (hostname_len) {
|
633
|
+
flags |= NTLM_NEGOTIATE_WORKSTATION_SUPPLIED;
|
634
|
+
hostname_offset = ntlm->negotiate.len;
|
635
|
+
increment_size(&ntlm->negotiate.len, hostname_len);
|
636
|
+
}
|
637
|
+
|
638
|
+
if (domain_len) {
|
639
|
+
flags |= NTLM_NEGOTIATE_DOMAIN_SUPPLIED;
|
640
|
+
domain_offset = ntlm->negotiate.len;
|
641
|
+
increment_size(&ntlm->negotiate.len, domain_len);
|
642
|
+
}
|
643
|
+
|
644
|
+
if (ntlm->negotiate.len == (size_t)-1) {
|
645
|
+
ntlm_client_set_errmsg(ntlm, "message too large");
|
646
|
+
return -1;
|
647
|
+
}
|
648
|
+
|
649
|
+
if ((ntlm->negotiate.buf = malloc(ntlm->negotiate.len)) == NULL) {
|
650
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
651
|
+
return -1;
|
652
|
+
}
|
653
|
+
|
654
|
+
memset(ntlm->negotiate.buf, 0, ntlm->negotiate.len);
|
655
|
+
|
656
|
+
if (!write_buf(ntlm, &ntlm->negotiate,
|
657
|
+
ntlm_client_signature, sizeof(ntlm_client_signature)) ||
|
658
|
+
!write_int32(ntlm, &ntlm->negotiate, 1) ||
|
659
|
+
!write_int32(ntlm, &ntlm->negotiate, flags))
|
660
|
+
return -1;
|
661
|
+
|
662
|
+
/* Domain information */
|
663
|
+
if (domain_len > 0 &&
|
664
|
+
!write_bufinfo(ntlm, &ntlm->negotiate, domain_len, domain_offset))
|
665
|
+
return -1;
|
666
|
+
|
667
|
+
/* Workstation information */
|
668
|
+
if (hostname_len > 0 &&
|
669
|
+
!write_bufinfo(ntlm, &ntlm->negotiate, hostname_len, hostname_offset))
|
670
|
+
return -1;
|
671
|
+
|
672
|
+
/* Version number */
|
673
|
+
if (!!(ntlm->flags & NTLM_ENABLE_HOSTVERSION) &&
|
674
|
+
!write_version(ntlm, &ntlm->negotiate, &ntlm->host_version))
|
675
|
+
return -1;
|
676
|
+
|
677
|
+
if (hostname_len > 0) {
|
678
|
+
assert(hostname_offset == ntlm->negotiate.pos);
|
679
|
+
if (!write_buf(ntlm, &ntlm->negotiate,
|
680
|
+
(const unsigned char *)ntlm->hostname, hostname_len))
|
681
|
+
return -1;
|
682
|
+
}
|
683
|
+
|
684
|
+
if (domain_len > 0) {
|
685
|
+
assert(domain_offset == ntlm->negotiate.pos);
|
686
|
+
if (!write_buf(ntlm, &ntlm->negotiate,
|
687
|
+
(const unsigned char *)ntlm->hostdomain, domain_len))
|
688
|
+
return -1;
|
689
|
+
}
|
690
|
+
|
691
|
+
assert(ntlm->negotiate.pos == ntlm->negotiate.len);
|
692
|
+
|
693
|
+
ntlm->state = NTLM_STATE_CHALLENGE;
|
694
|
+
|
695
|
+
*out = ntlm->negotiate.buf;
|
696
|
+
*out_len = ntlm->negotiate.len;
|
697
|
+
|
698
|
+
return 0;
|
699
|
+
}
|
700
|
+
|
701
|
+
int ntlm_client_set_challenge(
|
702
|
+
ntlm_client *ntlm,
|
703
|
+
const unsigned char *challenge_msg,
|
704
|
+
size_t challenge_msg_len)
|
705
|
+
{
|
706
|
+
unsigned char signature[8];
|
707
|
+
ntlm_buf challenge;
|
708
|
+
uint32_t type_indicator, header_end;
|
709
|
+
uint16_t name_len, info_len = 0;
|
710
|
+
uint32_t name_offset, info_offset = 0;
|
711
|
+
bool unicode, has_target_info = false;
|
712
|
+
|
713
|
+
assert(ntlm && (challenge_msg || !challenge_msg_len));
|
714
|
+
|
715
|
+
if (ntlm->state != NTLM_STATE_NEGOTIATE &&
|
716
|
+
ntlm->state != NTLM_STATE_CHALLENGE) {
|
717
|
+
ntlm_client_set_errmsg(ntlm, "ntlm handle in invalid state");
|
718
|
+
return -1;
|
719
|
+
}
|
720
|
+
|
721
|
+
challenge.buf = (unsigned char *)challenge_msg;
|
722
|
+
challenge.len = challenge_msg_len;
|
723
|
+
challenge.pos = 0;
|
724
|
+
|
725
|
+
if (!read_buf(signature, ntlm, &challenge, 8) ||
|
726
|
+
!read_int32(&type_indicator, ntlm, &challenge) ||
|
727
|
+
!read_bufinfo(&name_len, &name_offset, ntlm, &challenge) ||
|
728
|
+
!read_int32(&ntlm->challenge.flags, ntlm, &challenge) ||
|
729
|
+
!read_int64(&ntlm->challenge.nonce, ntlm, &challenge))
|
730
|
+
return -1;
|
731
|
+
|
732
|
+
if (memcmp(signature,
|
733
|
+
ntlm_client_signature, sizeof(ntlm_client_signature)) != 0) {
|
734
|
+
ntlm_client_set_errmsg(ntlm, "invalid message signature");
|
735
|
+
return -1;
|
736
|
+
}
|
737
|
+
|
738
|
+
if (type_indicator != 2) {
|
739
|
+
ntlm_client_set_errmsg(ntlm, "invalid message indicator");
|
740
|
+
return -1;
|
741
|
+
}
|
742
|
+
|
743
|
+
/*
|
744
|
+
* If there's additional space before the data section, that's the
|
745
|
+
* target information description section.
|
746
|
+
*/
|
747
|
+
header_end = challenge.len;
|
748
|
+
|
749
|
+
if (name_offset && name_offset < header_end)
|
750
|
+
header_end = name_offset;
|
751
|
+
|
752
|
+
if ((header_end - challenge.pos) >= 16) {
|
753
|
+
has_target_info = true;
|
754
|
+
}
|
755
|
+
|
756
|
+
if (!has_target_info &&
|
757
|
+
(ntlm->challenge.flags & NTLM_NEGOTIATE_TARGET_INFO)) {
|
758
|
+
ntlm_client_set_errmsg(ntlm,
|
759
|
+
"truncated message; expected target info");
|
760
|
+
return -1;
|
761
|
+
}
|
762
|
+
|
763
|
+
/*
|
764
|
+
* If there's a target info section then advanced over the reserved
|
765
|
+
* space and read the target information.
|
766
|
+
*/
|
767
|
+
if (has_target_info) {
|
768
|
+
uint64_t reserved;
|
769
|
+
|
770
|
+
if (!read_int64(&reserved, ntlm, &challenge)) {
|
771
|
+
ntlm_client_set_errmsg(ntlm,
|
772
|
+
"truncated message; expected reserved space");
|
773
|
+
return -1;
|
774
|
+
}
|
775
|
+
|
776
|
+
if (reserved != 0) {
|
777
|
+
ntlm_client_set_errmsg(ntlm,
|
778
|
+
"invalid message; expected reserved space to be empty");
|
779
|
+
return -1;
|
780
|
+
}
|
781
|
+
|
782
|
+
if (!read_bufinfo(&info_len, &info_offset, ntlm, &challenge)) {
|
783
|
+
ntlm_client_set_errmsg(ntlm,
|
784
|
+
"truncated message; expected target info");
|
785
|
+
return -1;
|
786
|
+
}
|
787
|
+
}
|
788
|
+
|
789
|
+
unicode = !!(ntlm->challenge.flags & NTLM_NEGOTIATE_UNICODE);
|
790
|
+
|
791
|
+
/*
|
792
|
+
* If there's still additional space before the data section,
|
793
|
+
* that's the server's version information.
|
794
|
+
*/
|
795
|
+
if (info_offset && info_offset < header_end)
|
796
|
+
header_end = info_offset;
|
797
|
+
|
798
|
+
if (ntlm->challenge.flags & NTLM_NEGOTIATE_VERSION) {
|
799
|
+
if ((header_end - challenge.pos) != sizeof(ntlm_version) ||
|
800
|
+
!read_version(&ntlm->challenge.target_version,
|
801
|
+
ntlm, &challenge)) {
|
802
|
+
ntlm_client_set_errmsg(ntlm,
|
803
|
+
"truncated message; expected version");
|
804
|
+
return -1;
|
805
|
+
}
|
806
|
+
}
|
807
|
+
|
808
|
+
/* validate data section */
|
809
|
+
if ((name_offset && name_offset < challenge.pos) ||
|
810
|
+
challenge.len < name_len ||
|
811
|
+
(challenge.len - name_len) < name_offset) {
|
812
|
+
ntlm_client_set_errmsg(ntlm,
|
813
|
+
"invalid message; invalid target name buffer");
|
814
|
+
return -1;
|
815
|
+
}
|
816
|
+
if ((info_offset && info_offset < challenge.pos) ||
|
817
|
+
challenge.len < info_len ||
|
818
|
+
(challenge.len - info_len) < info_offset) {
|
819
|
+
ntlm_client_set_errmsg(ntlm,
|
820
|
+
"invalid message; invalid target info buffer");
|
821
|
+
return -1;
|
822
|
+
}
|
823
|
+
|
824
|
+
/* advance to the data section */
|
825
|
+
if (name_len && name_offset) {
|
826
|
+
challenge.pos = name_offset;
|
827
|
+
|
828
|
+
if (!read_string(&ntlm->challenge.target,
|
829
|
+
ntlm, &challenge, name_len, unicode)) {
|
830
|
+
ntlm_client_set_errmsg(ntlm,
|
831
|
+
"truncated message; truncated target name");
|
832
|
+
return -1;
|
833
|
+
}
|
834
|
+
}
|
835
|
+
|
836
|
+
if (info_len && info_offset) {
|
837
|
+
ntlm_buf info_buf;
|
838
|
+
|
839
|
+
challenge.pos = info_offset;
|
840
|
+
|
841
|
+
/* create a copy of the target info; we need the literal data */
|
842
|
+
if ((ntlm->challenge.target_info = malloc(info_len)) == NULL) {
|
843
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
844
|
+
return -1;
|
845
|
+
}
|
846
|
+
|
847
|
+
if (!read_buf(ntlm->challenge.target_info,
|
848
|
+
ntlm, &challenge, info_len)) {
|
849
|
+
ntlm_client_set_errmsg(ntlm,
|
850
|
+
"truncated message; truncated target info");
|
851
|
+
return -1;
|
852
|
+
}
|
853
|
+
|
854
|
+
info_buf.buf = ntlm->challenge.target_info;
|
855
|
+
info_buf.pos = 0;
|
856
|
+
info_buf.len = info_len;
|
857
|
+
|
858
|
+
/* then set up the target info and parse it */
|
859
|
+
if (!read_target_info(&ntlm->challenge.target_server,
|
860
|
+
&ntlm->challenge.target_domain,
|
861
|
+
&ntlm->challenge.target_server_dns,
|
862
|
+
&ntlm->challenge.target_domain_dns,
|
863
|
+
ntlm, &info_buf, unicode))
|
864
|
+
return -1;
|
865
|
+
|
866
|
+
ntlm->challenge.target_info_len = info_len;
|
867
|
+
}
|
868
|
+
|
869
|
+
ntlm->state = NTLM_STATE_RESPONSE;
|
870
|
+
|
871
|
+
return 0;
|
872
|
+
}
|
873
|
+
|
874
|
+
uint64_t ntlm_client_challenge_nonce(ntlm_client *ntlm)
|
875
|
+
{
|
876
|
+
return ntlm->challenge.nonce;
|
877
|
+
}
|
878
|
+
|
879
|
+
const char *ntlm_client_target(ntlm_client *ntlm)
|
880
|
+
{
|
881
|
+
return ntlm->challenge.target;
|
882
|
+
}
|
883
|
+
|
884
|
+
const char *ntlm_client_target_server(ntlm_client *ntlm)
|
885
|
+
{
|
886
|
+
return ntlm->challenge.target_server;
|
887
|
+
}
|
888
|
+
|
889
|
+
const char *ntlm_client_target_domain(ntlm_client *ntlm)
|
890
|
+
{
|
891
|
+
return ntlm->challenge.target_domain;
|
892
|
+
}
|
893
|
+
|
894
|
+
const char *ntlm_client_target_server_dns(ntlm_client *ntlm)
|
895
|
+
{
|
896
|
+
return ntlm->challenge.target_server_dns;
|
897
|
+
}
|
898
|
+
|
899
|
+
const char *ntlm_client_target_domain_dns(ntlm_client *ntlm)
|
900
|
+
{
|
901
|
+
return ntlm->challenge.target_domain_dns;
|
902
|
+
}
|
903
|
+
|
904
|
+
#define EVEN_PARITY(a) \
|
905
|
+
(!!((a) & 0x01ll) ^ !!((a) & 0x02ll) ^ \
|
906
|
+
!!((a) & 0x04ll) ^ !!((a) & 0x08ll) ^ \
|
907
|
+
!!((a) & 0x10ll) ^ !!((a) & 0x20ll) ^ \
|
908
|
+
!!((a) & 0x40ll) ^ !!((a) & 0x80ll))
|
909
|
+
|
910
|
+
static void generate_odd_parity(ntlm_des_block *block)
|
911
|
+
{
|
912
|
+
size_t i;
|
913
|
+
|
914
|
+
for (i = 0; i < sizeof(ntlm_des_block); i++)
|
915
|
+
(*block)[i] |= (1 ^ EVEN_PARITY((*block)[i]));
|
916
|
+
}
|
917
|
+
|
918
|
+
static void des_key_from_password(
|
919
|
+
ntlm_des_block *out,
|
920
|
+
const unsigned char *plaintext,
|
921
|
+
size_t plaintext_len)
|
922
|
+
{
|
923
|
+
size_t i;
|
924
|
+
|
925
|
+
plaintext_len = MIN(plaintext_len, 7);
|
926
|
+
|
927
|
+
memset(*out, 0, sizeof(ntlm_des_block));
|
928
|
+
|
929
|
+
for (i = 0; i < plaintext_len; i++) {
|
930
|
+
size_t j = (7 - i);
|
931
|
+
uint8_t mask = (0xff >> j);
|
932
|
+
|
933
|
+
(*out)[i] |= ((plaintext[i] & (0xff - mask)) >> i);
|
934
|
+
(*out)[i+1] |= ((plaintext[i] & mask) << j);
|
935
|
+
}
|
936
|
+
|
937
|
+
generate_odd_parity(out);
|
938
|
+
}
|
939
|
+
|
940
|
+
static inline bool generate_lm_hash(
|
941
|
+
ntlm_des_block out[2],
|
942
|
+
const char *password)
|
943
|
+
{
|
944
|
+
/* LM encrypts this known plaintext using the password as a key */
|
945
|
+
ntlm_des_block plaintext = NTLM_LM_PLAINTEXT;
|
946
|
+
ntlm_des_block keystr1, keystr2;
|
947
|
+
size_t keystr1_len, keystr2_len;
|
948
|
+
ntlm_des_block key1, key2;
|
949
|
+
size_t password_len, i;
|
950
|
+
|
951
|
+
/* Copy the first 14 characters of the password, uppercased */
|
952
|
+
memset(&keystr1, 0, sizeof(keystr1));
|
953
|
+
memset(&keystr2, 0, sizeof(keystr2));
|
954
|
+
|
955
|
+
password_len = password ? strlen(password) : 0;
|
956
|
+
|
957
|
+
/* Split the password into two 7 byte chunks */
|
958
|
+
keystr1_len = MIN(7, password_len);
|
959
|
+
keystr2_len = (password_len > 7) ? MIN(14, password_len) - 7 : 0;
|
960
|
+
|
961
|
+
for (i = 0; i < keystr1_len; i++)
|
962
|
+
keystr1[i] = (unsigned char)toupper(password[i]);
|
963
|
+
for (i = 0; i < keystr2_len; i++)
|
964
|
+
keystr2[i] = (unsigned char)toupper(password[i+7]);
|
965
|
+
|
966
|
+
/* DES encrypt the LM constant using the password as the key */
|
967
|
+
des_key_from_password(&key1, keystr1, keystr1_len);
|
968
|
+
des_key_from_password(&key2, keystr2, keystr2_len);
|
969
|
+
|
970
|
+
return ntlm_des_encrypt(&out[0], &plaintext, &key1) &&
|
971
|
+
ntlm_des_encrypt(&out[1], &plaintext, &key2);
|
972
|
+
}
|
973
|
+
|
974
|
+
static void des_keys_from_lm_hash(ntlm_des_block out[3], ntlm_des_block lm_hash[2])
|
975
|
+
{
|
976
|
+
ntlm_des_block split[3];
|
977
|
+
|
978
|
+
memcpy(&split[0][0], &lm_hash[0][0], 7);
|
979
|
+
|
980
|
+
memcpy(&split[1][0], &lm_hash[0][7], 1);
|
981
|
+
memcpy(&split[1][1], &lm_hash[1][0], 6);
|
982
|
+
|
983
|
+
memcpy(&split[2][0], &lm_hash[1][6], 2);
|
984
|
+
|
985
|
+
des_key_from_password(&out[0], split[0], 7);
|
986
|
+
des_key_from_password(&out[1], split[1], 7);
|
987
|
+
des_key_from_password(&out[2], split[2], 2);
|
988
|
+
}
|
989
|
+
|
990
|
+
static bool generate_lm_response(ntlm_client *ntlm)
|
991
|
+
{
|
992
|
+
ntlm_des_block lm_hash[2], key[3], lm_response[3];
|
993
|
+
ntlm_des_block *challenge = (ntlm_des_block *)&ntlm->challenge.nonce;
|
994
|
+
|
995
|
+
/* Generate the LM hash from the password */
|
996
|
+
if (!generate_lm_hash(lm_hash, ntlm->password))
|
997
|
+
return false;
|
998
|
+
|
999
|
+
/* Convert that LM hash to three DES keys */
|
1000
|
+
des_keys_from_lm_hash(key, lm_hash);
|
1001
|
+
|
1002
|
+
/* Finally, encrypt the challenge with each of these keys */
|
1003
|
+
if (!ntlm_des_encrypt(&lm_response[0], challenge, &key[0]) ||
|
1004
|
+
!ntlm_des_encrypt(&lm_response[1], challenge, &key[1]) ||
|
1005
|
+
!ntlm_des_encrypt(&lm_response[2], challenge, &key[2]))
|
1006
|
+
return false;
|
1007
|
+
|
1008
|
+
memcpy(&ntlm->lm_response[0], lm_response[0], 8);
|
1009
|
+
memcpy(&ntlm->lm_response[8], lm_response[1], 8);
|
1010
|
+
memcpy(&ntlm->lm_response[16], lm_response[2], 8);
|
1011
|
+
|
1012
|
+
ntlm->lm_response_len = sizeof(ntlm->lm_response);
|
1013
|
+
|
1014
|
+
return true;
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
static bool generate_ntlm_hash(
|
1018
|
+
unsigned char out[NTLM_NTLM_HASH_LEN], ntlm_client *ntlm)
|
1019
|
+
{
|
1020
|
+
/* Generate the LM hash from the (Unicode) password */
|
1021
|
+
if (ntlm->password && !ntlm_unicode_utf8_to_16(
|
1022
|
+
&ntlm->password_utf16,
|
1023
|
+
&ntlm->password_utf16_len,
|
1024
|
+
ntlm->unicode_ctx,
|
1025
|
+
ntlm->password,
|
1026
|
+
strlen(ntlm->password)))
|
1027
|
+
return false;
|
1028
|
+
|
1029
|
+
return ntlm_md4_digest(out,
|
1030
|
+
(const unsigned char *)ntlm->password_utf16,
|
1031
|
+
ntlm->password_utf16_len);
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
static bool generate_ntlm_response(ntlm_client *ntlm)
|
1035
|
+
{
|
1036
|
+
unsigned char ntlm_hash[NTLM_NTLM_HASH_LEN] = {0};
|
1037
|
+
ntlm_des_block key[3], ntlm_response[3];
|
1038
|
+
ntlm_des_block *challenge =
|
1039
|
+
(ntlm_des_block *)&ntlm->challenge.nonce;
|
1040
|
+
|
1041
|
+
if (!generate_ntlm_hash(ntlm_hash, ntlm))
|
1042
|
+
return false;
|
1043
|
+
|
1044
|
+
/* Convert that LM hash to three DES keys */
|
1045
|
+
des_key_from_password(&key[0], &ntlm_hash[0], 7);
|
1046
|
+
des_key_from_password(&key[1], &ntlm_hash[7], 7);
|
1047
|
+
des_key_from_password(&key[2], &ntlm_hash[14], 2);
|
1048
|
+
|
1049
|
+
/* Finally, encrypt the challenge with each of these keys */
|
1050
|
+
if (!ntlm_des_encrypt(&ntlm_response[0], challenge, &key[0]) ||
|
1051
|
+
!ntlm_des_encrypt(&ntlm_response[1], challenge, &key[1]) ||
|
1052
|
+
!ntlm_des_encrypt(&ntlm_response[2], challenge, &key[2]))
|
1053
|
+
return false;
|
1054
|
+
|
1055
|
+
memcpy(&ntlm->ntlm_response[0], ntlm_response[0], 8);
|
1056
|
+
memcpy(&ntlm->ntlm_response[8], ntlm_response[1], 8);
|
1057
|
+
memcpy(&ntlm->ntlm_response[16], ntlm_response[2], 8);
|
1058
|
+
|
1059
|
+
ntlm->ntlm_response_len = sizeof(ntlm->ntlm_response);
|
1060
|
+
return true;
|
1061
|
+
}
|
1062
|
+
|
1063
|
+
static bool generate_ntlm2_hash(
|
1064
|
+
unsigned char out[NTLM_NTLM2_HASH_LEN], ntlm_client *ntlm)
|
1065
|
+
{
|
1066
|
+
unsigned char ntlm_hash[NTLM_NTLM_HASH_LEN] = {0};
|
1067
|
+
const unsigned char *username = NULL, *target = NULL;
|
1068
|
+
size_t username_len = 0, target_len = 0, out_len = NTLM_NTLM2_HASH_LEN;
|
1069
|
+
|
1070
|
+
if (!generate_ntlm_hash(ntlm_hash, ntlm))
|
1071
|
+
return false;
|
1072
|
+
|
1073
|
+
if (ntlm->username_upper_utf16) {
|
1074
|
+
username = (const unsigned char *)ntlm->username_upper_utf16;
|
1075
|
+
username_len = ntlm->username_upper_utf16_len;
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
if (ntlm->target_utf16) {
|
1079
|
+
target = (const unsigned char *)ntlm->target_utf16;
|
1080
|
+
target_len = ntlm->target_utf16_len;
|
1081
|
+
}
|
1082
|
+
|
1083
|
+
if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) ||
|
1084
|
+
!ntlm_hmac_md5_init(ntlm->hmac_ctx, ntlm_hash, sizeof(ntlm_hash)) ||
|
1085
|
+
!ntlm_hmac_md5_update(ntlm->hmac_ctx, username, username_len) ||
|
1086
|
+
!ntlm_hmac_md5_update(ntlm->hmac_ctx, target, target_len) ||
|
1087
|
+
!ntlm_hmac_md5_final(out, &out_len, ntlm->hmac_ctx)) {
|
1088
|
+
ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5");
|
1089
|
+
return false;
|
1090
|
+
}
|
1091
|
+
|
1092
|
+
assert(out_len == NTLM_NTLM2_HASH_LEN);
|
1093
|
+
return true;
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
static bool generate_ntlm2_challengehash(
|
1097
|
+
unsigned char out[16],
|
1098
|
+
ntlm_client *ntlm,
|
1099
|
+
unsigned char ntlm2_hash[NTLM_NTLM2_HASH_LEN],
|
1100
|
+
const unsigned char *blob,
|
1101
|
+
size_t blob_len)
|
1102
|
+
{
|
1103
|
+
size_t out_len = 16;
|
1104
|
+
|
1105
|
+
if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) ||
|
1106
|
+
!ntlm_hmac_md5_init(ntlm->hmac_ctx,
|
1107
|
+
ntlm2_hash, NTLM_NTLM2_HASH_LEN) ||
|
1108
|
+
!ntlm_hmac_md5_update(ntlm->hmac_ctx,
|
1109
|
+
(const unsigned char *)&ntlm->challenge.nonce, 8) ||
|
1110
|
+
!ntlm_hmac_md5_update(ntlm->hmac_ctx, blob, blob_len) ||
|
1111
|
+
!ntlm_hmac_md5_final(out, &out_len, ntlm->hmac_ctx)) {
|
1112
|
+
ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5");
|
1113
|
+
return false;
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
assert(out_len == 16);
|
1117
|
+
return true;
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
static bool generate_lm2_response(ntlm_client *ntlm,
|
1121
|
+
unsigned char ntlm2_hash[NTLM_NTLM2_HASH_LEN])
|
1122
|
+
{
|
1123
|
+
unsigned char lm2_challengehash[16];
|
1124
|
+
size_t lm2_len = 16;
|
1125
|
+
uint64_t local_nonce;
|
1126
|
+
|
1127
|
+
local_nonce = htonll(ntlm->nonce);
|
1128
|
+
|
1129
|
+
if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) ||
|
1130
|
+
!ntlm_hmac_md5_init(ntlm->hmac_ctx,
|
1131
|
+
ntlm2_hash, NTLM_NTLM2_HASH_LEN) ||
|
1132
|
+
!ntlm_hmac_md5_update(ntlm->hmac_ctx,
|
1133
|
+
(const unsigned char *)&ntlm->challenge.nonce, 8) ||
|
1134
|
+
!ntlm_hmac_md5_update(ntlm->hmac_ctx,
|
1135
|
+
(const unsigned char *)&local_nonce, 8) ||
|
1136
|
+
!ntlm_hmac_md5_final(lm2_challengehash, &lm2_len, ntlm->hmac_ctx)) {
|
1137
|
+
ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5");
|
1138
|
+
return false;
|
1139
|
+
}
|
1140
|
+
|
1141
|
+
assert(lm2_len == 16);
|
1142
|
+
|
1143
|
+
memcpy(&ntlm->lm_response[0], lm2_challengehash, 16);
|
1144
|
+
memcpy(&ntlm->lm_response[16], &local_nonce, 8);
|
1145
|
+
|
1146
|
+
ntlm->lm_response_len = 24;
|
1147
|
+
return true;
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
static bool generate_timestamp(ntlm_client *ntlm)
|
1151
|
+
{
|
1152
|
+
if (!ntlm->timestamp)
|
1153
|
+
ntlm->timestamp = (time(NULL) + 11644473600) * 10000000;
|
1154
|
+
|
1155
|
+
return true;
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
static bool generate_nonce(ntlm_client *ntlm)
|
1159
|
+
{
|
1160
|
+
unsigned char buf[8];
|
1161
|
+
|
1162
|
+
if (ntlm->nonce)
|
1163
|
+
return true;
|
1164
|
+
|
1165
|
+
if (!ntlm_random_bytes(ntlm, buf, 8))
|
1166
|
+
return false;
|
1167
|
+
|
1168
|
+
memcpy(&ntlm->nonce, buf, sizeof(uint64_t));
|
1169
|
+
return true;
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
static bool generate_ntlm2_response(ntlm_client *ntlm)
|
1173
|
+
{
|
1174
|
+
size_t blob_len, ntlm2_response_len;
|
1175
|
+
uint32_t signature;
|
1176
|
+
uint64_t timestamp, nonce;
|
1177
|
+
unsigned char ntlm2_hash[NTLM_NTLM2_HASH_LEN];
|
1178
|
+
unsigned char challengehash[16];
|
1179
|
+
unsigned char *blob;
|
1180
|
+
|
1181
|
+
if (!generate_timestamp(ntlm) ||
|
1182
|
+
!generate_nonce(ntlm) ||
|
1183
|
+
!generate_ntlm2_hash(ntlm2_hash, ntlm))
|
1184
|
+
return false;
|
1185
|
+
|
1186
|
+
blob_len = ntlm->challenge.target_info_len + 32;
|
1187
|
+
ntlm2_response_len = blob_len + 16;
|
1188
|
+
|
1189
|
+
if ((ntlm->ntlm2_response = malloc(ntlm2_response_len)) == NULL) {
|
1190
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
1191
|
+
return false;
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
/* position the blob in the response; we'll use it then return it */
|
1195
|
+
blob = ntlm->ntlm2_response + 16;
|
1196
|
+
|
1197
|
+
/* the blob's integer values are in network byte order */
|
1198
|
+
signature = htonl(0x01010000);
|
1199
|
+
timestamp = htonll(ntlm->timestamp);
|
1200
|
+
nonce = htonll(ntlm->nonce);
|
1201
|
+
|
1202
|
+
/* construct the blob */
|
1203
|
+
memcpy(&blob[0], &signature, 4);
|
1204
|
+
memset(&blob[4], 0, 4);
|
1205
|
+
memcpy(&blob[8], ×tamp, 8);
|
1206
|
+
memcpy(&blob[16], &nonce, 8);
|
1207
|
+
memset(&blob[24], 0, 4);
|
1208
|
+
memcpy(&blob[28], ntlm->challenge.target_info, ntlm->challenge.target_info_len);
|
1209
|
+
memset(&blob[28 + ntlm->challenge.target_info_len], 0, 4);
|
1210
|
+
|
1211
|
+
if (!generate_ntlm2_challengehash(challengehash, ntlm, ntlm2_hash, blob, blob_len))
|
1212
|
+
return false;
|
1213
|
+
|
1214
|
+
memcpy(ntlm->ntlm2_response, challengehash, 16);
|
1215
|
+
ntlm->ntlm2_response_len = ntlm2_response_len;
|
1216
|
+
|
1217
|
+
if (!generate_lm2_response(ntlm, ntlm2_hash))
|
1218
|
+
return false;
|
1219
|
+
|
1220
|
+
return true;
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
int ntlm_client_response(
|
1224
|
+
const unsigned char **out,
|
1225
|
+
size_t *out_len,
|
1226
|
+
ntlm_client *ntlm)
|
1227
|
+
{
|
1228
|
+
unsigned char *domain, *username, *hostname, *ntlm_rep, *session;
|
1229
|
+
size_t lm_rep_len, lm_rep_offset, ntlm_rep_len, ntlm_rep_offset,
|
1230
|
+
domain_len, domain_offset, username_len, username_offset,
|
1231
|
+
hostname_len, hostname_offset, session_len, session_offset;
|
1232
|
+
uint32_t flags = 0;
|
1233
|
+
bool unicode;
|
1234
|
+
|
1235
|
+
assert(out && out_len && ntlm);
|
1236
|
+
|
1237
|
+
*out = NULL;
|
1238
|
+
*out_len = 0;
|
1239
|
+
|
1240
|
+
if (ntlm->state != NTLM_STATE_RESPONSE) {
|
1241
|
+
ntlm_client_set_errmsg(ntlm, "ntlm handle in invalid state");
|
1242
|
+
return -1;
|
1243
|
+
}
|
1244
|
+
|
1245
|
+
/*
|
1246
|
+
* Minimum message size is 64 bytes:
|
1247
|
+
* 8 byte signature,
|
1248
|
+
* 4 byte message indicator,
|
1249
|
+
* 6x8 byte security buffers
|
1250
|
+
* 4 byte flags
|
1251
|
+
*/
|
1252
|
+
ntlm->response.len = 64;
|
1253
|
+
|
1254
|
+
unicode = supports_unicode(ntlm) &&
|
1255
|
+
(ntlm->challenge.flags & NTLM_NEGOTIATE_UNICODE);
|
1256
|
+
|
1257
|
+
if (unicode)
|
1258
|
+
flags |= NTLM_NEGOTIATE_UNICODE;
|
1259
|
+
else
|
1260
|
+
flags |= NTLM_NEGOTIATE_OEM;
|
1261
|
+
|
1262
|
+
if (unicode) {
|
1263
|
+
domain = (unsigned char *)ntlm->userdomain_utf16;
|
1264
|
+
domain_len = ntlm->userdomain_utf16_len;
|
1265
|
+
|
1266
|
+
username = (unsigned char *)ntlm->username_utf16;
|
1267
|
+
username_len = ntlm->username_utf16_len;
|
1268
|
+
|
1269
|
+
hostname = (unsigned char *)ntlm->hostname_utf16;
|
1270
|
+
hostname_len = ntlm->hostname_utf16_len;
|
1271
|
+
} else {
|
1272
|
+
domain = (unsigned char *)ntlm->userdomain;
|
1273
|
+
domain_len = ntlm->userdomain ? strlen(ntlm->userdomain) : 0;
|
1274
|
+
|
1275
|
+
username = (unsigned char *)ntlm->username;
|
1276
|
+
username_len = ntlm->username ? strlen(ntlm->username) : 0;
|
1277
|
+
|
1278
|
+
hostname = (unsigned char *)ntlm->hostname;
|
1279
|
+
hostname_len = ntlm->hostname ? strlen(ntlm->hostname) : 0;
|
1280
|
+
}
|
1281
|
+
|
1282
|
+
/* Negotiate our requested authentication type with the server's */
|
1283
|
+
if (!(ntlm->flags & NTLM_CLIENT_DISABLE_NTLM2) &&
|
1284
|
+
(ntlm->challenge.flags & NTLM_NEGOTIATE_NTLM)) {
|
1285
|
+
flags |= NTLM_NEGOTIATE_NTLM;
|
1286
|
+
|
1287
|
+
if (!generate_ntlm2_response(ntlm))
|
1288
|
+
return -1;
|
1289
|
+
} else if ((ntlm->flags & NTLM_CLIENT_ENABLE_NTLM) &&
|
1290
|
+
(ntlm->challenge.flags & NTLM_NEGOTIATE_NTLM)) {
|
1291
|
+
flags |= NTLM_NEGOTIATE_NTLM;
|
1292
|
+
|
1293
|
+
if (!generate_ntlm_response(ntlm) ||
|
1294
|
+
!generate_lm_response(ntlm))
|
1295
|
+
return -1;
|
1296
|
+
} else if (ntlm->flags & NTLM_CLIENT_ENABLE_LM) {
|
1297
|
+
if (!generate_lm_response(ntlm))
|
1298
|
+
return -1;
|
1299
|
+
} else {
|
1300
|
+
ntlm_client_set_errmsg(ntlm,
|
1301
|
+
"no encryption options could be negotiated");
|
1302
|
+
return -1;
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
domain_offset = ntlm->response.len;
|
1306
|
+
increment_size(&ntlm->response.len, domain_len);
|
1307
|
+
|
1308
|
+
username_offset = ntlm->response.len;
|
1309
|
+
increment_size(&ntlm->response.len, username_len);
|
1310
|
+
|
1311
|
+
hostname_offset = ntlm->response.len;
|
1312
|
+
increment_size(&ntlm->response.len, hostname_len);
|
1313
|
+
|
1314
|
+
lm_rep_len = ntlm->lm_response_len;
|
1315
|
+
lm_rep_offset = ntlm->response.len;
|
1316
|
+
increment_size(&ntlm->response.len, lm_rep_len);
|
1317
|
+
|
1318
|
+
ntlm_rep = ntlm->ntlm2_response_len ?
|
1319
|
+
ntlm->ntlm2_response : ntlm->ntlm_response;
|
1320
|
+
ntlm_rep_len = ntlm->ntlm2_response_len ?
|
1321
|
+
ntlm->ntlm2_response_len : ntlm->ntlm_response_len;
|
1322
|
+
ntlm_rep_offset = ntlm->response.len;
|
1323
|
+
increment_size(&ntlm->response.len, ntlm_rep_len);
|
1324
|
+
|
1325
|
+
session = NULL;
|
1326
|
+
session_len = 0;
|
1327
|
+
session_offset = ntlm->response.len;
|
1328
|
+
increment_size(&ntlm->response.len, session_len);
|
1329
|
+
|
1330
|
+
if (ntlm->response.len == (size_t)-1) {
|
1331
|
+
ntlm_client_set_errmsg(ntlm, "message too large");
|
1332
|
+
return -1;
|
1333
|
+
}
|
1334
|
+
|
1335
|
+
if ((ntlm->response.buf = malloc(ntlm->response.len)) == NULL) {
|
1336
|
+
ntlm_client_set_errmsg(ntlm, "out of memory");
|
1337
|
+
return -1;
|
1338
|
+
}
|
1339
|
+
|
1340
|
+
memset(ntlm->response.buf, 0, ntlm->response.len);
|
1341
|
+
|
1342
|
+
if (!write_buf(ntlm, &ntlm->response,
|
1343
|
+
ntlm_client_signature, sizeof(ntlm_client_signature)) ||
|
1344
|
+
!write_int32(ntlm, &ntlm->response, 3) ||
|
1345
|
+
!write_bufinfo(ntlm, &ntlm->response, lm_rep_len, lm_rep_offset) ||
|
1346
|
+
!write_bufinfo(ntlm, &ntlm->response, ntlm_rep_len, ntlm_rep_offset) ||
|
1347
|
+
!write_bufinfo(ntlm, &ntlm->response, domain_len, domain_offset) ||
|
1348
|
+
!write_bufinfo(ntlm, &ntlm->response, username_len, username_offset) ||
|
1349
|
+
!write_bufinfo(ntlm, &ntlm->response, hostname_len, hostname_offset) ||
|
1350
|
+
!write_bufinfo(ntlm, &ntlm->response, session_len, session_offset) ||
|
1351
|
+
!write_int32(ntlm, &ntlm->response, flags) ||
|
1352
|
+
!write_buf(ntlm, &ntlm->response, domain, domain_len) ||
|
1353
|
+
!write_buf(ntlm, &ntlm->response, username, username_len) ||
|
1354
|
+
!write_buf(ntlm, &ntlm->response, hostname, hostname_len) ||
|
1355
|
+
!write_buf(ntlm, &ntlm->response, ntlm->lm_response, lm_rep_len) ||
|
1356
|
+
!write_buf(ntlm, &ntlm->response, ntlm_rep, ntlm_rep_len) ||
|
1357
|
+
!write_buf(ntlm, &ntlm->response, session, session_len))
|
1358
|
+
return -1;
|
1359
|
+
|
1360
|
+
assert(ntlm->response.pos == ntlm->response.len);
|
1361
|
+
|
1362
|
+
ntlm->state = NTLM_STATE_COMPLETE;
|
1363
|
+
|
1364
|
+
*out = ntlm->response.buf;
|
1365
|
+
*out_len = ntlm->response.len;
|
1366
|
+
|
1367
|
+
return 0;
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
void ntlm_client_reset(ntlm_client *ntlm)
|
1371
|
+
{
|
1372
|
+
ntlm_client_flags flags;
|
1373
|
+
ntlm_hmac_ctx *hmac_ctx;
|
1374
|
+
ntlm_unicode_ctx *unicode_ctx;
|
1375
|
+
|
1376
|
+
assert(ntlm);
|
1377
|
+
|
1378
|
+
free(ntlm->negotiate.buf);
|
1379
|
+
free(ntlm->challenge.target_info);
|
1380
|
+
free(ntlm->challenge.target);
|
1381
|
+
free(ntlm->challenge.target_domain);
|
1382
|
+
free(ntlm->challenge.target_domain_dns);
|
1383
|
+
free(ntlm->challenge.target_server);
|
1384
|
+
free(ntlm->challenge.target_server_dns);
|
1385
|
+
free(ntlm->response.buf);
|
1386
|
+
|
1387
|
+
free(ntlm->hostname);
|
1388
|
+
free(ntlm->hostname_utf16);
|
1389
|
+
free(ntlm->hostdomain);
|
1390
|
+
|
1391
|
+
free(ntlm->target);
|
1392
|
+
free(ntlm->target_utf16);
|
1393
|
+
|
1394
|
+
free(ntlm->ntlm2_response);
|
1395
|
+
|
1396
|
+
free_credentials(ntlm);
|
1397
|
+
|
1398
|
+
flags = ntlm->flags;
|
1399
|
+
hmac_ctx = ntlm->hmac_ctx;
|
1400
|
+
unicode_ctx = ntlm->unicode_ctx;
|
1401
|
+
|
1402
|
+
memset(ntlm, 0, sizeof(struct ntlm_client));
|
1403
|
+
|
1404
|
+
ntlm->flags = flags;
|
1405
|
+
ntlm->hmac_ctx = hmac_ctx;
|
1406
|
+
ntlm->unicode_ctx = unicode_ctx;
|
1407
|
+
}
|
1408
|
+
|
1409
|
+
void ntlm_client_free(ntlm_client *ntlm)
|
1410
|
+
{
|
1411
|
+
if (!ntlm)
|
1412
|
+
return;
|
1413
|
+
|
1414
|
+
ntlm_client_reset(ntlm);
|
1415
|
+
|
1416
|
+
ntlm_hmac_ctx_free(ntlm->hmac_ctx);
|
1417
|
+
ntlm_unicode_ctx_free(ntlm->unicode_ctx);
|
1418
|
+
|
1419
|
+
free(ntlm);
|
1420
|
+
}
|