libssh2-1.11.0/0000755000175000017500000000000014435416503010146 500000000000000libssh2-1.11.0/tap-driver.sh0000755000175000017500000004600514424651703012510 00000000000000#! /bin/sh # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # 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, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . scriptversion=2013-12-23.17; # UTC # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u me=tap-driver.sh fatal () { echo "$me: fatal: $*" >&2 exit 1 } usage_error () { echo "$me: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat < # trap : 1 3 2 13 15 if test $merge -gt 0; then exec 2>&1 else exec 2>&3 fi "$@" echo $? ) | LC_ALL=C ${AM_TAP_AWK-awk} \ -v me="$me" \ -v test_script_name="$test_name" \ -v log_file="$log_file" \ -v trs_file="$trs_file" \ -v expect_failure="$expect_failure" \ -v merge="$merge" \ -v ignore_exit="$ignore_exit" \ -v comments="$comments" \ -v diag_string="$diag_string" \ ' # TODO: the usages of "cat >&3" below could be optimized when using # GNU awk, and/on on systems that supports /dev/fd/. # Implementation note: in what follows, `result_obj` will be an # associative array that (partly) simulates a TAP result object # from the `TAP::Parser` perl module. ## ----------- ## ## FUNCTIONS ## ## ----------- ## function fatal(msg) { print me ": " msg | "cat >&2" exit 1 } function abort(where) { fatal("internal error " where) } # Convert a boolean to a "yes"/"no" string. function yn(bool) { return bool ? "yes" : "no"; } function add_test_result(result) { if (!test_results_index) test_results_index = 0 test_results_list[test_results_index] = result test_results_index += 1 test_results_seen[result] = 1; } # Whether the test script should be re-run by "make recheck". function must_recheck() { for (k in test_results_seen) if (k != "XFAIL" && k != "PASS" && k != "SKIP") return 1 return 0 } # Whether the content of the log file associated to this test should # be copied into the "global" test-suite.log. function copy_in_global_log() { for (k in test_results_seen) if (k != "PASS") return 1 return 0 } function get_global_test_result() { if ("ERROR" in test_results_seen) return "ERROR" if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) return "FAIL" all_skipped = 1 for (k in test_results_seen) if (k != "SKIP") all_skipped = 0 if (all_skipped) return "SKIP" return "PASS"; } function stringify_result_obj(result_obj) { if (result_obj["is_unplanned"] || result_obj["number"] != testno) return "ERROR" if (plan_seen == LATE_PLAN) return "ERROR" if (result_obj["directive"] == "TODO") return result_obj["is_ok"] ? "XPASS" : "XFAIL" if (result_obj["directive"] == "SKIP") return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; if (length(result_obj["directive"])) abort("in function stringify_result_obj()") return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL } function decorate_result(result) { color_name = color_for_result[result] if (color_name) return color_map[color_name] "" result "" color_map["std"] # If we are not using colorized output, or if we do not know how # to colorize the given result, we should return it unchanged. return result } function report(result, details) { if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) { msg = ": " test_script_name add_test_result(result) } else if (result == "#") { msg = " " test_script_name ":" } else { abort("in function report()") } if (length(details)) msg = msg " " details # Output on console might be colorized. print decorate_result(result) msg # Log the result in the log file too, to help debugging (this is # especially true when said result is a TAP error or "Bail out!"). print result msg | "cat >&3"; } function testsuite_error(error_message) { report("ERROR", "- " error_message) } function handle_tap_result() { details = result_obj["number"]; if (length(result_obj["description"])) details = details " " result_obj["description"] if (plan_seen == LATE_PLAN) { details = details " # AFTER LATE PLAN"; } else if (result_obj["is_unplanned"]) { details = details " # UNPLANNED"; } else if (result_obj["number"] != testno) { details = sprintf("%s # OUT-OF-ORDER (expecting %d)", details, testno); } else if (result_obj["directive"]) { details = details " # " result_obj["directive"]; if (length(result_obj["explanation"])) details = details " " result_obj["explanation"] } report(stringify_result_obj(result_obj), details) } # `skip_reason` should be empty whenever planned > 0. function handle_tap_plan(planned, skip_reason) { planned += 0 # Avoid getting confused if, say, `planned` is "00" if (length(skip_reason) && planned > 0) abort("in function handle_tap_plan()") if (plan_seen) { # Error, only one plan per stream is acceptable. testsuite_error("multiple test plans") return; } planned_tests = planned # The TAP plan can come before or after *all* the TAP results; we speak # respectively of an "early" or a "late" plan. If we see the plan line # after at least one TAP result has been seen, assume we have a late # plan; in this case, any further test result seen after the plan will # be flagged as an error. plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) # If testno > 0, we have an error ("too many tests run") that will be # automatically dealt with later, so do not worry about it here. If # $plan_seen is true, we have an error due to a repeated plan, and that # has already been dealt with above. Otherwise, we have a valid "plan # with SKIP" specification, and should report it as a particular kind # of SKIP result. if (planned == 0 && testno == 0) { if (length(skip_reason)) skip_reason = "- " skip_reason; report("SKIP", skip_reason); } } function extract_tap_comment(line) { if (index(line, diag_string) == 1) { # Strip leading `diag_string` from `line`. line = substr(line, length(diag_string) + 1) # And strip any leading and trailing whitespace left. sub("^[ \t]*", "", line) sub("[ \t]*$", "", line) # Return what is left (if any). return line; } return ""; } # When this function is called, we know that line is a TAP result line, # so that it matches the (perl) RE "^(not )?ok\b". function setup_result_obj(line) { # Get the result, and remove it from the line. result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) sub("^(not )?ok[ \t]*", "", line) # If the result has an explicit number, get it and strip it; otherwise, # automatically assign the next test number to it. if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) { match(line, "^[0-9]+") # The final `+ 0` is to normalize numbers with leading zeros. result_obj["number"] = substr(line, 1, RLENGTH) + 0 line = substr(line, RLENGTH + 1) } else { result_obj["number"] = testno } if (plan_seen == LATE_PLAN) # No further test results are acceptable after a "late" TAP plan # has been seen. result_obj["is_unplanned"] = 1 else if (plan_seen && testno > planned_tests) result_obj["is_unplanned"] = 1 else result_obj["is_unplanned"] = 0 # Strip trailing and leading whitespace. sub("^[ \t]*", "", line) sub("[ \t]*$", "", line) # This will have to be corrected if we have a "TODO"/"SKIP" directive. result_obj["description"] = line result_obj["directive"] = "" result_obj["explanation"] = "" if (index(line, "#") == 0) return # No possible directive, nothing more to do. # Directives are case-insensitive. rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" # See whether we have the directive, and if yes, where. pos = match(line, rx "$") if (!pos) pos = match(line, rx "[^a-zA-Z0-9_]") # If there was no TAP directive, we have nothing more to do. if (!pos) return # Let`s now see if the TAP directive has been escaped. For example: # escaped: ok \# SKIP # not escaped: ok \\# SKIP # escaped: ok \\\\\# SKIP # not escaped: ok \ # SKIP if (substr(line, pos, 1) == "#") { bslash_count = 0 for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) bslash_count += 1 if (bslash_count % 2) return # Directive was escaped. } # Strip the directive and its explanation (if any) from the test # description. result_obj["description"] = substr(line, 1, pos - 1) # Now remove the test description from the line, that has been dealt # with already. line = substr(line, pos) # Strip the directive, and save its value (normalized to upper case). sub("^[ \t]*#[ \t]*", "", line) result_obj["directive"] = toupper(substr(line, 1, 4)) line = substr(line, 5) # Now get the explanation for the directive (if any), with leading # and trailing whitespace removed. sub("^[ \t]*", "", line) sub("[ \t]*$", "", line) result_obj["explanation"] = line } function get_test_exit_message(status) { if (status == 0) return "" if (status !~ /^[1-9][0-9]*$/) abort("getting exit status") if (status < 127) exit_details = "" else if (status == 127) exit_details = " (command not found?)" else if (status >= 128 && status <= 255) exit_details = sprintf(" (terminated by signal %d?)", status - 128) else if (status > 256 && status <= 384) # We used to report an "abnormal termination" here, but some Korn # shells, when a child process die due to signal number n, can leave # in $? an exit status of 256+n instead of the more standard 128+n. # Apparently, both behaviours are allowed by POSIX (2008), so be # prepared to handle them both. See also Austing Group report ID # 0000051 exit_details = sprintf(" (terminated by signal %d?)", status - 256) else # Never seen in practice. exit_details = " (abnormal termination)" return sprintf("exited with status %d%s", status, exit_details) } function write_test_results() { print ":global-test-result: " get_global_test_result() > trs_file print ":recheck: " yn(must_recheck()) > trs_file print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file for (i = 0; i < test_results_index; i += 1) print ":test-result: " test_results_list[i] > trs_file close(trs_file); } BEGIN { ## ------- ## ## SETUP ## ## ------- ## '"$init_colors"' # Properly initialized once the TAP plan is seen. planned_tests = 0 COOKED_PASS = expect_failure ? "XPASS": "PASS"; COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; # Enumeration-like constants to remember which kind of plan (if any) # has been seen. It is important that NO_PLAN evaluates "false" as # a boolean. NO_PLAN = 0 EARLY_PLAN = 1 LATE_PLAN = 2 testno = 0 # Number of test results seen so far. bailed_out = 0 # Whether a "Bail out!" directive has been seen. # Whether the TAP plan has been seen or not, and if yes, which kind # it is ("early" is seen before any test result, "late" otherwise). plan_seen = NO_PLAN ## --------- ## ## PARSING ## ## --------- ## is_first_read = 1 while (1) { # Involutions required so that we are able to read the exit status # from the last input line. st = getline if (st < 0) # I/O error. fatal("I/O error while reading from input stream") else if (st == 0) # End-of-input { if (is_first_read) abort("in input loop: only one input line") break } if (is_first_read) { is_first_read = 0 nextline = $0 continue } else { curline = nextline nextline = $0 $0 = curline } # Copy any input line verbatim into the log file. print | "cat >&3" # Parsing of TAP input should stop after a "Bail out!" directive. if (bailed_out) continue # TAP test result. if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) { testno += 1 setup_result_obj($0) handle_tap_result() } # TAP plan (normal or "SKIP" without explanation). else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) { # The next two lines will put the number of planned tests in $0. sub("^1\\.\\.", "") sub("[^0-9]*$", "") handle_tap_plan($0, "") continue } # TAP "SKIP" plan, with an explanation. else if ($0 ~ /^1\.\.0+[ \t]*#/) { # The next lines will put the skip explanation in $0, stripping # any leading and trailing whitespace. This is a little more # tricky in truth, since we want to also strip a potential leading # "SKIP" string from the message. sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") sub("[ \t]*$", ""); handle_tap_plan(0, $0) } # "Bail out!" magic. # Older versions of prove and TAP::Harness (e.g., 3.17) did not # recognize a "Bail out!" directive when preceded by leading # whitespace, but more modern versions (e.g., 3.23) do. So we # emulate the latter, "more modern" behaviour. else if ($0 ~ /^[ \t]*Bail out!/) { bailed_out = 1 # Get the bailout message (if any), with leading and trailing # whitespace stripped. The message remains stored in `$0`. sub("^[ \t]*Bail out![ \t]*", ""); sub("[ \t]*$", ""); # Format the error message for the bailout_message = "Bail out!" if (length($0)) bailout_message = bailout_message " " $0 testsuite_error(bailout_message) } # Maybe we have too look for dianogtic comments too. else if (comments != 0) { comment = extract_tap_comment($0); if (length(comment)) report("#", comment); } } ## -------- ## ## FINISH ## ## -------- ## # A "Bail out!" directive should cause us to ignore any following TAP # error, as well as a non-zero exit status from the TAP producer. if (!bailed_out) { if (!plan_seen) { testsuite_error("missing test plan") } else if (planned_tests != testno) { bad_amount = testno > planned_tests ? "many" : "few" testsuite_error(sprintf("too %s tests run (expected %d, got %d)", bad_amount, planned_tests, testno)) } if (!ignore_exit) { # Fetch exit status from the last line. exit_message = get_test_exit_message(nextline) if (exit_message) testsuite_error(exit_message) } } write_test_results() exit 0 } # End of "BEGIN" block. ' # TODO: document that we consume the file descriptor 3 :-( } 3>"$log_file" test $? -eq 0 || fatal "I/O or internal error" # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libssh2-1.11.0/tests/0000755000175000017500000000000014435416503011310 500000000000000libssh2-1.11.0/tests/runner.h0000644000175000017500000000340314424650606012714 00000000000000/* Copyright (C) 2016 Alexander Lamaison * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef LIBSSH2_TESTS_RUNNER_H #define LIBSSH2_TESTS_RUNNER_H /* Most tests need these */ #include "session_fixture.h" #include int test(LIBSSH2_SESSION *session); #endif libssh2-1.11.0/tests/key_dsa_wrong.pub0000644000175000017500000000113212756074465014603 00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAITW/+UvVW+OUkzIburTACCXa2pUzPLmHVFU60NLxtOVcsmDuSxPrfBOZeWnYd52AqR8cK7sAqyM/KDUJOu9EFrwEUS8yhQMBGiczCqXfhqIpUzL+3T96GeYJBX5kwWmxUWemEmlm5ctNbUXemcRtI253mwAKNtZvnW6XLkBTKe7AAAAFQDoY62zTmgLQtaGJIvAlcKZEPKx4QAAAIBhJ6ldEXcYlKOx5iAnZsKBwlLQv1qBy8oB/4V1z5kMk5yGGdkL+EYeyMB+DrYqjDAq45ixtxHdLgsnGIRFyZFpvDD6RQgvUTxstpBFs7KA2wdTwvIF1LHdaoLZYQ6lWRMCNgNZORs36qRvncgGgjQbAW3k/0Ye9BwAaSMYlABZZgAAAIAt7vxpDC5Xs6GxbaUupfIP95ZTMx2LqqFjqfT/81nypIHVyIlCnWMia0mWGe4qXmHSyk6ZYnsk7Ll6WxdwUrFhd75qERyXlRK2x/v/Q3h9IOwChpHdSFx/Tq1Zl9vMx3tmS1H0YF9tUdN7g8S5XTUSvYA+0Lzxs/9zOU5fa55+pA== awl03@bounty libssh2-1.11.0/tests/test_auth_pubkey_ok_rsa.c0000644000175000017500000000053714424650606016320 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_RSA_SHA1 /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_rsa.pub", "key_rsa"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/test_auth_pubkey_ok_ed25519.c0000644000175000017500000000054614424650606016531 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_ED25519 /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_ed25519.pub", "key_ed25519"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/key_dsa_wrong0000644000175000017500000000123412756074465014021 00000000000000-----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQCE1v/lL1VvjlJMyG7q0wAgl2tqVMzy5h1RVOtDS8bTlXLJg7ks T63wTmXlp2HedgKkfHCu7AKsjPyg1CTrvRBa8BFEvMoUDARonMwql34aiKVMy/t0 /ehnmCQV+ZMFpsVFnphJpZuXLTW1F3pnEbSNud5sACjbWb51uly5AUynuwIVAOhj rbNOaAtC1oYki8CVwpkQ8rHhAoGAYSepXRF3GJSjseYgJ2bCgcJS0L9agcvKAf+F dc+ZDJOchhnZC/hGHsjAfg62KowwKuOYsbcR3S4LJxiERcmRabww+kUIL1E8bLaQ RbOygNsHU8LyBdSx3WqC2WEOpVkTAjYDWTkbN+qkb53IBoI0GwFt5P9GHvQcAGkj GJQAWWYCgYAt7vxpDC5Xs6GxbaUupfIP95ZTMx2LqqFjqfT/81nypIHVyIlCnWMi a0mWGe4qXmHSyk6ZYnsk7Ll6WxdwUrFhd75qERyXlRK2x/v/Q3h9IOwChpHdSFx/ Tq1Zl9vMx3tmS1H0YF9tUdN7g8S5XTUSvYA+0Lzxs/9zOU5fa55+pAIVAKV45RLf hg2GNXvO68Q4tt3F6kSP -----END DSA PRIVATE KEY----- libssh2-1.11.0/tests/test_auth_pubkey_ok_rsa_signed.c0000644000175000017500000000066214424650606017650 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_RSA_SHA1 && \ (defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)) /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_rsa_signed-cert.pub", "key_rsa_signed"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/key_ed25519_encrypted.pub0000644000175000017500000000012113446422146015656 00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICHxEyUTOVHXvdMFARedFQ+H9DW/n8Zy3daKKRqnTDMq libssh2-1.11.0/tests/key_rsa0000644000175000017500000000321312756074465012622 00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEoQIBAAKCAQEAnak1T7zHJ+hVRFBDQ9pf1KVzmd5gaNc7y7NPmL13aOG3sYeJ evi1x1WM/R3tb8XnUnzZUX9GJN0MYovvZsw9bknG1mDP72LFbGp/gzPddGIKHBBp vceDaJ85sM/ME3XOtD7uuXQuNAuEHwEzSMMiSIEMcQS+lXIcMLr5xPLEkyNvqsO5 RqSjMTLHKHgY8gLWx7oQ1avokhwuDxF7P3Pqtj+rW2Te6vR0i1H6EyFPsBkzkgNX b33cus8M1CnTmYTSgJgmHO2LLcGpjQ5sL8T/PWIWHaSqTnkrFXEMysgoteXnAYIL jzyBaqq2WV4KA3TluGdAP2p8gC32QtKmIuis3QIBIwKCAQB1Hpyhoi2LXCIVfXPM AU6AtWvRY12PtdSl8uqr+nX2JATNBZlUCTaUE6qQJNxEZyDeMNvzZdxV5gkzQ2Fi TpQIyRddbH01fJKoTxzlHzbLfAeCj9mFqicahOkHAMN8K6Ddqxe89zhD60w0SgjW 91tLzZQ2sxE70RxBdPQOpbaZLxmUZSVxRgf5djotyZqB4CcGblKCEZYJ9ZemgCnF gEcSsqcn0Jxfu+aEJ4WinN2orWs+okfgsUu9G9Ozwcy9Ptq1LkIzcwwTIpL7TTDd LMvhql39a07SysepjFRHxjvXh8Gv+SsLvKQPJHheVv8XoG0dZd+9/Eden9rHKoVm vGPLAoGBANGDQtv5K/md/3sRGeJ6Ir3/Ao+WMe8C5onck+hW4y/2yQqm3ZLzyZon KdWRj2q4dnxFZyoyDgX0UHLpM4aSsMRjn4C6vcPLcYaZ9CGB5FWPGZrq+q6vuMGK V9/fo4ZNFkNK3wo4WCSgxC1Y8XUJc3klOvPVjsmVxZaeZnkukkAFAoGBAMCkqe/S hrKITzjZuyGN90a2Nq+3xMNGuc400Qvoi27D1OcSn7SJ/K3tVWbENOH3CAlkmlZT 46IM2SRRmM0bxF3aThEwnsD5yPqgz+tcweX+gK3nXnP5JZfYF1kArXk80/eYhNE9 PwnJNXDQMoxaM0/X6BVgQyt03/Q12lH9u0j5AoGAR9U7fp6Su/uoDO/rnhs/HJHy P9u5WULSsuyKe4uBF8JTjp+cbOXeuIJ0vkCI8WPQ2iZsg37gPI5Hd9rtGDJLPATm OsOuxslowG9MY0J6K/aMb6EFfbiXHckIL3/gS02hO6SkPgSwgZY0odVaGX+VThtk q18ppDNZr/vLXL+CmZsCgYEAlJxIlG80tZxaXw5dKIN1nPL2/JUUIZz1vFShQ7Nk P4EglP+9B52lqr5mc9kwHAe1vhpobns6kvP393IlawbKrsz6ZQg/8/PkLw5XQIli YPeH1pyKsTyKtvcn9DO5BcE1zaGLB9ApULEpOcUuTwPBLvcDfjRREuUhywT44Coi w0MCgYAX5yc7/Z3R6M30rGsrgb1Y2siHYsi2LCygUj7TDGQYpaZN4afPJOT5H/Nr 7x7dgZkbOR6PQFm00VgML0XxKih59t0dcQ+2qk1LX5JDKRF/1kER3np6dpceteDu cC+MEHB/KvijnviAtBZGvD0O7oZgvbkKHESu2igXpAnfXPZFvw== -----END RSA PRIVATE KEY----- libssh2-1.11.0/tests/key_ecdsa0000644000175000017500000000111614047566506013111 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS 1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQTosiScH/oRSazpIpPSEFcY4YVZyNby peARi49N3qy78OE118KGc5T8eifd+n1PSb7z8PnfDwOL4jBHxW5nWx0RCocIt7tb2a349J gfEl8PegHGcF/DwC+eesIKJvv0MfkAAADIKLgw6yi4MOsAAAATZWNkc2Etc2hhMi1uaXN0 cDM4NAAAAAhuaXN0cDM4NAAAAGEE6LIknB/6EUms6SKT0hBXGOGFWcjW8qXgEYuPTd6su/ DhNdfChnOU/Hon3fp9T0m+8/D53w8Di+IwR8VuZ1sdEQqHCLe7W9mt+PSYHxJfD3oBxnBf w8AvnnrCCib79DH5AAAAMGYdHu+u2/L8zC/0S9bao9y6vKiLSuTEfZpCIsyE5jWj/vrS0n r1lzv9kKj+5A86aQAAAAA= -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/test_simple.c0000644000175000017500000000536114424650606013733 00000000000000/* Copyright (C) 2007 The Written Word, Inc. * Copyright (C) 2008, 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include #include static int test_libssh2_base64_decode(LIBSSH2_SESSION *session) { char *data; size_t datalen; const char *src = "Zm5vcmQ="; int ret; ret = _libssh2_base64_decode(session, &data, &datalen, src, strlen(src)); if(ret) return ret; if(datalen != 5 || strcmp(data, "fnord") != 0) { fprintf(stderr, "_libssh2_base64_decode() failed (%d, %.*s)\n", (unsigned int)datalen, (unsigned int)datalen, data); return 1; } free(data); return 0; } int main(int argc, char *argv[]) { LIBSSH2_SESSION *session; int rc; (void)argv; (void)argc; rc = libssh2_init(LIBSSH2_INIT_NO_CRYPTO); if(rc) { fprintf(stderr, "libssh2_init() failed: %d\n", rc); return 1; } session = libssh2_session_init(); if(!session) { fprintf(stderr, "libssh2_session_init() failed\n"); return 1; } test_libssh2_base64_decode(session); libssh2_session_free(session); libssh2_exit(); return 0; } libssh2-1.11.0/tests/runner.c0000644000175000017500000000505114424650606012710 00000000000000/* Copyright (C) 2016 Alexander Lamaison * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "runner.h" int main(void) { int exit_code; int retries = 0, retry = 0; #ifdef LIBSSH2_WINCNG /* FIXME: Retry tests with WinCNG due to flakiness in hostkey verification: https://github.com/libssh2/libssh2/issues/804 */ retries += 2; #endif do { int skipped, rc; LIBSSH2_SESSION *session = start_session_fixture(&skipped, &rc); if(session) { exit_code = (test(session) == 0) ? 0 : 1; } else if(skipped) { fprintf(stderr, "Test skipped.\n"); exit_code = 0; } else { exit_code = 1; } stop_session_fixture(); if(exit_code == 0 || #ifdef LIBSSH2_WINCNG rc != LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE || #endif ++retry > retries) { break; } fprintf(stderr, "Test failed (%d)! Retrying... %d / %d\n", rc, retry, retries); } while(1); return exit_code; } libssh2-1.11.0/tests/key_ecdsa_signed0000644000175000017500000000113214424650606014432 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS 1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQRv1/fnN1SuIkg222jYnySqIJ88J5M3 bB6JGeloKhIvnZdPOSVFuFBjuF7NPrGrsm87QstQFbDiLhIlcDNHIq0VhS5itHNMjtC6Ym RRx7mlQSXPbRRF5MclxvDJCMyAIagAAADQekojnXpKI50AAAATZWNkc2Etc2hhMi1uaXN0 cDM4NAAAAAhuaXN0cDM4NAAAAGEEb9f35zdUriJINtto2J8kqiCfPCeTN2weiRnpaCoSL5 2XTzklRbhQY7hezT6xq7JvO0LLUBWw4i4SJXAzRyKtFYUuYrRzTI7QumJkUce5pUElz20U ReTHJcbwyQjMgCGoAAAAMQDmng9vaqXjHAhRssuBHeQylRKRwzOYOaToF8f+O0NmpmfLnc /c2wOcXf2f9GBAQdYAAAAAAQIDBAUGBw== -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/test_sshd.test0000755000175000017500000000675314435416425014152 00000000000000#!/usr/bin/env bash # Written by Simon Josefsson and Viktor Szakats # Start sshd, invoke test(s), saving exit code, kill sshd, and # return exit code. set -e set -u # https://testanything.org/tap-specification.html d="$(dirname "$0")" uname="$(uname)" # Load list of tests if [ -n "${1:-}" ]; then # for CMake or manual tests="$*" via_args=1 else # for autotools via_args=0 # Load list of SSHD tests from Makefile.inc tests='' load=0 while read -r l; do if [[ "${l}" = 'SSHD_TESTS ='* ]]; then load=1 elif [ "${load}" = '1' ]; then [[ "${l}" =~ [a-z0-9_]+ ]] && tests+="${tests:+ }./${BASH_REMATCH[0]}${EXEEXT:-}" [[ ! "${l}" = *"\\" ]] && break fi done <<< "$(tr -d $"\r" < "${d}/Makefile.inc")" fi if [ -n "${SSHD_TESTS_LIMIT_TO:-}" ]; then tests="$(echo "${tests}" | cut -d ' ' -f -"${SSHD_TESTS_LIMIT_TO}")" echo "# limiting tests to the first ${SSHD_TESTS_LIMIT_TO}." fi # Init and start sshd d="$(cd "${d}" || exit; pwd)" # sshd needs absolute paths SSHD="${SSHD:-/usr/sbin/sshd}" [[ "${uname}" = *'_NT'* ]] && SSHD="$(cygpath -u "${SSHD}")" ver="$("${SSHD}" -V 2>&1 || true)" if [[ "${ver}" =~ OpenSSH_[a-zA-Z0-9_\ .,]+ ]]; then ver="${BASH_REMATCH[0]}" else ver='' fi echo "# sshd executable: '${SSHD}' (${ver})" # for our test clients: [ -z "${PRIVKEY:-}" ] && export PRIVKEY="${d}/key_rsa" [ -z "${PUBKEY:-}" ] && export PUBKEY="${d}/key_rsa.pub" cakeys="${d}/openssh_server/ca_user_keys.pub" SSHD_FLAGS="${SSHD_FLAGS:-}" if [ -n "${DEBUG:-}" ]; then SSHD_FLAGS+=' -d -d' fi chmod go-rwx \ "${d}"/openssh_server/ssh_host_* \ "${cakeys}" # shellcheck disable=SC2086 "${SSHD}" \ -f "${SSHD_FIXTURE_CONFIG:-${d}/openssh_server/sshd_config}" \ -o 'Port 4711' \ -h "${d}/openssh_server/ssh_host_rsa_key" \ -h "${d}/openssh_server/ssh_host_ecdsa_key" \ -h "${d}/openssh_server/ssh_host_ed25519_key" \ -o "AuthorizedKeysFile ${PUBKEY} ${d}/openssh_server/authorized_keys" \ -o "TrustedUserCAKeys ${cakeys}" \ -o 'PermitRootLogin yes' \ -D \ ${SSHD_FLAGS} & sshdpid=$! trap 'kill "${sshdpid}"; echo "# signal killing sshd"; exit 1;' EXIT : "started sshd (${sshdpid})" SSH="$(command -v "${SSH:-ssh}" || true)" if [ -n "${SSH}" ]; then echo "# ssh executable: '${SSH}' ($("${SSH}" -V 2>&1 || true))" chmod go-rwx "${PRIVKEY}" if [[ "${uname}" = *'_NT'* ]]; then export MSYS2_ARG_CONV_EXCL='/reset' icacls "${PRIVKEY}" /reset icacls "${PRIVKEY}" /grant:r "${USERNAME}:(R)" icacls "${PRIVKEY}" /inheritance:r fi count=1 # shellcheck disable=SC2086 while ! "${SSH:-ssh}" -q -a -k \ -F /dev/null \ -o 'BatchMode yes' \ -o 'StrictHostKeyChecking no' \ -o 'UserKnownHostsFile /dev/null' \ -o 'ConnectTimeout 3' \ -i "${PRIVKEY}" \ -p 4711 ${SSH_FLAGS:-} localhost exit 2>/dev/null; do echo '# waiting for sshd...' ((count++)) [[ "${count}" -gt 8 ]] && break sleep 1 done else echo '# waiting for sshd...' sleep 5 fi # Run tests ec=0 count=1 total="$(echo "${tests}" | wc -w | tr -d ' ')" anyerror=0 echo "${count}..${total}" export OPENSSH_NO_DOCKER=1 for test in ${tests}; do if "${test}"; then res='ok' else anyerror=1 [ "${via_args}" = '1' ] && [ "${total}" = '1' ] && ec=$? res='not ok' fi echo "${res} ${count} - sshd-$(basename "${test}")" ((count++)) done # Stop sshd : "killing sshd (${sshdpid})" kill "${sshdpid}" > /dev/null 2>&1 trap '' EXIT [ "${via_args}" = '1' ] && [ "${total}" != '1' ] && ec="${anyerror}" exit "${ec}" libssh2-1.11.0/tests/key_dsa.pub0000644000175000017500000000113212756074465013367 00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAK2Jh2Ck+8W1+LsFrjgOIH7XHySiONPSdG+faFTZprinh9cjyR3odzntVA7+UuFH14WnGM/ub6MbAXjrxDo1TzGILvW5x6nQ6hdLu7xFygihZ8sO1mIMOVqGdlNbTiYHl8XGjbLt1iXfW8ThM91LGGqmS+cgEiy0wWHYzsOXTDz9AAAAFQD/ebunYNTluoBrEYIoq3LMtQPbcwAAAIEAjPBzkUKcmfMAmb0eO/QAVXmX+L8NC6Vn2m4QguQ2IcJ8NH6VMnxXEBHsnemCOa9jN55G+LnX17PViuKS0O3rqQiSdA5wcHyCHKBT519/v1KQNymDwudfnFvdxUyAAG6MDSxKlpbXDCbrhFd2+ahC9a7rKalRPSXR0R2hhWRvjK0AAACAJ+CGwV/1S4j1GVwa6pSP0nj4V86GWXosTTBg7GT+rKWu8lrxIcr6FzLWgFi/gHoMrgnKWGxO1yF7vkoYM5Yfo84oBYiH+MgpiBuOrZrgzacHsA66JJbUfrESRFWZl2blIPr6Gyjj6cVGgMabK3yCiTRi0v7hwffpm0rKyKv7Goo= awl03@bounty libssh2-1.11.0/tests/test_hostkey_hash.c0000644000175000017500000001545314424650606015136 00000000000000#include "runner.h" static const char *EXPECTED_RSA_HOSTKEY = "AAAAB3NzaC1yc2EAAAABIwAAAQEArrr/JuJmaZligyfS8vcNur+mWR2ddDQtVdhHzdKU" "UoR6/Om6cvxpe61H1YZO1xCpLUBXmkki4HoNtYOpPB2W4V+8U4BDeVBD5crypEOE1+7B" "Am99fnEDxYIOZq2/jTP0yQmzCpWYS3COyFmkOL7sfX1wQMeW5zQT2WKcxC6FSWbhDqrB" "eNEGi687hJJoJ7YXgY/IdiYW5NcOuqRSWljjGS3dAJsHHWk4nJbhjEDXbPaeduMAwQU9" "i6ELfP3r+q6wdu0P4jWaoo3De1aYxnToV/ldXykpipON4NPamsb6Ph2qlJQKypq7J4iQ" "gkIIbCU1A31+4ExvcIVoxLQw/aTSbw=="; static const char *EXPECTED_ECDSA_HOSTKEY = "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC+/syyeKJD9dC2ZH" "9Q7iJGReR4YM3rUCMsSynkyXojdfSClGCMY7JvWlt30ESjYvxoTfSRGx6WvaqYK/vPoYQ4="; static const char *EXPECTED_ED25519_HOSTKEY = "AAAAC3NzaC1lZDI1NTE5AAAAIIxtdyg2ZRXE70UwyPVUH3UyfDBV8GX5cPF636P6hjom"; static const char *EXPECTED_RSA_MD5_HASH_DIGEST = "0C0ED1A5BB10275F76924CE187CE5C5E"; static const char *EXPECTED_RSA_SHA1_HASH_DIGEST = "F3CD59E2913F4422B80F7B0A82B2B89EAE449387"; static const char *EXPECTED_RSA_SHA256_HASH_DIGEST = "92E3DA49DF3C7F99A828F505ED8239397A5D1F62914459760F878F7510F563A3"; static const char *EXPECTED_ECDSA_MD5_HASH_DIGEST = "0402E4D897580BBC911379CBD88BCD3D"; static const char *EXPECTED_ECDSA_SHA1_HASH_DIGEST = "12FDAD1E3B31B10BABB00F2A8D1B9A62C326BD2F"; static const char *EXPECTED_ECDSA_SHA256_HASH_DIGEST = "56FCD975B166C3F0342D0036E44C311A86C0EAE40713B53FC776369BAE7F5264"; static const char *EXPECTED_ED25519_SHA256_HASH_DIGEST = "2638B020F6121FA750A7F4754B718419F621814C6E779D68ADF26AA68814ADDF"; static const int MD5_HASH_SIZE = 16; static const int SHA1_HASH_SIZE = 20; static const int SHA256_HASH_SIZE = 32; static void calculate_digest(const char *hash, size_t hash_len, char *buffer, size_t buffer_len) { size_t i; char *p = buffer; char *end = buffer + buffer_len; for(i = 0; i < hash_len && p < end; ++i) { p += snprintf(p, end - p, "%02X", (unsigned char)hash[i]); } } int test(LIBSSH2_SESSION *session) { char buf[BUFSIZ]; const char *hostkey; const char *md5_hash; const char *sha1_hash; const char *sha256_hash; int type; size_t len; /* these are the host keys under test, they are currently unused */ (void)EXPECTED_RSA_HOSTKEY; (void)EXPECTED_ECDSA_HOSTKEY; (void)EXPECTED_ED25519_HOSTKEY; hostkey = libssh2_session_hostkey(session, &len, &type); if(!hostkey) { print_last_session_error("libssh2_session_hostkey"); return 1; } if(type == LIBSSH2_HOSTKEY_TYPE_ED25519) { sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256); if(!sha256_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)"); return 1; } calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_ED25519_SHA256_HASH_DIGEST) != 0) { fprintf(stderr, "ED25519 SHA256 hash not as expected - digest %s != %s\n", buf, EXPECTED_ED25519_SHA256_HASH_DIGEST); return 1; } } else if(type == LIBSSH2_HOSTKEY_TYPE_ECDSA_256) { md5_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); if(!md5_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_MD5)"); return 1; } calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_ECDSA_MD5_HASH_DIGEST) != 0) { fprintf(stderr, "ECDSA MD5 hash not as expected - digest %s != %s\n", buf, EXPECTED_ECDSA_MD5_HASH_DIGEST); return 1; } sha1_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); if(!sha1_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA1)"); return 1; } calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_ECDSA_SHA1_HASH_DIGEST) != 0) { fprintf(stderr, "ECDSA SHA1 hash not as expected - digest %s != %s\n", buf, EXPECTED_ECDSA_SHA1_HASH_DIGEST); return 1; } sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256); if(!sha256_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)"); return 1; } calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_ECDSA_SHA256_HASH_DIGEST) != 0) { fprintf(stderr, "ECDSA SHA256 hash not as expected - digest %s != %s\n", buf, EXPECTED_ECDSA_SHA256_HASH_DIGEST); return 1; } } else if(type == LIBSSH2_HOSTKEY_TYPE_RSA) { md5_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); if(!md5_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_MD5)"); return 1; } calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_RSA_MD5_HASH_DIGEST) != 0) { fprintf(stderr, "MD5 hash not as expected - digest %s != %s\n", buf, EXPECTED_RSA_MD5_HASH_DIGEST); return 1; } sha1_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); if(!sha1_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA1)"); return 1; } calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_RSA_SHA1_HASH_DIGEST) != 0) { fprintf(stderr, "SHA1 hash not as expected - digest %s != %s\n", buf, EXPECTED_RSA_SHA1_HASH_DIGEST); return 1; } sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256); if(!sha256_hash) { print_last_session_error( "libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)"); return 1; } calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ); if(strcmp(buf, EXPECTED_RSA_SHA256_HASH_DIGEST) != 0) { fprintf(stderr, "SHA256 hash not as expected - digest %s != %s\n", buf, EXPECTED_RSA_SHA256_HASH_DIGEST); return 1; } } else { fprintf(stderr, "Unexpected type of hostkey: %i\n", type); return 1; } return 0; } libssh2-1.11.0/tests/test_auth_keyboard_ok.c0000644000175000017500000000036214424650606015750 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { return test_auth_keyboard(session, 0, "libssh2", /* set in Dockerfile */ "my test password"); /* set in Dockerfile */ } libssh2-1.11.0/tests/test_auth_pubkey_ok_ed25519_encrypted.c0000644000175000017500000000057714424650606020612 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_ED25519 /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", "libssh2", "key_ed25519_encrypted.pub", "key_ed25519_encrypted"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/mansyntax.sh0000755000175000017500000000151614424650606013616 00000000000000#!/bin/sh set -e set -u # Written by Mikhail Gusarov # # Run syntax checks for all manpages in the documentation tree. # # Requirement on macOS: brew install man-db # command -v gman >/dev/null 2>&1 && man() { gman "$@"; } dstdir="${builddir:-$PWD}" mandir="$(dirname "$0")/../docs" ec=0 # # Only test if suitable man is available # if command -v grep >/dev/null 2>&1 && \ man --help 2>/dev/null | grep -q warnings; then trap 'rm -f "$dstdir/man3"' EXIT ln -sf "$mandir" "$dstdir/man3" for manpage in "$mandir"/libssh2_*.*; do echo "$manpage" warnings=$(LANG=en_US.UTF-8 MANWIDTH=80 man -M "$dstdir" --warnings \ -E UTF-8 -l "$manpage" >/dev/null 2>&1) if [ -n "$warnings" ]; then echo "$warnings" ec=1 fi done else echo 'mansyntax: Required tool not found, skipping tests.' fi exit "$ec" libssh2-1.11.0/tests/test_auth_pubkey_ok_rsa_openssh.c0000644000175000017500000000065714424650606020062 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_RSA_SHA1 && \ (defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)) /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_rsa_openssh.pub", "key_rsa_openssh"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/test_auth_keyboard_info_request.c0000644000175000017500000002131414432741311020033 00000000000000/* Copyright (C) 2022 Xaver Loppenstedt * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "userauth_kbd_packet.h" #include #define PASS 0 #define FAIL -1 struct expected { int rc; int last_error_code; const char *last_error_message; }; struct test_case { const char *data; int data_len; struct expected expected; }; #define TEST_CASES_LEN 16 static const struct test_case test_cases[TEST_CASES_LEN] = { /* too small */ { NULL, 0, {FAIL, -38, "userauth keyboard data buffer too small to get length"}}, /* too small */ { "1234", 4, {FAIL, -38, "userauth keyboard data buffer too small to get length"}}, /* smallest valid packet possible */ { "<" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0", 17, {PASS, 0, ""}}, /* overrun name */ { "<" "\0\0\0\x7f" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0", 17, {FAIL, -6, "Unable to decode keyboard-interactive 'name' request field"}}, /* overrun instruction */ { "<" "\0\0\0\0" "\0\0\0\x7f" "\0\0\0\0" "\0\0\0\0", 17, {FAIL, -6, "Unable to decode keyboard-interactive 'instruction' " "request field"}}, /* overrun language */ { "<" "\0\0\0\0" "\0\0\0\0" "\0\0\0\x7f" "\0\0\0\0", 17, {FAIL, -6, "Unable to decode keyboard-interactive 'language tag' " "request field"}}, /* underrun prompt number */ { "<" "\0\0\0\x01" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0", 17, {FAIL, -38, "Unable to decode keyboard-interactive number of " "keyboard prompts"}}, /* too many prompts */ { "<" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\x7f", 17, {FAIL, -41, "Too many replies for keyboard-interactive prompts"}}, /* empty prompt */ { "<" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\x01" "\0\0\0\0" "\0", 22, {PASS, 0, ""}}, /* copied from OpenSSH */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01" "\0\0\0\x0aPassword: \0", 32, {PASS, 0, ""}}, /* overrun in prompt text */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01" "\0\0\0\x7bPassword: \0", 32, {FAIL, -6, "Unable to decode keyboard-interactive " "prompt message"}}, /* no echo prompt boolean */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01" "\0\0\0\x0bPassword: \0", 32, {FAIL, -38, "Unable to decode user auth keyboard prompt echo"}}, /* two prompts */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02" "\0\0\0\x0aPassword: \0" "\0\0\0\x07Token: \1", 44, {PASS, 0, ""}}, /* example from RFC 4256 */ { "<" "\0\0\0\x19""CRYPTOCard Authentication" "\0\0\0\x1b""The challenge is '14315716'" "\0\0\0\x05""en-US" "\0\0\0\x01" "\0\0\0\x0aResponse: " "\x01" , 89, {PASS, 0, ""}}, /* three prompts, 3rd missing */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03" "\0\0\0\x0aPassword: \0" "\0\0\0\x07Token: \1", 44, {FAIL, -6, "Unable to decode keyboard-interactive prompt message"}}, /* overflow language on 32 bit platform */ { "<" "\0\0\0\x19" "\0\0\0\x01" "\0\0\0\x05""PWN3D\0\1\2\3\4\5\6\7\1\2\3" "\x01" "\0\0\0\x1b""The challenge is '14315716'" "\xff\xff\xff\xc4""en-US" "\0\0\0\x01" "\0\0\0\x0aResponse: " "\x01", 89, {FAIL, -6, "Unable to decode keyboard-interactive 'language tag' " "request field"}}, }; #define FAILED_MALLOC_TEST_CASES_LEN 2 static const struct test_case failed_malloc_test_cases[FAILED_MALLOC_TEST_CASES_LEN] = { /* malloc fail */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01" "\0\0\0\x0aPassword: \0", 32, {FAIL, -6, "Unable to allocate memory for " "keyboard-interactive prompts array"}}, /* malloc fail */ { "<" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01" "\0\0\0\x0aPassword: \0", 32, {FAIL, -6, "Unable to allocate memory for " "keyboard-interactive responses array" }} }; static int alloc_count = 0; static int free_count = 0; /* libssh2_default_alloc */ static LIBSSH2_ALLOC_FUNC(test_alloc) { int *threshold_int_ptr = *abstract; alloc_count++; if(*abstract && *threshold_int_ptr == alloc_count) { return NULL; } return malloc(count); } /* libssh2_default_free */ static LIBSSH2_FREE_FUNC(test_free) { (void)abstract; free_count++; free(ptr); } static int test_case(int num, const char *data, int data_len, void *abstract, struct expected expected) { int rc; char *message; int error_code; LIBSSH2_SESSION *session; alloc_count = 0; free_count = 0; session = libssh2_session_init_ex(test_alloc, test_free, NULL, abstract); if(!session) { fprintf(stderr, "libssh2_session_init_ex failed\n"); return 1; } session->userauth_kybd_data = LIBSSH2_ALLOC(session, data_len); session->userauth_kybd_data_len = data_len; memcpy(session->userauth_kybd_data, data, data_len); rc = userauth_keyboard_interactive_decode_info_request(session); if(rc != expected.rc) { fprintf(stdout, "Test case %d: expected return code to be %d got %d\n", num, expected.rc, rc); return 1; } error_code = libssh2_session_last_error(session, &message, NULL, 0); if(expected.last_error_code != error_code) { fprintf(stdout, "Test case %d: expected last error code to be " "\"%d\" got \"%d\"\n", num, expected.last_error_code, error_code); return 1; } if(strcmp(expected.last_error_message, message) != 0) { fprintf(stdout, "Test case %d: expected last error message to be " "\"%s\" got \"%s\"\n", num, expected.last_error_message, message); return 1; } libssh2_session_free(session); fprintf(stderr, "Test case %d passed\n", num); return 0; } int main(void) { int ret = 0; int i; for(i = 0; i < TEST_CASES_LEN; i++) { if(test_case(i + 1, test_cases[i].data, test_cases[i].data_len, NULL, test_cases[i].expected)) ret = 1; } for(i = 0; i < FAILED_MALLOC_TEST_CASES_LEN; i++) { int tc = i + TEST_CASES_LEN + 1; int malloc_call_num = 3 + i; if(test_case(tc, failed_malloc_test_cases[i].data, failed_malloc_test_cases[i].data_len, &malloc_call_num, failed_malloc_test_cases[i].expected)) ret = 1; } return ret; } libssh2-1.11.0/tests/test_read.c0000644000175000017500000000727114424650606013357 00000000000000/* libssh2 test receiving large amounts of data through a channel */ #include "runner.h" #include /* for getenv() */ /* set in Dockerfile */ static const char *username = "libssh2"; static const char *key_file_private = "key_rsa"; static const char *key_file_public = "key_rsa.pub"; int test(LIBSSH2_SESSION *session) { int rc; unsigned long xfer_bytes = 0; LIBSSH2_CHANNEL *channel; /* Size and number of blocks to transfer * This needs to be large to increase the chance of timing effects causing * different code paths to be hit in the unframing code, but not so long * that the integration tests take too long. 5 seconds of run time is * probably a reasonable compromise. The block size is an odd number to * increase the chance that various internal buffer and block boundaries * are overlapped. */ const unsigned long xfer_bs = 997; unsigned long xfer_count = 140080; char remote_command[256]; const char *env; const char *userauth_list = libssh2_userauth_list(session, username, (unsigned int)strlen(username)); if(!userauth_list) { print_last_session_error("libssh2_userauth_list"); return 1; } if(!strstr(userauth_list, "publickey")) { fprintf(stderr, "'publickey' was expected in userauth list: %s\n", userauth_list); return 1; } rc = libssh2_userauth_publickey_fromfile_ex(session, username, (unsigned int)strlen(username), srcdir_path(key_file_public), srcdir_path(key_file_private), NULL); if(rc) { print_last_session_error("libssh2_userauth_publickey_fromfile_ex"); return 1; } /* Request a session channel on which to run a shell */ channel = libssh2_channel_open_session(session); if(!channel) { fprintf(stderr, "Unable to open a session\n"); goto shutdown; } env = getenv("FIXTURE_XFER_COUNT"); if(env) { xfer_count = (unsigned long)strtol(env, NULL, 0); fprintf(stderr, "Custom xfer_count: %lu\n", xfer_count); } /* command to transfer the desired amount of data */ snprintf(remote_command, sizeof(remote_command), "dd if=/dev/zero bs=%lu count=%lu status=none", xfer_bs, xfer_count); /* Send the command to transfer data */ if(libssh2_channel_exec(channel, remote_command)) { fprintf(stderr, "Unable to request command on channel\n"); goto shutdown; } /* Read data */ while(!libssh2_channel_eof(channel)) { char buf[1024]; ssize_t err = libssh2_channel_read(channel, buf, sizeof(buf)); if(err < 0) fprintf(stderr, "Unable to read response: %d\n", (int)err); else { unsigned int i; for(i = 0; i < (unsigned long)err; ++i) { if(buf[i]) { fprintf(stderr, "Bad data received\n"); /* Test will fail below due to bad data length */ break; } } xfer_bytes += i; } } /* Shut down */ if(libssh2_channel_close(channel)) fprintf(stderr, "Unable to close channel\n"); if(channel) { libssh2_channel_free(channel); channel = NULL; } shutdown: /* Test check */ if(xfer_bytes != xfer_count * xfer_bs) { fprintf(stderr, "Not enough bytes received: %lu not %lu\n", xfer_bytes, xfer_count * xfer_bs); return 1; /* error */ } return 0; } libssh2-1.11.0/tests/Makefile.in0000644000175000017500000021402714432741316013303 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ TESTS = mansyntax.sh $(am__EXEEXT_4) $(am__EXEEXT_2) $(am__append_2) \ $(am__append_4) @RUN_DOCKER_TESTS_TRUE@am__append_1 = $(DOCKER_TESTS) @RUN_SSHD_TESTS_TRUE@@SSHD_TRUE@am__append_2 = test_sshd.test @RUN_SSHD_TESTS_TRUE@@SSHD_TRUE@am__append_3 = SSHD="$(SSHD)" @RUN_DOCKER_TESTS_TRUE@am__append_4 = test_read_algos.test check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = test_aa_warmup$(EXEEXT) test_agent_forward_ok$(EXEEXT) \ test_auth_keyboard_fail$(EXEEXT) \ test_auth_keyboard_info_request$(EXEEXT) \ test_auth_keyboard_ok$(EXEEXT) \ test_auth_password_fail_password$(EXEEXT) \ test_auth_password_fail_username$(EXEEXT) \ test_auth_password_ok$(EXEEXT) test_auth_pubkey_fail$(EXEEXT) \ test_auth_pubkey_ok_dsa$(EXEEXT) \ test_auth_pubkey_ok_ecdsa$(EXEEXT) \ test_auth_pubkey_ok_ecdsa_signed$(EXEEXT) \ test_auth_pubkey_ok_ed25519$(EXEEXT) \ test_auth_pubkey_ok_ed25519_encrypted$(EXEEXT) \ test_auth_pubkey_ok_ed25519_mem$(EXEEXT) \ test_auth_pubkey_ok_rsa$(EXEEXT) \ test_auth_pubkey_ok_rsa_encrypted$(EXEEXT) \ test_auth_pubkey_ok_rsa_openssh$(EXEEXT) \ test_auth_pubkey_ok_rsa_signed$(EXEEXT) test_hostkey$(EXEEXT) \ test_hostkey_hash$(EXEEXT) test_read$(EXEEXT) am__EXEEXT_2 = test_simple$(EXEEXT) am__EXEEXT_3 = test_ssh2$(EXEEXT) test_auth_pubkey_ok_ed25519$(EXEEXT) librunner_la_LIBADD = am_librunner_la_OBJECTS = runner.lo session_fixture.lo \ openssh_fixture.lo librunner_la_OBJECTS = $(am_librunner_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = test_aa_warmup_SOURCES = test_aa_warmup.c test_aa_warmup_OBJECTS = test_aa_warmup.$(OBJEXT) test_aa_warmup_LDADD = $(LDADD) test_aa_warmup_DEPENDENCIES = librunner.la ../src/libssh2.la test_agent_forward_ok_SOURCES = test_agent_forward_ok.c test_agent_forward_ok_OBJECTS = test_agent_forward_ok.$(OBJEXT) test_agent_forward_ok_LDADD = $(LDADD) test_agent_forward_ok_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_keyboard_fail_SOURCES = test_auth_keyboard_fail.c test_auth_keyboard_fail_OBJECTS = test_auth_keyboard_fail.$(OBJEXT) test_auth_keyboard_fail_LDADD = $(LDADD) test_auth_keyboard_fail_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_keyboard_info_request_SOURCES = \ test_auth_keyboard_info_request.c test_auth_keyboard_info_request_OBJECTS = \ test_auth_keyboard_info_request.$(OBJEXT) test_auth_keyboard_info_request_LDADD = $(LDADD) test_auth_keyboard_info_request_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_keyboard_info_request_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) \ $(test_auth_keyboard_info_request_LDFLAGS) $(LDFLAGS) -o $@ test_auth_keyboard_ok_SOURCES = test_auth_keyboard_ok.c test_auth_keyboard_ok_OBJECTS = test_auth_keyboard_ok.$(OBJEXT) test_auth_keyboard_ok_LDADD = $(LDADD) test_auth_keyboard_ok_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_password_fail_password_SOURCES = \ test_auth_password_fail_password.c test_auth_password_fail_password_OBJECTS = \ test_auth_password_fail_password.$(OBJEXT) test_auth_password_fail_password_LDADD = $(LDADD) test_auth_password_fail_password_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_password_fail_username_SOURCES = \ test_auth_password_fail_username.c test_auth_password_fail_username_OBJECTS = \ test_auth_password_fail_username.$(OBJEXT) test_auth_password_fail_username_LDADD = $(LDADD) test_auth_password_fail_username_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_password_ok_SOURCES = test_auth_password_ok.c test_auth_password_ok_OBJECTS = test_auth_password_ok.$(OBJEXT) test_auth_password_ok_LDADD = $(LDADD) test_auth_password_ok_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_pubkey_fail_SOURCES = test_auth_pubkey_fail.c test_auth_pubkey_fail_OBJECTS = test_auth_pubkey_fail.$(OBJEXT) test_auth_pubkey_fail_LDADD = $(LDADD) test_auth_pubkey_fail_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_pubkey_ok_dsa_SOURCES = test_auth_pubkey_ok_dsa.c test_auth_pubkey_ok_dsa_OBJECTS = test_auth_pubkey_ok_dsa.$(OBJEXT) test_auth_pubkey_ok_dsa_LDADD = $(LDADD) test_auth_pubkey_ok_dsa_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_pubkey_ok_ecdsa_SOURCES = test_auth_pubkey_ok_ecdsa.c test_auth_pubkey_ok_ecdsa_OBJECTS = \ test_auth_pubkey_ok_ecdsa.$(OBJEXT) test_auth_pubkey_ok_ecdsa_LDADD = $(LDADD) test_auth_pubkey_ok_ecdsa_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_ecdsa_signed_SOURCES = \ test_auth_pubkey_ok_ecdsa_signed.c test_auth_pubkey_ok_ecdsa_signed_OBJECTS = \ test_auth_pubkey_ok_ecdsa_signed.$(OBJEXT) test_auth_pubkey_ok_ecdsa_signed_LDADD = $(LDADD) test_auth_pubkey_ok_ecdsa_signed_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_ed25519_SOURCES = test_auth_pubkey_ok_ed25519.c test_auth_pubkey_ok_ed25519_OBJECTS = \ test_auth_pubkey_ok_ed25519.$(OBJEXT) test_auth_pubkey_ok_ed25519_LDADD = $(LDADD) test_auth_pubkey_ok_ed25519_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_ed25519_encrypted_SOURCES = \ test_auth_pubkey_ok_ed25519_encrypted.c test_auth_pubkey_ok_ed25519_encrypted_OBJECTS = \ test_auth_pubkey_ok_ed25519_encrypted.$(OBJEXT) test_auth_pubkey_ok_ed25519_encrypted_LDADD = $(LDADD) test_auth_pubkey_ok_ed25519_encrypted_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_ed25519_mem_SOURCES = \ test_auth_pubkey_ok_ed25519_mem.c test_auth_pubkey_ok_ed25519_mem_OBJECTS = \ test_auth_pubkey_ok_ed25519_mem.$(OBJEXT) test_auth_pubkey_ok_ed25519_mem_LDADD = $(LDADD) test_auth_pubkey_ok_ed25519_mem_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_rsa_SOURCES = test_auth_pubkey_ok_rsa.c test_auth_pubkey_ok_rsa_OBJECTS = test_auth_pubkey_ok_rsa.$(OBJEXT) test_auth_pubkey_ok_rsa_LDADD = $(LDADD) test_auth_pubkey_ok_rsa_DEPENDENCIES = librunner.la ../src/libssh2.la test_auth_pubkey_ok_rsa_encrypted_SOURCES = \ test_auth_pubkey_ok_rsa_encrypted.c test_auth_pubkey_ok_rsa_encrypted_OBJECTS = \ test_auth_pubkey_ok_rsa_encrypted.$(OBJEXT) test_auth_pubkey_ok_rsa_encrypted_LDADD = $(LDADD) test_auth_pubkey_ok_rsa_encrypted_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_rsa_openssh_SOURCES = \ test_auth_pubkey_ok_rsa_openssh.c test_auth_pubkey_ok_rsa_openssh_OBJECTS = \ test_auth_pubkey_ok_rsa_openssh.$(OBJEXT) test_auth_pubkey_ok_rsa_openssh_LDADD = $(LDADD) test_auth_pubkey_ok_rsa_openssh_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_auth_pubkey_ok_rsa_signed_SOURCES = \ test_auth_pubkey_ok_rsa_signed.c test_auth_pubkey_ok_rsa_signed_OBJECTS = \ test_auth_pubkey_ok_rsa_signed.$(OBJEXT) test_auth_pubkey_ok_rsa_signed_LDADD = $(LDADD) test_auth_pubkey_ok_rsa_signed_DEPENDENCIES = librunner.la \ ../src/libssh2.la test_hostkey_SOURCES = test_hostkey.c test_hostkey_OBJECTS = test_hostkey.$(OBJEXT) test_hostkey_LDADD = $(LDADD) test_hostkey_DEPENDENCIES = librunner.la ../src/libssh2.la test_hostkey_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(test_hostkey_LDFLAGS) $(LDFLAGS) -o $@ test_hostkey_hash_SOURCES = test_hostkey_hash.c test_hostkey_hash_OBJECTS = test_hostkey_hash.$(OBJEXT) test_hostkey_hash_LDADD = $(LDADD) test_hostkey_hash_DEPENDENCIES = librunner.la ../src/libssh2.la test_read_SOURCES = test_read.c test_read_OBJECTS = test_read.$(OBJEXT) test_read_LDADD = $(LDADD) test_read_DEPENDENCIES = librunner.la ../src/libssh2.la test_simple_SOURCES = test_simple.c test_simple_OBJECTS = test_simple.$(OBJEXT) test_simple_LDADD = $(LDADD) test_simple_DEPENDENCIES = librunner.la ../src/libssh2.la test_simple_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(test_simple_LDFLAGS) $(LDFLAGS) -o $@ test_ssh2_SOURCES = test_ssh2.c test_ssh2_OBJECTS = test_ssh2.$(OBJEXT) test_ssh2_LDADD = $(LDADD) test_ssh2_DEPENDENCIES = librunner.la ../src/libssh2.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/openssh_fixture.Plo \ ./$(DEPDIR)/runner.Plo ./$(DEPDIR)/session_fixture.Plo \ ./$(DEPDIR)/test_aa_warmup.Po \ ./$(DEPDIR)/test_agent_forward_ok.Po \ ./$(DEPDIR)/test_auth_keyboard_fail.Po \ ./$(DEPDIR)/test_auth_keyboard_info_request.Po \ ./$(DEPDIR)/test_auth_keyboard_ok.Po \ ./$(DEPDIR)/test_auth_password_fail_password.Po \ ./$(DEPDIR)/test_auth_password_fail_username.Po \ ./$(DEPDIR)/test_auth_password_ok.Po \ ./$(DEPDIR)/test_auth_pubkey_fail.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_dsa.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_ecdsa.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_ecdsa_signed.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_ed25519.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_ed25519_encrypted.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_ed25519_mem.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_rsa.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_rsa_encrypted.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_rsa_openssh.Po \ ./$(DEPDIR)/test_auth_pubkey_ok_rsa_signed.Po \ ./$(DEPDIR)/test_hostkey.Po ./$(DEPDIR)/test_hostkey_hash.Po \ ./$(DEPDIR)/test_read.Po ./$(DEPDIR)/test_simple.Po \ ./$(DEPDIR)/test_ssh2.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(librunner_la_SOURCES) test_aa_warmup.c \ test_agent_forward_ok.c test_auth_keyboard_fail.c \ test_auth_keyboard_info_request.c test_auth_keyboard_ok.c \ test_auth_password_fail_password.c \ test_auth_password_fail_username.c test_auth_password_ok.c \ test_auth_pubkey_fail.c test_auth_pubkey_ok_dsa.c \ test_auth_pubkey_ok_ecdsa.c test_auth_pubkey_ok_ecdsa_signed.c \ test_auth_pubkey_ok_ed25519.c \ test_auth_pubkey_ok_ed25519_encrypted.c \ test_auth_pubkey_ok_ed25519_mem.c test_auth_pubkey_ok_rsa.c \ test_auth_pubkey_ok_rsa_encrypted.c \ test_auth_pubkey_ok_rsa_openssh.c \ test_auth_pubkey_ok_rsa_signed.c test_hostkey.c \ test_hostkey_hash.c test_read.c test_simple.c test_ssh2.c DIST_SOURCES = $(librunner_la_SOURCES) test_aa_warmup.c \ test_agent_forward_ok.c test_auth_keyboard_fail.c \ test_auth_keyboard_info_request.c test_auth_keyboard_ok.c \ test_auth_password_fail_password.c \ test_auth_password_fail_username.c test_auth_password_ok.c \ test_auth_pubkey_fail.c test_auth_pubkey_ok_dsa.c \ test_auth_pubkey_ok_ecdsa.c test_auth_pubkey_ok_ecdsa_signed.c \ test_auth_pubkey_ok_ed25519.c \ test_auth_pubkey_ok_ed25519_encrypted.c \ test_auth_pubkey_ok_ed25519_mem.c test_auth_pubkey_ok_rsa.c \ test_auth_pubkey_ok_rsa_encrypted.c \ test_auth_pubkey_ok_rsa_openssh.c \ test_auth_pubkey_ok_rsa_signed.c test_hostkey.c \ test_hostkey_hash.c test_read.c test_simple.c test_ssh2.c RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ check recheck distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) @RUN_DOCKER_TESTS_TRUE@am__EXEEXT_4 = $(am__EXEEXT_1) TEST_SUITE_LOG = test-suite.log LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ $(top_srcdir)/depcomp $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@ HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBWOLFSSL = @HAVE_LIBWOLFSSL@ HAVE_LIBZ = @HAVE_LIBZ@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBCRYPT = @LIBBCRYPT@ LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSREQUIRED = @LIBSREQUIRED@ LIBSSH2VER = @LIBSSH2VER@ LIBSSL = @LIBSSL@ LIBSSL_PREFIX = @LIBSSL_PREFIX@ LIBTOOL = @LIBTOOL@ LIBWOLFSSL = @LIBWOLFSSL@ LIBWOLFSSL_PREFIX = @LIBWOLFSSL_PREFIX@ LIBZ = @LIBZ@ LIBZ_PREFIX = @LIBZ_PREFIX@ LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@ LTLIBOBJS = @LTLIBOBJS@ LTLIBSSL = @LTLIBSSL@ LTLIBWOLFSSL = @LTLIBWOLFSSL@ LTLIBZ = @LTLIBZ@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ RC = @RC@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSHD = @SSHD@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = ossfuzz AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top_srcdir)/include # Keep this list sorted # # NOTE: test_auth_keyboard_info_request does not use the network, but when # run as Windows standalone test, it intermittently fails on GHA with: # `Terminate batch job (Y/N)?` DOCKER_TESTS = \ test_aa_warmup \ test_agent_forward_ok \ test_auth_keyboard_fail \ test_auth_keyboard_info_request \ test_auth_keyboard_ok \ test_auth_password_fail_password \ test_auth_password_fail_username \ test_auth_password_ok \ test_auth_pubkey_fail \ test_auth_pubkey_ok_dsa \ test_auth_pubkey_ok_ecdsa \ test_auth_pubkey_ok_ecdsa_signed \ test_auth_pubkey_ok_ed25519 \ test_auth_pubkey_ok_ed25519_encrypted \ test_auth_pubkey_ok_ed25519_mem \ test_auth_pubkey_ok_rsa \ test_auth_pubkey_ok_rsa_encrypted \ test_auth_pubkey_ok_rsa_openssh \ test_auth_pubkey_ok_rsa_signed \ test_hostkey \ test_hostkey_hash \ test_read STANDALONE_TESTS = \ test_simple SSHD_TESTS = \ test_ssh2 \ test_auth_pubkey_ok_ed25519 # Programs of the above that use internal libssh2 functions so they need # to be statically linked against libssh2 TESTS_WITH_LIB_STATIC = \ test_auth_keyboard_info_request \ test_hostkey \ test_simple # Copy of the above for Makefile.am. # Is there a way to reuse the list above? test_auth_keyboard_info_request_LDFLAGS = -static test_hostkey_LDFLAGS = -static test_simple_LDFLAGS = -static librunner_la_SOURCES = \ runner.c runner.h \ session_fixture.c session_fixture.h \ openssh_fixture.c openssh_fixture.h EXTRA_DIST = \ CMakeLists.txt \ key_dsa \ key_dsa.pub \ key_dsa_wrong \ key_dsa_wrong.pub \ key_ecdsa \ key_ecdsa.pub \ key_ecdsa_signed \ key_ecdsa_signed-cert.pub \ key_ecdsa_signed.pub \ key_ed25519 \ key_ed25519.pub \ key_ed25519_encrypted \ key_ed25519_encrypted.pub \ key_rsa \ key_rsa.pub \ key_rsa_encrypted \ key_rsa_encrypted.pub \ key_rsa_openssh \ key_rsa_openssh.pub \ key_rsa_signed \ key_rsa_signed-cert.pub \ key_rsa_signed.pub \ mansyntax.sh \ openssh_server/Dockerfile \ openssh_server/authorized_keys \ openssh_server/ca_ecdsa \ openssh_server/ca_ecdsa.pub \ openssh_server/ca_rsa \ openssh_server/ca_rsa.pub \ openssh_server/ca_user_keys.pub \ openssh_server/ssh_host_ecdsa_key \ openssh_server/ssh_host_ed25519_key \ openssh_server/ssh_host_rsa_key \ openssh_server/sshd_config \ test_read_algos.test \ test_read_algos.txt \ test_sshd.test # Get DOCKER_TESTS, STANDALONE_TESTS, SSHD_TESTS, TESTS_WITH_LIB_STATIC, # librunner_la_SOURCES defines and *_LDFLAGS for statically linked tests. # Some tests rely on the 'srcdir' env. Set by autotools automatically. TESTS_ENVIRONMENT = EXEEXT=$(EXEEXT) $(am__append_3) # TAP tests TEST_EXTENSIONS = .test # 'TEST' in 'TEST_LOG_DRIVER' is the test extension in uppercase. TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/tap-driver.sh # Internal library used by tests # This must be last in the list so it resolves symbols in previous libraries LDADD = librunner.la ../src/libssh2.la check_LTLIBRARIES = librunner.la all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(srcdir)/Makefile.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } librunner.la: $(librunner_la_OBJECTS) $(librunner_la_DEPENDENCIES) $(EXTRA_librunner_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(librunner_la_OBJECTS) $(librunner_la_LIBADD) $(LIBS) test_aa_warmup$(EXEEXT): $(test_aa_warmup_OBJECTS) $(test_aa_warmup_DEPENDENCIES) $(EXTRA_test_aa_warmup_DEPENDENCIES) @rm -f test_aa_warmup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_aa_warmup_OBJECTS) $(test_aa_warmup_LDADD) $(LIBS) test_agent_forward_ok$(EXEEXT): $(test_agent_forward_ok_OBJECTS) $(test_agent_forward_ok_DEPENDENCIES) $(EXTRA_test_agent_forward_ok_DEPENDENCIES) @rm -f test_agent_forward_ok$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_agent_forward_ok_OBJECTS) $(test_agent_forward_ok_LDADD) $(LIBS) test_auth_keyboard_fail$(EXEEXT): $(test_auth_keyboard_fail_OBJECTS) $(test_auth_keyboard_fail_DEPENDENCIES) $(EXTRA_test_auth_keyboard_fail_DEPENDENCIES) @rm -f test_auth_keyboard_fail$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_keyboard_fail_OBJECTS) $(test_auth_keyboard_fail_LDADD) $(LIBS) test_auth_keyboard_info_request$(EXEEXT): $(test_auth_keyboard_info_request_OBJECTS) $(test_auth_keyboard_info_request_DEPENDENCIES) $(EXTRA_test_auth_keyboard_info_request_DEPENDENCIES) @rm -f test_auth_keyboard_info_request$(EXEEXT) $(AM_V_CCLD)$(test_auth_keyboard_info_request_LINK) $(test_auth_keyboard_info_request_OBJECTS) $(test_auth_keyboard_info_request_LDADD) $(LIBS) test_auth_keyboard_ok$(EXEEXT): $(test_auth_keyboard_ok_OBJECTS) $(test_auth_keyboard_ok_DEPENDENCIES) $(EXTRA_test_auth_keyboard_ok_DEPENDENCIES) @rm -f test_auth_keyboard_ok$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_keyboard_ok_OBJECTS) $(test_auth_keyboard_ok_LDADD) $(LIBS) test_auth_password_fail_password$(EXEEXT): $(test_auth_password_fail_password_OBJECTS) $(test_auth_password_fail_password_DEPENDENCIES) $(EXTRA_test_auth_password_fail_password_DEPENDENCIES) @rm -f test_auth_password_fail_password$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_password_fail_password_OBJECTS) $(test_auth_password_fail_password_LDADD) $(LIBS) test_auth_password_fail_username$(EXEEXT): $(test_auth_password_fail_username_OBJECTS) $(test_auth_password_fail_username_DEPENDENCIES) $(EXTRA_test_auth_password_fail_username_DEPENDENCIES) @rm -f test_auth_password_fail_username$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_password_fail_username_OBJECTS) $(test_auth_password_fail_username_LDADD) $(LIBS) test_auth_password_ok$(EXEEXT): $(test_auth_password_ok_OBJECTS) $(test_auth_password_ok_DEPENDENCIES) $(EXTRA_test_auth_password_ok_DEPENDENCIES) @rm -f test_auth_password_ok$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_password_ok_OBJECTS) $(test_auth_password_ok_LDADD) $(LIBS) test_auth_pubkey_fail$(EXEEXT): $(test_auth_pubkey_fail_OBJECTS) $(test_auth_pubkey_fail_DEPENDENCIES) $(EXTRA_test_auth_pubkey_fail_DEPENDENCIES) @rm -f test_auth_pubkey_fail$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_fail_OBJECTS) $(test_auth_pubkey_fail_LDADD) $(LIBS) test_auth_pubkey_ok_dsa$(EXEEXT): $(test_auth_pubkey_ok_dsa_OBJECTS) $(test_auth_pubkey_ok_dsa_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_dsa_DEPENDENCIES) @rm -f test_auth_pubkey_ok_dsa$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_dsa_OBJECTS) $(test_auth_pubkey_ok_dsa_LDADD) $(LIBS) test_auth_pubkey_ok_ecdsa$(EXEEXT): $(test_auth_pubkey_ok_ecdsa_OBJECTS) $(test_auth_pubkey_ok_ecdsa_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_ecdsa_DEPENDENCIES) @rm -f test_auth_pubkey_ok_ecdsa$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_ecdsa_OBJECTS) $(test_auth_pubkey_ok_ecdsa_LDADD) $(LIBS) test_auth_pubkey_ok_ecdsa_signed$(EXEEXT): $(test_auth_pubkey_ok_ecdsa_signed_OBJECTS) $(test_auth_pubkey_ok_ecdsa_signed_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_ecdsa_signed_DEPENDENCIES) @rm -f test_auth_pubkey_ok_ecdsa_signed$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_ecdsa_signed_OBJECTS) $(test_auth_pubkey_ok_ecdsa_signed_LDADD) $(LIBS) test_auth_pubkey_ok_ed25519$(EXEEXT): $(test_auth_pubkey_ok_ed25519_OBJECTS) $(test_auth_pubkey_ok_ed25519_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_ed25519_DEPENDENCIES) @rm -f test_auth_pubkey_ok_ed25519$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_ed25519_OBJECTS) $(test_auth_pubkey_ok_ed25519_LDADD) $(LIBS) test_auth_pubkey_ok_ed25519_encrypted$(EXEEXT): $(test_auth_pubkey_ok_ed25519_encrypted_OBJECTS) $(test_auth_pubkey_ok_ed25519_encrypted_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_ed25519_encrypted_DEPENDENCIES) @rm -f test_auth_pubkey_ok_ed25519_encrypted$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_ed25519_encrypted_OBJECTS) $(test_auth_pubkey_ok_ed25519_encrypted_LDADD) $(LIBS) test_auth_pubkey_ok_ed25519_mem$(EXEEXT): $(test_auth_pubkey_ok_ed25519_mem_OBJECTS) $(test_auth_pubkey_ok_ed25519_mem_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_ed25519_mem_DEPENDENCIES) @rm -f test_auth_pubkey_ok_ed25519_mem$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_ed25519_mem_OBJECTS) $(test_auth_pubkey_ok_ed25519_mem_LDADD) $(LIBS) test_auth_pubkey_ok_rsa$(EXEEXT): $(test_auth_pubkey_ok_rsa_OBJECTS) $(test_auth_pubkey_ok_rsa_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_rsa_DEPENDENCIES) @rm -f test_auth_pubkey_ok_rsa$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_rsa_OBJECTS) $(test_auth_pubkey_ok_rsa_LDADD) $(LIBS) test_auth_pubkey_ok_rsa_encrypted$(EXEEXT): $(test_auth_pubkey_ok_rsa_encrypted_OBJECTS) $(test_auth_pubkey_ok_rsa_encrypted_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_rsa_encrypted_DEPENDENCIES) @rm -f test_auth_pubkey_ok_rsa_encrypted$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_rsa_encrypted_OBJECTS) $(test_auth_pubkey_ok_rsa_encrypted_LDADD) $(LIBS) test_auth_pubkey_ok_rsa_openssh$(EXEEXT): $(test_auth_pubkey_ok_rsa_openssh_OBJECTS) $(test_auth_pubkey_ok_rsa_openssh_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_rsa_openssh_DEPENDENCIES) @rm -f test_auth_pubkey_ok_rsa_openssh$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_rsa_openssh_OBJECTS) $(test_auth_pubkey_ok_rsa_openssh_LDADD) $(LIBS) test_auth_pubkey_ok_rsa_signed$(EXEEXT): $(test_auth_pubkey_ok_rsa_signed_OBJECTS) $(test_auth_pubkey_ok_rsa_signed_DEPENDENCIES) $(EXTRA_test_auth_pubkey_ok_rsa_signed_DEPENDENCIES) @rm -f test_auth_pubkey_ok_rsa_signed$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_auth_pubkey_ok_rsa_signed_OBJECTS) $(test_auth_pubkey_ok_rsa_signed_LDADD) $(LIBS) test_hostkey$(EXEEXT): $(test_hostkey_OBJECTS) $(test_hostkey_DEPENDENCIES) $(EXTRA_test_hostkey_DEPENDENCIES) @rm -f test_hostkey$(EXEEXT) $(AM_V_CCLD)$(test_hostkey_LINK) $(test_hostkey_OBJECTS) $(test_hostkey_LDADD) $(LIBS) test_hostkey_hash$(EXEEXT): $(test_hostkey_hash_OBJECTS) $(test_hostkey_hash_DEPENDENCIES) $(EXTRA_test_hostkey_hash_DEPENDENCIES) @rm -f test_hostkey_hash$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_hostkey_hash_OBJECTS) $(test_hostkey_hash_LDADD) $(LIBS) test_read$(EXEEXT): $(test_read_OBJECTS) $(test_read_DEPENDENCIES) $(EXTRA_test_read_DEPENDENCIES) @rm -f test_read$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_read_OBJECTS) $(test_read_LDADD) $(LIBS) test_simple$(EXEEXT): $(test_simple_OBJECTS) $(test_simple_DEPENDENCIES) $(EXTRA_test_simple_DEPENDENCIES) @rm -f test_simple$(EXEEXT) $(AM_V_CCLD)$(test_simple_LINK) $(test_simple_OBJECTS) $(test_simple_LDADD) $(LIBS) test_ssh2$(EXEEXT): $(test_ssh2_OBJECTS) $(test_ssh2_DEPENDENCIES) $(EXTRA_test_ssh2_DEPENDENCIES) @rm -f test_ssh2$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ssh2_OBJECTS) $(test_ssh2_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssh_fixture.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runner.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session_fixture.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_aa_warmup.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_agent_forward_ok.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_keyboard_fail.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_keyboard_info_request.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_keyboard_ok.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_password_fail_password.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_password_fail_username.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_password_ok.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_fail.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_dsa.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_ecdsa.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_ecdsa_signed.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_ed25519.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_ed25519_encrypted.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_ed25519_mem.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_rsa.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_rsa_encrypted.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_rsa_openssh.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_pubkey_ok_rsa_signed.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_hostkey.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_hostkey_hash.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_read.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_simple.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ssh2.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) $(check_LTLIBRARIES) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(check_LTLIBRARIES) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? mansyntax.sh.log: mansyntax.sh @p='mansyntax.sh'; \ b='mansyntax.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_aa_warmup.log: test_aa_warmup$(EXEEXT) @p='test_aa_warmup$(EXEEXT)'; \ b='test_aa_warmup'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_agent_forward_ok.log: test_agent_forward_ok$(EXEEXT) @p='test_agent_forward_ok$(EXEEXT)'; \ b='test_agent_forward_ok'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_keyboard_fail.log: test_auth_keyboard_fail$(EXEEXT) @p='test_auth_keyboard_fail$(EXEEXT)'; \ b='test_auth_keyboard_fail'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_keyboard_info_request.log: test_auth_keyboard_info_request$(EXEEXT) @p='test_auth_keyboard_info_request$(EXEEXT)'; \ b='test_auth_keyboard_info_request'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_keyboard_ok.log: test_auth_keyboard_ok$(EXEEXT) @p='test_auth_keyboard_ok$(EXEEXT)'; \ b='test_auth_keyboard_ok'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_password_fail_password.log: test_auth_password_fail_password$(EXEEXT) @p='test_auth_password_fail_password$(EXEEXT)'; \ b='test_auth_password_fail_password'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_password_fail_username.log: test_auth_password_fail_username$(EXEEXT) @p='test_auth_password_fail_username$(EXEEXT)'; \ b='test_auth_password_fail_username'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_password_ok.log: test_auth_password_ok$(EXEEXT) @p='test_auth_password_ok$(EXEEXT)'; \ b='test_auth_password_ok'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_fail.log: test_auth_pubkey_fail$(EXEEXT) @p='test_auth_pubkey_fail$(EXEEXT)'; \ b='test_auth_pubkey_fail'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_dsa.log: test_auth_pubkey_ok_dsa$(EXEEXT) @p='test_auth_pubkey_ok_dsa$(EXEEXT)'; \ b='test_auth_pubkey_ok_dsa'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_ecdsa.log: test_auth_pubkey_ok_ecdsa$(EXEEXT) @p='test_auth_pubkey_ok_ecdsa$(EXEEXT)'; \ b='test_auth_pubkey_ok_ecdsa'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_ecdsa_signed.log: test_auth_pubkey_ok_ecdsa_signed$(EXEEXT) @p='test_auth_pubkey_ok_ecdsa_signed$(EXEEXT)'; \ b='test_auth_pubkey_ok_ecdsa_signed'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_ed25519.log: test_auth_pubkey_ok_ed25519$(EXEEXT) @p='test_auth_pubkey_ok_ed25519$(EXEEXT)'; \ b='test_auth_pubkey_ok_ed25519'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_ed25519_encrypted.log: test_auth_pubkey_ok_ed25519_encrypted$(EXEEXT) @p='test_auth_pubkey_ok_ed25519_encrypted$(EXEEXT)'; \ b='test_auth_pubkey_ok_ed25519_encrypted'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_ed25519_mem.log: test_auth_pubkey_ok_ed25519_mem$(EXEEXT) @p='test_auth_pubkey_ok_ed25519_mem$(EXEEXT)'; \ b='test_auth_pubkey_ok_ed25519_mem'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_rsa.log: test_auth_pubkey_ok_rsa$(EXEEXT) @p='test_auth_pubkey_ok_rsa$(EXEEXT)'; \ b='test_auth_pubkey_ok_rsa'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_rsa_encrypted.log: test_auth_pubkey_ok_rsa_encrypted$(EXEEXT) @p='test_auth_pubkey_ok_rsa_encrypted$(EXEEXT)'; \ b='test_auth_pubkey_ok_rsa_encrypted'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_rsa_openssh.log: test_auth_pubkey_ok_rsa_openssh$(EXEEXT) @p='test_auth_pubkey_ok_rsa_openssh$(EXEEXT)'; \ b='test_auth_pubkey_ok_rsa_openssh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_auth_pubkey_ok_rsa_signed.log: test_auth_pubkey_ok_rsa_signed$(EXEEXT) @p='test_auth_pubkey_ok_rsa_signed$(EXEEXT)'; \ b='test_auth_pubkey_ok_rsa_signed'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_hostkey.log: test_hostkey$(EXEEXT) @p='test_hostkey$(EXEEXT)'; \ b='test_hostkey'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_hostkey_hash.log: test_hostkey_hash$(EXEEXT) @p='test_hostkey_hash$(EXEEXT)'; \ b='test_hostkey_hash'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_read.log: test_read$(EXEEXT) @p='test_read$(EXEEXT)'; \ b='test_read'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_simple.log: test_simple$(EXEEXT) @p='test_simple$(EXEEXT)'; \ b='test_simple'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_LTLIBRARIES) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f ./$(DEPDIR)/openssh_fixture.Plo -rm -f ./$(DEPDIR)/runner.Plo -rm -f ./$(DEPDIR)/session_fixture.Plo -rm -f ./$(DEPDIR)/test_aa_warmup.Po -rm -f ./$(DEPDIR)/test_agent_forward_ok.Po -rm -f ./$(DEPDIR)/test_auth_keyboard_fail.Po -rm -f ./$(DEPDIR)/test_auth_keyboard_info_request.Po -rm -f ./$(DEPDIR)/test_auth_keyboard_ok.Po -rm -f ./$(DEPDIR)/test_auth_password_fail_password.Po -rm -f ./$(DEPDIR)/test_auth_password_fail_username.Po -rm -f ./$(DEPDIR)/test_auth_password_ok.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_fail.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_dsa.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ecdsa.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ecdsa_signed.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ed25519.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ed25519_encrypted.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ed25519_mem.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa_encrypted.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa_openssh.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa_signed.Po -rm -f ./$(DEPDIR)/test_hostkey.Po -rm -f ./$(DEPDIR)/test_hostkey_hash.Po -rm -f ./$(DEPDIR)/test_read.Po -rm -f ./$(DEPDIR)/test_simple.Po -rm -f ./$(DEPDIR)/test_ssh2.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/openssh_fixture.Plo -rm -f ./$(DEPDIR)/runner.Plo -rm -f ./$(DEPDIR)/session_fixture.Plo -rm -f ./$(DEPDIR)/test_aa_warmup.Po -rm -f ./$(DEPDIR)/test_agent_forward_ok.Po -rm -f ./$(DEPDIR)/test_auth_keyboard_fail.Po -rm -f ./$(DEPDIR)/test_auth_keyboard_info_request.Po -rm -f ./$(DEPDIR)/test_auth_keyboard_ok.Po -rm -f ./$(DEPDIR)/test_auth_password_fail_password.Po -rm -f ./$(DEPDIR)/test_auth_password_fail_username.Po -rm -f ./$(DEPDIR)/test_auth_password_ok.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_fail.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_dsa.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ecdsa.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ecdsa_signed.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ed25519.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ed25519_encrypted.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_ed25519_mem.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa_encrypted.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa_openssh.Po -rm -f ./$(DEPDIR)/test_auth_pubkey_ok_rsa_signed.Po -rm -f ./$(DEPDIR)/test_hostkey.Po -rm -f ./$(DEPDIR)/test_hostkey_hash.Po -rm -f ./$(DEPDIR)/test_read.Po -rm -f ./$(DEPDIR)/test_simple.Po -rm -f ./$(DEPDIR)/test_ssh2.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles check check-TESTS check-am clean \ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libssh2-1.11.0/tests/key_rsa_signed-cert.pub0000644000175000017500000000421514424650606015665 00000000000000ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgqdnJWdHT2qMpEe6kVJ81q9c0U3ODMvcuWfJJkV8UVBoAAAADAQABAAACAQCwMtW6rz83hgCKqV1Xf2KPgtWA5pkVA3jY4CosgWsV8rjwSpq+AMmB1wzVdTT/zrEEyy2iLoIwiAXQ7wlpo1QQWklnChIdlbaxg+F0UullsYIYoExrL+9YMwRGwmd00yIe/POHlBCa10qeBWfdMmjt5ZDlakPVYwFjvK5lZ0UW1FM1ucqX5HoIPhVONfReZonCP+jwvin44IMaqtdaSy4k71Qq7RuRbMYeTzpNaxv2CbxubvY5E7wlDrT47e25Dn/XeoV2VEX9T87ZAMnwmeyDbKW2Dv48l4Zze3Y8veUojfH3NlA/F9+1PwdTlqKsf45E/VVLyTTtn1KJy2hLyuav8Qt6Wgew41G2F9alDJab11urcogRiHyI/oPo0c6Km1vieF7IfW72yE5TFTZtbzSNS+W0GCo1xh4TUx8bBNXHO4+mDFt2gNCgX+Hf64FlPqM0kaZSUtBVKrWSupgTbMSXfHbRV5NJvSdGpPUWeFD1ifxYcPhxwJlznTXVQumEglDueIMsnE8yKEYjREtuao8/r9+ORtqf9OPZsT9j+bwROevLFnKZkzfD9xYQyU2aMrRDuo8R6SD7SiI6tXRwlohdflXA6ng9RTNyqVROQDOJ94bGPD5b4Bbnm31s2GhhWjoByQGlkNW4BRDEJmgG9sE8ztAxl7d8CV2V93BOisaPkwAAAAAAAAABAAAAAQAAAAhpZGVudGl0eQAAAAsAAAAHbGlic3NoMgAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEAxIgbEZbIoQoNJyRjalEYbMwmcNRcGZg6ZA+uC+hxX9lPxhVxYAwbWCWfM3YLmvkQPRf0DYateDlHpiV9/R4IAKMfwHMINbyj5ulj2AG9wzMs10+MLN9kmxXeZXf7EK6iVHjMWhS7tX9NnmNFLbUHuPpzI6DODHvfEIaO084KQyIJ/Z5bONko7eijPZrqkwSFb+FEsIvSLBZ/ueHtAhI34IhclPP/Gx+r6da7TDwOpuL7oncrdqT+zxxZ1J4pEBrGhuJXTvw/xtBRbTKj13gtcEFyOUR50Z7PU4iOhKd694euGSOYgWGXhtehZPp7hr7afli1hOZtNb3xB3OaPqdPY/jYtZkOaZlKtwDjPzGTIfngpE7LZwsp4P2xxGUyCkItZ57uveDHKvFtb9+MIDMgTd27xOuTYYyHS7m5x7w4M1Z9du8IzxHXlQ/UobQAsTUuGusSQloOpZR1cs3s6p4+vLpl63tNjLFy2xYpFf3xL1Dl1Kf6w3qPiyYs5NmxwJcpAAABlAAAAAxyc2Etc2hhMi01MTIAAAGAK6d2jj8qv89wqRuE2bUFKKJDH4aIs7PGzKclTjZFomlkGvjRF/bsdDeUgwWdJ98j2TPdUvsAMlQrDS1e0OrDicen6eHrFhirpQxVLsAxj/c56nLedvzpbA/BLh8cFcq1vUZ1QHb2WOgOqWRcRbH/3TZhlA+gJ46kKs3QEw9uYy6m906xGwCWRiBUetfll5hS1sWCbAP2LLnA/OJUbIK9vKynombePRApY3LuZ8Hr0JCGgeBnfsesFbWLN6Gb+jT0KR4ah7O39lqecmvdUOR5XcMaSp+sgPpdBr7CzA5lkZnoI/M2J7AV1P5SX/q7/khJMKHuKwAsYf5kNAQdnEnwrqNTp//+qIWe5KjAtc0N5UOF5aK0e1iNaBxSHZA08psRLCCUf3PW3zMIlphUF7qIrRfV+s5fUMW0iIS2iUqI8dTrD0OH0wU10ERKQPixNCqtxBSbJzOyhDWPkTNfBshS8zA2/OVfug0zuxaINpAnZaiCcMnyCjATuWtvWpad6yF9 key_rsa_signed libssh2-1.11.0/tests/Makefile.inc0000644000175000017500000000462014432741311013435 00000000000000# Keep this list sorted # # NOTE: test_auth_keyboard_info_request does not use the network, but when # run as Windows standalone test, it intermittently fails on GHA with: # `Terminate batch job (Y/N)?` DOCKER_TESTS = \ test_aa_warmup \ test_agent_forward_ok \ test_auth_keyboard_fail \ test_auth_keyboard_info_request \ test_auth_keyboard_ok \ test_auth_password_fail_password \ test_auth_password_fail_username \ test_auth_password_ok \ test_auth_pubkey_fail \ test_auth_pubkey_ok_dsa \ test_auth_pubkey_ok_ecdsa \ test_auth_pubkey_ok_ecdsa_signed \ test_auth_pubkey_ok_ed25519 \ test_auth_pubkey_ok_ed25519_encrypted \ test_auth_pubkey_ok_ed25519_mem \ test_auth_pubkey_ok_rsa \ test_auth_pubkey_ok_rsa_encrypted \ test_auth_pubkey_ok_rsa_openssh \ test_auth_pubkey_ok_rsa_signed \ test_hostkey \ test_hostkey_hash \ test_read STANDALONE_TESTS = \ test_simple SSHD_TESTS = \ test_ssh2 \ test_auth_pubkey_ok_ed25519 # Programs of the above that use internal libssh2 functions so they need # to be statically linked against libssh2 TESTS_WITH_LIB_STATIC = \ test_auth_keyboard_info_request \ test_hostkey \ test_simple # Copy of the above for Makefile.am. # Is there a way to reuse the list above? test_auth_keyboard_info_request_LDFLAGS = -static test_hostkey_LDFLAGS = -static test_simple_LDFLAGS = -static librunner_la_SOURCES = \ runner.c runner.h \ session_fixture.c session_fixture.h \ openssh_fixture.c openssh_fixture.h EXTRA_DIST = \ CMakeLists.txt \ key_dsa \ key_dsa.pub \ key_dsa_wrong \ key_dsa_wrong.pub \ key_ecdsa \ key_ecdsa.pub \ key_ecdsa_signed \ key_ecdsa_signed-cert.pub \ key_ecdsa_signed.pub \ key_ed25519 \ key_ed25519.pub \ key_ed25519_encrypted \ key_ed25519_encrypted.pub \ key_rsa \ key_rsa.pub \ key_rsa_encrypted \ key_rsa_encrypted.pub \ key_rsa_openssh \ key_rsa_openssh.pub \ key_rsa_signed \ key_rsa_signed-cert.pub \ key_rsa_signed.pub \ mansyntax.sh \ openssh_server/Dockerfile \ openssh_server/authorized_keys \ openssh_server/ca_ecdsa \ openssh_server/ca_ecdsa.pub \ openssh_server/ca_rsa \ openssh_server/ca_rsa.pub \ openssh_server/ca_user_keys.pub \ openssh_server/ssh_host_ecdsa_key \ openssh_server/ssh_host_ed25519_key \ openssh_server/ssh_host_rsa_key \ openssh_server/sshd_config \ test_read_algos.test \ test_read_algos.txt \ test_sshd.test libssh2-1.11.0/tests/test_ssh2.c0000644000175000017500000001557114424650606013325 00000000000000/* Self test, based on example/ssh2.c. */ #include "libssh2_setup.h" #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #include #include /* for getenv() */ static const char *hostname = "127.0.0.1"; static const unsigned short port_number = 4711; static const char *pubkey = "key_rsa.pub"; static const char *privkey = "key_rsa"; static const char *username = "username"; static const char *password = "password"; static void portable_sleep(unsigned int seconds) { #ifdef WIN32 Sleep(seconds); #else sleep(seconds); #endif } int main(int argc, char *argv[]) { uint32_t hostaddr; libssh2_socket_t sock; int i, auth_pw = 0; struct sockaddr_in sin; const char *fingerprint; char *userauthlist; int rc; LIBSSH2_SESSION *session = NULL; LIBSSH2_CHANNEL *channel; int counter; #ifdef WIN32 WSADATA wsadata; rc = WSAStartup(MAKEWORD(2, 0), &wsadata); if(rc) { fprintf(stderr, "WSAStartup failed with error: %d\n", rc); return 1; } #endif (void)argc; (void)argv; if(getenv("USER")) username = getenv("USER"); #ifdef WIN32 else if(getenv("USERNAME")) username = getenv("USERNAME"); #endif if(getenv("PRIVKEY")) privkey = getenv("PRIVKEY"); if(getenv("PUBKEY")) pubkey = getenv("PUBKEY"); hostaddr = inet_addr(hostname); if(hostaddr == (uint32_t)(-1)) { fprintf(stderr, "Failed to convert %s host address\n", hostname); return 1; } rc = libssh2_init(0); if(rc) { fprintf(stderr, "libssh2 initialization failed (%d)\n", rc); return 1; } rc = 1; sock = socket(AF_INET, SOCK_STREAM, 0); if(sock == LIBSSH2_INVALID_SOCKET) { fprintf(stderr, "failed to create socket!\n"); goto shutdown; } sin.sin_family = AF_INET; sin.sin_port = htons(port_number); sin.sin_addr.s_addr = hostaddr; for(counter = 0; counter < 3; ++counter) { if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) { fprintf(stderr, "Connection to %s:%d attempt #%d failed: retrying...\n", hostname, port_number, counter); portable_sleep(1 + 2*counter); } else { break; } } if(sock == LIBSSH2_INVALID_SOCKET) { fprintf(stderr, "Failed to connect to %s:%d\n", hostname, port_number); goto shutdown; } /* Create a session instance and start it up. This will trade welcome * banners, exchange keys, and setup crypto, compression, and MAC layers */ session = libssh2_session_init(); if(!session) { fprintf(stderr, "Could not initialize SSH session!\n"); goto shutdown; } if(getenv("FIXTURE_TRACE_ALL_CONNECT") || getenv("FIXTURE_TRACE_ALL")) { libssh2_trace(session, ~0); fprintf(stdout, "Trace all enabled.\n"); } libssh2_session_set_blocking(session, 1); { int retries = 0, retry = 0; #ifdef LIBSSH2_WINCNG /* FIXME: Retry tests with WinCNG due to flakiness in hostkey verification: https://github.com/libssh2/libssh2/issues/804 */ retries += 2; #endif do { rc = libssh2_session_handshake(session, sock); if(rc == 0) { break; } fprintf(stderr, "Failure establishing SSH session: %d\n", rc); if( #ifdef LIBSSH2_WINCNG rc != LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE || #endif ++retry > retries) { break; } fprintf(stderr, "Retrying... %d / %d\n", retry, retries); } while(1); } rc = 1; /* At this point we have not yet authenticated. The first thing to do * is check the hostkey's fingerprint against our known hosts Your app * may have it hard coded, may go to a file, may present it to the * user, that's your call */ fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1); fprintf(stderr, "Fingerprint: "); for(i = 0; i < 20; i++) { fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); } fprintf(stderr, "\n"); /* check what authentication methods are available */ userauthlist = libssh2_userauth_list(session, username, (unsigned int)strlen(username)); if(userauthlist) { fprintf(stderr, "Authentication methods: %s\n", userauthlist); if(strstr(userauthlist, "password")) { auth_pw |= 1; } if(strstr(userauthlist, "keyboard-interactive")) { auth_pw |= 2; } if(strstr(userauthlist, "publickey")) { auth_pw |= 4; } if(auth_pw & 4) { /* Authenticate by public key */ if(libssh2_userauth_publickey_fromfile(session, username, pubkey, privkey, password)) { fprintf(stderr, "Authentication by public key failed!\n"); goto shutdown; } else { fprintf(stderr, "Authentication by public key succeeded.\n"); } } else { fprintf(stderr, "No supported authentication methods found!\n"); goto shutdown; } } /* Request a session channel on which to run a shell */ channel = libssh2_channel_open_session(session); if(!channel) { fprintf(stderr, "Unable to open a session\n"); goto shutdown; } /* Some environment variables may be set, * It's up to the server which ones it'll allow though */ libssh2_channel_setenv(channel, "FOO", "bar"); /* Request a terminal with 'vanilla' terminal emulation * See /etc/termcap for more options. This is useful when opening * an interactive shell. */ if(libssh2_channel_request_pty(channel, "vanilla")) { fprintf(stderr, "Failed requesting pty\n"); goto skip_shell; } /* Open a SHELL on that pty */ if(libssh2_channel_shell(channel)) { fprintf(stderr, "Unable to request shell on allocated pty\n"); goto shutdown; } rc = 0; skip_shell: if(channel) { libssh2_channel_free(channel); channel = NULL; } shutdown: if(session) { libssh2_session_disconnect(session, "Normal Shutdown"); libssh2_session_free(session); } if(sock != LIBSSH2_INVALID_SOCKET) { shutdown(sock, 2 /* SHUT_RDWR */); #ifdef WIN32 closesocket(sock); #else close(sock); #endif } fprintf(stderr, "all done\n"); libssh2_exit(); return rc; } libssh2-1.11.0/tests/key_ed25519_encrypted0000644000175000017500000000072013446422146015076 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABD4qdu8J/ EAqXFQERrvzMerAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAICHxEyUTOVHXvdMF ARedFQ+H9DW/n8Zy3daKKRqnTDMqAAAAoO05oxXUkLz8cMQcMeeRSc4UvsaWnCvfN4Qm15 NaVwSjb/09AcGGVeF1xxwPEIjwsIRftAjjgLuauI6XpXzyeDOlr2HnwzgpZtmeaHzbB7lS NjpSENP+fXipXinSfgZqGOItPbbismEVWX4sQn/Zla6/f/JAcDV60TK2ZhVEZ5072t0NcA eZQeSzBnpoRhlB7IDO7/7pmu1kNysUzH94Bw8= -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/key_ecdsa_signed-cert.pub0000644000175000017500000000202714424650606016156 00000000000000ecdsa-sha2-nistp384-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAzODQtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgQCXc1JaqZ4XzkudbzP/pgEUbkioo7pl9aB09h6sg7KYAAAAIbmlzdHAzODQAAABhBG/X9+c3VK4iSDbbaNifJKognzwnkzdsHokZ6WgqEi+dl085JUW4UGO4Xs0+sauybztCy1AVsOIuEiVwM0cirRWFLmK0c0yO0LpiZFHHuaVBJc9tFEXkxyXG8MkIzIAhqAAAAAAAAAABAAAAAQAAAAhpZGVudGl0eQAAAAsAAAAHbGlic3NoMgAAAAAAAAAA//////////8AAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAAArAAAABNlY2RzYS1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQAfv15s+G2xg56J+audKAM4G9qOTFrbZRo0CTwvkb/oHrf9/2RSWqYsx/0m5mYCZVlecnZqwRHAOolXbc/Yb4cGjsALUj3UDirsnYR7Ve+SwnunkpvW/H3a98sA3sS+HCpd5RbpfWClSBOI9JEAlPtS1CrEQ7EmO7hmlFOH2cL0qfHCyYAAACnAAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAACMAAAAQgGxnhh8z8LNk5pMw0D9InyEtVRm8OJi23XEhqj/ieT/BsLZXbu65UAcMjrUn6DPdERxF9Dwe9pdIAWOLLjLHYEFBQAAAEIAlxz+XjUKa9Q2vpH0y8IgJMm0H1hTBUM1DQEoL8No1BVtgtIO20mac2fE3I35JxNDmmXoW+FuzmJnyrY9rxY+YXM= key_ecdsa_signed.pub libssh2-1.11.0/tests/test_read_algos.txt0000644000175000017500000000042714424650606015135 000000000000003des-cbc aes128-cbc aes128-ctr aes128-gcm@openssh.com aes192-cbc aes192-ctr aes256-cbc aes256-ctr aes256-gcm@openssh.com hmac-md5 hmac-md5-96 hmac-sha1 hmac-sha1-96 hmac-sha1-etm@openssh.com hmac-sha2-256 hmac-sha2-256-etm@openssh.com hmac-sha2-512 hmac-sha2-512-etm@openssh.com libssh2-1.11.0/tests/session_fixture.h0000644000175000017500000000475514424650606014647 00000000000000/* Copyright (C) 2016 Alexander Lamaison * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef LIBSSH2_TESTS_SESSION_FIXTURE_H #define LIBSSH2_TESTS_SESSION_FIXTURE_H #define LIBSSH2_TESTS #include "libssh2_priv.h" LIBSSH2_SESSION *start_session_fixture(int *skipped, int *err); void stop_session_fixture(void); void print_last_session_error(const char *function); const char *srcdir_path(const char *file); #define TEST_AUTH_SHOULDFAIL 1 #define TEST_AUTH_FROMMEM 2 int test_auth_keyboard(LIBSSH2_SESSION *session, int flags, const char *username, const char *password); int test_auth_password(LIBSSH2_SESSION *session, int flags, const char *username, const char *password); int test_auth_pubkey(LIBSSH2_SESSION *session, int flags, const char *username, const char *password, const char *fn_pub, const char *fn_priv); #endif libssh2-1.11.0/tests/key_ecdsa.pub0000644000175000017500000000031514424650606013670 00000000000000ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOiyJJwf+hFJrOkik9IQVxjhhVnI1vKl4BGLj03erLvw4TXXwoZzlPx6J936fU9JvvPw+d8PA4viMEfFbmdbHREKhwi3u1vZrfj0mB8SXw96AcZwX8PAL556wgom+/Qx+Q== libssh2-1.11.0/tests/key_ed25519.pub0000644000175000017500000000013514424650606013607 00000000000000ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFEg0II3zbc1yWGhRzIc5KwTRlmx10RQP0sS63+1oMPi key_ed25519 libssh2-1.11.0/tests/key_rsa_encrypted0000644000175000017500000000334613446422146014674 00000000000000-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,E030CC29AE4C20669EE41DF3DE4C0886 gLMMWawVUpqtAtpSVnr7HcH+P0gHKFU00hUhNY18TNJRfFIhPqc9R9xsLHgBac7k vHtD2nzUuWLVMIKQoS3+1IF/KO6Xj1zSqnyk49hyKWxFiD3U1YdZAiZNgJ/s6olg J/h4mNNsz8Nh6Swp3HwP2jtLHWHV8fOzsaE3dvnVYZ5gPnec7XAYcQycbOV0t2Wd NGlP09ooAQRWWuf1TaBewjj7Jm40l8OQat5EKZKzydUZZQYAqfJQ7fIw7jI/lQYF KJj9tq0ceFdxvk8LYMr5a+ixnDwirxgg4L0X3fjLocfLVt42qDKkfOGXGg9VI8CO gjTu/MbodGCWKe/5eeCSSLrKo486S/5B6RzN0Ax4QBb1iYAN5IECsV91Ekk0socY DBZmDMEGHppHJhNhbBzfMYeKssWbOQf9z0y+gDPesImV2gXNoMgTcmZrCLOJWj6L ifQAtTKc8P5fV+TLhg3dKmxCt1UMlCHpWWl7tPTsO3WaaXi50f9ypRfpbpH0hket SO//bZqF0lF+Ci8uC6ndXBniIfinFoMWPsY01bxyHvmEMwCTVApZEkrZtGlHnavy d2oYJ0Oc+eeSjnx2BccQ9GdoI3292CVJVgPiibr42updecFwTry+j//IY8H3d62m UYUXJQgIL04o2/1UIT0mPWwPigF3sJSZOwT5arn4MgUyBCC18p6OTmGmvIyrz3YB imbhndok/30sMwtJocgXKTdyreMUp0s8Hpw/2z4LQ0qlOstKwa8KnDcFAqaSFNGD 8tGTobAcGRhqq93PRrn3aRibk1T3KDpMF/oqRaajgBmXFVYOk1yuLy6meB+wAJFD VVIokZaygYs13SMX+hau0Gd6PmVh8QF0RmvG69ga7k4dfJMbe2uU59wf9uABmyvd +Ju+uXGiF0wYfcyv6HJarPIqA3630TPKR/z8dDWC3rJ83xx7hIpoEAA+b7RA3Vtx Gv0EoDK6zeq4UJK0tqxMZJuy+FHBDZhv+gAeB/PmIGPIbF+jV+flmCrUgHg2Ka8I Iaap+lQKMj5lzOv/1bbcZ6cpj717MGvo3XOwOD4x5b3wRX6DWphB0+oRWiVU3Vrd PiZ0gtlX31Rj+h+QB4DrMKZWMu++qEDF6NPLz2ktNcjOYBT29VVqX8ALKKFO+jOK ZASnUXXE3XnwbccwU9VIQ+3mom3K+GjJRGxsWNZsrPy364eQHckomcOptgk5ldI1 eF7t5w0xQ4hx6jrJBcKJL29SQAcmUO+vu+6Vg6synBpnlqM9mSe8Xlo3SQ9bROJ9 1unhrml0Jr1tJZfbM/kX7xhFUVc2kQHqYz6pwYl3fYceHk5dVj9IWaJj82Sfi1QQ il3DQb9t3y4oJcYQxR9OzyjiKPiCAkIDakYshZP/bb/ZfDy1szIIL0e3mKLUcdFc 3sqAvcBsPt+SngnTtodkAK1ddTuxjHUN3+XpIAUoNtqv02g47JCmvSQ0NGsPyXIz 2krWQoMlmYaG3N74ybMajTXW3Y8+wbe5moJ+Yt4bPUo61d8rMOVI/+3lU7YIyUj1 TqbwgHCvZRvaiXJQbC9lP7mbQipQhtwQgGMw9TdQB/oHldmDNETF4eNX11LC73+G -----END RSA PRIVATE KEY----- libssh2-1.11.0/tests/test_auth_password_fail_username.c0000644000175000017500000000037514424650606020217 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { return test_auth_password(session, TEST_AUTH_SHOULDFAIL, "I am the wrong username", "my test password"); /* set in Dockerfile */ } libssh2-1.11.0/tests/key_rsa_encrypted.pub0000644000175000017500000000061213446422146015452 00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC92YlGoc4PJy6DzX916JJZhxkvmkWBLGJdWOL7R9B6iaYEKebBxzTE3P1RcnxnuI06kklVq/KcDP9sLlgawTZcDg7ifM7HncPOi18OON8vvVVzodikHzuupjhpI5YTT9wwV2fDVi2URsBjvX4AFiZ5WM3/NwqdKpYABzWieBikXGJ58Tsnw+zQw2qMmKKESBuzSN538loTAj5iEH/GAKYDbbH9t2a17qhNCNEw4vrtURT9JqwO1cOg7N1OKpmqCPEbK0wuSTljNC230VJ06X/8UqahWWSH6MreGy6gwpPi6i9wFiFLur301R0dTPiKVhz6bguhcC1EAlhSgjfelFJt awl03@bounty libssh2-1.11.0/tests/test_aa_warmup.c0000644000175000017500000000071114424650606014410 00000000000000/* Warm-up test. Always return success. Workaround for CI/docker/etc flakiness on the first run. */ #include "runner.h" int test(LIBSSH2_SESSION *session) { size_t len = 0; int type = 0; const char *hostkey = libssh2_session_hostkey(session, &len, &type); (void)hostkey; fprintf(stdout, "libssh2_session_hostkey returned len, type: %d, %d\n", (int)len, type); return 0; /* always return success */ } libssh2-1.11.0/tests/test_auth_pubkey_ok_dsa.c0000644000175000017500000000053214424650606016275 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_DSA /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_dsa.pub", "key_dsa"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/test_hostkey.c0000644000175000017500000000464014424650606014127 00000000000000#include "runner.h" static const char *EXPECTED_RSA_HOSTKEY = "AAAAB3NzaC1yc2EAAAABIwAAAQEArrr/JuJmaZligyfS8vcNur+mWR2ddDQtVdhHzdKU" "UoR6/Om6cvxpe61H1YZO1xCpLUBXmkki4HoNtYOpPB2W4V+8U4BDeVBD5crypEOE1+7B" "Am99fnEDxYIOZq2/jTP0yQmzCpWYS3COyFmkOL7sfX1wQMeW5zQT2WKcxC6FSWbhDqrB" "eNEGi687hJJoJ7YXgY/IdiYW5NcOuqRSWljjGS3dAJsHHWk4nJbhjEDXbPaeduMAwQU9" "i6ELfP3r+q6wdu0P4jWaoo3De1aYxnToV/ldXykpipON4NPamsb6Ph2qlJQKypq7J4iQ" "gkIIbCU1A31+4ExvcIVoxLQw/aTSbw=="; static const char *EXPECTED_ECDSA_HOSTKEY = "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC+/syyeKJD9dC2ZH" "9Q7iJGReR4YM3rUCMsSynkyXojdfSClGCMY7JvWlt30ESjYvxoTfSRGx6WvaqYK/vPoYQ4="; static const char *EXPECTED_ED25519_HOSTKEY = "AAAAC3NzaC1lZDI1NTE5AAAAIIxtdyg2ZRXE70UwyPVUH3UyfDBV8GX5cPF636P6hjom"; int test(LIBSSH2_SESSION *session) { int rc; size_t len; int type; size_t expected_len = 0; char *expected_hostkey = NULL; const char *hostkey = libssh2_session_hostkey(session, &len, &type); if(!hostkey) { print_last_session_error("libssh2_session_hostkey"); return 1; } if(type == LIBSSH2_HOSTKEY_TYPE_ED25519) { rc = _libssh2_base64_decode(session, &expected_hostkey, &expected_len, EXPECTED_ED25519_HOSTKEY, strlen(EXPECTED_ED25519_HOSTKEY)); } else if(type == LIBSSH2_HOSTKEY_TYPE_ECDSA_256) { rc = _libssh2_base64_decode(session, &expected_hostkey, &expected_len, EXPECTED_ECDSA_HOSTKEY, strlen(EXPECTED_ECDSA_HOSTKEY)); } else if(type == LIBSSH2_HOSTKEY_TYPE_RSA) { rc = _libssh2_base64_decode(session, &expected_hostkey, &expected_len, EXPECTED_RSA_HOSTKEY, strlen(EXPECTED_RSA_HOSTKEY)); } else { fprintf(stderr, "Unexpected type of hostkey: %i\n", type); return 1; } if(rc) { print_last_session_error("_libssh2_base64_decode"); return 1; } if(len != expected_len) { fprintf(stderr, "Hostkey does not have the expected length %ld!=%ld\n", (unsigned long)len, (unsigned long)expected_len); return 1; } if(memcmp(hostkey, expected_hostkey, len) != 0) { fprintf(stderr, "Hostkeys do not match\n"); return 1; } return 0; } libssh2-1.11.0/tests/test_auth_pubkey_ok_rsa_encrypted.c0000644000175000017500000000057014424650606020372 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_RSA_SHA1 /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", "libssh2", "key_rsa_encrypted.pub", "key_rsa_encrypted"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/key_rsa_openssh0000644000175000017500000000343713446422146014357 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn NhAAAAAwEAAQAAAQEA03tZTdi/8nrdDGtSc15EH97dX/qWrgC3nNhbBmcvOykSVtQDsXE0 4nj45RcD9cn0itZVl0Prn9G+tYJCqqkedhQ5MtuByVrmJX15REDJ9nfzzQzVQw2zuE1ysj ccVBxSeqmDDXeJFozh/uq5mKFirFlft5g0Wx2oG1TxGC/MHqfDk6ijqq7lS1T82cmGZAbZ +FzhYulBPFioklXStQJtTuVMb5Q/ebd9nmHIesEPWs4DKo2urKXvy+VCYD/N0GRZJ1Qt8D 2VpI6qJlRapdBaWkHJRDcMmPzmTMa9HE/3+2wi+rOAP9V6W7BpgtMWpOP0xx2zp/tC3SHo 9pxlfCRaEQAAA8gL9Cg6C/QoOgAAAAdzc2gtcnNhAAABAQDTe1lN2L/yet0Ma1JzXkQf3t 1f+pauALec2FsGZy87KRJW1AOxcTTiePjlFwP1yfSK1lWXQ+uf0b61gkKqqR52FDky24HJ WuYlfXlEQMn2d/PNDNVDDbO4TXKyNxxUHFJ6qYMNd4kWjOH+6rmYoWKsWV+3mDRbHagbVP EYL8wep8OTqKOqruVLVPzZyYZkBtn4XOFi6UE8WKiSVdK1Am1O5UxvlD95t32eYch6wQ9a zgMqja6spe/L5UJgP83QZFknVC3wPZWkjqomVFql0FpaQclENwyY/OZMxr0cT/f7bCL6s4 A/1XpbsGmC0xak4/THHbOn+0LdIej2nGV8JFoRAAAAAwEAAQAAAQAykM27lVXf7oyoCYk/ WIzFag5YgpxAop9Ee17YWxep95oQ9MSlSsIwXGh2rlgeDtnP0IvKjUzre8UztR+nmqRT62 X5yQ5xTLC2yheSwEMKEYhTwPvE+qO8L5h7ED5Pxi3acmmJcMlwgOMQhqM14XCscPo39cae +qpVTqwO8m7F7Tu/GCQWKTDE6FekoX13/bYbnsgd7FZGTyc37rQ2kuergYeIRewrdTD3JB ne6LmRVbMEuGh9WbXfXFLr+5p79xgnTPs+whdoyQTY8+O3052D8yMV7UcU+T9A0zHFyU9E VT/SvTgMTF7icThTtVR6Vn095ahe77wh363N0JEe1rwBAAAAgQCSqhkKVowJSPw+Ho6PNk lKcXWCutA8sVg+x+MaIdnzTe9TbxItm/XW4zj1Ax1rJeEgAaCKQVwH5oJDeC3awNZZ5ZY9 GK6h4ueyolzVP5wwalR9HeY/S+wdRgaIvYmIpHewLAj/o5ykE2Ijzgf3+HdaNlRxwWXz1i 8ArMV1AwB8WwAAAIEA75OHcAo8RUM7EoU165FZp7nqBphKuGMb8Os/p2xbNC8MYz5CyDXy fzYZC3i67uGXyTTVLtl54+kzuciuZ/qLHJT49JY/AtOm+rmpXKACNQIZeEnCML8AewLDEg ugXuFCMIFR4/fupCjGv/tTVHvsh6LJ/td3+DQmisVG3uDnGDEAAACBAOH6xeQ5Z/VPFV1b +ZxutTMjFghLce50L6fSHpBbIN00vS+9I4TmXYI1XFvaFjHShYUrFifWiMFGBNjuoqRY+c 9/8UDvptdiXLqqLkw3SNB/UqUQRtZkD384Eazxud+FMfMguFBrgmkWYwAh9EVAzXrbzxQd U9To5SerEitsWsfhAAAAEHdpbGxAaUN1YmUubG9jYWwBAg== -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/test_auth_pubkey_ok_ecdsa.c0000644000175000017500000000054014424650606016604 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_ECDSA /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_ecdsa.pub", "key_ecdsa"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/key_ecdsa_signed.pub0000644000175000017500000000033614424650606015224 00000000000000ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBG/X9+c3VK4iSDbbaNifJKognzwnkzdsHokZ6WgqEi+dl085JUW4UGO4Xs0+sauybztCy1AVsOIuEiVwM0cirRWFLmK0c0yO0LpiZFHHuaVBJc9tFEXkxyXG8MkIzIAhqA== key_ecdsa_signed libssh2-1.11.0/tests/test_auth_password_fail_password.c0000644000175000017500000000036414424650606020240 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { return test_auth_password(session, TEST_AUTH_SHOULDFAIL, "libssh2", /* set in Dockerfile */ "I am the wrong password"); } libssh2-1.11.0/tests/test_auth_pubkey_ok_ecdsa_signed.c0000644000175000017500000000066314424650606020143 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_ECDSA && \ (defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)) /* set in Dockerfile */ return test_auth_pubkey(session, 0, "libssh2", NULL, "key_ecdsa_signed-cert.pub", "key_ecdsa_signed"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/openssh_server/0000755000175000017500000000000014435416503014355 500000000000000libssh2-1.11.0/tests/openssh_server/ssh_host_rsa_key0000644000175000017500000000321312756074465017601 00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEoQIBAAKCAQEArrr/JuJmaZligyfS8vcNur+mWR2ddDQtVdhHzdKUUoR6/Om6 cvxpe61H1YZO1xCpLUBXmkki4HoNtYOpPB2W4V+8U4BDeVBD5crypEOE1+7BAm99 fnEDxYIOZq2/jTP0yQmzCpWYS3COyFmkOL7sfX1wQMeW5zQT2WKcxC6FSWbhDqrB eNEGi687hJJoJ7YXgY/IdiYW5NcOuqRSWljjGS3dAJsHHWk4nJbhjEDXbPaeduMA wQU9i6ELfP3r+q6wdu0P4jWaoo3De1aYxnToV/ldXykpipON4NPamsb6Ph2qlJQK ypq7J4iQgkIIbCU1A31+4ExvcIVoxLQw/aTSbwIBIwKCAQAd9Cu9heWrs+UAinvv Iwmq/EhnDGQijJoOt1zEMrpXSekyq7mQDgN0SZdJLPeSlSRQ5nVq5/dZroYB3A5i E7N3F7nibcJskWq5rcMyGjQHwod8wqfMiGcL6mjeZu2jLXprm0NDpJ3DyicbCA2G EhnpoHmktIBE5FsslI/nHer2o6OA/kVWSEjak+pvI1pm22T8QOBBfY0yAX7B0ebk 8o4lB4cdLf3In7Q0ahpHNOwIPdRvQ2c4Tm/DcfUBkTW2ZYGUd45cFsyHqXZscNNy GX2Wcy/FLEvQ6zBFJsNLpxCYsUyBxfSDygn9dx9RQfiWFXjdRaRPpyRAr+BTXkLU yvabAoGBANt7sxfjvu/SLkRc7TnBoJ0h/AL7Mcuu9PJmOnis4boyF9ZxqbiRiS3J yK+EKxfC0S+xf5WJ5uf7dVGnOXHXKaRl4xH90iRtryNlvtILZwHw1DTqRFxv9jtz tTRrYMEHAnMKzadgDfV/lv4iJ6nwFzK76GQ7RQNZYiGTMEh3pUNjAoGBAMvNLGpz FxhpIh+fVvRjawKgGVP87T482WOUdsF18EEPFMe6D7DO5xpLuJi+C7QkvMI8WjvD /3RGvaSh9Wt7ikLZpeogiSJy121HsEqheTR5hTx2t72ClrjZvIhLbQMRu6PqGPu/ HOC2urEGGYm7O2vnftwpuG3zIVVLM2KstPCFAoGBAM7w+VEJ7opYdMQdGi8kRvqN wbmrAxCAY0ryrCijALbexgS0T5DDu9q28Gr49W4stpquq35dc0/BNBnJje7+EVHc aGFrqOCErHHU9b66Sy23LnsIxBykFAwrRHNAq66u1mx35nk9Tv1pq58nhHun21u4 fAa7ijZblwm2qd3tJsqBAoGAEXf8ficfPJtMEVbM8GBLADmbxV7Sga1xuBQKLdbo tR6MwKmMUPvKqnuE2eRnZzZZUnoznrkHRHsXkcS9Q7ohyzc6G2Hf3mGdb8RQ8HQ9 lsiWZESwqdf+SlvOVNND27EQFV01V2gnC/JnxgfWTaJVjOf07ky4CWycdQZyHmaT Ko8CgYB58jOyXMdo2ggOCG/HX2H92KPPpFUBFCX27fCue8BZLD5quIltpXupx5oj EyltgvPcmNDgvdSadkHvP5s6nykS+n5we+d9yIIJF/BfETWsXjR3ooip+trqiirw 0aHqUDFcYn9unm2wtrMYYViiDLRijNwLZ2sG0JIU4JHyseh+NA== -----END RSA PRIVATE KEY----- libssh2-1.11.0/tests/openssh_server/ssh_host_ed25519_key0000644000175000017500000000063313446422146020003 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACCMbXcoNmUVxO9FMMj1VB91MnwwVfBl+XDxet+j+oY6JgAAAJg8nvUxPJ71 MQAAAAtzc2gtZWQyNTUxOQAAACCMbXcoNmUVxO9FMMj1VB91MnwwVfBl+XDxet+j+oY6Jg AAAECnhCuTDYdz3kUn48BXkaCXXdbKdH7wSIQ/CUx1cbnR0Ixtdyg2ZRXE70UwyPVUH3Uy fDBV8GX5cPF636P6hjomAAAAEHdpbGxAaUN1YmUubG9jYWwBAgMEBQ== -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/openssh_server/ssh_host_ecdsa_key0000644000175000017500000000034313446422146020062 00000000000000-----BEGIN EC PRIVATE KEY----- MHcCAQEEIKdqGrp+52U1ehslMI4fX0cmvgHFmKSkMzQGmj6B07ecoAoGCCqGSM49 AwEHoUQDQgAEL7+zLJ4okP10LZkf1DuIkZF5HhgzetQIyxLKeTJeiN19IKUYIxjs m9aW3fQRKNi/GhN9JEbHpa9qpgr+8+hhDg== -----END EC PRIVATE KEY----- libssh2-1.11.0/tests/openssh_server/ca_rsa.pub0000644000175000017500000000106014347110653016231 00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDEiBsRlsihCg0nJGNqURhszCZw1FwZmDpkD64L6HFf2U/GFXFgDBtYJZ8zdgua+RA9F/QNhq14OUemJX39HggAox/Acwg1vKPm6WPYAb3DMyzXT4ws32SbFd5ld/sQrqJUeMxaFLu1f02eY0UttQe4+nMjoM4Me98Qho7TzgpDIgn9nls42Sjt6KM9muqTBIVv4USwi9IsFn+54e0CEjfgiFyU8/8bH6vp1rtMPA6m4vuidyt2pP7PHFnUnikQGsaG4ldO/D/G0FFtMqPXeC1wQXI5RHnRns9TiI6Ep3r3h64ZI5iBYZeG16Fk+nuGvtp+WLWE5m01vfEHc5o+p09j+Ni1mQ5pmUq3AOM/MZMh+eCkTstnCyng/bHEZTIKQi1nnu694Mcq8W1v34wgMyBN3bvE65NhjIdLubnHvDgzVn127wjPEdeVD9ShtACxNS4a6xJCWg6llHVyzezqnj68umXre02MsXLbFikV/fEvUOXUp/rDeo+LJizk2bHAlyk= ca_rsa libssh2-1.11.0/tests/openssh_server/ca_ecdsa.pub0000644000175000017500000000040014047566506016531 00000000000000ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB+/Xmz4bbGDnon5q50oAzgb2o5MWttlGjQJPC+Rv+get/3/ZFJapizH/SbmZgJlWV5ydmrBEcA6iVdtz9hvhwaOwAtSPdQOKuydhHtV75LCe6eSm9b8fdr3ywDexL4cKl3lFul9YKVIE4j0kQCU+1LUKsRDsSY7uGaUU4fZwvSp8cLJg== CA libssh2-1.11.0/tests/openssh_server/ca_ecdsa0000644000175000017500000000131414047566506015751 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS 1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQAfv15s+G2xg56J+audKAM4G9qOTFr bZRo0CTwvkb/oHrf9/2RSWqYsx/0m5mYCZVlecnZqwRHAOolXbc/Yb4cGjsALUj3UDirsn YR7Ve+SwnunkpvW/H3a98sA3sS+HCpd5RbpfWClSBOI9JEAlPtS1CrEQ7EmO7hmlFOH2cL 0qfHCyYAAAEA763VSe+t1UkAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ AAAIUEAH79ebPhtsYOeifmrnSgDOBvajkxa22UaNAk8L5G/6B63/f9kUlqmLMf9JuZmAmV ZXnJ2asERwDqJV23P2G+HBo7AC1I91A4q7J2Ee1XvksJ7p5Kb1vx92vfLAN7EvhwqXeUW6 X1gpUgTiPSRAJT7UtQqxEOxJju4ZpRTh9nC9KnxwsmAAAAQgD8VJwi9RHYN13CAfhvdmjW xVjH55J5jDjPlENU2Z+cnm01SQ+9mPFEY4wDSvfiovD1VstNJX/P97WbHw+e5XL+HwAAAA JDQQ== -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/openssh_server/sshd_config0000644000175000017500000000112014424650606016502 00000000000000HostKeyAlgorithms +ssh-rsa PubkeyAcceptedKeyTypes +ssh-rsa,ssh-dss,ssh-rsa-cert-v01@openssh.com MACs +hmac-sha1,hmac-sha1-96,hmac-sha2-256,hmac-sha2-512,hmac-md5,hmac-md5-96,umac-64@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1-96-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-md5-etm@openssh.com,hmac-md5-96-etm@openssh.com,umac-64-etm@openssh.com,umac-128-etm@openssh.com Ciphers +3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com libssh2-1.11.0/tests/openssh_server/Dockerfile0000644000175000017500000000736314424650606016302 00000000000000# Copyright (c) 2016 Alexander Lamaison # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided # that the following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the # following disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # # Neither the name of the copyright holder nor the names # of any other contributors may be used to endorse or # promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. FROM debian:testing-slim RUN apt-get update \ && apt-get install -y openssh-server \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* RUN mkdir /var/run/sshd # Chmodding because, when building on Windows, files are copied in with # -rwxr-xr-x permissions. # # Copying to a temp location, then moving because chmodding the copied file has # no effect (Docker AUFS-related bug maybe?) # Host keys COPY ssh_host_rsa_key /tmp/etc/ssh/ssh_host_rsa_key RUN mv /tmp/etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_rsa_key RUN chmod 600 /etc/ssh/ssh_host_rsa_key COPY ssh_host_ecdsa_key /tmp/etc/ssh/ssh_host_ecdsa_key RUN mv /tmp/etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key RUN chmod 600 /etc/ssh/ssh_host_ecdsa_key COPY ssh_host_ed25519_key /tmp/etc/ssh/ssh_host_ed25519_key RUN mv /tmp/etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key RUN chmod 600 /etc/ssh/ssh_host_ed25519_key # Trusted CA keys COPY ca_ecdsa /tmp/etc/ssh/ca_ecdsa RUN mv /tmp/etc/ssh/ca_ecdsa /etc/ssh/ca_ecdsa RUN chmod 600 /etc/ssh/ca_ecdsa COPY ca_rsa /tmp/etc/ssh/ca_rsa RUN mv /tmp/etc/ssh/ca_rsa /etc/ssh/ca_rsa RUN chmod 600 /etc/ssh/ca_rsa COPY ca_user_keys.pub /tmp/etc/ssh/ca_user_keys.pub RUN cp /tmp/etc/ssh/ca_user_keys.pub /etc/ssh/ca_user_keys.pub RUN chmod 600 /etc/ssh/ca_user_keys.pub # User RUN adduser --disabled-password --gecos 'Test user for libssh2 integration tests' libssh2 RUN echo 'libssh2:my test password' | chpasswd # Config RUN sed -i 's/KbdInteractiveAuthentication no/KbdInteractiveAuthentication yes/' /etc/ssh/sshd_config COPY sshd_config /tmp/etc/ssh/sshd_config RUN cat /tmp/etc/ssh/sshd_config >> /etc/ssh/sshd_config RUN echo "TrustedUserCAKeys /etc/ssh/ca_user_keys.pub" >> /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd USER libssh2 RUN mkdir -p /home/libssh2/.ssh RUN mkdir -p /home/libssh2/sandbox COPY authorized_keys /tmp/libssh2/.ssh/authorized_keys RUN cp /tmp/libssh2/.ssh/authorized_keys /home/libssh2/.ssh/authorized_keys RUN chmod 600 /home/libssh2/.ssh/authorized_keys USER root EXPOSE 22 # -e gives logs via 'docker logs' CMD ["/usr/sbin/sshd", "-D", "-e"] libssh2-1.11.0/tests/openssh_server/ca_rsa0000644000175000017500000000503614347110653015453 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn NhAAAAAwEAAQAAAYEAxIgbEZbIoQoNJyRjalEYbMwmcNRcGZg6ZA+uC+hxX9lPxhVxYAwb WCWfM3YLmvkQPRf0DYateDlHpiV9/R4IAKMfwHMINbyj5ulj2AG9wzMs10+MLN9kmxXeZX f7EK6iVHjMWhS7tX9NnmNFLbUHuPpzI6DODHvfEIaO084KQyIJ/Z5bONko7eijPZrqkwSF b+FEsIvSLBZ/ueHtAhI34IhclPP/Gx+r6da7TDwOpuL7oncrdqT+zxxZ1J4pEBrGhuJXTv w/xtBRbTKj13gtcEFyOUR50Z7PU4iOhKd694euGSOYgWGXhtehZPp7hr7afli1hOZtNb3x B3OaPqdPY/jYtZkOaZlKtwDjPzGTIfngpE7LZwsp4P2xxGUyCkItZ57uveDHKvFtb9+MID MgTd27xOuTYYyHS7m5x7w4M1Z9du8IzxHXlQ/UobQAsTUuGusSQloOpZR1cs3s6p4+vLpl 63tNjLFy2xYpFf3xL1Dl1Kf6w3qPiyYs5NmxwJcpAAAFgFr4gLRa+IC0AAAAB3NzaC1yc2 EAAAGBAMSIGxGWyKEKDSckY2pRGGzMJnDUXBmYOmQPrgvocV/ZT8YVcWAMG1glnzN2C5r5 ED0X9A2GrXg5R6Ylff0eCACjH8BzCDW8o+bpY9gBvcMzLNdPjCzfZJsV3mV3+xCuolR4zF oUu7V/TZ5jRS21B7j6cyOgzgx73xCGjtPOCkMiCf2eWzjZKO3ooz2a6pMEhW/hRLCL0iwW f7nh7QISN+CIXJTz/xsfq+nWu0w8Dqbi+6J3K3ak/s8cWdSeKRAaxobiV078P8bQUW0yo9 d4LXBBcjlEedGez1OIjoSneveHrhkjmIFhl4bXoWT6e4a+2n5YtYTmbTW98Qdzmj6nT2P4 2LWZDmmZSrcA4z8xkyH54KROy2cLKeD9scRlMgpCLWee7r3gxyrxbW/fjCAzIE3du8Trk2 GMh0u5uce8ODNWfXbvCM8R15UP1KG0ALE1LhrrEkJaDqWUdXLN7OqePry6Zet7TYyxctsW KRX98S9Q5dSn+sN6j4smLOTZscCXKQAAAAMBAAEAAAGAAI1BRjNeLNWSY+G+RbYkk2mfUg HGoGvE/jLtEit85f/+MVguEU73ZK/2WnaiYbUBTqqajM8r/YJrqRPB3swOybGrjSbFhyEY dLWDCkA3AC1Mmu4mPpoB9k2BaleD5PAYlJQiPr6AKGpLFX7B2vb/Jo3NdPQmn/JZFfrKu9 2AOeAGlyeyqd4yNzjH/IxKzE7e8Ql43+YEmQsXILZ5q9/ROFgpqmFk/faAzQ9FR1mD0QQi ILqk7JhZ/srdlbM7+keY9dV/5AAdf9UvdepQghszERWB1ccq6tY1Cd8Pk1iXBAMhtGnpKZ 6nwAV+inPPCxCKRESSL0TKRazUsy6AvWye7zBBUP6zqzB66/Dm8K7CqHWj/yG27VSp6mjU PIdysQK6WlnTRaQBWc7sjeBy5S702bWA+EwJoAgZ+8Yl6w6ltmhUfZONVrZSFLlrfk33Dm 2TYDTfS4c7FChh494MVE6Du30LlF8sm7qWws8TLJnBHIMuT/aW1eI/DRNgkw5wkx+BAAAA wDC8XxvhkZiuqNiHyqy3q2nlBS4n87PR/dOwSkk108mU6S50zQXt1k8XkK0Dn8ZB/aWXym rIDY0C3/xmUj2FswFmnDnvBa/dvCXzSZKjUufMnRXWBZWU+bhQP9ivzsiIKnDsfaJvIWo1 4PN/BapwL1s+/6CwRLgoSerBrWpd4YTV0LEaMqpu0LA79wWUe+XSjr2H8PnQ2SURHwHn6C OwYLqZISPcZZEfYGtOshWZQl0t6ElWWU1WRQScbhv/6hTTEgAAAMEA5FsniRNsgN5KUmIq HYuCzjBVpkzCHI8C3Wnh2Zl7qUKNQlBVg0EQlRXb+NAcfQMg3izZf6JO0mSOxJmcU9rGUM 40QB2jF4DxYIJWHoCeYw/0vL88+AClCHnwAGisFNXLX+b+C60FiVc0c1mcxnL446/Ouenr g9nsxG0nq3GzN41l+6OEpofgaYdCEMEik7GcVS/G6pxLZVCCxzLuXOQXJY9UzTRPrkZLGr xi6xEYO8DNptpkfZRZIjxo0IEOe9xdAAAAwQDcUrNAVgr/bXIYWDvsawjY66iy9sAMimgt ojoD3jCOEKcJcnW7mQ5Zw8V/KEpYOd91REX7j+NOVhRUqAOVbW2DmT6Lt7aaPF5RLKEvBV oBR+VDyejOOBbUsimdeAriwL8jS/FwbM/NveRk3eeDsjGejl9oNqI0VsGogd5YuMC7ue3f aNoNL9GK1i7Gkl2RgQ9K86PUOiK14n10CgZoYQ6K9LYaciZZ+GMGJO2TX1XMMx7vVNLVFv +zcpm8rKEYGT0AAAAGY2FfcnNhAQIDBAU= -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/openssh_server/authorized_keys0000644000175000017500000000413214424650606017433 00000000000000ssh-dss AAAAB3NzaC1kc3MAAACBAK2Jh2Ck+8W1+LsFrjgOIH7XHySiONPSdG+faFTZprinh9cjyR3odzntVA7+UuFH14WnGM/ub6MbAXjrxDo1TzGILvW5x6nQ6hdLu7xFygihZ8sO1mIMOVqGdlNbTiYHl8XGjbLt1iXfW8ThM91LGGqmS+cgEiy0wWHYzsOXTDz9AAAAFQD/ebunYNTluoBrEYIoq3LMtQPbcwAAAIEAjPBzkUKcmfMAmb0eO/QAVXmX+L8NC6Vn2m4QguQ2IcJ8NH6VMnxXEBHsnemCOa9jN55G+LnX17PViuKS0O3rqQiSdA5wcHyCHKBT519/v1KQNymDwudfnFvdxUyAAG6MDSxKlpbXDCbrhFd2+ahC9a7rKalRPSXR0R2hhWRvjK0AAACAJ+CGwV/1S4j1GVwa6pSP0nj4V86GWXosTTBg7GT+rKWu8lrxIcr6FzLWgFi/gHoMrgnKWGxO1yF7vkoYM5Yfo84oBYiH+MgpiBuOrZrgzacHsA66JJbUfrESRFWZl2blIPr6Gyjj6cVGgMabK3yCiTRi0v7hwffpm0rKyKv7Goo= awl03@bounty ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnak1T7zHJ+hVRFBDQ9pf1KVzmd5gaNc7y7NPmL13aOG3sYeJevi1x1WM/R3tb8XnUnzZUX9GJN0MYovvZsw9bknG1mDP72LFbGp/gzPddGIKHBBpvceDaJ85sM/ME3XOtD7uuXQuNAuEHwEzSMMiSIEMcQS+lXIcMLr5xPLEkyNvqsO5RqSjMTLHKHgY8gLWx7oQ1avokhwuDxF7P3Pqtj+rW2Te6vR0i1H6EyFPsBkzkgNXb33cus8M1CnTmYTSgJgmHO2LLcGpjQ5sL8T/PWIWHaSqTnkrFXEMysgoteXnAYILjzyBaqq2WV4KA3TluGdAP2p8gC32QtKmIuis3Q== awl03@bounty ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC92YlGoc4PJy6DzX916JJZhxkvmkWBLGJdWOL7R9B6iaYEKebBxzTE3P1RcnxnuI06kklVq/KcDP9sLlgawTZcDg7ifM7HncPOi18OON8vvVVzodikHzuupjhpI5YTT9wwV2fDVi2URsBjvX4AFiZ5WM3/NwqdKpYABzWieBikXGJ58Tsnw+zQw2qMmKKESBuzSN538loTAj5iEH/GAKYDbbH9t2a17qhNCNEw4vrtURT9JqwO1cOg7N1OKpmqCPEbK0wuSTljNC230VJ06X/8UqahWWSH6MreGy6gwpPi6i9wFiFLur301R0dTPiKVhz6bguhcC1EAlhSgjfelFJt awl03@bounty ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTe1lN2L/yet0Ma1JzXkQf3t1f+pauALec2FsGZy87KRJW1AOxcTTiePjlFwP1yfSK1lWXQ+uf0b61gkKqqR52FDky24HJWuYlfXlEQMn2d/PNDNVDDbO4TXKyNxxUHFJ6qYMNd4kWjOH+6rmYoWKsWV+3mDRbHagbVPEYL8wep8OTqKOqruVLVPzZyYZkBtn4XOFi6UE8WKiSVdK1Am1O5UxvlD95t32eYch6wQ9azgMqja6spe/L5UJgP83QZFknVC3wPZWkjqomVFql0FpaQclENwyY/OZMxr0cT/f7bCL6s4A/1XpbsGmC0xak4/THHbOn+0LdIej2nGV8JFoR ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFEg0II3zbc1yWGhRzIc5KwTRlmx10RQP0sS63+1oMPi ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICHxEyUTOVHXvdMFARedFQ+H9DW/n8Zy3daKKRqnTDMq ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOiyJJwf+hFJrOkik9IQVxjhhVnI1vKl4BGLj03erLvw4TXXwoZzlPx6J936fU9JvvPw+d8PA4viMEfFbmdbHREKhwi3u1vZrfj0mB8SXw96AcZwX8PAL556wgom+/Qx+Q== libssh2-1.11.0/tests/openssh_server/ca_user_keys.pub0000644000175000017500000000146014424650606017464 00000000000000ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB+/Xmz4bbGDnon5q50oAzgb2o5MWttlGjQJPC+Rv+get/3/ZFJapizH/SbmZgJlWV5ydmrBEcA6iVdtz9hvhwaOwAtSPdQOKuydhHtV75LCe6eSm9b8fdr3ywDexL4cKl3lFul9YKVIE4j0kQCU+1LUKsRDsSY7uGaUU4fZwvSp8cLJg== CA ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDEiBsRlsihCg0nJGNqURhszCZw1FwZmDpkD64L6HFf2U/GFXFgDBtYJZ8zdgua+RA9F/QNhq14OUemJX39HggAox/Acwg1vKPm6WPYAb3DMyzXT4ws32SbFd5ld/sQrqJUeMxaFLu1f02eY0UttQe4+nMjoM4Me98Qho7TzgpDIgn9nls42Sjt6KM9muqTBIVv4USwi9IsFn+54e0CEjfgiFyU8/8bH6vp1rtMPA6m4vuidyt2pP7PHFnUnikQGsaG4ldO/D/G0FFtMqPXeC1wQXI5RHnRns9TiI6Ep3r3h64ZI5iBYZeG16Fk+nuGvtp+WLWE5m01vfEHc5o+p09j+Ni1mQ5pmUq3AOM/MZMh+eCkTstnCyng/bHEZTIKQi1nnu694Mcq8W1v34wgMyBN3bvE65NhjIdLubnHvDgzVn127wjPEdeVD9ShtACxNS4a6xJCWg6llHVyzezqnj68umXre02MsXLbFikV/fEvUOXUp/rDeo+LJizk2bHAlyk= ca_rsa libssh2-1.11.0/tests/key_dsa0000644000175000017500000000124012756074465012602 00000000000000-----BEGIN DSA PRIVATE KEY----- MIIBvAIBAAKBgQCtiYdgpPvFtfi7Ba44DiB+1x8kojjT0nRvn2hU2aa4p4fXI8kd 6Hc57VQO/lLhR9eFpxjP7m+jGwF468Q6NU8xiC71ucep0OoXS7u8RcoIoWfLDtZi DDlahnZTW04mB5fFxo2y7dYl31vE4TPdSxhqpkvnIBIstMFh2M7Dl0w8/QIVAP95 u6dg1OW6gGsRgiircsy1A9tzAoGBAIzwc5FCnJnzAJm9Hjv0AFV5l/i/DQulZ9pu EILkNiHCfDR+lTJ8VxAR7J3pgjmvYzeeRvi519ez1YriktDt66kIknQOcHB8ghyg U+dff79SkDcpg8LnX5xb3cVMgABujA0sSpaW1wwm64RXdvmoQvWu6ympUT0l0dEd oYVkb4ytAoGAJ+CGwV/1S4j1GVwa6pSP0nj4V86GWXosTTBg7GT+rKWu8lrxIcr6 FzLWgFi/gHoMrgnKWGxO1yF7vkoYM5Yfo84oBYiH+MgpiBuOrZrgzacHsA66JJbU frESRFWZl2blIPr6Gyjj6cVGgMabK3yCiTRi0v7hwffpm0rKyKv7GooCFQCyaA6T tkJunHP+F0Xg/WAUV6tcqA== -----END DSA PRIVATE KEY----- libssh2-1.11.0/tests/session_fixture.c0000644000175000017500000003433614432741311014631 00000000000000/* Copyright (C) 2016 Alexander Lamaison * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "session_fixture.h" #include "openssh_fixture.h" #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #include #include #include static LIBSSH2_SESSION *connected_session = NULL; static libssh2_socket_t connected_socket = LIBSSH2_INVALID_SOCKET; static int connect_to_server(void) { int rc; connected_socket = open_socket_to_openssh_server(); if(connected_socket == LIBSSH2_INVALID_SOCKET) { return LIBSSH2_ERROR_SOCKET_NONE; } rc = libssh2_session_handshake(connected_session, connected_socket); if(rc) { print_last_session_error("libssh2_session_handshake"); return libssh2_session_last_errno(connected_session); } return LIBSSH2_ERROR_NONE; } /* List of crypto protocols for which tests are skipped */ static char const *skip_crypt[] = { #ifdef LIBSSH2_MBEDTLS /* Due to a bug with mbedTLS support, these crypt methods fail. Until that bug is fixed, don't run them there to avoid this known issue causing red tests. See: https://github.com/libssh2/libssh2/issues/793 */ "3des-cbc", "aes128-cbc", "aes192-cbc", "aes256-cbc", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com", "rijndael-cbc@lysator.liu.se", #endif #if defined(LIBSSH2_LIBGCRYPT) || defined(LIBSSH2_OS400QC3) || \ defined(LIBSSH2_WINCNG) /* Support for AES-GCM hasn't been added to these back-ends yet */ "aes128-gcm@openssh.com", "aes256-gcm@openssh.com", #endif NULL }; LIBSSH2_SESSION *start_session_fixture(int *skipped, int *err) { int rc; const char *crypt = getenv("FIXTURE_TEST_CRYPT"); const char *mac = getenv("FIXTURE_TEST_MAC"); *skipped = 0; *err = LIBSSH2_ERROR_NONE; if(crypt) { char const * const *cr; for(cr = skip_crypt; *cr; ++cr) { if(strcmp(*cr, crypt) == 0) { fprintf(stderr, "crypt algorithm (%s) skipped " "for this crypto backend.\n", crypt); *skipped = 1; return NULL; } } } rc = start_openssh_fixture(); if(rc) { return NULL; } rc = libssh2_init(0); if(rc) { fprintf(stderr, "libssh2_init failed (%d)\n", rc); return NULL; } connected_session = libssh2_session_init_ex(NULL, NULL, NULL, NULL); if(!connected_session) { fprintf(stderr, "libssh2_session_init_ex failed\n"); return NULL; } if(getenv("FIXTURE_TRACE_ALL_CONNECT")) { libssh2_trace(connected_session, ~0); fprintf(stdout, "Trace all enabled for connect_to_server.\n"); } else if(getenv("FIXTURE_TRACE_ALL")) { libssh2_trace(connected_session, ~0); fprintf(stdout, "Trace all enabled.\n"); } /* Override crypt algorithm for the test */ if(crypt) { if(libssh2_session_method_pref(connected_session, LIBSSH2_METHOD_CRYPT_CS, crypt) || libssh2_session_method_pref(connected_session, LIBSSH2_METHOD_CRYPT_SC, crypt)) { fprintf(stderr, "libssh2_session_method_pref CRYPT failed " "(probably disabled in the build): '%s'\n", crypt); return NULL; } } /* Override mac algorithm for the test */ if(mac) { if(libssh2_session_method_pref(connected_session, LIBSSH2_METHOD_MAC_CS, mac) || libssh2_session_method_pref(connected_session, LIBSSH2_METHOD_MAC_SC, mac)) { fprintf(stderr, "libssh2_session_method_pref MAC failed " "(probably disabled in the build): '%s'\n", mac); return NULL; } } libssh2_session_set_blocking(connected_session, 1); rc = connect_to_server(); if(rc != LIBSSH2_ERROR_NONE) { *err = rc; return NULL; } if(getenv("FIXTURE_TRACE_ALL_CONNECT")) { libssh2_trace(connected_session, 0); } return connected_session; } void print_last_session_error(const char *function) { if(connected_session) { char *message; int rc = libssh2_session_last_error(connected_session, &message, NULL, 0); fprintf(stderr, "%s failed (%d): %s\n", function, rc, message); } else { fprintf(stderr, "No session\n"); } } void stop_session_fixture(void) { if(connected_session) { libssh2_session_disconnect(connected_session, "test ended"); libssh2_session_free(connected_session); connected_session = NULL; } else { fprintf(stderr, "Cannot stop session - none started\n"); } close_socket_to_openssh_server(connected_socket); connected_socket = LIBSSH2_INVALID_SOCKET; libssh2_exit(); stop_openssh_fixture(); } /* Return a static string that contains a file path relative to the srcdir * variable, if found. It does so in a way that avoids leaking memory by using * a fixed number of static buffers. */ #define NUMPATHS 32 const char *srcdir_path(const char *file) { #ifdef WIN32 static char filepath[NUMPATHS][_MAX_PATH]; #else static char filepath[NUMPATHS][MAXPATHLEN]; #endif static int curpath; char *p = getenv("srcdir"); if(curpath >= NUMPATHS) { fprintf(stderr, "srcdir_path ran out of filepath slots.\n"); } assert(curpath < NUMPATHS); if(p) { /* Ensure the final string is nul-terminated on Windows */ filepath[curpath][sizeof(filepath[0]) - 1] = 0; snprintf(filepath[curpath], sizeof(filepath[0]) - 1, "%s/%s", p, file); } else { /* Ensure the final string is nul-terminated on Windows */ filepath[curpath][sizeof(filepath[0]) - 1] = 0; snprintf(filepath[curpath], sizeof(filepath[0]) - 1, "%s", file); } return filepath[curpath++]; } static const char *kbd_password; static void kbd_callback(const char *name, int name_len, const char *instruct, int instruct_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) { int i; (void)abstract; fprintf(stdout, "Kb-int name: %.*s\n", name_len, name); fprintf(stdout, "Kb-int instruction: %.*s\n", instruct_len, instruct); for(i = 0; i < num_prompts; ++i) { fprintf(stdout, "Kb-int prompt %d: %.*s\n", i, (int)prompts[i].length, prompts[i].text); } if(num_prompts == 1) { responses[0].text = strdup(kbd_password); responses[0].length = (unsigned int)strlen(kbd_password); } } int test_auth_keyboard(LIBSSH2_SESSION *session, int flags, const char *username, const char *password) { int rc; const char *userauth_list = libssh2_userauth_list(session, username, (unsigned int)strlen(username)); if(!userauth_list) { print_last_session_error("libssh2_userauth_list"); return 1; } if(!strstr(userauth_list, "keyboard-interactive")) { fprintf(stderr, "'keyboard-interactive' was expected in userauth list: %s\n", userauth_list); return 1; } kbd_password = password; rc = libssh2_userauth_keyboard_interactive_ex(session, username, (unsigned int)strlen(username), kbd_callback); kbd_password = NULL; if((flags & TEST_AUTH_SHOULDFAIL) != 0) { if(rc == 0) { fprintf(stderr, "Keyboard-interactive auth succeeded " "with wrong response\n"); return 1; } } else { if(rc) { print_last_session_error( "libssh2_userauth_keyboard_interactive_ex"); return 1; } } return 0; } int test_auth_password(LIBSSH2_SESSION *session, int flags, const char *username, const char *password) { int rc; const char *userauth_list = libssh2_userauth_list(session, username, (unsigned int)strlen(username)); if(!userauth_list) { print_last_session_error("libssh2_userauth_list"); return 1; } if(!strstr(userauth_list, "password")) { fprintf(stderr, "'password' was expected in userauth list: %s\n", userauth_list); return 1; } rc = libssh2_userauth_password_ex(session, username, (unsigned int)strlen(username), password, (unsigned int)strlen(password), NULL); if((flags & TEST_AUTH_SHOULDFAIL) != 0) { if(rc == 0) { fprintf(stderr, "Password auth succeeded with wrong password\n"); return 1; } } else { if(rc) { print_last_session_error("libssh2_userauth_password_ex"); return 1; } if(libssh2_userauth_authenticated(session) == 0) { fprintf(stderr, "Password auth appeared to succeed but " "libssh2_userauth_authenticated returned 0\n"); return 1; } } return 0; } static int read_file(const char *path, char **out_buffer, size_t *out_len) { FILE *fp; char *buffer; size_t len; if(!out_buffer || !out_len || !path) { fprintf(stderr, "invalid params.\n"); return 1; } *out_buffer = NULL; *out_len = 0; fp = fopen(path, "r"); if(!fp) { fprintf(stderr, "File could not be read: %s\n", path); return 1; } fseek(fp, 0L, SEEK_END); len = ftell(fp); rewind(fp); buffer = calloc(1, len + 1); if(!buffer) { fclose(fp); fprintf(stderr, "Could not alloc memory.\n"); return 1; } if(1 != fread(buffer, len, 1, fp)) { fclose(fp); free(buffer); fprintf(stderr, "Could not read file into memory.\n"); return 1; } fclose(fp); *out_buffer = buffer; *out_len = len; return 0; } int test_auth_pubkey(LIBSSH2_SESSION *session, int flags, const char *username, const char *password, const char *fn_pub, const char *fn_priv) { int rc; const char *userauth_list; /* Ignore our hard-wired Dockerfile user when not running under Docker */ if(!openssh_fixture_have_docker() && strcmp(username, "libssh2") == 0) { username = getenv("USER"); #ifdef WIN32 if(!username) username = getenv("USERNAME"); #endif } userauth_list = libssh2_userauth_list(session, username, (unsigned int)strlen(username)); if(!userauth_list) { print_last_session_error("libssh2_userauth_list"); return 1; } if(!strstr(userauth_list, "publickey")) { fprintf(stderr, "'publickey' was expected in userauth list: %s\n", userauth_list); return 1; } if((flags & TEST_AUTH_FROMMEM) != 0) { char *buffer = NULL; size_t len = 0; if(read_file(srcdir_path(fn_priv), &buffer, &len)) { fprintf(stderr, "Reading key file failed.\n"); return 1; } rc = libssh2_userauth_publickey_frommemory(session, username, strlen(username), NULL, 0, buffer, len, NULL); free(buffer); } else { rc = libssh2_userauth_publickey_fromfile_ex(session, username, (unsigned int)strlen(username), srcdir_path(fn_pub), srcdir_path(fn_priv), password); } if((flags & TEST_AUTH_SHOULDFAIL) != 0) { if(rc == 0) { fprintf(stderr, "Public-key auth succeeded with wrong key\n"); return 1; } } else { if(rc) { print_last_session_error("libssh2_userauth_publickey_fromfile_ex"); return 1; } } return 0; } libssh2-1.11.0/tests/CMakeLists.txt0000644000175000017500000001445414435416425014003 00000000000000# Copyright (c) 2014-2016 Alexander Lamaison # Copyright (c) 2023 Viktor Szakats # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided # that the following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the # following disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # # Neither the name of the copyright holder nor the names # of any other contributors may be used to endorse or # promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. include(CopyRuntimeDependencies) list(APPEND LIBRARIES ${SOCKET_LIBRARIES}) transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") # Get 'DOCKER_TESTS', 'STANDALONE_TESTS', 'SSHD_TESTS', 'TESTS_WITH_LIB_STATIC', # 'librunner_la_SOURCES' variables include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) if(CMAKE_COMPILER_IS_GNUCC) find_program(GCOV_PATH gcov) if(GCOV_PATH) set(GCOV_OPTIONS -g --coverage) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) set(GCOV_OPTIONS "${GCOV_OPTIONS} -fprofile-abs-path") endif() endif() endif() option(RUN_SSHD_TESTS "Run tests requiring sshd" ON) find_program(SH_EXECUTABLE sh) mark_as_advanced(SH_EXECUTABLE) if(SH_EXECUTABLE) if(RUN_SSHD_TESTS) find_program(SSHD_EXECUTABLE sshd) mark_as_advanced(SSHD_EXECUTABLE) endif() add_test(NAME mansyntax COMMAND ${SH_EXECUTABLE} -c "${CMAKE_CURRENT_SOURCE_DIR}/mansyntax.sh") endif() add_library(runner STATIC ${librunner_la_SOURCES}) target_compile_definitions(runner PRIVATE "${CRYPTO_BACKEND_DEFINE}") target_include_directories(runner PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../src" ../src ../include "${CRYPTO_BACKEND_INCLUDE_DIR}") foreach(test ${DOCKER_TESTS} ${STANDALONE_TESTS} ${SSHD_TESTS}) if(NOT ";${TESTS_WITH_LIB_STATIC};" MATCHES ";${test};") set(LIB_FOR_TESTS ${LIB_SELECTED}) elseif(TARGET ${LIB_STATIC}) set(LIB_FOR_TESTS ${LIB_STATIC}) else() unset(LIB_FOR_TESTS) message(STATUS "Skip test requiring static libssh2 lib: ${test}") endif() # We support the same target as both Docker and SSHD test. Build those just once. # Skip building tests that require the static lib when the static lib is disabled. if(NOT TARGET ${test} AND LIB_FOR_TESTS) add_executable(${test} ${test}.c) target_compile_definitions(${test} PRIVATE "${CRYPTO_BACKEND_DEFINE}") target_include_directories(${test} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../src" ../src ../include "${CRYPTO_BACKEND_INCLUDE_DIR}") set_target_properties(${test} PROPERTIES UNITY_BUILD false) # build a single test with gcov if(GCOV_PATH AND test STREQUAL test_auth_keyboard_info_request AND TARGET ${LIB_STATIC}) target_compile_options(${test} BEFORE PRIVATE ${GCOV_OPTIONS}) target_link_libraries(${test} runner ${LIB_FOR_TESTS} ${LIBRARIES} gcov) else() target_link_libraries(${test} runner ${LIB_FOR_TESTS} ${LIBRARIES}) endif() list(APPEND TEST_TARGETS ${test}) endif() endforeach() option(RUN_DOCKER_TESTS "Run tests requiring Docker" ON) if(RUN_DOCKER_TESTS) foreach(test ${DOCKER_TESTS}) if(TARGET ${test}) add_test(NAME ${test} COMMAND $) set_property(TEST ${test} APPEND PROPERTY ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}") endif() endforeach() endif() foreach(test ${STANDALONE_TESTS}) if(TARGET ${test}) add_test(NAME ${test} COMMAND $) set_property(TEST ${test} APPEND PROPERTY ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}") endif() endforeach() if(RUN_SSHD_TESTS AND SSHD_EXECUTABLE) unset(sshd_test_targets) foreach(test ${SSHD_TESTS}) if(TARGET ${test}) set(sshd_test_targets "${sshd_test_targets} $") endif() endforeach() if(sshd_test_targets) add_test(NAME test_sshd COMMAND ${SH_EXECUTABLE} -c "${CMAKE_CURRENT_SOURCE_DIR}/test_sshd.test ${sshd_test_targets}") set_property(TEST test_sshd APPEND PROPERTY ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}") set_property(TEST test_sshd APPEND PROPERTY ENVIRONMENT "SSHD=${SSHD_EXECUTABLE}") endif() endif() if(RUN_DOCKER_TESTS) # CRYPT/MAC algo tests file(READ "test_read_algos.txt" ALGO_TESTS) string(REGEX REPLACE "\\\n" ";" ALGO_TESTS ${ALGO_TESTS}) foreach(test ${ALGO_TESTS}) set(testname test_read-${test}) add_test(NAME ${testname} COMMAND "$") set_property(TEST ${testname} APPEND PROPERTY ENVIRONMENT "srcdir=${CMAKE_CURRENT_SOURCE_DIR}") if(test MATCHES "mac-") set_property(TEST ${testname} APPEND PROPERTY ENVIRONMENT "FIXTURE_TEST_MAC=${test}") else() set_property(TEST ${testname} APPEND PROPERTY ENVIRONMENT "FIXTURE_TEST_CRYPT=${test}") endif() endforeach() endif() add_custom_target(coverage COMMAND gcovr -r "${CMAKE_SOURCE_DIR}" --exclude tests/* COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/coverage/" COMMAND gcovr -r "${CMAKE_SOURCE_DIR}" --exclude tests/* --html-details --output "${CMAKE_CURRENT_BINARY_DIR}/coverage/index.html") add_custom_target(clean-coverage COMMAND rm -rf "${CMAKE_CURRENT_BINARY_DIR}/coverage/") add_target_to_copy_dependencies( TARGET copy_test_dependencies DEPENDENCIES ${RUNTIME_DEPENDENCIES} BEFORE_TARGETS ${TEST_TARGETS}) libssh2-1.11.0/tests/test_auth_password_ok.c0000644000175000017500000000036214424650606016012 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { return test_auth_password(session, 0, "libssh2", /* set in Dockerfile */ "my test password"); /* set in Dockerfile */ } libssh2-1.11.0/tests/openssh_fixture.c0000644000175000017500000003157714424650606014640 00000000000000/* Copyright (C) 2016 Alexander Lamaison * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "session_fixture.h" #include "openssh_fixture.h" #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #include #include #include #include #if defined(WIN32) && defined(_WIN64) #define LIBSSH2_SOCKET_MASK "%lld" #else #define LIBSSH2_SOCKET_MASK "%d" #endif #ifdef LIBSSH2_WINDOWS_UWP #define popen(x, y) (NULL) #define pclose(x) (-1) #elif defined(WIN32) #define popen _popen #define pclose _pclose #endif static int have_docker = 0; int openssh_fixture_have_docker(void) { return have_docker; } static int run_command_varg(char **output, const char *command, va_list args) { static const char redirect_stderr[] = "%s 2>&1"; FILE *pipe; char command_buf[BUFSIZ]; char buf[BUFSIZ]; int ret; size_t buf_len; if(output) { *output = NULL; } /* Format the command string */ ret = vsnprintf(command_buf, sizeof(command_buf), command, args); if(ret < 0 || ret >= BUFSIZ) { fprintf(stderr, "Unable to format command (%s)\n", command); return -1; } /* Rewrite the command to redirect stderr to stdout to we can output it */ if(strlen(command_buf) + strlen(redirect_stderr) >= sizeof(buf)) { fprintf(stderr, "Unable to rewrite command (%s)\n", command); return -1; } ret = snprintf(buf, sizeof(buf), redirect_stderr, command_buf); if(ret < 0 || ret >= BUFSIZ) { fprintf(stderr, "Unable to rewrite command (%s)\n", command); return -1; } fprintf(stdout, "Command: %s\n", command_buf); pipe = popen(buf, "r"); if(!pipe) { fprintf(stderr, "Unable to execute command '%s'\n", command); return -1; } buf[0] = 0; buf_len = 0; while(buf_len < (sizeof(buf) - 1) && fgets(&buf[buf_len], (int)(sizeof(buf) - buf_len), pipe)) { buf_len = strlen(buf); } ret = pclose(pipe); if(ret) { fprintf(stderr, "Error running command '%s' (exit %d): %s\n", command, ret, buf); } if(output) { /* command output may contain a trailing newline, so we trim * whitespace here */ size_t end = strlen(buf); while(end > 0 && isspace(buf[end - 1])) { buf[end - 1] = '\0'; } *output = strdup(buf); } return ret; } static int run_command(char **output, const char *command, ...) { va_list args; int ret; va_start(args, command); ret = run_command_varg(output, command, args); va_end(args); return ret; } static const char *openssh_server_image(void) { return getenv("OPENSSH_SERVER_IMAGE"); } static int build_openssh_server_docker_image(void) { if(have_docker) { char buildcmd[1024]; const char *container_image_name = openssh_server_image(); if(container_image_name) { int ret = run_command(NULL, "docker pull %s", container_image_name); if(ret == 0) { ret = run_command(NULL, "docker tag %s libssh2/openssh_server", container_image_name); if(ret == 0) { return ret; } } } buildcmd[sizeof(buildcmd)-1] = 0; snprintf(buildcmd, sizeof(buildcmd)-1, "docker build --quiet -t libssh2/openssh_server %s", srcdir_path("openssh_server")); return run_command(NULL, buildcmd); } else { return 0; } } static const char *openssh_server_port(void) { return getenv("OPENSSH_SERVER_PORT"); } static int start_openssh_server(char **container_id_out) { if(have_docker) { const char *container_host_port = openssh_server_port(); if(container_host_port) { return run_command(container_id_out, "docker run --rm -d -p %s:22 " "libssh2/openssh_server", container_host_port); } return run_command(container_id_out, "docker run --rm -d -p 22 " "libssh2/openssh_server"); } else { *container_id_out = strdup(""); return 0; } } static int stop_openssh_server(char *container_id) { if(have_docker) { return run_command(NULL, "docker stop %s", container_id); } else { return 0; } } static const char *docker_machine_name(void) { return getenv("DOCKER_MACHINE_NAME"); } static int is_running_inside_a_container(void) { #ifdef WIN32 return 0; #else const char *cgroup_filename = "/proc/self/cgroup"; FILE *f; char *line = NULL; size_t len = 0; ssize_t read; int found = 0; f = fopen(cgroup_filename, "r"); if(!f) { /* Don't go further, we are not in a container */ return 0; } while((read = getline(&line, &len, f)) != -1) { if(strstr(line, "docker")) { found = 1; break; } } fclose(f); free(line); return found; #endif } static void portable_sleep(unsigned int seconds) { #ifdef WIN32 Sleep(seconds); #else sleep(seconds); #endif } static int ip_address_from_container(char *container_id, char **ip_address_out) { const char *active_docker_machine = docker_machine_name(); if(active_docker_machine) { /* This can be flaky when tests run in parallel (see https://github.com/docker/machine/issues/2612), so we retry a few times with exponential backoff if it fails */ int attempt_no = 0; int wait_time = 500; for(;;) { int ret = run_command(ip_address_out, "docker-machine ip %s", active_docker_machine); if(ret == 0) { return 0; } else if(attempt_no > 5) { fprintf( stderr, "Unable to get IP from docker-machine after %d attempts\n", attempt_no); return -1; } else { portable_sleep(wait_time); ++attempt_no; wait_time *= 2; } } } else { if(is_running_inside_a_container()) { return run_command(ip_address_out, "docker inspect --format " "\"{{ .NetworkSettings.IPAddress }}\"" " %s", container_id); } else { return run_command(ip_address_out, "docker inspect --format " "\"{{ index (index (index " ".NetworkSettings.Ports " "\\\"22/tcp\\\") 0) \\\"HostIp\\\" }}\" %s", container_id); } } } static int port_from_container(char *container_id, char **port_out) { if(is_running_inside_a_container()) { *port_out = strdup("22"); return 0; } else { return run_command(port_out, "docker inspect --format " "\"{{ index (index (index .NetworkSettings.Ports " "\\\"22/tcp\\\") 0) \\\"HostPort\\\" }}\" %s", container_id); } } static libssh2_socket_t open_socket_to_container(char *container_id) { char *ip_address = NULL; char *port_string = NULL; uint32_t hostaddr; libssh2_socket_t sock; struct sockaddr_in sin; int counter; libssh2_socket_t ret = LIBSSH2_INVALID_SOCKET; if(have_docker) { int res; res = ip_address_from_container(container_id, &ip_address); if(res) { fprintf(stderr, "Failed to get IP address for container %s\n", container_id); goto cleanup; } res = port_from_container(container_id, &port_string); if(res) { fprintf(stderr, "Failed to get port for container %s\n", container_id); goto cleanup; } } else { const char *env; env = getenv("OPENSSH_SERVER_HOST"); if(!env) { env = "127.0.0.1"; } ip_address = strdup(env); env = openssh_server_port(); if(!env) { env = "4711"; } port_string = strdup(env); } /* 0.0.0.0 is returned by Docker for Windows, because the container is reachable from anywhere. But we cannot connect to 0.0.0.0, instead we assume localhost and try to connect to 127.0.0.1. */ if(ip_address && strcmp(ip_address, "0.0.0.0") == 0) { free(ip_address); ip_address = strdup("127.0.0.1"); } hostaddr = inet_addr(ip_address); if(hostaddr == (uint32_t)(-1)) { fprintf(stderr, "Failed to convert %s host address\n", ip_address); goto cleanup; } sock = socket(AF_INET, SOCK_STREAM, 0); if(sock == LIBSSH2_INVALID_SOCKET) { fprintf(stderr, "Failed to open socket (" LIBSSH2_SOCKET_MASK ")\n", sock); goto cleanup; } sin.sin_family = AF_INET; sin.sin_port = htons((short)strtol(port_string, NULL, 0)); sin.sin_addr.s_addr = hostaddr; for(counter = 0; counter < 3; ++counter) { if(connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) { fprintf(stderr, "Connection to %s:%s attempt #%d failed: retrying...\n", ip_address, port_string, counter); portable_sleep(1 + 2*counter); } else { ret = sock; break; } } if(ret == LIBSSH2_INVALID_SOCKET) { fprintf(stderr, "Failed to connect to %s:%s\n", ip_address, port_string); goto cleanup; } cleanup: free(ip_address); free(port_string); return ret; } static void close_socket_to_container(libssh2_socket_t sock) { if(sock != LIBSSH2_INVALID_SOCKET) { shutdown(sock, 2 /* SHUT_RDWR */); #ifdef WIN32 closesocket(sock); #else close(sock); #endif } } static char *running_container_id = NULL; int start_openssh_fixture(void) { int ret; #ifdef WIN32 WSADATA wsadata; ret = WSAStartup(MAKEWORD(2, 0), &wsadata); if(ret) { fprintf(stderr, "WSAStartup failed with error: %d\n", ret); return 1; } #endif have_docker = !getenv("OPENSSH_NO_DOCKER"); ret = build_openssh_server_docker_image(); if(!ret) { return start_openssh_server(&running_container_id); } else { fprintf(stderr, "Failed to build docker image\n"); return ret; } } void stop_openssh_fixture(void) { if(running_container_id) { stop_openssh_server(running_container_id); free(running_container_id); running_container_id = NULL; } else if(have_docker) { fprintf(stderr, "Cannot stop container - none started\n"); } } libssh2_socket_t open_socket_to_openssh_server(void) { return open_socket_to_container(running_container_id); } void close_socket_to_openssh_server(libssh2_socket_t sock) { close_socket_to_container(sock); } libssh2-1.11.0/tests/key_ed255190000644000175000017500000000061714424650606013027 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACBRINCCN823NclhoUcyHOSsE0ZZsddEUD9LEut/taDD4gAAAJDgVkFO4FZB TgAAAAtzc2gtZWQyNTUxOQAAACBRINCCN823NclhoUcyHOSsE0ZZsddEUD9LEut/taDD4g AAAECD4khMmQkiGtn/wwcwqKNRo3oCetwMOOlhli8S8So8OVEg0II3zbc1yWGhRzIc5KwT Rlmx10RQP0sS63+1oMPiAAAAC2tleV9lZDI1NTE5AQI= -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/openssh_fixture.h0000644000175000017500000000357714424650606014644 00000000000000/* Copyright (C) 2016 Alexander Lamaison * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef LIBSSH2_TESTS_OPENSSH_FIXTURE_H #define LIBSSH2_TESTS_OPENSSH_FIXTURE_H int start_openssh_fixture(void); void stop_openssh_fixture(void); libssh2_socket_t open_socket_to_openssh_server(void); void close_socket_to_openssh_server(libssh2_socket_t sock); int openssh_fixture_have_docker(void); #endif libssh2-1.11.0/tests/ossfuzz/0000755000175000017500000000000014435416503013033 500000000000000libssh2-1.11.0/tests/ossfuzz/ssh2_client_fuzzer.cc0000644000175000017500000000431414424650606017110 00000000000000#include #include #include #include #include #include #include #include #include #include "testinput.h" #define FUZZ_ASSERT(COND) \ if(!(COND)) \ { \ fprintf(stderr, "Assertion failed: " #COND "\n%s", \ strerror(errno)); \ assert((COND)); \ } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int socket_fds[2] = {-1, -1}; ssize_t written; int rc; LIBSSH2_SESSION *session = NULL; int handshake_completed = 0; rc = libssh2_init(0); if(rc) { fprintf(stderr, "libssh2 initialization failed (%d)\n", rc); goto EXIT_LABEL; } // Create a socket pair so data can be sent in. rc = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds); FUZZ_ASSERT(rc == 0); written = send(socket_fds[1], data, size, 0); if(written != size) { // Handle whatever error case we're in. fprintf(stderr, "send() of %zu bytes returned %zu (%d)\n", size, written, errno); goto EXIT_LABEL; } rc = shutdown(socket_fds[1], SHUT_WR); if(rc) { fprintf(stderr, "socket shutdown failed (%d)\n", rc); goto EXIT_LABEL; } // Create a session and start the handshake using the fuzz data passed in. session = libssh2_session_init(); if(session) { libssh2_session_set_blocking(session, 1); } else { goto EXIT_LABEL; } if(libssh2_session_handshake(session, socket_fds[0])) { goto EXIT_LABEL; } // If we get here the handshake actually completed. handshake_completed = 1; EXIT_LABEL: if(session) { if(handshake_completed) { libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); } libssh2_session_free(session); } libssh2_exit(); close(socket_fds[0]); close(socket_fds[1]); return 0; } libssh2-1.11.0/tests/ossfuzz/standaloneengine.cc0000644000175000017500000000342113734352707016606 00000000000000#include #include #include #include "testinput.h" /** * Main procedure for standalone fuzzing engine. * * Reads filenames from the argument array. For each filename, read the file * into memory and then call the fuzzing interface with the data. */ int main(int argc, char **argv) { int ii; for(ii = 1; ii < argc; ii++) { FILE *infile; printf("[%s] ", argv[ii]); /* Try and open the file. */ infile = fopen(argv[ii], "rb"); if(infile) { uint8_t *buffer = NULL; size_t buffer_len; printf("Opened.. "); /* Get the length of the file. */ fseek(infile, 0L, SEEK_END); buffer_len = ftell(infile); /* Reset the file indicator to the beginning of the file. */ fseek(infile, 0L, SEEK_SET); /* Allocate a buffer for the file contents. */ buffer = (uint8_t *)calloc(buffer_len, sizeof(uint8_t)); if(buffer) { /* Read all the text from the file into the buffer. */ fread(buffer, sizeof(uint8_t), buffer_len, infile); printf("Read %zu bytes, fuzzing.. ", buffer_len); /* Call the fuzzer with the data. */ LLVMFuzzerTestOneInput(buffer, buffer_len); printf("complete !!"); /* Free the buffer as it's no longer needed. */ free(buffer); buffer = NULL; } else { fprintf(stderr, "[%s] Failed to allocate %zu bytes \n", argv[ii], buffer_len); } /* Close the file as it's no longer needed. */ fclose(infile); infile = NULL; } else { /* Failed to open the file. Maybe wrong name or wrong permissions? */ fprintf(stderr, "[%s] Open failed. \n", argv[ii]); } printf("\n"); } } libssh2-1.11.0/tests/ossfuzz/Makefile.in0000644000175000017500000006554714424651703015042 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_TRUE@am__append_1 = $(LIB_FUZZING_ENGINE) @USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_FALSE@am__append_2 = libstandaloneengine.a noinst_PROGRAMS = $(am__EXEEXT_1) @USE_OSSFUZZERS_TRUE@am__append_3 = \ @USE_OSSFUZZERS_TRUE@ ssh2_client_fuzzer @USE_OSSFUZZERS_TRUE@am__append_4 = \ @USE_OSSFUZZERS_TRUE@ libstandaloneengine.a subdir = tests/ossfuzz ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @USE_OSSFUZZERS_TRUE@am__EXEEXT_1 = ssh2_client_fuzzer$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libstandaloneengine_a_AR = $(AR) $(ARFLAGS) libstandaloneengine_a_LIBADD = am_libstandaloneengine_a_OBJECTS = \ libstandaloneengine_a-standaloneengine.$(OBJEXT) libstandaloneengine_a_OBJECTS = $(am_libstandaloneengine_a_OBJECTS) am_ssh2_client_fuzzer_OBJECTS = \ ssh2_client_fuzzer-ssh2_client_fuzzer.$(OBJEXT) ssh2_client_fuzzer_OBJECTS = $(am_ssh2_client_fuzzer_OBJECTS) ssh2_client_fuzzer_LDADD = $(LDADD) am__DEPENDENCIES_1 = @USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) ssh2_client_fuzzer_DEPENDENCIES = $(top_builddir)/src/libssh2.la \ $(am__DEPENDENCIES_2) $(am__append_2) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = ssh2_client_fuzzer_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) \ $(ssh2_client_fuzzer_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ ./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po \ ./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libstandaloneengine_a_SOURCES) \ $(ssh2_client_fuzzer_SOURCES) DIST_SOURCES = $(libstandaloneengine_a_SOURCES) \ $(ssh2_client_fuzzer_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@ HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBWOLFSSL = @HAVE_LIBWOLFSSL@ HAVE_LIBZ = @HAVE_LIBZ@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBCRYPT = @LIBBCRYPT@ LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSREQUIRED = @LIBSREQUIRED@ LIBSSH2VER = @LIBSSH2VER@ LIBSSL = @LIBSSL@ LIBSSL_PREFIX = @LIBSSL_PREFIX@ LIBTOOL = @LIBTOOL@ LIBWOLFSSL = @LIBWOLFSSL@ LIBWOLFSSL_PREFIX = @LIBWOLFSSL_PREFIX@ LIBZ = @LIBZ@ LIBZ_PREFIX = @LIBZ_PREFIX@ LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@ LTLIBOBJS = @LTLIBOBJS@ LTLIBSSL = @LTLIBSSL@ LTLIBWOLFSSL = @LTLIBWOLFSSL@ LTLIBZ = @LTLIBZ@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ RC = @RC@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSHD = @SSHD@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_builddir)/include LDADD = $(top_builddir)/src/libssh2.la $(am__append_1) $(am__append_2) @USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_FALSE@FUZZ_FLAG = @USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_TRUE@FUZZ_FLAG = @USE_OSSFUZZ_FLAG_TRUE@FUZZ_FLAG = $(LIB_FUZZING_ENGINE) noinst_LIBRARIES = $(am__append_4) ssh2_client_fuzzer_SOURCES = ssh2_client_fuzzer.cc testinput.h ssh2_client_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG) ssh2_client_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static libstandaloneengine_a_SOURCES = standaloneengine.cc libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS) EXTRA_DIST = ossfuzz.sh all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/ossfuzz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/ossfuzz/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libstandaloneengine.a: $(libstandaloneengine_a_OBJECTS) $(libstandaloneengine_a_DEPENDENCIES) $(EXTRA_libstandaloneengine_a_DEPENDENCIES) $(AM_V_at)-rm -f libstandaloneengine.a $(AM_V_AR)$(libstandaloneengine_a_AR) libstandaloneengine.a $(libstandaloneengine_a_OBJECTS) $(libstandaloneengine_a_LIBADD) $(AM_V_at)$(RANLIB) libstandaloneengine.a ssh2_client_fuzzer$(EXEEXT): $(ssh2_client_fuzzer_OBJECTS) $(ssh2_client_fuzzer_DEPENDENCIES) $(EXTRA_ssh2_client_fuzzer_DEPENDENCIES) @rm -f ssh2_client_fuzzer$(EXEEXT) $(AM_V_CXXLD)$(ssh2_client_fuzzer_LINK) $(ssh2_client_fuzzer_OBJECTS) $(ssh2_client_fuzzer_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< libstandaloneengine_a-standaloneengine.o: standaloneengine.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -MT libstandaloneengine_a-standaloneengine.o -MD -MP -MF $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo -c -o libstandaloneengine_a-standaloneengine.o `test -f 'standaloneengine.cc' || echo '$(srcdir)/'`standaloneengine.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo $(DEPDIR)/libstandaloneengine_a-standaloneengine.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='standaloneengine.cc' object='libstandaloneengine_a-standaloneengine.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -c -o libstandaloneengine_a-standaloneengine.o `test -f 'standaloneengine.cc' || echo '$(srcdir)/'`standaloneengine.cc libstandaloneengine_a-standaloneengine.obj: standaloneengine.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -MT libstandaloneengine_a-standaloneengine.obj -MD -MP -MF $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo -c -o libstandaloneengine_a-standaloneengine.obj `if test -f 'standaloneengine.cc'; then $(CYGPATH_W) 'standaloneengine.cc'; else $(CYGPATH_W) '$(srcdir)/standaloneengine.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo $(DEPDIR)/libstandaloneengine_a-standaloneengine.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='standaloneengine.cc' object='libstandaloneengine_a-standaloneengine.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -c -o libstandaloneengine_a-standaloneengine.obj `if test -f 'standaloneengine.cc'; then $(CYGPATH_W) 'standaloneengine.cc'; else $(CYGPATH_W) '$(srcdir)/standaloneengine.cc'; fi` ssh2_client_fuzzer-ssh2_client_fuzzer.o: ssh2_client_fuzzer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -MT ssh2_client_fuzzer-ssh2_client_fuzzer.o -MD -MP -MF $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.o `test -f 'ssh2_client_fuzzer.cc' || echo '$(srcdir)/'`ssh2_client_fuzzer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ssh2_client_fuzzer.cc' object='ssh2_client_fuzzer-ssh2_client_fuzzer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.o `test -f 'ssh2_client_fuzzer.cc' || echo '$(srcdir)/'`ssh2_client_fuzzer.cc ssh2_client_fuzzer-ssh2_client_fuzzer.obj: ssh2_client_fuzzer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -MT ssh2_client_fuzzer-ssh2_client_fuzzer.obj -MD -MP -MF $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.obj `if test -f 'ssh2_client_fuzzer.cc'; then $(CYGPATH_W) 'ssh2_client_fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/ssh2_client_fuzzer.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ssh2_client_fuzzer.cc' object='ssh2_client_fuzzer-ssh2_client_fuzzer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.obj `if test -f 'ssh2_client_fuzzer.cc'; then $(CYGPATH_W) 'ssh2_client_fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/ssh2_client_fuzzer.cc'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po -rm -f ./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po -rm -f ./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLIBRARIES \ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libssh2-1.11.0/tests/ossfuzz/ossfuzz.sh0000755000175000017500000000141514424650606015040 00000000000000#!/usr/bin/env bash set -eu # This script is called by the oss-fuzz main project when compiling the fuzz # targets. This script is regression tested by ci/ossfuzz.sh. # Save off the current folder as the build root. export BUILD_ROOT="$PWD" echo "CC: $CC" echo "CXX: $CXX" echo "LIB_FUZZING_ENGINE: $LIB_FUZZING_ENGINE" echo "CFLAGS: $CFLAGS" echo "CXXFLAGS: $CXXFLAGS" echo "OUT: $OUT" MAKEFLAGS+="-j$(nproc)" export MAKEFLAGS # Install dependencies apt-get -y install automake libtool libssl-dev zlib1g-dev # Compile the fuzzer. ./buildconf ./configure --disable-shared \ --enable-ossfuzzers \ --disable-examples-build \ --enable-debug make V=1 # Copy the fuzzer to the output directory. cp -v tests/ossfuzz/ssh2_client_fuzzer "$OUT/" libssh2-1.11.0/tests/ossfuzz/testinput.h0000644000175000017500000000014013734352707015164 00000000000000#include extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); libssh2-1.11.0/tests/ossfuzz/Makefile.am0000644000175000017500000000131314424650606015007 00000000000000AM_CPPFLAGS = -I$(top_builddir)/include LDADD = $(top_builddir)/src/libssh2.la if USE_OSSFUZZ_FLAG FUZZ_FLAG = $(LIB_FUZZING_ENGINE) else if USE_OSSFUZZ_STATIC LDADD += $(LIB_FUZZING_ENGINE) FUZZ_FLAG = else LDADD += libstandaloneengine.a FUZZ_FLAG = endif endif noinst_PROGRAMS = noinst_LIBRARIES = if USE_OSSFUZZERS noinst_PROGRAMS += \ ssh2_client_fuzzer noinst_LIBRARIES += \ libstandaloneengine.a endif ssh2_client_fuzzer_SOURCES = ssh2_client_fuzzer.cc testinput.h ssh2_client_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG) ssh2_client_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static libstandaloneengine_a_SOURCES = standaloneengine.cc libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS) EXTRA_DIST = ossfuzz.sh libssh2-1.11.0/tests/Makefile.am0000644000175000017500000000212414432741311013256 00000000000000SUBDIRS = ossfuzz AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top_srcdir)/include # Get DOCKER_TESTS, STANDALONE_TESTS, SSHD_TESTS, TESTS_WITH_LIB_STATIC, # librunner_la_SOURCES defines and *_LDFLAGS for statically linked tests. include Makefile.inc # Some tests rely on the 'srcdir' env. Set by autotools automatically. TESTS_ENVIRONMENT = # Tests to run TESTS = mansyntax.sh if RUN_DOCKER_TESTS TESTS += $(DOCKER_TESTS) endif TESTS += $(STANDALONE_TESTS) # TAP tests TEST_EXTENSIONS = .test # 'TEST' in 'TEST_LOG_DRIVER' is the test extension in uppercase. TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/tap-driver.sh TESTS_ENVIRONMENT += EXEEXT=$(EXEEXT) if RUN_SSHD_TESTS if SSHD TESTS += test_sshd.test TESTS_ENVIRONMENT += SSHD="$(SSHD)" endif endif if RUN_DOCKER_TESTS TESTS += test_read_algos.test endif # Tests to build check_PROGRAMS = $(DOCKER_TESTS) $(STANDALONE_TESTS) $(SSHD_TESTS) # Internal library used by tests LDADD = librunner.la check_LTLIBRARIES = librunner.la # This must be last in the list so it resolves symbols in previous libraries LDADD += ../src/libssh2.la libssh2-1.11.0/tests/test_auth_keyboard_fail.c0000644000175000017500000000036414424650606016254 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { return test_auth_keyboard(session, TEST_AUTH_SHOULDFAIL, "libssh2", /* set in Dockerfile */ "I am the wrong password"); } libssh2-1.11.0/tests/test_auth_pubkey_fail.c0000644000175000017500000000046714424650606015757 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { return test_auth_pubkey(session, TEST_AUTH_SHOULDFAIL, "libssh2", /* set in Dockerfile */ NULL, "key_dsa_wrong.pub", "key_dsa_wrong"); } libssh2-1.11.0/tests/test_auth_pubkey_ok_ed25519_mem.c0000644000175000017500000000055114424650606017363 00000000000000#include "runner.h" int test(LIBSSH2_SESSION *session) { #if LIBSSH2_ED25519 /* set in Dockerfile */ return test_auth_pubkey(session, TEST_AUTH_FROMMEM, "libssh2", NULL, NULL, "key_ed25519"); #else (void)session; return 0; #endif } libssh2-1.11.0/tests/key_rsa_signed0000644000175000017500000000647514424650606014157 00000000000000-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn NhAAAAAwEAAQAAAgEAsDLVuq8/N4YAiqldV39ij4LVgOaZFQN42OAqLIFrFfK48EqavgDJ gdcM1XU0/86xBMstoi6CMIgF0O8JaaNUEFpJZwoSHZW2sYPhdFLpZbGCGKBMay/vWDMERs JndNMiHvzzh5QQmtdKngVn3TJo7eWQ5WpD1WMBY7yuZWdFFtRTNbnKl+R6CD4VTjX0XmaJ wj/o8L4p+OCDGqrXWksuJO9UKu0bkWzGHk86TWsb9gm8bm72ORO8JQ60+O3tuQ5/13qFdl RF/U/O2QDJ8Jnsg2yltg7+PJeGc3t2PL3lKI3x9zZQPxfftT8HU5airH+ORP1VS8k07Z9S ictoS8rmr/ELeloHsONRthfWpQyWm9dbq3KIEYh8iP6D6NHOiptb4nheyH1u9shOUxU2bW 80jUvltBgqNcYeE1MfGwTVxzuPpgxbdoDQoF/h3+uBZT6jNJGmUlLQVSq1krqYE2zEl3x2 0VeTSb0nRqT1FnhQ9Yn8WHD4ccCZc5011ULphIJQ7niDLJxPMihGI0RLbmqPP6/fjkban/ Tj2bE/Y/m8ETnryxZymZM3w/cWEMlNmjK0Q7qPEekg+0oiOrV0cJaIXX5VwOp4PUUzcqlU TkAzifeGxjw+W+AW55t9bNhoYVo6AckBpZDVuAUQxCZoBvbBPM7QMZe3fAldlfdwTorGj5 MAAAdQLNFgDyzRYA8AAAAHc3NoLXJzYQAAAgEAsDLVuq8/N4YAiqldV39ij4LVgOaZFQN4 2OAqLIFrFfK48EqavgDJgdcM1XU0/86xBMstoi6CMIgF0O8JaaNUEFpJZwoSHZW2sYPhdF LpZbGCGKBMay/vWDMERsJndNMiHvzzh5QQmtdKngVn3TJo7eWQ5WpD1WMBY7yuZWdFFtRT NbnKl+R6CD4VTjX0XmaJwj/o8L4p+OCDGqrXWksuJO9UKu0bkWzGHk86TWsb9gm8bm72OR O8JQ60+O3tuQ5/13qFdlRF/U/O2QDJ8Jnsg2yltg7+PJeGc3t2PL3lKI3x9zZQPxfftT8H U5airH+ORP1VS8k07Z9SictoS8rmr/ELeloHsONRthfWpQyWm9dbq3KIEYh8iP6D6NHOip tb4nheyH1u9shOUxU2bW80jUvltBgqNcYeE1MfGwTVxzuPpgxbdoDQoF/h3+uBZT6jNJGm UlLQVSq1krqYE2zEl3x20VeTSb0nRqT1FnhQ9Yn8WHD4ccCZc5011ULphIJQ7niDLJxPMi hGI0RLbmqPP6/fjkban/Tj2bE/Y/m8ETnryxZymZM3w/cWEMlNmjK0Q7qPEekg+0oiOrV0 cJaIXX5VwOp4PUUzcqlUTkAzifeGxjw+W+AW55t9bNhoYVo6AckBpZDVuAUQxCZoBvbBPM 7QMZe3fAldlfdwTorGj5MAAAADAQABAAACAAt65G4LaQUHGBXwvwIqbJOJJLwHSkYSOdd3 k4fezslZTS9qzPZAOuDY0B9ASbm5D9OOIWUFvrnGwwo/6M8XMyz1lP6/qzp+PK8INrJLjK VxkVZla1U4hFGs0USC+hakgv6d4Ige344XJOdy1reUxz1oza4E5HKMxtRmwL4eomPAZcOE XWzUGBddZCn6Xfegmq0rWNQGr9llV2VvaCSb7V++sC8zz64D9kyXQOc2aVX4gGx5klVZsd KASM5HQkviY/X4J6X0C7NbddCxunaQsNZHR+y6wVnVTY9MpgGDJeEkjnVa9pOFzK+UcbfC gsrWbMCV+O69J1OsI8aSmDMH/0uvqT4QTvE8K4j2Cv/akCVkPb5/tC28fmYBL28/qKOTvI JJpWOcJ3L0QZQkrTJYsO3eL9ZDd4hgI/LvPmUghphEmmqLeu7K7CPnDDjIXM5j/qaIAjXc BZpkhFZBb63FyQWS4Z51XoNKs9F4iirs4MoMK9VGTNjqTSFr2DYeYLamUgEUPAM73AFGrq yE2zzSNnh5BZC+rxhoh95Yn3dH8ysczhNP5drgbQ1oVTY0sdGPBZXmMNIVQSTg2snBabp3 Kr9GdOji6VNkIov5Wcqz67lAVrb068GyrTJn1Ilrv5ND57UC62i682T5sA244dyrZO2WNb 7lEaPhUEXw/2r9E9xhAAABAQDOQtDK19iBmN93sPBrCCVf5QHRc2nEiecTFmYdvo8pj+na v35Xkf/Jzlt3YXeyKRBOE5MvBP+A/wU86tjwz/2jZO70wkLB9jal67L5tBSrfTtnEQJL/L 2e9sCrcmcMoJWeG12GfEU9o08t4PW+l5lvjrqCQnD8dFQOfxrbcqGIwt3eTDa9JpebPnFV qpsTREG2+09ut0NLQyXiGRhHVPP1hSpRWF2xL7qAEukxxr8kcYL+BucicBL33pzVBpoR99 3l7VcJOb4LtTFwdniLN6UkItQQTGm8yKFoWXLYJv5N1zTkeyi/3UexD9kG+lTEskbolZ4o Eg8B4JmfisFWfq+8AAABAQDcNR7xe9N91XxMN73Yr1xL/tdt0KzdVm9jWsNZ0DzNlR6UKU ALWshKJozYtajEj+5HKJfpovDolNHWXCG9jj0Zj5jypzJkSWA1h+pO7ZckGOm0XRuHRgsa ptAMklu+Vz7l9s/pAa/XmGSpG50bnRq0PL64aLR45dAXvCFGm5EmY/eb5CVwi892cC/XwY JsvaoMDOjLillPOxB+UU7ggTLFue3uKzgbt3vez5HqtsLT5YLvXnxx0F9ezjFpT2XmFHRa 7mtRlMfdKqEzR6xQ9/ncMgzrUWbNMxw/52HHMlgqTaHfj6CBrXarEqOFbOUwo+SyLBJMd5 d6BrRj6MZqw9J7AAABAQDM1n5T+2eznjYahX07VmdzMX9lzMUnH7cRbAcv0QZv4nZNgZkj 1h+kX6BzVvrARQW2GQ0dg4+03lMpd4fKtqUo6etptocl0zjHqTpIbYKDwWr1s9GUiRC9hL O0gE8nuYZl3c/Z8lNwV9XaDr6a83g24TUcjlj4M3m8S2vi9FGp01ch3JJjzhvoosx7iqkd 4Eq6mk3vZHmCgppn8JswWE1ea6bXZFoECRrOnaKbcLImJKu0H+aEq7ra680XqBtNdRVPwg Xex/tfw77hvUBZFZos1t1PUvXjHQtyMSCDbA2I9Jfe3lDwNsS0OG/zYa2/yKGqh8IT8NFR Vq+eerPcc9fJAAAAFnNhYmFuc2FsQHNhYmFuc2FsLWRldjMBAgME -----END OPENSSH PRIVATE KEY----- libssh2-1.11.0/tests/test_agent_forward_ok.c0000644000175000017500000000305014424650606015746 00000000000000#include "runner.h" static const char *username = "libssh2"; /* set in Dockerfile */ static const char *key_file_private = "key_rsa"; static const char *key_file_public = "key_rsa.pub"; /* set in Dockerfile */ int test(LIBSSH2_SESSION *session) { int rc; LIBSSH2_CHANNEL *channel; const char *userauth_list = libssh2_userauth_list(session, username, (unsigned int)strlen(username)); if(!userauth_list) { print_last_session_error("libssh2_userauth_list"); return 1; } if(!strstr(userauth_list, "publickey")) { fprintf(stderr, "'publickey' was expected in userauth list: %s\n", userauth_list); return 1; } rc = libssh2_userauth_publickey_fromfile_ex(session, username, (unsigned int)strlen(username), srcdir_path(key_file_public), srcdir_path(key_file_private), NULL); if(rc) { print_last_session_error("libssh2_userauth_publickey_fromfile_ex"); return 1; } channel = libssh2_channel_open_session(session); #if 0 if(!channel) { printf("Error opening channel\n"); return 1; } #endif rc = libssh2_channel_request_auth_agent(channel); if(rc) { fprintf(stderr, "Auth agent request for agent forwarding failed, " "error code %d\n", rc); return 1; } return 0; } libssh2-1.11.0/tests/key_rsa_signed.pub0000644000175000017500000000134414424650606014732 00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwMtW6rz83hgCKqV1Xf2KPgtWA5pkVA3jY4CosgWsV8rjwSpq+AMmB1wzVdTT/zrEEyy2iLoIwiAXQ7wlpo1QQWklnChIdlbaxg+F0UullsYIYoExrL+9YMwRGwmd00yIe/POHlBCa10qeBWfdMmjt5ZDlakPVYwFjvK5lZ0UW1FM1ucqX5HoIPhVONfReZonCP+jwvin44IMaqtdaSy4k71Qq7RuRbMYeTzpNaxv2CbxubvY5E7wlDrT47e25Dn/XeoV2VEX9T87ZAMnwmeyDbKW2Dv48l4Zze3Y8veUojfH3NlA/F9+1PwdTlqKsf45E/VVLyTTtn1KJy2hLyuav8Qt6Wgew41G2F9alDJab11urcogRiHyI/oPo0c6Km1vieF7IfW72yE5TFTZtbzSNS+W0GCo1xh4TUx8bBNXHO4+mDFt2gNCgX+Hf64FlPqM0kaZSUtBVKrWSupgTbMSXfHbRV5NJvSdGpPUWeFD1ifxYcPhxwJlznTXVQumEglDueIMsnE8yKEYjREtuao8/r9+ORtqf9OPZsT9j+bwROevLFnKZkzfD9xYQyU2aMrRDuo8R6SD7SiI6tXRwlohdflXA6ng9RTNyqVROQDOJ94bGPD5b4Bbnm31s2GhhWjoByQGlkNW4BRDEJmgG9sE8ztAxl7d8CV2V93BOisaPkw== key_rsa_signed libssh2-1.11.0/tests/key_rsa_openssh.pub0000644000175000017500000000057514424650606015145 00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTe1lN2L/yet0Ma1JzXkQf3t1f+pauALec2FsGZy87KRJW1AOxcTTiePjlFwP1yfSK1lWXQ+uf0b61gkKqqR52FDky24HJWuYlfXlEQMn2d/PNDNVDDbO4TXKyNxxUHFJ6qYMNd4kWjOH+6rmYoWKsWV+3mDRbHagbVPEYL8wep8OTqKOqruVLVPzZyYZkBtn4XOFi6UE8WKiSVdK1Am1O5UxvlD95t32eYch6wQ9azgMqja6spe/L5UJgP83QZFknVC3wPZWkjqomVFql0FpaQclENwyY/OZMxr0cT/f7bCL6s4A/1XpbsGmC0xak4/THHbOn+0LdIej2nGV8JFoR libssh2-1.11.0/tests/key_rsa.pub0000644000175000017500000000061212756074465013407 00000000000000ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnak1T7zHJ+hVRFBDQ9pf1KVzmd5gaNc7y7NPmL13aOG3sYeJevi1x1WM/R3tb8XnUnzZUX9GJN0MYovvZsw9bknG1mDP72LFbGp/gzPddGIKHBBpvceDaJ85sM/ME3XOtD7uuXQuNAuEHwEzSMMiSIEMcQS+lXIcMLr5xPLEkyNvqsO5RqSjMTLHKHgY8gLWx7oQ1avokhwuDxF7P3Pqtj+rW2Te6vR0i1H6EyFPsBkzkgNXb33cus8M1CnTmYTSgJgmHO2LLcGpjQ5sL8T/PWIWHaSqTnkrFXEMysgoteXnAYILjzyBaqq2WV4KA3TluGdAP2p8gC32QtKmIuis3Q== awl03@bounty libssh2-1.11.0/tests/test_read_algos.test0000755000175000017500000000123514435416425015277 00000000000000#!/usr/bin/env bash # Copyright (c) Viktor Szakats set -e set -u # https://testanything.org/tap-specification.html testbin="./test_read${EXEEXT:-}" d="$(dirname "$0")" algos="$(tr -d $"\r" < "${d}/test_read_algos.txt")" count=1 total="$(echo "${algos}" | wc -l | tr -d ' ')" echo "${count}..${total}" while read -r test; do if [[ "${test}" = *'mac-'* ]]; then if FIXTURE_TEST_MAC="${test}" "${testbin}"; then res='ok' else res='not ok' fi else if FIXTURE_TEST_CRYPT="${test}" "${testbin}"; then res='ok' else res='not ok' fi fi echo "${res} ${count} - test_read-${test}" ((count++)) done <<< "${algos}" libssh2-1.11.0/compile0000755000175000017500000001635014424651703011452 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey . # # 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, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libssh2-1.11.0/configure0000755000175000017500000323166314424651702012013 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for libssh2 -. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: libssh2-devel@lists.haxx.se about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libssh2' PACKAGE_TARNAME='libssh2' PACKAGE_VERSION='-' PACKAGE_STRING='libssh2 -' PACKAGE_BUGREPORT='libssh2-devel@lists.haxx.se' PACKAGE_URL='' ac_unique_file="src" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS HAVE_WINDRES_FALSE HAVE_WINDRES_TRUE ALLOCA USE_OSSFUZZ_STATIC_FALSE USE_OSSFUZZ_STATIC_TRUE USE_OSSFUZZ_FLAG_FALSE USE_OSSFUZZ_FLAG_TRUE LIB_FUZZING_ENGINE USE_OSSFUZZERS_FALSE USE_OSSFUZZERS_TRUE BUILD_EXAMPLES_FALSE BUILD_EXAMPLES_TRUE RUN_SSHD_TESTS_FALSE RUN_SSHD_TESTS_TRUE RUN_DOCKER_TESTS_FALSE RUN_DOCKER_TESTS_TRUE ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE CPP LIBSREQUIRED LIBZ_PREFIX LTLIBZ LIBZ HAVE_LIBZ LIBWOLFSSL_PREFIX LTLIBWOLFSSL LIBWOLFSSL HAVE_LIBWOLFSSL LIBBCRYPT_PREFIX LTLIBBCRYPT LIBBCRYPT HAVE_LIBBCRYPT LIBMBEDCRYPTO_PREFIX LTLIBMBEDCRYPTO LIBMBEDCRYPTO HAVE_LIBMBEDCRYPTO LIBGCRYPT_PREFIX LTLIBGCRYPT LIBGCRYPT HAVE_LIBGCRYPT LIBSSL_PREFIX LTLIBSSL LIBSSL HAVE_LIBSSL RC CXXCPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR FILECMD NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP LIBTOOL OBJDUMP DLLTOOL AS SSHD_FALSE SSHD_TRUE SSHD LN_S am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBSSH2VER CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM SED AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock enable_largefile with_crypto enable_rpath with_libssl_prefix with_libgcrypt_prefix with_libmbedcrypto_prefix with_libbcrypt_prefix with_libwolfssl_prefix with_libz with_libz_prefix enable_clear_memory enable_debug enable_hidden_symbols enable_tests enable_docker_tests enable_sshd_tests enable_examples_build enable_ossfuzzers enable_werror ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC LT_SYS_LIBRARY_PATH CXXCPP CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libssh2 - to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libssh2] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libssh2 -:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-largefile omit support for large files --disable-rpath do not hardcode runtime library paths --disable-clear-memory Disable clearing of memory before being freed --enable-debug Enable pedantic and debug options --disable-debug Disable debug options --enable-hidden-symbols Hide internal symbols in library --disable-hidden-symbols Leave all symbols with default visibility in library --disable-tests Disable tests [default=enabled] --disable-docker-tests Do not run tests requiring Docker --disable-sshd-tests Do not run tests requiring sshd --enable-examples-build Build example applications (this is the default) --disable-examples-build Do not build example applications --enable-ossfuzzers Whether to generate the fuzzers for OSS-Fuzz --enable-werror Enable compiler warnings as errors --disable-werror Disable compiler warnings as errors Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-crypto=auto|openssl|libgcrypt|mbedtls|wincng|wolfssl Select crypto backend (default: auto) --with-gnu-ld assume the C compiler uses GNU ld default=no --with-libssl-prefix[=DIR] search for libssl in DIR/include and DIR/lib --without-libssl-prefix don't search for libssl in includedir and libdir --with-libgcrypt-prefix[=DIR] search for libgcrypt in DIR/include and DIR/lib --without-libgcrypt-prefix don't search for libgcrypt in includedir and libdir --with-libmbedcrypto-prefix[=DIR] search for libmbedcrypto in DIR/include and DIR/lib --without-libmbedcrypto-prefix don't search for libmbedcrypto in includedir and libdir --with-libbcrypt-prefix[=DIR] search for libbcrypt in DIR/include and DIR/lib --without-libbcrypt-prefix don't search for libbcrypt in includedir and libdir --with-libwolfssl-prefix[=DIR] search for libwolfssl in DIR/include and DIR/lib --without-libwolfssl-prefix don't search for libwolfssl in includedir and libdir --with-libz Use libz for compression --with-libz-prefix[=DIR] search for libz in DIR/include and DIR/lib --without-libz-prefix don't search for libz in includedir and libdir Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags LT_SYS_LIBRARY_PATH User-defined run-time library search path. CXXCPP C++ preprocessor CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libssh2 configure - generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libssh2 $as_me -, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="config.rpath ltmain.sh compile config.guess config.sub missing install-sh tap-driver.sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/libssh2_config.h" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else $as_nop USE_MAINTAINER_MODE=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 printf "%s\n" "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$PATH:/usr/bin:/usr/local/bin" for as_dir in $as_dummy do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SED="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SED" && ac_cv_path_SED="sed-was-not-found-by-configure" ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 printf "%s\n" "$SED" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$SED" = "xsed-was-not-found-by-configure"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: sed was not found, this may ruin your chances to build fine" >&5 printf "%s\n" "$as_me: WARNING: sed was not found, this may ruin your chances to build fine" >&2;} fi LIBSSH2VER=`$SED -ne 's/^#define LIBSSH2_VERSION *"\(.*\)"/\1/p' ${srcdir}/include/libssh2.h` am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libssh2' VERSION='-' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking libssh2 version" >&5 printf %s "checking libssh2 version... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBSSH2VER" >&5 printf "%s\n" "$LIBSSH2VER" >&6; } AB_VERSION=$LIBSSH2VER # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac if test -z "$AB_PACKAGE"; then AB_PACKAGE=${PACKAGE_NAME:-$PACKAGE} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: autobuild project... $AB_PACKAGE" >&5 printf "%s\n" "$as_me: autobuild project... $AB_PACKAGE" >&6;} if test -z "$AB_VERSION"; then AB_VERSION=${PACKAGE_VERSION:-$VERSION} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: autobuild revision... $AB_VERSION" >&5 printf "%s\n" "$as_me: autobuild revision... $AB_VERSION" >&6;} hostname=`hostname` if test "$hostname"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: autobuild hostname... $hostname" >&5 printf "%s\n" "$as_me: autobuild hostname... $hostname" >&6;} fi date=`date +%Y%m%d-%H%M%S` if test "$?" != 0; then date=`date` fi if test "$date"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: autobuild timestamp... $date" >&5 printf "%s\n" "$as_me: autobuild timestamp... $date" >&6;} fi # Check for the OS. # Daniel's note: this should not be necessary and we need to work to # get this removed. case "$host" in *-mingw*) LIBS="$LIBS -lws2_32" ;; *darwin*) ;; *hpux*) ;; *osf*) CFLAGS="$CFLAGS -D_POSIX_PII_SOCKET" ;; *) ;; esac DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if _REENTRANT is already defined" >&5 printf %s "checking if _REENTRANT is already defined... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifdef _REENTRANT int dummy=1; #else force compilation error #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } tmp_reentrant_initially_defined="yes" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } tmp_reentrant_initially_defined="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # if test "$tmp_reentrant_initially_defined" = "no"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if _REENTRANT is actually needed" >&5 printf %s "checking if _REENTRANT is actually needed... " >&6; } case $host in *-*-solaris* | *-*-hpux*) tmp_need_reentrant="yes" ;; *) tmp_need_reentrant="no" ;; esac if test "$tmp_need_reentrant" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if _REENTRANT is onwards defined" >&5 printf %s "checking if _REENTRANT is onwards defined... " >&6; } if test "$tmp_reentrant_initially_defined" = "yes" || test "$tmp_need_reentrant" = "yes"; then printf "%s\n" "#define NEED_REENTRANT 1" >>confdefs.h cat >>confdefs.h <<_EOF #ifndef _REENTRANT # define _REENTRANT #endif _EOF { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # # Some systems (Solaris?) have socket() in -lsocket. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 printf %s "checking for library containing socket... " >&6; } if test ${ac_cv_search_socket+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char socket (); int main (void) { return socket (); ; return 0; } _ACEOF for ac_lib in '' socket do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_socket=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_socket+y} then : break fi done if test ${ac_cv_search_socket+y} then : else $as_nop ac_cv_search_socket=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 printf "%s\n" "$ac_cv_search_socket" >&6; } ac_res=$ac_cv_search_socket if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi # Solaris has inet_addr() in -lnsl. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing inet_addr" >&5 printf %s "checking for library containing inet_addr... " >&6; } if test ${ac_cv_search_inet_addr+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char inet_addr (); int main (void) { return inet_addr (); ; return 0; } _ACEOF for ac_lib in '' nsl do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_inet_addr=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_inet_addr+y} then : break fi done if test ${ac_cv_search_inet_addr+y} then : else $as_nop ac_cv_search_inet_addr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_addr" >&5 printf "%s\n" "$ac_cv_search_inet_addr" >&6; } ac_res=$ac_cv_search_inet_addr if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CXX_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi for ac_prog in sshd do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SSHD+y} then : printf %s "(cached) " >&6 else $as_nop case $SSHD in [\\/]* | ?:[\\/]*) ac_cv_path_SSHD="$SSHD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/libexec$PATH_SEPARATOR /usr/sbin$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/etc do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SSHD="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SSHD=$ac_cv_path_SSHD if test -n "$SSHD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SSHD" >&5 printf "%s\n" "$SSHD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$SSHD" && break done if test -n "$SSHD"; then SSHD_TRUE= SSHD_FALSE='#' else SSHD_TRUE='#' SSHD_FALSE= fi case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf # Set options enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AS+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 printf "%s\n" "$AS" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AS+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 printf "%s\n" "$ac_ct_AS" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump enable_dlopen=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_shared=yes fi # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes file_list_spec_CXX='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test ${lt_cv_prog_compiler_pic_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc_CXX+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 printf "%s\n" "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 printf %s "checking whether byte ordering is bigendian... " >&6; } if test ${ac_cv_c_bigendian+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO" then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_bigendian=yes else $as_nop ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_bigendian=yes else $as_nop ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ unsigned short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; unsigned short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } unsigned short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; unsigned short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main (void) { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main (void) { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : ac_cv_c_bigendian=no else $as_nop ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 printf "%s\n" "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. set dummy ${ac_tool_prefix}windres; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RC"; then ac_cv_prog_RC="$RC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RC="${ac_tool_prefix}windres" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RC=$ac_cv_prog_RC if test -n "$RC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RC" >&5 printf "%s\n" "$RC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RC"; then ac_ct_RC=$RC # Extract the first word of "windres", so it can be a program name with args. set dummy windres; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RC"; then ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RC="windres" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RC=$ac_cv_prog_ac_ct_RC if test -n "$ac_ct_RC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5 printf "%s\n" "$ac_ct_RC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RC" = x; then RC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RC=$ac_ct_RC fi else RC="$ac_cv_prog_RC" fi # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o objext_RC=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC compiler_RC=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result lt_cv_prog_compiler_c_o_RC=yes if test -n "$compiler"; then : fi GCC=$lt_save_GCC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS # Check whether --enable-largefile was given. if test ${enable_largefile+y} then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 printf %s "checking for special C compiler options needed for large files... " >&6; } if test ${ac_cv_sys_largefile_CC+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : break fi rm -f core conftest.err conftest.$ac_objext conftest.beam CC="$CC -n32" if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if test ${ac_cv_sys_file_offset_bits+y} then : printf %s "(cached) " >&6 else $as_nop while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 printf %s "checking for _LARGE_FILES value needed for large files... " >&6; } if test ${ac_cv_sys_large_files+y} then : printf %s "(cached) " >&6 else $as_nop while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 printf "%s\n" "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h ;; esac rm -rf conftest* fi fi # Crypto backends found_crypto=none found_crypto_str="" crypto_errors="" # Check whether --with-crypto was given. if test ${with_crypto+y} then : withval=$with_crypto; use_crypto=$withval else $as_nop use_crypto=auto fi case "${use_crypto}" in auto|openssl|libgcrypt|mbedtls|wincng|wolfssl) if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 printf %s "checking for ld used by GCC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | [A-Za-z]:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${acl_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi fi LD="$acl_cv_path_LD" if test -n "$LD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${acl_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU ld's only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$acl_cv_prog_gnu_ld" >&6; } with_gnu_ld=$acl_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 printf %s "checking for shared library run path origin... " >&6; } if test ${acl_cv_rpath+y} then : printf %s "(cached) " >&6 else $as_nop CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 printf "%s\n" "$acl_cv_rpath" >&6; } wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" # Check whether --enable-rpath was given. if test ${enable_rpath+y} then : enableval=$enable_rpath; : else $as_nop enable_rpath=yes fi acl_libdirstem=lib searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "openssl"; then libssh2_save_CPPFLAGS="$CPPFLAGS" libssh2_save_LDFLAGS="$LDFLAGS" if test "${with_libssl_prefix+set}" = set; then CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libssl_prefix}/include" LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_libssl_prefix}/lib" fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libssl-prefix was given. if test ${with_libssl_prefix+y} then : withval=$with_libssl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi fi LIBSSL= LTLIBSSL= INCSSL= LIBSSL_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='ssl crypto' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBSSL="${LIBSSL}${LIBSSL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBSSL="${LIBSSL}${LIBSSL:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" else LIBSSL="${LIBSSL}${LIBSSL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBSSL="${LIBSSL}${LIBSSL:+ }$found_a" else LIBSSL="${LIBSSL}${LIBSSL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIBSSL_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCSSL="${INCSSL}${INCSSL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBSSL="${LIBSSL}${LIBSSL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBSSL="${LIBSSL}${LIBSSL:+ }$dep" LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }$dep" ;; esac done fi else LIBSSL="${LIBSSL}${LIBSSL:+ }-l$name" LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBSSL="${LIBSSL}${LIBSSL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBSSL="${LIBSSL}${LIBSSL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" for element in $INCSSL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libssl" >&5 printf %s "checking for libssl... " >&6; } if test ${ac_cv_libssl+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_LIBS="$LIBS" LIBS="$LIBS $LIBSSL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_libssl=yes else $as_nop ac_cv_libssl=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libssl" >&5 printf "%s\n" "$ac_cv_libssl" >&6; } if test "$ac_cv_libssl" = yes; then HAVE_LIBSSL=yes printf "%s\n" "#define HAVE_LIBSSL 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libssl" >&5 printf %s "checking how to link with libssl... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBSSL" >&5 printf "%s\n" "$LIBSSL" >&6; } else HAVE_LIBSSL=no CPPFLAGS="$ac_save_CPPFLAGS" LIBSSL= LTLIBSSL= LIBSSL_PREFIX= fi LDFLAGS="$libssh2_save_LDFLAGS" if test "$ac_cv_libssl" = "yes"; then : printf "%s\n" "#define LIBSSH2_OPENSSL 1" >>confdefs.h LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libssl libcrypto" found_crypto="openssl" found_crypto_str="OpenSSL" else CPPFLAGS="$libssh2_save_CPPFLAGS" fi test "$found_crypto" = "none" && crypto_errors="${crypto_errors}No openssl crypto library found! " fi if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "libgcrypt"; then libssh2_save_CPPFLAGS="$CPPFLAGS" libssh2_save_LDFLAGS="$LDFLAGS" if test "${with_libgcrypt_prefix+set}" = set; then CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libgcrypt_prefix}/include" LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_libgcrypt_prefix}/lib" fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libgcrypt-prefix was given. if test ${with_libgcrypt_prefix+y} then : withval=$with_libgcrypt_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi fi LIBGCRYPT= LTLIBGCRYPT= INCGCRYPT= LIBGCRYPT_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='gcrypt ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBGCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBGCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" else LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_a" else LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIBGCRYPT_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCGCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCGCRYPT="${INCGCRYPT}${INCGCRYPT:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBGCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBGCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$dep" LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }$dep" ;; esac done fi else LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-l$name" LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" for element in $INCGCRYPT; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libgcrypt" >&5 printf %s "checking for libgcrypt... " >&6; } if test ${ac_cv_libgcrypt+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_LIBS="$LIBS" LIBS="$LIBS $LIBGCRYPT" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_libgcrypt=yes else $as_nop ac_cv_libgcrypt=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libgcrypt" >&5 printf "%s\n" "$ac_cv_libgcrypt" >&6; } if test "$ac_cv_libgcrypt" = yes; then HAVE_LIBGCRYPT=yes printf "%s\n" "#define HAVE_LIBGCRYPT 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libgcrypt" >&5 printf %s "checking how to link with libgcrypt... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBGCRYPT" >&5 printf "%s\n" "$LIBGCRYPT" >&6; } else HAVE_LIBGCRYPT=no CPPFLAGS="$ac_save_CPPFLAGS" LIBGCRYPT= LTLIBGCRYPT= LIBGCRYPT_PREFIX= fi LDFLAGS="$libssh2_save_LDFLAGS" if test "$ac_cv_libgcrypt" = "yes"; then : printf "%s\n" "#define LIBSSH2_LIBGCRYPT 1" >>confdefs.h found_crypto="libgcrypt" else CPPFLAGS="$libssh2_save_CPPFLAGS" fi test "$found_crypto" = "none" && crypto_errors="${crypto_errors}No libgcrypt crypto library found! " fi if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "mbedtls"; then libssh2_save_CPPFLAGS="$CPPFLAGS" libssh2_save_LDFLAGS="$LDFLAGS" if test "${with_libmbedcrypto_prefix+set}" = set; then CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libmbedcrypto_prefix}/include" LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_libmbedcrypto_prefix}/lib" fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libmbedcrypto-prefix was given. if test ${with_libmbedcrypto_prefix+y} then : withval=$with_libmbedcrypto_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi fi LIBMBEDCRYPTO= LTLIBMBEDCRYPTO= INCMBEDCRYPTO= LIBMBEDCRYPTO_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='mbedcrypto ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBMBEDCRYPTO="${LTLIBMBEDCRYPTO}${LTLIBMBEDCRYPTO:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBMBEDCRYPTO; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBMBEDCRYPTO="${LTLIBMBEDCRYPTO}${LTLIBMBEDCRYPTO:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBMBEDCRYPTO; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$found_so" else LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$found_a" else LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIBMBEDCRYPTO_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCMBEDCRYPTO; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCMBEDCRYPTO="${INCMBEDCRYPTO}${INCMBEDCRYPTO:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBMBEDCRYPTO; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBMBEDCRYPTO; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBMBEDCRYPTO="${LTLIBMBEDCRYPTO}${LTLIBMBEDCRYPTO:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$dep" LTLIBMBEDCRYPTO="${LTLIBMBEDCRYPTO}${LTLIBMBEDCRYPTO:+ }$dep" ;; esac done fi else LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }-l$name" LTLIBMBEDCRYPTO="${LTLIBMBEDCRYPTO}${LTLIBMBEDCRYPTO:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBMBEDCRYPTO="${LIBMBEDCRYPTO}${LIBMBEDCRYPTO:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBMBEDCRYPTO="${LTLIBMBEDCRYPTO}${LTLIBMBEDCRYPTO:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" for element in $INCMBEDCRYPTO; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmbedcrypto" >&5 printf %s "checking for libmbedcrypto... " >&6; } if test ${ac_cv_libmbedcrypto+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_LIBS="$LIBS" LIBS="$LIBS $LIBMBEDCRYPTO" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_libmbedcrypto=yes else $as_nop ac_cv_libmbedcrypto=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libmbedcrypto" >&5 printf "%s\n" "$ac_cv_libmbedcrypto" >&6; } if test "$ac_cv_libmbedcrypto" = yes; then HAVE_LIBMBEDCRYPTO=yes printf "%s\n" "#define HAVE_LIBMBEDCRYPTO 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libmbedcrypto" >&5 printf %s "checking how to link with libmbedcrypto... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBMBEDCRYPTO" >&5 printf "%s\n" "$LIBMBEDCRYPTO" >&6; } else HAVE_LIBMBEDCRYPTO=no CPPFLAGS="$ac_save_CPPFLAGS" LIBMBEDCRYPTO= LTLIBMBEDCRYPTO= LIBMBEDCRYPTO_PREFIX= fi LDFLAGS="$libssh2_save_LDFLAGS" if test "$ac_cv_libmbedcrypto" = "yes"; then : printf "%s\n" "#define LIBSSH2_MBEDTLS 1" >>confdefs.h LIBS="$LIBS -lmbedcrypto" found_crypto="mbedtls" else CPPFLAGS="$libssh2_save_CPPFLAGS" fi test "$found_crypto" = "none" && crypto_errors="${crypto_errors}No mbedtls crypto library found! " fi if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "wincng"; then # Look for Windows Cryptography API: Next Generation LIBS="$LIBS -lcrypt32" # Check necessary for old-MinGW libssh2_save_CPPFLAGS="$CPPFLAGS" libssh2_save_LDFLAGS="$LDFLAGS" if test "${with_libbcrypt_prefix+set}" = set; then CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libbcrypt_prefix}/include" LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_libbcrypt_prefix}/lib" fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libbcrypt-prefix was given. if test ${with_libbcrypt_prefix+y} then : withval=$with_libbcrypt_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi fi LIBBCRYPT= LTLIBBCRYPT= INCBCRYPT= LIBBCRYPT_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='bcrypt ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBBCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBBCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" else LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_a" else LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIBBCRYPT_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCBCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCBCRYPT="${INCBCRYPT}${INCBCRYPT:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBBCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBBCRYPT; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$dep" LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }$dep" ;; esac done fi else LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-l$name" LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" for element in $INCBCRYPT; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libbcrypt" >&5 printf %s "checking for libbcrypt... " >&6; } if test ${ac_cv_libbcrypt+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_LIBS="$LIBS" LIBS="$LIBS $LIBBCRYPT" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_libbcrypt=yes else $as_nop ac_cv_libbcrypt=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libbcrypt" >&5 printf "%s\n" "$ac_cv_libbcrypt" >&6; } if test "$ac_cv_libbcrypt" = yes; then HAVE_LIBBCRYPT=yes printf "%s\n" "#define HAVE_LIBBCRYPT 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libbcrypt" >&5 printf %s "checking how to link with libbcrypt... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBBCRYPT" >&5 printf "%s\n" "$LIBBCRYPT" >&6; } else HAVE_LIBBCRYPT=no CPPFLAGS="$ac_save_CPPFLAGS" LIBBCRYPT= LTLIBBCRYPT= LIBBCRYPT_PREFIX= fi LDFLAGS="$libssh2_save_LDFLAGS" if test "$ac_cv_libbcrypt" = "yes"; then : printf "%s\n" "#define LIBSSH2_WINCNG 1" >>confdefs.h found_crypto="wincng" found_crypto_str="Windows Cryptography API: Next Generation" else CPPFLAGS="$libssh2_save_CPPFLAGS" fi test "$found_crypto" = "none" && crypto_errors="${crypto_errors}No wincng crypto library found! " fi if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "wolfssl"; then if test "${with_libwolfssl_prefix+set}" = set; then CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libwolfssl_prefix}/include/wolfssl" else as_fn_error $? "When using wolfSSL, must specify prefix with --with-libwolfssl-prefix in order to find OpenSSL compatibility headers." "$LINENO" 5 fi libssh2_save_CPPFLAGS="$CPPFLAGS" libssh2_save_LDFLAGS="$LDFLAGS" if test "${with_libwolfssl_prefix+set}" = set; then CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_libwolfssl_prefix}/include" LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_libwolfssl_prefix}/lib" fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libwolfssl-prefix was given. if test ${with_libwolfssl_prefix+y} then : withval=$with_libwolfssl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi fi LIBWOLFSSL= LTLIBWOLFSSL= INCWOLFSSL= LIBWOLFSSL_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='wolfssl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBWOLFSSL="${LTLIBWOLFSSL}${LTLIBWOLFSSL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBWOLFSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBWOLFSSL="${LTLIBWOLFSSL}${LTLIBWOLFSSL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBWOLFSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$found_so" else LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$found_a" else LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIBWOLFSSL_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCWOLFSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCWOLFSSL="${INCWOLFSSL}${INCWOLFSSL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBWOLFSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBWOLFSSL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBWOLFSSL="${LTLIBWOLFSSL}${LTLIBWOLFSSL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$dep" LTLIBWOLFSSL="${LTLIBWOLFSSL}${LTLIBWOLFSSL:+ }$dep" ;; esac done fi else LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }-l$name" LTLIBWOLFSSL="${LTLIBWOLFSSL}${LTLIBWOLFSSL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBWOLFSSL="${LIBWOLFSSL}${LIBWOLFSSL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBWOLFSSL="${LTLIBWOLFSSL}${LTLIBWOLFSSL:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" for element in $INCWOLFSSL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libwolfssl" >&5 printf %s "checking for libwolfssl... " >&6; } if test ${ac_cv_libwolfssl+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_LIBS="$LIBS" LIBS="$LIBS $LIBWOLFSSL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_libwolfssl=yes else $as_nop ac_cv_libwolfssl=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libwolfssl" >&5 printf "%s\n" "$ac_cv_libwolfssl" >&6; } if test "$ac_cv_libwolfssl" = yes; then HAVE_LIBWOLFSSL=yes printf "%s\n" "#define HAVE_LIBWOLFSSL 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libwolfssl" >&5 printf %s "checking how to link with libwolfssl... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBWOLFSSL" >&5 printf "%s\n" "$LIBWOLFSSL" >&6; } else HAVE_LIBWOLFSSL=no CPPFLAGS="$ac_save_CPPFLAGS" LIBWOLFSSL= LTLIBWOLFSSL= LIBWOLFSSL_PREFIX= fi LDFLAGS="$libssh2_save_LDFLAGS" if test "$ac_cv_libwolfssl" = "yes"; then : printf "%s\n" "#define LIBSSH2_WOLFSSL 1" >>confdefs.h LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libwolfssl" found_crypto="wolfssl" else CPPFLAGS="$libssh2_save_CPPFLAGS" fi test "$found_crypto" = "none" && crypto_errors="${crypto_errors}No wolfssl crypto library found! " fi ;; yes|"") crypto_errors="No crypto backend specified!" ;; *) crypto_errors="Unknown crypto backend '${use_crypto}' specified!" ;; esac if test "$found_crypto" = "none"; then crypto_errors="${crypto_errors} Specify --with-crypto=\$backend and/or the necessary library search prefix. Known crypto backends: auto, openssl, libgcrypt, mbedtls, wincng, wolfssl" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: ERROR: ${crypto_errors}" >&5 printf "%s\n" "$as_me: ERROR: ${crypto_errors}" >&6;} else test "$found_crypto_str" = "" && found_crypto_str="$found_crypto" fi # libz # Check whether --with-libz was given. if test ${with_libz+y} then : withval=$with_libz; use_libz=$withval else $as_nop use_libz=auto fi found_libz=no libz_errors="" if test "$use_libz" != no; then use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libz-prefix was given. if test ${with_libz_prefix+y} then : withval=$with_libz_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi fi LIBZ= LTLIBZ= INCZ= LIBZ_PREFIX= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='z ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBZ="${LIBZ}${LIBZ:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBZ="${LTLIBZ}${LTLIBZ:+ }$value" else : fi else found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBZ; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then LIBZ="${LIBZ}${LIBZ:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$acl_hardcode_direct" = yes; then LIBZ="${LIBZ}${LIBZ:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then LIBZ="${LIBZ}${LIBZ:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBZ; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBZ="${LIBZ}${LIBZ:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then LIBZ="${LIBZ}${LIBZ:+ }$found_so" else LIBZ="${LIBZ}${LIBZ:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBZ="${LIBZ}${LIBZ:+ }$found_a" else LIBZ="${LIBZ}${LIBZ:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` LIBZ_PREFIX="$basedir" additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCZ; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCZ="${INCZ}${INCZ:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBZ; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBZ="${LIBZ}${LIBZ:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBZ; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBZ="${LIBZ}${LIBZ:+ }$dep" LTLIBZ="${LTLIBZ}${LTLIBZ:+ }$dep" ;; esac done fi else LIBZ="${LIBZ}${LIBZ:+ }-l$name" LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBZ="${LIBZ}${LIBZ:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBZ="${LIBZ}${LIBZ:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" for element in $INCZ; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libz" >&5 printf %s "checking for libz... " >&6; } if test ${ac_cv_libz+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_LIBS="$LIBS" LIBS="$LIBS $LIBZ" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_libz=yes else $as_nop ac_cv_libz=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libz" >&5 printf "%s\n" "$ac_cv_libz" >&6; } if test "$ac_cv_libz" = yes; then HAVE_LIBZ=yes printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libz" >&5 printf %s "checking how to link with libz... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBZ" >&5 printf "%s\n" "$LIBZ" >&6; } else HAVE_LIBZ=no CPPFLAGS="$ac_save_CPPFLAGS" LIBZ= LTLIBZ= LIBZ_PREFIX= fi if test "$ac_cv_libz" != yes; then if test "$use_libz" = auto; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Cannot find libz, disabling compression" >&5 printf "%s\n" "$as_me: Cannot find libz, disabling compression" >&6;} found_libz="disabled; no libz found" else libz_errors="No libz found! Try --with-libz-prefix=PATH if you know that you have it." { printf "%s\n" "$as_me:${as_lineno-$LINENO}: ERROR: $libz_errors" >&5 printf "%s\n" "$as_me: ERROR: $libz_errors" >&6;} fi else printf "%s\n" "#define LIBSSH2_HAVE_ZLIB 1" >>confdefs.h LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }zlib" found_libz="yes" fi fi # # Optional Settings # # Check whether --enable-clear-memory was given. if test ${enable_clear_memory+y} then : enableval=$enable_clear_memory; CLEAR_MEMORY=$enableval fi if test "$CLEAR_MEMORY" = "no"; then printf "%s\n" "#define LIBSSH2_NO_CLEAR_MEMORY 1" >>confdefs.h enable_clear_memory=no else enable_clear_memory=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable pedantic and debug compiler options" >&5 printf %s "checking whether to enable pedantic and debug compiler options... " >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if cpp -P is needed" >&5 printf %s "checking if cpp -P is needed... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include TEST EINVAL TEST _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "TEST.*TEST" >/dev/null 2>&1 then : cpp=no else $as_nop cpp=yes fi rm -rf conftest* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cpp" >&5 printf "%s\n" "$cpp" >&6; } if test "x$cpp" = "xyes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if cpp -P works" >&5 printf %s "checking if cpp -P works... " >&6; } OLDCPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS -P" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include TEST EINVAL TEST _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "TEST.*TEST" >/dev/null 2>&1 then : cpp_p=yes else $as_nop cpp_p=no fi rm -rf conftest* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cpp_p" >&5 printf "%s\n" "$cpp_p" >&6; } if test "x$cpp_p" = "xno"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: failed to figure out cpp -P alternative" >&5 printf "%s\n" "$as_me: WARNING: failed to figure out cpp -P alternative" >&2;} # without -P CPPPFLAG="" else # with -P CPPPFLAG="-P" fi CPPFLAGS=$OLDCPPFLAGS else # without -P CPPPFLAG="" fi squeeze() { _sqz_result="" eval _sqz_input=\$$1 for _sqz_token in $_sqz_input; do if test -z "$_sqz_result"; then _sqz_result="$_sqz_token" else _sqz_result="$_sqz_result $_sqz_token" fi done eval $1=\$_sqz_result return 0 } # Check whether --enable-debug was given. if test ${enable_debug+y} then : enableval=$enable_debug; case "$enable_debug" in no) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } CPPFLAGS="$CPPFLAGS -DNDEBUG" ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } enable_debug=yes CPPFLAGS="$CPPFLAGS -DLIBSSH2DEBUG" CFLAGS="$CFLAGS -g" if test "z$CLANG" = "z"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler is clang" >&5 printf %s "checking if compiler is clang... " >&6; } OLDCPPFLAGS=$CPPFLAGS # CPPPFLAG comes from CURL_CPP_P CPPFLAGS="$CPPFLAGS $CPPPFLAG" if test -z "$SED"; then as_fn_error $? "SED not set. Cannot continue without SED being set." "$LINENO" 5 fi if test -z "$GREP"; then as_fn_error $? "GREP not set. Cannot continue without GREP being set." "$LINENO" 5 fi tmp_exp="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __clang__ CURL_DEF_TOKEN __clang__ #endif _ACEOF if ac_fn_c_try_cpp "$LINENO" then : tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \ "$GREP" CURL_DEF_TOKEN 2>/dev/null | \ "$SED" 's/.*CURL_DEF_TOKEN[ ][ ]*//' 2>/dev/null | \ "$SED" 's/["][ ]*["]//g' 2>/dev/null` if test -z "$tmp_exp" || test "$tmp_exp" = "__clang__"; then tmp_exp="" fi fi rm -f conftest.err conftest.i conftest.$ac_ext if test -z "$tmp_exp"; then curl_cv_have_def___clang__=no else curl_cv_have_def___clang__=yes curl_cv_def___clang__=$tmp_exp fi CPPFLAGS=$OLDCPPFLAGS if test "$curl_cv_have_def___clang__" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler is xlclang" >&5 printf %s "checking if compiler is xlclang... " >&6; } OLDCPPFLAGS=$CPPFLAGS # CPPPFLAG comes from CURL_CPP_P CPPFLAGS="$CPPFLAGS $CPPPFLAG" if test -z "$SED"; then as_fn_error $? "SED not set. Cannot continue without SED being set." "$LINENO" 5 fi if test -z "$GREP"; then as_fn_error $? "GREP not set. Cannot continue without GREP being set." "$LINENO" 5 fi tmp_exp="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __ibmxl__ CURL_DEF_TOKEN __ibmxl__ #endif _ACEOF if ac_fn_c_try_cpp "$LINENO" then : tmp_exp=`eval "$ac_cpp conftest.$ac_ext" 2>/dev/null | \ "$GREP" CURL_DEF_TOKEN 2>/dev/null | \ "$SED" 's/.*CURL_DEF_TOKEN[ ][ ]*//' 2>/dev/null | \ "$SED" 's/["][ ]*["]//g' 2>/dev/null` if test -z "$tmp_exp" || test "$tmp_exp" = "__ibmxl__"; then tmp_exp="" fi fi rm -f conftest.err conftest.i conftest.$ac_ext if test -z "$tmp_exp"; then curl_cv_have_def___ibmxl__=no else curl_cv_have_def___ibmxl__=yes curl_cv_def___ibmxl__=$tmp_exp fi CPPFLAGS=$OLDCPPFLAGS if test "$curl_cv_have_def___ibmxl__" = "yes" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } compiler_id="XLCLANG" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } compiler_id="CLANG" fi fullclangver=`$CC -v 2>&1 | grep version` clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \([0-9]*\.[0-9]*\).*)/\1/'` if test -z "$clangver"; then if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then clangver="3.7" else clangver=`echo $fullclangver | "$SED" 's/.*version \([0-9]*\.[0-9]*\).*/\1/'` fi fi clangvhi=`echo $clangver | cut -d . -f1` clangvlo=`echo $clangver | cut -d . -f2` compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` flags_dbg_yes="-g" flags_opt_all="-O -O0 -O1 -O2 -Os -O3 -O4" flags_opt_yes="-O2" flags_opt_off="-O0" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "z$compiler_id" = "zCLANG"; then CLANG="yes" else CLANG="no" fi fi if test "z$ICC" = "z"; then ICC="no" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for icc in use" >&5 printf %s "checking for icc in use... " >&6; } if test "$GCC" = "yes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ __INTEL_COMPILER _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "^__INTEL_COMPILER" >/dev/null 2>&1 then : ICC="no" else $as_nop ICC="yes" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi rm -rf conftest* fi if test "$ICC" = "no"; then # this is not ICC { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test "$CLANG" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking clang version" >&5 printf %s "checking clang version... " >&6; } fullclangver=`$CC -v 2>&1 | grep version` clangver=`echo $fullclangver | grep "based on LLVM " | "$SED" 's/.*(based on LLVM \([0-9]*\.[0-9]*\).*)/\1/'` if test -z "$clangver"; then if echo $fullclangver | grep "Apple LLVM version " >/dev/null; then clangver="3.7" else clangver=`echo $fullclangver | "$SED" 's/.*version \([0-9]*\.[0-9]*\).*/\1/'` fi fi clangvhi=`echo $clangver | cut -d . -f1` clangvlo=`echo $clangver | cut -d . -f2` compiler_num=`(expr $clangvhi "*" 100 + $clangvlo) 2>/dev/null` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $compiler_num" >&5 printf "%s\n" "$compiler_num" >&6; } WARN="-pedantic" ac_var_added_warnings="" for warning in all extra; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in pointer-arith write-strings; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in shadow; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in inline nested-externs; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in missing-declarations; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in missing-prototypes; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -Wno-long-long" ac_var_added_warnings="" for warning in float-equal; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in no-multichar sign-compare; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in undef; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -Wno-format-nonliteral" ac_var_added_warnings="" for warning in endif-labels strict-prototypes; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in declaration-after-statement; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in cast-align; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -Wno-system-headers" ac_var_added_warnings="" for warning in shorten-64-to-32; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN # if test "$compiler_num" -ge "101"; then ac_var_added_warnings="" for warning in unused; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "208"; then ac_var_added_warnings="" for warning in vla; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "209"; then ac_var_added_warnings="" for warning in shift-sign-overflow; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "300"; then ac_var_added_warnings="" for warning in bad-function-cast; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in conversion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in empty-body; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in ignored-qualifiers; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in type-limits; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in no-sign-conversion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "302"; then ac_var_added_warnings="" for warning in enum-conversion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN case $host_os in cygwin* | mingw*) ;; *) ac_var_added_warnings="" for warning in missing-variable-declarations; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ;; esac fi # if test "$compiler_num" -ge "304"; then ac_var_added_warnings="" for warning in unused-const-variable; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "306"; then ac_var_added_warnings="" for warning in double-promotion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "309"; then ac_var_added_warnings="" for warning in comma; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN # avoid the varargs warning, fixed in 4.0 # https://bugs.llvm.org/show_bug.cgi?id=29140 if test "$compiler_num" -lt "400"; then WARN="$WARN -Wno-varargs" fi fi if test "$compiler_num" -ge "700"; then ac_var_added_warnings="" for warning in assign-enum; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in extra-semi-stmt; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi CFLAGS="$CFLAGS $WARN" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added this set of compiler options: $WARN" >&5 printf "%s\n" "$as_me: Added this set of compiler options: $WARN" >&6;} elif test "$GCC" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gcc version" >&5 printf %s "checking gcc version... " >&6; } gccver=`$CC -dumpversion` num1=`echo $gccver | cut -d . -f1` num2=`echo $gccver | cut -d . -f2` compiler_num=`(expr $num1 "*" 100 + $num2) 2>/dev/null` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gccver" >&5 printf "%s\n" "$gccver" >&6; } if test "$ICC" = "yes"; then WARN="-wd279,269,981,1418,1419" if test "$compiler_num" -gt "600"; then WARN="-Wall $WARN" fi else WARN="-W -Wall -Wwrite-strings -pedantic -Wpointer-arith -Wnested-externs -Winline -Wmissing-prototypes" if test "$compiler_num" -ge "207"; then WARN="$WARN -Wmissing-declarations" fi if test "$compiler_num" -gt "295"; then WARN="$WARN -Wbad-function-cast -Wundef -Wno-long-long -Wno-multichar -Wshadow -Wsign-compare -Wunused" fi if test "$compiler_num" -ge "296"; then WARN="$WARN -Wfloat-equal" fi if test "$compiler_num" -gt "296"; then WARN="$WARN -Wno-format-nonliteral" fi if test "$compiler_num" -ge "303"; then WARN="$WARN -Wendif-labels -Wstrict-prototypes" fi if test "$compiler_num" -ge "304"; then # try these on gcc 3.4 WARN="$WARN -Wdeclaration-after-statement" fi if test "$compiler_num" -ge "400"; then WARN="$WARN -Wstrict-aliasing=3" fi # if test "$compiler_num" -ge "401"; then ac_var_added_warnings="" for warning in no-system-headers; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "402"; then ac_var_added_warnings="" for warning in cast-align; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "403"; then ac_var_added_warnings="" for warning in type-limits old-style-declaration; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in missing-parameter-type empty-body; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in ignored-qualifiers; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in conversion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -Wno-sign-conversion" ac_var_added_warnings="" for warning in vla; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -ftree-vrp" fi # if test "$compiler_num" -ge "405"; then case $host_os in mingw*) WARN="$WARN -Wno-pedantic-ms-format" ;; esac fi # if test "$compiler_num" -ge "406"; then ac_var_added_warnings="" for warning in double-promotion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "408"; then WARN="$WARN -Wformat=2" fi # if test "$compiler_num" -ge "500"; then WARN="$WARN -Warray-bounds=2" fi # if test "$compiler_num" -ge "600"; then ac_var_added_warnings="" for warning in shift-negative-value; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -Wshift-overflow=2" ac_var_added_warnings="" for warning in null-dereference; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -fdelete-null-pointer-checks" ac_var_added_warnings="" for warning in duplicated-cond; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in unused-const-variable; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi # if test "$compiler_num" -ge "700"; then ac_var_added_warnings="" for warning in duplicated-branches; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in restrict; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in alloc-zero; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN WARN="$WARN -Wformat-overflow=2" WARN="$WARN -Wformat-truncation=1" fi # if test "$compiler_num" -ge "1000"; then ac_var_added_warnings="" for warning in arith-conversion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN ac_var_added_warnings="" for warning in enum-conversion; do ac_var_match_word="no" for word1 in $CFLAGS; do for word2 in -Wno-$warning -W$warning; do if test "$word1" = "$word2"; then ac_var_match_word="yes" fi done done if test "$ac_var_match_word" = "no"; then ac_var_added_warnings="$ac_var_added_warnings -W$warning" fi done WARN="$WARN $ac_var_added_warnings" squeeze WARN fi for flag in $CPPFLAGS; do case "$flag" in -I*) add=`echo $flag | sed 's/^-I/-isystem /g'` WARN="$WARN $add" ;; esac done fi CFLAGS="$CFLAGS $WARN" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added this set of compiler options: $WARN" >&5 printf "%s\n" "$as_me: Added this set of compiler options: $WARN" >&6;} else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Added no extra compiler options" >&5 printf "%s\n" "$as_me: Added no extra compiler options" >&6;} fi NEWFLAGS="" for flag in $CFLAGS; do case "$flag" in -O*) ;; *) NEWFLAGS="$NEWFLAGS $flag" ;; esac done CFLAGS=$NEWFLAGS ;; esac else $as_nop enable_debug=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable hidden symbols in the library" >&5 printf %s "checking whether to enable hidden symbols in the library... " >&6; } # Check whether --enable-hidden-symbols was given. if test ${enable_hidden_symbols+y} then : enableval=$enable_hidden_symbols; case "$enableval" in no) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports it" >&5 printf %s "checking whether $CC supports it... " >&6; } if test "$GCC" = yes ; then if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define LIBSSH2_API __attribute__ ((visibility (\"default\")))" >>confdefs.h CFLAGS="$CFLAGS -fvisibility=hidden" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define LIBSSH2_API __global" >>confdefs.h CFLAGS="$CFLAGS -xldscope=hidden" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi ;; esac else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Build tests? # Check whether --enable-tests was given. if test ${enable_tests+y} then : enableval=$enable_tests; if ! test "x${enable_tests}" = "xyes"; then enable_tests="no" fi else $as_nop enable_tests="yes" fi if test "x$enable_tests" = xyes; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi # Run Docker tests? # Check whether --enable-docker-tests was given. if test ${enable_docker_tests+y} then : enableval=$enable_docker_tests; run_docker_tests=no else $as_nop run_docker_tests=yes fi if test "x$run_docker_tests" != "xno"; then RUN_DOCKER_TESTS_TRUE= RUN_DOCKER_TESTS_FALSE='#' else RUN_DOCKER_TESTS_TRUE='#' RUN_DOCKER_TESTS_FALSE= fi # Run sshd tests? # Check whether --enable-sshd-tests was given. if test ${enable_sshd_tests+y} then : enableval=$enable_sshd_tests; run_sshd_tests=no else $as_nop run_sshd_tests=yes fi if test "x$run_sshd_tests" != "xno"; then RUN_SSHD_TESTS_TRUE= RUN_SSHD_TESTS_FALSE='#' else RUN_SSHD_TESTS_TRUE='#' RUN_SSHD_TESTS_FALSE= fi # Build example applications? { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build example applications" >&5 printf %s "checking whether to build example applications... " >&6; } # Check whether --enable-examples-build was given. if test ${enable_examples_build+y} then : enableval=$enable_examples_build; case "$enableval" in no | false) build_examples='no' ;; *) build_examples='yes' ;; esac else $as_nop build_examples='yes' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $build_examples" >&5 printf "%s\n" "$build_examples" >&6; } if test "x$build_examples" != "xno"; then BUILD_EXAMPLES_TRUE= BUILD_EXAMPLES_FALSE='#' else BUILD_EXAMPLES_TRUE='#' BUILD_EXAMPLES_FALSE= fi # Build OSS fuzzing targets? # Check whether --enable-ossfuzzers was given. if test ${enable_ossfuzzers+y} then : enableval=$enable_ossfuzzers; have_ossfuzzers=yes else $as_nop have_ossfuzzers=no fi if test "x$have_ossfuzzers" = "xyes"; then USE_OSSFUZZERS_TRUE= USE_OSSFUZZERS_FALSE='#' else USE_OSSFUZZERS_TRUE='#' USE_OSSFUZZERS_FALSE= fi # Set the correct flags for the given fuzzing engine. if test "x$LIB_FUZZING_ENGINE" = "x-fsanitize=fuzzer"; then USE_OSSFUZZ_FLAG_TRUE= USE_OSSFUZZ_FLAG_FALSE='#' else USE_OSSFUZZ_FLAG_TRUE='#' USE_OSSFUZZ_FLAG_FALSE= fi if test -f "$LIB_FUZZING_ENGINE"; then USE_OSSFUZZ_STATIC_TRUE= USE_OSSFUZZ_STATIC_FALSE='#' else USE_OSSFUZZ_STATIC_TRUE='#' USE_OSSFUZZ_STATIC_FALSE= fi # Checks for header files. ac_fn_c_check_header_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default" if test "x$ac_cv_header_errno_h" = xyes then : printf "%s\n" "#define HAVE_ERRNO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" if test "x$ac_cv_header_fcntl_h" = xyes then : printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" if test "x$ac_cv_header_stdio_h" = xyes then : printf "%s\n" "#define HAVE_STDIO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes then : printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" if test "x$ac_cv_header_sys_param_h" = xyes then : printf "%s\n" "#define HAVE_SYS_PARAM_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_uio_h" = xyes then : printf "%s\n" "#define HAVE_SYS_UIO_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default" if test "x$ac_cv_header_sys_select_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" if test "x$ac_cv_header_sys_socket_h" = xyes then : printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_ioctl_h" = xyes then : printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes then : printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default" if test "x$ac_cv_header_arpa_inet_h" = xyes then : printf "%s\n" "#define HAVE_ARPA_INET_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default" if test "x$ac_cv_header_netinet_in_h" = xyes then : printf "%s\n" "#define HAVE_NETINET_IN_H 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" if test "x$ac_cv_header_sys_un_h" = xyes then : printf "%s\n" "#define HAVE_SYS_UN_H 1" >>confdefs.h fi case $host in *-*-cygwin* | *-*-cegcc*) # These are POSIX-like systems using BSD-like sockets API. ;; *) for ac_header in windows.h do : ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" if test "x$ac_cv_header_windows_h" = xyes then : printf "%s\n" "#define HAVE_WINDOWS_H 1" >>confdefs.h have_windows_h=yes else $as_nop have_windows_h=no fi done ;; esac case $host in *darwin*|*interix*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: poll use is disabled on this platform" >&5 printf "%s\n" "$as_me: poll use is disabled on this platform" >&6;} ;; *) ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" if test "x$ac_cv_func_poll" = xyes then : printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h fi ;; esac ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" if test "x$ac_cv_func_gettimeofday" = xyes then : printf "%s\n" "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "select" "ac_cv_func_select" if test "x$ac_cv_func_select" = xyes then : printf "%s\n" "#define HAVE_SELECT 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll" if test "x$ac_cv_func_strtoll" = xyes then : printf "%s\n" "#define HAVE_STRTOLL 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero" if test "x$ac_cv_func_explicit_bzero" = xyes then : printf "%s\n" "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "explicit_memset" "ac_cv_func_explicit_memset" if test "x$ac_cv_func_explicit_memset" = xyes then : printf "%s\n" "#define HAVE_EXPLICIT_MEMSET 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "memset_s" "ac_cv_func_memset_s" if test "x$ac_cv_func_memset_s" = xyes then : printf "%s\n" "#define HAVE_MEMSET_S 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes then : printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h fi if test "$ac_cv_func_select" != "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for select in ws2_32" >&5 printf %s "checking for select in ws2_32... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_WINDOWS_H #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #endif int main (void) { select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } HAVE_SELECT="1" printf "%s\n" "#define HAVE_SELECT 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes then : else $as_nop printf "%s\n" "#define size_t unsigned int" >>confdefs.h fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 printf %s "checking for working alloca.h... " >&6; } if test ${ac_cv_working_alloca_h+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_working_alloca_h=yes else $as_nop ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 printf "%s\n" "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 printf %s "checking for alloca... " >&6; } if test ${ac_cv_func_alloca_works+y} then : printf %s "(cached) " >&6 else $as_nop if test $ac_cv_working_alloca_h = yes; then ac_cv_func_alloca_works=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef alloca # ifdef __GNUC__ # define alloca __builtin_alloca # elif defined _MSC_VER # include # define alloca _alloca # else # ifdef __cplusplus extern "C" # endif void *alloca (size_t); # endif #endif int main (void) { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_func_alloca_works=yes else $as_nop ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 printf "%s\n" "$ac_cv_func_alloca_works" >&6; } fi if test $ac_cv_func_alloca_works = yes; then printf "%s\n" "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext printf "%s\n" "#define C_ALLOCA 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 printf %s "checking stack direction for C alloca... " >&6; } if test ${ac_cv_c_stack_direction+y} then : printf %s "(cached) " >&6 else $as_nop if test "$cross_compiling" = yes then : ac_cv_c_stack_direction=0 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : ac_cv_c_stack_direction=1 else $as_nop ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 printf "%s\n" "$ac_cv_c_stack_direction" >&6; } printf "%s\n" "#define STACK_DIRECTION $ac_cv_c_stack_direction" >>confdefs.h fi # Checks for typedefs, structures, and compiler characteristics. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 printf %s "checking for an ANSI C-conforming const... " >&6; } if test ${ac_cv_c_const+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* IBM XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_const=yes else $as_nop ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 printf "%s\n" "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then printf "%s\n" "#define const /**/" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 printf %s "checking for inline... " >&6; } if test ${ac_cv_c_inline+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo (void) {return 0; } $ac_kw foo_t foo (void) {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 printf "%s\n" "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking non-blocking sockets style" >&5 printf %s "checking non-blocking sockets style... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* headers for O_NONBLOCK test */ #include #include #include int main (void) { /* try to compile O_NONBLOCK */ #if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) # if defined(__SVR4) || defined(__srv4__) # define PLATFORM_SOLARIS # else # define PLATFORM_SUNOS4 # endif #endif #if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41) # define PLATFORM_AIX_V3 #endif #if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__) #error "O_NONBLOCK does not work on this platform" #endif int socket; int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : nonblock="O_NONBLOCK" printf "%s\n" "#define HAVE_O_NONBLOCK 1" >>confdefs.h else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* headers for FIONBIO test */ #include #include int main (void) { /* FIONBIO source test (old-style unix) */ int socket; int flags = ioctl(socket, FIONBIO, &flags); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : nonblock="FIONBIO" printf "%s\n" "#define HAVE_FIONBIO 1" >>confdefs.h else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* headers for IoctlSocket test (Amiga?) */ #include int main (void) { /* IoctlSocket source code */ int socket; int flags = IoctlSocket(socket, FIONBIO, (long)1); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : nonblock="IoctlSocket" printf "%s\n" "#define HAVE_IOCTLSOCKET_CASE 1" >>confdefs.h else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* headers for SO_NONBLOCK test (BeOS) */ #include int main (void) { /* SO_NONBLOCK source code */ long b = 1; int socket; int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : nonblock="SO_NONBLOCK" printf "%s\n" "#define HAVE_SO_NONBLOCK 1" >>confdefs.h else $as_nop nonblock="nada" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $nonblock" >&5 printf "%s\n" "$nonblock" >&6; } if test "$nonblock" = "nada"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: non-block sockets disabled" >&5 printf "%s\n" "$as_me: WARNING: non-block sockets disabled" >&2;} fi missing_required_deps=0 if test "${libz_errors}" != ""; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: ERROR: ${libz_errors}" >&5 printf "%s\n" "$as_me: ERROR: ${libz_errors}" >&6;} missing_required_deps=1 fi if test "$found_crypto" = "none"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: ERROR: ${crypto_errors}" >&5 printf "%s\n" "$as_me: ERROR: ${crypto_errors}" >&6;} missing_required_deps=1 fi if test $missing_required_deps = 1; then as_fn_error $? "Required dependencies are missing!" "$LINENO" 5 fi if test "x$have_windows_h" = "xyes" && test "x${enable_shared}" = "xyes" && test -n "${RC}"; then HAVE_WINDRES_TRUE= HAVE_WINDRES_FALSE='#' else HAVE_WINDRES_TRUE='#' HAVE_WINDRES_FALSE= fi # Configure parameters { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable compiler warnings as errors" >&5 printf %s "checking whether to enable compiler warnings as errors... " >&6; } OPT_COMPILER_WERROR="default" # Check whether --enable-werror was given. if test ${enable_werror+y} then : enableval=$enable_werror; OPT_COMPILER_WERROR=$enableval fi case "$OPT_COMPILER_WERROR" in no) want_werror="no" ;; default) want_werror="no" ;; *) want_werror="yes" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $want_werror" >&5 printf "%s\n" "$want_werror" >&6; } if test X"$want_werror" = Xyes; then CFLAGS="$CFLAGS -Werror" fi # Append crypto lib if test "$found_crypto" = "openssl"; then LIBS="${LIBS} ${LTLIBSSL}" elif test "$found_crypto" = "wolfssl"; then LIBS="${LIBS} ${LTLIBWOLFSSL}" elif test "$found_crypto" = "libgcrypt"; then LIBS="${LIBS} ${LTLIBGCRYPT}" elif test "$found_crypto" = "wincng"; then LIBS="${LIBS} ${LTLIBBCRYPT}" elif test "$found_crypto" = "mbedtls"; then LIBS="${LIBS} ${LTLIBMBEDCRYPTO}" fi ac_config_files="$ac_config_files Makefile src/Makefile tests/Makefile tests/ossfuzz/Makefile example/Makefile docs/Makefile libssh2.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SSHD_TRUE}" && test -z "${SSHD_FALSE}"; then as_fn_error $? "conditional \"SSHD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${RUN_DOCKER_TESTS_TRUE}" && test -z "${RUN_DOCKER_TESTS_FALSE}"; then as_fn_error $? "conditional \"RUN_DOCKER_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${RUN_SSHD_TESTS_TRUE}" && test -z "${RUN_SSHD_TESTS_FALSE}"; then as_fn_error $? "conditional \"RUN_SSHD_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_EXAMPLES_TRUE}" && test -z "${BUILD_EXAMPLES_FALSE}"; then as_fn_error $? "conditional \"BUILD_EXAMPLES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_OSSFUZZERS_TRUE}" && test -z "${USE_OSSFUZZERS_FALSE}"; then as_fn_error $? "conditional \"USE_OSSFUZZERS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_OSSFUZZ_FLAG_TRUE}" && test -z "${USE_OSSFUZZ_FLAG_FALSE}"; then as_fn_error $? "conditional \"USE_OSSFUZZ_FLAG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USE_OSSFUZZ_STATIC_TRUE}" && test -z "${USE_OSSFUZZ_STATIC_FALSE}"; then as_fn_error $? "conditional \"USE_OSSFUZZ_STATIC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_WINDRES_TRUE}" && test -z "${HAVE_WINDRES_FALSE}"; then as_fn_error $? "conditional \"HAVE_WINDRES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libssh2 $as_me -, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ libssh2 config.status - configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' LD_RC='`$ECHO "$LD_RC" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_RC='`$ECHO "$reload_flag_RC" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_RC='`$ECHO "$reload_cmds_RC" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_RC='`$ECHO "$old_archive_cmds_RC" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' compiler_RC='`$ECHO "$compiler_RC" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' GCC_RC='`$ECHO "$GCC_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_RC='`$ECHO "$lt_prog_compiler_no_builtin_flag_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_RC='`$ECHO "$lt_prog_compiler_pic_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_RC='`$ECHO "$lt_prog_compiler_wl_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_RC='`$ECHO "$lt_prog_compiler_static_RC" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_RC='`$ECHO "$lt_cv_prog_compiler_c_o_RC" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_RC='`$ECHO "$archive_cmds_need_lc_RC" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_RC='`$ECHO "$enable_shared_with_static_runtimes_RC" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_RC='`$ECHO "$export_dynamic_flag_spec_RC" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_RC='`$ECHO "$whole_archive_flag_spec_RC" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_RC='`$ECHO "$compiler_needs_object_RC" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_RC='`$ECHO "$old_archive_from_new_cmds_RC" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_RC='`$ECHO "$old_archive_from_expsyms_cmds_RC" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_RC='`$ECHO "$archive_cmds_RC" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_RC='`$ECHO "$archive_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_RC='`$ECHO "$module_cmds_RC" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_RC='`$ECHO "$module_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_RC='`$ECHO "$with_gnu_ld_RC" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_RC='`$ECHO "$allow_undefined_flag_RC" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_RC='`$ECHO "$no_undefined_flag_RC" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_RC='`$ECHO "$hardcode_libdir_flag_spec_RC" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_RC='`$ECHO "$hardcode_libdir_separator_RC" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_RC='`$ECHO "$hardcode_direct_RC" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_RC='`$ECHO "$hardcode_direct_absolute_RC" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_RC='`$ECHO "$hardcode_minus_L_RC" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_RC='`$ECHO "$hardcode_shlibpath_var_RC" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_RC='`$ECHO "$hardcode_automatic_RC" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_RC='`$ECHO "$inherit_rpath_RC" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_RC='`$ECHO "$link_all_deplibs_RC" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_RC='`$ECHO "$always_export_symbols_RC" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_RC='`$ECHO "$export_symbols_cmds_RC" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_RC='`$ECHO "$exclude_expsyms_RC" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_RC='`$ECHO "$include_expsyms_RC" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_RC='`$ECHO "$prelink_cmds_RC" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_RC='`$ECHO "$postlink_cmds_RC" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_RC='`$ECHO "$file_list_spec_RC" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_RC='`$ECHO "$hardcode_action_RC" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_RC='`$ECHO "$compiler_lib_search_dirs_RC" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_RC='`$ECHO "$predep_objects_RC" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_RC='`$ECHO "$postdep_objects_RC" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' predeps_RC='`$ECHO "$predeps_RC" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_RC='`$ECHO "$postdeps_RC" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_RC='`$ECHO "$compiler_lib_search_path_RC" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in AS \ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ LD_RC \ reload_flag_CXX \ reload_flag_RC \ compiler_CXX \ compiler_RC \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_no_builtin_flag_RC \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_pic_RC \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_wl_RC \ lt_prog_compiler_static_CXX \ lt_prog_compiler_static_RC \ lt_cv_prog_compiler_c_o_CXX \ lt_cv_prog_compiler_c_o_RC \ export_dynamic_flag_spec_CXX \ export_dynamic_flag_spec_RC \ whole_archive_flag_spec_CXX \ whole_archive_flag_spec_RC \ compiler_needs_object_CXX \ compiler_needs_object_RC \ with_gnu_ld_CXX \ with_gnu_ld_RC \ allow_undefined_flag_CXX \ allow_undefined_flag_RC \ no_undefined_flag_CXX \ no_undefined_flag_RC \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_flag_spec_RC \ hardcode_libdir_separator_CXX \ hardcode_libdir_separator_RC \ exclude_expsyms_CXX \ exclude_expsyms_RC \ include_expsyms_CXX \ include_expsyms_RC \ file_list_spec_CXX \ file_list_spec_RC \ compiler_lib_search_dirs_CXX \ compiler_lib_search_dirs_RC \ predep_objects_CXX \ predep_objects_RC \ postdep_objects_CXX \ postdep_objects_RC \ predeps_CXX \ predeps_RC \ postdeps_CXX \ postdeps_RC \ compiler_lib_search_path_CXX \ compiler_lib_search_path_RC; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ reload_cmds_RC \ old_archive_cmds_CXX \ old_archive_cmds_RC \ old_archive_from_new_cmds_CXX \ old_archive_from_new_cmds_RC \ old_archive_from_expsyms_cmds_CXX \ old_archive_from_expsyms_cmds_RC \ archive_cmds_CXX \ archive_cmds_RC \ archive_expsym_cmds_CXX \ archive_expsym_cmds_RC \ module_cmds_CXX \ module_cmds_RC \ module_expsym_cmds_CXX \ module_expsym_cmds_RC \ export_symbols_cmds_CXX \ export_symbols_cmds_RC \ prelink_cmds_CXX \ prelink_cmds_RC \ postlink_cmds_CXX \ postlink_cmds_RC; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/libssh2_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/libssh2_config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/ossfuzz/Makefile") CONFIG_FILES="$CONFIG_FILES tests/ossfuzz/Makefile" ;; "example/Makefile") CONFIG_FILES="$CONFIG_FILES example/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "libssh2.pc") CONFIG_FILES="$CONFIG_FILES libssh2.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool 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 . # The names of the tagged configurations supported by this script. available_tags='CXX RC ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: RC # The linker used to build libraries. LD=$lt_LD_RC # How to create reloadable object files. reload_flag=$lt_reload_flag_RC reload_cmds=$lt_reload_cmds_RC # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_RC # A language specific compiler. CC=$lt_compiler_RC # Is the compiler the GNU compiler? with_gcc=$GCC_RC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_RC # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_RC # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_RC # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_RC # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_RC # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_RC archive_expsym_cmds=$lt_archive_expsym_cmds_RC # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_RC module_expsym_cmds=$lt_module_expsym_cmds_RC # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_RC # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_RC # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_RC # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_RC # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_RC # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_RC # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_RC # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_RC # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_RC # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_RC # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_RC # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_RC # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_RC # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_RC # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_RC # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_RC # Specify filename containing input files. file_list_spec=$lt_file_list_spec_RC # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_RC # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_RC # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_RC postdep_objects=$lt_postdep_objects_RC predeps=$lt_predeps_RC postdeps=$lt_postdeps_RC # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_RC # ### END LIBTOOL TAG CONFIG: RC _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: summary of build options: version: ${LIBSSH2VER} Host type: ${host} Install prefix: ${prefix} Compiler: ${CC} Compiler flags: ${CFLAGS} Library types: Shared=${enable_shared}, Static=${enable_static} Crypto library: ${found_crypto_str} zlib compression: ${found_libz} Clear memory: $enable_clear_memory Debug build: $enable_debug Build examples: $build_examples Run Docker tests: $run_docker_tests Run sshd tests: $run_sshd_tests Path to sshd: $ac_cv_path_SSHD (only for self-tests) " >&5 printf "%s\n" "$as_me: summary of build options: version: ${LIBSSH2VER} Host type: ${host} Install prefix: ${prefix} Compiler: ${CC} Compiler flags: ${CFLAGS} Library types: Shared=${enable_shared}, Static=${enable_static} Crypto library: ${found_crypto_str} zlib compression: ${found_libz} Clear memory: $enable_clear_memory Debug build: $enable_debug Build examples: $build_examples Run Docker tests: $run_docker_tests Run sshd tests: $run_sshd_tests Path to sshd: $ac_cv_path_SSHD (only for self-tests) " >&6;} libssh2-1.11.0/missing0000755000175000017500000001533614424651703011476 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # 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, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libssh2-1.11.0/COPYING0000644000175000017500000000364714435416425011136 00000000000000/* Copyright (c) 2004-2007 Sara Golemon * Copyright (c) 2005,2006 Mikhail Gusarov * Copyright (c) 2006-2007 The Written Word, Inc. * Copyright (c) 2007 Eli Fant * Copyright (c) 2009-2023 Daniel Stenberg * Copyright (C) 2008, 2009 Simon Josefsson * Copyright (c) 2000 Markus Friedl * Copyright (c) 2015 Microsoft Corp. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ libssh2-1.11.0/include/0000755000175000017500000000000014435416502011570 500000000000000libssh2-1.11.0/include/libssh2_publickey.h0000644000175000017500000001145514424650606015307 00000000000000/* Copyright (c) 2004-2006, Sara Golemon * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* Note: This include file is only needed for using the * publickey SUBSYSTEM which is not the same as publickey * authentication. For authentication you only need libssh2.h * * For more information on the publickey subsystem, * refer to IETF draft: secsh-publickey */ #ifndef LIBSSH2_PUBLICKEY_H #define LIBSSH2_PUBLICKEY_H 1 #include "libssh2.h" typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; typedef struct _libssh2_publickey_attribute { const char *name; unsigned long name_len; const char *value; unsigned long value_len; char mandatory; } libssh2_publickey_attribute; typedef struct _libssh2_publickey_list { unsigned char *packet; /* For freeing */ const unsigned char *name; unsigned long name_len; const unsigned char *blob; unsigned long blob_len; unsigned long num_attrs; libssh2_publickey_attribute *attrs; /* free me */ } libssh2_publickey_list; /* Generally use the first macro here, but if both name and value are string literals, you can use _fast() to take advantage of preprocessing */ #define libssh2_publickey_attribute(name, value, mandatory) \ { (name), strlen(name), (value), strlen(value), (mandatory) }, #define libssh2_publickey_attribute_fast(name, value, mandatory) \ { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) }, #ifdef __cplusplus extern "C" { #endif /* Publickey Subsystem */ LIBSSH2_API LIBSSH2_PUBLICKEY * libssh2_publickey_init(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len, char overwrite, unsigned long num_attrs, const libssh2_publickey_attribute attrs[]); #define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \ num_attrs, attrs) \ libssh2_publickey_add_ex((pkey), \ (name), strlen(name), \ (blob), (blob_len), \ (overwrite), (num_attrs), (attrs)) LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len); #define libssh2_publickey_remove(pkey, name, blob, blob_len) \ libssh2_publickey_remove_ex((pkey), \ (name), strlen(name), \ (blob), (blob_len)) LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list); LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list); LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* LIBSSH2_PUBLICKEY_H */ libssh2-1.11.0/include/libssh2.h0000644000175000017500000016235214435416503013241 00000000000000/* Copyright (c) 2004-2009, Sara Golemon * Copyright (c) 2009-2021 Daniel Stenberg * Copyright (c) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef LIBSSH2_H #define LIBSSH2_H 1 #define LIBSSH2_COPYRIGHT "2004-2023 The libssh2 project and its contributors." /* We use underscore instead of dash when appending DEV in dev versions just to make the BANNER define (used by src/session.c) be a valid SSH banner. Release versions have no appended strings and may of course not have dashes either. */ #define LIBSSH2_VERSION "1.11.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBSSH2_VERSION_MAJOR 1 #define LIBSSH2_VERSION_MINOR 11 #define LIBSSH2_VERSION_PATCH 0 /* This is the numeric version of the libssh2 version number, meant for easier parsing and comparisons by programs. The LIBSSH2_VERSION_NUM define will always follow this syntax: 0xXXYYZZ Where XX, YY and ZZ are the main version, release and patch numbers in hexadecimal (using 8 bits each). All three numbers are always represented using two digits. 1.2 would appear as "0x010200" while version 9.11.7 appears as "0x090b07". This 6-digit (24 bits) hexadecimal number does not show pre-release number, and it is always a greater number in a more recent release. It makes comparisons with greater than and less than work. */ #define LIBSSH2_VERSION_NUM 0x010b00 /* * This is the date and time when the full source package was created. The * timestamp is not stored in the source code repo, as the timestamp is * properly set in the tarballs by the maketgz script. * * The format of the date should follow this template: * * "Mon Feb 12 11:35:33 UTC 2007" */ #define LIBSSH2_TIMESTAMP "Tue May 30 03:58:58 PM UTC 2023" #ifndef RC_INVOKED #ifdef __cplusplus extern "C" { #endif #if defined(_WIN32) || defined(WIN32) #define LIBSSH2_WIN32 #endif #ifdef LIBSSH2_WIN32 # include # include #endif #include #include #include #include /* Allow alternate API prefix from CFLAGS or calling app */ #ifndef LIBSSH2_API # ifdef LIBSSH2_WIN32 # if defined(LIBSSH2_EXPORTS) || defined(DLL_EXPORT) || defined(_WINDLL) # ifdef LIBSSH2_LIBRARY # define LIBSSH2_API __declspec(dllexport) # else # define LIBSSH2_API __declspec(dllimport) # endif /* LIBSSH2_LIBRARY */ # else # define LIBSSH2_API # endif # else /* !LIBSSH2_WIN32 */ # define LIBSSH2_API # endif /* LIBSSH2_WIN32 */ #endif /* LIBSSH2_API */ #ifdef HAVE_SYS_UIO_H # include #endif #ifdef _MSC_VER typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; typedef unsigned __int64 libssh2_uint64_t; typedef __int64 libssh2_int64_t; #if (!defined(HAVE_SSIZE_T) && !defined(ssize_t)) typedef SSIZE_T ssize_t; #define HAVE_SSIZE_T #endif #else #include typedef unsigned long long libssh2_uint64_t; typedef long long libssh2_int64_t; #endif #ifdef LIBSSH2_WIN32 typedef SOCKET libssh2_socket_t; #define LIBSSH2_INVALID_SOCKET INVALID_SOCKET #else /* !LIBSSH2_WIN32 */ typedef int libssh2_socket_t; #define LIBSSH2_INVALID_SOCKET -1 #endif /* LIBSSH2_WIN32 */ /* * Determine whether there is small or large file support on windows. */ #if defined(_MSC_VER) && !defined(_WIN32_WCE) # if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) # define LIBSSH2_USE_WIN32_LARGE_FILES # else # define LIBSSH2_USE_WIN32_SMALL_FILES # endif #endif #if defined(__MINGW32__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) # define LIBSSH2_USE_WIN32_LARGE_FILES #endif #if defined(__WATCOMC__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) # define LIBSSH2_USE_WIN32_LARGE_FILES #endif #if defined(__POCC__) # undef LIBSSH2_USE_WIN32_LARGE_FILES #endif #if defined(LIBSSH2_WIN32) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) && \ !defined(LIBSSH2_USE_WIN32_SMALL_FILES) # define LIBSSH2_USE_WIN32_SMALL_FILES #endif /* * Large file (>2Gb) support using WIN32 functions. */ #ifdef LIBSSH2_USE_WIN32_LARGE_FILES # include # define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%I64d" typedef struct _stati64 libssh2_struct_stat; typedef __int64 libssh2_struct_stat_size; #endif /* * Small file (<2Gb) support using WIN32 functions. */ #ifdef LIBSSH2_USE_WIN32_SMALL_FILES # ifndef _WIN32_WCE # define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" typedef struct _stat libssh2_struct_stat; typedef off_t libssh2_struct_stat_size; # endif #endif #ifndef LIBSSH2_STRUCT_STAT_SIZE_FORMAT # ifdef __VMS /* We have to roll our own format here because %z is a C99-ism we don't have. */ # if __USE_OFF64_T || __USING_STD_STAT # define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%Ld" # else # define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" # endif # else # define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%zd" # endif typedef struct stat libssh2_struct_stat; typedef off_t libssh2_struct_stat_size; #endif /* Part of every banner, user specified or not */ #define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION #define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER #define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" /* Defaults for pty requests */ #define LIBSSH2_TERM_WIDTH 80 #define LIBSSH2_TERM_HEIGHT 24 #define LIBSSH2_TERM_WIDTH_PX 0 #define LIBSSH2_TERM_HEIGHT_PX 0 /* 1/4 second */ #define LIBSSH2_SOCKET_POLL_UDELAY 250000 /* 0.25 * 120 == 30 seconds */ #define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 /* Maximum size to allow a payload to compress to, plays it safe by falling short of spec limits */ #define LIBSSH2_PACKET_MAXCOMP 32000 /* Maximum size to allow a payload to deccompress to, plays it safe by allowing more than spec requires */ #define LIBSSH2_PACKET_MAXDECOMP 40000 /* Maximum size for an inbound compressed payload, plays it safe by overshooting spec limits */ #define LIBSSH2_PACKET_MAXPAYLOAD 40000 /* Malloc callbacks */ #define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) #define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, \ void **abstract) #define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract) typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT { unsigned char *text; size_t length; unsigned char echo; } LIBSSH2_USERAUTH_KBDINT_PROMPT; typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE { char *text; unsigned int length; } LIBSSH2_USERAUTH_KBDINT_RESPONSE; typedef struct _LIBSSH2_SK_SIG_INFO { uint8_t flags; uint32_t counter; unsigned char *sig_r; size_t sig_r_len; unsigned char *sig_s; size_t sig_s_len; } LIBSSH2_SK_SIG_INFO; /* 'publickey' authentication callback */ #define LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC(name) \ int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \ const unsigned char *data, size_t data_len, void **abstract) /* 'keyboard-interactive' authentication callback */ #define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \ void name_(const char *name, int name_len, const char *instruction, \ int instruction_len, int num_prompts, \ const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, \ LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) /* SK authentication callback */ #define LIBSSH2_USERAUTH_SK_SIGN_FUNC(name) \ int name(LIBSSH2_SESSION *session, LIBSSH2_SK_SIG_INFO *sig_info, \ const unsigned char *data, size_t data_len, \ int algorithm, uint8_t flags, \ const char *application, const unsigned char *key_handle, \ size_t handle_len, \ void **abstract) /* Flags for SK authentication */ #define LIBSSH2_SK_PRESENCE_REQUIRED 0x01 #define LIBSSH2_SK_VERIFICATION_REQUIRED 0x04 /* Callbacks for special SSH packets */ #define LIBSSH2_IGNORE_FUNC(name) \ void name(LIBSSH2_SESSION *session, const char *message, int message_len, \ void **abstract) #define LIBSSH2_DEBUG_FUNC(name) \ void name(LIBSSH2_SESSION *session, int always_display, \ const char *message, int message_len, \ const char *language, int language_len, \ void **abstract) #define LIBSSH2_DISCONNECT_FUNC(name) \ void name(LIBSSH2_SESSION *session, int reason, \ const char *message, int message_len, \ const char *language, int language_len, \ void **abstract) #define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) \ void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \ void **abstract) #define LIBSSH2_MACERROR_FUNC(name) \ int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \ void **abstract) #define LIBSSH2_X11_OPEN_FUNC(name) \ void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \ const char *shost, int sport, void **abstract) #define LIBSSH2_AUTHAGENT_FUNC(name) \ void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \ void **abstract) #define LIBSSH2_ADD_IDENTITIES_FUNC(name) \ void name(LIBSSH2_SESSION *session, void *buffer, \ const char *agent_path, void **abstract) #define LIBSSH2_AUTHAGENT_SIGN_FUNC(name) \ int name(LIBSSH2_SESSION* session, \ unsigned char *blob, unsigned int blen, \ const unsigned char *data, unsigned int dlen, \ unsigned char **signature, unsigned int *sigLen, \ const char *agentPath, \ void **abstract) #define LIBSSH2_CHANNEL_CLOSE_FUNC(name) \ void name(LIBSSH2_SESSION *session, void **session_abstract, \ LIBSSH2_CHANNEL *channel, void **channel_abstract) /* I/O callbacks */ #define LIBSSH2_RECV_FUNC(name) \ ssize_t name(libssh2_socket_t socket, \ void *buffer, size_t length, \ int flags, void **abstract) #define LIBSSH2_SEND_FUNC(name) \ ssize_t name(libssh2_socket_t socket, \ const void *buffer, size_t length, \ int flags, void **abstract) /* libssh2_session_callback_set() constants */ #define LIBSSH2_CALLBACK_IGNORE 0 #define LIBSSH2_CALLBACK_DEBUG 1 #define LIBSSH2_CALLBACK_DISCONNECT 2 #define LIBSSH2_CALLBACK_MACERROR 3 #define LIBSSH2_CALLBACK_X11 4 #define LIBSSH2_CALLBACK_SEND 5 #define LIBSSH2_CALLBACK_RECV 6 #define LIBSSH2_CALLBACK_AUTHAGENT 7 #define LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES 8 #define LIBSSH2_CALLBACK_AUTHAGENT_SIGN 9 /* libssh2_session_method_pref() constants */ #define LIBSSH2_METHOD_KEX 0 #define LIBSSH2_METHOD_HOSTKEY 1 #define LIBSSH2_METHOD_CRYPT_CS 2 #define LIBSSH2_METHOD_CRYPT_SC 3 #define LIBSSH2_METHOD_MAC_CS 4 #define LIBSSH2_METHOD_MAC_SC 5 #define LIBSSH2_METHOD_COMP_CS 6 #define LIBSSH2_METHOD_COMP_SC 7 #define LIBSSH2_METHOD_LANG_CS 8 #define LIBSSH2_METHOD_LANG_SC 9 #define LIBSSH2_METHOD_SIGN_ALGO 10 /* flags */ #define LIBSSH2_FLAG_SIGPIPE 1 #define LIBSSH2_FLAG_COMPRESS 2 #define LIBSSH2_FLAG_QUOTE_PATHS 3 typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS; typedef struct _LIBSSH2_AGENT LIBSSH2_AGENT; /* SK signature callback */ typedef struct _LIBSSH2_PRIVKEY_SK { int algorithm; uint8_t flags; const char *application; const unsigned char *key_handle; size_t handle_len; LIBSSH2_USERAUTH_SK_SIGN_FUNC((*sign_callback)); void **orig_abstract; } LIBSSH2_PRIVKEY_SK; int libssh2_sign_sk(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract); typedef struct _LIBSSH2_POLLFD { unsigned char type; /* LIBSSH2_POLLFD_* below */ union { libssh2_socket_t socket; /* File descriptors -- examined with system select() call */ LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */ LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound connections waiting to be accepted? */ } fd; unsigned long events; /* Requested Events */ unsigned long revents; /* Returned Events */ } LIBSSH2_POLLFD; /* Poll FD Descriptor Types */ #define LIBSSH2_POLLFD_SOCKET 1 #define LIBSSH2_POLLFD_CHANNEL 2 #define LIBSSH2_POLLFD_LISTENER 3 /* Note: Win32 Doesn't actually have a poll() implementation, so some of these values are faked with select() data */ /* Poll FD events/revents -- Match sys/poll.h where possible */ #define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or connection available -- All */ #define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to be read -- Socket only */ #define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to be read -- Channel only */ #define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- Socket/Channel */ /* revents only */ #define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ #define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ #define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ #define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket Only */ #define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- Socket/Win32 */ #define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ #define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ #define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION /* Block Direction Types */ #define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001 #define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002 /* Hash Types */ #define LIBSSH2_HOSTKEY_HASH_MD5 1 #define LIBSSH2_HOSTKEY_HASH_SHA1 2 #define LIBSSH2_HOSTKEY_HASH_SHA256 3 /* Hostkey Types */ #define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0 #define LIBSSH2_HOSTKEY_TYPE_RSA 1 #define LIBSSH2_HOSTKEY_TYPE_DSS 2 #define LIBSSH2_HOSTKEY_TYPE_ECDSA_256 3 #define LIBSSH2_HOSTKEY_TYPE_ECDSA_384 4 #define LIBSSH2_HOSTKEY_TYPE_ECDSA_521 5 #define LIBSSH2_HOSTKEY_TYPE_ED25519 6 /* Disconnect Codes (defined by SSH protocol) */ #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 #define SSH_DISCONNECT_PROTOCOL_ERROR 2 #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 #define SSH_DISCONNECT_RESERVED 4 #define SSH_DISCONNECT_MAC_ERROR 5 #define SSH_DISCONNECT_COMPRESSION_ERROR 6 #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 #define SSH_DISCONNECT_CONNECTION_LOST 10 #define SSH_DISCONNECT_BY_APPLICATION 11 #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15 /* Error Codes (defined by libssh2) */ #define LIBSSH2_ERROR_NONE 0 /* The library once used -1 as a generic error return value on numerous places through the code, which subsequently was converted to LIBSSH2_ERROR_SOCKET_NONE uses over time. As this is a generic error code, the goal is to never ever return this code but instead make sure that a more accurate and descriptive error code is used. */ #define LIBSSH2_ERROR_SOCKET_NONE -1 #define LIBSSH2_ERROR_BANNER_RECV -2 #define LIBSSH2_ERROR_BANNER_SEND -3 #define LIBSSH2_ERROR_INVALID_MAC -4 #define LIBSSH2_ERROR_KEX_FAILURE -5 #define LIBSSH2_ERROR_ALLOC -6 #define LIBSSH2_ERROR_SOCKET_SEND -7 #define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE -8 #define LIBSSH2_ERROR_TIMEOUT -9 #define LIBSSH2_ERROR_HOSTKEY_INIT -10 #define LIBSSH2_ERROR_HOSTKEY_SIGN -11 #define LIBSSH2_ERROR_DECRYPT -12 #define LIBSSH2_ERROR_SOCKET_DISCONNECT -13 #define LIBSSH2_ERROR_PROTO -14 #define LIBSSH2_ERROR_PASSWORD_EXPIRED -15 #define LIBSSH2_ERROR_FILE -16 #define LIBSSH2_ERROR_METHOD_NONE -17 #define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18 #define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED \ LIBSSH2_ERROR_AUTHENTICATION_FAILED #define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 #define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 #define LIBSSH2_ERROR_CHANNEL_FAILURE -21 #define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED -22 #define LIBSSH2_ERROR_CHANNEL_UNKNOWN -23 #define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED -24 #define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED -25 #define LIBSSH2_ERROR_CHANNEL_CLOSED -26 #define LIBSSH2_ERROR_CHANNEL_EOF_SENT -27 #define LIBSSH2_ERROR_SCP_PROTOCOL -28 #define LIBSSH2_ERROR_ZLIB -29 #define LIBSSH2_ERROR_SOCKET_TIMEOUT -30 #define LIBSSH2_ERROR_SFTP_PROTOCOL -31 #define LIBSSH2_ERROR_REQUEST_DENIED -32 #define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED -33 #define LIBSSH2_ERROR_INVAL -34 #define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 #define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36 #define LIBSSH2_ERROR_EAGAIN -37 #define LIBSSH2_ERROR_BUFFER_TOO_SMALL -38 #define LIBSSH2_ERROR_BAD_USE -39 #define LIBSSH2_ERROR_COMPRESS -40 #define LIBSSH2_ERROR_OUT_OF_BOUNDARY -41 #define LIBSSH2_ERROR_AGENT_PROTOCOL -42 #define LIBSSH2_ERROR_SOCKET_RECV -43 #define LIBSSH2_ERROR_ENCRYPT -44 #define LIBSSH2_ERROR_BAD_SOCKET -45 #define LIBSSH2_ERROR_KNOWN_HOSTS -46 #define LIBSSH2_ERROR_CHANNEL_WINDOW_FULL -47 #define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48 #define LIBSSH2_ERROR_RANDGEN -49 #define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50 #define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51 /* this is a define to provide the old (<= 1.2.7) name */ #define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV /* Global API */ #define LIBSSH2_INIT_NO_CRYPTO 0x0001 /* * libssh2_init() * * Initialize the libssh2 functions. This typically initialize the * crypto library. It uses a global state, and is not thread safe -- * you must make sure this function is not called concurrently. * * Flags can be: * 0: Normal initialize * LIBSSH2_INIT_NO_CRYPTO: Do not initialize the crypto library (ie. * OPENSSL_add_cipher_algoritms() for OpenSSL * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_init(int flags); /* * libssh2_exit() * * Exit the libssh2 functions and free's all memory used internal. */ LIBSSH2_API void libssh2_exit(void); /* * libssh2_free() * * Deallocate memory allocated by earlier call to libssh2 functions. */ LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr); /* * libssh2_session_supported_algs() * * Fills algs with a list of supported acryptographic algorithms. Returns a * non-negative number (number of supported algorithms) on success or a * negative number (an error code) on failure. * * NOTE: on success, algs must be deallocated (by calling libssh2_free) when * not needed anymore */ LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, int method_type, const char ***algs); /* Session API */ LIBSSH2_API LIBSSH2_SESSION * libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), LIBSSH2_FREE_FUNC((*my_free)), LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract); #define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL) LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session); LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback); LIBSSH2_API int libssh2_session_banner_set(LIBSSH2_SESSION *session, const char *banner); LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner); LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock); LIBSSH2_API int libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock); LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang); #define libssh2_session_disconnect(session, description) \ libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \ (description), "") LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session); LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type); LIBSSH2_API const char *libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type); LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs); LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type); LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf); LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg); LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value); LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session); /* Userauth API */ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len); LIBSSH2_API int libssh2_userauth_banner(LIBSSH2_SESSION *session, char **banner); LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC ((*passwd_change_cb))); #define libssh2_userauth_password(session, username, password) \ libssh2_userauth_password_ex((session), (username), \ (unsigned int)strlen(username), \ (password), (unsigned int)strlen(password), \ NULL) LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *publickey, const char *privatekey, const char *passphrase); #define libssh2_userauth_publickey_fromfile(session, username, publickey, \ privatekey, passphrase) \ libssh2_userauth_publickey_fromfile_ex((session), (username), \ (unsigned int)strlen(username), \ (publickey), \ (privatekey), (passphrase)) LIBSSH2_API int libssh2_userauth_publickey(LIBSSH2_SESSION *session, const char *username, const unsigned char *pubkeydata, size_t pubkeydata_len, LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC ((*sign_callback)), void **abstract); LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *publickey, const char *privatekey, const char *passphrase, const char *hostname, unsigned int hostname_len, const char *local_username, unsigned int local_username_len); #define libssh2_userauth_hostbased_fromfile(session, username, publickey, \ privatekey, passphrase, hostname) \ libssh2_userauth_hostbased_fromfile_ex((session), (username), \ (unsigned int)strlen(username), \ (publickey), \ (privatekey), (passphrase), \ (hostname), \ (unsigned int)strlen(hostname), \ (username), \ (unsigned int)strlen(username)) LIBSSH2_API int libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeyfiledata, size_t publickeyfiledata_len, const char *privatekeyfiledata, size_t privatekeyfiledata_len, const char *passphrase); /* * response_callback is provided with filled by library prompts array, * but client must allocate and fill individual responses. Responses * array is already allocated. Responses data will be freed by libssh2 * after callback return, but before subsequent callback invocation. */ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, const char *username, unsigned int username_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC ((*response_callback))); #define libssh2_userauth_keyboard_interactive(session, username, \ response_callback) \ libssh2_userauth_keyboard_interactive_ex((session), (username), \ (unsigned int)strlen(username), \ (response_callback)) LIBSSH2_API int libssh2_userauth_publickey_sk(LIBSSH2_SESSION *session, const char *username, size_t username_len, const unsigned char *pubkeydata, size_t pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase, LIBSSH2_USERAUTH_SK_SIGN_FUNC ((*sign_callback)), void **abstract); LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout); /* Channel API */ #define LIBSSH2_CHANNEL_WINDOW_DEFAULT (2*1024*1024) #define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768 #define LIBSSH2_CHANNEL_MINADJUST 1024 /* Extended Data Handling */ #define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 #define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 #define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 #define SSH_EXTENDED_DATA_STDERR 1 /* Returned by any function that would block during a read/write operation */ #define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len); #define libssh2_channel_open_session(session) \ libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \ LIBSSH2_CHANNEL_WINDOW_DEFAULT, \ LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport); #define libssh2_channel_direct_tcpip(session, host, port) \ libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_direct_streamlocal_ex(LIBSSH2_SESSION * session, const char *socket_path, const char *shost, int sport); LIBSSH2_API LIBSSH2_LISTENER * libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize); #define libssh2_channel_forward_listen(session, port) \ libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener); LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, const char *varname, unsigned int varname_len, const char *value, unsigned int value_len); #define libssh2_channel_setenv(channel, varname, value) \ libssh2_channel_setenv_ex((channel), (varname), \ (unsigned int)strlen(varname), (value), \ (unsigned int)strlen(value)) LIBSSH2_API int libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px); #define libssh2_channel_request_pty(channel, term) \ libssh2_channel_request_pty_ex((channel), (term), \ (unsigned int)strlen(term), \ NULL, 0, \ LIBSSH2_TERM_WIDTH, \ LIBSSH2_TERM_HEIGHT, \ LIBSSH2_TERM_WIDTH_PX, \ LIBSSH2_TERM_HEIGHT_PX) LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, int width, int height, int width_px, int height_px); #define libssh2_channel_request_pty_size(channel, width, height) \ libssh2_channel_request_pty_size_ex((channel), (width), (height), 0, 0) LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number); #define libssh2_channel_x11_req(channel, screen_number) \ libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) LIBSSH2_API int libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel, const char *signame, size_t signame_len); #define libssh2_channel_signal(channel, signame) \ libssh2_channel_signal_ex((channel), signame, strlen(signame)) LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len); #define libssh2_channel_shell(channel) \ libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \ NULL, 0) #define libssh2_channel_exec(channel, command) \ libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \ (command), (unsigned int)strlen(command)) #define libssh2_channel_subsystem(channel, subsystem) \ libssh2_channel_process_startup((channel), "subsystem", \ sizeof("subsystem") - 1, (subsystem), \ (unsigned int)strlen(subsystem)) LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen); #define libssh2_channel_read(channel, buf, buflen) \ libssh2_channel_read_ex((channel), 0, \ (buf), (buflen)) #define libssh2_channel_read_stderr(channel, buf, buflen) \ libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, \ (buf), (buflen)) LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended); LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial); #define libssh2_channel_window_read(channel) \ libssh2_channel_window_read_ex((channel), NULL, NULL) /* libssh2_channel_receive_window_adjust() is DEPRECATED, do not use! */ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force); LIBSSH2_API int libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force, unsigned int *storewindow); LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen); #define libssh2_channel_write(channel, buf, buflen) \ libssh2_channel_write_ex((channel), 0, \ (buf), (buflen)) #define libssh2_channel_write_stderr(channel, buf, buflen) \ libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, \ (buf), (buflen)) LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial); #define libssh2_channel_window_write(channel) \ libssh2_channel_window_write_ex((channel), NULL) LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, int blocking); LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session); LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking); LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session, long timeout); LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session); LIBSSH2_API void libssh2_session_set_read_timeout(LIBSSH2_SESSION* session, long timeout); LIBSSH2_API long libssh2_session_get_read_timeout(LIBSSH2_SESSION* session); /* libssh2_channel_handle_extended_data() is DEPRECATED, do not use! */ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode); /* libssh2_channel_ignore_extended_data() is defined below for BC with version * 0.1 * * Future uses should use libssh2_channel_handle_extended_data() directly if * LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read * (FIFO) from the standard data channel */ /* DEPRECATED */ #define libssh2_channel_ignore_extended_data(channel, ignore) \ libssh2_channel_handle_extended_data((channel), (ignore) ? \ LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \ LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL) #define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 #define LIBSSH2_CHANNEL_FLUSH_ALL -2 LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid); #define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0) #define libssh2_channel_flush_stderr(channel) \ libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR) LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel); LIBSSH2_API int libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL* channel, char **exitsignal, size_t *exitsignal_len, char **errmsg, size_t *errmsg_len, char **langtag, size_t *langtag_len); LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel); LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel); /* libssh2_scp_recv is DEPRECATED, do not use! */ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb); /* Use libssh2_scp_recv2() for large (> 2GB) file support on windows */ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, libssh2_struct_stat *sb); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime); LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, libssh2_int64_t size, time_t mtime, time_t atime); #define libssh2_scp_send(session, path, mode, size) \ libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) /* DEPRECATED */ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, unsigned int *dest_len, const char *src, unsigned int src_len); LIBSSH2_API const char *libssh2_version(int req_version_num); typedef enum { libssh2_no_crypto = 0, libssh2_openssl, libssh2_gcrypt, libssh2_mbedtls, libssh2_wincng, libssh2_os400qc3 } libssh2_crypto_engine_t; LIBSSH2_API libssh2_crypto_engine_t libssh2_crypto_engine(void); #define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */ #define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */ #define HAVE_LIBSSH2_CRYPTOENGINE_API 0x011100 /* libssh2_crypto_engine since 1.11 */ struct libssh2_knownhost { unsigned int magic; /* magic stored by the library */ void *node; /* handle to the internal representation of this host */ char *name; /* this is NULL if no plain text host name exists */ char *key; /* key in base64/printable format */ int typemask; }; /* * libssh2_knownhost_init() * * Init a collection of known hosts. Returns the pointer to a collection. * */ LIBSSH2_API LIBSSH2_KNOWNHOSTS * libssh2_knownhost_init(LIBSSH2_SESSION *session); /* * libssh2_knownhost_add() * * Add a host and its associated key to the collection of known hosts. * * The 'type' argument specifies on what format the given host and keys are: * * plain - ascii "hostname.domain.tld" * sha1 - SHA1( ) base64-encoded! * custom - another hash * * If 'sha1' is selected as type, the salt must be provided to the salt * argument. This too base64 encoded. * * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If * a custom type is used, salt is ignored and you must provide the host * pre-hashed when checking for it in the libssh2_knownhost_check() function. * * The keylen parameter may be omitted (zero) if the key is provided as a * NULL-terminated base64-encoded string. */ /* host format (2 bits) */ #define LIBSSH2_KNOWNHOST_TYPE_MASK 0xffff #define LIBSSH2_KNOWNHOST_TYPE_PLAIN 1 #define LIBSSH2_KNOWNHOST_TYPE_SHA1 2 /* always base64 encoded */ #define LIBSSH2_KNOWNHOST_TYPE_CUSTOM 3 /* key format (2 bits) */ #define LIBSSH2_KNOWNHOST_KEYENC_MASK (3<<16) #define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16) #define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16) /* type of key (4 bits) */ #define LIBSSH2_KNOWNHOST_KEY_MASK (15<<18) #define LIBSSH2_KNOWNHOST_KEY_SHIFT 18 #define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18) #define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18) #define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18) #define LIBSSH2_KNOWNHOST_KEY_ECDSA_256 (4<<18) #define LIBSSH2_KNOWNHOST_KEY_ECDSA_384 (5<<18) #define LIBSSH2_KNOWNHOST_KEY_ECDSA_521 (6<<18) #define LIBSSH2_KNOWNHOST_KEY_ED25519 (7<<18) #define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (15<<18) LIBSSH2_API int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, const char *host, const char *salt, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **store); /* * libssh2_knownhost_addc() * * Add a host and its associated key to the collection of known hosts. * * Takes a comment argument that may be NULL. A NULL comment indicates * there is no comment and the entry will end directly after the key * when written out to a file. An empty string "" comment will indicate an * empty comment which will cause a single space to be written after the key. * * The 'type' argument specifies on what format the given host and keys are: * * plain - ascii "hostname.domain.tld" * sha1 - SHA1( ) base64-encoded! * custom - another hash * * If 'sha1' is selected as type, the salt must be provided to the salt * argument. This too base64 encoded. * * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. * If a custom type is used, salt is ignored and you must provide the host * pre-hashed when checking for it in the libssh2_knownhost_check() function. * * The keylen parameter may be omitted (zero) if the key is provided as a * NULL-terminated base64-encoded string. */ LIBSSH2_API int libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, const char *host, const char *salt, const char *key, size_t keylen, const char *comment, size_t commentlen, int typemask, struct libssh2_knownhost **store); /* * libssh2_knownhost_check() * * Check a host and its associated key against the collection of known hosts. * * The type is the type/format of the given host name. * * plain - ascii "hostname.domain.tld" * custom - prehashed base64 encoded. Note that this cannot use any salts. * * * 'knownhost' may be set to NULL if you don't care about that info. * * Returns: * * LIBSSH2_KNOWNHOST_CHECK_* values, see below * */ #define LIBSSH2_KNOWNHOST_CHECK_MATCH 0 #define LIBSSH2_KNOWNHOST_CHECK_MISMATCH 1 #define LIBSSH2_KNOWNHOST_CHECK_NOTFOUND 2 #define LIBSSH2_KNOWNHOST_CHECK_FAILURE 3 LIBSSH2_API int libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, const char *host, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **knownhost); /* this function is identital to the above one, but also takes a port argument that allows libssh2 to do a better check */ LIBSSH2_API int libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, const char *host, int port, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **knownhost); /* * libssh2_knownhost_del() * * Remove a host from the collection of known hosts. The 'entry' struct is * retrieved by a call to libssh2_knownhost_check(). * */ LIBSSH2_API int libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost *entry); /* * libssh2_knownhost_free() * * Free an entire collection of known hosts. * */ LIBSSH2_API void libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts); /* * libssh2_knownhost_readline() * * Pass in a line of a file of 'type'. It makes libssh2 read this line. * * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. * */ LIBSSH2_API int libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, const char *line, size_t len, int type); /* * libssh2_knownhost_readfile() * * Add hosts+key pairs from a given file. * * Returns a negative value for error or number of successfully added hosts. * * This implementation currently only knows one 'type' (openssh), all others * are reserved for future use. */ #define LIBSSH2_KNOWNHOST_FILE_OPENSSH 1 LIBSSH2_API int libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, const char *filename, int type); /* * libssh2_knownhost_writeline() * * Ask libssh2 to convert a known host to an output line for storage. * * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given * output buffer is too small to hold the desired output. * * This implementation currently only knows one 'type' (openssh), all others * are reserved for future use. * */ LIBSSH2_API int libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost *known, char *buffer, size_t buflen, size_t *outlen, /* the amount of written data */ int type); /* * libssh2_knownhost_writefile() * * Write hosts+key pairs to a given file. * * This implementation currently only knows one 'type' (openssh), all others * are reserved for future use. */ LIBSSH2_API int libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, const char *filename, int type); /* * libssh2_knownhost_get() * * Traverse the internal list of known hosts. Pass NULL to 'prev' to get * the first one. Or pass a pointer to the previously returned one to get the * next. * * Returns: * 0 if a fine host was stored in 'store' * 1 if end of hosts * [negative] on errors */ LIBSSH2_API int libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost **store, struct libssh2_knownhost *prev); #define HAVE_LIBSSH2_AGENT_API 0x010202 /* since 1.2.2 */ struct libssh2_agent_publickey { unsigned int magic; /* magic stored by the library */ void *node; /* handle to the internal representation of key */ unsigned char *blob; /* public key blob */ size_t blob_len; /* length of the public key blob */ char *comment; /* comment in printable format */ }; /* * libssh2_agent_init() * * Init an ssh-agent handle. Returns the pointer to the handle. * */ LIBSSH2_API LIBSSH2_AGENT * libssh2_agent_init(LIBSSH2_SESSION *session); /* * libssh2_agent_connect() * * Connect to an ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_connect(LIBSSH2_AGENT *agent); /* * libssh2_agent_list_identities() * * Request an ssh-agent to list identities. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_list_identities(LIBSSH2_AGENT *agent); /* * libssh2_agent_get_identity() * * Traverse the internal list of public keys. Pass NULL to 'prev' to get * the first one. Or pass a pointer to the previously returned one to get the * next. * * Returns: * 0 if a fine public key was stored in 'store' * 1 if end of public keys * [negative] on errors */ LIBSSH2_API int libssh2_agent_get_identity(LIBSSH2_AGENT *agent, struct libssh2_agent_publickey **store, struct libssh2_agent_publickey *prev); /* * libssh2_agent_userauth() * * Do publickey user authentication with the help of ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_userauth(LIBSSH2_AGENT *agent, const char *username, struct libssh2_agent_publickey *identity); /* * libssh2_agent_sign() * * Sign a payload using a system-installed ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_sign(LIBSSH2_AGENT *agent, struct libssh2_agent_publickey *identity, unsigned char **sig, size_t *s_len, const unsigned char *data, size_t d_len, const char *method, unsigned int method_len); /* * libssh2_agent_disconnect() * * Close a connection to an ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_disconnect(LIBSSH2_AGENT *agent); /* * libssh2_agent_free() * * Free an ssh-agent handle. This function also frees the internal * collection of public keys. */ LIBSSH2_API void libssh2_agent_free(LIBSSH2_AGENT *agent); /* * libssh2_agent_set_identity_path() * * Allows a custom agent identity socket path beyond SSH_AUTH_SOCK env * */ LIBSSH2_API void libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, const char *path); /* * libssh2_agent_get_identity_path() * * Returns the custom agent identity socket path if set * */ LIBSSH2_API const char * libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent); /* * libssh2_keepalive_config() * * Set how often keepalive messages should be sent. WANT_REPLY * indicates whether the keepalive messages should request a response * from the server. INTERVAL is number of seconds that can pass * without any I/O, use 0 (the default) to disable keepalives. To * avoid some busy-loop corner-cases, if you specify an interval of 1 * it will be treated as 2. * * Note that non-blocking applications are responsible for sending the * keepalive messages using libssh2_keepalive_send(). */ LIBSSH2_API void libssh2_keepalive_config(LIBSSH2_SESSION *session, int want_reply, unsigned interval); /* * libssh2_keepalive_send() * * Send a keepalive message if needed. SECONDS_TO_NEXT indicates how * many seconds you can sleep after this call before you need to call * it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on * I/O errors. */ LIBSSH2_API int libssh2_keepalive_send(LIBSSH2_SESSION *session, int *seconds_to_next); /* NOTE NOTE NOTE libssh2_trace() has no function in builds that aren't built with debug enabled */ LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask); #define LIBSSH2_TRACE_TRANS (1<<1) #define LIBSSH2_TRACE_KEX (1<<2) #define LIBSSH2_TRACE_AUTH (1<<3) #define LIBSSH2_TRACE_CONN (1<<4) #define LIBSSH2_TRACE_SCP (1<<5) #define LIBSSH2_TRACE_SFTP (1<<6) #define LIBSSH2_TRACE_ERROR (1<<7) #define LIBSSH2_TRACE_PUBLICKEY (1<<8) #define LIBSSH2_TRACE_SOCKET (1<<9) typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*, void *, const char *, size_t); LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *context, libssh2_trace_handler_func callback); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* !RC_INVOKED */ #endif /* LIBSSH2_H */ libssh2-1.11.0/include/libssh2_sftp.h0000644000175000017500000004060014424650606014266 00000000000000/* Copyright (c) 2004-2008, Sara Golemon * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef LIBSSH2_SFTP_H #define LIBSSH2_SFTP_H 1 #include "libssh2.h" #ifndef LIBSSH2_WIN32 #include #endif #ifdef __cplusplus extern "C" { #endif /* Note: Version 6 was documented at the time of writing * However it was marked as "DO NOT IMPLEMENT" due to pending changes * * Let's start with Version 3 (The version found in OpenSSH) and go from there */ #define LIBSSH2_SFTP_VERSION 3 typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP; typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE; typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES; typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS; /* Flags for open_ex() */ #define LIBSSH2_SFTP_OPENFILE 0 #define LIBSSH2_SFTP_OPENDIR 1 /* Flags for rename_ex() */ #define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001 #define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002 #define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004 /* Flags for stat_ex() */ #define LIBSSH2_SFTP_STAT 0 #define LIBSSH2_SFTP_LSTAT 1 #define LIBSSH2_SFTP_SETSTAT 2 /* Flags for symlink_ex() */ #define LIBSSH2_SFTP_SYMLINK 0 #define LIBSSH2_SFTP_READLINK 1 #define LIBSSH2_SFTP_REALPATH 2 /* Flags for sftp_mkdir() */ #define LIBSSH2_SFTP_DEFAULT_MODE -1 /* SFTP attribute flag bits */ #define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 #define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 #define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004 #define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008 #define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000 /* SFTP statvfs flag bits */ #define LIBSSH2_SFTP_ST_RDONLY 0x00000001 #define LIBSSH2_SFTP_ST_NOSUID 0x00000002 struct _LIBSSH2_SFTP_ATTRIBUTES { /* If flags & ATTR_* bit is set, then the value in this struct will be * meaningful Otherwise it should be ignored */ unsigned long flags; libssh2_uint64_t filesize; unsigned long uid, gid; unsigned long permissions; unsigned long atime, mtime; }; struct _LIBSSH2_SFTP_STATVFS { libssh2_uint64_t f_bsize; /* file system block size */ libssh2_uint64_t f_frsize; /* fragment size */ libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */ libssh2_uint64_t f_bfree; /* # free blocks */ libssh2_uint64_t f_bavail; /* # free blocks for non-root */ libssh2_uint64_t f_files; /* # inodes */ libssh2_uint64_t f_ffree; /* # free inodes */ libssh2_uint64_t f_favail; /* # free inodes for non-root */ libssh2_uint64_t f_fsid; /* file system ID */ libssh2_uint64_t f_flag; /* mount flags */ libssh2_uint64_t f_namemax; /* maximum filename length */ }; /* SFTP filetypes */ #define LIBSSH2_SFTP_TYPE_REGULAR 1 #define LIBSSH2_SFTP_TYPE_DIRECTORY 2 #define LIBSSH2_SFTP_TYPE_SYMLINK 3 #define LIBSSH2_SFTP_TYPE_SPECIAL 4 #define LIBSSH2_SFTP_TYPE_UNKNOWN 5 #define LIBSSH2_SFTP_TYPE_SOCKET 6 #define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7 #define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 #define LIBSSH2_SFTP_TYPE_FIFO 9 /* * Reproduce the POSIX file modes here for systems that are not POSIX * compliant. * * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES" */ /* File type */ #define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */ #define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */ #define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */ #define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */ #define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */ #define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */ #define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */ #define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */ /* File mode */ /* Read, write, execute/search by owner */ #define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */ #define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */ #define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */ #define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */ /* Read, write, execute/search by group */ #define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */ #define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */ #define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */ #define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */ /* Read, write, execute/search by others */ #define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */ #define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */ #define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */ #define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */ /* macros to check for specific file types, added in 1.2.5 */ #define LIBSSH2_SFTP_S_ISLNK(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK) #define LIBSSH2_SFTP_S_ISREG(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG) #define LIBSSH2_SFTP_S_ISDIR(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR) #define LIBSSH2_SFTP_S_ISCHR(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR) #define LIBSSH2_SFTP_S_ISBLK(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK) #define LIBSSH2_SFTP_S_ISFIFO(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO) #define LIBSSH2_SFTP_S_ISSOCK(m) \ (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK) /* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */ #define LIBSSH2_FXF_READ 0x00000001 #define LIBSSH2_FXF_WRITE 0x00000002 #define LIBSSH2_FXF_APPEND 0x00000004 #define LIBSSH2_FXF_CREAT 0x00000008 #define LIBSSH2_FXF_TRUNC 0x00000010 #define LIBSSH2_FXF_EXCL 0x00000020 /* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */ #define LIBSSH2_FX_OK 0UL #define LIBSSH2_FX_EOF 1UL #define LIBSSH2_FX_NO_SUCH_FILE 2UL #define LIBSSH2_FX_PERMISSION_DENIED 3UL #define LIBSSH2_FX_FAILURE 4UL #define LIBSSH2_FX_BAD_MESSAGE 5UL #define LIBSSH2_FX_NO_CONNECTION 6UL #define LIBSSH2_FX_CONNECTION_LOST 7UL #define LIBSSH2_FX_OP_UNSUPPORTED 8UL #define LIBSSH2_FX_INVALID_HANDLE 9UL #define LIBSSH2_FX_NO_SUCH_PATH 10UL #define LIBSSH2_FX_FILE_ALREADY_EXISTS 11UL #define LIBSSH2_FX_WRITE_PROTECT 12UL #define LIBSSH2_FX_NO_MEDIA 13UL #define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14UL #define LIBSSH2_FX_QUOTA_EXCEEDED 15UL #define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16UL /* Initial mis-spelling */ #define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16UL #define LIBSSH2_FX_LOCK_CONFlICT 17UL /* Initial mis-spelling */ #define LIBSSH2_FX_LOCK_CONFLICT 17UL #define LIBSSH2_FX_DIR_NOT_EMPTY 18UL #define LIBSSH2_FX_NOT_A_DIRECTORY 19UL #define LIBSSH2_FX_INVALID_FILENAME 20UL #define LIBSSH2_FX_LINK_LOOP 21UL /* Returned by any function that would block during a read/write operation */ #define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN /* SFTP API */ LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp); LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp); /* File / Directory Ops */ LIBSSH2_API LIBSSH2_SFTP_HANDLE * libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type); #define libssh2_sftp_open(sftp, filename, flags, mode) \ libssh2_sftp_open_ex((sftp), \ (filename), (unsigned int)strlen(filename), \ (flags), (mode), LIBSSH2_SFTP_OPENFILE) #define libssh2_sftp_opendir(sftp, path) \ libssh2_sftp_open_ex((sftp), \ (path), (unsigned int)strlen(path), \ 0, 0, LIBSSH2_SFTP_OPENDIR) LIBSSH2_API LIBSSH2_SFTP_HANDLE * libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp, const char *filename, size_t filename_len, unsigned long flags, long mode, int open_type, LIBSSH2_SFTP_ATTRIBUTES *attrs); #define libssh2_sftp_open_r(sftp, filename, flags, mode, attrs) \ libssh2_sftp_open_ex_r((sftp), (filename), strlen(filename), \ (flags), (mode), LIBSSH2_SFTP_OPENFILE, \ (attrs)) LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen); LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \ char *buffer, size_t buffer_maxlen, char *longentry, size_t longentry_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs); #define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \ libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \ (attrs)) LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count); LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle); LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle); #define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) #define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle) LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset); LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset); #define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0) LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle); LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle); LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat); #define libssh2_sftp_fstat(handle, attrs) \ libssh2_sftp_fstat_ex((handle), (attrs), 0) #define libssh2_sftp_fsetstat(handle, attrs) \ libssh2_sftp_fstat_ex((handle), (attrs), 1) /* Miscellaneous Ops */ LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int srouce_filename_len, const char *dest_filename, unsigned int dest_filename_len, long flags); #define libssh2_sftp_rename(sftp, sourcefile, destfile) \ libssh2_sftp_rename_ex((sftp), \ (sourcefile), (unsigned int)strlen(sourcefile), \ (destfile), (unsigned int)strlen(destfile), \ LIBSSH2_SFTP_RENAME_OVERWRITE | \ LIBSSH2_SFTP_RENAME_ATOMIC | \ LIBSSH2_SFTP_RENAME_NATIVE) LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len); #define libssh2_sftp_unlink(sftp, filename) \ libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st); LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, size_t path_len, LIBSSH2_SFTP_STATVFS *st); LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode); #define libssh2_sftp_mkdir(sftp, path, mode) \ libssh2_sftp_mkdir_ex((sftp), (path), (unsigned int)strlen(path), (mode)) LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len); #define libssh2_sftp_rmdir(sftp, path) \ libssh2_sftp_rmdir_ex((sftp), (path), (unsigned int)strlen(path)) LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs); #define libssh2_sftp_stat(sftp, path, attrs) \ libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \ LIBSSH2_SFTP_STAT, (attrs)) #define libssh2_sftp_lstat(sftp, path, attrs) \ libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \ LIBSSH2_SFTP_LSTAT, (attrs)) #define libssh2_sftp_setstat(sftp, path, attrs) \ libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \ LIBSSH2_SFTP_SETSTAT, (attrs)) LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type); #define libssh2_sftp_symlink(sftp, orig, linkpath) \ libssh2_sftp_symlink_ex((sftp), \ (orig), (unsigned int)strlen(orig), \ (linkpath), (unsigned int)strlen(linkpath), \ LIBSSH2_SFTP_SYMLINK) #define libssh2_sftp_readlink(sftp, path, target, maxlen) \ libssh2_sftp_symlink_ex((sftp), \ (path), (unsigned int)strlen(path), \ (target), (maxlen), \ LIBSSH2_SFTP_READLINK) #define libssh2_sftp_realpath(sftp, path, target, maxlen) \ libssh2_sftp_symlink_ex((sftp), \ (path), (unsigned int)strlen(path), \ (target), (maxlen), \ LIBSSH2_SFTP_REALPATH) #ifdef __cplusplus } /* extern "C" */ #endif #endif /* LIBSSH2_SFTP_H */ libssh2-1.11.0/config.rpath0000755000175000017500000004336311765364714012420 00000000000000#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2006 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; darwin*) case $cc_basename in xlc*) wl='-Wl,' ;; esac ;; mingw* | pw32* | os2*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; newsos6) ;; linux*) case $cc_basename in icc* | ecc*) wl='-Wl,' ;; pgcc | pgf77 | pgf90) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; sco3.2v5*) ;; solaris*) wl='-Wl,' ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) wl='-Wl,' ;; sysv4*MP*) ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix3* | aix4* | aix5*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # Samuel A. Falvo II reports # that the semantics of dynamic libraries on AmigaOS, at least up # to version 4, is to share data among multiple programs linked # with the same dynamic library. Since this doesn't match the # behavior of shared libraries on other platforms, we cannot use # them. ld_shlibs=no ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; interix3*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; linux*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix4* | aix5*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix5*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 hardcode_direct=yes else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes # see comment about different semantics on the GNU ld section ld_shlibs=no ;; bsdi[45]*) ;; cygwin* | mingw* | pw32*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if test "$GCC" = yes ; then : else case $cc_basename in xlc*) ;; *) ld_shlibs=no ;; esac fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd1*) ld_shlibs=no ;; freebsd2.2*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; freebsd2*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | kfreebsd*-gnu | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; openbsd*) hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the # linker has special search rules. library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) library_names_spec='$libname.a' ;; aix4* | aix5*) library_names_spec='$libname$shrext' ;; amigaos*) library_names_spec='$libname.a' ;; beos*) library_names_spec='$libname$shrext' ;; bsdi[45]*) library_names_spec='$libname$shrext' ;; cygwin* | mingw* | pw32*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib library_names_spec='$libname$shrext' ;; dgux*) library_names_spec='$libname$shrext' ;; freebsd1*) ;; kfreebsd*-gnu) library_names_spec='$libname$shrext' ;; freebsd* | dragonfly*) case "$host_os" in freebsd[123]*) library_names_spec='$libname$shrext$versuffix' ;; *) library_names_spec='$libname$shrext' ;; esac ;; gnu*) library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac library_names_spec='$libname$shrext' ;; interix3*) library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux*) library_names_spec='$libname$shrext' ;; knetbsd*-gnu) library_names_spec='$libname$shrext' ;; netbsd*) library_names_spec='$libname$shrext' ;; newsos6) library_names_spec='$libname$shrext' ;; nto-qnx*) library_names_spec='$libname$shrext' ;; openbsd*) library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) library_names_spec='$libname$shrext' ;; solaris*) library_names_spec='$libname$shrext' ;; sunos4*) library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) library_names_spec='$libname$shrext' ;; sysv4*MP*) library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) library_names_spec='$libname$shrext' ;; uts4*) library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <) { my $l = $_; if($l =~/^commit ([[:xdigit:]]*) ?(.*)/) { $co = $1; my $ref = $2; if ($ref =~ /refs\/tags\/(libssh2-|VERSION\.)([0-9._]*)/) { $tag = $2; } else { $tag = ''; } } elsif($l =~ /^Author: *(.*) +NUL /q /f $(subst /,\,$1) RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) MKDIR = -md 2>NUL $(subst /,\,$1) COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) endif AWK := awk ZIP := zip -qzr9 # Include the version info retrieved from libssh2.h -include $(OBJ_DIR)/version.inc vpath %.c src ifdef WIN32 vpath %.rc src endif # Get CSOURCES define include src/Makefile.inc OBJS := $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(CSOURCES))) TARGET := $(BLD_DIR)/libssh2 # Override the path below to point to your Distribution folder. DISTNAM ?= libssh2-$(LIBSSH2_VERSION_STR)-bin-$(word 1,$(subst -, ,$(TRIPLET))) DISTDIR := $(BLD_DIR)/$(DISTNAM) DISTARC := $(DISTDIR).zip LIBSSH2_DYN_SUFFIX ?= libssh2_dyn_LIBRARY := $(TARGET)$(LIBSSH2_DYN_SUFFIX)$(DYN_EXT) OBJS_dyn := $(OBJS) ifdef WIN32 libssh2_def_LIBRARY := $(libssh2_dyn_LIBRARY:$(DYN_EXT)=.def) libssh2_dyn_a_LIBRARY := $(TARGET).dll.a OBJS_dyn += $(OBJ_DIR)/libssh2.res LIBSSH2_LDFLAGS_DYN += -Wl,--output-def,$(libssh2_def_LIBRARY),--out-implib,$(libssh2_dyn_a_LIBRARY) endif # Get noinst_PROGRAMS define include example/Makefile.am TARGETS_EXAMPLES := $(patsubst %.c,%$(BIN_EXT),$(strip $(wildcard example/*.c))) all: lib dyn # For compatibility dll: dyn dyn: prebuild $(libssh2_dyn_LIBRARY) lib: prebuild $(TARGET).a prebuild: $(OBJ_DIR) $(OBJ_DIR)/version.inc example: $(TARGETS_EXAMPLES) # Get DOCKER_TESTS, STANDALONE_TESTS, SSHD_TESTS, TESTS_WITH_LIB_STATIC, # librunner_la_SOURCES defines include tests/Makefile.inc TARGETS_RUNNER := $(TARGET)-runner.a TARGETS_RUNNER_OBJS := $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(filter %.c,$(librunner_la_SOURCES)))) TARGETS_TESTS := $(patsubst %.c,%$(BIN_EXT),$(addprefix tests/,$(addsuffix .c,$(DOCKER_TESTS) $(STANDALONE_TESTS) $(SSHD_TESTS)))) ifdef DYN TARGETS_TESTS := $(filter-out $(patsubst %.c,%$(BIN_EXT),$(addprefix tests/,$(addsuffix .c,$(TESTS_WITH_LIB_STATIC)))),$(TARGETS_TESTS)) endif test: $(TARGETS_RUNNER) $(TARGETS_TESTS) $(TARGETS_RUNNER_OBJS): $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) -c $(patsubst $(OBJ_DIR)/%.o,tests/%.c,$@) -o $@ $(TARGETS_RUNNER): $(TARGETS_RUNNER_OBJS) @$(call DEL, $@) $(AR) rcs $@ $^ test_%$(BIN_EXT): $(libssh2_DEPENDENCIES) $(TARGETS_RUNNER) $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBSSH2_LDFLAGS_BIN) \ $(patsubst %$(BIN_EXT),%.c,$@) -o $@ $(TARGETS_RUNNER) $(LIBS) $(LIBS_BIN) %$(BIN_EXT): %.c $(libssh2_DEPENDENCIES) $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBSSH2_LDFLAGS_BIN) $< -o $@ $(LIBS) $(LIBS_BIN) $(OBJ_DIR)/%.o: %.c $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) $(LIBSSH2_CPPFLAGS_LIB) -c $< -o $@ $(libssh2_dyn_LIBRARY) $(libssh2_dyn_a_LIBRARY): $(OBJS_dyn) @$(call DEL, $@) $(CC) $(LDFLAGS) -shared $(LIBSSH2_LDFLAGS_DYN) $^ -o $@ $(LIBS) $(LIBS_DYN) ifdef WIN32 $(OBJ_DIR)/%.res: %.rc $(RC) -O coff $(RCFLAGS) -i $< -o $@ endif $(TARGET).a: $(OBJS) @$(call DEL, $@) $(AR) rcs $@ $^ $(OBJ_DIR)/version.inc: get_ver.awk include/libssh2.h $(OBJ_DIR) $(AWK) -f $^ > $@ dist: all $(DISTDIR) $(DISTDIR)/readme.txt @$(call MKDIR, $(DISTDIR)/bin) @$(call MKDIR, $(DISTDIR)/include) @$(call MKDIR, $(DISTDIR)/lib) @$(call COPY, COPYING, $(DISTDIR)) @$(call COPY, README, $(DISTDIR)) @$(call COPY, RELEASE-NOTES, $(DISTDIR)) @$(call COPY, include/*.h, $(DISTDIR)/include) @$(call COPY, $(TARGET).a, $(DISTDIR)/lib) ifdef WIN32 @$(call COPY, $(libssh2_def_LIBRARY), $(DISTDIR)/bin) @$(call COPY, $(libssh2_dyn_LIBRARY), $(DISTDIR)/bin) @$(call COPY, $(libssh2_dyn_a_LIBRARY), $(DISTDIR)/lib) else @$(call COPY, $(libssh2_dyn_LIBRARY), $(DISTDIR)/lib) endif @echo Creating... $(DISTARC) (cd $(DISTDIR)/.. && $(ZIP) $(abspath $(DISTARC)) $(DISTNAM)/* < $(abspath $(DISTDIR)/readme.txt)) distclean vclean: clean $(call RMDIR, $(DISTDIR)) $(call DEL, $(DISTARC)) objclean: all $(call RMDIR, $(OBJ_DIR)) exampleclean: $(call DEL, $(TARGETS_EXAMPLES)) testclean: $(call DEL, $(TARGETS_RUNNER_OBJS) $(TARGETS_RUNNER) $(TARGETS_TESTS)) clean: $(call DEL, $(TARGET).a $(libssh2_dyn_LIBRARY) $(libssh2_def_LIBRARY) $(libssh2_dyn_a_LIBRARY)) $(call RMDIR, $(OBJ_DIR)) $(OBJ_DIR) $(DISTDIR): @$(call MKDIR, $@) $(DISTDIR)/readme.txt: Makefile.mk @echo Creating... $@ @echo $(DL)This is a binary distribution for $(TRIPLET).$(DL) > $@ @echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@ @echo $(DL)Please download the complete libssh2 package for$(DL) >> $@ @echo $(DL)any further documentation:$(DL) >> $@ @echo $(DL)https://www.libssh2.org/$(DL) >> $@ help: $(OBJ_DIR)/version.inc @echo $(DL)===========================================================$(DL) @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) @echo $(DL)wolfSSL path = $(WOLFSSL_PATH)$(DL) @echo $(DL)libgcrypt path = $(LIBGCRYPT_PATH)$(DL) @echo $(DL)mbedTLS path = $(MBEDTLS_PATH)$(DL) @echo $(DL)zlib path = $(ZLIB_PATH)$(DL) @echo $(DL)===========================================================$(DL) @echo $(DL)libssh2 $(LIBSSH2_VERSION_STR) - available targets are:$(DL) @echo $(DL)$(MAKE) all$(DL) @echo $(DL)$(MAKE) dyn$(DL) @echo $(DL)$(MAKE) lib$(DL) @echo $(DL)$(MAKE) clean$(DL) @echo $(DL)$(MAKE) dist$(DL) @echo $(DL)$(MAKE) distclean$(DL) @echo $(DL)$(MAKE) objclean$(DL) @echo $(DL)$(MAKE) example$(DL) @echo $(DL)$(MAKE) exampleclean$(DL) @echo $(DL)$(MAKE) test$(DL) @echo $(DL)$(MAKE) testclean$(DL) @echo $(DL)===========================================================$(DL) libssh2-1.11.0/Makefile.in0000644000175000017500000007732014435416502012143 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_TESTS_TRUE@am__append_1 = tests @BUILD_EXAMPLES_TRUE@am__append_2 = example subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(include_HEADERS) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h CONFIG_CLEAN_FILES = libssh2.pc CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(includedir)" DATA = $(pkgconfig_DATA) HEADERS = $(include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = src docs tests example am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libssh2.pc.in \ COPYING ChangeLog NEWS README compile config.guess \ config.rpath config.sub depcomp install-sh ltmain.sh missing \ tap-driver.sh DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@ HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBWOLFSSL = @HAVE_LIBWOLFSSL@ HAVE_LIBZ = @HAVE_LIBZ@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBCRYPT = @LIBBCRYPT@ LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSREQUIRED = @LIBSREQUIRED@ LIBSSH2VER = @LIBSSH2VER@ LIBSSL = @LIBSSL@ LIBSSL_PREFIX = @LIBSSL_PREFIX@ LIBTOOL = @LIBTOOL@ LIBWOLFSSL = @LIBWOLFSSL@ LIBWOLFSSL_PREFIX = @LIBWOLFSSL_PREFIX@ LIBZ = @LIBZ@ LIBZ_PREFIX = @LIBZ_PREFIX@ LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@ LTLIBOBJS = @LTLIBOBJS@ LTLIBSSL = @LTLIBSSL@ LTLIBWOLFSSL = @LTLIBWOLFSSL@ LTLIBZ = @LTLIBZ@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ RC = @RC@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSHD = @SSHD@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign nostdinc SUBDIRS = src docs $(am__append_1) $(am__append_2) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libssh2.pc include_HEADERS = \ include/libssh2.h \ include/libssh2_publickey.h \ include/libssh2_sftp.h DISTCLEANFILES = ChangeLog VMSFILES = vms/libssh2_make_example.dcl vms/libssh2_make_help.dcl \ vms/libssh2_make_kit.dcl vms/libssh2_make_lib.dcl vms/man2help.c \ vms/readme.vms vms/libssh2_config.h WIN32FILES = src/libssh2.rc NMakefile OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \ os400/make-src.sh os400/make-rpg.sh os400/make-include.sh \ os400/os400sys.c os400/ccsid.c \ os400/libssh2_config.h os400/macros.h os400/libssh2_ccsid.h \ os400/include/alloca.h os400/include/sys/socket.h os400/include/stdio.h \ os400/include/assert.h \ os400/libssh2rpg/libssh2.rpgle.in \ os400/libssh2rpg/libssh2_ccsid.rpgle.in \ os400/libssh2rpg/libssh2_publickey.rpgle \ os400/libssh2rpg/libssh2_sftp.rpgle EXTRA_DIST = $(WIN32FILES) get_ver.awk \ maketgz RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \ CMakeLists.txt cmake git2news.pl libssh2-style.el README.md $(OS400FILES) \ buildconf Makefile.mk ACLOCAL_AMFLAGS = -I m4 all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): libssh2.pc: $(top_builddir)/config.status $(srcdir)/libssh2.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-includeHEADERS install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-includeHEADERS uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \ distclean-generic distclean-libtool distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am \ install-includeHEADERS install-info install-info-am \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-includeHEADERS uninstall-pkgconfigDATA .PRECIOUS: Makefile .PHONY: ChangeLog ChangeLog: echo "see NEWS" > ./ChangeLog dist-hook: rm -rf $(top_builddir)/tests/log find $(distdir) -name "*.dist" -exec rm {} \; (distit=`find $(srcdir) -name "*.dist"`; \ for file in $$distit; do \ strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ cp $$file $(distdir)$$strip; \ done) # Code Coverage init-coverage: make clean lcov --directory . --zerocounters COVERAGE_CCOPTS ?= "-g --coverage" COVERAGE_OUT ?= docs/coverage build-coverage: make CFLAGS=$(COVERAGE_CCOPTS) check mkdir -p $(COVERAGE_OUT) lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \ --capture gen-coverage: genhtml --output-directory $(COVERAGE_OUT) \ $(COVERAGE_OUT)/$(PACKAGE).info \ --highlight --frames --legend \ --title "$(PACKAGE_NAME)" coverage: init-coverage build-coverage gen-coverage checksrc: perl ci/checksrc.pl -i4 -m79 \ -ASNPRINTF \ -ACOPYRIGHT \ -AFOPENMODE \ -ATYPEDEFSTRUCT \ -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c \ tests/*.[ch] # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libssh2-1.11.0/src/0000755000175000017500000000000014435416502010734 500000000000000libssh2-1.11.0/src/pem.c0000644000175000017500000006421614432741311011606 00000000000000/* Copyright (C) 2007 The Written Word, Inc. * Copyright (C) 2008, Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" static int readline(char *line, int line_size, FILE * fp) { size_t len; if(!line) { return -1; } if(!fgets(line, line_size, fp)) { return -1; } if(*line) { len = strlen(line); if(len > 0 && line[len - 1] == '\n') { line[len - 1] = '\0'; } } if(*line) { len = strlen(line); if(len > 0 && line[len - 1] == '\r') { line[len - 1] = '\0'; } } return 0; } static int readline_memory(char *line, size_t line_size, const char *filedata, size_t filedata_len, size_t *filedata_offset) { size_t off, len; off = *filedata_offset; for(len = 0; off + len < filedata_len && len < line_size - 1; len++) { if(filedata[off + len] == '\n' || filedata[off + len] == '\r') { break; } } if(len) { memcpy(line, filedata + off, len); *filedata_offset += len; } line[len] = '\0'; *filedata_offset += 1; return 0; } #define LINE_SIZE 128 static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED"; static unsigned char hex_decode(char digit) { return (unsigned char) ((digit >= 'A') ? (0xA + (digit - 'A')) : (digit - '0')); } /* Hack to fix builds with crypto backends with MD5 support disabled. FIXME: Honor our LIBSSH2_MD5 macro for MD5-dependent logic. */ #ifdef OPENSSL_NO_MD5 #define MD5_DIGEST_LENGTH 16 #endif int _libssh2_pem_parse(LIBSSH2_SESSION * session, const char *headerbegin, const char *headerend, const unsigned char *passphrase, FILE * fp, unsigned char **data, size_t *datalen) { char line[LINE_SIZE]; unsigned char iv[LINE_SIZE]; char *b64data = NULL; size_t b64datalen = 0; int ret; const LIBSSH2_CRYPT_METHOD *method = NULL; do { *line = '\0'; if(readline(line, LINE_SIZE, fp)) { return -1; } } while(strcmp(line, headerbegin) != 0); if(readline(line, LINE_SIZE, fp)) { return -1; } if(passphrase && memcmp(line, crypt_annotation, strlen(crypt_annotation)) == 0) { const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method; int i; if(readline(line, LINE_SIZE, fp)) { ret = -1; goto out; } all_methods = libssh2_crypt_methods(); /* !checksrc! disable EQUALSNULL 1 */ while((cur_method = *all_methods++) != NULL) { if(*cur_method->pem_annotation && memcmp(line, cur_method->pem_annotation, strlen(cur_method->pem_annotation)) == 0) { method = cur_method; memcpy(iv, line + strlen(method->pem_annotation) + 1, 2*method->iv_len); } } /* None of the available crypt methods were able to decrypt the key */ if(!method) return -1; /* Decode IV from hex */ for(i = 0; i < method->iv_len; ++i) { iv[i] = (unsigned char)(hex_decode(iv[2*i]) << 4); iv[i] |= hex_decode(iv[2*i + 1]); } /* skip to the next line */ if(readline(line, LINE_SIZE, fp)) { ret = -1; goto out; } } do { if(*line) { char *tmp; size_t linelen; linelen = strlen(line); tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); if(!tmp) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for PEM parsing"); ret = -1; goto out; } memcpy(tmp + b64datalen, line, linelen); b64data = tmp; b64datalen += linelen; } *line = '\0'; if(readline(line, LINE_SIZE, fp)) { ret = -1; goto out; } } while(strcmp(line, headerend) != 0); if(!b64data) { return -1; } if(_libssh2_base64_decode(session, (char **) data, datalen, b64data, b64datalen)) { ret = -1; goto out; } if(method) { /* Set up decryption */ int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0; int blocksize = method->blocksize; void *abstract; unsigned char secret[2*MD5_DIGEST_LENGTH]; libssh2_md5_ctx fingerprint_ctx; /* Perform key derivation (PBKDF1/MD5) */ if(!libssh2_md5_init(&fingerprint_ctx)) { ret = -1; goto out; } libssh2_md5_update(fingerprint_ctx, passphrase, strlen((char *)passphrase)); libssh2_md5_update(fingerprint_ctx, iv, 8); libssh2_md5_final(fingerprint_ctx, secret); if(method->secret_len > MD5_DIGEST_LENGTH) { if(!libssh2_md5_init(&fingerprint_ctx)) { ret = -1; goto out; } libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH); libssh2_md5_update(fingerprint_ctx, passphrase, strlen((char *)passphrase)); libssh2_md5_update(fingerprint_ctx, iv, 8); libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH); } /* Initialize the decryption */ if(method->init(session, method, iv, &free_iv, secret, &free_secret, 0, &abstract)) { _libssh2_explicit_zero((char *)secret, sizeof(secret)); LIBSSH2_FREE(session, data); ret = -1; goto out; } if(free_secret) { _libssh2_explicit_zero((char *)secret, sizeof(secret)); } /* Do the actual decryption */ if((*datalen % blocksize) != 0) { _libssh2_explicit_zero((char *)secret, sizeof(secret)); method->dtor(session, &abstract); _libssh2_explicit_zero(*data, *datalen); LIBSSH2_FREE(session, *data); ret = -1; goto out; } while(len_decrypted <= (int)*datalen - blocksize) { if(method->crypt(session, *data + len_decrypted, blocksize, &abstract, len_decrypted == 0 ? FIRST_BLOCK : ((len_decrypted == (int)*datalen - blocksize) ? LAST_BLOCK : MIDDLE_BLOCK) )) { ret = LIBSSH2_ERROR_DECRYPT; _libssh2_explicit_zero((char *)secret, sizeof(secret)); method->dtor(session, &abstract); _libssh2_explicit_zero(*data, *datalen); LIBSSH2_FREE(session, *data); goto out; } len_decrypted += blocksize; } /* Account for padding */ padding = (*data)[*datalen - 1]; memset(&(*data)[*datalen-padding], 0, padding); *datalen -= padding; /* Clean up */ _libssh2_explicit_zero((char *)secret, sizeof(secret)); method->dtor(session, &abstract); } ret = 0; out: if(b64data) { _libssh2_explicit_zero(b64data, b64datalen); LIBSSH2_FREE(session, b64data); } return ret; } int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session, const char *headerbegin, const char *headerend, const char *filedata, size_t filedata_len, unsigned char **data, size_t *datalen) { char line[LINE_SIZE]; char *b64data = NULL; size_t b64datalen = 0; size_t off = 0; int ret; do { *line = '\0'; if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { return -1; } } while(strcmp(line, headerbegin) != 0); *line = '\0'; do { if(*line) { char *tmp; size_t linelen; linelen = strlen(line); tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); if(!tmp) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for PEM parsing"); ret = -1; goto out; } memcpy(tmp + b64datalen, line, linelen); b64data = tmp; b64datalen += linelen; } *line = '\0'; if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { ret = -1; goto out; } } while(strcmp(line, headerend) != 0); if(!b64data) { return -1; } if(_libssh2_base64_decode(session, (char **) data, datalen, b64data, b64datalen)) { ret = -1; goto out; } ret = 0; out: if(b64data) { _libssh2_explicit_zero(b64data, b64datalen); LIBSSH2_FREE(session, b64data); } return ret; } /* OpenSSH formatted keys */ #define AUTH_MAGIC "openssh-key-v1" #define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----" #define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----" static int _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session, const unsigned char *passphrase, const char *b64data, size_t b64datalen, struct string_buf **decrypted_buf) { const LIBSSH2_CRYPT_METHOD *method = NULL; struct string_buf decoded, decrypted, kdf_buf; unsigned char *ciphername = NULL; unsigned char *kdfname = NULL; unsigned char *kdf = NULL; unsigned char *buf = NULL; unsigned char *salt = NULL; uint32_t nkeys, check1, check2; uint32_t rounds = 0; unsigned char *key = NULL; unsigned char *key_part = NULL; unsigned char *iv_part = NULL; unsigned char *f = NULL; size_t f_len = 0; int ret = 0, keylen = 0, ivlen = 0, total_len = 0; size_t kdf_len = 0, tmp_len = 0, salt_len = 0; if(decrypted_buf) *decrypted_buf = NULL; /* decode file */ if(_libssh2_base64_decode(session, (char **)&f, &f_len, b64data, b64datalen)) { ret = -1; goto out; } /* Parse the file */ decoded.data = (unsigned char *)f; decoded.dataptr = (unsigned char *)f; decoded.len = f_len; if(decoded.len < strlen(AUTH_MAGIC)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key too short"); goto out; } if(strncmp((char *) decoded.dataptr, AUTH_MAGIC, strlen(AUTH_MAGIC)) != 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key auth magic mismatch"); goto out; } decoded.dataptr += strlen(AUTH_MAGIC) + 1; if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) || tmp_len == 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ciphername is missing"); goto out; } if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) || tmp_len == 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "kdfname is missing"); goto out; } if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "kdf is missing"); goto out; } else { kdf_buf.data = kdf; kdf_buf.dataptr = kdf; kdf_buf.len = kdf_len; } if((!passphrase || strlen((const char *)passphrase) == 0) && strcmp((const char *)ciphername, "none") != 0) { /* passphrase required */ ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED; goto out; } if(strcmp((const char *)kdfname, "none") != 0 && strcmp((const char *)kdfname, "bcrypt") != 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "unknown cipher"); goto out; } if(!strcmp((const char *)kdfname, "none") && strcmp((const char *)ciphername, "none") != 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "invalid format"); goto out; } if(_libssh2_get_u32(&decoded, &nkeys) != 0 || nkeys != 1) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Multiple keys are unsupported"); goto out; } /* unencrypted public key */ if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid private key; " "expect embedded public key"); goto out; } if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Private key data not found"); goto out; } /* decode encrypted private key */ decrypted.data = decrypted.dataptr = buf; decrypted.len = tmp_len; if(ciphername && strcmp((const char *)ciphername, "none") != 0) { const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method; all_methods = libssh2_crypt_methods(); /* !checksrc! disable EQUALSNULL 1 */ while((cur_method = *all_methods++) != NULL) { if(*cur_method->name && memcmp(ciphername, cur_method->name, strlen(cur_method->name)) == 0) { method = cur_method; } } /* None of the available crypt methods were able to decrypt the key */ if(!method) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No supported cipher found"); goto out; } } if(method) { int free_iv = 0, free_secret = 0, len_decrypted = 0; int blocksize; void *abstract = NULL; keylen = method->secret_len; ivlen = method->iv_len; total_len = keylen + ivlen; key = LIBSSH2_CALLOC(session, total_len); if(!key) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Could not alloc key"); goto out; } if(strcmp((const char *)kdfname, "bcrypt") == 0 && passphrase) { if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) || (_libssh2_get_u32(&kdf_buf, &rounds) != 0)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "kdf contains unexpected values"); LIBSSH2_FREE(session, key); goto out; } if(_libssh2_bcrypt_pbkdf((const char *)passphrase, strlen((const char *)passphrase), salt, salt_len, key, keylen + ivlen, rounds) < 0) { ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT, "invalid format"); LIBSSH2_FREE(session, key); goto out; } } else { ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED, "bcrypted without passphrase"); LIBSSH2_FREE(session, key); goto out; } /* Set up decryption */ blocksize = method->blocksize; key_part = LIBSSH2_CALLOC(session, keylen); if(!key_part) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Could not alloc key part"); goto out; } iv_part = LIBSSH2_CALLOC(session, ivlen); if(!iv_part) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Could not alloc iv part"); goto out; } memcpy(key_part, key, keylen); memcpy(iv_part, key + keylen, ivlen); /* Initialize the decryption */ if(method->init(session, method, iv_part, &free_iv, key_part, &free_secret, 0, &abstract)) { ret = LIBSSH2_ERROR_DECRYPT; goto out; } /* Do the actual decryption */ if((decrypted.len % blocksize) != 0) { method->dtor(session, &abstract); ret = LIBSSH2_ERROR_DECRYPT; goto out; } while((size_t)len_decrypted <= decrypted.len - blocksize) { if(method->crypt(session, decrypted.data + len_decrypted, blocksize, &abstract, len_decrypted == 0 ? FIRST_BLOCK : ( ((size_t)len_decrypted == decrypted.len - blocksize) ? LAST_BLOCK : MIDDLE_BLOCK) )) { ret = LIBSSH2_ERROR_DECRYPT; method->dtor(session, &abstract); goto out; } len_decrypted += blocksize; } /* No padding */ method->dtor(session, &abstract); } /* Check random bytes match */ if(_libssh2_get_u32(&decrypted, &check1) != 0 || _libssh2_get_u32(&decrypted, &check2) != 0 || check1 != check2) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Private key unpack failed (correct password?)"); ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED; goto out; } if(decrypted_buf) { /* copy data to out-going buffer */ struct string_buf *out_buf = _libssh2_string_buf_new(session); if(!out_buf) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "decrypted struct"); goto out; } out_buf->data = LIBSSH2_CALLOC(session, decrypted.len); if(!out_buf->data) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "decrypted struct"); _libssh2_string_buf_free(session, out_buf); goto out; } memcpy(out_buf->data, decrypted.data, decrypted.len); out_buf->dataptr = out_buf->data + (decrypted.dataptr - decrypted.data); out_buf->len = decrypted.len; *decrypted_buf = out_buf; } out: /* Clean up */ if(key) { _libssh2_explicit_zero(key, total_len); LIBSSH2_FREE(session, key); } if(key_part) { _libssh2_explicit_zero(key_part, keylen); LIBSSH2_FREE(session, key_part); } if(iv_part) { _libssh2_explicit_zero(iv_part, ivlen); LIBSSH2_FREE(session, iv_part); } if(f) { _libssh2_explicit_zero(f, f_len); LIBSSH2_FREE(session, f); } return ret; } int _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session, const unsigned char *passphrase, FILE * fp, struct string_buf **decrypted_buf) { char line[LINE_SIZE]; char *b64data = NULL; size_t b64datalen = 0; int ret = 0; /* read file */ do { *line = '\0'; if(readline(line, LINE_SIZE, fp)) { return -1; } } while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0); if(readline(line, LINE_SIZE, fp)) { return -1; } do { if(*line) { char *tmp; size_t linelen; linelen = strlen(line); tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); if(!tmp) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for PEM parsing"); ret = -1; goto out; } memcpy(tmp + b64datalen, line, linelen); b64data = tmp; b64datalen += linelen; } *line = '\0'; if(readline(line, LINE_SIZE, fp)) { ret = -1; goto out; } } while(strcmp(line, OPENSSH_HEADER_END) != 0); if(!b64data) { return -1; } ret = _libssh2_openssh_pem_parse_data(session, passphrase, (const char *)b64data, b64datalen, decrypted_buf); if(b64data) { _libssh2_explicit_zero(b64data, b64datalen); LIBSSH2_FREE(session, b64data); } out: return ret; } int _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session, const unsigned char *passphrase, const char *filedata, size_t filedata_len, struct string_buf **decrypted_buf) { char line[LINE_SIZE]; char *b64data = NULL; size_t b64datalen = 0; size_t off = 0; int ret; if(!filedata || filedata_len <= 0) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Error parsing PEM: filedata missing"); do { *line = '\0'; if(off >= filedata_len) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Error parsing PEM: " "OpenSSH header not found"); if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { return -1; } } while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0); *line = '\0'; do { if(*line) { char *tmp; size_t linelen; linelen = strlen(line); tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); if(!tmp) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "PEM parsing"); goto out; } memcpy(tmp + b64datalen, line, linelen); b64data = tmp; b64datalen += linelen; } *line = '\0'; if(off >= filedata_len) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Error parsing PEM: offset out of bounds"); goto out; } if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { ret = -1; goto out; } } while(strcmp(line, OPENSSH_HEADER_END) != 0); if(!b64data) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Error parsing PEM: base 64 data missing"); ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data, b64datalen, decrypted_buf); out: if(b64data) { _libssh2_explicit_zero(b64data, b64datalen); LIBSSH2_FREE(session, b64data); } return ret; } static int read_asn1_length(const unsigned char *data, size_t datalen, size_t *len) { unsigned int lenlen; int nextpos; if(datalen < 1) { return -1; } *len = data[0]; if(*len >= 0x80) { lenlen = *len & 0x7F; *len = data[1]; if(1 + lenlen > datalen) { return -1; } if(lenlen > 1) { *len <<= 8; *len |= data[2]; } } else { lenlen = 0; } nextpos = 1 + lenlen; if(lenlen > 2 || 1 + lenlen + *len > datalen) { return -1; } return nextpos; } int _libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen) { size_t len; int lenlen; if(*datalen < 1) { return -1; } if((*data)[0] != '\x30') { return -1; } (*data)++; (*datalen)--; lenlen = read_asn1_length(*data, *datalen, &len); if(lenlen < 0 || lenlen + len != *datalen) { return -1; } *data += lenlen; *datalen -= lenlen; return 0; } int _libssh2_pem_decode_integer(unsigned char **data, size_t *datalen, unsigned char **i, unsigned int *ilen) { size_t len; int lenlen; if(*datalen < 1) { return -1; } if((*data)[0] != '\x02') { return -1; } (*data)++; (*datalen)--; lenlen = read_asn1_length(*data, *datalen, &len); if(lenlen < 0 || lenlen + len > *datalen) { return -1; } *data += lenlen; *datalen -= lenlen; *i = *data; *ilen = (unsigned int)len; *data += len; *datalen -= len; return 0; } libssh2-1.11.0/src/agent_win.c0000644000175000017500000003454214432741311012777 00000000000000/* * Copyright (c) 2009 by Daiki Ueno * Copyright (C) 2010-2014 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef HAVE_WIN32_AGENTS /* Compile this via agent.c */ #include /* for getenv() */ /* Code to talk to OpenSSH was taken and modified from the Win32 port of * Portable OpenSSH by the PowerShell team. Commit * 8ab565c53f3619d6a1f5ac229e212cad8a52852c of * https://github.com/PowerShell/openssh-portable.git was used as the base, * specifically the following files: * * - contrib\win32\win32compat\fileio.c * - Structure of agent_connect_openssh from ssh_get_authentication_socket * - Structure of agent_transact_openssh from ssh_request_reply * - contrib\win32\win32compat\wmain_common.c * - Windows equivalent functions for common Unix functions, inlined into * this implementation * - fileio_connect replacing connect * - fileio_read replacing read * - fileio_write replacing write * - fileio_close replacing close * * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Functions for connecting the local authentication agent. * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". * * SSH2 implementation, * Copyright (c) 2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright (c) 2015 Microsoft Corp. * All rights reserved * * Microsoft openssh win32 port * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define WIN32_OPENSSH_AGENT_SOCK "\\\\.\\pipe\\openssh-ssh-agent" static int agent_connect_openssh(LIBSSH2_AGENT *agent) { int ret = LIBSSH2_ERROR_NONE; const char *path; HANDLE pipe = INVALID_HANDLE_VALUE; HANDLE event = NULL; path = agent->identity_agent_path; if(!path) { path = getenv("SSH_AUTH_SOCK"); if(!path) path = WIN32_OPENSSH_AGENT_SOCK; } for(;;) { pipe = CreateFileA( path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, /* Non-blocking mode for agent connections is not implemented at * the point this was implemented. The code for Win32 OpenSSH * should support non-blocking IO, but the code calling it doesn't * support it as of yet. * When non-blocking IO is implemented for the surrounding code, * uncomment the following line to enable support within the Win32 * OpenSSH code. */ /* FILE_FLAG_OVERLAPPED | */ SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, NULL ); if(pipe != INVALID_HANDLE_VALUE) break; if(GetLastError() != ERROR_PIPE_BUSY) break; /* Wait up to 1 second for a pipe instance to become available */ if(!WaitNamedPipeA(path, 1000)) break; } if(pipe == INVALID_HANDLE_VALUE) { ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "unable to connect to agent pipe"); goto cleanup; } if(SetHandleInformation(pipe, HANDLE_FLAG_INHERIT, 0) == FALSE) { ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "unable to set handle information of agent pipe"); goto cleanup; } event = CreateEventA(NULL, TRUE, FALSE, NULL); if(!event) { ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "unable to create async I/O event"); goto cleanup; } agent->pipe = pipe; pipe = INVALID_HANDLE_VALUE; agent->overlapped.hEvent = event; event = NULL; agent->fd = 0; /* Mark as the connection has been established */ cleanup: if(event) CloseHandle(event); if(pipe != INVALID_HANDLE_VALUE) CloseHandle(pipe); return ret; } #define RECV_SEND_ALL(func, agent, buffer, length, total) \ DWORD bytes_transfered; \ BOOL ret; \ DWORD err; \ int rc; \ \ while(*total < length) { \ if(!agent->pending_io) \ ret = func(agent->pipe, (char *)buffer + *total, \ (DWORD)(length - *total), &bytes_transfered, \ &agent->overlapped); \ else \ ret = GetOverlappedResult(agent->pipe, &agent->overlapped, \ &bytes_transfered, FALSE); \ \ *total += bytes_transfered; \ if(!ret) { \ err = GetLastError(); \ if((!agent->pending_io && ERROR_IO_PENDING == err) \ || (agent->pending_io && ERROR_IO_INCOMPLETE == err)) { \ agent->pending_io = TRUE; \ return LIBSSH2_ERROR_EAGAIN; \ } \ \ return LIBSSH2_ERROR_SOCKET_NONE; \ } \ agent->pending_io = FALSE; \ } \ \ rc = (int)*total; \ *total = 0; \ return rc; static int win32_openssh_send_all(LIBSSH2_AGENT *agent, void *buffer, size_t length, size_t *send_recv_total) { RECV_SEND_ALL(WriteFile, agent, buffer, length, send_recv_total) } static int win32_openssh_recv_all(LIBSSH2_AGENT *agent, void *buffer, size_t length, size_t *send_recv_total) { RECV_SEND_ALL(ReadFile, agent, buffer, length, send_recv_total) } #undef RECV_SEND_ALL static int agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) { unsigned char buf[4]; int rc; /* Send the length of the request */ if(transctx->state == agent_NB_state_request_created) { _libssh2_htonu32(buf, (uint32_t)transctx->request_len); rc = win32_openssh_send_all(agent, buf, sizeof(buf), &transctx->send_recv_total); if(rc == LIBSSH2_ERROR_EAGAIN) return LIBSSH2_ERROR_EAGAIN; else if(rc < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, "agent send failed"); transctx->state = agent_NB_state_request_length_sent; } /* Send the request body */ if(transctx->state == agent_NB_state_request_length_sent) { rc = win32_openssh_send_all(agent, transctx->request, transctx->request_len, &transctx->send_recv_total); if(rc == LIBSSH2_ERROR_EAGAIN) return LIBSSH2_ERROR_EAGAIN; else if(rc < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, "agent send failed"); transctx->state = agent_NB_state_request_sent; } /* Receive the length of the body */ if(transctx->state == agent_NB_state_request_sent) { rc = win32_openssh_recv_all(agent, buf, sizeof(buf), &transctx->send_recv_total); if(rc == LIBSSH2_ERROR_EAGAIN) return LIBSSH2_ERROR_EAGAIN; else if(rc < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, "agent recv failed"); transctx->response_len = _libssh2_ntohu32(buf); transctx->response = LIBSSH2_ALLOC(agent->session, transctx->response_len); if(!transctx->response) return LIBSSH2_ERROR_ALLOC; transctx->state = agent_NB_state_response_length_received; } /* Receive the response body */ if(transctx->state == agent_NB_state_response_length_received) { rc = win32_openssh_recv_all(agent, transctx->response, transctx->response_len, &transctx->send_recv_total); if(rc == LIBSSH2_ERROR_EAGAIN) return LIBSSH2_ERROR_EAGAIN; else if(rc < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, "agent recv failed"); transctx->state = agent_NB_state_response_received; } return LIBSSH2_ERROR_NONE; } static int agent_disconnect_openssh(LIBSSH2_AGENT *agent) { if(!CancelIo(agent->pipe)) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, "failed to cancel pending IO of agent pipe"); if(!CloseHandle(agent->overlapped.hEvent)) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, "failed to close handle to async I/O event"); agent->overlapped.hEvent = NULL; /* let queued APCs (if any) drain */ SleepEx(0, TRUE); if(!CloseHandle(agent->pipe)) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, "failed to close handle to agent pipe"); agent->pipe = INVALID_HANDLE_VALUE; agent->fd = LIBSSH2_INVALID_SOCKET; return LIBSSH2_ERROR_NONE; } static struct agent_ops agent_ops_openssh = { agent_connect_openssh, agent_transact_openssh, agent_disconnect_openssh }; #endif /* HAVE_WIN32_AGENTS */ libssh2-1.11.0/src/wincng.h0000644000175000017500000006000014424650606012311 00000000000000#ifndef __LIBSSH2_WINCNG_H #define __LIBSSH2_WINCNG_H /* * Copyright (C) 2013-2020 Marc Hoersken * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #define LIBSSH2_CRYPTO_ENGINE libssh2_wincng /* required for cross-compilation against the w64 mingw-runtime package */ #if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) #undef _WIN32_WINNT #endif #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0600 #endif #include #include #define LIBSSH2_MD5 1 #define LIBSSH2_HMAC_RIPEMD 0 #define LIBSSH2_HMAC_SHA256 1 #define LIBSSH2_HMAC_SHA512 1 #define LIBSSH2_AES_CBC 1 #define LIBSSH2_AES_CTR 1 #define LIBSSH2_AES_GCM 0 #define LIBSSH2_BLOWFISH 0 #define LIBSSH2_RC4 1 #define LIBSSH2_CAST 0 #define LIBSSH2_3DES 1 #define LIBSSH2_RSA 1 #define LIBSSH2_RSA_SHA1 1 #define LIBSSH2_RSA_SHA2 1 #define LIBSSH2_DSA 1 #define LIBSSH2_ECDSA 0 #define LIBSSH2_ED25519 0 #define MD5_DIGEST_LENGTH 16 #define SHA_DIGEST_LENGTH 20 #define SHA256_DIGEST_LENGTH 32 #define SHA384_DIGEST_LENGTH 48 #define SHA512_DIGEST_LENGTH 64 #define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) #if LIBSSH2_ECDSA #else #define _libssh2_ec_key void #endif /*******************************************************************/ /* * Windows CNG backend: Global context handles */ struct _libssh2_wincng_ctx { BCRYPT_ALG_HANDLE hAlgRNG; BCRYPT_ALG_HANDLE hAlgHashMD5; BCRYPT_ALG_HANDLE hAlgHashSHA1; BCRYPT_ALG_HANDLE hAlgHashSHA256; BCRYPT_ALG_HANDLE hAlgHashSHA384; BCRYPT_ALG_HANDLE hAlgHashSHA512; BCRYPT_ALG_HANDLE hAlgHmacMD5; BCRYPT_ALG_HANDLE hAlgHmacSHA1; BCRYPT_ALG_HANDLE hAlgHmacSHA256; BCRYPT_ALG_HANDLE hAlgHmacSHA384; BCRYPT_ALG_HANDLE hAlgHmacSHA512; BCRYPT_ALG_HANDLE hAlgRSA; BCRYPT_ALG_HANDLE hAlgDSA; BCRYPT_ALG_HANDLE hAlgAES_CBC; BCRYPT_ALG_HANDLE hAlgAES_ECB; BCRYPT_ALG_HANDLE hAlgRC4_NA; BCRYPT_ALG_HANDLE hAlg3DES_CBC; BCRYPT_ALG_HANDLE hAlgDH; volatile int hasAlgDHwithKDF; /* -1=no, 0=maybe, 1=yes */ }; extern struct _libssh2_wincng_ctx _libssh2_wincng; /*******************************************************************/ /* * Windows CNG backend: Generic functions */ void _libssh2_wincng_init(void); void _libssh2_wincng_free(void); #define libssh2_crypto_init() \ _libssh2_wincng_init() #define libssh2_crypto_exit() \ _libssh2_wincng_free() #define _libssh2_random(buf, len) \ _libssh2_wincng_random(buf, len) #define libssh2_prepare_iovec(vec, len) /* Empty. */ /*******************************************************************/ /* * Windows CNG backend: Hash structure */ typedef struct __libssh2_wincng_hash_ctx { BCRYPT_HASH_HANDLE hHash; unsigned char *pbHashObject; unsigned long dwHashObject; unsigned long cbHash; } _libssh2_wincng_hash_ctx; /* * Windows CNG backend: Hash functions */ #define libssh2_sha1_ctx _libssh2_wincng_hash_ctx #define libssh2_sha1_init(ctx) \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ SHA_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha1_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, \ (const unsigned char *) data, \ (unsigned long) datalen) #define libssh2_sha1_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, hash) #define libssh2_sha1(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \ hash, SHA_DIGEST_LENGTH) #define libssh2_sha256_ctx _libssh2_wincng_hash_ctx #define libssh2_sha256_init(ctx) \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \ SHA256_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha256_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, \ (const unsigned char *) data, \ (unsigned long) datalen) #define libssh2_sha256_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, hash) #define libssh2_sha256(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \ hash, SHA256_DIGEST_LENGTH) #define libssh2_sha384_ctx _libssh2_wincng_hash_ctx #define libssh2_sha384_init(ctx) \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \ SHA384_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha384_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, \ (const unsigned char *) data, \ (unsigned long) datalen) #define libssh2_sha384_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, hash) #define libssh2_sha384(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \ hash, SHA384_DIGEST_LENGTH) #define libssh2_sha512_ctx _libssh2_wincng_hash_ctx #define libssh2_sha512_init(ctx) \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \ SHA512_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha512_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, \ (const unsigned char *) data, \ (unsigned long) datalen) #define libssh2_sha512_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, hash) #define libssh2_sha512(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \ hash, SHA512_DIGEST_LENGTH) #define libssh2_md5_ctx _libssh2_wincng_hash_ctx #define libssh2_md5_init(ctx) \ (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \ MD5_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_md5_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, \ (const unsigned char *) data, \ (unsigned long) datalen) #define libssh2_md5_final(ctx, hash) \ _libssh2_wincng_hash_final(&ctx, hash) #define libssh2_md5(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \ hash, MD5_DIGEST_LENGTH) /* * Windows CNG backend: HMAC functions */ #define libssh2_hmac_ctx _libssh2_wincng_hash_ctx #define libssh2_hmac_ctx_init(ctx) #define libssh2_hmac_sha1_init(ctx, key, keylen) \ _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \ SHA_DIGEST_LENGTH, \ key, (unsigned long) keylen) #define libssh2_hmac_md5_init(ctx, key, keylen) \ _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \ MD5_DIGEST_LENGTH, \ key, (unsigned long) keylen) #define libssh2_hmac_ripemd160_init(ctx, key, keylen) /* not implemented */ #define libssh2_hmac_sha256_init(ctx, key, keylen) \ _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA256, \ SHA256_DIGEST_LENGTH, \ key, (unsigned long) keylen) #define libssh2_hmac_sha512_init(ctx, key, keylen) \ _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA512, \ SHA512_DIGEST_LENGTH, \ key, (unsigned long) keylen) #define libssh2_hmac_update(ctx, data, datalen) \ _libssh2_wincng_hash_update(&ctx, \ (const unsigned char *) data, \ (unsigned long) datalen) #define libssh2_hmac_final(ctx, hash) \ _libssh2_wincng_hmac_final(&ctx, hash) #define libssh2_hmac_cleanup(ctx) \ _libssh2_wincng_hmac_cleanup(ctx) /*******************************************************************/ /* * Windows CNG backend: Key Context structure */ typedef struct __libssh2_wincng_key_ctx { BCRYPT_KEY_HANDLE hKey; void *pbKeyObject; unsigned long cbKeyObject; } _libssh2_wincng_key_ctx; /* * Windows CNG backend: RSA functions */ #define libssh2_rsa_ctx _libssh2_wincng_key_ctx #define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ d, d_len, p, p_len, q, q_len, \ e1, e1_len, e2, e2_len, c, c_len) \ _libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \ d, d_len, p, p_len, q, q_len, \ e1, e1_len, e2, e2_len, c, c_len) #define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ _libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase) #define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \ filedata_len, passphrase) \ _libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \ filedata_len, passphrase) #define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ _libssh2_wincng_rsa_sha_sign(s, rsactx, hash, hash_len, sig, sig_len) #define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \ _libssh2_wincng_rsa_sha_sign(s, rsactx, hash, hash_len, sig, sig_len) #define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ _libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) #define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \ _libssh2_wincng_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) #define _libssh2_rsa_free(rsactx) \ _libssh2_wincng_rsa_free(rsactx) /* * Windows CNG backend: DSA functions */ #define libssh2_dsa_ctx _libssh2_wincng_key_ctx #define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \ g, g_len, y, y_len, x, x_len) \ _libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \ g, g_len, y, y_len, x, x_len) #define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \ _libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase) #define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \ filedata_len, passphrase) \ _libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \ filedata_len, passphrase) #define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \ _libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig) #define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \ _libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len) #define _libssh2_dsa_free(dsactx) \ _libssh2_wincng_dsa_free(dsactx) /* * Windows CNG backend: Key functions */ #define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ _libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) #define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ pk, pk_len, pw) \ _libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ pk, pk_len, pw) #define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \ f, kh, kh_len, pk, pk_len, pw) \ _libssh2_wincng_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \ f, kh, kh_len, pk, pk_len, pw) /*******************************************************************/ /* * Windows CNG backend: Cipher Context structure */ struct _libssh2_wincng_cipher_ctx { BCRYPT_KEY_HANDLE hKey; unsigned char *pbKeyObject; unsigned char *pbIV; unsigned char *pbCtr; unsigned long dwKeyObject; unsigned long dwIV; unsigned long dwBlockLength; unsigned long dwCtrLength; }; #define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx /* * Windows CNG backend: Cipher Type structure */ struct _libssh2_wincng_cipher_type { BCRYPT_ALG_HANDLE *phAlg; unsigned long dwKeyLength; int useIV; /* TODO: Convert to bool when a C89 compatible bool type is defined */ int ctrMode; }; #define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type #define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 } #define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 } #define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 } #define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 } #define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 } #define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 } #define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 } #define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 } /* * Windows CNG backend: Cipher functions */ #define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ _libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt) #define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \ _libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) #define _libssh2_cipher_dtor(ctx) \ _libssh2_wincng_cipher_dtor(ctx) /*******************************************************************/ /* * Windows CNG backend: BigNumber Context */ #define _libssh2_bn_ctx int /* not used */ #define _libssh2_bn_ctx_new() 0 /* not used */ #define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ /*******************************************************************/ /* * Windows CNG backend: BigNumber structure */ struct _libssh2_wincng_bignum { unsigned char *bignum; unsigned long length; }; #define _libssh2_bn struct _libssh2_wincng_bignum /* * Windows CNG backend: BigNumber functions */ _libssh2_bn *_libssh2_wincng_bignum_init(void); #define _libssh2_bn_init() \ _libssh2_wincng_bignum_init() #define _libssh2_bn_init_from_bin() \ _libssh2_bn_init() #define _libssh2_bn_set_word(bn, word) \ _libssh2_wincng_bignum_set_word(bn, word) #define _libssh2_bn_from_bin(bn, len, bin) \ _libssh2_wincng_bignum_from_bin(bn, (unsigned long) len, bin) #define _libssh2_bn_to_bin(bn, bin) \ _libssh2_wincng_bignum_to_bin(bn, bin) #define _libssh2_bn_bytes(bn) bn->length #define _libssh2_bn_bits(bn) \ _libssh2_wincng_bignum_bits(bn) #define _libssh2_bn_free(bn) \ _libssh2_wincng_bignum_free(bn) /* * Windows CNG backend: Diffie-Hellman support */ /* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ #define LIBSSH2_DH_GEX_MINGROUP 2048 #define LIBSSH2_DH_GEX_OPTGROUP 4096 #define LIBSSH2_DH_GEX_MAXGROUP 8192 #define LIBSSH2_DH_MAX_MODULUS_BITS 16384 typedef struct { /* holds our private and public key components */ BCRYPT_KEY_HANDLE dh_handle; /* records the parsed out modulus and generator * parameters that are shared with the peer */ BCRYPT_DH_PARAMETER_HEADER *dh_params; /* records the parsed out private key component for * fallback if the DH API raw KDF is not supported */ struct _libssh2_wincng_bignum *dh_privbn; } _libssh2_dh_ctx; #define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) #define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ _libssh2_dh_key_pair(dhctx, public, g, p, group_order) #define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ _libssh2_dh_secret(dhctx, secret, f, p) #define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) /*******************************************************************/ /* * Windows CNG backend: forward declarations */ void _libssh2_wincng_init(void); void _libssh2_wincng_free(void); int _libssh2_wincng_random(void *buf, size_t len); int _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, unsigned char *key, unsigned long keylen); int _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, const unsigned char *data, unsigned long datalen); int _libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, unsigned char *hash); int _libssh2_wincng_hash(const unsigned char *data, unsigned long datalen, BCRYPT_ALG_HANDLE hAlg, unsigned char *hash, unsigned long hashlen); int _libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, unsigned char *hash); void _libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx); int _libssh2_wincng_key_sha_verify(_libssh2_wincng_key_ctx *ctx, unsigned long hashlen, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, unsigned long flags); int _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen); int _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase); int _libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); int _libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len); int _libssh2_wincng_rsa_sha_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); void _libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa); #if LIBSSH2_DSA int _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *gdata, unsigned long glen, const unsigned char *ydata, unsigned long ylen, const unsigned char *xdata, unsigned long xlen); int _libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase); int _libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); int _libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, const unsigned char *sig_fixed, const unsigned char *m, size_t m_len); int _libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, const unsigned char *hash, unsigned long hash_len, unsigned char *sig_fixed); void _libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa); #endif int _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase); int _libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase); int _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), unsigned char *iv, unsigned char *secret, int encrypt); int _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), int encrypt, unsigned char *block, size_t blocklen, int firstlast); void _libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx); _libssh2_bn * _libssh2_wincng_bignum_init(void); int _libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word); unsigned long _libssh2_wincng_bignum_bits(const _libssh2_bn *bn); void _libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, const unsigned char *bin); void _libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin); void _libssh2_wincng_bignum_free(_libssh2_bn *bn); extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx); extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order); extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p); extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); #endif /* __LIBSSH2_WINCNG_H */ libssh2-1.11.0/src/sftp.c0000644000175000017500000040410314432741311011772 00000000000000/* Copyright (c) 2004-2008, Sara Golemon * Copyright (c) 2007 Eli Fant * Copyright (c) 2009-2019 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "libssh2_sftp.h" #include "channel.h" #include "session.h" #include "sftp.h" #include /* This release of libssh2 implements Version 5 with automatic downgrade * based on server's declaration * https://www.ietf.org/archive/id/draft-ietf-secsh-filexfer-05.txt * * Version 6: * https://www.ietf.org/archive/id/draft-ietf-secsh-filexfer-13.txt */ /* SFTP packet types */ #define SSH_FXP_INIT 1 #define SSH_FXP_VERSION 2 #define SSH_FXP_OPEN 3 #define SSH_FXP_CLOSE 4 #define SSH_FXP_READ 5 #define SSH_FXP_WRITE 6 #define SSH_FXP_LSTAT 7 #define SSH_FXP_FSTAT 8 #define SSH_FXP_SETSTAT 9 #define SSH_FXP_FSETSTAT 10 #define SSH_FXP_OPENDIR 11 #define SSH_FXP_READDIR 12 #define SSH_FXP_REMOVE 13 #define SSH_FXP_MKDIR 14 #define SSH_FXP_RMDIR 15 #define SSH_FXP_REALPATH 16 #define SSH_FXP_STAT 17 #define SSH_FXP_RENAME 18 #define SSH_FXP_READLINK 19 #define SSH_FXP_SYMLINK 20 #define SSH_FXP_STATUS 101 #define SSH_FXP_HANDLE 102 #define SSH_FXP_DATA 103 #define SSH_FXP_NAME 104 #define SSH_FXP_ATTRS 105 #define SSH_FXP_EXTENDED 200 #define SSH_FXP_EXTENDED_REPLY 201 /* S_IFREG */ #define LIBSSH2_SFTP_ATTR_PFILETYPE_FILE 0100000 /* S_IFDIR */ #define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000 #define SSH_FXE_STATVFS_ST_RDONLY 0x00000001 #define SSH_FXE_STATVFS_ST_NOSUID 0x00000002 /* This is the maximum packet length to accept, as larger than this indicate some kind of server problem. */ #define LIBSSH2_SFTP_PACKET_MAXLEN (256 * 1024) static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, uint32_t request_id, unsigned char **data, size_t *data_len); static void sftp_packet_flush(LIBSSH2_SFTP *sftp); /* _libssh2_store_u64 */ static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value) { uint32_t msl = (uint32_t)(value >> 32); unsigned char *buf = *ptr; buf[0] = (unsigned char)((msl >> 24) & 0xFF); buf[1] = (unsigned char)((msl >> 16) & 0xFF); buf[2] = (unsigned char)((msl >> 8) & 0xFF); buf[3] = (unsigned char)( msl & 0xFF); buf[4] = (unsigned char)((value >> 24) & 0xFF); buf[5] = (unsigned char)((value >> 16) & 0xFF); buf[6] = (unsigned char)((value >> 8) & 0xFF); buf[7] = (unsigned char)( value & 0xFF); *ptr += 8; } /* * Search list of zombied FXP_READ request IDs. * * Returns NULL if ID not in list. */ static struct sftp_zombie_requests * find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) { struct sftp_zombie_requests *zombie = _libssh2_list_first(&sftp->zombie_requests); while(zombie) { if(zombie->request_id == request_id) break; else zombie = _libssh2_list_next(&zombie->node); } return zombie; } static void remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) { LIBSSH2_SESSION *session = sftp->channel->session; struct sftp_zombie_requests *zombie = find_zombie_request(sftp, request_id); if(zombie) { _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Removing request ID %ld from the list of " "zombie requests", request_id)); _libssh2_list_remove(&zombie->node); LIBSSH2_FREE(session, zombie); } } static int add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) { LIBSSH2_SESSION *session = sftp->channel->session; struct sftp_zombie_requests *zombie; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Marking request ID %ld as a zombie request", request_id)); zombie = LIBSSH2_ALLOC(sftp->channel->session, sizeof(struct sftp_zombie_requests)); if(!zombie) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "malloc fail for zombie request ID"); else { zombie->request_id = request_id; _libssh2_list_add(&sftp->zombie_requests, &zombie->node); return LIBSSH2_ERROR_NONE; } } /* sftp_packet_add * Add a packet to the SFTP packet brigade */ static int sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, size_t data_len) { LIBSSH2_SESSION *session = sftp->channel->session; LIBSSH2_SFTP_PACKET *packet; uint32_t request_id; if(data_len < 5) { return LIBSSH2_ERROR_OUT_OF_BOUNDARY; } _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Received packet type %d (len %d)", (int) data[0], data_len)); /* * Experience shows that if we mess up EAGAIN handling somewhere or * otherwise get out of sync with the channel, this is where we first get * a wrong byte and if so we need to bail out at once to aid tracking the * problem better. */ switch(data[0]) { case SSH_FXP_INIT: case SSH_FXP_VERSION: case SSH_FXP_OPEN: case SSH_FXP_CLOSE: case SSH_FXP_READ: case SSH_FXP_WRITE: case SSH_FXP_LSTAT: case SSH_FXP_FSTAT: case SSH_FXP_SETSTAT: case SSH_FXP_FSETSTAT: case SSH_FXP_OPENDIR: case SSH_FXP_READDIR: case SSH_FXP_REMOVE: case SSH_FXP_MKDIR: case SSH_FXP_RMDIR: case SSH_FXP_REALPATH: case SSH_FXP_STAT: case SSH_FXP_RENAME: case SSH_FXP_READLINK: case SSH_FXP_SYMLINK: case SSH_FXP_STATUS: case SSH_FXP_HANDLE: case SSH_FXP_DATA: case SSH_FXP_NAME: case SSH_FXP_ATTRS: case SSH_FXP_EXTENDED: case SSH_FXP_EXTENDED_REPLY: break; default: sftp->last_errno = LIBSSH2_FX_OK; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Out of sync with the world"); } request_id = _libssh2_ntohu32(&data[1]); _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Received packet id %d", request_id)); /* Don't add the packet if it answers a request we've given up on. */ if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA) && find_zombie_request(sftp, request_id)) { /* If we get here, the file ended before the response arrived. We are no longer interested in the request so we discard it */ LIBSSH2_FREE(session, data); remove_zombie_request(sftp, request_id); return LIBSSH2_ERROR_NONE; } packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET)); if(!packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate datablock for SFTP packet"); } packet->data = data; packet->data_len = data_len; packet->request_id = request_id; _libssh2_list_add(&sftp->packets, &packet->node); return LIBSSH2_ERROR_NONE; } /* sftp_packet_read * Frame an SFTP packet off the channel */ static int sftp_packet_read(LIBSSH2_SFTP *sftp) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; unsigned char *packet = NULL; ssize_t rc; unsigned long recv_window; int packet_type; uint32_t request_id; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "recv packet")); switch(sftp->packet_state) { case libssh2_NB_state_sent: /* EAGAIN from window adjusting */ sftp->packet_state = libssh2_NB_state_idle; packet = sftp->partial_packet; goto window_adjust; case libssh2_NB_state_sent1: /* EAGAIN from channel read */ sftp->packet_state = libssh2_NB_state_idle; packet = sftp->partial_packet; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "partial read cont, len: %lu", sftp->partial_len)); _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "partial read cont, already recvd: %lu", sftp->partial_received)); /* fall-through */ default: if(!packet) { /* only do this if there's not already a packet buffer allocated to use */ /* each packet starts with a 32 bit length field */ rc = _libssh2_channel_read(channel, 0, (char *)&sftp->packet_header[ sftp->packet_header_len], sizeof(sftp->packet_header) - sftp->packet_header_len); if(rc == LIBSSH2_ERROR_EAGAIN) return (int)rc; else if(rc < 0) return _libssh2_error(session, (int)rc, "channel read"); sftp->packet_header_len += rc; if(sftp->packet_header_len != sizeof(sftp->packet_header)) /* we got a short read for the header part */ return LIBSSH2_ERROR_EAGAIN; /* parse SFTP packet header */ sftp->partial_len = _libssh2_ntohu32(sftp->packet_header); packet_type = sftp->packet_header[4]; request_id = _libssh2_ntohu32(sftp->packet_header + 5); /* make sure we don't proceed if the packet size is unreasonably large */ if(sftp->partial_len > LIBSSH2_SFTP_PACKET_MAXLEN && /* exception: response to SSH_FXP_READDIR request */ !(sftp->readdir_state != libssh2_NB_state_idle && sftp->readdir_request_id == request_id && packet_type == SSH_FXP_NAME)) { libssh2_channel_flush(channel); sftp->packet_header_len = 0; return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, "SFTP packet too large"); } if(sftp->partial_len < 5) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Invalid SFTP packet size"); _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Data begin - Packet Length: %lu", sftp->partial_len)); packet = LIBSSH2_ALLOC(session, sftp->partial_len); if(!packet) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate SFTP packet"); sftp->packet_header_len = 0; sftp->partial_packet = packet; /* copy over packet type(4) and request id(1) */ sftp->partial_received = 5; memcpy(packet, sftp->packet_header + 4, 5); window_adjust: recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); if(sftp->partial_len > recv_window) { /* ask for twice the data amount we need at once */ rc = _libssh2_channel_receive_window_adjust(channel, sftp->partial_len * 2, 1, NULL); /* store the state so that we continue with the correct operation at next invoke */ sftp->packet_state = (rc == LIBSSH2_ERROR_EAGAIN)? libssh2_NB_state_sent: libssh2_NB_state_idle; if(rc == LIBSSH2_ERROR_EAGAIN) return (int)rc; } } /* Read as much of the packet as we can */ while(sftp->partial_len > sftp->partial_received) { rc = _libssh2_channel_read(channel, 0, (char *)&packet[sftp->partial_received], sftp->partial_len - sftp->partial_received); if(rc == LIBSSH2_ERROR_EAGAIN) { /* * We received EAGAIN, save what we have and return EAGAIN to * the caller. Set 'partial_packet' so that this function * knows how to continue on the next invoke. */ sftp->packet_state = libssh2_NB_state_sent1; return (int)rc; } else if(rc < 0) { LIBSSH2_FREE(session, packet); sftp->partial_packet = NULL; return _libssh2_error(session, (int)rc, "Error waiting for SFTP packet"); } sftp->partial_received += rc; } sftp->partial_packet = NULL; /* sftp_packet_add takes ownership of the packet and might free it so we take a copy of the packet type before we call it. */ packet_type = packet[0]; rc = sftp_packet_add(sftp, packet, sftp->partial_len); if(rc) { LIBSSH2_FREE(session, packet); return (int)rc; } else { return packet_type; } } /* WON'T REACH */ } /* sftp_packetlist_flush * * Remove all pending packets in the packet_list and the corresponding one(s) * in the SFTP packet brigade. */ static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle) { struct sftp_pipeline_chunk *chunk; LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_SESSION *session = sftp->channel->session; /* remove pending packets, if any */ chunk = _libssh2_list_first(&handle->packet_list); while(chunk) { unsigned char *data; size_t data_len; int rc; struct sftp_pipeline_chunk *next = _libssh2_list_next(&chunk->node); rc = sftp_packet_ask(sftp, SSH_FXP_STATUS, chunk->request_id, &data, &data_len); if(rc) rc = sftp_packet_ask(sftp, SSH_FXP_DATA, chunk->request_id, &data, &data_len); if(!rc) /* we found a packet, free it */ LIBSSH2_FREE(session, data); else if(chunk->sent) /* there was no incoming packet for this request, mark this request as a zombie if it ever sent the request */ add_zombie_request(sftp, chunk->request_id); _libssh2_list_remove(&chunk->node); LIBSSH2_FREE(session, chunk); chunk = next; } } /* * sftp_packet_ask * * Checks if there's a matching SFTP packet available. */ static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, uint32_t request_id, unsigned char **data, size_t *data_len) { LIBSSH2_SESSION *session = sftp->channel->session; LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); if(!packet) return -1; /* Special consideration when getting VERSION packet */ while(packet) { if((packet->data[0] == packet_type) && ((packet_type == SSH_FXP_VERSION) || (packet->request_id == request_id))) { /* Match! Fetch the data */ *data = packet->data; *data_len = packet->data_len; /* unlink and free this struct */ _libssh2_list_remove(&packet->node); LIBSSH2_FREE(session, packet); return 0; } /* check next struct in the list */ packet = _libssh2_list_next(&packet->node); } return -1; } /* sftp_packet_require * A la libssh2_packet_require */ static int sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type, uint32_t request_id, unsigned char **data, size_t *data_len, size_t required_size) { LIBSSH2_SESSION *session = sftp->channel->session; int rc; if(!data || !data_len || required_size == 0) { return LIBSSH2_ERROR_BAD_USE; } _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld", (int) packet_type, request_id)); if(sftp_packet_ask(sftp, packet_type, request_id, data, data_len) == 0) { /* The right packet was available in the packet brigade */ _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Got %d", (int) packet_type)); if(*data_len < required_size) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } return LIBSSH2_ERROR_NONE; } while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { rc = sftp_packet_read(sftp); if(rc < 0) return rc; /* data was read, check the queue again */ if(!sftp_packet_ask(sftp, packet_type, request_id, data, data_len)) { /* The right packet was available in the packet brigade */ _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Got %d", (int) packet_type)); if(*data_len < required_size) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } return LIBSSH2_ERROR_NONE; } } /* Only reached if the socket died */ return LIBSSH2_ERROR_SOCKET_DISCONNECT; } /* sftp_packet_requirev * Require one of N possible responses */ static int sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses, const unsigned char *valid_responses, uint32_t request_id, unsigned char **data, size_t *data_len, size_t required_size) { int i; int rc; if(!data || !data_len || required_size == 0) { return LIBSSH2_ERROR_BAD_USE; } /* If no timeout is active, start a new one */ if(sftp->requirev_start == 0) sftp->requirev_start = time(NULL); while(sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) { for(i = 0; i < num_valid_responses; i++) { if(sftp_packet_ask(sftp, valid_responses[i], request_id, data, data_len) == 0) { /* * Set to zero before all returns to say * the timeout is not active */ sftp->requirev_start = 0; if(*data_len < required_size) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } return LIBSSH2_ERROR_NONE; } } rc = sftp_packet_read(sftp); if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { sftp->requirev_start = 0; return rc; } else if(rc <= 0) { /* prevent busy-looping */ long left = sftp->channel->session->packet_read_timeout - (long)(time(NULL) - sftp->requirev_start); if(left <= 0) { sftp->requirev_start = 0; return LIBSSH2_ERROR_TIMEOUT; } else if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } } } sftp->requirev_start = 0; /* Only reached if the socket died */ return LIBSSH2_ERROR_SOCKET_DISCONNECT; } /* sftp_attrsize * Size that attr with this flagset will occupy when turned into a bin struct */ static int sftp_attrsize(unsigned long flags) { return 4 + /* flags(4) */ ((flags & LIBSSH2_SFTP_ATTR_SIZE) ? 8 : 0) + ((flags & LIBSSH2_SFTP_ATTR_UIDGID) ? 8 : 0) + ((flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) ? 4 : 0) + ((flags & LIBSSH2_SFTP_ATTR_ACMODTIME) ? 8 : 0); /* atime + mtime as u32 */ } /* sftp_attr2bin * Populate attributes into an SFTP block */ static ssize_t sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs) { unsigned char *s = p; uint32_t flag_mask = LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID | LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME; /* TODO: When we add SFTP4+ functionality flag_mask can get additional bits */ if(!attrs) { _libssh2_htonu32(s, 0); return 4; } _libssh2_store_u32(&s, (uint32_t)(attrs->flags & flag_mask)); if(attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { _libssh2_store_u64(&s, attrs->filesize); } if(attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { _libssh2_store_u32(&s, (uint32_t)attrs->uid); _libssh2_store_u32(&s, (uint32_t)attrs->gid); } if(attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { _libssh2_store_u32(&s, (uint32_t)attrs->permissions); } if(attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { _libssh2_store_u32(&s, (uint32_t)attrs->atime); _libssh2_store_u32(&s, (uint32_t)attrs->mtime); } return s - p; } /* sftp_bin2attr */ static ssize_t sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES *attrs, const unsigned char *p, size_t data_len) { struct string_buf buf; uint32_t flags = 0; buf.data = (unsigned char *)p; buf.dataptr = buf.data; buf.len = data_len; if(_libssh2_get_u32(&buf, &flags)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } attrs->flags = flags; if(attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { if(_libssh2_get_u64(&buf, &(attrs->filesize))) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } } if(attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { uint32_t uid = 0; uint32_t gid = 0; if(_libssh2_get_u32(&buf, &uid) || _libssh2_get_u32(&buf, &gid)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } attrs->uid = uid; attrs->gid = gid; } if(attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { uint32_t permissions; if(_libssh2_get_u32(&buf, &permissions)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } attrs->permissions = permissions; } if(attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { uint32_t atime; uint32_t mtime; if(_libssh2_get_u32(&buf, &atime) || _libssh2_get_u32(&buf, &mtime)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } attrs->atime = atime; attrs->mtime = mtime; } /* Parse extended data, if present, to avoid stream parsing errors */ if(attrs->flags & LIBSSH2_SFTP_ATTR_EXTENDED) { uint32_t extended_count; uint32_t i; size_t etype_len; unsigned char *etype; size_t edata_len; unsigned char *edata; if(_libssh2_get_u32(&buf, &extended_count)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } for(i = 0; i < extended_count; ++i) { if(_libssh2_get_string(&buf, &etype, &etype_len) || _libssh2_get_string(&buf, &edata, &edata_len)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } } } return buf.dataptr - buf.data; } /* ************ * SFTP API * ************ */ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor); /* libssh2_sftp_dtor * Shutdown an SFTP stream when the channel closes */ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor) { LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP *) (*channel_abstract); (void)session_abstract; (void)channel; /* Free the partial packet storage for sftp_packet_read */ if(sftp->partial_packet) { LIBSSH2_FREE(session, sftp->partial_packet); } /* Free the packet storage for _libssh2_sftp_packet_readdir */ if(sftp->readdir_packet) { LIBSSH2_FREE(session, sftp->readdir_packet); } LIBSSH2_FREE(session, sftp); } /* sftp_init * Startup an SFTP session */ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session) { unsigned char *data; size_t data_len = 0; ssize_t rc; LIBSSH2_SFTP *sftp_handle; struct string_buf buf; unsigned char *endp; if(session->sftpInit_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Initializing SFTP subsystem")); /* * The 'sftpInit_sftp' and 'sftpInit_channel' struct fields within the * session struct are only to be used during the setup phase. As soon * as the SFTP session is created they are cleared and can thus be * re-used again to allow any amount of SFTP handles per sessions. * * Note that you MUST NOT try to call libssh2_sftp_init() again to get * another handle until the previous call has finished and either * successfully made a handle or failed and returned error (not * including *EAGAIN). */ assert(!session->sftpInit_sftp); session->sftpInit_sftp = NULL; session->sftpInit_state = libssh2_NB_state_created; } sftp_handle = session->sftpInit_sftp; if(session->sftpInit_state == libssh2_NB_state_created) { session->sftpInit_channel = _libssh2_channel_open(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if(!session->sftpInit_channel) { if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel"); } else { _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel"); session->sftpInit_state = libssh2_NB_state_idle; } return NULL; } session->sftpInit_state = libssh2_NB_state_sent; } if(session->sftpInit_state == libssh2_NB_state_sent) { int ret = _libssh2_channel_process_startup(session->sftpInit_channel, "subsystem", sizeof("subsystem") - 1, "sftp", strlen("sftp")); if(ret == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block to request SFTP subsystem"); return NULL; } else if(ret) { _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request SFTP subsystem"); goto sftp_init_error; } session->sftpInit_state = libssh2_NB_state_sent1; } if(session->sftpInit_state == libssh2_NB_state_sent1) { rc = _libssh2_channel_extended_data(session->sftpInit_channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting handle extended data"); return NULL; } sftp_handle = session->sftpInit_sftp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP)); if(!sftp_handle) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new SFTP structure"); goto sftp_init_error; } sftp_handle->channel = session->sftpInit_channel; sftp_handle->request_id = 0; _libssh2_htonu32(session->sftpInit_buffer, 5); session->sftpInit_buffer[4] = SSH_FXP_INIT; _libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION); session->sftpInit_sent = 0; /* nothing's sent yet */ _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Sending FXP_INIT packet advertising " "version %d support", (int) LIBSSH2_SFTP_VERSION)); session->sftpInit_state = libssh2_NB_state_sent2; } if(session->sftpInit_state == libssh2_NB_state_sent2) { /* sent off what's left of the init buffer to send */ rc = _libssh2_channel_write(session->sftpInit_channel, 0, session->sftpInit_buffer + session->sftpInit_sent, 9 - session->sftpInit_sent); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SSH_FXP_INIT"); return NULL; } else if(rc < 0) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send SSH_FXP_INIT"); goto sftp_init_error; } else { /* add up the number of bytes sent */ session->sftpInit_sent += rc; if(session->sftpInit_sent == 9) /* move on */ session->sftpInit_state = libssh2_NB_state_sent3; /* if less than 9, we remain in this state to send more later on */ } } if(session->sftpInit_state == libssh2_NB_state_error_closing) { rc = _libssh2_channel_free(session->sftpInit_channel); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block closing channel"); return NULL; } session->sftpInit_channel = NULL; if(session->sftpInit_sftp) { LIBSSH2_FREE(session, session->sftpInit_sftp); session->sftpInit_sftp = NULL; } session->sftpInit_state = libssh2_NB_state_idle; return NULL; } rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION, 0, &data, &data_len, 5); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block receiving SSH_FXP_VERSION"); return NULL; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Invalid SSH_FXP_VERSION response"); goto sftp_init_error; } else if(rc) { _libssh2_error(session, (int)rc, "Timeout waiting for response from SFTP subsystem"); goto sftp_init_error; } buf.data = data; buf.dataptr = buf.data + 1; buf.len = data_len; endp = &buf.data[data_len]; if(_libssh2_get_u32(&buf, &(sftp_handle->version))) { LIBSSH2_FREE(session, data); rc = LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto sftp_init_error; } if(sftp_handle->version > LIBSSH2_SFTP_VERSION) { _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Truncating remote SFTP version from %lu", sftp_handle->version)); sftp_handle->version = LIBSSH2_SFTP_VERSION; } _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Enabling SFTP version %lu compatibility", sftp_handle->version)); while(buf.dataptr < endp) { unsigned char *extname, *extdata; if(_libssh2_get_string(&buf, &extname, NULL)) { LIBSSH2_FREE(session, data); _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short when extracting extname"); goto sftp_init_error; } if(_libssh2_get_string(&buf, &extdata, NULL)) { LIBSSH2_FREE(session, data); _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short when extracting extdata"); goto sftp_init_error; } } LIBSSH2_FREE(session, data); /* Make sure that when the channel gets closed, the SFTP service is shut down too */ sftp_handle->channel->abstract = sftp_handle; sftp_handle->channel->close_cb = libssh2_sftp_dtor; session->sftpInit_state = libssh2_NB_state_idle; /* clear the sftp and channel pointers in this session struct now */ session->sftpInit_sftp = NULL; session->sftpInit_channel = NULL; _libssh2_list_init(&sftp_handle->sftp_handles); return sftp_handle; sftp_init_error: session->sftpInit_state = libssh2_NB_state_error_closing; return NULL; } /* libssh2_sftp_init * Startup an SFTP session */ LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session) { LIBSSH2_SFTP *ptr; if(!session) return NULL; if(!(session->state & LIBSSH2_STATE_AUTHENTICATED)) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "session not authenticated yet"); return NULL; } BLOCK_ADJUST_ERRNO(ptr, session, sftp_init(session)); return ptr; } /* sftp_shutdown * Shuts down the SFTP subsystem */ static int sftp_shutdown(LIBSSH2_SFTP *sftp) { int rc; LIBSSH2_SESSION *session = sftp->channel->session; /* * Make sure all memory used in the state variables are free */ if(sftp->partial_packet) { LIBSSH2_FREE(session, sftp->partial_packet); sftp->partial_packet = NULL; } if(sftp->open_packet) { LIBSSH2_FREE(session, sftp->open_packet); sftp->open_packet = NULL; } if(sftp->readdir_packet) { LIBSSH2_FREE(session, sftp->readdir_packet); sftp->readdir_packet = NULL; } if(sftp->fstat_packet) { LIBSSH2_FREE(session, sftp->fstat_packet); sftp->fstat_packet = NULL; } if(sftp->unlink_packet) { LIBSSH2_FREE(session, sftp->unlink_packet); sftp->unlink_packet = NULL; } if(sftp->rename_packet) { LIBSSH2_FREE(session, sftp->rename_packet); sftp->rename_packet = NULL; } if(sftp->fstatvfs_packet) { LIBSSH2_FREE(session, sftp->fstatvfs_packet); sftp->fstatvfs_packet = NULL; } if(sftp->statvfs_packet) { LIBSSH2_FREE(session, sftp->statvfs_packet); sftp->statvfs_packet = NULL; } if(sftp->mkdir_packet) { LIBSSH2_FREE(session, sftp->mkdir_packet); sftp->mkdir_packet = NULL; } if(sftp->rmdir_packet) { LIBSSH2_FREE(session, sftp->rmdir_packet); sftp->rmdir_packet = NULL; } if(sftp->stat_packet) { LIBSSH2_FREE(session, sftp->stat_packet); sftp->stat_packet = NULL; } if(sftp->symlink_packet) { LIBSSH2_FREE(session, sftp->symlink_packet); sftp->symlink_packet = NULL; } if(sftp->fsync_packet) { LIBSSH2_FREE(session, sftp->fsync_packet); sftp->fsync_packet = NULL; } sftp_packet_flush(sftp); /* TODO: We should consider walking over the sftp_handles list and kill * any remaining sftp handles ... */ rc = _libssh2_channel_free(sftp->channel); return rc; } /* libssh2_sftp_shutdown * Shutsdown the SFTP subsystem */ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_shutdown(sftp)); return rc; } /* ******************************* * SFTP File and Directory Ops * ******************************* */ /* sftp_open */ static LIBSSH2_SFTP_HANDLE * sftp_open(LIBSSH2_SFTP *sftp, const char *filename, size_t filename_len, uint32_t flags, long mode, int open_type, LIBSSH2_SFTP_ATTRIBUTES *attrs_in) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; LIBSSH2_SFTP_HANDLE *fp; LIBSSH2_SFTP_ATTRIBUTES attrs = { LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 }; unsigned char *s; ssize_t rc; int open_file = (open_type == LIBSSH2_SFTP_OPENFILE) ? 1 : 0; if(sftp->open_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; if(attrs_in) { memcpy(&attrs, attrs_in, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); } /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + flags(4) */ sftp->open_packet_len = (uint32_t)(filename_len + 13 + (open_file? (4 + sftp_attrsize(attrs.flags)) : 0)); /* surprise! this starts out with nothing sent */ sftp->open_packet_sent = 0; s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len); if(!sftp->open_packet) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_OPEN or " "FXP_OPENDIR packet"); return NULL; } /* Filetype in SFTP 3 and earlier */ attrs.permissions = mode | (open_file ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); _libssh2_store_u32(&s, sftp->open_packet_len - 4); *(s++) = open_file? SSH_FXP_OPEN : SSH_FXP_OPENDIR; sftp->open_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->open_request_id); _libssh2_store_str(&s, filename, filename_len); if(open_file) { _libssh2_store_u32(&s, flags); s += sftp_attr2bin(s, &attrs); } _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Sending %s open request", open_file? "file" : "directory")); sftp->open_state = libssh2_NB_state_created; } if(sftp->open_state == libssh2_NB_state_created) { rc = _libssh2_channel_write(channel, 0, sftp->open_packet+ sftp->open_packet_sent, sftp->open_packet_len - sftp->open_packet_sent); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending FXP_OPEN or " "FXP_OPENDIR command"); return NULL; } else if(rc < 0) { _libssh2_error(session, (int)rc, "Unable to send FXP_OPEN*"); LIBSSH2_FREE(session, sftp->open_packet); sftp->open_packet = NULL; sftp->open_state = libssh2_NB_state_idle; return NULL; } /* bump the sent counter and remain in this state until the whole data is off */ sftp->open_packet_sent += rc; if(sftp->open_packet_len == sftp->open_packet_sent) { LIBSSH2_FREE(session, sftp->open_packet); sftp->open_packet = NULL; sftp->open_state = libssh2_NB_state_sent; } } if(sftp->open_state == libssh2_NB_state_sent) { size_t data_len = 0; unsigned char *data; static const unsigned char fopen_responses[2] = { SSH_FXP_HANDLE, SSH_FXP_STATUS }; rc = sftp_packet_requirev(sftp, 2, fopen_responses, sftp->open_request_id, &data, &data_len, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for status message"); return NULL; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Response too small"); return NULL; } sftp->open_state = libssh2_NB_state_idle; if(rc) { _libssh2_error(session, (int)rc, "Timeout waiting for status message"); return NULL; } /* OPEN can basically get STATUS or HANDLE back, where HANDLE implies a fine response while STATUS means error. It seems though that at times we get an SSH_FX_OK back in a STATUS, followed the "real" HANDLE so we need to properly deal with that. */ if(data[0] == SSH_FXP_STATUS) { int badness = 1; if(data_len < 9) { _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Too small FXP_STATUS"); LIBSSH2_FREE(session, data); return NULL; } sftp->last_errno = _libssh2_ntohu32(data + 5); if(LIBSSH2_FX_OK == sftp->last_errno) { _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "got HANDLE FXOK!")); LIBSSH2_FREE(session, data); /* silly situation, but check for a HANDLE */ rc = sftp_packet_require(sftp, SSH_FXP_HANDLE, sftp->open_request_id, &data, &data_len, 10); if(rc == LIBSSH2_ERROR_EAGAIN) { /* go back to sent state and wait for something else */ sftp->open_state = libssh2_NB_state_sent; return NULL; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Too small FXP_HANDLE"); return NULL; } else if(!rc) /* we got the handle so this is not a bad situation */ badness = 0; } if(badness) { _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Failed opening remote file"); _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "got FXP_STATUS %d", sftp->last_errno)); LIBSSH2_FREE(session, data); return NULL; } } if(data_len < 10) { _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Too small FXP_HANDLE"); LIBSSH2_FREE(session, data); return NULL; } fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE)); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate new SFTP handle structure"); LIBSSH2_FREE(session, data); return NULL; } fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE : LIBSSH2_SFTP_HANDLE_DIR; fp->handle_len = _libssh2_ntohu32(data + 5); if(fp->handle_len > SFTP_HANDLE_MAXLEN) /* SFTP doesn't allow handles longer than 256 characters */ fp->handle_len = SFTP_HANDLE_MAXLEN; if(fp->handle_len > (data_len - 9)) /* do not reach beyond the end of the data we got */ fp->handle_len = data_len - 9; memcpy(fp->handle, data + 9, fp->handle_len); LIBSSH2_FREE(session, data); /* add this file handle to the list kept in the sftp session */ _libssh2_list_add(&sftp->sftp_handles, &fp->node); fp->sftp = sftp; /* point to the parent struct */ fp->u.file.offset = 0; fp->u.file.offset_sent = 0; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Open command successful")); return fp; } return NULL; } /* libssh2_sftp_open_ex */ LIBSSH2_API LIBSSH2_SFTP_HANDLE * libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type) { LIBSSH2_SFTP_HANDLE *hnd; if(!sftp) return NULL; BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session, sftp_open(sftp, filename, filename_len, (uint32_t)flags, mode, open_type, NULL)); return hnd; } /* libssh2_sftp_open_ex_r */ LIBSSH2_API LIBSSH2_SFTP_HANDLE * libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp, const char *filename, size_t filename_len, unsigned long flags, long mode, int open_type, LIBSSH2_SFTP_ATTRIBUTES *attrs) { LIBSSH2_SFTP_HANDLE *hnd; if(!sftp) return NULL; BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session, sftp_open(sftp, filename, filename_len, (uint32_t)flags, mode, open_type, attrs)); return hnd; } /* sftp_read * Read from an SFTP file handle */ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer, size_t buffer_size) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t count = 0; struct sftp_pipeline_chunk *chunk; struct sftp_pipeline_chunk *next; ssize_t rc; struct _libssh2_sftp_handle_file_data *filep = &handle->u.file; size_t bytes_in_buffer = 0; char *sliding_bufferp = buffer; /* This function can be interrupted in three different places where it might need to wait for data from the network. It returns EAGAIN to allow non-blocking clients to do other work but these client are expected to call this function again (possibly many times) to finish the operation. The tricky part is that if we previously aborted a sftp_read due to EAGAIN, we must continue at the same spot to continue the previously interrupted operation. This is done using a state machine to record what phase of execution we were at. The state is stored in sftp->read_state. libssh2_NB_state_idle: The first phase is where we prepare multiple FXP_READ packets to do optimistic read-ahead. We send off as many as possible in the second phase without waiting for a response to each one; this is the key to fast reads. But we may have to adjust the channel window size to do this which may interrupt this function while waiting. The state machine saves the phase as libssh2_NB_state_idle so it returns here on the next call. libssh2_NB_state_sent: The second phase is where we send the FXP_READ packets. Writing them to the channel can be interrupted with EAGAIN but the state machine ensures we skip the first phase on the next call and resume sending. libssh2_NB_state_sent2: In the third phase (indicated by ) we read the data from the responses that have arrived so far. Reading can be interrupted with EAGAIN but the state machine ensures we skip the first and second phases on the next call and resume sending. */ switch(sftp->read_state) { case libssh2_NB_state_idle: sftp->last_errno = LIBSSH2_FX_OK; /* Some data may already have been read from the server in the previous call but didn't fit in the buffer at the time. If so, we return that now as we can't risk being interrupted later with data partially written to the buffer. */ if(filep->data_left) { size_t copy = LIBSSH2_MIN(buffer_size, filep->data_left); memcpy(buffer, &filep->data[ filep->data_len - filep->data_left], copy); filep->data_left -= copy; filep->offset += copy; if(!filep->data_left) { LIBSSH2_FREE(session, filep->data); filep->data = NULL; } return copy; } if(filep->eof) { return 0; } else { /* We allow a number of bytes being requested at any given time without having been acked - until we reach EOF. */ /* Number of bytes asked for that haven't been acked yet */ size_t already = (size_t)(filep->offset_sent - filep->offset); size_t max_read_ahead = buffer_size*4; unsigned long recv_window; if(max_read_ahead > LIBSSH2_CHANNEL_WINDOW_DEFAULT*4) max_read_ahead = LIBSSH2_CHANNEL_WINDOW_DEFAULT*4; /* if the buffer_size passed in now is smaller than what has already been sent, we risk getting count become a very large number */ if(max_read_ahead > already) count = max_read_ahead - already; /* 'count' is how much more data to ask for, and 'already' is how much data that already has been asked for but not yet returned. Specifically, 'count' means how much data that have or will be asked for by the nodes that are already added to the linked list. Some of those read requests may not actually have been sent off successfully yet. If 'already' is very large it should be perfectly fine to have count set to 0 as then we don't have to ask for more data (right now). buffer_size*4 is just picked more or less out of the air. The idea is that when reading SFTP from a remote server, we send away multiple read requests guessing that the client will read more than only this 'buffer_size' amount of memory. So we ask for maximum buffer_size*4 amount of data so that we can return them very fast in subsequent calls. */ recv_window = libssh2_channel_window_read_ex(sftp->channel, NULL, NULL); if(max_read_ahead > recv_window) { /* more data will be asked for than what the window currently allows, expand it! */ rc = _libssh2_channel_receive_window_adjust(sftp->channel, (uint32_t)(max_read_ahead * 8), 1, NULL); /* if this returns EAGAIN, we will get back to this function at next call */ assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->data_left); assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->eof); if(rc) return rc; } } while(count > 0) { unsigned char *s; /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + count(4) */ uint32_t packet_len = (uint32_t)(handle->handle_len + 25); uint32_t request_id; uint32_t size = (uint32_t)count; if(size < buffer_size) size = (uint32_t)buffer_size; if(size > MAX_SFTP_READ_SIZE) size = MAX_SFTP_READ_SIZE; chunk = LIBSSH2_ALLOC(session, packet_len + sizeof(struct sftp_pipeline_chunk)); if(!chunk) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "malloc fail for FXP_WRITE"); chunk->offset = filep->offset_sent; chunk->len = size; chunk->lefttosend = packet_len; chunk->sent = 0; s = chunk->packet; _libssh2_store_u32(&s, packet_len - 4); *s++ = SSH_FXP_READ; request_id = sftp->request_id++; chunk->request_id = request_id; _libssh2_store_u32(&s, request_id); _libssh2_store_str(&s, handle->handle, handle->handle_len); _libssh2_store_u64(&s, filep->offset_sent); filep->offset_sent += size; /* advance offset at once */ _libssh2_store_u32(&s, size); /* add this new entry LAST in the list */ _libssh2_list_add(&handle->packet_list, &chunk->node); /* deduct the size we used, as we might have to create more packets */ count -= LIBSSH2_MIN(size, count); _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "read request id %d sent (offset: %d, size: %d)", request_id, (int)chunk->offset, (int)chunk->len)); } /* FALL-THROUGH */ case libssh2_NB_state_sent: sftp->read_state = libssh2_NB_state_idle; /* move through the READ packets that haven't been sent and send as many as possible - remember that we don't block */ chunk = _libssh2_list_first(&handle->packet_list); while(chunk) { if(chunk->lefttosend) { rc = _libssh2_channel_write(channel, 0, &chunk->packet[chunk->sent], chunk->lefttosend); if(rc < 0) { sftp->read_state = libssh2_NB_state_sent; return rc; } /* remember where to continue sending the next time */ chunk->lefttosend -= rc; chunk->sent += rc; if(chunk->lefttosend) { /* We still have data left to send for this chunk. * If there is at least one completely sent chunk, * we can get out of this loop and start reading. */ if(chunk != _libssh2_list_first(&handle->packet_list)) { break; } else { continue; } } } /* move on to the next chunk with data to send */ chunk = _libssh2_list_next(&chunk->node); } /* FALL-THROUGH */ case libssh2_NB_state_sent2: sftp->read_state = libssh2_NB_state_idle; /* * Count all ACKed packets and act on the contents of them. */ chunk = _libssh2_list_first(&handle->packet_list); while(chunk) { unsigned char *data; size_t data_len = 0; uint32_t rc32; static const unsigned char read_responses[2] = { SSH_FXP_DATA, SSH_FXP_STATUS }; if(chunk->lefttosend) { /* if the chunk still has data left to send, we shouldn't wait for an ACK for it just yet */ if(bytes_in_buffer > 0) { return bytes_in_buffer; } else { /* we should never reach this point */ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "sftp_read() internal error"); } } rc = sftp_packet_requirev(sftp, 2, read_responses, chunk->request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN && bytes_in_buffer) { /* do not return EAGAIN if we have already * written data into the buffer */ return bytes_in_buffer; } if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Response too small"); } else if(rc < 0) { sftp->read_state = libssh2_NB_state_sent2; return rc; } /* * We get DATA or STATUS back. STATUS can be error, or it is * FX_EOF when we reach the end of the file. */ switch(data[0]) { case SSH_FXP_STATUS: /* remove the chunk we just processed */ _libssh2_list_remove(&chunk->node); LIBSSH2_FREE(session, chunk); /* we must remove all outstanding READ requests, as either we got an error or we're at end of file */ sftp_packetlist_flush(handle); rc32 = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(rc32 == LIBSSH2_FX_EOF) { filep->eof = TRUE; return bytes_in_buffer; } else { sftp->last_errno = rc32; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP READ error"); } break; case SSH_FXP_DATA: if(chunk->offset != filep->offset) { /* This could happen if the server returns less bytes than requested, which shouldn't happen for normal files. See: https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02 #section-6.4 */ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Read Packet At Unexpected Offset"); } rc32 = _libssh2_ntohu32(data + 5); if(rc32 > (data_len - 9)) return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol badness"); if(rc32 > chunk->len) { /* A chunk larger than we requested was returned to us. This is a protocol violation and we don't know how to deal with it. Bail out! */ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "FXP_READ response too big"); } if(rc32 != chunk->len) { /* a short read does not imply end of file, but we must adjust the offset_sent since it was advanced with a full chunk->len before */ filep->offset_sent -= (chunk->len - rc32); } if((bytes_in_buffer + rc32) > buffer_size) { /* figure out the overlap amount */ filep->data_left = (bytes_in_buffer + rc32) - buffer_size; /* getting the full packet would overflow the buffer, so only get the correct amount and keep the remainder */ rc32 = (uint32_t)(buffer_size - bytes_in_buffer); /* store data to keep for next call */ filep->data = data; filep->data_len = data_len; } else filep->data_len = 0; /* copy the received data from the received FXP_DATA packet to the buffer at the correct index */ memcpy(sliding_bufferp, data + 9, rc32); filep->offset += rc32; bytes_in_buffer += rc32; sliding_bufferp += rc32; if(filep->data_len == 0) /* free the allocated data if not stored to keep */ LIBSSH2_FREE(session, data); /* remove the chunk we just processed keeping track of the * next one in case we need it */ next = _libssh2_list_next(&chunk->node); _libssh2_list_remove(&chunk->node); LIBSSH2_FREE(session, chunk); /* check if we have space left in the buffer * and either continue to the next chunk or stop */ if(bytes_in_buffer < buffer_size) { chunk = next; } else { chunk = NULL; } break; default: return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol badness: unrecognised " "read request response"); } } if(bytes_in_buffer > 0) return bytes_in_buffer; break; default: assert(0); /* State machine error; unrecognised read state */ } /* we should never reach this point */ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "sftp_read() internal error"); } /* libssh2_sftp_read * Read from an SFTP file handle */ LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, size_t buffer_maxlen) { ssize_t rc; if(!hnd) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_read(hnd, buffer, buffer_maxlen)); return rc; } /* sftp_readdir * Read from an SFTP directory handle */ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, char *longentry, size_t longentry_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; uint32_t num_names; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ uint32_t packet_len = (uint32_t)(handle->handle_len + 13); unsigned char *s, *data; static const unsigned char read_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; ssize_t retcode; if(sftp->readdir_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; if(handle->u.dir.names_left) { /* * A prior request returned more than one directory entry, * feed it back from the buffer */ LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; size_t real_longentry_len; size_t real_filename_len; size_t filename_len; size_t longentry_len; size_t names_packet_len = handle->u.dir.names_packet_len; ssize_t attr_len = 0; if(names_packet_len >= 4) { s = (unsigned char *) handle->u.dir.next_name; real_filename_len = _libssh2_ntohu32(s); s += 4; names_packet_len -= 4; } else { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } filename_len = real_filename_len; if(filename_len >= buffer_maxlen) { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } if(buffer_maxlen >= filename_len && names_packet_len >= filename_len) { memcpy(buffer, s, filename_len); buffer[filename_len] = '\0'; /* zero terminate */ s += real_filename_len; names_packet_len -= real_filename_len; } else { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } if(names_packet_len >= 4) { real_longentry_len = _libssh2_ntohu32(s); s += 4; names_packet_len -= 4; } else { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } if(longentry && (longentry_maxlen > 1)) { longentry_len = real_longentry_len; if(longentry_len >= longentry_maxlen || longentry_len > names_packet_len) { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } memcpy(longentry, s, longentry_len); longentry[longentry_len] = '\0'; /* zero terminate */ } if(real_longentry_len <= names_packet_len) { s += real_longentry_len; names_packet_len -= real_longentry_len; } else { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } if(attrs) memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); attr_len = sftp_bin2attr(attrs ? attrs : &attrs_dummy, s, names_packet_len); if(attr_len >= 0) { s += attr_len; names_packet_len -= attr_len; } else { filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; goto end; } handle->u.dir.next_name = (char *) s; handle->u.dir.names_packet_len = names_packet_len; if((--handle->u.dir.names_left) == 0) LIBSSH2_FREE(session, handle->u.dir.names_packet); end: _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "libssh2_sftp_readdir_ex() return %d", filename_len)); return (ssize_t)filename_len; } /* Request another entry(entries?) */ s = sftp->readdir_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->readdir_packet) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "FXP_READDIR packet"); _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_READDIR; sftp->readdir_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->readdir_request_id); _libssh2_store_str(&s, handle->handle, handle->handle_len); sftp->readdir_state = libssh2_NB_state_created; } if(sftp->readdir_state == libssh2_NB_state_created) { _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Reading entries from directory handle")); retcode = _libssh2_channel_write(channel, 0, sftp->readdir_packet, packet_len); if(retcode == LIBSSH2_ERROR_EAGAIN) { return retcode; } else if((ssize_t)packet_len != retcode) { LIBSSH2_FREE(session, sftp->readdir_packet); sftp->readdir_packet = NULL; sftp->readdir_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "_libssh2_channel_write() failed"); } LIBSSH2_FREE(session, sftp->readdir_packet); sftp->readdir_packet = NULL; sftp->readdir_state = libssh2_NB_state_sent; } retcode = sftp_packet_requirev(sftp, 2, read_responses, sftp->readdir_request_id, &data, &data_len, 9); if(retcode == LIBSSH2_ERROR_EAGAIN) return retcode; else if(retcode == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Status message too short"); } else if(retcode) { sftp->readdir_state = libssh2_NB_state_idle; return _libssh2_error(session, (int)retcode, "Timeout waiting for status message"); } if(data[0] == SSH_FXP_STATUS) { unsigned int rerrno; rerrno = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(rerrno == LIBSSH2_FX_EOF) { sftp->readdir_state = libssh2_NB_state_idle; return 0; } else { sftp->last_errno = rerrno; sftp->readdir_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } sftp->readdir_state = libssh2_NB_state_idle; num_names = _libssh2_ntohu32(data + 5); _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "%lu entries returned", num_names)); if(!num_names) { LIBSSH2_FREE(session, data); return 0; } handle->u.dir.names_left = num_names; handle->u.dir.names_packet = data; handle->u.dir.next_name = (char *) data + 9; handle->u.dir.names_packet_len = data_len - 9; /* use the name popping mechanism from the start of the function */ return sftp_readdir(handle, buffer, buffer_maxlen, longentry, longentry_maxlen, attrs); } /* libssh2_sftp_readdir_ex * Read from an SFTP directory handle */ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, size_t buffer_maxlen, char *longentry, size_t longentry_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) { ssize_t rc; if(!hnd) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_readdir(hnd, buffer, buffer_maxlen, longentry, longentry_maxlen, attrs)); return (int)rc; /* FIXME: -> ssize_t */ } /* sftp_write * * Write data to an SFTP handle. Returns the number of bytes written, or * a negative error code. * * We recommend sending very large data buffers to this function! * * Concept: * * - Detect how much of the given buffer that was already sent in a previous * call by inspecting the linked list of outgoing chunks. Make sure to skip * passed the data that has already been taken care of. * * - Split all (new) outgoing data in chunks no larger than N. * * - Each N bytes chunk gets created as a separate SFTP packet. * * - Add all created outgoing packets to the linked list. * * - Walk through the list and send the chunks that haven't been sent, * as many as possible until EAGAIN. Some of the chunks may have been put * in the list in a previous invoke. * * - For all the chunks in the list that have been completely sent off, check * for ACKs. If a chunk has been ACKed, it is removed from the linked * list and the "acked" counter gets increased with that data amount. * * - Return TOTAL bytes acked so far. * * Caveats: * - be careful: we must not return a higher number than what was given! * * TODO: * Introduce an option that disables this sort of "speculative" ahead writing * as there's a risk that it will do harm to some app. */ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; uint32_t retcode; uint32_t packet_len; unsigned char *s, *data = NULL; ssize_t rc; struct sftp_pipeline_chunk *chunk; struct sftp_pipeline_chunk *next; size_t acked = 0; size_t org_count = count; size_t already; switch(sftp->write_state) { default: case libssh2_NB_state_idle: sftp->last_errno = LIBSSH2_FX_OK; /* Number of bytes sent off that haven't been acked and therefore we will get passed in here again. Also, add up the number of bytes that actually already have been acked but we haven't been able to return as such yet, so we will get that data as well passed in here again. */ already = (size_t)(handle->u.file.offset_sent - handle->u.file.offset)+ handle->u.file.acked; if(count >= already) { /* skip the part already made into packets */ buffer += already; count -= already; } else /* there is more data already fine than what we got in this call */ count = 0; sftp->write_state = libssh2_NB_state_idle; while(count) { /* TODO: Possibly this should have some logic to prevent a very very small fraction to be left but lets ignore that for now */ uint32_t size = (uint32_t)(LIBSSH2_MIN(MAX_SFTP_OUTGOING_SIZE, count)); uint32_t request_id; /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + count(4) */ packet_len = (uint32_t)(handle->handle_len + size + 25); chunk = LIBSSH2_ALLOC(session, packet_len + sizeof(struct sftp_pipeline_chunk)); if(!chunk) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "malloc fail for FXP_WRITE"); chunk->len = size; chunk->sent = 0; chunk->lefttosend = packet_len; s = chunk->packet; _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_WRITE; request_id = sftp->request_id++; chunk->request_id = request_id; _libssh2_store_u32(&s, request_id); _libssh2_store_str(&s, handle->handle, handle->handle_len); _libssh2_store_u64(&s, handle->u.file.offset_sent); handle->u.file.offset_sent += size; /* advance offset at once */ _libssh2_store_str(&s, buffer, size); /* add this new entry LAST in the list */ _libssh2_list_add(&handle->packet_list, &chunk->node); buffer += size; count -= size; /* deduct the size we used, as we might have to create more packets */ } /* move through the WRITE packets that haven't been sent and send as many as possible - remember that we don't block */ chunk = _libssh2_list_first(&handle->packet_list); while(chunk) { if(chunk->lefttosend) { rc = _libssh2_channel_write(channel, 0, &chunk->packet[chunk->sent], chunk->lefttosend); if(rc < 0) /* remain in idle state */ return rc; /* remember where to continue sending the next time */ chunk->lefttosend -= rc; chunk->sent += rc; if(chunk->lefttosend) /* data left to send, get out of loop */ break; } /* move on to the next chunk with data to send */ chunk = _libssh2_list_next(&chunk->node); } /* fall-through */ case libssh2_NB_state_sent: sftp->write_state = libssh2_NB_state_idle; /* * Count all ACKed packets */ chunk = _libssh2_list_first(&handle->packet_list); while(chunk) { if(chunk->lefttosend) /* if the chunk still has data left to send, we shouldn't wait for an ACK for it just yet */ break; else if(acked) /* if we have sent data that is acked, we must return that info before we call a function that might return EAGAIN */ break; /* we check the packets in order */ rc = sftp_packet_require(sftp, SSH_FXP_STATUS, chunk->request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "FXP write packet too short"); } else if(rc < 0) { if(rc == LIBSSH2_ERROR_EAGAIN) sftp->write_state = libssh2_NB_state_sent; return rc; } retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); sftp->last_errno = retcode; if(retcode == LIBSSH2_FX_OK) { acked += chunk->len; /* number of payload data that was acked here */ /* we increase the offset value for all acks */ handle->u.file.offset += chunk->len; next = _libssh2_list_next(&chunk->node); _libssh2_list_remove(&chunk->node); /* remove from list */ LIBSSH2_FREE(session, chunk); /* free memory */ chunk = next; } else { /* flush all pending packets from the outgoing list */ sftp_packetlist_flush(handle); /* since we return error now, the application will not get any outstanding data acked, so we need to rewind the offset to where the application knows it has reached with acked data */ handle->u.file.offset -= handle->u.file.acked; /* then reset the offset_sent to be the same as the offset */ handle->u.file.offset_sent = handle->u.file.offset; /* clear the acked counter since we can have no pending data to ack after an error */ handle->u.file.acked = 0; /* the server returned an error for that written chunk, propagate this back to our parent function */ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "FXP write failed"); } } break; } /* if there were acked data in a previous call that wasn't returned then, add that up and try to return it all now. This can happen if the app first sends a huge buffer of data, and then in a second call it sends a smaller one. */ acked += handle->u.file.acked; if(acked) { ssize_t ret = LIBSSH2_MIN(acked, org_count); /* we got data acked so return that amount, but no more than what was asked to get sent! */ /* store the remainder. 'ret' is always equal to or less than 'acked' here */ handle->u.file.acked = acked - ret; return ret; } else return 0; /* nothing was acked, and no EAGAIN was received! */ } /* libssh2_sftp_write * Write data to a file handle */ LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer, size_t count) { ssize_t rc; if(!hnd) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_write(hnd, buffer, count)); return rc; } static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; /* 34 = packet_len(4) + packet_type(1) + request_id(4) + string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */ uint32_t packet_len = (uint32_t)(handle->handle_len + 34); size_t data_len = 0; unsigned char *packet, *s, *data = NULL; ssize_t rc; uint32_t retcode; if(sftp->fsync_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Issuing fsync command")); s = packet = LIBSSH2_ALLOC(session, packet_len); if(!packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_EXTENDED " "packet"); } _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_EXTENDED; sftp->fsync_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->fsync_request_id); _libssh2_store_str(&s, "fsync@openssh.com", 17); _libssh2_store_str(&s, handle->handle, handle->handle_len); sftp->fsync_state = libssh2_NB_state_created; } else { packet = sftp->fsync_packet; } if(sftp->fsync_state == libssh2_NB_state_created) { rc = _libssh2_channel_write(channel, 0, packet, packet_len); if(rc == LIBSSH2_ERROR_EAGAIN || (0 <= rc && rc < (ssize_t)packet_len)) { sftp->fsync_packet = packet; return LIBSSH2_ERROR_EAGAIN; } LIBSSH2_FREE(session, packet); sftp->fsync_packet = NULL; if(rc < 0) { sftp->fsync_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "_libssh2_channel_write() failed"); } sftp->fsync_state = libssh2_NB_state_sent; } rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->fsync_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP fsync packet too short"); } else if(rc) { sftp->fsync_state = libssh2_NB_state_idle; return _libssh2_error(session, (int)rc, "Error waiting for FXP EXTENDED REPLY"); } sftp->fsync_state = libssh2_NB_state_idle; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode != LIBSSH2_FX_OK) { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "fsync failed"); } return 0; } /* libssh2_sftp_fsync * Commit data on the handle to disk. */ LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd) { int rc; if(!hnd) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_fsync(hnd)); return rc; } /* sftp_fstat * Get or Set stat on a file */ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ uint32_t packet_len = (uint32_t)(handle->handle_len + 13 + (setstat ? sftp_attrsize(attrs->flags) : 0)); unsigned char *s, *data = NULL; static const unsigned char fstat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; ssize_t rc; if(sftp->fstat_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Issuing %s command", setstat ? "set-stat" : "stat")); s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->fstat_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "FSTAT/FSETSTAT packet"); } _libssh2_store_u32(&s, packet_len - 4); *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; sftp->fstat_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->fstat_request_id); _libssh2_store_str(&s, handle->handle, handle->handle_len); if(setstat) { s += sftp_attr2bin(s, attrs); } sftp->fstat_state = libssh2_NB_state_created; } if(sftp->fstat_state == libssh2_NB_state_created) { rc = _libssh2_channel_write(channel, 0, sftp->fstat_packet, packet_len); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if((ssize_t)packet_len != rc) { LIBSSH2_FREE(session, sftp->fstat_packet); sftp->fstat_packet = NULL; sftp->fstat_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, (setstat ? "Unable to send FXP_FSETSTAT" : "Unable to send FXP_FSTAT command")); } LIBSSH2_FREE(session, sftp->fstat_packet); sftp->fstat_packet = NULL; sftp->fstat_state = libssh2_NB_state_sent; } rc = sftp_packet_requirev(sftp, 2, fstat_responses, sftp->fstat_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) return (int)rc; else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP fstat packet too short"); } else if(rc) { sftp->fstat_state = libssh2_NB_state_idle; return _libssh2_error(session, (int)rc, "Timeout waiting for status message"); } sftp->fstat_state = libssh2_NB_state_idle; if(data[0] == SSH_FXP_STATUS) { uint32_t retcode; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode == LIBSSH2_FX_OK) { return 0; } else { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } if(sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) { LIBSSH2_FREE(session, data); return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Attributes too short in SFTP fstat"); } LIBSSH2_FREE(session, data); return 0; } /* libssh2_sftp_fstat_ex * Get or Set stat on a file */ LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) { int rc; if(!hnd || !attrs) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_fstat(hnd, attrs, setstat)); return rc; } /* libssh2_sftp_seek64 * Set the read/write pointer to an arbitrary position within the file */ LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset) { if(!handle) return; if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset) return; handle->u.file.offset = handle->u.file.offset_sent = offset; /* discard all pending requests and currently read data */ sftp_packetlist_flush(handle); /* free the left received buffered data */ if(handle->u.file.data_left) { LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data); handle->u.file.data_left = handle->u.file.data_len = 0; handle->u.file.data = NULL; } /* reset EOF to False */ handle->u.file.eof = FALSE; } /* libssh2_sftp_seek * Set the read/write pointer to an arbitrary position within the file */ LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset) { libssh2_sftp_seek64(handle, (libssh2_uint64_t)offset); } /* libssh2_sftp_tell * Return the current read/write pointer's offset */ LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) { if(!handle) return 0; /* no handle, no size */ /* NOTE: this may very well truncate the size if it is larger than what size_t can hold, so libssh2_sftp_tell64() is really the function you should use */ return (size_t)(handle->u.file.offset); } /* libssh2_sftp_tell64 * Return the current read/write pointer's offset */ LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle) { if(!handle) return 0; /* no handle, no size */ return handle->u.file.offset; } /* * Flush all remaining incoming SFTP packets and zombies. */ static void sftp_packet_flush(LIBSSH2_SFTP *sftp) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); struct sftp_zombie_requests *zombie = _libssh2_list_first(&sftp->zombie_requests); while(packet) { LIBSSH2_SFTP_PACKET *next; /* check next struct in the list */ next = _libssh2_list_next(&packet->node); _libssh2_list_remove(&packet->node); LIBSSH2_FREE(session, packet->data); LIBSSH2_FREE(session, packet); packet = next; } while(zombie) { /* figure out the next node */ struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node); /* unlink the current one */ _libssh2_list_remove(&zombie->node); /* free the memory */ LIBSSH2_FREE(session, zombie); zombie = next; } } /* sftp_close_handle * * Close a file or directory handle. * Also frees handle resource and unlinks it from the SFTP structure. * The handle is no longer usable after return of this function, unless * the return value is LIBSSH2_ERROR_EAGAIN in which case this function * should be called again. */ static int sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ uint32_t packet_len = (uint32_t)(handle->handle_len + 13); unsigned char *s, *data = NULL; int rc = 0; if(handle->close_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Closing handle")); s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len); if(!handle->close_packet) { handle->close_state = libssh2_NB_state_idle; rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_CLOSE " "packet"); } else { _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_CLOSE; handle->close_request_id = sftp->request_id++; _libssh2_store_u32(&s, handle->close_request_id); _libssh2_store_str(&s, handle->handle, handle->handle_len); handle->close_state = libssh2_NB_state_created; } } if(handle->close_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, handle->close_packet, packet_len); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if((ssize_t)packet_len != nwritten) { handle->close_state = libssh2_NB_state_idle; rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_CLOSE command"); } else handle->close_state = libssh2_NB_state_sent; LIBSSH2_FREE(session, handle->close_packet); handle->close_packet = NULL; } if(handle->close_state == libssh2_NB_state_sent) { rc = sftp_packet_require(sftp, SSH_FXP_STATUS, handle->close_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } data = NULL; _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Packet too short in FXP_CLOSE command"); } else if(rc) { _libssh2_error(session, rc, "Error waiting for status message"); } handle->close_state = libssh2_NB_state_sent1; } if(!data) { /* if it reaches this point with data unset, something unwanted happened for which we should have set an error code */ assert(rc); } else { uint32_t retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode != LIBSSH2_FX_OK) { sftp->last_errno = retcode; handle->close_state = libssh2_NB_state_idle; rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } /* remove this handle from the parent's list */ _libssh2_list_remove(&handle->node); if(handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) { if(handle->u.dir.names_left) LIBSSH2_FREE(session, handle->u.dir.names_packet); } else if(handle->handle_type == LIBSSH2_SFTP_HANDLE_FILE) { if(handle->u.file.data) LIBSSH2_FREE(session, handle->u.file.data); } sftp_packetlist_flush(handle); sftp->read_state = libssh2_NB_state_idle; handle->close_state = libssh2_NB_state_idle; LIBSSH2_FREE(session, handle); return rc; } /* libssh2_sftp_close_handle * * Close a file or directory handle * Also frees handle resource and unlinks it from the SFTP structure */ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *hnd) { int rc; if(!hnd) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_close_handle(hnd)); return rc; } /* sftp_unlink * Delete a file from the remote server */ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename, size_t filename_len) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; uint32_t retcode; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */ uint32_t packet_len = (uint32_t)(filename_len + 13); unsigned char *s, *data = NULL; int rc; if(sftp->unlink_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Unlinking %s", filename)); s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->unlink_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_REMOVE " "packet"); } _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_REMOVE; sftp->unlink_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->unlink_request_id); _libssh2_store_str(&s, filename, filename_len); sftp->unlink_state = libssh2_NB_state_created; } if(sftp->unlink_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, sftp->unlink_packet, packet_len); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if((ssize_t)packet_len != nwritten) { LIBSSH2_FREE(session, sftp->unlink_packet); sftp->unlink_packet = NULL; sftp->unlink_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_REMOVE command"); } LIBSSH2_FREE(session, sftp->unlink_packet); sftp->unlink_packet = NULL; sftp->unlink_state = libssh2_NB_state_sent; } rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->unlink_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP unlink packet too short"); } else if(rc) { sftp->unlink_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Error waiting for FXP STATUS"); } sftp->unlink_state = libssh2_NB_state_idle; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode == LIBSSH2_FX_OK) { return 0; } else { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } /* libssh2_sftp_unlink_ex * Delete a file from the remote server */ LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_unlink(sftp, filename, filename_len)); return rc; } /* sftp_rename * Rename a file on the remote server */ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int source_filename_len, const char *dest_filename, unsigned int dest_filename_len, long flags) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; int retcode; uint32_t packet_len = source_filename_len + dest_filename_len + 17 + (sftp->version >= 5 ? 4 : 0); /* packet_len(4) + packet_type(1) + request_id(4) + source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ unsigned char *data = NULL; ssize_t rc; if(sftp->rename_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; if(sftp->version < 2) { return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support RENAME"); } _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Renaming %s to %s", source_filename, dest_filename)); sftp->rename_s = sftp->rename_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->rename_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_RENAME " "packet"); } _libssh2_store_u32(&sftp->rename_s, packet_len - 4); *(sftp->rename_s++) = SSH_FXP_RENAME; sftp->rename_request_id = sftp->request_id++; _libssh2_store_u32(&sftp->rename_s, sftp->rename_request_id); _libssh2_store_str(&sftp->rename_s, source_filename, source_filename_len); _libssh2_store_str(&sftp->rename_s, dest_filename, dest_filename_len); if(sftp->version >= 5) _libssh2_store_u32(&sftp->rename_s, (uint32_t)flags); sftp->rename_state = libssh2_NB_state_created; } if(sftp->rename_state == libssh2_NB_state_created) { rc = _libssh2_channel_write(channel, 0, sftp->rename_packet, sftp->rename_s - sftp->rename_packet); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if((ssize_t)packet_len != rc) { LIBSSH2_FREE(session, sftp->rename_packet); sftp->rename_packet = NULL; sftp->rename_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_RENAME command"); } LIBSSH2_FREE(session, sftp->rename_packet); sftp->rename_packet = NULL; sftp->rename_state = libssh2_NB_state_sent; } rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->rename_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP rename packet too short"); } else if(rc) { sftp->rename_state = libssh2_NB_state_idle; return _libssh2_error(session, (int)rc, "Error waiting for FXP STATUS"); } sftp->rename_state = libssh2_NB_state_idle; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); sftp->last_errno = retcode; /* now convert the SFTP error code to libssh2 return code or error message */ switch(retcode) { case LIBSSH2_FX_OK: retcode = LIBSSH2_ERROR_NONE; break; case LIBSSH2_FX_FILE_ALREADY_EXISTS: retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "File already exists and " "SSH_FXP_RENAME_OVERWRITE not specified"); break; case LIBSSH2_FX_OP_UNSUPPORTED: retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Operation Not Supported"); break; default: retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); break; } return retcode; } /* libssh2_sftp_rename_ex * Rename a file on the remote server */ LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int source_filename_len, const char *dest_filename, unsigned int dest_filename_len, long flags) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_rename(sftp, source_filename, source_filename_len, dest_filename, dest_filename_len, flags)); return rc; } /* sftp_fstatvfs * Get file system statistics */ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) { LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + handle_len (4) */ /* 20 = strlen ("fstatvfs@openssh.com") */ uint32_t packet_len = (uint32_t)(handle->handle_len + 20 + 17); unsigned char *packet, *s, *data = NULL; ssize_t rc; unsigned int flag; static const unsigned char responses[2] = { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; if(sftp->fstatvfs_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Getting file system statistics")); s = packet = LIBSSH2_ALLOC(session, packet_len); if(!packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_EXTENDED " "packet"); } _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_EXTENDED; sftp->fstatvfs_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->fstatvfs_request_id); _libssh2_store_str(&s, "fstatvfs@openssh.com", 20); _libssh2_store_str(&s, handle->handle, handle->handle_len); sftp->fstatvfs_state = libssh2_NB_state_created; } else { packet = sftp->fstatvfs_packet; } if(sftp->fstatvfs_state == libssh2_NB_state_created) { rc = _libssh2_channel_write(channel, 0, packet, packet_len); if(rc == LIBSSH2_ERROR_EAGAIN || (0 <= rc && rc < (ssize_t)packet_len)) { sftp->fstatvfs_packet = packet; return LIBSSH2_ERROR_EAGAIN; } LIBSSH2_FREE(session, packet); sftp->fstatvfs_packet = NULL; if(rc < 0) { sftp->fstatvfs_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "_libssh2_channel_write() failed"); } sftp->fstatvfs_state = libssh2_NB_state_sent; } rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP rename packet too short"); } else if(rc) { sftp->fstatvfs_state = libssh2_NB_state_idle; return _libssh2_error(session, (int)rc, "Error waiting for FXP EXTENDED REPLY"); } if(data[0] == SSH_FXP_STATUS) { uint32_t retcode = _libssh2_ntohu32(data + 5); sftp->fstatvfs_state = libssh2_NB_state_idle; LIBSSH2_FREE(session, data); sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } if(data_len < 93) { LIBSSH2_FREE(session, data); sftp->fstatvfs_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error: short response"); } sftp->fstatvfs_state = libssh2_NB_state_idle; st->f_bsize = _libssh2_ntohu64(data + 5); st->f_frsize = _libssh2_ntohu64(data + 13); st->f_blocks = _libssh2_ntohu64(data + 21); st->f_bfree = _libssh2_ntohu64(data + 29); st->f_bavail = _libssh2_ntohu64(data + 37); st->f_files = _libssh2_ntohu64(data + 45); st->f_ffree = _libssh2_ntohu64(data + 53); st->f_favail = _libssh2_ntohu64(data + 61); st->f_fsid = _libssh2_ntohu64(data + 69); flag = (unsigned int)_libssh2_ntohu64(data + 77); st->f_namemax = _libssh2_ntohu64(data + 85); st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) ? LIBSSH2_SFTP_ST_RDONLY : 0; st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) ? LIBSSH2_SFTP_ST_NOSUID : 0; LIBSSH2_FREE(session, data); return 0; } /* libssh2_sftp_fstatvfs * Get filesystem space and inode utilization (requires fstatvfs@openssh.com * support on the server) */ LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) { int rc; if(!handle || !st) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, handle->sftp->channel->session, sftp_fstatvfs(handle, st)); return rc; } /* sftp_statvfs * Get file system statistics */ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, LIBSSH2_SFTP_STATVFS *st) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + path_len (4) */ /* 19 = strlen ("statvfs@openssh.com") */ uint32_t packet_len = path_len + 19 + 17; unsigned char *packet, *s, *data = NULL; ssize_t rc; unsigned int flag; static const unsigned char responses[2] = { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; if(sftp->statvfs_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Getting file system statistics of %s", path)); s = packet = LIBSSH2_ALLOC(session, packet_len); if(!packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_EXTENDED " "packet"); } _libssh2_store_u32(&s, packet_len - 4); *(s++) = SSH_FXP_EXTENDED; sftp->statvfs_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->statvfs_request_id); _libssh2_store_str(&s, "statvfs@openssh.com", 19); _libssh2_store_str(&s, path, path_len); sftp->statvfs_state = libssh2_NB_state_created; } else { packet = sftp->statvfs_packet; } if(sftp->statvfs_state == libssh2_NB_state_created) { rc = _libssh2_channel_write(channel, 0, packet, packet_len); if(rc == LIBSSH2_ERROR_EAGAIN || (0 <= rc && rc < (ssize_t)packet_len)) { sftp->statvfs_packet = packet; return LIBSSH2_ERROR_EAGAIN; } LIBSSH2_FREE(session, packet); sftp->statvfs_packet = NULL; if(rc < 0) { sftp->statvfs_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "_libssh2_channel_write() failed"); } sftp->statvfs_state = libssh2_NB_state_sent; } rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP fstat packet too short"); } else if(rc) { sftp->statvfs_state = libssh2_NB_state_idle; return _libssh2_error(session, (int)rc, "Error waiting for FXP EXTENDED REPLY"); } if(data[0] == SSH_FXP_STATUS) { uint32_t retcode = _libssh2_ntohu32(data + 5); sftp->statvfs_state = libssh2_NB_state_idle; LIBSSH2_FREE(session, data); sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } if(data_len < 93) { LIBSSH2_FREE(session, data); sftp->statvfs_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error: short response"); } sftp->statvfs_state = libssh2_NB_state_idle; st->f_bsize = _libssh2_ntohu64(data + 5); st->f_frsize = _libssh2_ntohu64(data + 13); st->f_blocks = _libssh2_ntohu64(data + 21); st->f_bfree = _libssh2_ntohu64(data + 29); st->f_bavail = _libssh2_ntohu64(data + 37); st->f_files = _libssh2_ntohu64(data + 45); st->f_ffree = _libssh2_ntohu64(data + 53); st->f_favail = _libssh2_ntohu64(data + 61); st->f_fsid = _libssh2_ntohu64(data + 69); flag = (unsigned int)_libssh2_ntohu64(data + 77); st->f_namemax = _libssh2_ntohu64(data + 85); st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) ? LIBSSH2_SFTP_ST_RDONLY : 0; st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) ? LIBSSH2_SFTP_ST_NOSUID : 0; LIBSSH2_FREE(session, data); return 0; } /* libssh2_sftp_statvfs_ex * Get filesystem space and inode utilization (requires statvfs@openssh.com * support on the server) */ LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, size_t path_len, LIBSSH2_SFTP_STATVFS *st) { int rc; if(!sftp || !st) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_statvfs(sftp, path, (unsigned int)path_len, st)); return rc; } /* sftp_mkdir * Create an SFTP directory */ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; LIBSSH2_SFTP_ATTRIBUTES attrs = { 0, 0, 0, 0, 0, 0, 0 }; size_t data_len = 0; uint32_t retcode; ssize_t packet_len; unsigned char *packet, *s, *data = NULL; int rc; if(mode != LIBSSH2_SFTP_DEFAULT_MODE) { /* Filetype in SFTP 3 and earlier */ attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR; } /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ packet_len = path_len + 13 + sftp_attrsize(attrs.flags); if(sftp->mkdir_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Creating directory %s with mode 0%lo", path, mode)); s = packet = LIBSSH2_ALLOC(session, packet_len); if(!packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR " "packet"); } _libssh2_store_u32(&s, (uint32_t)(packet_len - 4)); *(s++) = SSH_FXP_MKDIR; sftp->mkdir_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->mkdir_request_id); _libssh2_store_str(&s, path, path_len); s += sftp_attr2bin(s, &attrs); sftp->mkdir_state = libssh2_NB_state_created; } else { packet = sftp->mkdir_packet; } if(sftp->mkdir_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, packet, packet_len); if(nwritten == LIBSSH2_ERROR_EAGAIN) { sftp->mkdir_packet = packet; return (int)nwritten; } if(packet_len != nwritten) { LIBSSH2_FREE(session, packet); sftp->mkdir_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "_libssh2_channel_write() failed"); } LIBSSH2_FREE(session, packet); sftp->mkdir_state = libssh2_NB_state_sent; sftp->mkdir_packet = NULL; } rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP mkdir packet too short"); } else if(rc) { sftp->mkdir_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Error waiting for FXP STATUS"); } sftp->mkdir_state = libssh2_NB_state_idle; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode == LIBSSH2_FX_OK) { _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "OK!")); return 0; } else { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } /* libssh2_sftp_mkdir_ex * Create an SFTP directory */ LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_mkdir(sftp, path, path_len, mode)); return rc; } /* sftp_rmdir * Remove a directory */ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; uint32_t retcode; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ ssize_t packet_len = path_len + 13; unsigned char *s, *data = NULL; int rc; if(sftp->rmdir_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Removing directory: %s", path)); s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->rmdir_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_RMDIR " "packet"); } _libssh2_store_u32(&s, (uint32_t)(packet_len - 4)); *(s++) = SSH_FXP_RMDIR; sftp->rmdir_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->rmdir_request_id); _libssh2_store_str(&s, path, path_len); sftp->rmdir_state = libssh2_NB_state_created; } if(sftp->rmdir_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, sftp->rmdir_packet, packet_len); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if(packet_len != nwritten) { LIBSSH2_FREE(session, sftp->rmdir_packet); sftp->rmdir_packet = NULL; sftp->rmdir_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_RMDIR command"); } LIBSSH2_FREE(session, sftp->rmdir_packet); sftp->rmdir_packet = NULL; sftp->rmdir_state = libssh2_NB_state_sent; } rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->rmdir_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP rmdir packet too short"); } else if(rc) { sftp->rmdir_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Error waiting for FXP STATUS"); } sftp->rmdir_state = libssh2_NB_state_idle; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode == LIBSSH2_FX_OK) { return 0; } else { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } /* libssh2_sftp_rmdir_ex * Remove a directory */ LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_rmdir(sftp, path, path_len)); return rc; } /* sftp_stat * Stat a file or symbolic link */ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES * attrs) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ ssize_t packet_len = path_len + 13 + ((stat_type == LIBSSH2_SFTP_SETSTAT) ? sftp_attrsize(attrs->flags) : 0); unsigned char *s, *data = NULL; static const unsigned char stat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; int rc; if(sftp->stat_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "%s %s", (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : (stat_type == LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path)); s = sftp->stat_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->stat_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_*STAT " "packet"); } _libssh2_store_u32(&s, (uint32_t)(packet_len - 4)); switch(stat_type) { case LIBSSH2_SFTP_SETSTAT: *(s++) = SSH_FXP_SETSTAT; break; case LIBSSH2_SFTP_LSTAT: *(s++) = SSH_FXP_LSTAT; break; case LIBSSH2_SFTP_STAT: default: *(s++) = SSH_FXP_STAT; } sftp->stat_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->stat_request_id); _libssh2_store_str(&s, path, path_len); if(stat_type == LIBSSH2_SFTP_SETSTAT) s += sftp_attr2bin(s, attrs); sftp->stat_state = libssh2_NB_state_created; } if(sftp->stat_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if(packet_len != nwritten) { LIBSSH2_FREE(session, sftp->stat_packet); sftp->stat_packet = NULL; sftp->stat_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send STAT/LSTAT/SETSTAT command"); } LIBSSH2_FREE(session, sftp->stat_packet); sftp->stat_packet = NULL; sftp->stat_state = libssh2_NB_state_sent; } rc = sftp_packet_requirev(sftp, 2, stat_responses, sftp->stat_request_id, &data, &data_len, 9); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP stat packet too short"); } else if(rc) { sftp->stat_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Timeout waiting for status message"); } sftp->stat_state = libssh2_NB_state_idle; if(data[0] == SSH_FXP_STATUS) { uint32_t retcode; retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode == LIBSSH2_FX_OK) { memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); return 0; } else { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); if(sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) { LIBSSH2_FREE(session, data); return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Attributes too short in SFTP fstat"); } LIBSSH2_FREE(session, data); return 0; } /* libssh2_sftp_stat_ex * Stat a file or symbolic link */ LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_stat(sftp, path, path_len, stat_type, attrs)); return rc; } /* sftp_symlink * Read or set a symlink */ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; size_t data_len = 0, link_len; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ ssize_t packet_len = path_len + 13 + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); unsigned char *s, *data = NULL; static const unsigned char link_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; int retcode; if(sftp->symlink_state == libssh2_NB_state_idle) { sftp->last_errno = LIBSSH2_FX_OK; if((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) { return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support SYMLINK or" " READLINK"); } s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len); if(!sftp->symlink_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "SYMLINK/READLINK/REALPATH packet"); } _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "%s %s on %s", (link_type == LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading", (link_type == LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path)); _libssh2_store_u32(&s, (uint32_t)(packet_len - 4)); switch(link_type) { case LIBSSH2_SFTP_REALPATH: *(s++) = SSH_FXP_REALPATH; break; case LIBSSH2_SFTP_SYMLINK: *(s++) = SSH_FXP_SYMLINK; break; case LIBSSH2_SFTP_READLINK: default: *(s++) = SSH_FXP_READLINK; } sftp->symlink_request_id = sftp->request_id++; _libssh2_store_u32(&s, sftp->symlink_request_id); _libssh2_store_str(&s, path, path_len); if(link_type == LIBSSH2_SFTP_SYMLINK) _libssh2_store_str(&s, target, target_len); sftp->symlink_state = libssh2_NB_state_created; } if(sftp->symlink_state == libssh2_NB_state_created) { ssize_t rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet, packet_len); if(rc == LIBSSH2_ERROR_EAGAIN) return (int)rc; else if(packet_len != rc) { LIBSSH2_FREE(session, sftp->symlink_packet); sftp->symlink_packet = NULL; sftp->symlink_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send SYMLINK/READLINK command"); } LIBSSH2_FREE(session, sftp->symlink_packet); sftp->symlink_packet = NULL; sftp->symlink_state = libssh2_NB_state_sent; } retcode = sftp_packet_requirev(sftp, 2, link_responses, sftp->symlink_request_id, &data, &data_len, 9); if(retcode == LIBSSH2_ERROR_EAGAIN) return retcode; else if(retcode == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP symlink packet too short"); } else if(retcode) { sftp->symlink_state = libssh2_NB_state_idle; return _libssh2_error(session, retcode, "Error waiting for status message"); } sftp->symlink_state = libssh2_NB_state_idle; if(data[0] == SSH_FXP_STATUS) { retcode = _libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); if(retcode == LIBSSH2_FX_OK) return LIBSSH2_ERROR_NONE; else { sftp->last_errno = retcode; return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error"); } } if(_libssh2_ntohu32(data + 5) < 1) { LIBSSH2_FREE(session, data); return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Invalid READLINK/REALPATH response, " "no name entries"); } if(data_len < 13) { if(data_len > 0) { LIBSSH2_FREE(session, data); } return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP stat packet too short"); } /* this reads a u32 and stores it into a signed 32bit value */ link_len = _libssh2_ntohu32(data + 9); if(link_len < target_len) { memcpy(target, data + 13, link_len); target[link_len] = 0; retcode = (int)link_len; } else retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL; LIBSSH2_FREE(session, data); return retcode; } /* libssh2_sftp_symlink_ex * Read or set a symlink */ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type) { int rc; if(!sftp) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, sftp->channel->session, sftp_symlink(sftp, path, path_len, target, target_len, link_type)); return rc; } /* libssh2_sftp_last_error * Returns the last error code reported by SFTP */ LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp) { if(!sftp) return 0; return sftp->last_errno; } /* libssh2_sftp_get_channel * Return the channel of sftp, then caller can control the channel's behavior. */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp) { if(!sftp) return NULL; return sftp->channel; } libssh2-1.11.0/src/userauth_kbd_packet.c0000644000175000017500000001414514424650606015037 00000000000000/* Copyright (c) 2022, Xaver Loppenstedt * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "userauth_kbd_packet.h" int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *session) { unsigned char *language_tag; size_t language_tag_len; unsigned int i; unsigned char packet_type; uint32_t tmp_u32; struct string_buf decoded; decoded.data = session->userauth_kybd_data; decoded.dataptr = session->userauth_kybd_data; decoded.len = session->userauth_kybd_data_len; if(session->userauth_kybd_data_len < 17) { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "userauth keyboard data buffer too small " "to get length"); return -1; } /* byte SSH_MSG_USERAUTH_INFO_REQUEST */ _libssh2_get_byte(&decoded, &packet_type); /* string name (ISO-10646 UTF-8) */ if(_libssh2_copy_string(session, &decoded, &session->userauth_kybd_auth_name, &session->userauth_kybd_auth_name_len) == -1) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to decode " "keyboard-interactive 'name' " "request field"); return -1; } /* string instruction (ISO-10646 UTF-8) */ if(_libssh2_copy_string(session, &decoded, &session->userauth_kybd_auth_instruction, &session->userauth_kybd_auth_instruction_len) == -1) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to decode " "keyboard-interactive 'instruction' " "request field"); return -1; } /* string language tag (as defined in [RFC-3066]) */ if(_libssh2_get_string(&decoded, &language_tag, &language_tag_len) == -1) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to decode " "keyboard-interactive 'language tag' " "request field"); return -1; } /* int num-prompts */ if(_libssh2_get_u32(&decoded, &tmp_u32) == -1 || (session->userauth_kybd_num_prompts = tmp_u32) != tmp_u32) { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Unable to decode " "keyboard-interactive number of keyboard prompts"); return -1; } if(session->userauth_kybd_num_prompts > 100) { _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, "Too many replies for " "keyboard-interactive prompts"); return -1; } if(session->userauth_kybd_num_prompts == 0) { return 0; } session->userauth_kybd_prompts = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * session->userauth_kybd_num_prompts); if(!session->userauth_kybd_prompts) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "keyboard-interactive prompts array"); return -1; } session->userauth_kybd_responses = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * session->userauth_kybd_num_prompts); if(!session->userauth_kybd_responses) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "keyboard-interactive responses array"); return -1; } for(i = 0; i < session->userauth_kybd_num_prompts; i++) { /* string prompt[1] (ISO-10646 UTF-8) */ if(_libssh2_copy_string(session, &decoded, &session->userauth_kybd_prompts[i].text, &session->userauth_kybd_prompts[i].length) == -1) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to decode " "keyboard-interactive prompt message"); return -1; } /* boolean echo[1] */ if(_libssh2_get_boolean(&decoded, &session->userauth_kybd_prompts[i].echo) == -1) { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Unable to decode " "user auth keyboard prompt echo"); return -1; } } return 0; } libssh2-1.11.0/src/bcrypt_pbkdf.c0000644000175000017500000001511114424650606013473 00000000000000/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */ /* * Copyright (c) 2013 Ted Unangst * * 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. */ #include "libssh2_priv.h" #ifndef HAVE_BCRYPT_PBKDF #include #define LIBSSH2_BCRYPT_PBKDF_C #include "blowfish.c" /* * pkcs #5 pbkdf2 implementation using the "bcrypt" hash * * The bcrypt hash function is derived from the bcrypt password hashing * function with the following modifications: * 1. The input password and salt are preprocessed with SHA512. * 2. The output length is expanded to 256 bits. * 3. Subsequently the magic string to be encrypted is lengthened and modified * to "OxychromaticBlowfishSwatDynamite" * 4. The hash function is defined to perform 64 rounds of initial state * expansion. (More rounds are performed by iterating the hash.) * * Note that this implementation pulls the SHA512 operations into the caller * as a performance optimization. * * One modification from official pbkdf2. Instead of outputting key material * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to * generate (i.e.) 512 bits of key material for use as two 256 bit keys, an * attacker can merely run once through the outer loop below, but the user * always runs it twice. Shuffling output bytes requires computing the * entirety of the key material to assemble any subkey. This is something a * wise caller could do; we just do it for you. */ #define BCRYPT_BLOCKS 8 #define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4) static void bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out) { blf_ctx state; uint8_t ciphertext[BCRYPT_HASHSIZE] = { 'O', 'x', 'y', 'c', 'h', 'r', 'o', 'm', 'a', 't', 'i', 'c', 'B', 'l', 'o', 'w', 'f', 'i', 's', 'h', 'S', 'w', 'a', 't', 'D', 'y', 'n', 'a', 'm', 'i', 't', 'e' }; uint32_t cdata[BCRYPT_BLOCKS]; int i; uint16_t j; uint16_t shalen = SHA512_DIGEST_LENGTH; /* key expansion */ Blowfish_initstate(&state); Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen); for(i = 0; i < 64; i++) { Blowfish_expand0state(&state, sha2salt, shalen); Blowfish_expand0state(&state, sha2pass, shalen); } /* encryption */ j = 0; for(i = 0; i < BCRYPT_BLOCKS; i++) cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), &j); for(i = 0; i < 64; i++) blf_enc(&state, cdata, BCRYPT_BLOCKS / 2); /* copy out */ for(i = 0; i < BCRYPT_BLOCKS; i++) { out[4 * i + 3] = (uint8_t)((cdata[i] >> 24) & 0xff); out[4 * i + 2] = (cdata[i] >> 16) & 0xff; out[4 * i + 1] = (cdata[i] >> 8) & 0xff; out[4 * i + 0] = cdata[i] & 0xff; } /* zap */ _libssh2_explicit_zero(ciphertext, sizeof(ciphertext)); _libssh2_explicit_zero(cdata, sizeof(cdata)); _libssh2_explicit_zero(&state, sizeof(state)); } static int bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, uint8_t *key, size_t keylen, unsigned int rounds) { uint8_t sha2pass[SHA512_DIGEST_LENGTH]; uint8_t sha2salt[SHA512_DIGEST_LENGTH]; uint8_t out[BCRYPT_HASHSIZE]; uint8_t tmpout[BCRYPT_HASHSIZE]; uint8_t *countsalt; size_t i, j, amt, stride; uint32_t count; size_t origkeylen = keylen; libssh2_sha512_ctx ctx; /* nothing crazy */ if(rounds < 1) return -1; if(passlen == 0 || saltlen == 0 || keylen == 0 || keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20) return -1; countsalt = calloc(1, saltlen + 4); if(!countsalt) return -1; stride = (keylen + sizeof(out) - 1) / sizeof(out); amt = (keylen + stride - 1) / stride; memcpy(countsalt, salt, saltlen); /* collapse password */ (void)libssh2_sha512_init(&ctx); libssh2_sha512_update(ctx, pass, passlen); libssh2_sha512_final(ctx, sha2pass); /* generate key, sizeof(out) at a time */ for(count = 1; keylen > 0; count++) { countsalt[saltlen + 0] = (uint8_t)((count >> 24) & 0xff); countsalt[saltlen + 1] = (count >> 16) & 0xff; countsalt[saltlen + 2] = (count >> 8) & 0xff; countsalt[saltlen + 3] = count & 0xff; /* first round, salt is salt */ (void)libssh2_sha512_init(&ctx); libssh2_sha512_update(ctx, countsalt, saltlen + 4); libssh2_sha512_final(ctx, sha2salt); bcrypt_hash(sha2pass, sha2salt, tmpout); memcpy(out, tmpout, sizeof(out)); for(i = 1; i < rounds; i++) { /* subsequent rounds, salt is previous output */ (void)libssh2_sha512_init(&ctx); libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)); libssh2_sha512_final(ctx, sha2salt); bcrypt_hash(sha2pass, sha2salt, tmpout); for(j = 0; j < sizeof(out); j++) out[j] ^= tmpout[j]; } /* * pbkdf2 deviation: output the key material non-linearly. */ amt = LIBSSH2_MIN(amt, keylen); for(i = 0; i < amt; i++) { size_t dest = i * stride + (count - 1); if(dest >= origkeylen) { break; } key[dest] = out[i]; } keylen -= i; } /* zap */ _libssh2_explicit_zero(out, sizeof(out)); free(countsalt); return 0; } #endif /* HAVE_BCRYPT_PBKDF */ /* Wrapper */ int _libssh2_bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, uint8_t *key, size_t keylen, unsigned int rounds) { return bcrypt_pbkdf(pass, passlen, salt, saltlen, key, keylen, rounds); } libssh2-1.11.0/src/agent.c0000644000175000017500000007600314432741311012120 00000000000000/* * Copyright (c) 2009 by Daiki Ueno * Copyright (C) 2010-2021 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include #include /* for getenv() */ #ifdef HAVE_SYS_UN_H #include #else /* Use the existence of sys/un.h as a test if Unix domain socket is supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually support them. */ #undef PF_UNIX #endif #if defined(WIN32) && !defined(LIBSSH2_WINDOWS_UWP) #define HAVE_WIN32_AGENTS #endif #include "userauth.h" #include "session.h" /* Requests from client to agent for protocol 1 key operations */ #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 #define SSH_AGENTC_RSA_CHALLENGE 3 #define SSH_AGENTC_ADD_RSA_IDENTITY 7 #define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 #define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 #define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 /* Requests from client to agent for protocol 2 key operations */ #define SSH2_AGENTC_REQUEST_IDENTITIES 11 #define SSH2_AGENTC_SIGN_REQUEST 13 #define SSH2_AGENTC_ADD_IDENTITY 17 #define SSH2_AGENTC_REMOVE_IDENTITY 18 #define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 /* Key-type independent requests from client to agent */ #define SSH_AGENTC_ADD_SMARTCARD_KEY 20 #define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 #define SSH_AGENTC_LOCK 22 #define SSH_AGENTC_UNLOCK 23 #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 /* Generic replies from agent to client */ #define SSH_AGENT_FAILURE 5 #define SSH_AGENT_SUCCESS 6 /* Replies from agent to client for protocol 1 key operations */ #define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 #define SSH_AGENT_RSA_RESPONSE 4 /* Replies from agent to client for protocol 2 key operations */ #define SSH2_AGENT_IDENTITIES_ANSWER 12 #define SSH2_AGENT_SIGN_RESPONSE 14 /* Key constraint identifiers */ #define SSH_AGENT_CONSTRAIN_LIFETIME 1 #define SSH_AGENT_CONSTRAIN_CONFIRM 2 /* Signature request methods */ #define SSH_AGENT_RSA_SHA2_256 2 #define SSH_AGENT_RSA_SHA2_512 4 /* non-blocking mode on agent connection is not yet implemented, but for future use. */ typedef enum { agent_NB_state_init = 0, agent_NB_state_request_created, agent_NB_state_request_length_sent, agent_NB_state_request_sent, agent_NB_state_response_length_received, agent_NB_state_response_received } agent_nonblocking_states; typedef struct agent_transaction_ctx { unsigned char *request; size_t request_len; unsigned char *response; size_t response_len; agent_nonblocking_states state; size_t send_recv_total; } *agent_transaction_ctx_t; typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent); typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx); typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent); struct agent_publickey { struct list_node node; /* this is the struct we expose externally */ struct libssh2_agent_publickey external; }; struct agent_ops { const agent_connect_func connect; const agent_transact_func transact; const agent_disconnect_func disconnect; }; struct _LIBSSH2_AGENT { LIBSSH2_SESSION *session; /* the session this "belongs to" */ libssh2_socket_t fd; struct agent_ops *ops; struct agent_transaction_ctx transctx; struct agent_publickey *identity; struct list_head head; /* list of public keys */ char *identity_agent_path; /* Path to a custom identity agent socket */ #ifdef HAVE_WIN32_AGENTS OVERLAPPED overlapped; HANDLE pipe; BOOL pending_io; #endif }; #include "agent_win.c" #ifdef PF_UNIX static int agent_connect_unix(LIBSSH2_AGENT *agent) { const char *path; struct sockaddr_un s_un; path = agent->identity_agent_path; if(!path) { path = getenv("SSH_AUTH_SOCK"); if(!path) return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, "no auth sock variable"); } agent->fd = socket(PF_UNIX, SOCK_STREAM, 0); if(agent->fd < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET, "failed creating socket"); s_un.sun_family = AF_UNIX; strncpy(s_un.sun_path, path, sizeof(s_un.sun_path)); s_un.sun_path[sizeof(s_un.sun_path)-1] = 0; /* make sure there's a trailing zero */ if(connect(agent->fd, (struct sockaddr*)(&s_un), sizeof(s_un)) != 0) { close(agent->fd); return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "failed connecting with agent"); } return LIBSSH2_ERROR_NONE; } #define RECV_SEND_ALL(func, socket, buffer, length, flags, abstract) \ do { \ size_t finished = 0; \ \ while(finished < length) { \ ssize_t rc; \ rc = func(socket, \ (char *)buffer + finished, length - finished, \ flags, abstract); \ if(rc < 0) \ return rc; \ \ finished += rc; \ } \ \ return finished; \ } while(0) static ssize_t _send_all(LIBSSH2_SEND_FUNC(func), libssh2_socket_t socket, const void *buffer, size_t length, int flags, void **abstract) { RECV_SEND_ALL(func, socket, buffer, length, flags, abstract); } static ssize_t _recv_all(LIBSSH2_RECV_FUNC(func), libssh2_socket_t socket, void *buffer, size_t length, int flags, void **abstract) { RECV_SEND_ALL(func, socket, buffer, length, flags, abstract); } #undef RECV_SEND_ALL static int agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) { unsigned char buf[4]; int rc; /* Send the length of the request */ if(transctx->state == agent_NB_state_request_created) { _libssh2_htonu32(buf, (uint32_t)transctx->request_len); rc = (int)_send_all(agent->session->send, agent->fd, buf, sizeof(buf), 0, &agent->session->abstract); if(rc == -EAGAIN) return LIBSSH2_ERROR_EAGAIN; else if(rc < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, "agent send failed"); transctx->state = agent_NB_state_request_length_sent; } /* Send the request body */ if(transctx->state == agent_NB_state_request_length_sent) { rc = (int)_send_all(agent->session->send, agent->fd, transctx->request, transctx->request_len, 0, &agent->session->abstract); if(rc == -EAGAIN) return LIBSSH2_ERROR_EAGAIN; else if(rc < 0) return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, "agent send failed"); transctx->state = agent_NB_state_request_sent; } /* Receive the length of a response */ if(transctx->state == agent_NB_state_request_sent) { rc = (int)_recv_all(agent->session->recv, agent->fd, buf, sizeof(buf), 0, &agent->session->abstract); if(rc < 0) { if(rc == -EAGAIN) return LIBSSH2_ERROR_EAGAIN; return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, "agent recv failed"); } transctx->response_len = _libssh2_ntohu32(buf); transctx->response = LIBSSH2_ALLOC(agent->session, transctx->response_len); if(!transctx->response) return LIBSSH2_ERROR_ALLOC; transctx->state = agent_NB_state_response_length_received; } /* Receive the response body */ if(transctx->state == agent_NB_state_response_length_received) { rc = (int)_recv_all(agent->session->recv, agent->fd, transctx->response, transctx->response_len, 0, &agent->session->abstract); if(rc < 0) { if(rc == -EAGAIN) return LIBSSH2_ERROR_EAGAIN; return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, "agent recv failed"); } transctx->state = agent_NB_state_response_received; } return 0; } static int agent_disconnect_unix(LIBSSH2_AGENT *agent) { int ret; ret = close(agent->fd); if(ret != -1) agent->fd = LIBSSH2_INVALID_SOCKET; else return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, "failed closing the agent socket"); return LIBSSH2_ERROR_NONE; } static struct agent_ops agent_ops_unix = { agent_connect_unix, agent_transact_unix, agent_disconnect_unix }; #endif /* PF_UNIX */ #ifdef HAVE_WIN32_AGENTS /* Code to talk to Pageant was taken from PuTTY. * * Portions copyright Robert de Bath, Joris van Rantwijk, Delian * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas * Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, * Markus Kuhn, Colin Watson, and CORE SDI S.A. */ #define PAGEANT_COPYDATA_ID 0x804e50ba /* random goop */ #define PAGEANT_MAX_MSGLEN 8192 static int agent_connect_pageant(LIBSSH2_AGENT *agent) { HWND hwnd; hwnd = FindWindowA("Pageant", "Pageant"); if(!hwnd) return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "failed connecting agent"); agent->fd = 0; /* Mark as the connection has been established */ return LIBSSH2_ERROR_NONE; } static int agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) { HWND hwnd; char mapname[23]; HANDLE filemap; unsigned char *p; unsigned char *p2; LRESULT id; COPYDATASTRUCT cds; if(!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL, "illegal input"); hwnd = FindWindowA("Pageant", "Pageant"); if(!hwnd) return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "found no pageant"); snprintf(mapname, sizeof(mapname), "PageantRequest%08x", (unsigned)GetCurrentThreadId()); filemap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, PAGEANT_MAX_MSGLEN, mapname); if(!filemap || filemap == INVALID_HANDLE_VALUE) return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "failed setting up pageant filemap"); p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); if(!p || !p2) { CloseHandle(filemap); return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "failed to open pageant filemap for writing"); } _libssh2_store_str(&p2, (const char *)transctx->request, transctx->request_len); cds.dwData = PAGEANT_COPYDATA_ID; cds.cbData = (DWORD)(1 + strlen(mapname)); cds.lpData = mapname; id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); if(id > 0) { transctx->response_len = _libssh2_ntohu32(p); if(transctx->response_len > PAGEANT_MAX_MSGLEN) { UnmapViewOfFile(p); CloseHandle(filemap); return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, "agent setup fail"); } transctx->response = LIBSSH2_ALLOC(agent->session, transctx->response_len); if(!transctx->response) { UnmapViewOfFile(p); CloseHandle(filemap); return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC, "agent malloc"); } memcpy(transctx->response, p + 4, transctx->response_len); } UnmapViewOfFile(p); CloseHandle(filemap); return 0; } static int agent_disconnect_pageant(LIBSSH2_AGENT *agent) { agent->fd = LIBSSH2_INVALID_SOCKET; return 0; } static struct agent_ops agent_ops_pageant = { agent_connect_pageant, agent_transact_pageant, agent_disconnect_pageant }; #endif /* HAVE_WIN32_AGENTS */ static struct { const char *name; struct agent_ops *ops; } supported_backends[] = { #ifdef HAVE_WIN32_AGENTS {"Pageant", &agent_ops_pageant}, {"OpenSSH", &agent_ops_openssh}, #endif /* HAVE_WIN32_AGENTS */ #ifdef PF_UNIX {"Unix", &agent_ops_unix}, #endif /* PF_UNIX */ {NULL, NULL} }; static int agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) { LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract); agent_transaction_ctx_t transctx = &agent->transctx; struct agent_publickey *identity = agent->identity; ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4; ssize_t method_len; unsigned char *s; int rc; unsigned char *method_name = NULL; uint32_t sign_flags = 0; ssize_t plain_len; /* Create a request to sign the data */ if(transctx->state == agent_NB_state_init) { s = transctx->request = LIBSSH2_ALLOC(session, len); if(!transctx->request) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "out of memory"); *s++ = SSH2_AGENTC_SIGN_REQUEST; /* key blob */ _libssh2_store_str(&s, (const char *)identity->external.blob, identity->external.blob_len); /* data */ _libssh2_store_str(&s, (const char *)data, data_len); /* flags */ if(session->userauth_pblc_method_len > 0 && session->userauth_pblc_method) { if(session->userauth_pblc_method_len == 12 && !memcmp(session->userauth_pblc_method, "rsa-sha2-512", 12)) { sign_flags = SSH_AGENT_RSA_SHA2_512; } else if(session->userauth_pblc_method_len == 12 && !memcmp(session->userauth_pblc_method, "rsa-sha2-256", 12)) { sign_flags = SSH_AGENT_RSA_SHA2_256; } } _libssh2_store_u32(&s, sign_flags); transctx->request_len = s - transctx->request; transctx->send_recv_total = 0; transctx->state = agent_NB_state_request_created; } /* Make sure to be re-called as a result of EAGAIN. */ if(*transctx->request != SSH2_AGENTC_SIGN_REQUEST) return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, "illegal request"); if(!agent->ops) /* if no agent has been connected, bail out */ return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, "agent not connected"); rc = agent->ops->transact(agent, transctx); if(rc) { goto error; } LIBSSH2_FREE(session, transctx->request); transctx->request = NULL; len = transctx->response_len; s = transctx->response; len--; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } if(*s != SSH2_AGENT_SIGN_RESPONSE) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } s++; /* Skip the entire length of the signature */ len -= 4; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } s += 4; /* Skip signing method */ len -= 4; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } method_len = _libssh2_ntohu32(s); s += 4; len -= method_len; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } /* method name */ method_name = LIBSSH2_ALLOC(session, method_len); if(!method_name) { rc = LIBSSH2_ERROR_ALLOC; goto error; } memcpy(method_name, s, method_len); s += method_len; plain_len = plain_method((char *)session->userauth_pblc_method, session->userauth_pblc_method_len); /* check to see if we match requested */ if(((size_t)method_len != session->userauth_pblc_method_len && method_len != plain_len) || memcmp(method_name, session->userauth_pblc_method, method_len)) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agent sign method %.*s", method_len, method_name)); rc = LIBSSH2_ERROR_ALGO_UNSUPPORTED; goto error; } /* Read the signature */ len -= 4; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } *sig_len = _libssh2_ntohu32(s); s += 4; len -= *sig_len; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } *sig = LIBSSH2_ALLOC(session, *sig_len); if(!*sig) { rc = LIBSSH2_ERROR_ALLOC; goto error; } memcpy(*sig, s, *sig_len); error: if(method_name) LIBSSH2_FREE(session, method_name); LIBSSH2_FREE(session, transctx->request); transctx->request = NULL; LIBSSH2_FREE(session, transctx->response); transctx->response = NULL; transctx->state = agent_NB_state_init; return _libssh2_error(session, rc, "agent sign failure"); } static int agent_list_identities(LIBSSH2_AGENT *agent) { agent_transaction_ctx_t transctx = &agent->transctx; ssize_t len, num_identities; unsigned char *s; int rc; unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES; /* Create a request to list identities */ if(transctx->state == agent_NB_state_init) { transctx->request = &c; transctx->request_len = 1; transctx->send_recv_total = 0; transctx->state = agent_NB_state_request_created; } /* Make sure to be re-called as a result of EAGAIN. */ if(*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, "illegal agent request"); if(!agent->ops) /* if no agent has been connected, bail out */ return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, "agent not connected"); rc = agent->ops->transact(agent, transctx); if(rc) { LIBSSH2_FREE(agent->session, transctx->response); transctx->response = NULL; return rc; } transctx->request = NULL; len = transctx->response_len; s = transctx->response; len--; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } if(*s != SSH2_AGENT_IDENTITIES_ANSWER) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } s++; /* Read the length of identities */ len -= 4; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } num_identities = _libssh2_ntohu32(s); s += 4; while(num_identities--) { struct agent_publickey *identity; size_t comment_len; /* Read the length of the blob */ len -= 4; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; goto error; } identity = LIBSSH2_ALLOC(agent->session, sizeof(*identity)); if(!identity) { rc = LIBSSH2_ERROR_ALLOC; goto error; } identity->external.blob_len = _libssh2_ntohu32(s); s += 4; /* Read the blob */ len -= identity->external.blob_len; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; LIBSSH2_FREE(agent->session, identity); goto error; } identity->external.blob = LIBSSH2_ALLOC(agent->session, identity->external.blob_len); if(!identity->external.blob) { rc = LIBSSH2_ERROR_ALLOC; LIBSSH2_FREE(agent->session, identity); goto error; } memcpy(identity->external.blob, s, identity->external.blob_len); s += identity->external.blob_len; /* Read the length of the comment */ len -= 4; if(len < 0) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; LIBSSH2_FREE(agent->session, identity->external.blob); LIBSSH2_FREE(agent->session, identity); goto error; } comment_len = _libssh2_ntohu32(s); s += 4; if(comment_len > (size_t)len) { rc = LIBSSH2_ERROR_AGENT_PROTOCOL; LIBSSH2_FREE(agent->session, identity->external.blob); LIBSSH2_FREE(agent->session, identity); goto error; } /* Read the comment */ len -= comment_len; identity->external.comment = LIBSSH2_ALLOC(agent->session, comment_len + 1); if(!identity->external.comment) { rc = LIBSSH2_ERROR_ALLOC; LIBSSH2_FREE(agent->session, identity->external.blob); LIBSSH2_FREE(agent->session, identity); goto error; } identity->external.comment[comment_len] = '\0'; memcpy(identity->external.comment, s, comment_len); s += comment_len; _libssh2_list_add(&agent->head, &identity->node); } error: LIBSSH2_FREE(agent->session, transctx->response); transctx->response = NULL; return _libssh2_error(agent->session, rc, "agent list id failed"); } static void agent_free_identities(LIBSSH2_AGENT *agent) { struct agent_publickey *node; struct agent_publickey *next; for(node = _libssh2_list_first(&agent->head); node; node = next) { next = _libssh2_list_next(&node->node); LIBSSH2_FREE(agent->session, node->external.blob); LIBSSH2_FREE(agent->session, node->external.comment); LIBSSH2_FREE(agent->session, node); } _libssh2_list_init(&agent->head); } #define AGENT_PUBLICKEY_MAGIC 0x3bdefed2 /* * agent_publickey_to_external * * Copies data from the internal to the external representation struct. * */ static struct libssh2_agent_publickey * agent_publickey_to_external(struct agent_publickey *node) { struct libssh2_agent_publickey *ext = &node->external; ext->magic = AGENT_PUBLICKEY_MAGIC; ext->node = node; return ext; } /* * libssh2_agent_init * * Init an ssh-agent handle. Returns the pointer to the handle. * */ LIBSSH2_API LIBSSH2_AGENT * libssh2_agent_init(LIBSSH2_SESSION *session) { LIBSSH2_AGENT *agent; agent = LIBSSH2_CALLOC(session, sizeof(*agent)); if(!agent) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate space for agent connection"); return NULL; } agent->fd = LIBSSH2_INVALID_SOCKET; agent->session = session; agent->identity_agent_path = NULL; _libssh2_list_init(&agent->head); #ifdef HAVE_WIN32_AGENTS agent->pipe = INVALID_HANDLE_VALUE; memset(&agent->overlapped, 0, sizeof(OVERLAPPED)); agent->pending_io = FALSE; #endif return agent; } /* * libssh2_agent_connect * * Connect to an ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_connect(LIBSSH2_AGENT *agent) { int i, rc = -1; for(i = 0; supported_backends[i].name; i++) { agent->ops = supported_backends[i].ops; rc = (agent->ops->connect)(agent); if(!rc) return 0; } return rc; } /* * libssh2_agent_list_identities * * Request ssh-agent to list identities. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_list_identities(LIBSSH2_AGENT *agent) { memset(&agent->transctx, 0, sizeof(agent->transctx)); /* Abandon the last fetched identities */ agent_free_identities(agent); return agent_list_identities(agent); } /* * libssh2_agent_get_identity * * Traverse the internal list of public keys. Pass NULL to 'prev' to get * the first one. Or pass a pointer to the previously returned one to get the * next. * * Returns: * 0 if a fine public key was stored in 'store' * 1 if end of public keys * [negative] on errors */ LIBSSH2_API int libssh2_agent_get_identity(LIBSSH2_AGENT *agent, struct libssh2_agent_publickey **ext, struct libssh2_agent_publickey *oprev) { struct agent_publickey *node; if(oprev && oprev->node) { /* we have a starting point */ struct agent_publickey *prev = oprev->node; /* get the next node in the list */ node = _libssh2_list_next(&prev->node); } else node = _libssh2_list_first(&agent->head); if(!node) /* no (more) node */ return 1; *ext = agent_publickey_to_external(node); return 0; } /* * libssh2_agent_userauth * * Do publickey user authentication with the help of ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_userauth(LIBSSH2_AGENT *agent, const char *username, struct libssh2_agent_publickey *identity) { void *abstract = agent; int rc; if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) { memset(&agent->transctx, 0, sizeof(agent->transctx)); agent->identity = identity->node; } BLOCK_ADJUST(rc, agent->session, _libssh2_userauth_publickey(agent->session, username, strlen(username), identity->blob, identity->blob_len, agent_sign, &abstract)); return rc; } /* * libssh2_agent_sign * * Sign a payload using a system-installed ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_sign(LIBSSH2_AGENT *agent, struct libssh2_agent_publickey *identity, unsigned char **sig, size_t *s_len, const unsigned char *data, size_t d_len, const char *method, unsigned int method_len) { void *abstract = agent; int rc; uint32_t methodLen; if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) { memset(&agent->transctx, 0, sizeof(agent->transctx)); agent->identity = identity->node; } if(identity->blob_len < sizeof(uint32_t)) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } methodLen = _libssh2_ntohu32(identity->blob); if(identity->blob_len < sizeof(uint32_t) + methodLen) { return LIBSSH2_ERROR_BUFFER_TOO_SMALL; } agent->session->userauth_pblc_method_len = method_len; agent->session->userauth_pblc_method = LIBSSH2_ALLOC(agent->session, method_len); memcpy(agent->session->userauth_pblc_method, method, methodLen); rc = agent_sign(agent->session, sig, s_len, data, d_len, &abstract); LIBSSH2_FREE(agent->session, agent->session->userauth_pblc_method); agent->session->userauth_pblc_method = NULL; agent->session->userauth_pblc_method_len = 0; return rc; } /* * libssh2_agent_disconnect * * Close a connection to an ssh-agent. * * Returns 0 if succeeded, or a negative value for error. */ LIBSSH2_API int libssh2_agent_disconnect(LIBSSH2_AGENT *agent) { if(agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET) return agent->ops->disconnect(agent); return 0; } /* * libssh2_agent_free * * Free an ssh-agent handle. This function also frees the internal * collection of public keys. */ LIBSSH2_API void libssh2_agent_free(LIBSSH2_AGENT *agent) { /* Allow connection freeing when the socket has lost its connection */ if(agent->fd != LIBSSH2_INVALID_SOCKET) { libssh2_agent_disconnect(agent); } if(agent->identity_agent_path) LIBSSH2_FREE(agent->session, agent->identity_agent_path); agent_free_identities(agent); LIBSSH2_FREE(agent->session, agent); } /* * libssh2_agent_set_identity_path * * Allows a custom agent socket path beyond SSH_AUTH_SOCK env * */ LIBSSH2_API void libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, const char *path) { if(agent->identity_agent_path) { LIBSSH2_FREE(agent->session, agent->identity_agent_path); agent->identity_agent_path = NULL; } if(path) { size_t path_len = strlen(path); if(path_len < SIZE_MAX - 1) { char *path_buf = LIBSSH2_ALLOC(agent->session, path_len + 1); memcpy(path_buf, path, path_len); path_buf[path_len] = '\0'; agent->identity_agent_path = path_buf; } } } /* * libssh2_agent_get_identity_path * * Returns the custom agent socket path if set * */ LIBSSH2_API const char *libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent) { return agent->identity_agent_path; } libssh2-1.11.0/src/openssl.c0000644000175000017500000035364214432741311012514 00000000000000/* Copyright (C) 2009, 2010 Simon Josefsson * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. * Copyright (c) 2004-2006, Sara Golemon * * Author: Simon Josefsson * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */ #include #include #ifndef EVP_MAX_BLOCK_LENGTH #define EVP_MAX_BLOCK_LENGTH 32 #endif int read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session, const char *key_type, const char *filedata, size_t filedata_len, unsigned const char *passphrase); static int _libssh2_sk_pub_openssh_keyfilememory(LIBSSH2_SESSION *session, void **key_ctx, const char *key_type, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, unsigned const char *passphrase); #if LIBSSH2_RSA || LIBSSH2_DSA || LIBSSH2_ECDSA static unsigned char * write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes) { unsigned char *p = buf; /* Left space for bn size which will be written below. */ p += 4; *p = 0; BN_bn2bin(bn, p + 1); if(!(*(p + 1) & 0x80)) { memmove(p, p + 1, --bn_bytes); } _libssh2_htonu32(p - 4, bn_bytes); /* Post write bn size. */ return p + bn_bytes; } #endif int _libssh2_openssl_random(void *buf, size_t len) { if(len > INT_MAX) { return -1; } return RAND_bytes(buf, (int)len) == 1 ? 0 : -1; } #if LIBSSH2_RSA int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { BIGNUM * e; BIGNUM * n; BIGNUM * d = 0; BIGNUM * p = 0; BIGNUM * q = 0; BIGNUM * dmp1 = 0; BIGNUM * dmq1 = 0; BIGNUM * iqmp = 0; e = BN_new(); BN_bin2bn(edata, (int) elen, e); n = BN_new(); BN_bin2bn(ndata, (int) nlen, n); if(ddata) { d = BN_new(); BN_bin2bn(ddata, (int) dlen, d); p = BN_new(); BN_bin2bn(pdata, (int) plen, p); q = BN_new(); BN_bin2bn(qdata, (int) qlen, q); dmp1 = BN_new(); BN_bin2bn(e1data, (int) e1len, dmp1); dmq1 = BN_new(); BN_bin2bn(e2data, (int) e2len, dmq1); iqmp = BN_new(); BN_bin2bn(coeffdata, (int) coefflen, iqmp); } *rsa = RSA_new(); #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_key(*rsa, n, e, d); #else (*rsa)->e = e; (*rsa)->n = n; (*rsa)->d = d; #endif #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_factors(*rsa, p, q); #else (*rsa)->p = p; (*rsa)->q = q; #endif #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_crt_params(*rsa, dmp1, dmq1, iqmp); #else (*rsa)->dmp1 = dmp1; (*rsa)->dmq1 = dmq1; (*rsa)->iqmp = iqmp; #endif return 0; } int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, size_t hash_len, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { int ret; int nid_type; unsigned char *hash = malloc(hash_len); if(!hash) return -1; if(hash_len == SHA_DIGEST_LENGTH) { nid_type = NID_sha1; ret = _libssh2_sha1(m, m_len, hash); } else if(hash_len == SHA256_DIGEST_LENGTH) { nid_type = NID_sha256; ret = _libssh2_sha256(m, m_len, hash); } else if(hash_len == SHA512_DIGEST_LENGTH) { nid_type = NID_sha512; ret = _libssh2_sha512(m, m_len, hash); } else { /* silence: warning C4701: potentially uninitialized local variable 'nid_type' used */ #if defined(_MSC_VER) nid_type = 0; #endif ret = -1; /* unsupported digest */ } if(ret) { free(hash); return -1; /* failure */ } ret = RSA_verify(nid_type, hash, (unsigned int) hash_len, (unsigned char *) sig, (unsigned int) sig_len, rsactx); free(hash); return (ret == 1) ? 0 : -1; } #if LIBSSH2_RSA_SHA1 int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { return _libssh2_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, sig, sig_len, m, m_len); } #endif #endif #if LIBSSH2_DSA int _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, const unsigned char *p, unsigned long p_len, const unsigned char *q, unsigned long q_len, const unsigned char *g, unsigned long g_len, const unsigned char *y, unsigned long y_len, const unsigned char *x, unsigned long x_len) { BIGNUM * p_bn; BIGNUM * q_bn; BIGNUM * g_bn; BIGNUM * pub_key; BIGNUM * priv_key = NULL; p_bn = BN_new(); BN_bin2bn(p, (int) p_len, p_bn); q_bn = BN_new(); BN_bin2bn(q, (int) q_len, q_bn); g_bn = BN_new(); BN_bin2bn(g, (int) g_len, g_bn); pub_key = BN_new(); BN_bin2bn(y, (int) y_len, pub_key); if(x_len) { priv_key = BN_new(); BN_bin2bn(x, (int) x_len, priv_key); } *dsactx = DSA_new(); #ifdef HAVE_OPAQUE_STRUCTS DSA_set0_pqg(*dsactx, p_bn, q_bn, g_bn); #else (*dsactx)->p = p_bn; (*dsactx)->g = g_bn; (*dsactx)->q = q_bn; #endif #ifdef HAVE_OPAQUE_STRUCTS DSA_set0_key(*dsactx, pub_key, priv_key); #else (*dsactx)->pub_key = pub_key; (*dsactx)->priv_key = priv_key; #endif return 0; } int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, const unsigned char *sig, const unsigned char *m, size_t m_len) { unsigned char hash[SHA_DIGEST_LENGTH]; DSA_SIG * dsasig; BIGNUM * r; BIGNUM * s; int ret = -1; r = BN_new(); BN_bin2bn(sig, 20, r); s = BN_new(); BN_bin2bn(sig + 20, 20, s); dsasig = DSA_SIG_new(); #ifdef HAVE_OPAQUE_STRUCTS DSA_SIG_set0(dsasig, r, s); #else dsasig->r = r; dsasig->s = s; #endif if(!_libssh2_sha1(m, m_len, hash)) /* _libssh2_sha1() succeeded */ ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, dsasig, dsactx); DSA_SIG_free(dsasig); return (ret == 1) ? 0 : -1; } #endif /* LIBSSH_DSA */ #if LIBSSH2_ECDSA /* _libssh2_ecdsa_get_curve_type * * returns key curve type that maps to libssh2_curve_type * */ libssh2_curve_type _libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx) { const EC_GROUP *group = EC_KEY_get0_group(ec_ctx); return EC_GROUP_get_curve_name(group); } /* _libssh2_ecdsa_curve_type_from_name * * returns 0 for success, key curve type that maps to libssh2_curve_type * */ int _libssh2_ecdsa_curve_type_from_name(const char *name, libssh2_curve_type *out_type) { int ret = 0; libssh2_curve_type type; if(!name || strlen(name) != 19) return -1; if(strcmp(name, "ecdsa-sha2-nistp256") == 0) type = LIBSSH2_EC_CURVE_NISTP256; else if(strcmp(name, "ecdsa-sha2-nistp384") == 0) type = LIBSSH2_EC_CURVE_NISTP384; else if(strcmp(name, "ecdsa-sha2-nistp521") == 0) type = LIBSSH2_EC_CURVE_NISTP521; else { /* silence: warning C4701: potentially uninitialized local variable 'type' used */ #if defined(_MSC_VER) type = (libssh2_curve_type)0; #endif ret = -1; } if(ret == 0 && out_type) { *out_type = type; } return ret; } /* _libssh2_ecdsa_curve_name_with_octal_new * * Creates a new public key given an octal string, length and type * */ int _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx, const unsigned char *k, size_t k_len, libssh2_curve_type curve) { int ret = 0; const EC_GROUP *ec_group = NULL; EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve); EC_POINT *point = NULL; if(ec_key) { ec_group = EC_KEY_get0_group(ec_key); point = EC_POINT_new(ec_group); ret = EC_POINT_oct2point(ec_group, point, k, k_len, NULL); ret = EC_KEY_set_public_key(ec_key, point); if(point) EC_POINT_free(point); if(ec_ctx) *ec_ctx = ec_key; } return (ret == 1) ? 0 : -1; } #define LIBSSH2_ECDSA_VERIFY(digest_type) \ do { \ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ libssh2_sha##digest_type(m, m_len, hash); \ ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH, \ ecdsa_sig, ec_key); \ } while(0) int _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx, const unsigned char *r, size_t r_len, const unsigned char *s, size_t s_len, const unsigned char *m, size_t m_len) { int ret = 0; EC_KEY *ec_key = (EC_KEY*)ctx; libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_key); #ifdef HAVE_OPAQUE_STRUCTS ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new(); BIGNUM *pr = BN_new(); BIGNUM *ps = BN_new(); BN_bin2bn(r, (int) r_len, pr); BN_bin2bn(s, (int) s_len, ps); ECDSA_SIG_set0(ecdsa_sig, pr, ps); #else ECDSA_SIG ecdsa_sig_; ECDSA_SIG *ecdsa_sig = &ecdsa_sig_; ecdsa_sig_.r = BN_new(); BN_bin2bn(r, (int) r_len, ecdsa_sig_.r); ecdsa_sig_.s = BN_new(); BN_bin2bn(s, (int) s_len, ecdsa_sig_.s); #endif if(type == LIBSSH2_EC_CURVE_NISTP256) { LIBSSH2_ECDSA_VERIFY(256); } else if(type == LIBSSH2_EC_CURVE_NISTP384) { LIBSSH2_ECDSA_VERIFY(384); } else if(type == LIBSSH2_EC_CURVE_NISTP521) { LIBSSH2_ECDSA_VERIFY(512); } #ifdef HAVE_OPAQUE_STRUCTS if(ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); #else BN_clear_free(ecdsa_sig_.s); BN_clear_free(ecdsa_sig_.r); #endif return (ret == 1) ? 0 : -1; } #endif /* LIBSSH2_ECDSA */ int _libssh2_cipher_init(_libssh2_cipher_ctx * h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { #ifdef HAVE_OPAQUE_STRUCTS #if LIBSSH2_AES_GCM const int is_aesgcm = (algo == EVP_aes_128_gcm) || (algo == EVP_aes_256_gcm); #endif /* LIBSSH2_AES_GCM */ int rc; *h = EVP_CIPHER_CTX_new(); rc = !EVP_CipherInit(*h, algo(), secret, iv, encrypt); #if LIBSSH2_AES_GCM if(is_aesgcm) { /* Sets both fixed and invocation_counter parts of IV */ rc |= !EVP_CIPHER_CTX_ctrl(*h, EVP_CTRL_AEAD_SET_IV_FIXED, -1, iv); } #endif /* LIBSSH2_AES_GCM */ return rc; #else # if LIBSSH2_AES_GCM # error AES-GCM is only supported with opaque structs in use # endif /* LIBSSH2_AES_GCM */ EVP_CIPHER_CTX_init(h); return !EVP_CipherInit(h, algo(), secret, iv, encrypt); #endif } int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize, int firstlast) { unsigned char buf[EVP_MAX_BLOCK_LENGTH]; int ret = 1; int rc = 1; #if LIBSSH2_AES_GCM const int is_aesgcm = (algo == EVP_aes_128_gcm) || (algo == EVP_aes_256_gcm); char lastiv[1]; #else const int is_aesgcm = 0; #endif /* LIBSSH2_AES_GCM */ /* length of AES-GCM Authentication Tag */ const int authlen = is_aesgcm ? 16 : 0; /* length of AAD, only on the first block */ const int aadlen = (is_aesgcm && IS_FIRST(firstlast)) ? 4 : 0; /* size of AT, if present */ const int authenticationtag = IS_LAST(firstlast) ? authlen : 0; /* length to encrypt */ const int cryptlen = (unsigned int)blocksize - aadlen - authenticationtag; (void)algo; assert(blocksize <= sizeof(buf)); assert(cryptlen >= 0); #if LIBSSH2_AES_GCM /* First block */ if(IS_FIRST(firstlast)) { /* Increments invocation_counter portion of IV */ if(is_aesgcm) { ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_IV_GEN, 1, lastiv); } if(aadlen) { /* Include the 4 byte packet length as AAD */ ret = EVP_Cipher(*ctx, NULL, block, aadlen); } } /* Last portion of block to encrypt/decrypt */ if(IS_LAST(firstlast)) { if(is_aesgcm && !encrypt) { /* set tag on decryption */ ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_TAG, authlen, block + blocksize - authlen); } } #else (void)encrypt; (void)firstlast; #endif /* LIBSSH2_AES_GCM */ if(cryptlen > 0) { #ifdef HAVE_OPAQUE_STRUCTS ret = EVP_Cipher(*ctx, buf + aadlen, block + aadlen, cryptlen); #else ret = EVP_Cipher(ctx, buf + aadlen, block + aadlen, cryptlen); #endif } #if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || \ defined(LIBSSH2_WOLFSSL) if(ret != -1) #else if(ret >= 1) #endif { rc = 0; if(IS_LAST(firstlast)) { /* This is the last block. encrypt: compute tag, if applicable decrypt: verify tag, if applicable in!=NULL is equivalent to EVP_CipherUpdate in==NULL is equivalent to EVP_CipherFinal */ #ifdef HAVE_OPAQUE_STRUCTS ret = EVP_Cipher(*ctx, NULL, NULL, 0); /* final */ #else ret = EVP_Cipher(ctx, NULL, NULL, 0); /* final */ #endif if(ret < 0) { ret = 0; } else { ret = 1; #if LIBSSH2_AES_GCM if(is_aesgcm && encrypt) { /* write the Authentication Tag a.k.a. MAC at the end of the block */ assert(authenticationtag == authlen); ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_GET_TAG, authlen, block + blocksize - authenticationtag); } #endif /* LIBSSH2_AES_GCM */ } } /* Copy en/decrypted data back to the caller. The first aadlen should not be touched because they weren't encrypted and are unmodified. */ memcpy(block + aadlen, buf + aadlen, cryptlen); rc = !ret; } /* TODO: the return code should distinguish between decryption errors and invalid MACs */ return rc; } void _libssh2_openssl_crypto_init(void) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ !defined(LIBRESSL_VERSION_NUMBER) #ifndef OPENSSL_NO_ENGINE ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); #endif #else OpenSSL_add_all_algorithms(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); #ifndef OPENSSL_NO_ENGINE ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); #endif #endif } void _libssh2_openssl_crypto_exit(void) { } #if LIBSSH2_RSA || LIBSSH2_DSA || LIBSSH2_ECDSA || LIBSSH2_ED25519 /* TODO: Optionally call a passphrase callback specified by the * calling program */ static int passphrase_cb(char *buf, int size, int rwflag, char *passphrase) { int passphrase_len = (int) strlen(passphrase); (void)rwflag; if(passphrase_len > (size - 1)) { passphrase_len = size - 1; } memcpy(buf, passphrase, passphrase_len); buf[passphrase_len] = '\0'; return passphrase_len; } typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *, void *u); static int read_private_key_from_memory(void **key_ctx, pem_read_bio_func read_private_key, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { BIO * bp; *key_ctx = NULL; #if OPENSSL_VERSION_NUMBER >= 0x1000200fL bp = BIO_new_mem_buf(filedata, (int)filedata_len); #else bp = BIO_new_mem_buf((char *)filedata, (int)filedata_len); #endif if(!bp) { return -1; } *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, (void *) passphrase); BIO_free(bp); return (*key_ctx) ? 0 : -1; } #endif #if LIBSSH2_RSA || LIBSSH2_DSA || LIBSSH2_ECDSA static int read_private_key_from_file(void **key_ctx, pem_read_bio_func read_private_key, const char *filename, unsigned const char *passphrase) { BIO * bp; *key_ctx = NULL; bp = BIO_new_file(filename, "r"); if(!bp) { return -1; } *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, (void *) passphrase); BIO_free(bp); return (*key_ctx) ? 0 : -1; } #endif #if LIBSSH2_RSA int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { int rc; pem_read_bio_func read_rsa = (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_memory((void **) rsa, read_rsa, filedata, filedata_len, passphrase); if(rc) { rc = read_openssh_private_key_from_memory((void **)rsa, session, "ssh-rsa", filedata, filedata_len, passphrase); } return rc; } static unsigned char * gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa, size_t *key_len) { int e_bytes, n_bytes; unsigned long len; unsigned char *key; unsigned char *p; const BIGNUM * e; const BIGNUM * n; #ifdef HAVE_OPAQUE_STRUCTS RSA_get0_key(rsa, &n, &e, NULL); #else e = rsa->e; n = rsa->n; #endif e_bytes = BN_num_bytes(e) + 1; n_bytes = BN_num_bytes(n) + 1; /* Key form is "ssh-rsa" + e + n. */ len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; key = LIBSSH2_ALLOC(session, len); if(!key) { return NULL; } /* Process key encoding. */ p = key; _libssh2_htonu32(p, 7); /* Key type. */ p += 4; memcpy(p, "ssh-rsa", 7); p += 7; p = write_bn(p, e, e_bytes); p = write_bn(p, n, n_bytes); *key_len = (size_t)(p - key); return key; } static int gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, EVP_PKEY *pk) { RSA* rsa = NULL; unsigned char *key; unsigned char *method_buf = NULL; size_t key_len; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from RSA private key envelope")); rsa = EVP_PKEY_get1_RSA(pk); if(!rsa) { /* Assume memory allocation error... what else could it be ? */ goto __alloc_error; } method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-rsa. */ if(!method_buf) { goto __alloc_error; } key = gen_publickey_from_rsa(session, rsa, &key_len); if(!key) { goto __alloc_error; } RSA_free(rsa); memcpy(method_buf, "ssh-rsa", 7); *method = method_buf; *method_len = 7; *pubkeydata = key; *pubkeydata_len = key_len; return 0; __alloc_error: if(rsa) { RSA_free(rsa); } if(method_buf) { LIBSSH2_FREE(session, method_buf); } return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); } static int _libssh2_rsa_new_additional_parameters(RSA *rsa) { BN_CTX *ctx = NULL; BIGNUM *aux = NULL; BIGNUM *dmp1 = NULL; BIGNUM *dmq1 = NULL; const BIGNUM *p = NULL; const BIGNUM *q = NULL; const BIGNUM *d = NULL; int rc = 0; #ifdef HAVE_OPAQUE_STRUCTS RSA_get0_key(rsa, NULL, NULL, &d); RSA_get0_factors(rsa, &p, &q); #else d = (*rsa).d; p = (*rsa).p; q = (*rsa).q; #endif ctx = BN_CTX_new(); if(!ctx) return -1; aux = BN_new(); if(!aux) { rc = -1; goto out; } dmp1 = BN_new(); if(!dmp1) { rc = -1; goto out; } dmq1 = BN_new(); if(!dmq1) { rc = -1; goto out; } if((BN_sub(aux, q, BN_value_one()) == 0) || (BN_mod(dmq1, d, aux, ctx) == 0) || (BN_sub(aux, p, BN_value_one()) == 0) || (BN_mod(dmp1, d, aux, ctx) == 0)) { rc = -1; goto out; } #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_crt_params(rsa, dmp1, dmq1, NULL); #else (*rsa).dmp1 = dmp1; (*rsa).dmq1 = dmq1; #endif out: if(aux) BN_clear_free(aux); BN_CTX_free(ctx); if(rc) { if(dmp1) BN_clear_free(dmp1); if(dmq1) BN_clear_free(dmq1); } return rc; } static int gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session, struct string_buf *decrypted, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, libssh2_rsa_ctx **rsa_ctx) { int rc = 0; size_t nlen, elen, dlen, plen, qlen, coefflen, commentlen; unsigned char *n, *e, *d, *p, *q, *coeff, *comment; RSA *rsa = NULL; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing RSA keys from private key data")); /* public key data */ if(_libssh2_get_bignum_bytes(decrypted, &n, &nlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no n"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &e, &elen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no e"); return -1; } /* private key data */ if(_libssh2_get_bignum_bytes(decrypted, &d, &dlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no d"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &coeff, &coefflen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no coeff"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no p"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no q"); return -1; } if(_libssh2_get_string(decrypted, &comment, &commentlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "RSA no comment"); return -1; } rc = _libssh2_rsa_new(&rsa, e, (unsigned long)elen, n, (unsigned long)nlen, d, (unsigned long)dlen, p, (unsigned long)plen, q, (unsigned long)qlen, NULL, 0, NULL, 0, coeff, (unsigned long)coefflen); if(rc) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Could not create RSA private key")); goto fail; } if(rsa) rc = _libssh2_rsa_new_additional_parameters(rsa); if(rsa && pubkeydata && method) { EVP_PKEY *pk = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pk, rsa); rc = gen_publickey_from_rsa_evp(session, method, method_len, pubkeydata, pubkeydata_len, pk); if(pk) EVP_PKEY_free(pk); } if(rsa_ctx) *rsa_ctx = rsa; else RSA_free(rsa); return rc; fail: if(rsa) RSA_free(rsa); return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); } static int _libssh2_rsa_new_openssh_private(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { FILE *fp; int rc; unsigned char *buf = NULL; struct string_buf *decrypted = NULL; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(filename, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open OpenSSH RSA private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); fclose(fp); if(rc) { return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } if(strcmp("ssh-rsa", (const char *)buf) == 0) { rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted, NULL, 0, NULL, 0, rsa); } else { rc = -1; } if(decrypted) _libssh2_string_buf_free(session, decrypted); return rc; } int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { int rc; pem_read_bio_func read_rsa = (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_file((void **) rsa, read_rsa, filename, passphrase); if(rc) { rc = _libssh2_rsa_new_openssh_private(rsa, session, filename, passphrase); } return rc; } #endif #if LIBSSH2_DSA int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { int rc; pem_read_bio_func read_dsa = (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_memory((void **)dsa, read_dsa, filedata, filedata_len, passphrase); if(rc) { rc = read_openssh_private_key_from_memory((void **)dsa, session, "ssh-dsa", filedata, filedata_len, passphrase); } return rc; } static unsigned char * gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa, size_t *key_len) { int p_bytes, q_bytes, g_bytes, k_bytes; unsigned long len; unsigned char *key; unsigned char *p; const BIGNUM * p_bn; const BIGNUM * q; const BIGNUM * g; const BIGNUM * pub_key; #ifdef HAVE_OPAQUE_STRUCTS DSA_get0_pqg(dsa, &p_bn, &q, &g); #else p_bn = dsa->p; q = dsa->q; g = dsa->g; #endif #ifdef HAVE_OPAQUE_STRUCTS DSA_get0_key(dsa, &pub_key, NULL); #else pub_key = dsa->pub_key; #endif p_bytes = BN_num_bytes(p_bn) + 1; q_bytes = BN_num_bytes(q) + 1; g_bytes = BN_num_bytes(g) + 1; k_bytes = BN_num_bytes(pub_key) + 1; /* Key form is "ssh-dss" + p + q + g + pub_key. */ len = 4 + 7 + 4 + p_bytes + 4 + q_bytes + 4 + g_bytes + 4 + k_bytes; key = LIBSSH2_ALLOC(session, len); if(!key) { return NULL; } /* Process key encoding. */ p = key; _libssh2_htonu32(p, 7); /* Key type. */ p += 4; memcpy(p, "ssh-dss", 7); p += 7; p = write_bn(p, p_bn, p_bytes); p = write_bn(p, q, q_bytes); p = write_bn(p, g, g_bytes); p = write_bn(p, pub_key, k_bytes); *key_len = (size_t)(p - key); return key; } static int gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, EVP_PKEY *pk) { DSA* dsa = NULL; unsigned char *key; unsigned char *method_buf = NULL; size_t key_len; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from DSA private key envelope")); dsa = EVP_PKEY_get1_DSA(pk); if(!dsa) { /* Assume memory allocation error... what else could it be ? */ goto __alloc_error; } method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-dss. */ if(!method_buf) { goto __alloc_error; } key = gen_publickey_from_dsa(session, dsa, &key_len); if(!key) { goto __alloc_error; } DSA_free(dsa); memcpy(method_buf, "ssh-dss", 7); *method = method_buf; *method_len = 7; *pubkeydata = key; *pubkeydata_len = key_len; return 0; __alloc_error: if(dsa) { DSA_free(dsa); } if(method_buf) { LIBSSH2_FREE(session, method_buf); } return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); } static int gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session, struct string_buf *decrypted, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, libssh2_dsa_ctx **dsa_ctx) { int rc = 0; size_t plen, qlen, glen, pub_len, priv_len; unsigned char *p, *q, *g, *pub_key, *priv_key; DSA *dsa = NULL; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing DSA keys from private key data")); if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "DSA no p"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "DSA no q"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &g, &glen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "DSA no g"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &pub_key, &pub_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "DSA no public key"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &priv_key, &priv_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "DSA no private key"); return -1; } rc = _libssh2_dsa_new(&dsa, p, (unsigned long)plen, q, (unsigned long)qlen, g, (unsigned long)glen, pub_key, (unsigned long)pub_len, priv_key, (unsigned long)priv_len); if(rc) { _libssh2_debug((session, LIBSSH2_ERROR_PROTO, "Could not create DSA private key")); goto fail; } if(dsa && pubkeydata && method) { EVP_PKEY *pk = EVP_PKEY_new(); EVP_PKEY_set1_DSA(pk, dsa); rc = gen_publickey_from_dsa_evp(session, method, method_len, pubkeydata, pubkeydata_len, pk); if(pk) EVP_PKEY_free(pk); } if(dsa_ctx) *dsa_ctx = dsa; else DSA_free(dsa); return rc; fail: if(dsa) DSA_free(dsa); return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); } static int _libssh2_dsa_new_openssh_private(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { FILE *fp; int rc; unsigned char *buf = NULL; struct string_buf *decrypted = NULL; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(filename, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open OpenSSH DSA private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); fclose(fp); if(rc) { return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } if(strcmp("ssh-dss", (const char *)buf) == 0) { rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted, NULL, 0, NULL, 0, dsa); } else { rc = -1; } if(decrypted) _libssh2_string_buf_free(session, decrypted); return rc; } int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { int rc; pem_read_bio_func read_dsa = (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_file((void **) dsa, read_dsa, filename, passphrase); if(rc) { rc = _libssh2_dsa_new_openssh_private(dsa, session, filename, passphrase); } return rc; } #endif /* LIBSSH_DSA */ #if LIBSSH2_ECDSA int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { int rc; pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_memory((void **) ec_ctx, read_ec, filedata, filedata_len, passphrase); if(rc) { rc = read_openssh_private_key_from_memory((void **)ec_ctx, session, "ssh-ecdsa", filedata, filedata_len, passphrase); } return rc; } int _libssh2_ecdsa_new_private_frommemory_sk(libssh2_ecdsa_ctx ** ec_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { int algorithm; return _libssh2_sk_pub_openssh_keyfilememory(session, (void **)ec_ctx, "sk-ecdsa-sha2-nistp256@openssh.com", NULL, NULL, NULL, NULL, &algorithm, flags, application, key_handle, handle_len, filedata, filedata_len, passphrase); } #endif /* LIBSSH2_ECDSA */ #if LIBSSH2_ED25519 int _libssh2_curve25519_new(LIBSSH2_SESSION *session, unsigned char **out_public_key, unsigned char **out_private_key) { EVP_PKEY *key = NULL; EVP_PKEY_CTX *pctx = NULL; unsigned char *priv = NULL, *pub = NULL; size_t privLen, pubLen; int rc = -1; pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL); if(!pctx) return -1; if(EVP_PKEY_keygen_init(pctx) != 1 || EVP_PKEY_keygen(pctx, &key) != 1) { goto clean_exit; } if(out_private_key) { privLen = LIBSSH2_ED25519_KEY_LEN; priv = LIBSSH2_ALLOC(session, privLen); if(!priv) goto clean_exit; if(EVP_PKEY_get_raw_private_key(key, priv, &privLen) != 1 || privLen != LIBSSH2_ED25519_KEY_LEN) { goto clean_exit; } *out_private_key = priv; priv = NULL; } if(out_public_key) { pubLen = LIBSSH2_ED25519_KEY_LEN; pub = LIBSSH2_ALLOC(session, pubLen); if(!pub) goto clean_exit; if(EVP_PKEY_get_raw_public_key(key, pub, &pubLen) != 1 || pubLen != LIBSSH2_ED25519_KEY_LEN) { goto clean_exit; } *out_public_key = pub; pub = NULL; } /* success */ rc = 0; clean_exit: if(pctx) EVP_PKEY_CTX_free(pctx); if(key) EVP_PKEY_free(key); if(priv) LIBSSH2_FREE(session, priv); if(pub) LIBSSH2_FREE(session, pub); return rc; } static int gen_publickey_from_ed_evp(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, EVP_PKEY *pk) { const char methodName[] = "ssh-ed25519"; unsigned char *methodBuf = NULL; size_t rawKeyLen = 0; unsigned char *keyBuf = NULL; size_t bufLen = 0; unsigned char *bufPos = NULL; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from ED private key envelope")); methodBuf = LIBSSH2_ALLOC(session, sizeof(methodName) - 1); if(!methodBuf) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); goto fail; } memcpy(methodBuf, methodName, sizeof(methodName) - 1); if(EVP_PKEY_get_raw_public_key(pk, NULL, &rawKeyLen) != 1) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "EVP_PKEY_get_raw_public_key failed"); goto fail; } /* Key form is: type_len(4) + type(11) + pub_key_len(4) + pub_key(32). */ bufLen = 4 + sizeof(methodName) - 1 + 4 + rawKeyLen; bufPos = keyBuf = LIBSSH2_ALLOC(session, bufLen); if(!keyBuf) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); goto fail; } _libssh2_store_str(&bufPos, methodName, sizeof(methodName) - 1); _libssh2_store_u32(&bufPos, (uint32_t) rawKeyLen); if(EVP_PKEY_get_raw_public_key(pk, bufPos, &rawKeyLen) != 1) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "EVP_PKEY_get_raw_public_key failed"); goto fail; } *method = methodBuf; *method_len = sizeof(methodName) - 1; *pubkeydata = keyBuf; *pubkeydata_len = bufLen; return 0; fail: if(methodBuf) LIBSSH2_FREE(session, methodBuf); if(keyBuf) LIBSSH2_FREE(session, keyBuf); return -1; } static int gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session, struct string_buf *decrypted, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, libssh2_ed25519_ctx **out_ctx) { libssh2_ed25519_ctx *ctx = NULL; unsigned char *method_buf = NULL; unsigned char *key = NULL; int i, ret = 0; unsigned char *pub_key, *priv_key, *buf; size_t key_len = 0, tmp_len = 0; unsigned char *p; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing ED25519 keys from private key data")); if(_libssh2_get_string(decrypted, &pub_key, &tmp_len) || tmp_len != LIBSSH2_ED25519_KEY_LEN) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Wrong public key length"); return -1; } if(_libssh2_get_string(decrypted, &priv_key, &tmp_len) || tmp_len != LIBSSH2_ED25519_PRIVATE_KEY_LEN) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Wrong private key length"); ret = -1; goto clean_exit; } /* first 32 bytes of priv_key is the private key, the last 32 bytes are the public key */ ctx = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, (const unsigned char *)priv_key, LIBSSH2_ED25519_KEY_LEN); /* comment */ if(_libssh2_get_string(decrypted, &buf, &tmp_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unable to read comment"); ret = -1; goto clean_exit; } if(tmp_len > 0) { unsigned char *comment = LIBSSH2_CALLOC(session, tmp_len + 1); if(comment) { memcpy(comment, buf, tmp_len); memcpy(comment + tmp_len, "\0", 1); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Key comment: %s", comment)); LIBSSH2_FREE(session, comment); } } /* Padding */ i = 1; while(decrypted->dataptr < decrypted->data + decrypted->len) { if(*decrypted->dataptr != i) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Wrong padding"); ret = -1; goto clean_exit; } i++; decrypted->dataptr++; } if(ret == 0) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from ED25519 " "private key envelope")); method_buf = LIBSSH2_ALLOC(session, 11); /* ssh-ed25519. */ if(!method_buf) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for ED25519 key"); goto clean_exit; } /* Key form is: type_len(4) + type(11) + pub_key_len(4) + pub_key(32). */ key_len = LIBSSH2_ED25519_KEY_LEN + 19; key = LIBSSH2_CALLOC(session, key_len); if(!key) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for ED25519 key"); goto clean_exit; } p = key; _libssh2_store_str(&p, "ssh-ed25519", 11); _libssh2_store_str(&p, (const char *)pub_key, LIBSSH2_ED25519_KEY_LEN); memcpy(method_buf, "ssh-ed25519", 11); if(method) *method = method_buf; else LIBSSH2_FREE(session, method_buf); if(method_len) *method_len = 11; if(pubkeydata) *pubkeydata = key; else LIBSSH2_FREE(session, key); if(pubkeydata_len) *pubkeydata_len = key_len; if(out_ctx) *out_ctx = ctx; else if(ctx) _libssh2_ed25519_free(ctx); return 0; } clean_exit: if(ctx) _libssh2_ed25519_free(ctx); if(method_buf) LIBSSH2_FREE(session, method_buf); if(key) LIBSSH2_FREE(session, key); return -1; } static int gen_publickey_from_sk_ed25519_openssh_priv_data(LIBSSH2_SESSION *session, struct string_buf *decrypted, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, libssh2_ed25519_ctx **out_ctx) { const char *key_type = "sk-ssh-ed25519@openssh.com"; libssh2_ed25519_ctx *ctx = NULL; unsigned char *method_buf = NULL; unsigned char *key = NULL; int ret = 0; unsigned char *pub_key, *app; size_t key_len = 0, app_len = 0, tmp_len = 0; unsigned char *p; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing sk-ED25519 keys from private key data")); if(_libssh2_get_string(decrypted, &pub_key, &tmp_len) || tmp_len != LIBSSH2_ED25519_KEY_LEN) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Wrong public key length"); return -1; } if(_libssh2_get_string(decrypted, &app, &app_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No SK application."); return -1; } if(flags && _libssh2_get_byte(decrypted, flags)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No SK flags."); return -1; } if(key_handle && handle_len) { unsigned char *handle = NULL; if(_libssh2_get_string(decrypted, &handle, handle_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No SK key_handle."); return -1; } if(*handle_len > 0) { *key_handle = LIBSSH2_ALLOC(session, *handle_len); if(key_handle) { memcpy((void *)*key_handle, handle, *handle_len); } } } ctx = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, (const unsigned char *)pub_key, LIBSSH2_ED25519_KEY_LEN); if(ret == 0) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from ED25519 " "private key envelope")); /* sk-ssh-ed25519@openssh.com. */ method_buf = LIBSSH2_ALLOC(session, strlen(key_type)); if(!method_buf) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for ED25519 key"); goto clean_exit; } /* Key form is: type_len(4) + type(26) + pub_key_len(4) + pub_key(32) + application_len(4) + application(X). */ key_len = LIBSSH2_ED25519_KEY_LEN + 38 + app_len; key = LIBSSH2_CALLOC(session, key_len); if(!key) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for ED25519 key"); goto clean_exit; } p = key; _libssh2_store_str(&p, key_type, strlen(key_type)); _libssh2_store_str(&p, (const char *)pub_key, LIBSSH2_ED25519_KEY_LEN); _libssh2_store_str(&p, (const char *)app, app_len); if(application && app_len > 0) { *application = (const char *)LIBSSH2_ALLOC(session, app_len + 1); _libssh2_explicit_zero((void *)*application, app_len + 1); memcpy((void *)*application, app, app_len); } memcpy(method_buf, key_type, strlen(key_type)); if(method) *method = method_buf; else LIBSSH2_FREE(session, method_buf); if(method_len) *method_len = strlen(key_type); if(pubkeydata) *pubkeydata = key; else if(key) LIBSSH2_FREE(session, key); if(pubkeydata_len) *pubkeydata_len = key_len; if(out_ctx) *out_ctx = ctx; else if(ctx) _libssh2_ed25519_free(ctx); return 0; } clean_exit: if(ctx) _libssh2_ed25519_free(ctx); if(method_buf) LIBSSH2_FREE(session, method_buf); if(key) LIBSSH2_FREE(session, key); if(application && *application) { LIBSSH2_FREE(session, (void *)application); *application = NULL; } if(key_handle && *key_handle) { LIBSSH2_FREE(session, (void *)key_handle); *key_handle = NULL; } return -1; } int _libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx, LIBSSH2_SESSION * session, const char *filename, const uint8_t *passphrase) { int rc; FILE *fp; unsigned char *buf; struct string_buf *decrypted = NULL; libssh2_ed25519_ctx *ctx = NULL; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(filename, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open ED25519 private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); fclose(fp); if(rc) { return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } if(strcmp("ssh-ed25519", (const char *)buf) == 0) { rc = gen_publickey_from_ed25519_openssh_priv_data(session, decrypted, NULL, NULL, NULL, NULL, &ctx); } else { rc = -1; } if(decrypted) _libssh2_string_buf_free(session, decrypted); if(rc == 0) { if(ed_ctx) *ed_ctx = ctx; else if(ctx) _libssh2_ed25519_free(ctx); } return rc; } int _libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION *session, const char *filename, const uint8_t *passphrase) { int rc; FILE *fp; unsigned char *buf; struct string_buf *decrypted = NULL; libssh2_ed25519_ctx *ctx = NULL; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(filename, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open ED25519 SK private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); fclose(fp); if(rc) { return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } if(strcmp("sk-ssh-ed25519@openssh.com", (const char *)buf) == 0) { rc = gen_publickey_from_sk_ed25519_openssh_priv_data(session, decrypted, NULL, NULL, NULL, NULL, flags, application, key_handle, handle_len, &ctx); } else { rc = -1; } if(decrypted) _libssh2_string_buf_free(session, decrypted); if(rc == 0) { if(ed_ctx) *ed_ctx = ctx; else if(ctx) _libssh2_ed25519_free(ctx); } return rc; } int _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx ** ed_ctx, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { libssh2_ed25519_ctx *ctx = NULL; _libssh2_init_if_needed(); if(read_private_key_from_memory((void **)&ctx, (pem_read_bio_func) &PEM_read_bio_PrivateKey, filedata, filedata_len, passphrase) == 0) { if(EVP_PKEY_id(ctx) != EVP_PKEY_ED25519) { _libssh2_ed25519_free(ctx); return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Private key is not an ED25519 key"); } *ed_ctx = ctx; return 0; } return read_openssh_private_key_from_memory((void **)ed_ctx, session, "ssh-ed25519", filedata, filedata_len, passphrase); } int _libssh2_ed25519_new_private_frommemory_sk(libssh2_ed25519_ctx **ed_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { int algorithm; return _libssh2_sk_pub_openssh_keyfilememory(session, (void **)ed_ctx, "sk-ssh-ed25519@openssh.com", NULL, NULL, NULL, NULL, &algorithm, flags, application, key_handle, handle_len, filedata, filedata_len, passphrase); } int _libssh2_ed25519_new_public(libssh2_ed25519_ctx ** ed_ctx, LIBSSH2_SESSION * session, const unsigned char *raw_pub_key, const size_t key_len) { libssh2_ed25519_ctx *ctx = NULL; if(!ed_ctx) return -1; ctx = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, raw_pub_key, key_len); if(!ctx) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "could not create ED25519 public key"); if(ed_ctx) *ed_ctx = ctx; else if(ctx) _libssh2_ed25519_free(ctx); return 0; } #endif /* LIBSSH2_ED25519 */ #if LIBSSH2_RSA int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { int ret; unsigned char *sig; unsigned int sig_len; sig_len = RSA_size(rsactx); sig = LIBSSH2_ALLOC(session, sig_len); if(!sig) { return -1; } if(hash_len == SHA_DIGEST_LENGTH) ret = RSA_sign(NID_sha1, hash, (unsigned int) hash_len, sig, &sig_len, rsactx); else if(hash_len == SHA256_DIGEST_LENGTH) ret = RSA_sign(NID_sha256, hash, (unsigned int) hash_len, sig, &sig_len, rsactx); else if(hash_len == SHA512_DIGEST_LENGTH) ret = RSA_sign(NID_sha512, hash, (unsigned int) hash_len, sig, &sig_len, rsactx); else { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unsupported hash digest length"); ret = -1; } if(!ret) { LIBSSH2_FREE(session, sig); return -1; } *signature = sig; *signature_len = sig_len; return 0; } #if LIBSSH2_RSA_SHA1 int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { return _libssh2_rsa_sha2_sign(session, rsactx, hash, hash_len, signature, signature_len); } #endif #endif #if LIBSSH2_DSA int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, const unsigned char *hash, unsigned long hash_len, unsigned char *signature) { DSA_SIG *sig; const BIGNUM * r; const BIGNUM * s; int r_len, s_len; (void)hash_len; sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); if(!sig) { return -1; } #ifdef HAVE_OPAQUE_STRUCTS DSA_SIG_get0(sig, &r, &s); #else r = sig->r; s = sig->s; #endif r_len = BN_num_bytes(r); if(r_len < 1 || r_len > 20) { DSA_SIG_free(sig); return -1; } s_len = BN_num_bytes(s); if(s_len < 1 || s_len > 20) { DSA_SIG_free(sig); return -1; } memset(signature, 0, 40); BN_bn2bin(r, signature + (20 - r_len)); BN_bn2bin(s, signature + 20 + (20 - s_len)); DSA_SIG_free(sig); return 0; } #endif /* LIBSSH_DSA */ #if LIBSSH2_ECDSA int _libssh2_ecdsa_sign(LIBSSH2_SESSION * session, libssh2_ecdsa_ctx * ec_ctx, const unsigned char *hash, unsigned long hash_len, unsigned char **signature, size_t *signature_len) { int r_len, s_len; int rc = 0; size_t out_buffer_len = 0; unsigned char *sp; const BIGNUM *pr = NULL, *ps = NULL; unsigned char *temp_buffer = NULL; unsigned char *out_buffer = NULL; ECDSA_SIG *sig = ECDSA_do_sign(hash, (int) hash_len, ec_ctx); if(!sig) return -1; #ifdef HAVE_OPAQUE_STRUCTS ECDSA_SIG_get0(sig, &pr, &ps); #else pr = sig->r; ps = sig->s; #endif r_len = BN_num_bytes(pr) + 1; s_len = BN_num_bytes(ps) + 1; temp_buffer = malloc(r_len + s_len + 8); if(!temp_buffer) { rc = -1; goto clean_exit; } sp = temp_buffer; sp = write_bn(sp, pr, r_len); sp = write_bn(sp, ps, s_len); out_buffer_len = (size_t)(sp - temp_buffer); out_buffer = LIBSSH2_CALLOC(session, out_buffer_len); if(!out_buffer) { rc = -1; goto clean_exit; } memcpy(out_buffer, temp_buffer, out_buffer_len); *signature = out_buffer; *signature_len = out_buffer_len; clean_exit: if(temp_buffer) free(temp_buffer); if(sig) ECDSA_SIG_free(sig); return rc; } #endif /* LIBSSH2_ECDSA */ int _libssh2_sha1_init(libssh2_sha1_ctx *ctx) { #ifdef HAVE_OPAQUE_STRUCTS *ctx = EVP_MD_CTX_new(); if(!*ctx) return 0; if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha1"))) return 1; EVP_MD_CTX_free(*ctx); *ctx = NULL; return 0; #else EVP_MD_CTX_init(ctx); return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1")); #endif } int _libssh2_sha1(const unsigned char *message, size_t len, unsigned char *out) { #ifdef HAVE_OPAQUE_STRUCTS EVP_MD_CTX * ctx = EVP_MD_CTX_new(); if(!ctx) return 1; /* error */ if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))) { EVP_DigestUpdate(ctx, message, len); EVP_DigestFinal(ctx, out, NULL); EVP_MD_CTX_free(ctx); return 0; /* success */ } EVP_MD_CTX_free(ctx); #else EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"))) { EVP_DigestUpdate(&ctx, message, len); EVP_DigestFinal(&ctx, out, NULL); return 0; /* success */ } #endif return 1; /* error */ } int _libssh2_sha256_init(libssh2_sha256_ctx *ctx) { #ifdef HAVE_OPAQUE_STRUCTS *ctx = EVP_MD_CTX_new(); if(!*ctx) return 0; if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha256"))) return 1; EVP_MD_CTX_free(*ctx); *ctx = NULL; return 0; #else EVP_MD_CTX_init(ctx); return EVP_DigestInit(ctx, EVP_get_digestbyname("sha256")); #endif } int _libssh2_sha256(const unsigned char *message, size_t len, unsigned char *out) { #ifdef HAVE_OPAQUE_STRUCTS EVP_MD_CTX * ctx = EVP_MD_CTX_new(); if(!ctx) return 1; /* error */ if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha256"))) { EVP_DigestUpdate(ctx, message, len); EVP_DigestFinal(ctx, out, NULL); EVP_MD_CTX_free(ctx); return 0; /* success */ } EVP_MD_CTX_free(ctx); #else EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha256"))) { EVP_DigestUpdate(&ctx, message, len); EVP_DigestFinal(&ctx, out, NULL); return 0; /* success */ } #endif return 1; /* error */ } int _libssh2_sha384_init(libssh2_sha384_ctx *ctx) { #ifdef HAVE_OPAQUE_STRUCTS *ctx = EVP_MD_CTX_new(); if(!*ctx) return 0; if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha384"))) return 1; EVP_MD_CTX_free(*ctx); *ctx = NULL; return 0; #else EVP_MD_CTX_init(ctx); return EVP_DigestInit(ctx, EVP_get_digestbyname("sha384")); #endif } int _libssh2_sha384(const unsigned char *message, size_t len, unsigned char *out) { #ifdef HAVE_OPAQUE_STRUCTS EVP_MD_CTX * ctx = EVP_MD_CTX_new(); if(!ctx) return 1; /* error */ if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha384"))) { EVP_DigestUpdate(ctx, message, len); EVP_DigestFinal(ctx, out, NULL); EVP_MD_CTX_free(ctx); return 0; /* success */ } EVP_MD_CTX_free(ctx); #else EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha384"))) { EVP_DigestUpdate(&ctx, message, len); EVP_DigestFinal(&ctx, out, NULL); return 0; /* success */ } #endif return 1; /* error */ } int _libssh2_sha512_init(libssh2_sha512_ctx *ctx) { #ifdef HAVE_OPAQUE_STRUCTS *ctx = EVP_MD_CTX_new(); if(!*ctx) return 0; if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha512"))) return 1; EVP_MD_CTX_free(*ctx); *ctx = NULL; return 0; #else EVP_MD_CTX_init(ctx); return EVP_DigestInit(ctx, EVP_get_digestbyname("sha512")); #endif } int _libssh2_sha512(const unsigned char *message, size_t len, unsigned char *out) { #ifdef HAVE_OPAQUE_STRUCTS EVP_MD_CTX * ctx = EVP_MD_CTX_new(); if(!ctx) return 1; /* error */ if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha512"))) { EVP_DigestUpdate(ctx, message, len); EVP_DigestFinal(ctx, out, NULL); EVP_MD_CTX_free(ctx); return 0; /* success */ } EVP_MD_CTX_free(ctx); #else EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha512"))) { EVP_DigestUpdate(&ctx, message, len); EVP_DigestFinal(&ctx, out, NULL); return 0; /* success */ } #endif return 1; /* error */ } int _libssh2_md5_init(libssh2_md5_ctx *ctx) { /* MD5 digest is not supported in OpenSSL FIPS mode * Trying to init it will result in a latent OpenSSL error: * "digital envelope routines:FIPS_DIGESTINIT:disabled for fips" * So, just return 0 in FIPS mode */ #if OPENSSL_VERSION_NUMBER >= 0x000907000L && \ defined(OPENSSL_VERSION_MAJOR) && \ OPENSSL_VERSION_MAJOR < 3 && \ !defined(LIBRESSL_VERSION_NUMBER) if(FIPS_mode()) return 0; #endif #ifdef HAVE_OPAQUE_STRUCTS *ctx = EVP_MD_CTX_new(); if(!*ctx) return 0; if(EVP_DigestInit(*ctx, EVP_get_digestbyname("md5"))) return 1; EVP_MD_CTX_free(*ctx); *ctx = NULL; return 0; #else EVP_MD_CTX_init(ctx); return EVP_DigestInit(ctx, EVP_get_digestbyname("md5")); #endif } #if LIBSSH2_ECDSA static int gen_publickey_from_ec_evp(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int is_sk, EVP_PKEY *pk) { int rc = 0; EC_KEY *ec = NULL; unsigned char *p; unsigned char *method_buf = NULL; unsigned char *key; size_t key_len = 0; unsigned char *octal_value = NULL; size_t octal_len; const EC_POINT *public_key; const EC_GROUP *group; BN_CTX *bn_ctx; libssh2_curve_type type; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from EC private key envelope")); bn_ctx = BN_CTX_new(); if(!bn_ctx) return -1; ec = EVP_PKEY_get1_EC_KEY(pk); if(!ec) { rc = -1; goto clean_exit; } public_key = EC_KEY_get0_public_key(ec); group = EC_KEY_get0_group(ec); type = _libssh2_ecdsa_get_curve_type(ec); if(is_sk) *method_len = 34; else *method_len = 19; method_buf = LIBSSH2_ALLOC(session, *method_len); if(!method_buf) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "out of memory"); } if(is_sk) memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com", *method_len); else if(type == LIBSSH2_EC_CURVE_NISTP256) memcpy(method_buf, "ecdsa-sha2-nistp256", *method_len); else if(type == LIBSSH2_EC_CURVE_NISTP384) memcpy(method_buf, "ecdsa-sha2-nistp384", *method_len); else if(type == LIBSSH2_EC_CURVE_NISTP521) memcpy(method_buf, "ecdsa-sha2-nistp521", *method_len); else { _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "Unsupported EC private key type")); rc = -1; goto clean_exit; } /* get length */ octal_len = EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx); if(octal_len > EC_MAX_POINT_LEN) { rc = -1; goto clean_exit; } octal_value = malloc(octal_len); if(!octal_value) { rc = -1; goto clean_exit; } /* convert to octal */ if(EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, octal_value, octal_len, bn_ctx) != octal_len) { rc = -1; goto clean_exit; } /* Key form is: type_len(4) + type(method_len) + domain_len(4) + domain(8) + pub_key_len(4) + pub_key(~65). */ key_len = 4 + *method_len + 4 + 8 + 4 + octal_len; key = LIBSSH2_ALLOC(session, key_len); if(!key) { rc = -1; goto clean_exit; } /* Process key encoding. */ p = key; /* Key type */ _libssh2_store_str(&p, (const char *)method_buf, *method_len); /* Name domain */ if(is_sk) { _libssh2_store_str(&p, "nistp256", 8); } else { _libssh2_store_str(&p, (const char *)method_buf + 11, 8); } /* Public key */ _libssh2_store_str(&p, (const char *)octal_value, octal_len); *method = method_buf; *pubkeydata = key; *pubkeydata_len = key_len; clean_exit: if(ec) EC_KEY_free(ec); if(bn_ctx) { BN_CTX_free(bn_ctx); } if(octal_value) free(octal_value); if(rc == 0) return 0; if(method_buf) LIBSSH2_FREE(session, method_buf); return -1; } static int gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session, libssh2_curve_type curve_type, struct string_buf *decrypted, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, libssh2_ecdsa_ctx **ec_ctx) { int rc = 0; size_t curvelen, exponentlen, pointlen; unsigned char *curve, *exponent, *point_buf; EC_KEY *ec_key = NULL; BIGNUM *bn_exponent; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing ECDSA keys from private key data")); if(_libssh2_get_string(decrypted, &curve, &curvelen) || curvelen == 0) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA no curve"); return -1; } if(_libssh2_get_string(decrypted, &point_buf, &pointlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA no point"); return -1; } if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA no exponent"); return -1; } rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf, pointlen, curve_type); if(rc) { rc = -1; _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA could not create key"); goto fail; } bn_exponent = BN_new(); if(!bn_exponent) { rc = -1; _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for private key data"); goto fail; } BN_bin2bn(exponent, (int) exponentlen, bn_exponent); rc = (EC_KEY_set_private_key(ec_key, bn_exponent) != 1); if(rc == 0 && ec_key && pubkeydata && method) { EVP_PKEY *pk = EVP_PKEY_new(); EVP_PKEY_set1_EC_KEY(pk, ec_key); rc = gen_publickey_from_ec_evp(session, method, method_len, pubkeydata, pubkeydata_len, 0, pk); if(pk) EVP_PKEY_free(pk); } if(ec_ctx) *ec_ctx = ec_key; else EC_KEY_free(ec_key); return rc; fail: if(ec_key) EC_KEY_free(ec_key); return rc; } static int gen_publickey_from_sk_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session, struct string_buf *decrypted, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, uint8_t *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, libssh2_ecdsa_ctx **ec_ctx) { int rc = 0; size_t curvelen, pointlen, key_len, app_len; unsigned char *curve, *point_buf, *p, *key, *app; EC_KEY *ec_key = NULL; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Extracting ECDSA-SK public key")); if(_libssh2_get_string(decrypted, &curve, &curvelen) || curvelen == 0) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA no curve"); return -1; } if(_libssh2_get_string(decrypted, &point_buf, &pointlen)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA no point"); return -1; } rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf, pointlen, LIBSSH2_EC_CURVE_NISTP256); if(rc) { rc = -1; _libssh2_error(session, LIBSSH2_ERROR_PROTO, "ECDSA could not create key"); goto fail; } if(_libssh2_get_string(decrypted, &app, &app_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No SK application."); goto fail; } if(flags && _libssh2_get_byte(decrypted, flags)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No SK flags."); goto fail; } if(key_handle && handle_len) { unsigned char *handle = NULL; if(_libssh2_get_string(decrypted, &handle, handle_len)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "No SK key_handle."); goto fail; } if(*handle_len > 0) { *key_handle = LIBSSH2_ALLOC(session, *handle_len); if(*key_handle) { memcpy((void *)*key_handle, handle, *handle_len); } } } if(rc == 0 && ec_key && pubkeydata && method) { EVP_PKEY *pk = EVP_PKEY_new(); EVP_PKEY_set1_EC_KEY(pk, ec_key); rc = gen_publickey_from_ec_evp(session, method, method_len, pubkeydata, pubkeydata_len, 1, pk); if(pk) EVP_PKEY_free(pk); } if(rc == 0 && pubkeydata) { key_len = *pubkeydata_len + app_len + 4; key = LIBSSH2_ALLOC(session, key_len); if(!key) { rc = -1; goto fail; } p = key + *pubkeydata_len; memcpy(key, *pubkeydata, *pubkeydata_len); _libssh2_store_str(&p, (const char *)app, app_len); if(application && app_len > 0) { *application = (const char *)LIBSSH2_ALLOC(session, app_len + 1); _libssh2_explicit_zero((void *)*application, app_len + 1); memcpy((void *)*application, app, app_len); } LIBSSH2_FREE(session, *pubkeydata); *pubkeydata_len = key_len; if(pubkeydata) *pubkeydata = key; else if(key) LIBSSH2_FREE(session, key); } if(ec_ctx) *ec_ctx = ec_key; else EC_KEY_free(ec_key); return rc; fail: if(ec_key) EC_KEY_free(ec_key); if(application && *application) { LIBSSH2_FREE(session, (void *)application); *application = NULL; } if(key_handle && *key_handle) { LIBSSH2_FREE(session, (void *)key_handle); *key_handle = NULL; } return rc; } static int _libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx ** ec_ctx, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { FILE *fp; int rc; unsigned char *buf = NULL; libssh2_curve_type type; struct string_buf *decrypted = NULL; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(filename, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open OpenSSH ECDSA private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); fclose(fp); if(rc) { return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } rc = _libssh2_ecdsa_curve_type_from_name((const char *)buf, &type); if(rc == 0) { rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type, decrypted, NULL, 0, NULL, 0, ec_ctx); } else { rc = -1; } if(decrypted) _libssh2_string_buf_free(session, decrypted); return rc; } static int _libssh2_ecdsa_new_openssh_private_sk(libssh2_ecdsa_ctx ** ec_ctx, uint8_t *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { FILE *fp; int rc; unsigned char *buf = NULL; struct string_buf *decrypted = NULL; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(filename, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open OpenSSH ECDSA private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); fclose(fp); if(rc) { return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } if(strcmp("sk-ecdsa-sha2-nistp256@openssh.com", (const char *)buf) == 0) { rc = gen_publickey_from_sk_ecdsa_openssh_priv_data(session, decrypted, NULL, 0, NULL, 0, flags, application, key_handle, handle_len, ec_ctx); } else { rc = -1; } if(decrypted) _libssh2_string_buf_free(session, decrypted); return rc; } int _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { int rc; pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_file((void **) ec_ctx, read_ec, filename, passphrase); if(rc) { return _libssh2_ecdsa_new_openssh_private(ec_ctx, session, filename, passphrase); } return rc; } int _libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { int rc; pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey; _libssh2_init_if_needed(); rc = read_private_key_from_file((void **) ec_ctx, read_ec, filename, passphrase); if(rc) { return _libssh2_ecdsa_new_openssh_private_sk(ec_ctx, flags, application, key_handle, handle_len, session, filename, passphrase); } return rc; } /* * _libssh2_ecdsa_create_key * * Creates a local private key based on input curve * and returns octal value and octal length * */ int _libssh2_ecdsa_create_key(LIBSSH2_SESSION *session, _libssh2_ec_key **out_private_key, unsigned char **out_public_key_octal, size_t *out_public_key_octal_len, libssh2_curve_type curve_type) { int ret = 1; size_t octal_len = 0; unsigned char octal_value[EC_MAX_POINT_LEN]; const EC_POINT *public_key = NULL; EC_KEY *private_key = NULL; const EC_GROUP *group = NULL; /* create key */ BN_CTX *bn_ctx = BN_CTX_new(); if(!bn_ctx) return -1; private_key = EC_KEY_new_by_curve_name(curve_type); group = EC_KEY_get0_group(private_key); EC_KEY_generate_key(private_key); public_key = EC_KEY_get0_public_key(private_key); /* get length */ octal_len = EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx); if(octal_len > EC_MAX_POINT_LEN) { ret = -1; goto clean_exit; } /* convert to octal */ if(EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, octal_value, octal_len, bn_ctx) != octal_len) { ret = -1; goto clean_exit; } if(out_private_key) *out_private_key = private_key; if(out_public_key_octal) { *out_public_key_octal = LIBSSH2_ALLOC(session, octal_len); if(!*out_public_key_octal) { ret = -1; goto clean_exit; } memcpy(*out_public_key_octal, octal_value, octal_len); } if(out_public_key_octal_len) *out_public_key_octal_len = octal_len; clean_exit: if(bn_ctx) BN_CTX_free(bn_ctx); return (ret == 1) ? 0 : -1; } /* _libssh2_ecdh_gen_k * * Computes the shared secret K given a local private key, * remote public key and length */ int _libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key, const unsigned char *server_public_key, size_t server_public_key_len) { int ret = 0; int rc; size_t secret_len; unsigned char *secret = NULL; const EC_GROUP *private_key_group; EC_POINT *server_public_key_point; BN_CTX *bn_ctx = BN_CTX_new(); if(!bn_ctx) return -1; if(!k) return -1; private_key_group = EC_KEY_get0_group(private_key); server_public_key_point = EC_POINT_new(private_key_group); if(!server_public_key_point) return -1; rc = EC_POINT_oct2point(private_key_group, server_public_key_point, server_public_key, server_public_key_len, bn_ctx); if(rc != 1) { ret = -1; goto clean_exit; } secret_len = (EC_GROUP_get_degree(private_key_group) + 7) / 8; secret = malloc(secret_len); if(!secret) { ret = -1; goto clean_exit; } secret_len = ECDH_compute_key(secret, secret_len, server_public_key_point, private_key, NULL); if(secret_len <= 0 || secret_len > EC_MAX_POINT_LEN) { ret = -1; goto clean_exit; } BN_bin2bn(secret, (int) secret_len, *k); clean_exit: if(server_public_key_point) EC_POINT_free(server_public_key_point); if(bn_ctx) BN_CTX_free(bn_ctx); if(secret) free(secret); return ret; } #endif /* LIBSSH2_ECDSA */ #if LIBSSH2_ED25519 int _libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session, uint8_t **out_sig, size_t *out_sig_len, const uint8_t *message, size_t message_len) { int rc = -1; EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); size_t sig_len = 0; unsigned char *sig = NULL; if(md_ctx) { if(EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, ctx) != 1) goto clean_exit; if(EVP_DigestSign(md_ctx, NULL, &sig_len, message, message_len) != 1) goto clean_exit; if(sig_len != LIBSSH2_ED25519_SIG_LEN) goto clean_exit; sig = LIBSSH2_CALLOC(session, sig_len); if(!sig) goto clean_exit; rc = EVP_DigestSign(md_ctx, sig, &sig_len, message, message_len); } if(rc == 1) { *out_sig = sig; *out_sig_len = sig_len; } else { *out_sig_len = 0; *out_sig = NULL; LIBSSH2_FREE(session, sig); } clean_exit: if(md_ctx) EVP_MD_CTX_free(md_ctx); return (rc == 1) ? 0 : -1; } int _libssh2_curve25519_gen_k(_libssh2_bn **k, uint8_t private_key[LIBSSH2_ED25519_KEY_LEN], uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]) { int rc = -1; unsigned char out_shared_key[LIBSSH2_ED25519_KEY_LEN]; EVP_PKEY *peer_key = NULL, *server_key = NULL; EVP_PKEY_CTX *server_key_ctx = NULL; BN_CTX *bn_ctx = NULL; size_t out_len = 0; if(!k || !*k) return -1; bn_ctx = BN_CTX_new(); if(!bn_ctx) return -1; peer_key = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL, server_public_key, LIBSSH2_ED25519_KEY_LEN); server_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, private_key, LIBSSH2_ED25519_KEY_LEN); if(!peer_key || !server_key) { goto clean_exit; } server_key_ctx = EVP_PKEY_CTX_new(server_key, NULL); if(!server_key_ctx) { goto clean_exit; } rc = EVP_PKEY_derive_init(server_key_ctx); if(rc <= 0) { goto clean_exit; } rc = EVP_PKEY_derive_set_peer(server_key_ctx, peer_key); if(rc <= 0) { goto clean_exit; } rc = EVP_PKEY_derive(server_key_ctx, NULL, &out_len); if(rc <= 0) { goto clean_exit; } if(out_len != LIBSSH2_ED25519_KEY_LEN) { rc = -1; goto clean_exit; } rc = EVP_PKEY_derive(server_key_ctx, out_shared_key, &out_len); if(rc == 1 && out_len == LIBSSH2_ED25519_KEY_LEN) { BN_bin2bn(out_shared_key, LIBSSH2_ED25519_KEY_LEN, *k); } else { rc = -1; } clean_exit: if(server_key_ctx) EVP_PKEY_CTX_free(server_key_ctx); if(peer_key) EVP_PKEY_free(peer_key); if(server_key) EVP_PKEY_free(server_key); if(bn_ctx) BN_CTX_free(bn_ctx); return (rc == 1) ? 0 : -1; } int _libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s, size_t s_len, const uint8_t *m, size_t m_len) { int ret = -1; EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); if(!md_ctx) return -1; ret = EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, ctx); if(ret != 1) goto clean_exit; ret = EVP_DigestVerify(md_ctx, s, s_len, m, m_len); clean_exit: EVP_MD_CTX_free(md_ctx); return (ret == 1) ? 0 : -1; } #endif /* LIBSSH2_ED25519 */ static int _libssh2_pub_priv_openssh_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { FILE *fp; unsigned char *buf = NULL; struct string_buf *decrypted = NULL; int rc = 0; if(!session) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); return -1; } _libssh2_init_if_needed(); fp = fopen(privatekey, "r"); if(!fp) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open private key file"); return -1; } rc = _libssh2_openssh_pem_parse(session, (const unsigned char *)passphrase, fp, &decrypted); fclose(fp); if(rc) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Not an OpenSSH key file"); return rc; } /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted key data not found"); return -1; } rc = -1; /* Avoid unused variable warnings when all branches below are disabled */ (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; #if LIBSSH2_ED25519 if(strcmp("ssh-ed25519", (const char *)buf) == 0) { rc = gen_publickey_from_ed25519_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, NULL); } #endif #if LIBSSH2_RSA if(strcmp("ssh-rsa", (const char *)buf) == 0) { rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, NULL); } #endif #if LIBSSH2_DSA if(strcmp("ssh-dss", (const char *)buf) == 0) { rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, NULL); } #endif #if LIBSSH2_ECDSA { libssh2_curve_type type; if(_libssh2_ecdsa_curve_type_from_name((const char *)buf, &type) == 0) { rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type, decrypted, method, method_len, pubkeydata, pubkeydata_len, NULL); } } #endif if(decrypted) _libssh2_string_buf_free(session, decrypted); if(rc) { _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unsupported OpenSSH key type"); } return rc; } int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { int st; BIO* bp; EVP_PKEY* pk; int pktype; int rc; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from private key file: %s", privatekey)); bp = BIO_new_file(privatekey, "r"); if(!bp) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key from private key " "file: Unable to open private key file"); } BIO_reset(bp); pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase); BIO_free(bp); if(!pk) { /* Try OpenSSH format */ rc = _libssh2_pub_priv_openssh_keyfile(session, method, method_len, pubkeydata, pubkeydata_len, privatekey, passphrase); if(rc) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key file: " "Wrong passphrase or invalid/unrecognized " "private key file format"); } return 0; } #ifdef HAVE_OPAQUE_STRUCTS pktype = EVP_PKEY_id(pk); #else pktype = pk->type; #endif switch(pktype) { #if LIBSSH2_ED25519 case EVP_PKEY_ED25519: st = gen_publickey_from_ed_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH2_ED25519 */ #if LIBSSH2_RSA case EVP_PKEY_RSA: st = gen_publickey_from_rsa_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH2_RSA */ #if LIBSSH2_DSA case EVP_PKEY_DSA: st = gen_publickey_from_dsa_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH2_DSA */ #if LIBSSH2_ECDSA case EVP_PKEY_EC: st = gen_publickey_from_ec_evp( session, method, method_len, pubkeydata, pubkeydata_len, 0, pk); break; #endif /* LIBSSH2_ECDSA */ default: st = _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key file: " "Unsupported private key file format"); break; } EVP_PKEY_free(pk); return st; } static int _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session, void **key_ctx, const char *key_type, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, unsigned const char *passphrase) { int rc; unsigned char *buf = NULL; struct string_buf *decrypted = NULL; if(key_ctx) *key_ctx = NULL; if(!session) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); if(key_type && (strlen(key_type) > 11 || strlen(key_type) < 7)) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "type is invalid"); _libssh2_init_if_needed(); rc = _libssh2_openssh_pem_parse_memory(session, passphrase, privatekeydata, privatekeydata_len, &decrypted); if(rc) return rc; /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted " "key data not found"); rc = LIBSSH2_ERROR_FILE; /* Avoid unused variable warnings when all branches below are disabled */ (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; #if LIBSSH2_ED25519 if(strcmp("ssh-ed25519", (const char *)buf) == 0) { if(!key_type || strcmp("ssh-ed25519", key_type) == 0) { rc = gen_publickey_from_ed25519_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, (libssh2_ed25519_ctx**)key_ctx); } } if(strcmp("sk-ssh-ed25519@openssh.com", (const char *)buf) == 0) { if(!key_type || strcmp("sk-ssh-ed25519@openssh.com", key_type) == 0) { rc = gen_publickey_from_sk_ed25519_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, NULL, NULL, NULL, NULL, (libssh2_ed25519_ctx**)key_ctx); } } #endif #if LIBSSH2_RSA if(strcmp("ssh-rsa", (const char *)buf) == 0) { if(!key_type || strcmp("ssh-rsa", key_type) == 0) { rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, (libssh2_rsa_ctx**)key_ctx); } } #endif #if LIBSSH2_DSA if(strcmp("ssh-dss", (const char *)buf) == 0) { if(!key_type || strcmp("ssh-dss", key_type) == 0) { rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, (libssh2_dsa_ctx**)key_ctx); } } #endif #if LIBSSH2_ECDSA { libssh2_curve_type type; if(strcmp("sk-ecdsa-sha2-nistp256@openssh.com", (const char *)buf) == 0) { rc = gen_publickey_from_sk_ecdsa_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, NULL, NULL, NULL, NULL, (libssh2_ecdsa_ctx**)key_ctx); } else if(_libssh2_ecdsa_curve_type_from_name((const char *)buf, &type) == 0) { if(!key_type || strcmp("ssh-ecdsa", key_type) == 0) { rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type, decrypted, method, method_len, pubkeydata, pubkeydata_len, (libssh2_ecdsa_ctx**)key_ctx); } } } #endif if(rc == LIBSSH2_ERROR_FILE) rc = _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key from private key file: " "invalid/unrecognized private key file format"); if(decrypted) _libssh2_string_buf_free(session, decrypted); return rc; } static int _libssh2_sk_pub_openssh_keyfilememory(LIBSSH2_SESSION *session, void **key_ctx, const char *key_type, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, unsigned const char *passphrase) { int rc; unsigned char *buf = NULL; struct string_buf *decrypted = NULL; if(key_ctx) *key_ctx = NULL; if(!session) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Session is required"); if(key_type && strlen(key_type) < 7) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "type is invalid"); _libssh2_init_if_needed(); rc = _libssh2_openssh_pem_parse_memory(session, passphrase, privatekeydata, privatekeydata_len, &decrypted); if(rc) return rc; /* We have a new key file, now try and parse it using supported types */ rc = _libssh2_get_string(decrypted, &buf, NULL); if(rc || !buf) return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Public key type in decrypted " "key data not found"); rc = LIBSSH2_ERROR_FILE; /* Avoid unused variable warnings when all branches below are disabled */ (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)algorithm; (void)flags; (void)application; (void)key_handle; (void)handle_len; #if LIBSSH2_ED25519 if(strcmp("sk-ssh-ed25519@openssh.com", (const char *)buf) == 0) { *algorithm = LIBSSH2_HOSTKEY_TYPE_ED25519; if(!key_type || strcmp("sk-ssh-ed25519@openssh.com", key_type) == 0) { rc = gen_publickey_from_sk_ed25519_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, flags, application, key_handle, handle_len, (libssh2_ed25519_ctx**)key_ctx); } } #endif #if LIBSSH2_ECDSA if(strcmp("sk-ecdsa-sha2-nistp256@openssh.com", (const char *)buf) == 0) { *algorithm = LIBSSH2_HOSTKEY_TYPE_ECDSA_256; rc = gen_publickey_from_sk_ecdsa_openssh_priv_data(session, decrypted, method, method_len, pubkeydata, pubkeydata_len, flags, application, key_handle, handle_len, (libssh2_ecdsa_ctx**)key_ctx); } #endif if(rc == LIBSSH2_ERROR_FILE) rc = _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key from private key file: " "invalid/unrecognized private key file format"); if(decrypted) _libssh2_string_buf_free(session, decrypted); return rc; } int read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session, const char *key_type, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { return _libssh2_pub_priv_openssh_keyfilememory(session, key_ctx, key_type, NULL, NULL, NULL, NULL, filedata, filedata_len, passphrase); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L #define HAVE_SSLERROR_BAD_DECRYPT #endif int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { int st; BIO* bp; EVP_PKEY* pk; int pktype; #ifdef HAVE_SSLERROR_BAD_DECRYPT unsigned long sslError; #endif _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from private key.")); #if OPENSSL_VERSION_NUMBER >= 0x1000200fL bp = BIO_new_mem_buf(privatekeydata, (int)privatekeydata_len); #else bp = BIO_new_mem_buf((char *)privatekeydata, (int)privatekeydata_len); #endif if(!bp) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory when" "computing public key"); BIO_reset(bp); pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase); #ifdef HAVE_SSLERROR_BAD_DECRYPT sslError = ERR_get_error(); #endif BIO_free(bp); if(!pk) { /* Try OpenSSH format */ st = _libssh2_pub_priv_openssh_keyfilememory(session, NULL, NULL, method, method_len, pubkeydata, pubkeydata_len, privatekeydata, privatekeydata_len, (unsigned const char *)passphrase); if(st == 0) return 0; #ifdef HAVE_SSLERROR_BAD_DECRYPT if((ERR_GET_LIB(sslError) == ERR_LIB_PEM && ERR_GET_REASON(sslError) == PEM_R_BAD_DECRYPT) || (ERR_GET_LIB(sslError) == ERR_LIB_PROV && ERR_GET_REASON(sslError) == EVP_R_BAD_DECRYPT)) return _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED, "Wrong passphrase for private key"); #endif return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key file: " "Unsupported private key file format"); } #ifdef HAVE_OPAQUE_STRUCTS pktype = EVP_PKEY_id(pk); #else pktype = pk->type; #endif switch(pktype) { #if LIBSSH2_ED25519 case EVP_PKEY_ED25519: st = gen_publickey_from_ed_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH2_ED25519 */ #if LIBSSH2_RSA case EVP_PKEY_RSA: st = gen_publickey_from_rsa_evp(session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH2_RSA */ #if LIBSSH2_DSA case EVP_PKEY_DSA: st = gen_publickey_from_dsa_evp(session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH2_DSA */ #if LIBSSH2_ECDSA case EVP_PKEY_EC: st = gen_publickey_from_ec_evp(session, method, method_len, pubkeydata, pubkeydata_len, 0, pk); break; #endif /* LIBSSH2_ECDSA */ default: st = _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key file: " "Unsupported private key file format"); break; } EVP_PKEY_free(pk); return st; } int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { int st = -1; BIO* bp; EVP_PKEY* pk; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Computing public key from private key.")); #if OPENSSL_VERSION_NUMBER >= 0x1000200fL bp = BIO_new_mem_buf(privatekeydata, (int)privatekeydata_len); #else bp = BIO_new_mem_buf((char *)privatekeydata, (int)privatekeydata_len); #endif if(!bp) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory when" "computing public key"); BIO_reset(bp); pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase); BIO_free(bp); if(!pk) { /* Try OpenSSH format */ st = _libssh2_sk_pub_openssh_keyfilememory(session, NULL, NULL, method, method_len, pubkeydata, pubkeydata_len, algorithm, flags, application, key_handle, handle_len, privatekeydata, privatekeydata_len, (unsigned const char *)passphrase); } return st; } void _libssh2_dh_init(_libssh2_dh_ctx *dhctx) { *dhctx = BN_new(); /* Random from client */ } int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order, _libssh2_bn_ctx *bnctx) { /* Generate x and e */ BN_rand(*dhctx, group_order * 8 - 1, 0, -1); BN_mod_exp(public, g, *dhctx, p, bnctx); return 0; } int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p, _libssh2_bn_ctx *bnctx) { /* Compute the shared secret */ BN_mod_exp(secret, f, *dhctx, p, bnctx); return 0; } void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) { BN_clear_free(*dhctx); *dhctx = NULL; } /* _libssh2_supported_key_sign_algorithms * * Return supported key hash algo upgrades, see crypto.h * */ const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len) { (void)session; #if LIBSSH2_RSA_SHA2 if(key_method_len == 7 && memcmp(key_method, "ssh-rsa", key_method_len) == 0) { return "rsa-sha2-512,rsa-sha2-256,ssh-rsa"; } #endif return NULL; } #endif /* LIBSSH2_CRYPTO_C */ libssh2-1.11.0/src/session.c0000644000175000017500000016063714424650606012523 00000000000000/* Copyright (c) 2004-2007 Sara Golemon * Copyright (c) 2009-2015 by Daniel Stenberg * Copyright (c) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #ifdef WIN32 #include /* for socklen_t */ #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ALLOCA_H #include #endif #include #include #include #include "transport.h" #include "session.h" #include "channel.h" #include "mac.h" #if defined(WIN32) #define libssh2_usec_t long #elif defined(__APPLE__) #define libssh2_usec_t suseconds_t #else #undef libssh2_usec_t #endif /* libssh2_default_alloc */ static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) { (void)abstract; return malloc(count); } /* libssh2_default_free */ static LIBSSH2_FREE_FUNC(libssh2_default_free) { (void)abstract; free(ptr); } /* libssh2_default_realloc */ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) { (void)abstract; return realloc(ptr, count); } /* * banner_receive * * Wait for a hello from the remote host * Allocate a buffer and store the banner in session->remote.banner * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative * on failure */ static int banner_receive(LIBSSH2_SESSION * session) { ssize_t ret; size_t banner_len; if(session->banner_TxRx_state == libssh2_NB_state_idle) { banner_len = 0; session->banner_TxRx_state = libssh2_NB_state_created; } else { banner_len = session->banner_TxRx_total_send; } while((banner_len < sizeof(session->banner_TxRx_banner)) && ((banner_len == 0) || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) { char c = '\0'; /* no incoming block yet! */ session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; ret = LIBSSH2_RECV(session, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session)); if(ret < 0) { if(session->api_block_mode || (ret != -EAGAIN)) /* ignore EAGAIN when non-blocking */ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Error recving %d bytes: %d", 1, (int)-ret)); } else _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Recved %d bytes banner", (int)ret)); if(ret < 0) { if(ret == -EAGAIN) { session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND; session->banner_TxRx_total_send = banner_len; return LIBSSH2_ERROR_EAGAIN; } /* Some kinda error */ session->banner_TxRx_state = libssh2_NB_state_idle; session->banner_TxRx_total_send = 0; return LIBSSH2_ERROR_SOCKET_RECV; } if(ret == 0) { session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; return LIBSSH2_ERROR_SOCKET_DISCONNECT; } if((c == '\r' || c == '\n') && banner_len == 0) { continue; } if(c == '\0') { /* NULLs are not allowed in SSH banners */ session->banner_TxRx_state = libssh2_NB_state_idle; session->banner_TxRx_total_send = 0; return LIBSSH2_ERROR_BANNER_RECV; } session->banner_TxRx_banner[banner_len++] = c; } while(banner_len && ((session->banner_TxRx_banner[banner_len - 1] == '\n') || (session->banner_TxRx_banner[banner_len - 1] == '\r'))) { banner_len--; } /* From this point on, we are done here */ session->banner_TxRx_state = libssh2_NB_state_idle; session->banner_TxRx_total_send = 0; if(!banner_len) return LIBSSH2_ERROR_BANNER_RECV; if(session->remote.banner) LIBSSH2_FREE(session, session->remote.banner); session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); if(!session->remote.banner) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner"); } memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len); session->remote.banner[banner_len] = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Received Banner: %s", session->remote.banner)); return LIBSSH2_ERROR_NONE; } /* * banner_send * * Send the default banner, or the one set via libssh2_setopt_string * * Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you * should call this function again as soon as it is likely that more data can * be sent, and this function should then be called with the same argument set * (same data pointer and same data_len) until zero or failure is returned. */ static int banner_send(LIBSSH2_SESSION * session) { char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; size_t banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; ssize_t ret; if(session->banner_TxRx_state == libssh2_NB_state_idle) { if(session->local.banner) { /* setopt_string will have given us our \r\n characters */ banner_len = strlen((char *) session->local.banner); banner = (char *) session->local.banner; } #ifdef LIBSSH2DEBUG { char banner_dup[256]; /* Hack and slash to avoid sending CRLF in debug output */ if(banner_len < 256) { memcpy(banner_dup, banner, banner_len - 2); banner_dup[banner_len - 2] = '\0'; } else { memcpy(banner_dup, banner, 255); banner_dup[255] = '\0'; } _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s", banner_dup)); } #endif session->banner_TxRx_state = libssh2_NB_state_created; } /* no outgoing block yet! */ session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; ret = LIBSSH2_SEND(session, banner + session->banner_TxRx_total_send, banner_len - session->banner_TxRx_total_send, LIBSSH2_SOCKET_SEND_FLAGS(session)); if(ret < 0) _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Error sending %d bytes: %d", banner_len - session->banner_TxRx_total_send, -ret)); else _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p+%d", ret, banner_len - session->banner_TxRx_total_send, banner, session->banner_TxRx_total_send)); if(ret != (ssize_t)(banner_len - session->banner_TxRx_total_send)) { if(ret >= 0 || ret == -EAGAIN) { /* the whole packet could not be sent, save the what was */ session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND; if(ret > 0) session->banner_TxRx_total_send += ret; return LIBSSH2_ERROR_EAGAIN; } session->banner_TxRx_state = libssh2_NB_state_idle; session->banner_TxRx_total_send = 0; return LIBSSH2_ERROR_SOCKET_RECV; } /* Set the state back to idle */ session->banner_TxRx_state = libssh2_NB_state_idle; session->banner_TxRx_total_send = 0; return 0; } /* * session_nonblock() sets the given socket to either blocking or * non-blocking mode based on the 'nonblock' boolean argument. This function * is copied from the libcurl sources with permission. */ static int session_nonblock(libssh2_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */ ) { #ifdef HAVE_O_NONBLOCK /* most recent unix versions */ int flags; flags = fcntl(sockfd, F_GETFL, 0); if(nonblock) return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); else return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); #elif defined(HAVE_FIONBIO) /* older unix versions and VMS */ int flags; flags = nonblock; return ioctl(sockfd, FIONBIO, &flags); #elif defined(HAVE_IOCTLSOCKET_CASE) /* presumably for Amiga */ return IoctlSocket(sockfd, FIONBIO, (long) nonblock); #elif defined(HAVE_SO_NONBLOCK) /* BeOS */ long b = nonblock ? 1 : 0; return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); #elif defined(WIN32) unsigned long flags; flags = nonblock; return ioctlsocket(sockfd, FIONBIO, &flags); #else (void)sockfd; (void)nonblock; return 0; /* returns success */ #endif } /* * get_socket_nonblocking * * gets the given blocking or non-blocking state of the socket. */ static int get_socket_nonblocking(libssh2_socket_t sockfd) { /* operate on this */ #ifdef HAVE_O_NONBLOCK /* most recent unix versions */ int flags = fcntl(sockfd, F_GETFL, 0); if(flags == -1) { /* Assume blocking on error */ return 1; } return (flags & O_NONBLOCK); #elif defined(HAVE_SO_NONBLOCK) /* BeOS */ long b; if(getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) { /* Assume blocking on error */ return 1; } return (int) b; #elif defined(SO_STATE) && defined(__VMS) /* VMS TCP/IP Services */ size_t sockstat = 0; int callstat = 0; size_t size = sizeof(int); callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE, (char *)&sockstat, &size); if(callstat == -1) { return 0; } if((sockstat&SS_NBIO) != 0) { return 1; } return 0; #elif defined(WIN32) unsigned int option_value; socklen_t option_len = sizeof(option_value); if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) { /* Assume blocking on error */ return 1; } return (int) option_value; #else (void)sockfd; return 1; /* returns blocking */ #endif } /* libssh2_session_banner_set * Set the local banner to use in the server handshake. */ LIBSSH2_API int libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner) { size_t banner_len = banner ? strlen(banner) : 0; if(session->local.banner) { LIBSSH2_FREE(session, session->local.banner); session->local.banner = NULL; } if(!banner_len) return 0; session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); if(!session->local.banner) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner"); } memcpy(session->local.banner, banner, banner_len); /* first zero terminate like this so that the debug output is nice */ session->local.banner[banner_len] = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s", session->local.banner)); session->local.banner[banner_len++] = '\r'; session->local.banner[banner_len++] = '\n'; session->local.banner[banner_len] = '\0'; return 0; } /* libssh2_banner_set * Set the local banner. DEPRECATED VERSION */ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner) { return libssh2_session_banner_set(session, banner); } /* * libssh2_session_init_ex * * Allocate and initialize a libssh2 session structure. Allows for malloc * callbacks in case the calling program has its own memory manager It's * allowable (but unadvisable) to define some but not all of the malloc * callbacks An additional pointer value may be optionally passed to be sent * to the callbacks (so they know who's asking) */ LIBSSH2_API LIBSSH2_SESSION * libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), LIBSSH2_FREE_FUNC((*my_free)), LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract) { LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc; LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; LIBSSH2_SESSION *session; if(my_alloc) { local_alloc = my_alloc; } if(my_free) { local_free = my_free; } if(my_realloc) { local_realloc = my_realloc; } session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract); if(session) { memset(session, 0, sizeof(LIBSSH2_SESSION)); session->alloc = local_alloc; session->free = local_free; session->realloc = local_realloc; session->send = _libssh2_send; session->recv = _libssh2_recv; session->abstract = abstract; session->api_timeout = 0; /* timeout-free API by default */ session->api_block_mode = 1; /* blocking API by default */ session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT; session->flag.quote_paths = 1; /* default behavior is to quote paths for the scp subsystem */ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "New session resource allocated")); _libssh2_init_if_needed(); } return session; } /* * libssh2_session_callback_set * * Set (or reset) a callback function * Returns the prior address * * ALERT: this function relies on that we can typecast function pointers * to void pointers, which isn't allowed in ISO C! */ #ifdef _MSC_VER #pragma warning(push) /* nonstandard extension, function/data pointer conversion in expression */ #pragma warning(disable:4152) #else #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #endif LIBSSH2_API void * libssh2_session_callback_set(LIBSSH2_SESSION * session, int cbtype, void *callback) { void *oldcb; switch(cbtype) { case LIBSSH2_CALLBACK_IGNORE: oldcb = session->ssh_msg_ignore; session->ssh_msg_ignore = callback; return oldcb; case LIBSSH2_CALLBACK_DEBUG: oldcb = session->ssh_msg_debug; session->ssh_msg_debug = callback; return oldcb; case LIBSSH2_CALLBACK_DISCONNECT: oldcb = session->ssh_msg_disconnect; session->ssh_msg_disconnect = callback; return oldcb; case LIBSSH2_CALLBACK_MACERROR: oldcb = session->macerror; session->macerror = callback; return oldcb; case LIBSSH2_CALLBACK_X11: oldcb = session->x11; session->x11 = callback; return oldcb; case LIBSSH2_CALLBACK_SEND: oldcb = session->send; session->send = callback; return oldcb; case LIBSSH2_CALLBACK_RECV: oldcb = session->recv; session->recv = callback; return oldcb; case LIBSSH2_CALLBACK_AUTHAGENT: oldcb = session->authagent; session->authagent = callback; return oldcb; case LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES: oldcb = session->addLocalIdentities; session->addLocalIdentities = callback; return oldcb; case LIBSSH2_CALLBACK_AUTHAGENT_SIGN: oldcb = session->agentSignCallback; session->agentSignCallback = callback; return oldcb; } _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype)); return NULL; } #ifdef _MSC_VER #pragma warning(pop) #else #pragma GCC diagnostic pop #endif /* * _libssh2_wait_socket * * Utility function that waits for action on the socket. Returns 0 when ready * to run again or error on timeout. */ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time) { int rc; int seconds_to_next; int dir; int has_timeout; long ms_to_next = 0; long elapsed_ms; /* since libssh2 often sets EAGAIN internally before this function is called, we can decrease some amount of confusion in user programs by resetting the error code in this function to reduce the risk of EAGAIN being stored as error when a blocking function has returned */ session->err_code = LIBSSH2_ERROR_NONE; rc = libssh2_keepalive_send(session, &seconds_to_next); if(rc) return rc; ms_to_next = seconds_to_next * 1000; /* figure out what to wait for */ dir = libssh2_session_block_directions(session); if(!dir) { _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Nothing to wait for in wait_socket")); /* To avoid that we hang below just because there's nothing set to wait for, we timeout on 1 second to also avoid busy-looping during this condition */ ms_to_next = 1000; } if(session->api_timeout > 0 && (seconds_to_next == 0 || ms_to_next > session->api_timeout)) { time_t now = time(NULL); elapsed_ms = (long)(1000*difftime(now, start_time)); if(elapsed_ms > session->api_timeout) { return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "API timeout expired"); } ms_to_next = (session->api_timeout - elapsed_ms); has_timeout = 1; } else if(ms_to_next > 0) { has_timeout = 1; } else has_timeout = 0; #ifdef HAVE_POLL { struct pollfd sockets[1]; sockets[0].fd = session->socket_fd; sockets[0].events = 0; sockets[0].revents = 0; if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) sockets[0].events |= POLLIN; if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) sockets[0].events |= POLLOUT; rc = poll(sockets, 1, has_timeout ? (int)ms_to_next : -1); } #else { fd_set rfd; fd_set wfd; fd_set *writefd = NULL; fd_set *readfd = NULL; struct timeval tv; tv.tv_sec = ms_to_next / 1000; #ifdef libssh2_usec_t tv.tv_usec = (libssh2_usec_t)((ms_to_next - tv.tv_sec*1000) * 1000); #else tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000; #endif if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) { FD_ZERO(&rfd); FD_SET(session->socket_fd, &rfd); readfd = &rfd; } if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) { FD_ZERO(&wfd); FD_SET(session->socket_fd, &wfd); writefd = &wfd; } rc = select((int)(session->socket_fd + 1), readfd, writefd, NULL, has_timeout ? &tv : NULL); } #endif if(rc == 0) { return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting on socket"); } if(rc < 0) { return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Error waiting on socket"); } return 0; /* ready to try again */ } static int session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock) { int rc; if(session->startup_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "session_startup for socket %d", sock)); if(LIBSSH2_INVALID_SOCKET == sock) { /* Did we forget something? */ return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET, "Bad socket provided"); } session->socket_fd = sock; session->socket_prev_blockstate = !get_socket_nonblocking(session->socket_fd); if(session->socket_prev_blockstate) { /* If in blocking state change to non-blocking */ rc = session_nonblock(session->socket_fd, 1); if(rc) { return _libssh2_error(session, rc, "Failed changing socket's " "blocking state to non-blocking"); } } session->startup_state = libssh2_NB_state_created; } if(session->startup_state == libssh2_NB_state_created) { rc = banner_send(session); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; else if(rc) { return _libssh2_error(session, rc, "Failed sending banner"); } session->startup_state = libssh2_NB_state_sent; session->banner_TxRx_state = libssh2_NB_state_idle; } if(session->startup_state == libssh2_NB_state_sent) { do { rc = banner_receive(session); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; else if(rc) return _libssh2_error(session, rc, "Failed getting banner"); } while(strncmp("SSH-", (const char *)session->remote.banner, 4)); session->startup_state = libssh2_NB_state_sent1; } if(session->startup_state == libssh2_NB_state_sent1) { rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; else if(rc) return _libssh2_error(session, rc, "Unable to exchange encryption keys"); session->startup_state = libssh2_NB_state_sent2; } if(session->startup_state == libssh2_NB_state_sent2) { _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Requesting userauth service")); /* Request the userauth service */ session->startup_service[0] = SSH_MSG_SERVICE_REQUEST; _libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1); memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1); session->startup_state = libssh2_NB_state_sent3; } if(session->startup_state == libssh2_NB_state_sent3) { rc = _libssh2_transport_send(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; else if(rc) { return _libssh2_error(session, rc, "Unable to ask for ssh-userauth service"); } session->startup_state = libssh2_NB_state_sent4; } if(session->startup_state == libssh2_NB_state_sent4) { rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, &session->startup_data, &session->startup_data_len, 0, NULL, 0, &session->startup_req_state); if(rc) return _libssh2_error(session, rc, "Failed to get response to " "ssh-userauth request"); if(session->startup_data_len < 5) { return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet length"); } session->startup_service_length = _libssh2_ntohu32(session->startup_data + 1); if((session->startup_service_length != (sizeof("ssh-userauth") - 1)) || strncmp("ssh-userauth", (const char *) session->startup_data + 5, session->startup_service_length)) { LIBSSH2_FREE(session, session->startup_data); session->startup_data = NULL; return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server"); } LIBSSH2_FREE(session, session->startup_data); session->startup_data = NULL; session->startup_state = libssh2_NB_state_idle; return 0; } /* just for safety return some error */ return LIBSSH2_ERROR_INVAL; } /* * libssh2_session_handshake * * session: LIBSSH2_SESSION struct allocated and owned by the calling program * sock: *must* be populated with an opened and connected socket. * * Returns: 0 on success, or non-zero on failure */ LIBSSH2_API int libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock) { int rc; BLOCK_ADJUST(rc, session, session_startup(session, sock)); return rc; } /* * libssh2_session_startup * * DEPRECATED. Use libssh2_session_handshake() instead! This function is not * portable enough. * * session: LIBSSH2_SESSION struct allocated and owned by the calling program * sock: *must* be populated with an opened and connected socket. * * Returns: 0 on success, or non-zero on failure */ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock) { return libssh2_session_handshake(session, (libssh2_socket_t) sock); } /* * session_free * * Frees the memory allocated to the session * Also closes and frees any channels attached to this session */ static int session_free(LIBSSH2_SESSION *session) { int rc; LIBSSH2_PACKET *pkg; LIBSSH2_CHANNEL *ch; LIBSSH2_LISTENER *l; int packets_left = 0; if(session->free_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Freeing session resource", session->remote.banner)); session->free_state = libssh2_NB_state_created; } if(session->free_state == libssh2_NB_state_created) { /* !checksrc! disable EQUALSNULL 1 */ while((ch = _libssh2_list_first(&session->channels)) != NULL) { rc = _libssh2_channel_free(ch); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; } session->free_state = libssh2_NB_state_sent; } if(session->free_state == libssh2_NB_state_sent) { /* !checksrc! disable EQUALSNULL 1 */ while((l = _libssh2_list_first(&session->listeners)) != NULL) { rc = _libssh2_channel_forward_cancel(l); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; } session->free_state = libssh2_NB_state_sent1; } if(session->state & LIBSSH2_STATE_NEWKEYS) { /* hostkey */ if(session->hostkey && session->hostkey->dtor) { session->hostkey->dtor(session, &session->server_hostkey_abstract); } /* Client to Server */ /* crypt */ if(session->local.crypt && session->local.crypt->dtor) { session->local.crypt->dtor(session, &session->local.crypt_abstract); } /* comp */ if(session->local.comp && session->local.comp->dtor) { session->local.comp->dtor(session, 1, &session->local.comp_abstract); } /* mac */ if(session->local.mac && session->local.mac->dtor) { session->local.mac->dtor(session, &session->local.mac_abstract); } /* Server to Client */ /* crypt */ if(session->remote.crypt && session->remote.crypt->dtor) { session->remote.crypt->dtor(session, &session->remote.crypt_abstract); } /* comp */ if(session->remote.comp && session->remote.comp->dtor) { session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); } /* mac */ if(session->remote.mac && session->remote.mac->dtor) { session->remote.mac->dtor(session, &session->remote.mac_abstract); } /* session_id */ if(session->session_id) { LIBSSH2_FREE(session, session->session_id); } } /* Free banner(s) */ if(session->remote.banner) { LIBSSH2_FREE(session, session->remote.banner); } if(session->local.banner) { LIBSSH2_FREE(session, session->local.banner); } /* Free preference(s) */ if(session->kex_prefs) { LIBSSH2_FREE(session, session->kex_prefs); } if(session->hostkey_prefs) { LIBSSH2_FREE(session, session->hostkey_prefs); } if(session->local.kexinit) { LIBSSH2_FREE(session, session->local.kexinit); } if(session->local.crypt_prefs) { LIBSSH2_FREE(session, session->local.crypt_prefs); } if(session->local.mac_prefs) { LIBSSH2_FREE(session, session->local.mac_prefs); } if(session->local.comp_prefs) { LIBSSH2_FREE(session, session->local.comp_prefs); } if(session->local.lang_prefs) { LIBSSH2_FREE(session, session->local.lang_prefs); } if(session->remote.kexinit) { LIBSSH2_FREE(session, session->remote.kexinit); } if(session->remote.crypt_prefs) { LIBSSH2_FREE(session, session->remote.crypt_prefs); } if(session->remote.mac_prefs) { LIBSSH2_FREE(session, session->remote.mac_prefs); } if(session->remote.comp_prefs) { LIBSSH2_FREE(session, session->remote.comp_prefs); } if(session->remote.lang_prefs) { LIBSSH2_FREE(session, session->remote.lang_prefs); } if(session->server_sign_algorithms) { LIBSSH2_FREE(session, session->server_sign_algorithms); } if(session->sign_algo_prefs) { LIBSSH2_FREE(session, session->sign_algo_prefs); } /* * Make sure all memory used in the state variables are free */ if(session->kexinit_data) { LIBSSH2_FREE(session, session->kexinit_data); } if(session->startup_data) { LIBSSH2_FREE(session, session->startup_data); } if(session->userauth_list_data) { LIBSSH2_FREE(session, session->userauth_list_data); } if(session->userauth_banner) { LIBSSH2_FREE(session, session->userauth_banner); } if(session->userauth_pswd_data) { LIBSSH2_FREE(session, session->userauth_pswd_data); } if(session->userauth_pswd_newpw) { LIBSSH2_FREE(session, session->userauth_pswd_newpw); } if(session->userauth_host_packet) { LIBSSH2_FREE(session, session->userauth_host_packet); } if(session->userauth_host_method) { LIBSSH2_FREE(session, session->userauth_host_method); } if(session->userauth_host_data) { LIBSSH2_FREE(session, session->userauth_host_data); } if(session->userauth_pblc_data) { LIBSSH2_FREE(session, session->userauth_pblc_data); } if(session->userauth_pblc_packet) { LIBSSH2_FREE(session, session->userauth_pblc_packet); } if(session->userauth_pblc_method) { LIBSSH2_FREE(session, session->userauth_pblc_method); } if(session->userauth_kybd_data) { LIBSSH2_FREE(session, session->userauth_kybd_data); } if(session->userauth_kybd_packet) { LIBSSH2_FREE(session, session->userauth_kybd_packet); } if(session->userauth_kybd_auth_instruction) { LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); } if(session->open_packet) { LIBSSH2_FREE(session, session->open_packet); } if(session->open_data) { LIBSSH2_FREE(session, session->open_data); } if(session->direct_message) { LIBSSH2_FREE(session, session->direct_message); } if(session->fwdLstn_packet) { LIBSSH2_FREE(session, session->fwdLstn_packet); } if(session->pkeyInit_data) { LIBSSH2_FREE(session, session->pkeyInit_data); } if(session->scpRecv_command) { LIBSSH2_FREE(session, session->scpRecv_command); } if(session->scpSend_command) { LIBSSH2_FREE(session, session->scpSend_command); } if(session->sftpInit_sftp) { LIBSSH2_FREE(session, session->sftpInit_sftp); } /* Free payload buffer */ if(session->packet.total_num) { LIBSSH2_FREE(session, session->packet.payload); } /* Cleanup all remaining packets */ /* !checksrc! disable EQUALSNULL 1 */ while((pkg = _libssh2_list_first(&session->packets)) != NULL) { packets_left++; _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "packet left with id %d", pkg->data[0])); /* unlink the node */ _libssh2_list_remove(&pkg->node); /* free */ LIBSSH2_FREE(session, pkg->data); LIBSSH2_FREE(session, pkg); } (void)packets_left; _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Extra packets left %d", packets_left)); if(session->socket_prev_blockstate) { /* if the socket was previously blocking, put it back so */ rc = session_nonblock(session->socket_fd, 0); if(rc) { _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "unable to reset socket's blocking state")); } } if(session->server_hostkey) { LIBSSH2_FREE(session, session->server_hostkey); } /* error string */ if(session->err_msg && ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) { LIBSSH2_FREE(session, (char *)session->err_msg); } LIBSSH2_FREE(session, session); return 0; } /* * libssh2_session_free * * Frees the memory allocated to the session * Also closes and frees any channels attached to this session */ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION * session) { int rc; BLOCK_ADJUST(rc, session, session_free(session)); return rc; } /* * session_disconnect */ static int session_disconnect(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang) { unsigned char *s; size_t descr_len = 0, lang_len = 0; int rc; if(session->disconnect_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang)); if(description) descr_len = strlen(description); if(lang) lang_len = strlen(lang); if(descr_len > 256) return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "too long description"); if(lang_len > 256) return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "too long language string"); /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ session->disconnect_data_len = descr_len + lang_len + 13; s = session->disconnect_data; *(s++) = SSH_MSG_DISCONNECT; _libssh2_store_u32(&s, reason); _libssh2_store_str(&s, description, descr_len); /* store length only, lang is sent separately */ _libssh2_store_u32(&s, (uint32_t)lang_len); session->disconnect_state = libssh2_NB_state_created; } rc = _libssh2_transport_send(session, session->disconnect_data, session->disconnect_data_len, (const unsigned char *)lang, lang_len); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; session->disconnect_state = libssh2_NB_state_idle; return 0; } /* * libssh2_session_disconnect_ex */ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *desc, const char *lang) { int rc; session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; BLOCK_ADJUST(rc, session, session_disconnect(session, reason, desc, lang)); return rc; } /* libssh2_session_methods * * Return the currently active methods for method_type * * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string * regardless of actual negotiation Strings should NOT be freed */ LIBSSH2_API const char * libssh2_session_methods(LIBSSH2_SESSION * session, int method_type) { /* All methods have char *name as their first element */ const LIBSSH2_KEX_METHOD *method = NULL; switch(method_type) { case LIBSSH2_METHOD_KEX: method = session->kex; break; case LIBSSH2_METHOD_HOSTKEY: method = (LIBSSH2_KEX_METHOD *) session->hostkey; break; case LIBSSH2_METHOD_CRYPT_CS: method = (LIBSSH2_KEX_METHOD *) session->local.crypt; break; case LIBSSH2_METHOD_CRYPT_SC: method = (LIBSSH2_KEX_METHOD *) session->remote.crypt; break; case LIBSSH2_METHOD_MAC_CS: method = (LIBSSH2_KEX_METHOD *) session->local.mac; break; case LIBSSH2_METHOD_MAC_SC: method = (LIBSSH2_KEX_METHOD *) session->remote.mac; break; case LIBSSH2_METHOD_COMP_CS: method = (LIBSSH2_KEX_METHOD *) session->local.comp; break; case LIBSSH2_METHOD_COMP_SC: method = (LIBSSH2_KEX_METHOD *) session->remote.comp; break; case LIBSSH2_METHOD_LANG_CS: return ""; case LIBSSH2_METHOD_LANG_SC: return ""; default: _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type"); return NULL; } if(!method) { _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No method negotiated"); return NULL; } return method->name; } /* libssh2_session_abstract * Retrieve a pointer to the abstract property */ LIBSSH2_API void ** libssh2_session_abstract(LIBSSH2_SESSION * session) { return &session->abstract; } /* libssh2_session_last_error * * Returns error code and populates an error string into errmsg If want_buf is * non-zero then the string placed into errmsg must be freed by the calling * program. Otherwise it is assumed to be owned by libssh2 */ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg, int *errmsg_len, int want_buf) { size_t msglen = 0; /* No error to report */ if(!session->err_code) { if(errmsg) { if(want_buf) { *errmsg = LIBSSH2_ALLOC(session, 1); if(*errmsg) { **errmsg = 0; } } else { *errmsg = (char *) ""; } } if(errmsg_len) { *errmsg_len = 0; } return 0; } if(errmsg) { const char *error = session->err_msg ? session->err_msg : ""; msglen = strlen(error); if(want_buf) { /* Make a copy so the calling program can own it */ *errmsg = LIBSSH2_ALLOC(session, msglen + 1); if(*errmsg) { memcpy(*errmsg, error, msglen); (*errmsg)[msglen] = 0; } } else *errmsg = (char *)error; } if(errmsg_len) { *errmsg_len = (int)msglen; } return session->err_code; } /* libssh2_session_last_errno * * Returns error code */ LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION * session) { return session->err_code; } /* libssh2_session_set_last_error * * Sets the internal error code for the session. * * This function is available specifically to be used by high level * language wrappers (i.e. Python or Perl) that may extend the library * features while still relying on its error reporting mechanism. */ LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg) { return _libssh2_error_flags(session, errcode, errmsg, LIBSSH2_ERR_FLAG_DUP); } /* libssh2_session_flag * * Set/Get session flags * * Return error code. */ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) { switch(flag) { case LIBSSH2_FLAG_SIGPIPE: session->flag.sigpipe = value; break; case LIBSSH2_FLAG_COMPRESS: session->flag.compress = value; break; case LIBSSH2_FLAG_QUOTE_PATHS: session->flag.quote_paths = value; break; default: /* unknown flag */ return LIBSSH2_ERROR_INVAL; } return LIBSSH2_ERROR_NONE; } /* _libssh2_session_set_blocking * * Set a session's blocking mode on or off, return the previous status when * this function is called. Note this function does not alter the state of the * actual socket involved. */ int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) { int bl = session->api_block_mode; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Setting blocking mode %s", blocking ? "ON" : "OFF")); session->api_block_mode = blocking; return bl; } /* libssh2_session_set_blocking * * Set a channel's blocking mode on or off, similar to a socket's * fcntl(fd, F_SETFL, O_NONBLOCK); type command */ LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking) { (void)_libssh2_session_set_blocking(session, blocking); } /* libssh2_session_get_blocking * * Returns a session's blocking mode on or off */ LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION * session) { return session->api_block_mode; } /* libssh2_session_set_timeout * * Set a session's timeout (in msec) for blocking mode, * or 0 to disable timeouts. */ LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION * session, long timeout) { session->api_timeout = timeout; } /* libssh2_session_get_timeout * * Returns a session's timeout, or 0 if disabled */ LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION * session) { return session->api_timeout; } /* libssh2_session_set_read_timeout * * Set a session's timeout (in sec) when reading packets, * or 0 to use default of 60 seconds. */ LIBSSH2_API void libssh2_session_set_read_timeout(LIBSSH2_SESSION * session, long timeout) { if(timeout <= 0) { timeout = LIBSSH2_DEFAULT_READ_TIMEOUT; } session->packet_read_timeout = timeout; } /* libssh2_session_get_read_timeout * * Returns a session's timeout. Default is 60 seconds. */ LIBSSH2_API long libssh2_session_get_read_timeout(LIBSSH2_SESSION * session) { return session->packet_read_timeout; } /* * libssh2_poll_channel_read * * Returns 0 if no data is waiting on channel, * non-0 if data is available */ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended) { LIBSSH2_SESSION *session; LIBSSH2_PACKET *packet; if(!channel) return LIBSSH2_ERROR_BAD_USE; session = channel->session; packet = _libssh2_list_first(&session->packets); while(packet) { if(packet->data_len < 5) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Packet too small"); } if(channel->local.id == _libssh2_ntohu32(packet->data + 1)) { if(extended == 1 && (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA || packet->data[0] == SSH_MSG_CHANNEL_DATA)) { return 1; } else if(extended == 0 && packet->data[0] == SSH_MSG_CHANNEL_DATA) { return 1; } /* else - no data of any type is ready to be read */ } packet = _libssh2_list_next(&packet->node); } return 0; } /* * poll_channel_write * * Returns 0 if writing to channel would block, * non-0 if data can be written without blocking */ static inline int poll_channel_write(LIBSSH2_CHANNEL * channel) { return channel->local.window_size ? 1 : 0; } /* poll_listener_queued * * Returns 0 if no connections are waiting to be accepted * non-0 if one or more connections are available */ static inline int poll_listener_queued(LIBSSH2_LISTENER * listener) { return _libssh2_list_first(&listener->queue) ? 1 : 0; } /* * libssh2_poll * * Poll sockets, channels, and listeners for activity */ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout) { long timeout_remaining; unsigned int i, active_fds; #ifdef HAVE_POLL LIBSSH2_SESSION *session = NULL; #ifdef HAVE_ALLOCA struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds); #else struct pollfd sockets[256]; if(nfds > 256) /* systems without alloca use a fixed-size array, this can be fixed if we really want to, at least if the compiler is a C99 capable one */ return -1; #endif /* Setup sockets for polling */ for(i = 0; i < nfds; i++) { fds[i].revents = 0; switch(fds[i].type) { case LIBSSH2_POLLFD_SOCKET: sockets[i].fd = fds[i].fd.socket; sockets[i].events = (short)fds[i].events; sockets[i].revents = 0; break; case LIBSSH2_POLLFD_CHANNEL: sockets[i].fd = fds[i].fd.channel->session->socket_fd; sockets[i].events = POLLIN; sockets[i].revents = 0; if(!session) session = fds[i].fd.channel->session; break; case LIBSSH2_POLLFD_LISTENER: sockets[i].fd = fds[i].fd.listener->session->socket_fd; sockets[i].events = POLLIN; sockets[i].revents = 0; if(!session) session = fds[i].fd.listener->session; break; default: if(session) _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, "Invalid descriptor passed to libssh2_poll()"); return -1; } } #elif defined(HAVE_SELECT) LIBSSH2_SESSION *session = NULL; libssh2_socket_t maxfd = 0; fd_set rfds, wfds; struct timeval tv; FD_ZERO(&rfds); FD_ZERO(&wfds); for(i = 0; i < nfds; i++) { fds[i].revents = 0; switch(fds[i].type) { case LIBSSH2_POLLFD_SOCKET: if(fds[i].events & LIBSSH2_POLLFD_POLLIN) { FD_SET(fds[i].fd.socket, &rfds); if(fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket; } if(fds[i].events & LIBSSH2_POLLFD_POLLOUT) { FD_SET(fds[i].fd.socket, &wfds); if(fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket; } break; case LIBSSH2_POLLFD_CHANNEL: FD_SET(fds[i].fd.channel->session->socket_fd, &rfds); if(fds[i].fd.channel->session->socket_fd > maxfd) maxfd = fds[i].fd.channel->session->socket_fd; if(!session) session = fds[i].fd.channel->session; break; case LIBSSH2_POLLFD_LISTENER: FD_SET(fds[i].fd.listener->session->socket_fd, &rfds); if(fds[i].fd.listener->session->socket_fd > maxfd) maxfd = fds[i].fd.listener->session->socket_fd; if(!session) session = fds[i].fd.listener->session; break; default: if(session) _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, "Invalid descriptor passed to libssh2_poll()"); return -1; } } #else /* No select() or poll() * no sockets structure to setup */ timeout = 0; #endif /* HAVE_POLL or HAVE_SELECT */ timeout_remaining = timeout; do { #if defined(HAVE_POLL) || defined(HAVE_SELECT) int sysret; #endif active_fds = 0; for(i = 0; i < nfds; i++) { if(fds[i].events != fds[i].revents) { switch(fds[i].type) { case LIBSSH2_POLLFD_CHANNEL: if((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want to be ready for read */ ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* Not yet known to be ready for read */ fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 0) ? LIBSSH2_POLLFD_POLLIN : 0; } if((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && /* Want to be ready for extended read */ ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { /* Not yet known to be ready for extended read */ fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 1) ? LIBSSH2_POLLFD_POLLEXT : 0; } if((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && /* Want to be ready for write */ ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */ fds[i].revents |= poll_channel_write(fds[i].fd. channel) ? LIBSSH2_POLLFD_POLLOUT : 0; } if(fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) { fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; } if(fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; } break; case LIBSSH2_POLLFD_LISTENER: if((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */ ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */ fds[i].revents |= poll_listener_queued(fds[i].fd. listener) ? LIBSSH2_POLLFD_POLLIN : 0; } if(fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; } break; } } if(fds[i].revents) { active_fds++; } } if(active_fds) { /* Don't block on the sockets if we have channels/listeners which are ready */ timeout_remaining = 0; } #ifdef HAVE_POLL { struct timeval tv_begin, tv_end; gettimeofday(&tv_begin, NULL); sysret = poll(sockets, nfds, (int)timeout_remaining); gettimeofday(&tv_end, NULL); timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; } if(sysret > 0) { for(i = 0; i < nfds; i++) { switch(fds[i].type) { case LIBSSH2_POLLFD_SOCKET: fds[i].revents = sockets[i].revents; sockets[i].revents = 0; /* In case we loop again, be nice */ if(fds[i].revents) { active_fds++; } break; case LIBSSH2_POLLFD_CHANNEL: if(sockets[i].events & POLLIN) { /* Spin session until no data available */ while(_libssh2_transport_read(fds[i].fd. channel->session) > 0); } if(sockets[i].revents & POLLHUP) { fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; } sockets[i].revents = 0; break; case LIBSSH2_POLLFD_LISTENER: if(sockets[i].events & POLLIN) { /* Spin session until no data available */ while(_libssh2_transport_read(fds[i].fd. listener->session) > 0); } if(sockets[i].revents & POLLHUP) { fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; } sockets[i].revents = 0; break; } } } #elif defined(HAVE_SELECT) tv.tv_sec = timeout_remaining / 1000; tv.tv_usec = (timeout_remaining % 1000) * 1000; { struct timeval tv_begin, tv_end; gettimeofday(&tv_begin, NULL); sysret = select((int)(maxfd + 1), &rfds, &wfds, NULL, &tv); gettimeofday(&tv_end, NULL); timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; } if(sysret > 0) { for(i = 0; i < nfds; i++) { switch(fds[i].type) { case LIBSSH2_POLLFD_SOCKET: if(FD_ISSET(fds[i].fd.socket, &rfds)) { fds[i].revents |= LIBSSH2_POLLFD_POLLIN; } if(FD_ISSET(fds[i].fd.socket, &wfds)) { fds[i].revents |= LIBSSH2_POLLFD_POLLOUT; } if(fds[i].revents) { active_fds++; } break; case LIBSSH2_POLLFD_CHANNEL: if(FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { /* Spin session until no data available */ while(_libssh2_transport_read(fds[i].fd. channel->session) > 0); } break; case LIBSSH2_POLLFD_LISTENER: if(FD_ISSET (fds[i].fd.listener->session->socket_fd, &rfds)) { /* Spin session until no data available */ while(_libssh2_transport_read(fds[i].fd. listener->session) > 0); } break; } } } #endif /* else no select() or poll() -- timeout (and by extension * timeout_remaining) will be equal to 0 */ } while((timeout_remaining > 0) && !active_fds); return active_fds; } /* * libssh2_session_block_directions * * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked */ LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session) { return session->socket_block_directions; } /* libssh2_session_banner_get * Get the remote banner (server ID string) */ LIBSSH2_API const char * libssh2_session_banner_get(LIBSSH2_SESSION *session) { /* to avoid a coredump when session is NULL */ if(!session) return NULL; if(!session->remote.banner) return NULL; return (const char *) session->remote.banner; } libssh2-1.11.0/src/version.c0000644000175000017500000000362314424650606012514 00000000000000/* Copyright (C) 2009 Daniel Stenberg. All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ #include "libssh2_priv.h" LIBSSH2_API const char *libssh2_version(int req_version_num) { if(req_version_num <= LIBSSH2_VERSION_NUM) return LIBSSH2_VERSION; return NULL; /* this is not a suitable library! */ } LIBSSH2_API libssh2_crypto_engine_t libssh2_crypto_engine(void) { return LIBSSH2_CRYPTO_ENGINE; } libssh2-1.11.0/src/channel.h0000644000175000017500000001122714424650606012443 00000000000000#ifndef __LIBSSH2_CHANNEL_H #define __LIBSSH2_CHANNEL_H /* Copyright (c) 2008-2010 by Daniel Stenberg * * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* * _libssh2_channel_receive_window_adjust * * Adjust the receive window for a channel by adjustment bytes. If the amount * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the * adjustment amount will be queued for a later packet. * * Always non-blocking. */ int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, uint32_t adjustment, unsigned char force, unsigned int *store); /* * _libssh2_channel_flush * * Flush data from one (or all) stream * Returns number of bytes flushed, or negative on failure */ int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid); /* * _libssh2_channel_free * * Make sure a channel is closed, then remove the channel from the session * and free its resource(s) * * Returns 0 on success, negative on failure */ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel); int _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); /* * _libssh2_channel_write * * Send data to a channel */ ssize_t _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, const unsigned char *buf, size_t buflen); /* * _libssh2_channel_open * * Establish a generic session channel */ LIBSSH2_CHANNEL * _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, uint32_t channel_type_len, uint32_t window_size, uint32_t packet_size, const unsigned char *message, size_t message_len); /* * _libssh2_channel_process_startup * * Primitive for libssh2_channel_(shell|exec|subsystem) */ int _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, size_t request_len, const char *message, size_t message_len); /* * _libssh2_channel_read * * Read data from a channel * * It is important to not return 0 until the currently read channel is * complete. If we read stuff from the wire but it was no payload data to fill * in the buffer with, we MUST make sure to return PACKET_EAGAIN. */ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen); uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session); LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session, uint32_t channel_id); size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id); int _libssh2_channel_close(LIBSSH2_CHANNEL * channel); /* * _libssh2_channel_forward_cancel * * Stop listening on a remote port and free the listener * Toss out any pending (un-accept()ed) connections * * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error */ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); #endif /* __LIBSSH2_CHANNEL_H */ libssh2-1.11.0/src/crypto.h0000644000175000017500000003661714432741311012356 00000000000000#ifndef __LIBSSH2_CRYPTO_H #define __LIBSSH2_CRYPTO_H /* Copyright (C) 2009, 2010 Simon Josefsson * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. * Copyright (C) 2010-2019 Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL) #include "openssl.h" #elif defined(LIBSSH2_LIBGCRYPT) #include "libgcrypt.h" #elif defined(LIBSSH2_MBEDTLS) #include "mbedtls.h" #elif defined(LIBSSH2_OS400QC3) #include "os400qc3.h" #elif defined(LIBSSH2_WINCNG) #include "wincng.h" #else #error "no cryptography backend selected" #endif #ifdef LIBSSH2_NO_MD5 #undef LIBSSH2_MD5 #define LIBSSH2_MD5 0 #endif #ifdef LIBSSH2_NO_HMAC_RIPEMD #undef LIBSSH2_HMAC_RIPEMD #define LIBSSH2_HMAC_RIPEMD 0 #endif #ifdef LIBSSH2_NO_DSA #undef LIBSSH2_DSA #define LIBSSH2_DSA 0 #endif #ifdef LIBSSH2_NO_RSA #undef LIBSSH2_RSA #define LIBSSH2_RSA 0 #endif #ifdef LIBSSH2_NO_RSA_SHA1 #undef LIBSSH2_RSA_SHA1 #define LIBSSH2_RSA_SHA1 0 #endif #ifdef LIBSSH2_NO_ECDSA #undef LIBSSH2_ECDSA #define LIBSSH2_ECDSA 0 #endif #ifdef LIBSSH2_NO_ED25519 #undef LIBSSH2_ED25519 #define LIBSSH2_ED25519 0 #endif #ifdef LIBSSH2_NO_AES_CTR #undef LIBSSH2_AES_CTR #define LIBSSH2_AES_CTR 0 #endif #ifdef LIBSSH2_NO_AES_CBC #undef LIBSSH2_AES_CBC #define LIBSSH2_AES_CBC 0 #endif #ifdef LIBSSH2_NO_BLOWFISH #undef LIBSSH2_BLOWFISH #define LIBSSH2_BLOWFISH 0 #endif #ifdef LIBSSH2_NO_RC4 #undef LIBSSH2_RC4 #define LIBSSH2_RC4 0 #endif #ifdef LIBSSH2_NO_CAST #undef LIBSSH2_CAST #define LIBSSH2_CAST 0 #endif #ifdef LIBSSH2_NO_3DES #undef LIBSSH2_3DES #define LIBSSH2_3DES 0 #endif #define LIBSSH2_ED25519_KEY_LEN 32 #define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64 #define LIBSSH2_ED25519_SIG_LEN 64 #if LIBSSH2_RSA int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen); int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase); #if LIBSSH2_RSA_SHA1 int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len); int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); #endif #if LIBSSH2_RSA_SHA2 int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa, size_t hash_len, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len); #endif int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); #endif #if LIBSSH2_DSA int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *gdata, unsigned long glen, const unsigned char *ydata, unsigned long ylen, const unsigned char *x, unsigned long x_len); int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase); int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, const unsigned char *sig, const unsigned char *m, size_t m_len); int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, const unsigned char *hash, unsigned long hash_len, unsigned char *sig); int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); #endif #if LIBSSH2_ECDSA int _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx, const unsigned char *k, size_t k_len, libssh2_curve_type type); int _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase); int _libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase); int _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx, const unsigned char *r, size_t r_len, const unsigned char *s, size_t s_len, const unsigned char *m, size_t m_len); int _libssh2_ecdsa_create_key(LIBSSH2_SESSION *session, _libssh2_ec_key **out_private_key, unsigned char **out_public_key_octal, size_t *out_public_key_octal_len, libssh2_curve_type curve_type); int _libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key, const unsigned char *server_public_key, size_t server_public_key_len); int _libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx, const unsigned char *hash, unsigned long hash_len, unsigned char **signature, size_t *signature_len); int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); int _libssh2_ecdsa_new_private_frommemory_sk(libssh2_ecdsa_ctx ** ec_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); libssh2_curve_type _libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx); int _libssh2_ecdsa_curve_type_from_name(const char *name, libssh2_curve_type *out_type); #endif /* LIBSSH2_ECDSA */ #if LIBSSH2_ED25519 int _libssh2_curve25519_new(LIBSSH2_SESSION *session, uint8_t **out_public_key, uint8_t **out_private_key); int _libssh2_curve25519_gen_k(_libssh2_bn **k, uint8_t private_key[LIBSSH2_ED25519_KEY_LEN], uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]); int _libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s, size_t s_len, const uint8_t *m, size_t m_len); int _libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const char *filename, const uint8_t *passphrase); int _libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION *session, const char *filename, const uint8_t *passphrase); int _libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const unsigned char *raw_pub_key, const size_t key_len); int _libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session, uint8_t **out_sig, size_t *out_sig_len, const uint8_t *message, size_t message_len); int _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); int _libssh2_ed25519_new_private_frommemory_sk(libssh2_ed25519_ctx **ed_ctx, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); #endif /* LIBSSH2_ED25519 */ int _libssh2_cipher_init(_libssh2_cipher_ctx * h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt); int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize, int firstlast); int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase); int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase); int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase); /** * @function _libssh2_supported_key_sign_algorithms * @abstract Returns supported algorithms used for upgrading public * key signing RFC 8332 * @discussion Based on the incoming key_method value, this function * will return supported algorithms that can upgrade the key method * @related _libssh2_key_sign_algorithm() * @param key_method current key method, usually the default key sig method * @param key_method_len length of the key method buffer * @result comma separated list of supported upgrade options per RFC 8332, if * there is no upgrade option return NULL */ const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len); #endif /* __LIBSSH2_CRYPTO_H */ libssh2-1.11.0/src/packet.c0000644000175000017500000016747314432741311012305 00000000000000/* Copyright (c) 2004-2007, Sara Golemon * Copyright (c) 2005,2006 Mikhail Gusarov * Copyright (c) 2009-2014 by Daniel Stenberg * Copyright (c) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif /* Needed for struct iovec on some platforms */ #ifdef HAVE_SYS_UIO_H #include #endif #include "transport.h" #include "channel.h" #include "packet.h" /* * libssh2_packet_queue_listener * * Queue a connection request for a listener */ static inline int packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data, size_t datalen, packet_queue_listener_state_t *listen_state) { /* * Look for a matching listener */ /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ size_t packet_len = 17 + (sizeof(FwdNotReq) - 1); unsigned char *p; LIBSSH2_LISTENER *listn = _libssh2_list_first(&session->listeners); char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; int rc; if(listen_state->state == libssh2_NB_state_idle) { size_t offset = (sizeof("forwarded-tcpip") - 1) + 5; size_t temp_len = 0; struct string_buf buf; buf.data = data; buf.dataptr = buf.data; buf.len = datalen; if(datalen < offset) { return _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, "Unexpected packet size"); } buf.dataptr += offset; if(_libssh2_get_u32(&buf, &(listen_state->sender_channel))) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting channel"); } if(_libssh2_get_u32(&buf, &(listen_state->initial_window_size))) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting window size"); } if(_libssh2_get_u32(&buf, &(listen_state->packet_size))) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting packet"); } if(_libssh2_get_string(&buf, &(listen_state->host), &temp_len)) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting host"); } listen_state->host_len = (uint32_t)temp_len; if(_libssh2_get_u32(&buf, &(listen_state->port))) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting port"); } if(_libssh2_get_string(&buf, &(listen_state->shost), &temp_len)) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting shost"); } listen_state->shost_len = (uint32_t)temp_len; if(_libssh2_get_u32(&buf, &(listen_state->sport))) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Data too short extracting sport"); } _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Remote received connection from %s:%ld to %s:%ld", listen_state->shost, listen_state->sport, listen_state->host, listen_state->port)); listen_state->state = libssh2_NB_state_allocated; } if(listen_state->state != libssh2_NB_state_sent) { while(listn) { if((listn->port == (int) listen_state->port) && (strlen(listn->host) == listen_state->host_len) && (memcmp (listn->host, listen_state->host, listen_state->host_len) == 0)) { /* This is our listener */ LIBSSH2_CHANNEL *channel = NULL; listen_state->channel = NULL; if(listen_state->state == libssh2_NB_state_allocated) { if(listn->queue_maxsize && (listn->queue_maxsize <= listn->queue_size)) { /* Queue is full */ failure_code = SSH_OPEN_RESOURCE_SHORTAGE; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Listener queue full, ignoring")); listen_state->state = libssh2_NB_state_sent; break; } channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); if(!channel) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for " "new connection"); failure_code = SSH_OPEN_RESOURCE_SHORTAGE; listen_state->state = libssh2_NB_state_sent; break; } listen_state->channel = channel; channel->session = session; channel->channel_type_len = sizeof("forwarded-tcpip") - 1; channel->channel_type = LIBSSH2_ALLOC(session, channel-> channel_type_len + 1); if(!channel->channel_type) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new" " connection"); LIBSSH2_FREE(session, channel); failure_code = SSH_OPEN_RESOURCE_SHORTAGE; listen_state->state = libssh2_NB_state_sent; break; } memcpy(channel->channel_type, "forwarded-tcpip", channel->channel_type_len + 1); channel->remote.id = listen_state->sender_channel; channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; channel->local.id = _libssh2_channel_nextid(session); channel->local.window_size_initial = listen_state->initial_window_size; channel->local.window_size = listen_state->initial_window_size; channel->local.packet_size = listen_state->packet_size; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Connection queued: channel %lu/%lu " "win %lu/%lu packet %lu/%lu", channel->local.id, channel->remote.id, channel->local.window_size, channel->remote.window_size, channel->local.packet_size, channel->remote.packet_size)); p = listen_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; _libssh2_store_u32(&p, channel->remote.id); _libssh2_store_u32(&p, channel->local.id); _libssh2_store_u32(&p, channel->remote.window_size_initial); _libssh2_store_u32(&p, channel->remote.packet_size); listen_state->state = libssh2_NB_state_created; } if(listen_state->state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, listen_state->packet, 17, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; else if(rc) { listen_state->state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send channel " "open confirmation"); } /* Link the channel into the end of the queue list */ if(listen_state->channel) { _libssh2_list_add(&listn->queue, &listen_state->channel->node); listn->queue_size++; } listen_state->state = libssh2_NB_state_idle; return 0; } } listn = _libssh2_list_next(&listn->node); } listen_state->state = libssh2_NB_state_sent; } /* We're not listening to you */ p = listen_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; _libssh2_store_u32(&p, listen_state->sender_channel); _libssh2_store_u32(&p, failure_code); _libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1); _libssh2_htonu32(p, 0); rc = _libssh2_transport_send(session, listen_state->packet, packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { listen_state->state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send open failure"); } listen_state->state = libssh2_NB_state_idle; return 0; } /* * packet_x11_open * * Accept a forwarded X11 connection */ static inline int packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data, size_t datalen, packet_x11_open_state_t *x11open_state) { int failure_code = SSH_OPEN_CONNECT_FAILED; /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ size_t packet_len = 17 + (sizeof(X11FwdUnAvil) - 1); unsigned char *p; LIBSSH2_CHANNEL *channel = x11open_state->channel; int rc; if(x11open_state->state == libssh2_NB_state_idle) { size_t offset = (sizeof("x11") - 1) + 5; size_t temp_len = 0; struct string_buf buf; buf.data = data; buf.dataptr = buf.data; buf.len = datalen; if(datalen < offset) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "unexpected data length"); failure_code = SSH_OPEN_CONNECT_FAILED; goto x11_exit; } buf.dataptr += offset; if(_libssh2_get_u32(&buf, &(x11open_state->sender_channel))) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "unexpected sender channel size"); failure_code = SSH_OPEN_CONNECT_FAILED; goto x11_exit; } if(_libssh2_get_u32(&buf, &(x11open_state->initial_window_size))) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "unexpected window size"); failure_code = SSH_OPEN_CONNECT_FAILED; goto x11_exit; } if(_libssh2_get_u32(&buf, &(x11open_state->packet_size))) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "unexpected window size"); failure_code = SSH_OPEN_CONNECT_FAILED; goto x11_exit; } if(_libssh2_get_string(&buf, &(x11open_state->shost), &temp_len)) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "unexpected host size"); failure_code = SSH_OPEN_CONNECT_FAILED; goto x11_exit; } x11open_state->shost_len = (uint32_t)temp_len; if(_libssh2_get_u32(&buf, &(x11open_state->sport))) { _libssh2_error(session, LIBSSH2_ERROR_INVAL, "unexpected port size"); failure_code = SSH_OPEN_CONNECT_FAILED; goto x11_exit; } _libssh2_debug((session, LIBSSH2_TRACE_CONN, "X11 Connection Received from %s:%ld on channel %lu", x11open_state->shost, x11open_state->sport, x11open_state->sender_channel)); x11open_state->state = libssh2_NB_state_allocated; } if(session->x11) { if(x11open_state->state == libssh2_NB_state_allocated) { channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); if(!channel) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "allocate a channel for new connection"); failure_code = SSH_OPEN_RESOURCE_SHORTAGE; goto x11_exit; } channel->session = session; channel->channel_type_len = sizeof("x11") - 1; channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type_len + 1); if(!channel->channel_type) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "allocate a channel for new connection"); LIBSSH2_FREE(session, channel); failure_code = SSH_OPEN_RESOURCE_SHORTAGE; goto x11_exit; } memcpy(channel->channel_type, "x11", channel->channel_type_len + 1); channel->remote.id = x11open_state->sender_channel; channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; channel->local.id = _libssh2_channel_nextid(session); channel->local.window_size_initial = x11open_state->initial_window_size; channel->local.window_size = x11open_state->initial_window_size; channel->local.packet_size = x11open_state->packet_size; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "X11 Connection established: channel %lu/%lu " "win %lu/%lu packet %lu/%lu", channel->local.id, channel->remote.id, channel->local.window_size, channel->remote.window_size, channel->local.packet_size, channel->remote.packet_size)); p = x11open_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; _libssh2_store_u32(&p, channel->remote.id); _libssh2_store_u32(&p, channel->local.id); _libssh2_store_u32(&p, channel->remote.window_size_initial); _libssh2_store_u32(&p, channel->remote.packet_size); x11open_state->state = libssh2_NB_state_created; } if(x11open_state->state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, x11open_state->packet, 17, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { x11open_state->state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open " "confirmation"); } /* Link the channel into the session */ _libssh2_list_add(&session->channels, &channel->node); /* * Pass control to the callback, they may turn right around and * free the channel, or actually use it */ LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, x11open_state->sport); x11open_state->state = libssh2_NB_state_idle; return 0; } } else failure_code = SSH_OPEN_RESOURCE_SHORTAGE; /* fall-trough */ x11_exit: p = x11open_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; _libssh2_store_u32(&p, x11open_state->sender_channel); _libssh2_store_u32(&p, failure_code); _libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1); _libssh2_htonu32(p, 0); rc = _libssh2_transport_send(session, x11open_state->packet, packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { x11open_state->state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send open failure"); } x11open_state->state = libssh2_NB_state_idle; return 0; } /* * packet_authagent_open * * Open a connection to authentication agent */ static inline int packet_authagent_open(LIBSSH2_SESSION * session, unsigned char *data, size_t datalen, packet_authagent_state_t *authagent_state) { int failure_code = SSH_OPEN_CONNECT_FAILED; /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ size_t packet_len = 17 + (sizeof(X11FwdUnAvil) - 1); unsigned char *p; LIBSSH2_CHANNEL *channel = authagent_state->channel; int rc; (void)datalen; if(authagent_state->state == libssh2_NB_state_idle) { unsigned char *s = data + (sizeof("auth-agent@openssh.org") - 1) + 5; authagent_state->sender_channel = _libssh2_ntohu32(s); s += 4; authagent_state->initial_window_size = _libssh2_ntohu32(s); s += 4; authagent_state->packet_size = _libssh2_ntohu32(s); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Auth Agent Connection Received on channel %lu", authagent_state->sender_channel)); authagent_state->state = libssh2_NB_state_allocated; } if(session->authagent) { if(authagent_state->state == libssh2_NB_state_allocated) { channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); authagent_state->channel = channel; if(!channel) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "allocate a channel for new connection"); failure_code = SSH_OPEN_RESOURCE_SHORTAGE; goto authagent_exit; } memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); channel->session = session; channel->channel_type_len = sizeof("auth agent") - 1; channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type_len + 1); if(!channel->channel_type) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "allocate a channel for new connection"); LIBSSH2_FREE(session, channel); failure_code = SSH_OPEN_RESOURCE_SHORTAGE; goto authagent_exit; } memcpy(channel->channel_type, "auth agent", channel->channel_type_len + 1); channel->remote.id = authagent_state->sender_channel; channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; channel->local.id = _libssh2_channel_nextid(session); channel->local.window_size_initial = authagent_state->initial_window_size; channel->local.window_size = authagent_state->initial_window_size; channel->local.packet_size = authagent_state->packet_size; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Auth Agent Connection established: channel " "%lu/%lu win %lu/%lu packet %lu/%lu", channel->local.id, channel->remote.id, channel->local.window_size, channel->remote.window_size, channel->local.packet_size, channel->remote.packet_size)); p = authagent_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; _libssh2_store_u32(&p, channel->remote.id); _libssh2_store_u32(&p, channel->local.id); _libssh2_store_u32(&p, channel->remote.window_size_initial); _libssh2_store_u32(&p, channel->remote.packet_size); authagent_state->state = libssh2_NB_state_created; } if(authagent_state->state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, authagent_state->packet, 17, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { authagent_state->state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open " "confirmation"); } /* Link the channel into the session */ _libssh2_list_add(&session->channels, &channel->node); /* mess with stuff so we don't keep reading the same packet over and over */ session->packet.total_num = 0; session->fullpacket_state = libssh2_NB_state_idle; /* Pass control to the callback, they may turn right around and and free the channel, or actually use it */ LIBSSH2_AUTHAGENT(channel); authagent_state->state = libssh2_NB_state_idle; return 0; } } else failure_code = SSH_OPEN_RESOURCE_SHORTAGE; /* fall-through */ authagent_exit: p = authagent_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; _libssh2_store_u32(&p, authagent_state->sender_channel); _libssh2_store_u32(&p, failure_code); _libssh2_store_str(&p, AuthAgentUnavail, sizeof(AuthAgentUnavail) - 1); _libssh2_htonu32(p, 0); rc = _libssh2_transport_send(session, authagent_state->packet, packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { authagent_state->state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send open failure"); } authagent_state->state = libssh2_NB_state_idle; return 0; } /* * _libssh2_packet_add * * Create a new packet and attach it to the brigade. Called from the transport * layer when it has received a packet. * * The input pointer 'data' is pointing to allocated data that this function * is asked to deal with so on failure OR success, it must be freed fine. * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN. * * This function will always be called with 'datalen' greater than zero. */ int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, size_t datalen, int macstate) { int rc = 0; unsigned char *message = NULL; unsigned char *language = NULL; size_t message_len = 0; size_t language_len = 0; LIBSSH2_CHANNEL *channelp = NULL; size_t data_head = 0; unsigned char msg = data[0]; switch(session->packAdd_state) { case libssh2_NB_state_idle: _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Packet type %d received, length=%d", (int) msg, (int) datalen)); if((macstate == LIBSSH2_MAC_INVALID) && (!session->macerror || LIBSSH2_MACERROR(session, (char *) data, datalen))) { /* Bad MAC input, but no callback set or non-zero return from the callback */ LIBSSH2_FREE(session, data); return _libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, "Invalid MAC received"); } session->packAdd_state = libssh2_NB_state_allocated; break; case libssh2_NB_state_jump1: goto libssh2_packet_add_jump_point1; case libssh2_NB_state_jump2: goto libssh2_packet_add_jump_point2; case libssh2_NB_state_jump3: goto libssh2_packet_add_jump_point3; case libssh2_NB_state_jump4: goto libssh2_packet_add_jump_point4; case libssh2_NB_state_jump5: goto libssh2_packet_add_jump_point5; case libssh2_NB_state_jumpauthagent: goto libssh2_packet_add_jump_authagent; default: /* nothing to do */ break; } if(session->packAdd_state == libssh2_NB_state_allocated) { /* A couple exceptions to the packet adding rule: */ switch(msg) { /* byte SSH_MSG_DISCONNECT uint32 reason code string description in ISO-10646 UTF-8 encoding [RFC3629] string language tag [RFC3066] */ case SSH_MSG_DISCONNECT: if(datalen >= 5) { uint32_t reason = 0; struct string_buf buf; buf.data = (unsigned char *)data; buf.dataptr = buf.data; buf.len = datalen; buf.dataptr++; /* advance past type */ _libssh2_get_u32(&buf, &reason); _libssh2_get_string(&buf, &message, &message_len); _libssh2_get_string(&buf, &language, &language_len); if(session->ssh_msg_disconnect) { LIBSSH2_DISCONNECT(session, reason, (const char *)message, message_len, (const char *)language, language_len); } _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Disconnect(%d): %s(%s)", reason, message, language)); } LIBSSH2_FREE(session, data); session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; session->packAdd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, "socket disconnect"); /* byte SSH_MSG_IGNORE string data */ case SSH_MSG_IGNORE: if(datalen >= 2) { if(session->ssh_msg_ignore) { LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1); } } else if(session->ssh_msg_ignore) { LIBSSH2_IGNORE(session, "", 0); } LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; /* byte SSH_MSG_DEBUG boolean always_display string message in ISO-10646 UTF-8 encoding [RFC3629] string language tag [RFC3066] */ case SSH_MSG_DEBUG: if(datalen >= 2) { int always_display = data[1]; if(datalen >= 6) { struct string_buf buf; buf.data = (unsigned char *)data; buf.dataptr = buf.data; buf.len = datalen; buf.dataptr += 2; /* advance past type & always display */ _libssh2_get_string(&buf, &message, &message_len); _libssh2_get_string(&buf, &language, &language_len); } if(session->ssh_msg_debug) { LIBSSH2_DEBUG(session, always_display, (const char *)message, message_len, (const char *)language, language_len); } } /* * _libssh2_debug() will actually truncate this for us so * that it's not an inordinate about of data */ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Debug Packet: %s", message)); LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; /* byte SSH_MSG_EXT_INFO uint32 nr-extensions [repeat "nr-extensions" times] string extension-name [RFC8308] string extension-value (binary) */ case SSH_MSG_EXT_INFO: if(datalen >= 5) { uint32_t nr_extensions = 0; struct string_buf buf; buf.data = (unsigned char *)data; buf.dataptr = buf.data; buf.len = datalen; buf.dataptr += 1; /* advance past type */ if(_libssh2_get_u32(&buf, &nr_extensions) != 0) { rc = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid extension info received"); } while(rc == 0 && nr_extensions > 0) { size_t name_len = 0; size_t value_len = 0; unsigned char *name = NULL; unsigned char *value = NULL; nr_extensions -= 1; _libssh2_get_string(&buf, &name, &name_len); _libssh2_get_string(&buf, &value, &value_len); if(name && value) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client extension %.*s: %.*s", name_len, name, value_len, value)); } if(name_len == 15 && memcmp(name, "server-sig-algs", 15) == 0) { if(session->server_sign_algorithms) { LIBSSH2_FREE(session, session->server_sign_algorithms); } session->server_sign_algorithms = LIBSSH2_ALLOC(session, value_len + 1); if(session->server_sign_algorithms) { memcpy(session->server_sign_algorithms, value, value_len); session->server_sign_algorithms[value_len] = '\0'; } else { rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "memory for server sign algo"); } } } } LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return rc; /* byte SSH_MSG_GLOBAL_REQUEST string request name in US-ASCII only boolean want reply .... request-specific data follows */ case SSH_MSG_GLOBAL_REQUEST: if(datalen >= 5) { uint32_t len = 0; unsigned char want_reply = 0; len = _libssh2_ntohu32(data + 1); if((len <= (UINT_MAX - 6)) && (datalen >= (6 + len))) { want_reply = data[5 + len]; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Received global request type %.*s (wr %X)", len, data + 5, want_reply)); } if(want_reply) { static const unsigned char packet = SSH_MSG_REQUEST_FAILURE; libssh2_packet_add_jump_point5: session->packAdd_state = libssh2_NB_state_jump5; rc = _libssh2_transport_send(session, &packet, 1, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; } } LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; /* byte SSH_MSG_CHANNEL_EXTENDED_DATA uint32 recipient channel uint32 data_type_code string data */ case SSH_MSG_CHANNEL_EXTENDED_DATA: /* streamid(4) */ data_head += 4; /* fall-through */ /* byte SSH_MSG_CHANNEL_DATA uint32 recipient channel string data */ case SSH_MSG_CHANNEL_DATA: /* packet_type(1) + channelno(4) + datalen(4) */ data_head += 9; if(datalen >= data_head) channelp = _libssh2_channel_locate(session, _libssh2_ntohu32(data + 1)); if(!channelp) { _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, "Packet received for unknown channel"); LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; } #ifdef LIBSSH2DEBUG { uint32_t stream_id = 0; if(msg == SSH_MSG_CHANNEL_EXTENDED_DATA) stream_id = _libssh2_ntohu32(data + 5); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "%d bytes packet_add() for %lu/%lu/%lu", (int) (datalen - data_head), channelp->local.id, channelp->remote.id, stream_id)); } #endif if((channelp->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && (msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) { /* Pretend we didn't receive this */ LIBSSH2_FREE(session, data); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Ignoring extended data and refunding %d bytes", (int) (datalen - 13))); if(channelp->read_avail + datalen - data_head >= channelp->remote.window_size) datalen = channelp->remote.window_size - channelp->read_avail + data_head; channelp->remote.window_size -= (uint32_t)(datalen - data_head); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "shrinking window size by %lu bytes to %lu, " "read_avail %lu", datalen - data_head, channelp->remote.window_size, channelp->read_avail)); session->packAdd_channelp = channelp; /* Adjust the window based on the block we just freed */ libssh2_packet_add_jump_point1: session->packAdd_state = libssh2_NB_state_jump1; rc = _libssh2_channel_receive_window_adjust(session-> packAdd_channelp, (uint32_t)(datalen - 13), 1, NULL); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; session->packAdd_state = libssh2_NB_state_idle; return 0; } /* * REMEMBER! remote means remote as source of data, * NOT remote window! */ if(channelp->remote.packet_size < (datalen - data_head)) { /* * Spec says we MAY ignore bytes sent beyond * packet_size */ _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, "Packet contains more data than we offered" " to receive, truncating"); datalen = channelp->remote.packet_size + data_head; } if(channelp->remote.window_size <= channelp->read_avail) { /* * Spec says we MAY ignore bytes sent beyond * window_size */ _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "The current receive window is full," " data ignored"); LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; } /* Reset EOF status */ channelp->remote.eof = 0; if(channelp->read_avail + datalen - data_head > channelp->remote.window_size) { _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "Remote sent more data than current " "window allows, truncating"); datalen = channelp->remote.window_size - channelp->read_avail + data_head; } /* Update the read_avail counter. The window size will be * updated once the data is actually read from the queue * from an upper layer */ channelp->read_avail += datalen - data_head; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "increasing read_avail by %lu bytes to %lu/%lu", (long)(datalen - data_head), (long)channelp->read_avail, (long)channelp->remote.window_size)); break; /* byte SSH_MSG_CHANNEL_EOF uint32 recipient channel */ case SSH_MSG_CHANNEL_EOF: if(datalen >= 5) channelp = _libssh2_channel_locate(session, _libssh2_ntohu32(data + 1)); if(!channelp) /* We may have freed already, just quietly ignore this... */ ; else { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "EOF received for channel %lu/%lu", channelp->local.id, channelp->remote.id)); channelp->remote.eof = 1; } LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; /* byte SSH_MSG_CHANNEL_REQUEST uint32 recipient channel string request type in US-ASCII characters only boolean want reply .... type-specific data follows */ case SSH_MSG_CHANNEL_REQUEST: if(datalen >= 9) { uint32_t channel = _libssh2_ntohu32(data + 1); uint32_t len = _libssh2_ntohu32(data + 5); unsigned char want_reply = 1; if((len + 9) < datalen) want_reply = data[len + 9]; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Channel %d received request type %.*s (wr %X)", channel, len, data + 9, want_reply)); if(len == sizeof("exit-status") - 1 && (sizeof("exit-status") - 1 + 9) <= datalen && !memcmp("exit-status", data + 9, sizeof("exit-status") - 1)) { /* we've got "exit-status" packet. Set the session value */ if(datalen >= 20) channelp = _libssh2_channel_locate(session, channel); if(channelp && (sizeof("exit-status") + 13) <= datalen) { channelp->exit_status = _libssh2_ntohu32(data + 9 + sizeof("exit-status")); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Exit status %lu received for " "channel %lu/%lu", channelp->exit_status, channelp->local.id, channelp->remote.id)); } } else if(len == sizeof("exit-signal") - 1 && (sizeof("exit-signal") - 1 + 9) <= datalen && !memcmp("exit-signal", data + 9, sizeof("exit-signal") - 1)) { /* command terminated due to signal */ if(datalen >= 20) channelp = _libssh2_channel_locate(session, channel); if(channelp && (sizeof("exit-signal") + 13) <= datalen) { /* set signal name (without SIG prefix) */ uint32_t namelen = _libssh2_ntohu32(data + 9 + sizeof("exit-signal")); if(namelen <= UINT_MAX - 1) { channelp->exit_signal = LIBSSH2_ALLOC(session, namelen + 1); } else { channelp->exit_signal = NULL; } if(!channelp->exit_signal) rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "memory for signal name"); else if((sizeof("exit-signal") + 13 + namelen <= datalen)) { memcpy(channelp->exit_signal, data + 13 + sizeof("exit-signal"), namelen); channelp->exit_signal[namelen] = '\0'; /* TODO: save error message and language tag */ _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Exit signal %s received for " "channel %lu/%lu", channelp->exit_signal, channelp->local.id, channelp->remote.id)); } } } if(want_reply) { unsigned char packet[5]; libssh2_packet_add_jump_point4: session->packAdd_state = libssh2_NB_state_jump4; packet[0] = SSH_MSG_CHANNEL_FAILURE; memcpy(&packet[1], data + 1, 4); rc = _libssh2_transport_send(session, packet, 5, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; } } LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return rc; /* byte SSH_MSG_CHANNEL_CLOSE uint32 recipient channel */ case SSH_MSG_CHANNEL_CLOSE: if(datalen >= 5) channelp = _libssh2_channel_locate(session, _libssh2_ntohu32(data + 1)); if(!channelp) { /* We may have freed already, just quietly ignore this... */ LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; } _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Close received for channel %lu/%lu", channelp->local.id, channelp->remote.id)); channelp->remote.close = 1; channelp->remote.eof = 1; LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; /* byte SSH_MSG_CHANNEL_OPEN string "session" uint32 sender channel uint32 initial window size uint32 maximum packet size */ case SSH_MSG_CHANNEL_OPEN: if(datalen < 17) ; else if((datalen >= (sizeof("forwarded-tcpip") + 4)) && ((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1)) && (memcmp(data + 5, "forwarded-tcpip", sizeof("forwarded-tcpip") - 1) == 0)) { /* init the state struct */ memset(&session->packAdd_Qlstn_state, 0, sizeof(session->packAdd_Qlstn_state)); libssh2_packet_add_jump_point2: session->packAdd_state = libssh2_NB_state_jump2; rc = packet_queue_listener(session, data, datalen, &session->packAdd_Qlstn_state); } else if((datalen >= (sizeof("x11") + 4)) && ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) && (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { /* init the state struct */ memset(&session->packAdd_x11open_state, 0, sizeof(session->packAdd_x11open_state)); libssh2_packet_add_jump_point3: session->packAdd_state = libssh2_NB_state_jump3; rc = packet_x11_open(session, data, datalen, &session->packAdd_x11open_state); } else if((datalen >= (sizeof("auth-agent@openssh.com") + 4)) && ((sizeof("auth-agent@openssh.com") - 1) == _libssh2_ntohu32(data + 1)) && (memcmp(data + 5, "auth-agent@openssh.com", sizeof("auth-agent@openssh.com") - 1) == 0)) { /* init the state struct */ memset(&session->packAdd_authagent_state, 0, sizeof(session->packAdd_authagent_state)); libssh2_packet_add_jump_authagent: session->packAdd_state = libssh2_NB_state_jumpauthagent; rc = packet_authagent_open(session, data, datalen, &session->packAdd_authagent_state); } if(rc == LIBSSH2_ERROR_EAGAIN) return rc; LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return rc; /* byte SSH_MSG_CHANNEL_WINDOW_ADJUST uint32 recipient channel uint32 bytes to add */ case SSH_MSG_CHANNEL_WINDOW_ADJUST: if(datalen < 9) ; else { uint32_t bytestoadd = _libssh2_ntohu32(data + 5); channelp = _libssh2_channel_locate(session, _libssh2_ntohu32(data + 1)); if(channelp) { channelp->local.window_size += bytestoadd; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Window adjust for channel %lu/%lu, " "adding %lu bytes, new window_size=%lu", channelp->local.id, channelp->remote.id, bytestoadd, channelp->local.window_size)); } } LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; default: break; } session->packAdd_state = libssh2_NB_state_sent; } if(session->packAdd_state == libssh2_NB_state_sent) { LIBSSH2_PACKET *packetp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); if(!packetp) { _libssh2_debug((session, LIBSSH2_ERROR_ALLOC, "memory for packet")); LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return LIBSSH2_ERROR_ALLOC; } packetp->data = data; packetp->data_len = datalen; packetp->data_head = data_head; _libssh2_list_add(&session->packets, &packetp->node); session->packAdd_state = libssh2_NB_state_sent1; } if((msg == SSH_MSG_KEXINIT && !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) || (session->packAdd_state == libssh2_NB_state_sent2)) { if(session->packAdd_state == libssh2_NB_state_sent1) { /* * Remote wants new keys * Well, it's already in the brigade, * let's just call back into ourselves */ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys")); session->packAdd_state = libssh2_NB_state_sent2; } /* * The KEXINIT message has been added to the queue. The packAdd and * readPack states need to be reset because _libssh2_kex_exchange * (eventually) calls upon _libssh2_transport_read to read the rest of * the key exchange conversation. */ session->readPack_state = libssh2_NB_state_idle; session->packet.total_num = 0; session->packAdd_state = libssh2_NB_state_idle; session->fullpacket_state = libssh2_NB_state_idle; memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t)); /* * If there was a key reexchange failure, let's just hope we didn't * send NEWKEYS yet, otherwise remote will drop us like a rock */ rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; } session->packAdd_state = libssh2_NB_state_idle; return 0; } /* * _libssh2_packet_ask * * Scan the brigade for a matching packet type, optionally poll the socket for * a packet first */ int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len) { LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets); _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Looking for packet of type: %d", (int) packet_type)); while(packet) { if(packet->data[0] == packet_type && (packet->data_len >= (match_ofs + match_len)) && (!match_buf || (memcmp(packet->data + match_ofs, match_buf, match_len) == 0))) { *data = packet->data; *data_len = packet->data_len; /* unlink struct from session->packets */ _libssh2_list_remove(&packet->node); LIBSSH2_FREE(session, packet); return 0; } packet = _libssh2_list_next(&packet->node); } return -1; } /* * libssh2_packet_askv * * Scan for any of a list of packet types in the brigade, optionally poll the * socket for a packet first */ int _libssh2_packet_askv(LIBSSH2_SESSION * session, const unsigned char *packet_types, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len) { size_t i, packet_types_len = strlen((const char *) packet_types); for(i = 0; i < packet_types_len; i++) { if(_libssh2_packet_ask(session, packet_types[i], data, data_len, match_ofs, match_buf, match_len) == 0) { return 0; } } return -1; } /* * _libssh2_packet_require * * Loops _libssh2_transport_read() until the packet requested is available * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout * * Returns negative on error * Returns 0 when it has taken care of the requested packet. */ int _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len, packet_require_state_t *state) { if(state->start == 0) { if(_libssh2_packet_ask(session, packet_type, data, data_len, match_ofs, match_buf, match_len) == 0) { /* A packet was available in the packet brigade */ return 0; } state->start = time(NULL); } while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { int ret = _libssh2_transport_read(session); if(ret == LIBSSH2_ERROR_EAGAIN) return ret; else if(ret < 0) { state->start = 0; /* an error which is not just because of blocking */ return ret; } else if(ret == packet_type) { /* Be lazy, let packet_ask pull it out of the brigade */ ret = _libssh2_packet_ask(session, packet_type, data, data_len, match_ofs, match_buf, match_len); state->start = 0; return ret; } else if(ret == 0) { /* nothing available, wait until data arrives or we time out */ long left = session->packet_read_timeout - (long)(time(NULL) - state->start); if(left <= 0) { state->start = 0; return LIBSSH2_ERROR_TIMEOUT; } return -1; /* no packet available yet */ } } /* Only reached if the socket died */ return LIBSSH2_ERROR_SOCKET_DISCONNECT; } /* * _libssh2_packet_burn * * Loops _libssh2_transport_read() until any packet is available and promptly * discards it. * Used during KEX exchange to discard badly guessed KEX_INIT packets */ int _libssh2_packet_burn(LIBSSH2_SESSION * session, libssh2_nonblocking_states * state) { unsigned char *data; size_t data_len; unsigned char i, all_packets[255]; int ret; if(*state == libssh2_NB_state_idle) { for(i = 1; i < 255; i++) { all_packets[i - 1] = i; } all_packets[254] = 0; if(_libssh2_packet_askv(session, all_packets, &data, &data_len, 0, NULL, 0) == 0) { i = data[0]; /* A packet was available in the packet brigade, burn it */ LIBSSH2_FREE(session, data); return i; } _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Blocking until packet becomes available to burn")); *state = libssh2_NB_state_created; } while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { ret = _libssh2_transport_read(session); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } else if(ret < 0) { *state = libssh2_NB_state_idle; return ret; } else if(ret == 0) { /* FIXME: this might busyloop */ continue; } /* Be lazy, let packet_ask pull it out of the brigade */ if(0 == _libssh2_packet_ask(session, (unsigned char)ret, &data, &data_len, 0, NULL, 0)) { /* Smoke 'em if you got 'em */ LIBSSH2_FREE(session, data); *state = libssh2_NB_state_idle; return ret; } } /* Only reached if the socket died */ return LIBSSH2_ERROR_SOCKET_DISCONNECT; } /* * _libssh2_packet_requirev * * Loops _libssh2_transport_read() until one of a list of packet types * requested is available. SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause * a bailout. packet_types is a null terminated list of packet_type numbers */ int _libssh2_packet_requirev(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len, packet_requirev_state_t * state) { if(_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs, match_buf, match_len) == 0) { /* One of the packets listed was available in the packet brigade */ state->start = 0; return 0; } if(state->start == 0) { state->start = time(NULL); } while(session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { int ret = _libssh2_transport_read(session); if((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) { state->start = 0; return ret; } if(ret <= 0) { long left = session->packet_read_timeout - (long)(time(NULL) - state->start); if(left <= 0) { state->start = 0; return LIBSSH2_ERROR_TIMEOUT; } else if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } } if(strchr((char *) packet_types, ret)) { /* Be lazy, let packet_ask pull it out of the brigade */ ret = _libssh2_packet_askv(session, packet_types, data, data_len, match_ofs, match_buf, match_len); state->start = 0; return ret; } } /* Only reached if the socket died */ state->start = 0; return LIBSSH2_ERROR_SOCKET_DISCONNECT; } libssh2-1.11.0/src/Makefile.in0000644000175000017500000007246314432741315012735 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_WINDRES_TRUE@am__append_1 = libssh2.rc subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = libssh2_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libssh2_la_LIBADD = am__libssh2_la_SOURCES_DIST = agent.c bcrypt_pbkdf.c channel.c comp.c \ crypt.c crypto.c global.c hostkey.c keepalive.c kex.c \ knownhost.c mac.c misc.c packet.c pem.c publickey.c scp.c \ session.c sftp.c transport.c userauth.c userauth_kbd_packet.c \ version.c channel.h comp.h crypto.h libgcrypt.h libssh2_priv.h \ libssh2_setup.h mac.h mbedtls.h misc.h openssl.h os400qc3.h \ packet.h session.h sftp.h transport.h userauth.h \ userauth_kbd_packet.h wincng.h libssh2.rc am__objects_1 = agent.lo bcrypt_pbkdf.lo channel.lo comp.lo crypt.lo \ crypto.lo global.lo hostkey.lo keepalive.lo kex.lo \ knownhost.lo mac.lo misc.lo packet.lo pem.lo publickey.lo \ scp.lo session.lo sftp.lo transport.lo userauth.lo \ userauth_kbd_packet.lo version.lo am__objects_2 = @HAVE_WINDRES_TRUE@am__objects_3 = libssh2.lo am_libssh2_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) libssh2_la_OBJECTS = $(am_libssh2_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libssh2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libssh2_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/agent.Plo \ ./$(DEPDIR)/bcrypt_pbkdf.Plo ./$(DEPDIR)/channel.Plo \ ./$(DEPDIR)/comp.Plo ./$(DEPDIR)/crypt.Plo \ ./$(DEPDIR)/crypto.Plo ./$(DEPDIR)/global.Plo \ ./$(DEPDIR)/hostkey.Plo ./$(DEPDIR)/keepalive.Plo \ ./$(DEPDIR)/kex.Plo ./$(DEPDIR)/knownhost.Plo \ ./$(DEPDIR)/mac.Plo ./$(DEPDIR)/misc.Plo \ ./$(DEPDIR)/packet.Plo ./$(DEPDIR)/pem.Plo \ ./$(DEPDIR)/publickey.Plo ./$(DEPDIR)/scp.Plo \ ./$(DEPDIR)/session.Plo ./$(DEPDIR)/sftp.Plo \ ./$(DEPDIR)/transport.Plo ./$(DEPDIR)/userauth.Plo \ ./$(DEPDIR)/userauth_kbd_packet.Plo ./$(DEPDIR)/version.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libssh2_la_SOURCES) DIST_SOURCES = $(am__libssh2_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ libssh2_config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ $(srcdir)/libssh2_config.h.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@ HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBWOLFSSL = @HAVE_LIBWOLFSSL@ HAVE_LIBZ = @HAVE_LIBZ@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBCRYPT = @LIBBCRYPT@ LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSREQUIRED = @LIBSREQUIRED@ LIBSSH2VER = @LIBSSH2VER@ LIBSSL = @LIBSSL@ LIBSSL_PREFIX = @LIBSSL_PREFIX@ LIBTOOL = @LIBTOOL@ LIBWOLFSSL = @LIBWOLFSSL@ LIBWOLFSSL_PREFIX = @LIBWOLFSSL_PREFIX@ LIBZ = @LIBZ@ LIBZ_PREFIX = @LIBZ_PREFIX@ LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@ LTLIBOBJS = @LTLIBOBJS@ LTLIBSSL = @LTLIBSSL@ LTLIBWOLFSSL = @LTLIBWOLFSSL@ LTLIBZ = @LTLIBZ@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ RC = @RC@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSHD = @SSHD@ STRIP = @STRIP@ VERSION = -version-info 1:1:0 abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign nostdinc CSOURCES = \ agent.c \ bcrypt_pbkdf.c \ channel.c \ comp.c \ crypt.c \ crypto.c \ global.c \ hostkey.c \ keepalive.c \ kex.c \ knownhost.c \ mac.c \ misc.c \ packet.c \ pem.c \ publickey.c \ scp.c \ session.c \ sftp.c \ transport.c \ userauth.c \ userauth_kbd_packet.c \ version.c HHEADERS = \ channel.h \ comp.h \ crypto.h \ libgcrypt.h \ libssh2_priv.h \ libssh2_setup.h \ mac.h \ mbedtls.h \ misc.h \ openssl.h \ os400qc3.h \ packet.h \ session.h \ sftp.h \ transport.h \ userauth.h \ userauth_kbd_packet.h \ wincng.h EXTRA_DIST = agent_win.c blowfish.c libgcrypt.c mbedtls.c openssl.c \ os400qc3.c wincng.c libssh2_config.h.in \ libssh2_config_cmake.h.in CMakeLists.txt # Get the CSOURCES, HHEADERS and EXTRA_DIST defines libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS) $(am__append_1) lib_LTLIBRARIES = libssh2.la # srcdir/include for the shipped headers # builddir/src for the generated config header when building out of the source # tree AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/include # This flag accepts an argument of the form current[:revision[:age]]. So, # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to # 1. # # If either revision or age are omitted, they default to 0. Also note that age # must be less than or equal to the current interface number. # # Here are a set of rules to help you update your library version information: # # 1.Start with version information of 0:0:0 for each libtool library. # # 2.Update the version information only immediately before a public release of # your software. More frequent updates are unnecessary, and only guarantee # that the current interface number gets larger faster. # # 3.If the library source code has changed at all since the last update, then # increment revision (c:r+1:a) # # 4.If any interfaces have been added, removed, or changed since the last # update, increment current, and set revision to 0. (c+1:r=0:a) # # 5.If any interfaces have been added since the last public release, then # increment age. (c:r:a+1) # # 6.If any interfaces have been removed since the last public release, then # set age to 0. (c:r:a=0) # libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ -export-symbols-regex '^libssh2_.*' \ $(LTLIBZ) all: libssh2_config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj .rc $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(srcdir)/Makefile.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): libssh2_config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/libssh2_config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status src/libssh2_config.h $(srcdir)/libssh2_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f libssh2_config.h stamp-h1 install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libssh2.la: $(libssh2_la_OBJECTS) $(libssh2_la_DEPENDENCIES) $(EXTRA_libssh2_la_DEPENDENCIES) $(AM_V_CCLD)$(libssh2_la_LINK) -rpath $(libdir) $(libssh2_la_OBJECTS) $(libssh2_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcrypt_pbkdf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostkey.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keepalive.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/knownhost.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/publickey.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sftp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transport.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/userauth.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/userauth_kbd_packet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) libssh2_config.h installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/agent.Plo -rm -f ./$(DEPDIR)/bcrypt_pbkdf.Plo -rm -f ./$(DEPDIR)/channel.Plo -rm -f ./$(DEPDIR)/comp.Plo -rm -f ./$(DEPDIR)/crypt.Plo -rm -f ./$(DEPDIR)/crypto.Plo -rm -f ./$(DEPDIR)/global.Plo -rm -f ./$(DEPDIR)/hostkey.Plo -rm -f ./$(DEPDIR)/keepalive.Plo -rm -f ./$(DEPDIR)/kex.Plo -rm -f ./$(DEPDIR)/knownhost.Plo -rm -f ./$(DEPDIR)/mac.Plo -rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/packet.Plo -rm -f ./$(DEPDIR)/pem.Plo -rm -f ./$(DEPDIR)/publickey.Plo -rm -f ./$(DEPDIR)/scp.Plo -rm -f ./$(DEPDIR)/session.Plo -rm -f ./$(DEPDIR)/sftp.Plo -rm -f ./$(DEPDIR)/transport.Plo -rm -f ./$(DEPDIR)/userauth.Plo -rm -f ./$(DEPDIR)/userauth_kbd_packet.Plo -rm -f ./$(DEPDIR)/version.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/agent.Plo -rm -f ./$(DEPDIR)/bcrypt_pbkdf.Plo -rm -f ./$(DEPDIR)/channel.Plo -rm -f ./$(DEPDIR)/comp.Plo -rm -f ./$(DEPDIR)/crypt.Plo -rm -f ./$(DEPDIR)/crypto.Plo -rm -f ./$(DEPDIR)/global.Plo -rm -f ./$(DEPDIR)/hostkey.Plo -rm -f ./$(DEPDIR)/keepalive.Plo -rm -f ./$(DEPDIR)/kex.Plo -rm -f ./$(DEPDIR)/knownhost.Plo -rm -f ./$(DEPDIR)/mac.Plo -rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/packet.Plo -rm -f ./$(DEPDIR)/pem.Plo -rm -f ./$(DEPDIR)/publickey.Plo -rm -f ./$(DEPDIR)/scp.Plo -rm -f ./$(DEPDIR)/session.Plo -rm -f ./$(DEPDIR)/sftp.Plo -rm -f ./$(DEPDIR)/transport.Plo -rm -f ./$(DEPDIR)/userauth.Plo -rm -f ./$(DEPDIR)/userauth_kbd_packet.Plo -rm -f ./$(DEPDIR)/version.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: all install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-libLTLIBRARIES \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-libLTLIBRARIES .PRECIOUS: Makefile @HAVE_WINDRES_TRUE@.rc.lo: @HAVE_WINDRES_TRUE@ $(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libssh2-1.11.0/src/comp.c0000644000175000017500000002521314424650606011764 00000000000000/* Copyright (c) 2004-2007, 2019, Sara Golemon * Copyright (c) 2010-2014, Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #ifdef LIBSSH2_HAVE_ZLIB #include #undef compress /* dodge name clash with ZLIB macro */ #endif #include "comp.h" /* ******** * none * ******** */ /* * comp_method_none_comp * * Minimalist compression: Absolutely none */ static int comp_method_none_comp(LIBSSH2_SESSION *session, unsigned char *dest, size_t *dest_len, const unsigned char *src, size_t src_len, void **abstract) { (void)session; (void)abstract; (void)dest; (void)dest_len; (void)src; (void)src_len; return 0; } /* * comp_method_none_decomp * * Minimalist decompression: Absolutely none */ static int comp_method_none_decomp(LIBSSH2_SESSION * session, unsigned char **dest, size_t *dest_len, size_t payload_limit, const unsigned char *src, size_t src_len, void **abstract) { (void)session; (void)payload_limit; (void)abstract; *dest = (unsigned char *) src; *dest_len = src_len; return 0; } static const LIBSSH2_COMP_METHOD comp_method_none = { "none", 0, /* not really compressing */ 0, /* isn't used in userauth, go figure */ NULL, comp_method_none_comp, comp_method_none_decomp, NULL }; #ifdef LIBSSH2_HAVE_ZLIB /* ******** * zlib * ******** */ /* Memory management wrappers * Yes, I realize we're doing a callback to a callback, * Deal... */ static voidpf comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) { LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; return (voidpf) LIBSSH2_ALLOC(session, items * size); } static void comp_method_zlib_free(voidpf opaque, voidpf address) { LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; LIBSSH2_FREE(session, address); } /* libssh2_comp_method_zlib_init * All your bandwidth are belong to us (so save some) */ static int comp_method_zlib_init(LIBSSH2_SESSION * session, int compr, void **abstract) { z_stream *strm; int status; strm = LIBSSH2_CALLOC(session, sizeof(z_stream)); if(!strm) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "zlib compression/decompression"); } strm->opaque = (voidpf) session; strm->zalloc = (alloc_func) comp_method_zlib_alloc; strm->zfree = (free_func) comp_method_zlib_free; if(compr) { /* deflate */ status = deflateInit(strm, Z_DEFAULT_COMPRESSION); } else { /* inflate */ status = inflateInit(strm); } if(status != Z_OK) { LIBSSH2_FREE(session, strm); _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "unhandled zlib error %d", status)); return LIBSSH2_ERROR_COMPRESS; } *abstract = strm; return LIBSSH2_ERROR_NONE; } /* * libssh2_comp_method_zlib_comp * * Compresses source to destination. Without allocation. */ static int comp_method_zlib_comp(LIBSSH2_SESSION *session, unsigned char *dest, /* dest_len is a pointer to allow this function to update it with the final actual size used */ size_t *dest_len, const unsigned char *src, size_t src_len, void **abstract) { z_stream *strm = *abstract; uInt out_maxlen = (uInt)*dest_len; int status; strm->next_in = (unsigned char *) src; strm->avail_in = (uInt)src_len; strm->next_out = dest; strm->avail_out = out_maxlen; status = deflate(strm, Z_PARTIAL_FLUSH); if((status == Z_OK) && (strm->avail_out > 0)) { *dest_len = out_maxlen - strm->avail_out; return 0; } _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "unhandled zlib compression error %d, avail_out", status, strm->avail_out)); return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure"); } /* * libssh2_comp_method_zlib_decomp * * Decompresses source to destination. Allocates the output memory. */ static int comp_method_zlib_decomp(LIBSSH2_SESSION * session, unsigned char **dest, size_t *dest_len, size_t payload_limit, const unsigned char *src, size_t src_len, void **abstract) { z_stream *strm = *abstract; /* A short-term alloc of a full data chunk is better than a series of reallocs */ char *out; size_t out_maxlen; if(src_len <= SIZE_MAX / 4) out_maxlen = (uInt)src_len * 4; else out_maxlen = payload_limit; /* If strm is null, then we have not yet been initialized. */ if(!strm) return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS, "decompression uninitialized"); /* In practice they never come smaller than this */ if(out_maxlen < 25) out_maxlen = 25; if(out_maxlen > payload_limit) out_maxlen = payload_limit; strm->next_in = (unsigned char *) src; strm->avail_in = (uInt)src_len; strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, (uInt)out_maxlen); out = (char *) strm->next_out; strm->avail_out = (uInt)out_maxlen; if(!strm->next_out) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate decompression buffer"); /* Loop until it's all inflated or hit error */ for(;;) { int status; size_t out_ofs; char *newout; status = inflate(strm, Z_PARTIAL_FLUSH); if(status == Z_OK) { if(strm->avail_out > 0) /* status is OK and the output buffer has not been exhausted so we're done */ break; } else if(status == Z_BUF_ERROR) { /* the input data has been exhausted so we are done */ break; } else { /* error state */ LIBSSH2_FREE(session, out); _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "unhandled zlib error %d", status)); return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "decompression failure"); } if(out_maxlen > payload_limit || out_maxlen > SIZE_MAX / 2) { LIBSSH2_FREE(session, out); return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase"); } /* If we get here we need to grow the output buffer and try again */ out_ofs = out_maxlen - strm->avail_out; out_maxlen *= 2; newout = LIBSSH2_REALLOC(session, out, out_maxlen); if(!newout) { LIBSSH2_FREE(session, out); return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand decompression buffer"); } out = newout; strm->next_out = (unsigned char *) out + out_ofs; strm->avail_out = (uInt)(out_maxlen - out_ofs); } *dest = (unsigned char *) out; *dest_len = out_maxlen - strm->avail_out; return 0; } /* libssh2_comp_method_zlib_dtor * All done, no more compression for you */ static int comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract) { z_stream *strm = *abstract; if(strm) { if(compr) deflateEnd(strm); else inflateEnd(strm); LIBSSH2_FREE(session, strm); } *abstract = NULL; return 0; } static const LIBSSH2_COMP_METHOD comp_method_zlib = { "zlib", 1, /* yes, this compresses */ 1, /* do compression during userauth */ comp_method_zlib_init, comp_method_zlib_comp, comp_method_zlib_decomp, comp_method_zlib_dtor, }; static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = { "zlib@openssh.com", 1, /* yes, this compresses */ 0, /* don't use compression during userauth */ comp_method_zlib_init, comp_method_zlib_comp, comp_method_zlib_decomp, comp_method_zlib_dtor, }; #endif /* LIBSSH2_HAVE_ZLIB */ /* If compression is enabled by the API, then this array is used which then may allow compression if zlib is available at build time */ static const LIBSSH2_COMP_METHOD *comp_methods[] = { #ifdef LIBSSH2_HAVE_ZLIB &comp_method_zlib, &comp_method_zlib_openssh, #endif /* LIBSSH2_HAVE_ZLIB */ &comp_method_none, NULL }; /* If compression is disabled by the API, then this array is used */ static const LIBSSH2_COMP_METHOD *no_comp_methods[] = { &comp_method_none, NULL }; const LIBSSH2_COMP_METHOD ** _libssh2_comp_methods(LIBSSH2_SESSION *session) { if(session->flag.compress) return comp_methods; else return no_comp_methods; } libssh2-1.11.0/src/Makefile.inc0000644000175000017500000000240414432741311013060 00000000000000CSOURCES = \ agent.c \ bcrypt_pbkdf.c \ channel.c \ comp.c \ crypt.c \ crypto.c \ global.c \ hostkey.c \ keepalive.c \ kex.c \ knownhost.c \ mac.c \ misc.c \ packet.c \ pem.c \ publickey.c \ scp.c \ session.c \ sftp.c \ transport.c \ userauth.c \ userauth_kbd_packet.c \ version.c HHEADERS = \ channel.h \ comp.h \ crypto.h \ libgcrypt.h \ libssh2_priv.h \ libssh2_setup.h \ mac.h \ mbedtls.h \ misc.h \ openssl.h \ os400qc3.h \ packet.h \ session.h \ sftp.h \ transport.h \ userauth.h \ userauth_kbd_packet.h \ wincng.h EXTRA_DIST = \ agent_win.c \ blowfish.c \ libgcrypt.c \ mbedtls.c \ openssl.c \ os400qc3.c \ wincng.c libssh2-1.11.0/src/libssh2_config_cmake.h.in0000644000175000017500000000506514424650606015476 00000000000000/* Copyright (c) 2014 Alexander Lamaison * Copyright (c) 1999-2011 Douglas Gilbert. All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* Headers */ #cmakedefine HAVE_UNISTD_H #cmakedefine HAVE_INTTYPES_H #cmakedefine HAVE_SYS_SELECT_H #cmakedefine HAVE_SYS_UIO_H #cmakedefine HAVE_SYS_SOCKET_H #cmakedefine HAVE_SYS_IOCTL_H #cmakedefine HAVE_SYS_TIME_H #cmakedefine HAVE_SYS_UN_H /* for example and tests */ #cmakedefine HAVE_SYS_PARAM_H #cmakedefine HAVE_ARPA_INET_H #cmakedefine HAVE_NETINET_IN_H /* Functions */ #cmakedefine HAVE_GETTIMEOFDAY #cmakedefine HAVE_STRTOLL #cmakedefine HAVE_STRTOI64 #cmakedefine HAVE_SNPRINTF #cmakedefine HAVE_EXPLICIT_BZERO #cmakedefine HAVE_EXPLICIT_MEMSET #cmakedefine HAVE_MEMSET_S #cmakedefine HAVE_POLL #cmakedefine HAVE_SELECT /* Socket non-blocking support */ #cmakedefine HAVE_O_NONBLOCK #cmakedefine HAVE_FIONBIO #cmakedefine HAVE_IOCTLSOCKET_CASE #cmakedefine HAVE_SO_NONBLOCK /* attribute to export symbol */ #if defined(LIBSSH2_EXPORTS) && defined(LIBSSH2_LIBRARY) #cmakedefine LIBSSH2_API ${LIBSSH2_API} #endif libssh2-1.11.0/src/kex.c0000644000175000017500000047425614432741311011625 00000000000000/* Copyright (c) 2004-2007, Sara Golemon * Copyright (c) 2010-2019, Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "transport.h" #include "comp.h" #include "mac.h" #include /* define SHA1_DIGEST_LENGTH for the macro below */ #ifndef SHA1_DIGEST_LENGTH #define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH #endif /* TODO: Switch this to an inline and handle alloc() failures */ /* Helper macro called from kex_method_diffie_hellman_group1_sha1_key_exchange */ #define LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(value, reqlen, version) \ do { \ if(type == LIBSSH2_EC_CURVE_NISTP256) { \ LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, value, reqlen, version); \ } \ else if(type == LIBSSH2_EC_CURVE_NISTP384) { \ LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(384, value, reqlen, version); \ } \ else if(type == LIBSSH2_EC_CURVE_NISTP521) { \ LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, value, reqlen, version); \ } \ } while(0) #define LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(digest_type, value, \ reqlen, version) \ do { \ libssh2_sha##digest_type##_ctx hash; \ size_t len = 0; \ if(!(value)) { \ value = LIBSSH2_ALLOC(session, \ reqlen + SHA##digest_type##_DIGEST_LENGTH); \ } \ if(value) \ while(len < (size_t)reqlen) { \ (void)libssh2_sha##digest_type##_init(&hash); \ libssh2_sha##digest_type##_update(hash, \ exchange_state->k_value, \ exchange_state->k_value_len); \ libssh2_sha##digest_type##_update(hash, \ exchange_state->h_sig_comp, \ SHA##digest_type##_DIGEST_LENGTH); \ if(len > 0) { \ libssh2_sha##digest_type##_update(hash, value, len); \ } \ else { \ libssh2_sha##digest_type##_update(hash, (version), 1); \ libssh2_sha##digest_type##_update(hash, session->session_id,\ session->session_id_len); \ } \ libssh2_sha##digest_type##_final(hash, (value) + len); \ len += SHA##digest_type##_DIGEST_LENGTH; \ } \ } while(0) /*! * @note The following are wrapper functions used by diffie_hellman_sha_algo(). * TODO: Switch backend SHA macros to functions to allow function pointers * @discussion Ideally these would be function pointers but the backend macros * don't allow it so we have to wrap them up in helper functions */ static void _libssh2_sha_algo_ctx_init(int sha_algo, void *ctx) { if(sha_algo == 512) { (void)libssh2_sha512_init((libssh2_sha512_ctx*)ctx); } else if(sha_algo == 384) { (void)libssh2_sha384_init((libssh2_sha384_ctx*)ctx); } else if(sha_algo == 256) { (void)libssh2_sha256_init((libssh2_sha256_ctx*)ctx); } else if(sha_algo == 1) { (void)libssh2_sha1_init((libssh2_sha1_ctx*)ctx); } else { assert(0); } } static void _libssh2_sha_algo_ctx_update(int sha_algo, void *ctx, void *data, size_t len) { if(sha_algo == 512) { libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx; libssh2_sha512_update(*_ctx, data, len); } else if(sha_algo == 384) { libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx; libssh2_sha384_update(*_ctx, data, len); } else if(sha_algo == 256) { libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx; libssh2_sha256_update(*_ctx, data, len); } else if(sha_algo == 1) { libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx; libssh2_sha1_update(*_ctx, data, len); } else { #ifdef LIBSSH2DEBUG assert(0); #endif } } static void _libssh2_sha_algo_ctx_final(int sha_algo, void *ctx, void *hash) { if(sha_algo == 512) { libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx; libssh2_sha512_final(*_ctx, hash); } else if(sha_algo == 384) { libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx; libssh2_sha384_final(*_ctx, hash); } else if(sha_algo == 256) { libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx; libssh2_sha256_final(*_ctx, hash); } else if(sha_algo == 1) { libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx; libssh2_sha1_final(*_ctx, hash); } else { #ifdef LIBSSH2DEBUG assert(0); #endif } } static void _libssh2_sha_algo_value_hash(int sha_algo, LIBSSH2_SESSION *session, kmdhgGPshakex_state_t *exchange_state, unsigned char **data, size_t data_len, const unsigned char *version) { if(sha_algo == 512) { LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, *data, data_len, version); } else if(sha_algo == 384) { LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(384, *data, data_len, version); } else if(sha_algo == 256) { LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, *data, data_len, version); } else if(sha_algo == 1) { LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(1, *data, data_len, version); } else { #ifdef LIBSSH2DEBUG assert(0); #endif } } /*! * @function diffie_hellman_sha_algo * @abstract Diffie Hellman Key Exchange, Group Agnostic, * SHA Algorithm Agnostic * @result 0 on success, error code on failure */ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, _libssh2_bn *g, _libssh2_bn *p, int group_order, int sha_algo_value, void *exchange_hash_ctx, unsigned char packet_type_init, unsigned char packet_type_reply, unsigned char *midhash, size_t midhash_len, kmdhgGPshakex_state_t *exchange_state) { int ret = 0; int rc; int digest_len = 0; if(sha_algo_value == 512) digest_len = SHA512_DIGEST_LENGTH; else if(sha_algo_value == 384) digest_len = SHA384_DIGEST_LENGTH; else if(sha_algo_value == 256) digest_len = SHA256_DIGEST_LENGTH; else if(sha_algo_value == 1) digest_len = SHA1_DIGEST_LENGTH; else { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "sha algo value is unimplemented"); goto clean_exit; } if(exchange_state->state == libssh2_NB_state_idle) { /* Setup initial values */ exchange_state->e_packet = NULL; exchange_state->s_packet = NULL; exchange_state->k_value = NULL; exchange_state->ctx = _libssh2_bn_ctx_new(); libssh2_dh_init(&exchange_state->x); exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from server) mod p */ exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ /* Zero the whole thing out */ memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); /* Generate x and e */ if(_libssh2_bn_bits(p) > LIBSSH2_DH_MAX_MODULUS_BITS) { ret = _libssh2_error(session, LIBSSH2_ERROR_INVAL, "dh modulus value is too large"); goto clean_exit; } rc = libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, group_order, exchange_state->ctx); if(rc) { ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "dh key pair generation failed"); goto clean_exit; } /* Send KEX init */ /* packet_type(1) + String Length(4) + leading 0(1) */ exchange_state->e_packet_len = _libssh2_bn_bytes(exchange_state->e) + 6; if(_libssh2_bn_bits(exchange_state->e) % 8) { /* Leading 00 not needed */ exchange_state->e_packet_len--; } exchange_state->e_packet = LIBSSH2_ALLOC(session, exchange_state->e_packet_len); if(!exchange_state->e_packet) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error"); goto clean_exit; } exchange_state->e_packet[0] = packet_type_init; _libssh2_htonu32(exchange_state->e_packet + 1, (uint32_t)(exchange_state->e_packet_len - 5)); if(_libssh2_bn_bits(exchange_state->e) % 8) { _libssh2_bn_to_bin(exchange_state->e, exchange_state->e_packet + 5); } else { exchange_state->e_packet[5] = 0; _libssh2_bn_to_bin(exchange_state->e, exchange_state->e_packet + 6); } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", (int) packet_type_init)); exchange_state->state = libssh2_NB_state_created; } if(exchange_state->state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, exchange_state->e_packet, exchange_state->e_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send KEX init message"); goto clean_exit; } exchange_state->state = libssh2_NB_state_sent; } if(exchange_state->state == libssh2_NB_state_sent) { if(session->burn_optimistic_kexinit) { /* The first KEX packet to come along will be the guess initially * sent by the server. That guess turned out to be wrong so we * need to silently ignore it */ int burn_type; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Waiting for badly guessed KEX packet " "(to be ignored)")); burn_type = _libssh2_packet_burn(session, &exchange_state->burn_state); if(burn_type == LIBSSH2_ERROR_EAGAIN) { return burn_type; } else if(burn_type <= 0) { /* Failed to receive a packet */ ret = burn_type; goto clean_exit; } session->burn_optimistic_kexinit = 0; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Burnt packet of type: %02x", (unsigned int) burn_type)); } exchange_state->state = libssh2_NB_state_sent1; } if(exchange_state->state == libssh2_NB_state_sent1) { /* Wait for KEX reply */ struct string_buf buf; size_t host_key_len; int err; rc = _libssh2_packet_require(session, packet_type_reply, &exchange_state->s_packet, &exchange_state->s_packet_len, 0, NULL, 0, &exchange_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } if(rc) { ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting for KEX reply"); goto clean_exit; } /* Parse KEXDH_REPLY */ if(exchange_state->s_packet_len < 5) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet length DH-SHA"); goto clean_exit; } buf.data = exchange_state->s_packet; buf.len = exchange_state->s_packet_len; buf.dataptr = buf.data; buf.dataptr++; /* advance past type */ if(session->server_hostkey) LIBSSH2_FREE(session, session->server_hostkey); if(_libssh2_copy_string(session, &buf, &(session->server_hostkey), &host_key_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Could not copy host key"); goto clean_exit; } session->server_hostkey_len = (uint32_t)host_key_len; #if LIBSSH2_MD5 { libssh2_md5_ctx fingerprint_ctx; if(libssh2_md5_init(&fingerprint_ctx)) { libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5); session->server_hostkey_md5_valid = TRUE; } else { session->server_hostkey_md5_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char fingerprint[50], *fprint = fingerprint; int i; for(i = 0; i < 16; i++, fprint += 3) { snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); } *(--fprint) = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's MD5 Fingerprint: %s", fingerprint)); } #endif /* LIBSSH2DEBUG */ #endif /* ! LIBSSH2_MD5 */ { libssh2_sha1_ctx fingerprint_ctx; if(libssh2_sha1_init(&fingerprint_ctx)) { libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1); session->server_hostkey_sha1_valid = TRUE; } else { session->server_hostkey_sha1_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char fingerprint[64], *fprint = fingerprint; int i; for(i = 0; i < 20; i++, fprint += 3) { snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); } *(--fprint) = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's SHA1 Fingerprint: %s", fingerprint)); } #endif /* LIBSSH2DEBUG */ { libssh2_sha256_ctx fingerprint_ctx; if(libssh2_sha256_init(&fingerprint_ctx)) { libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha256_final(fingerprint_ctx, session->server_hostkey_sha256); session->server_hostkey_sha256_valid = TRUE; } else { session->server_hostkey_sha256_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char *base64Fingerprint = NULL; _libssh2_base64_encode(session, (const char *) session->server_hostkey_sha256, SHA256_DIGEST_LENGTH, &base64Fingerprint); if(base64Fingerprint) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's SHA256 Fingerprint: %s", base64Fingerprint)); LIBSSH2_FREE(session, base64Fingerprint); } } #endif /* LIBSSH2DEBUG */ if(session->hostkey->init(session, session->server_hostkey, session->server_hostkey_len, &session->server_hostkey_abstract)) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to initialize hostkey importer " "DH-SHA"); goto clean_exit; } if(_libssh2_get_string(&buf, &(exchange_state->f_value), &(exchange_state->f_value_len))) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to get DH-SHA f value"); goto clean_exit; } _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, exchange_state->f_value); if(_libssh2_get_string(&buf, &(exchange_state->h_sig), &(exchange_state->h_sig_len))) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to get DH-SHA h sig"); goto clean_exit; } /* Compute the shared secret */ libssh2_dh_secret(&exchange_state->x, exchange_state->k, exchange_state->f, p, exchange_state->ctx); exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; if(_libssh2_bn_bits(exchange_state->k) % 8) { /* don't need leading 00 */ exchange_state->k_value_len--; } exchange_state->k_value = LIBSSH2_ALLOC(session, exchange_state->k_value_len); if(!exchange_state->k_value) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for DH-SHA K"); goto clean_exit; } _libssh2_htonu32(exchange_state->k_value, (uint32_t)(exchange_state->k_value_len - 4)); if(_libssh2_bn_bits(exchange_state->k) % 8) { _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); } else { exchange_state->k_value[4] = 0; _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); } exchange_state->exchange_hash = (void *)&exchange_hash_ctx; _libssh2_sha_algo_ctx_init(sha_algo_value, exchange_hash_ctx); if(session->local.banner) { _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)(strlen((char *) session->local.banner) - 2)); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, session->local.banner, strlen((char *) session->local.banner) - 2); } else { _libssh2_htonu32(exchange_state->h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, (unsigned char *) LIBSSH2_SSH_DEFAULT_BANNER, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); } _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)strlen((char *) session->remote.banner)); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, session->remote.banner, strlen((char *) session->remote.banner)); _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)session->local.kexinit_len); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, session->local.kexinit, session->local.kexinit_len); _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)session->remote.kexinit_len); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, session->remote.kexinit, session->remote.kexinit_len); _libssh2_htonu32(exchange_state->h_sig_comp, session->server_hostkey_len); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, session->server_hostkey, session->server_hostkey_len); if(packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { /* diffie-hellman-group-exchange hashes additional fields */ _libssh2_htonu32(exchange_state->h_sig_comp, LIBSSH2_DH_GEX_MINGROUP); _libssh2_htonu32(exchange_state->h_sig_comp + 4, LIBSSH2_DH_GEX_OPTGROUP); _libssh2_htonu32(exchange_state->h_sig_comp + 8, LIBSSH2_DH_GEX_MAXGROUP); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 12); } if(midhash) { _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, midhash, midhash_len); } _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->e_packet + 1, exchange_state->e_packet_len - 1); _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)exchange_state->f_value_len); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp, 4); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->f_value, exchange_state->f_value_len); _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, exchange_state->k_value, exchange_state->k_value_len); _libssh2_sha_algo_ctx_final(sha_algo_value, exchange_hash_ctx, exchange_state->h_sig_comp); err = session->hostkey->sig_verify(session, exchange_state->h_sig, exchange_state->h_sig_len, exchange_state->h_sig_comp, digest_len, &session->server_hostkey_abstract); if(err) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Failed hostkey sig_verify(): %s: %d", session->hostkey->name, err)); ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature " "DH-SHA"); goto clean_exit; } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message")); exchange_state->c = SSH_MSG_NEWKEYS; exchange_state->state = libssh2_NB_state_sent2; } if(exchange_state->state == libssh2_NB_state_sent2) { rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message DH-SHA"); goto clean_exit; } exchange_state->state = libssh2_NB_state_sent3; } if(exchange_state->state == libssh2_NB_state_sent3) { rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, &exchange_state->tmp, &exchange_state->tmp_len, 0, NULL, 0, &exchange_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS DH-SHA"); goto clean_exit; } /* The first key exchange has been performed, switch to active crypt/comp/mac mode */ session->state |= LIBSSH2_STATE_NEWKEYS; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message DH-SHA")); /* This will actually end up being just packet_type(1) for this packet type anyway */ LIBSSH2_FREE(session, exchange_state->tmp); if(!session->session_id) { session->session_id = LIBSSH2_ALLOC(session, digest_len); if(!session->session_id) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for " "SHA digest"); goto clean_exit; } memcpy(session->session_id, exchange_state->h_sig_comp, digest_len); session->session_id_len = digest_len; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "session_id calculated")); } /* Cleanup any existing cipher */ if(session->local.crypt->dtor) { session->local.crypt->dtor(session, &session->local.crypt_abstract); } /* Calculate IV/Secret/Key for each direction */ if(session->local.crypt->init) { unsigned char *iv = NULL, *secret = NULL; int free_iv = 0, free_secret = 0; _libssh2_sha_algo_value_hash(sha_algo_value, session, exchange_state, &iv, session->local.crypt->iv_len, (const unsigned char *)"A"); if(!iv) { ret = -1; goto clean_exit; } _libssh2_sha_algo_value_hash(sha_algo_value, session, exchange_state, &secret, session->local.crypt->secret_len, (const unsigned char *)"C"); if(!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(session->local.crypt-> init(session, session->local.crypt, iv, &free_iv, secret, &free_secret, 1, &session->local.crypt_abstract)) { LIBSSH2_FREE(session, iv); LIBSSH2_FREE(session, secret); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(free_iv) { _libssh2_explicit_zero(iv, session->local.crypt->iv_len); LIBSSH2_FREE(session, iv); } if(free_secret) { _libssh2_explicit_zero(secret, session->local.crypt->secret_len); LIBSSH2_FREE(session, secret); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server IV and Key calculated")); if(session->remote.crypt->dtor) { /* Cleanup any existing cipher */ session->remote.crypt->dtor(session, &session->remote.crypt_abstract); } if(session->remote.crypt->init) { unsigned char *iv = NULL, *secret = NULL; int free_iv = 0, free_secret = 0; _libssh2_sha_algo_value_hash(sha_algo_value, session, exchange_state, &iv, session->remote.crypt->iv_len, (const unsigned char *)"B"); if(!iv) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } _libssh2_sha_algo_value_hash(sha_algo_value, session, exchange_state, &secret, session->remote.crypt->secret_len, (const unsigned char *)"D"); if(!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(session->remote.crypt-> init(session, session->remote.crypt, iv, &free_iv, secret, &free_secret, 0, &session->remote.crypt_abstract)) { LIBSSH2_FREE(session, iv); LIBSSH2_FREE(session, secret); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(free_iv) { _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); LIBSSH2_FREE(session, iv); } if(free_secret) { _libssh2_explicit_zero(secret, session->remote.crypt->secret_len); LIBSSH2_FREE(session, secret); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client IV and Key calculated")); if(session->local.mac->dtor) { session->local.mac->dtor(session, &session->local.mac_abstract); } if(session->local.mac->init) { unsigned char *key = NULL; int free_key = 0; _libssh2_sha_algo_value_hash(sha_algo_value, session, exchange_state, &key, session->local.mac->key_len, (const unsigned char *)"E"); if(!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } session->local.mac->init(session, key, &free_key, &session->local.mac_abstract); if(free_key) { _libssh2_explicit_zero(key, session->local.mac->key_len); LIBSSH2_FREE(session, key); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server HMAC Key calculated")); if(session->remote.mac->dtor) { session->remote.mac->dtor(session, &session->remote.mac_abstract); } if(session->remote.mac->init) { unsigned char *key = NULL; int free_key = 0; _libssh2_sha_algo_value_hash(sha_algo_value, session, exchange_state, &key, session->remote.mac->key_len, (const unsigned char *)"F"); if(!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } session->remote.mac->init(session, key, &free_key, &session->remote.mac_abstract); if(free_key) { _libssh2_explicit_zero(key, session->remote.mac->key_len); LIBSSH2_FREE(session, key); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client HMAC Key calculated")); /* Initialize compression for each direction */ /* Cleanup any existing compression */ if(session->local.comp && session->local.comp->dtor) { session->local.comp->dtor(session, 1, &session->local.comp_abstract); } if(session->local.comp && session->local.comp->init) { if(session->local.comp->init(session, 1, &session->local.comp_abstract)) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server compression initialized")); if(session->remote.comp && session->remote.comp->dtor) { session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); } if(session->remote.comp && session->remote.comp->init) { if(session->remote.comp->init(session, 0, &session->remote.comp_abstract)) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client compression initialized")); } clean_exit: libssh2_dh_dtor(&exchange_state->x); _libssh2_bn_free(exchange_state->e); exchange_state->e = NULL; _libssh2_bn_free(exchange_state->f); exchange_state->f = NULL; _libssh2_bn_free(exchange_state->k); exchange_state->k = NULL; _libssh2_bn_ctx_free(exchange_state->ctx); exchange_state->ctx = NULL; if(exchange_state->e_packet) { LIBSSH2_FREE(session, exchange_state->e_packet); exchange_state->e_packet = NULL; } if(exchange_state->s_packet) { LIBSSH2_FREE(session, exchange_state->s_packet); exchange_state->s_packet = NULL; } if(exchange_state->k_value) { LIBSSH2_FREE(session, exchange_state->k_value); exchange_state->k_value = NULL; } exchange_state->state = libssh2_NB_state_idle; return ret; } /* kex_method_diffie_hellman_group1_sha1_key_exchange * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1 */ static int kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t * key_state) { static const unsigned char p_value[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int ret; libssh2_sha1_ctx exchange_hash_ctx; if(key_state->state == libssh2_NB_state_idle) { /* g == 2 */ key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ /* Initialize P and G */ _libssh2_bn_set_word(key_state->g, 2); _libssh2_bn_from_bin(key_state->p, 128, p_value); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating Diffie-Hellman Group1 Key Exchange")); key_state->state = libssh2_NB_state_created; } ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, 128, 1, (void *)&exchange_hash_ctx, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } _libssh2_bn_free(key_state->p); key_state->p = NULL; _libssh2_bn_free(key_state->g); key_state->g = NULL; key_state->state = libssh2_NB_state_idle; return ret; } /* kex_method_diffie_hellman_group14_key_exchange * Diffie-Hellman Group14 Key Exchange with hash function callback */ typedef int (*diffie_hellman_hash_func_t)(LIBSSH2_SESSION *, _libssh2_bn *, _libssh2_bn *, int, int, void *, unsigned char, unsigned char, unsigned char *, size_t, kmdhgGPshakex_state_t *); static int kex_method_diffie_hellman_group14_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t * key_state, int sha_algo_value, void *exchange_hash_ctx, diffie_hellman_hash_func_t hashfunc) { static const unsigned char p_value[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int ret; if(key_state->state == libssh2_NB_state_idle) { key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ /* g == 2 */ /* Initialize P and G */ _libssh2_bn_set_word(key_state->g, 2); _libssh2_bn_from_bin(key_state->p, 256, p_value); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating Diffie-Hellman Group14 Key Exchange")); key_state->state = libssh2_NB_state_created; } ret = hashfunc(session, key_state->g, key_state->p, 256, sha_algo_value, exchange_hash_ctx, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } key_state->state = libssh2_NB_state_idle; _libssh2_bn_free(key_state->p); key_state->p = NULL; _libssh2_bn_free(key_state->g); key_state->g = NULL; return ret; } /* kex_method_diffie_hellman_group14_sha1_key_exchange * Diffie-Hellman Group14 Key Exchange using SHA1 */ static int kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t * key_state) { libssh2_sha1_ctx ctx; return kex_method_diffie_hellman_group14_key_exchange(session, key_state, 1, &ctx, diffie_hellman_sha_algo); } /* kex_method_diffie_hellman_group14_sha256_key_exchange * Diffie-Hellman Group14 Key Exchange using SHA256 */ static int kex_method_diffie_hellman_group14_sha256_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t * key_state) { libssh2_sha256_ctx ctx; return kex_method_diffie_hellman_group14_key_exchange(session, key_state, 256, &ctx, diffie_hellman_sha_algo); } /* kex_method_diffie_hellman_group16_sha512_key_exchange * Diffie-Hellman Group16 Key Exchange using SHA512 */ static int kex_method_diffie_hellman_group16_sha512_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t * key_state) { static const unsigned char p_value[512] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int ret; libssh2_sha512_ctx exchange_hash_ctx; if(key_state->state == libssh2_NB_state_idle) { key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ /* g == 2 */ /* Initialize P and G */ _libssh2_bn_set_word(key_state->g, 2); _libssh2_bn_from_bin(key_state->p, 512, p_value); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating Diffie-Hellman Group16 Key Exchange")); key_state->state = libssh2_NB_state_created; } ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, 512, 512, (void *)&exchange_hash_ctx, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } key_state->state = libssh2_NB_state_idle; _libssh2_bn_free(key_state->p); key_state->p = NULL; _libssh2_bn_free(key_state->g); key_state->g = NULL; return ret; } /* kex_method_diffie_hellman_group16_sha512_key_exchange * Diffie-Hellman Group18 Key Exchange using SHA512 */ static int kex_method_diffie_hellman_group18_sha512_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t * key_state) { static const unsigned char p_value[1024] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int ret; libssh2_sha512_ctx exchange_hash_ctx; if(key_state->state == libssh2_NB_state_idle) { key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ /* g == 2 */ /* Initialize P and G */ _libssh2_bn_set_word(key_state->g, 2); _libssh2_bn_from_bin(key_state->p, 1024, p_value); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating Diffie-Hellman Group18 Key Exchange")); key_state->state = libssh2_NB_state_created; } ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, 1024, 512, (void *)&exchange_hash_ctx, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } key_state->state = libssh2_NB_state_idle; _libssh2_bn_free(key_state->p); key_state->p = NULL; _libssh2_bn_free(key_state->g); key_state->g = NULL; return ret; } /* kex_method_diffie_hellman_group_exchange_sha1_key_exchange * Diffie-Hellman Group Exchange Key Exchange using SHA1 * Negotiates random(ish) group for secret derivation */ static int kex_method_diffie_hellman_group_exchange_sha1_key_exchange( LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) { int ret = 0; int rc; if(key_state->state == libssh2_NB_state_idle) { key_state->p = _libssh2_bn_init_from_bin(); key_state->g = _libssh2_bn_init_from_bin(); /* Ask for a P and G pair */ key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); key_state->request_len = 13; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating Diffie-Hellman Group-Exchange SHA1")); key_state->state = libssh2_NB_state_created; } if(key_state->state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, key_state->request, key_state->request_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send Group Exchange Request"); goto dh_gex_clean_exit; } key_state->state = libssh2_NB_state_sent; } if(key_state->state == libssh2_NB_state_sent) { rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, &key_state->data, &key_state->data_len, 0, NULL, 0, &key_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timeout waiting for GEX_GROUP reply"); goto dh_gex_clean_exit; } key_state->state = libssh2_NB_state_sent1; } if(key_state->state == libssh2_NB_state_sent1) { size_t p_len, g_len; unsigned char *p, *g; struct string_buf buf; libssh2_sha1_ctx exchange_hash_ctx; if(key_state->data_len < 9) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected key length DH-SHA1"); goto dh_gex_clean_exit; } buf.data = key_state->data; buf.dataptr = buf.data; buf.len = key_state->data_len; buf.dataptr++; /* increment to big num */ if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected value DH-SHA1 p"); goto dh_gex_clean_exit; } if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected value DH-SHA1 g"); goto dh_gex_clean_exit; } _libssh2_bn_from_bin(key_state->p, p_len, p); _libssh2_bn_from_bin(key_state->g, g_len, g); ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, (int)p_len, 1, (void *)&exchange_hash_ctx, SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, key_state->data + 1, key_state->data_len - 1, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } LIBSSH2_FREE(session, key_state->data); } dh_gex_clean_exit: key_state->state = libssh2_NB_state_idle; _libssh2_bn_free(key_state->g); key_state->g = NULL; _libssh2_bn_free(key_state->p); key_state->p = NULL; return ret; } /* kex_method_diffie_hellman_group_exchange_sha256_key_exchange * Diffie-Hellman Group Exchange Key Exchange using SHA256 * Negotiates random(ish) group for secret derivation */ static int kex_method_diffie_hellman_group_exchange_sha256_key_exchange( LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) { int ret = 0; int rc; if(key_state->state == libssh2_NB_state_idle) { key_state->p = _libssh2_bn_init(); key_state->g = _libssh2_bn_init(); /* Ask for a P and G pair */ key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); key_state->request_len = 13; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating Diffie-Hellman Group-Exchange SHA256")); key_state->state = libssh2_NB_state_created; } if(key_state->state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, key_state->request, key_state->request_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send " "Group Exchange Request SHA256"); goto dh_gex_clean_exit; } key_state->state = libssh2_NB_state_sent; } if(key_state->state == libssh2_NB_state_sent) { rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, &key_state->data, &key_state->data_len, 0, NULL, 0, &key_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timeout waiting for GEX_GROUP reply SHA256"); goto dh_gex_clean_exit; } key_state->state = libssh2_NB_state_sent1; } if(key_state->state == libssh2_NB_state_sent1) { unsigned char *p, *g; size_t p_len, g_len; struct string_buf buf; libssh2_sha256_ctx exchange_hash_ctx; if(key_state->data_len < 9) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected key length DH-SHA256"); goto dh_gex_clean_exit; } buf.data = key_state->data; buf.dataptr = buf.data; buf.len = key_state->data_len; buf.dataptr++; /* increment to big num */ if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected value DH-SHA256 p"); goto dh_gex_clean_exit; } if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected value DH-SHA256 g"); goto dh_gex_clean_exit; } _libssh2_bn_from_bin(key_state->p, p_len, p); _libssh2_bn_from_bin(key_state->g, g_len, g); ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, (int)p_len, 256, (void *)&exchange_hash_ctx, SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, key_state->data + 1, key_state->data_len - 1, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } LIBSSH2_FREE(session, key_state->data); } dh_gex_clean_exit: key_state->state = libssh2_NB_state_idle; _libssh2_bn_free(key_state->g); key_state->g = NULL; _libssh2_bn_free(key_state->p); key_state->p = NULL; return ret; } /* LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY * * Macro that create and verifies EC SHA hash with a given digest bytes * * Payload format: * * string V_C, client's identification string (CR and LF excluded) * string V_S, server's identification string (CR and LF excluded) * string I_C, payload of the client's SSH_MSG_KEXINIT * string I_S, payload of the server's SSH_MSG_KEXINIT * string K_S, server's public host key * string Q_C, client's ephemeral public key octet string * string Q_S, server's ephemeral public key octet string * mpint K, shared secret * */ #define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \ do { \ libssh2_sha##digest_type##_ctx ctx; \ exchange_state->exchange_hash = (void *)&ctx; \ (void)libssh2_sha##digest_type##_init(&ctx); \ if(session->local.banner) { \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)(strlen((char *) session->local.banner) - 2)); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ (char *) session->local.banner, \ strlen((char *) \ session->local.banner) \ - 2); \ } \ else { \ _libssh2_htonu32(exchange_state->h_sig_comp, \ sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ LIBSSH2_SSH_DEFAULT_BANNER, \ sizeof(LIBSSH2_SSH_DEFAULT_BANNER) \ - 1); \ } \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)strlen((char *) session->remote.banner)); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ session->remote.banner, \ strlen((char *) \ session->remote.banner)); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)session->local.kexinit_len); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ session->local.kexinit, \ session->local.kexinit_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)session->remote.kexinit_len); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ session->remote.kexinit, \ session->remote.kexinit_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ session->server_hostkey_len); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ session->server_hostkey, \ session->server_hostkey_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)public_key_len); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ public_key, \ public_key_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)server_public_key_len); \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ libssh2_sha##digest_type##_update(ctx, \ server_public_key, \ server_public_key_len); \ \ libssh2_sha##digest_type##_update(ctx, \ exchange_state->k_value, \ exchange_state->k_value_len); \ \ libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \ \ if(session->hostkey-> \ sig_verify(session, exchange_state->h_sig, \ exchange_state->h_sig_len, exchange_state->h_sig_comp, \ SHA##digest_type##_DIGEST_LENGTH, \ &session->server_hostkey_abstract)) { \ rc = -1; \ } \ } while(0) #if LIBSSH2_ECDSA /* kex_session_ecdh_curve_type * returns the EC curve type by name used in key exchange */ static int kex_session_ecdh_curve_type(const char *name, libssh2_curve_type *out_type) { int ret = 0; libssh2_curve_type type; if(!name) return -1; if(strcmp(name, "ecdh-sha2-nistp256") == 0) type = LIBSSH2_EC_CURVE_NISTP256; else if(strcmp(name, "ecdh-sha2-nistp384") == 0) type = LIBSSH2_EC_CURVE_NISTP384; else if(strcmp(name, "ecdh-sha2-nistp521") == 0) type = LIBSSH2_EC_CURVE_NISTP521; else { /* silence: warning C4701: potentially uninitialized local variable 'type' used */ #if defined(_MSC_VER) type = (libssh2_curve_type)0; #endif ret = -1; } if(ret == 0 && out_type) { *out_type = type; } return ret; } /* ecdh_sha2_nistp * Elliptic Curve Diffie Hellman Key Exchange */ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type, unsigned char *data, size_t data_len, unsigned char *public_key, size_t public_key_len, _libssh2_ec_key *private_key, kmdhgGPshakex_state_t *exchange_state) { int ret = 0; int rc; if(data_len < 5) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Host key data is too short"); return ret; } if(exchange_state->state == libssh2_NB_state_idle) { /* Setup initial values */ exchange_state->k = _libssh2_bn_init(); exchange_state->state = libssh2_NB_state_created; } if(exchange_state->state == libssh2_NB_state_created) { /* parse INIT reply data */ /* host key K_S */ unsigned char *server_public_key; size_t server_public_key_len; struct string_buf buf; buf.data = data; buf.len = data_len; buf.dataptr = buf.data; buf.dataptr++; /* Advance past packet type */ if(_libssh2_copy_string(session, &buf, &(session->server_hostkey), &server_public_key_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for a copy " "of the host ECDH key"); goto clean_exit; } session->server_hostkey_len = (uint32_t)server_public_key_len; #if LIBSSH2_MD5 { libssh2_md5_ctx fingerprint_ctx; if(libssh2_md5_init(&fingerprint_ctx)) { libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5); session->server_hostkey_md5_valid = TRUE; } else { session->server_hostkey_md5_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char fingerprint[50], *fprint = fingerprint; int i; for(i = 0; i < 16; i++, fprint += 3) { snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); } *(--fprint) = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's MD5 Fingerprint: %s", fingerprint)); } #endif /* LIBSSH2DEBUG */ #endif /* ! LIBSSH2_MD5 */ { libssh2_sha1_ctx fingerprint_ctx; if(libssh2_sha1_init(&fingerprint_ctx)) { libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1); session->server_hostkey_sha1_valid = TRUE; } else { session->server_hostkey_sha1_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char fingerprint[64], *fprint = fingerprint; int i; for(i = 0; i < 20; i++, fprint += 3) { snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); } *(--fprint) = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's SHA1 Fingerprint: %s", fingerprint)); } #endif /* LIBSSH2DEBUG */ /* SHA256 */ { libssh2_sha256_ctx fingerprint_ctx; if(libssh2_sha256_init(&fingerprint_ctx)) { libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha256_final(fingerprint_ctx, session->server_hostkey_sha256); session->server_hostkey_sha256_valid = TRUE; } else { session->server_hostkey_sha256_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char *base64Fingerprint = NULL; _libssh2_base64_encode(session, (const char *) session->server_hostkey_sha256, SHA256_DIGEST_LENGTH, &base64Fingerprint); if(base64Fingerprint) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's SHA256 Fingerprint: %s", base64Fingerprint)); LIBSSH2_FREE(session, base64Fingerprint); } } #endif /* LIBSSH2DEBUG */ if(session->hostkey->init(session, session->server_hostkey, session->server_hostkey_len, &session->server_hostkey_abstract)) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to initialize hostkey importer " "ECDH"); goto clean_exit; } /* server public key Q_S */ if(_libssh2_get_string(&buf, &server_public_key, &server_public_key_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected key length ECDH"); goto clean_exit; } /* server signature */ if(_libssh2_get_string(&buf, &exchange_state->h_sig, &(exchange_state->h_sig_len))) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unexpected ECDH server sig length"); goto clean_exit; } /* Compute the shared secret K */ rc = _libssh2_ecdh_gen_k(&exchange_state->k, private_key, server_public_key, server_public_key_len); if(rc) { ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to create ECDH shared secret"); goto clean_exit; } exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; if(_libssh2_bn_bits(exchange_state->k) % 8) { /* don't need leading 00 */ exchange_state->k_value_len--; } exchange_state->k_value = LIBSSH2_ALLOC(session, exchange_state->k_value_len); if(!exchange_state->k_value) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for ECDH K"); goto clean_exit; } _libssh2_htonu32(exchange_state->k_value, (uint32_t)(exchange_state->k_value_len - 4)); if(_libssh2_bn_bits(exchange_state->k) % 8) { _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); } else { exchange_state->k_value[4] = 0; _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); } /* verify hash */ switch(type) { case LIBSSH2_EC_CURVE_NISTP256: LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256); break; case LIBSSH2_EC_CURVE_NISTP384: LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(384); break; case LIBSSH2_EC_CURVE_NISTP521: LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(512); break; } if(rc) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature " "ECDH"); goto clean_exit; } exchange_state->c = SSH_MSG_NEWKEYS; exchange_state->state = libssh2_NB_state_sent; } if(exchange_state->state == libssh2_NB_state_sent) { rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message ECDH"); goto clean_exit; } exchange_state->state = libssh2_NB_state_sent2; } if(exchange_state->state == libssh2_NB_state_sent2) { rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, &exchange_state->tmp, &exchange_state->tmp_len, 0, NULL, 0, &exchange_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS ECDH"); goto clean_exit; } /* The first key exchange has been performed, switch to active crypt/comp/mac mode */ session->state |= LIBSSH2_STATE_NEWKEYS; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message ECDH")); /* This will actually end up being just packet_type(1) for this packet type anyway */ LIBSSH2_FREE(session, exchange_state->tmp); if(!session->session_id) { size_t digest_length = 0; if(type == LIBSSH2_EC_CURVE_NISTP256) digest_length = SHA256_DIGEST_LENGTH; else if(type == LIBSSH2_EC_CURVE_NISTP384) digest_length = SHA384_DIGEST_LENGTH; else if(type == LIBSSH2_EC_CURVE_NISTP521) digest_length = SHA512_DIGEST_LENGTH; else{ ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unknown SHA digest for EC curve"); goto clean_exit; } session->session_id = LIBSSH2_ALLOC(session, digest_length); if(!session->session_id) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for " "SHA digest"); goto clean_exit; } memcpy(session->session_id, exchange_state->h_sig_comp, digest_length); session->session_id_len = (uint32_t)digest_length; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "session_id calculated")); } /* Cleanup any existing cipher */ if(session->local.crypt->dtor) { session->local.crypt->dtor(session, &session->local.crypt_abstract); } /* Calculate IV/Secret/Key for each direction */ if(session->local.crypt->init) { unsigned char *iv = NULL, *secret = NULL; int free_iv = 0, free_secret = 0; LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(iv, session->local.crypt-> iv_len, "A"); if(!iv) { ret = -1; goto clean_exit; } LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(secret, session->local.crypt-> secret_len, "C"); if(!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(session->local.crypt-> init(session, session->local.crypt, iv, &free_iv, secret, &free_secret, 1, &session->local.crypt_abstract)) { LIBSSH2_FREE(session, iv); LIBSSH2_FREE(session, secret); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(free_iv) { _libssh2_explicit_zero(iv, session->local.crypt->iv_len); LIBSSH2_FREE(session, iv); } if(free_secret) { _libssh2_explicit_zero(secret, session->local.crypt->secret_len); LIBSSH2_FREE(session, secret); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server IV and Key calculated")); if(session->remote.crypt->dtor) { /* Cleanup any existing cipher */ session->remote.crypt->dtor(session, &session->remote.crypt_abstract); } if(session->remote.crypt->init) { unsigned char *iv = NULL, *secret = NULL; int free_iv = 0, free_secret = 0; LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(iv, session->remote.crypt-> iv_len, "B"); if(!iv) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(secret, session->remote.crypt-> secret_len, "D"); if(!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(session->remote.crypt-> init(session, session->remote.crypt, iv, &free_iv, secret, &free_secret, 0, &session->remote.crypt_abstract)) { LIBSSH2_FREE(session, iv); LIBSSH2_FREE(session, secret); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(free_iv) { _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); LIBSSH2_FREE(session, iv); } if(free_secret) { _libssh2_explicit_zero(secret, session->remote.crypt->secret_len); LIBSSH2_FREE(session, secret); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client IV and Key calculated")); if(session->local.mac->dtor) { session->local.mac->dtor(session, &session->local.mac_abstract); } if(session->local.mac->init) { unsigned char *key = NULL; int free_key = 0; LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(key, session->local.mac-> key_len, "E"); if(!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } session->local.mac->init(session, key, &free_key, &session->local.mac_abstract); if(free_key) { _libssh2_explicit_zero(key, session->local.mac->key_len); LIBSSH2_FREE(session, key); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server HMAC Key calculated")); if(session->remote.mac->dtor) { session->remote.mac->dtor(session, &session->remote.mac_abstract); } if(session->remote.mac->init) { unsigned char *key = NULL; int free_key = 0; LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(key, session->remote.mac-> key_len, "F"); if(!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } session->remote.mac->init(session, key, &free_key, &session->remote.mac_abstract); if(free_key) { _libssh2_explicit_zero(key, session->remote.mac->key_len); LIBSSH2_FREE(session, key); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client HMAC Key calculated")); /* Initialize compression for each direction */ /* Cleanup any existing compression */ if(session->local.comp && session->local.comp->dtor) { session->local.comp->dtor(session, 1, &session->local.comp_abstract); } if(session->local.comp && session->local.comp->init) { if(session->local.comp->init(session, 1, &session->local.comp_abstract)) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server compression initialized")); if(session->remote.comp && session->remote.comp->dtor) { session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); } if(session->remote.comp && session->remote.comp->init) { if(session->remote.comp->init(session, 0, &session->remote.comp_abstract)) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client compression initialized")); } clean_exit: _libssh2_bn_free(exchange_state->k); exchange_state->k = NULL; if(exchange_state->k_value) { LIBSSH2_FREE(session, exchange_state->k_value); exchange_state->k_value = NULL; } exchange_state->state = libssh2_NB_state_idle; return ret; } /* kex_method_ecdh_key_exchange * * Elliptic Curve Diffie Hellman Key Exchange * supports SHA256/384/512 hashes based on negotiated ecdh method * */ static int kex_method_ecdh_key_exchange (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) { int ret = 0; int rc = 0; unsigned char *s; libssh2_curve_type type; if(key_state->state == libssh2_NB_state_idle) { key_state->public_key_oct = NULL; key_state->state = libssh2_NB_state_created; } if(key_state->state == libssh2_NB_state_created) { rc = kex_session_ecdh_curve_type(session->kex->name, &type); if(rc) { ret = _libssh2_error(session, -1, "Unknown KEX nistp curve type"); goto ecdh_clean_exit; } rc = _libssh2_ecdsa_create_key(session, &key_state->private_key, &key_state->public_key_oct, &key_state->public_key_oct_len, type); if(rc) { ret = _libssh2_error(session, rc, "Unable to create private key"); goto ecdh_clean_exit; } key_state->request[0] = SSH2_MSG_KEX_ECDH_INIT; s = key_state->request + 1; _libssh2_store_str(&s, (const char *)key_state->public_key_oct, key_state->public_key_oct_len); key_state->request_len = key_state->public_key_oct_len + 5; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating ECDH SHA2 NISTP256")); key_state->state = libssh2_NB_state_sent; } if(key_state->state == libssh2_NB_state_sent) { rc = _libssh2_transport_send(session, key_state->request, key_state->request_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send ECDH_INIT"); goto ecdh_clean_exit; } key_state->state = libssh2_NB_state_sent1; } if(key_state->state == libssh2_NB_state_sent1) { rc = _libssh2_packet_require(session, SSH2_MSG_KEX_ECDH_REPLY, &key_state->data, &key_state->data_len, 0, NULL, 0, &key_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timeout waiting for ECDH_REPLY reply"); goto ecdh_clean_exit; } key_state->state = libssh2_NB_state_sent2; } if(key_state->state == libssh2_NB_state_sent2) { rc = kex_session_ecdh_curve_type(session->kex->name, &type); if(rc) { ret = _libssh2_error(session, -1, "Unknown KEX nistp curve type"); goto ecdh_clean_exit; } ret = ecdh_sha2_nistp(session, type, key_state->data, key_state->data_len, (unsigned char *)key_state->public_key_oct, key_state->public_key_oct_len, key_state->private_key, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } LIBSSH2_FREE(session, key_state->data); } ecdh_clean_exit: if(key_state->public_key_oct) { LIBSSH2_FREE(session, key_state->public_key_oct); key_state->public_key_oct = NULL; } if(key_state->private_key) { _libssh2_ecdsa_free(key_state->private_key); key_state->private_key = NULL; } key_state->state = libssh2_NB_state_idle; return ret; } #endif /* LIBSSH2_ECDSA */ #if LIBSSH2_ED25519 /* curve25519_sha256 * Elliptic Curve Key Exchange */ static int curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data, size_t data_len, unsigned char public_key[LIBSSH2_ED25519_KEY_LEN], unsigned char private_key[LIBSSH2_ED25519_KEY_LEN], kmdhgGPshakex_state_t *exchange_state) { int ret = 0; int rc; int public_key_len = LIBSSH2_ED25519_KEY_LEN; if(data_len < 5) { return _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Data is too short"); } if(exchange_state->state == libssh2_NB_state_idle) { /* Setup initial values */ exchange_state->k = _libssh2_bn_init(); exchange_state->state = libssh2_NB_state_created; } if(exchange_state->state == libssh2_NB_state_created) { /* parse INIT reply data */ unsigned char *server_public_key, *server_host_key; size_t server_public_key_len, hostkey_len; struct string_buf buf; if(data_len < 5) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected curve25519 key length 1"); goto clean_exit; } buf.data = data; buf.len = data_len; buf.dataptr = buf.data; buf.dataptr++; /* advance past packet type */ if(_libssh2_get_string(&buf, &server_host_key, &hostkey_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected curve25519 key length 2"); goto clean_exit; } session->server_hostkey_len = (uint32_t)hostkey_len; session->server_hostkey = LIBSSH2_ALLOC(session, session->server_hostkey_len); if(!session->server_hostkey) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for a copy " "of the host curve25519 key"); goto clean_exit; } memcpy(session->server_hostkey, server_host_key, session->server_hostkey_len); #if LIBSSH2_MD5 { libssh2_md5_ctx fingerprint_ctx; if(libssh2_md5_init(&fingerprint_ctx)) { libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5); session->server_hostkey_md5_valid = TRUE; } else { session->server_hostkey_md5_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char fingerprint[50], *fprint = fingerprint; int i; for(i = 0; i < 16; i++, fprint += 3) { snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); } *(--fprint) = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's MD5 Fingerprint: %s", fingerprint)); } #endif /* LIBSSH2DEBUG */ #endif /* ! LIBSSH2_MD5 */ { libssh2_sha1_ctx fingerprint_ctx; if(libssh2_sha1_init(&fingerprint_ctx)) { libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1); session->server_hostkey_sha1_valid = TRUE; } else { session->server_hostkey_sha1_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char fingerprint[64], *fprint = fingerprint; int i; for(i = 0; i < 20; i++, fprint += 3) { snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); } *(--fprint) = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's SHA1 Fingerprint: %s", fingerprint)); } #endif /* LIBSSH2DEBUG */ /* SHA256 */ { libssh2_sha256_ctx fingerprint_ctx; if(libssh2_sha256_init(&fingerprint_ctx)) { libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); libssh2_sha256_final(fingerprint_ctx, session->server_hostkey_sha256); session->server_hostkey_sha256_valid = TRUE; } else { session->server_hostkey_sha256_valid = FALSE; } } #ifdef LIBSSH2DEBUG { char *base64Fingerprint = NULL; _libssh2_base64_encode(session, (const char *) session->server_hostkey_sha256, SHA256_DIGEST_LENGTH, &base64Fingerprint); if(base64Fingerprint) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server's SHA256 Fingerprint: %s", base64Fingerprint)); LIBSSH2_FREE(session, base64Fingerprint); } } #endif /* LIBSSH2DEBUG */ if(session->hostkey->init(session, session->server_hostkey, session->server_hostkey_len, &session->server_hostkey_abstract)) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to initialize hostkey importer " "curve25519"); goto clean_exit; } /* server public key Q_S */ if(_libssh2_get_string(&buf, &server_public_key, &server_public_key_len)) { ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected curve25519 key length"); goto clean_exit; } if(server_public_key_len != LIBSSH2_ED25519_KEY_LEN) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unexpected curve25519 server " "public key length"); goto clean_exit; } /* server signature */ if(_libssh2_get_string(&buf, &exchange_state->h_sig, &(exchange_state->h_sig_len))) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unexpected curve25519 server sig length"); goto clean_exit; } /* Compute the shared secret K */ rc = _libssh2_curve25519_gen_k(&exchange_state->k, private_key, server_public_key); if(rc) { ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to create curve25519 shared secret"); goto clean_exit; } exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; if(_libssh2_bn_bits(exchange_state->k) % 8) { /* don't need leading 00 */ exchange_state->k_value_len--; } exchange_state->k_value = LIBSSH2_ALLOC(session, exchange_state->k_value_len); if(!exchange_state->k_value) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for K"); goto clean_exit; } _libssh2_htonu32(exchange_state->k_value, (uint32_t)(exchange_state->k_value_len - 4)); if(_libssh2_bn_bits(exchange_state->k) % 8) { _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); } else { exchange_state->k_value[4] = 0; _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); } /*/ verify hash */ LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256); if(rc) { ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature " "curve25519"); goto clean_exit; } exchange_state->c = SSH_MSG_NEWKEYS; exchange_state->state = libssh2_NB_state_sent; } if(exchange_state->state == libssh2_NB_state_sent) { rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message curve25519"); goto clean_exit; } exchange_state->state = libssh2_NB_state_sent2; } if(exchange_state->state == libssh2_NB_state_sent2) { rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, &exchange_state->tmp, &exchange_state->tmp_len, 0, NULL, 0, &exchange_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS curve25519"); goto clean_exit; } /* The first key exchange has been performed, switch to active crypt/comp/mac mode */ session->state |= LIBSSH2_STATE_NEWKEYS; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message curve25519")); /* This will actually end up being just packet_type(1) for this packet type anyway */ LIBSSH2_FREE(session, exchange_state->tmp); if(!session->session_id) { size_t digest_length = SHA256_DIGEST_LENGTH; session->session_id = LIBSSH2_ALLOC(session, digest_length); if(!session->session_id) { ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for " "SHA digest"); goto clean_exit; } memcpy(session->session_id, exchange_state->h_sig_comp, digest_length); session->session_id_len = (uint32_t)digest_length; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "session_id calculated")); } /* Cleanup any existing cipher */ if(session->local.crypt->dtor) { session->local.crypt->dtor(session, &session->local.crypt_abstract); } /* Calculate IV/Secret/Key for each direction */ if(session->local.crypt->init) { unsigned char *iv = NULL, *secret = NULL; int free_iv = 0, free_secret = 0; LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv, session->local.crypt-> iv_len, "A"); if(!iv) { ret = -1; goto clean_exit; } LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret, session->local.crypt-> secret_len, "C"); if(!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(session->local.crypt-> init(session, session->local.crypt, iv, &free_iv, secret, &free_secret, 1, &session->local.crypt_abstract)) { LIBSSH2_FREE(session, iv); LIBSSH2_FREE(session, secret); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(free_iv) { _libssh2_explicit_zero(iv, session->local.crypt->iv_len); LIBSSH2_FREE(session, iv); } if(free_secret) { _libssh2_explicit_zero(secret, session->local.crypt->secret_len); LIBSSH2_FREE(session, secret); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server IV and Key calculated")); if(session->remote.crypt->dtor) { /* Cleanup any existing cipher */ session->remote.crypt->dtor(session, &session->remote.crypt_abstract); } if(session->remote.crypt->init) { unsigned char *iv = NULL, *secret = NULL; int free_iv = 0, free_secret = 0; LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv, session->remote.crypt-> iv_len, "B"); if(!iv) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret, session->remote.crypt-> secret_len, "D"); if(!secret) { LIBSSH2_FREE(session, iv); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(session->remote.crypt-> init(session, session->remote.crypt, iv, &free_iv, secret, &free_secret, 0, &session->remote.crypt_abstract)) { LIBSSH2_FREE(session, iv); LIBSSH2_FREE(session, secret); ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } if(free_iv) { _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); LIBSSH2_FREE(session, iv); } if(free_secret) { _libssh2_explicit_zero(secret, session->remote.crypt->secret_len); LIBSSH2_FREE(session, secret); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client IV and Key calculated")); if(session->local.mac->dtor) { session->local.mac->dtor(session, &session->local.mac_abstract); } if(session->local.mac->init) { unsigned char *key = NULL; int free_key = 0; LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key, session->local.mac-> key_len, "E"); if(!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } session->local.mac->init(session, key, &free_key, &session->local.mac_abstract); if(free_key) { _libssh2_explicit_zero(key, session->local.mac->key_len); LIBSSH2_FREE(session, key); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server HMAC Key calculated")); if(session->remote.mac->dtor) { session->remote.mac->dtor(session, &session->remote.mac_abstract); } if(session->remote.mac->init) { unsigned char *key = NULL; int free_key = 0; LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key, session->remote.mac-> key_len, "F"); if(!key) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } session->remote.mac->init(session, key, &free_key, &session->remote.mac_abstract); if(free_key) { _libssh2_explicit_zero(key, session->remote.mac->key_len); LIBSSH2_FREE(session, key); } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client HMAC Key calculated")); /* Initialize compression for each direction */ /* Cleanup any existing compression */ if(session->local.comp && session->local.comp->dtor) { session->local.comp->dtor(session, 1, &session->local.comp_abstract); } if(session->local.comp && session->local.comp->init) { if(session->local.comp->init(session, 1, &session->local.comp_abstract)) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Client to Server compression initialized")); if(session->remote.comp && session->remote.comp->dtor) { session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); } if(session->remote.comp && session->remote.comp->init) { if(session->remote.comp->init(session, 0, &session->remote.comp_abstract)) { ret = LIBSSH2_ERROR_KEX_FAILURE; goto clean_exit; } } _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Server to Client compression initialized")); } clean_exit: _libssh2_bn_free(exchange_state->k); exchange_state->k = NULL; if(exchange_state->k_value) { LIBSSH2_FREE(session, exchange_state->k_value); exchange_state->k_value = NULL; } exchange_state->state = libssh2_NB_state_idle; return ret; } /* kex_method_curve25519_key_exchange * * Elliptic Curve X25519 Key Exchange with SHA256 hash * */ static int kex_method_curve25519_key_exchange (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) { int ret = 0; int rc = 0; if(key_state->state == libssh2_NB_state_idle) { key_state->public_key_oct = NULL; key_state->state = libssh2_NB_state_created; } if(key_state->state == libssh2_NB_state_created) { unsigned char *s = NULL; rc = strcmp(session->kex->name, "curve25519-sha256@libssh.org"); if(rc) rc = strcmp(session->kex->name, "curve25519-sha256"); if(rc) { ret = _libssh2_error(session, -1, "Unknown KEX curve25519 curve type"); goto clean_exit; } rc = _libssh2_curve25519_new(session, &key_state->curve25519_public_key, &key_state->curve25519_private_key); if(rc) { ret = _libssh2_error(session, rc, "Unable to create private key"); goto clean_exit; } key_state->request[0] = SSH2_MSG_KEX_ECDH_INIT; s = key_state->request + 1; _libssh2_store_str(&s, (const char *)key_state->curve25519_public_key, LIBSSH2_ED25519_KEY_LEN); key_state->request_len = LIBSSH2_ED25519_KEY_LEN + 5; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Initiating curve25519 SHA2")); key_state->state = libssh2_NB_state_sent; } if(key_state->state == libssh2_NB_state_sent) { rc = _libssh2_transport_send(session, key_state->request, key_state->request_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Unable to send ECDH_INIT"); goto clean_exit; } key_state->state = libssh2_NB_state_sent1; } if(key_state->state == libssh2_NB_state_sent1) { rc = _libssh2_packet_require(session, SSH2_MSG_KEX_ECDH_REPLY, &key_state->data, &key_state->data_len, 0, NULL, 0, &key_state->req_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { ret = _libssh2_error(session, rc, "Timeout waiting for ECDH_REPLY reply"); goto clean_exit; } key_state->state = libssh2_NB_state_sent2; } if(key_state->state == libssh2_NB_state_sent2) { ret = curve25519_sha256(session, key_state->data, key_state->data_len, key_state->curve25519_public_key, key_state->curve25519_private_key, &key_state->exchange_state); if(ret == LIBSSH2_ERROR_EAGAIN) { return ret; } LIBSSH2_FREE(session, key_state->data); } clean_exit: if(key_state->curve25519_public_key) { _libssh2_explicit_zero(key_state->curve25519_public_key, LIBSSH2_ED25519_KEY_LEN); LIBSSH2_FREE(session, key_state->curve25519_public_key); key_state->curve25519_public_key = NULL; } if(key_state->curve25519_private_key) { _libssh2_explicit_zero(key_state->curve25519_private_key, LIBSSH2_ED25519_KEY_LEN); LIBSSH2_FREE(session, key_state->curve25519_private_key); key_state->curve25519_private_key = NULL; } key_state->state = libssh2_NB_state_idle; return ret; } #endif /* LIBSSH2_ED25519 */ #define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 #define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002 static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = { "diffie-hellman-group1-sha1", kex_method_diffie_hellman_group1_sha1_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = { "diffie-hellman-group14-sha1", kex_method_diffie_hellman_group14_sha1_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha256 = { "diffie-hellman-group14-sha256", kex_method_diffie_hellman_group14_sha256_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group16_sha512 = { "diffie-hellman-group16-sha512", kex_method_diffie_hellman_group16_sha512_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group18_sha512 = { "diffie-hellman-group18-sha512", kex_method_diffie_hellman_group18_sha512_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group_exchange_sha1 = { "diffie-hellman-group-exchange-sha1", kex_method_diffie_hellman_group_exchange_sha1_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group_exchange_sha256 = { "diffie-hellman-group-exchange-sha256", kex_method_diffie_hellman_group_exchange_sha256_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; #if LIBSSH2_ECDSA static const LIBSSH2_KEX_METHOD kex_method_ecdh_sha2_nistp256 = { "ecdh-sha2-nistp256", kex_method_ecdh_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_ecdh_sha2_nistp384 = { "ecdh-sha2-nistp384", kex_method_ecdh_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_ecdh_sha2_nistp521 = { "ecdh-sha2-nistp521", kex_method_ecdh_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; #endif #if LIBSSH2_ED25519 static const LIBSSH2_KEX_METHOD kex_method_ssh_curve25519_sha256_libssh = { "curve25519-sha256@libssh.org", kex_method_curve25519_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD kex_method_ssh_curve25519_sha256 = { "curve25519-sha256", kex_method_curve25519_key_exchange, LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; #endif /* this kex method signals that client can receive extensions * as described in https://datatracker.ietf.org/doc/html/rfc8308 */ static const LIBSSH2_KEX_METHOD kex_method_extension_negotiation = { "ext-info-c", NULL, 0, }; static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { #if LIBSSH2_ED25519 &kex_method_ssh_curve25519_sha256, &kex_method_ssh_curve25519_sha256_libssh, #endif #if LIBSSH2_ECDSA &kex_method_ecdh_sha2_nistp256, &kex_method_ecdh_sha2_nistp384, &kex_method_ecdh_sha2_nistp521, #endif &kex_method_diffie_helman_group_exchange_sha256, &kex_method_diffie_helman_group16_sha512, &kex_method_diffie_helman_group18_sha512, &kex_method_diffie_helman_group14_sha256, &kex_method_diffie_helman_group14_sha1, &kex_method_diffie_helman_group1_sha1, &kex_method_diffie_helman_group_exchange_sha1, &kex_method_extension_negotiation, NULL }; typedef struct _LIBSSH2_COMMON_METHOD { const char *name; } LIBSSH2_COMMON_METHOD; /* kex_method_strlen * * Calculate the length of a particular method list's resulting string * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 * (because the last coma isn't used) * Another sign of bad coding practices gone mad. Pretend you don't see this. */ static size_t kex_method_strlen(LIBSSH2_COMMON_METHOD ** method) { size_t len = 0; if(!method || !*method) { return 0; } while(*method && (*method)->name) { len += strlen((*method)->name) + 1; method++; } return len - 1; } /* kex_method_list * Generate formatted preference list in buf */ static uint32_t kex_method_list(unsigned char *buf, uint32_t list_strlen, LIBSSH2_COMMON_METHOD ** method) { _libssh2_htonu32(buf, list_strlen); buf += 4; if(!method || !*method) { return 4; } while(*method && (*method)->name) { uint32_t mlen = (uint32_t)strlen((*method)->name); memcpy(buf, (*method)->name, mlen); buf += mlen; *(buf++) = ','; method++; } return list_strlen + 4; } #define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \ (uint32_t)((prefvar) ? strlen(prefvar) : \ kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) #define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ do { \ if(prefvar) { \ _libssh2_htonu32((buf), (prefvarlen)); \ buf += 4; \ memcpy((buf), (prefvar), (prefvarlen)); \ buf += (prefvarlen); \ } \ else { \ buf += kex_method_list((buf), (prefvarlen), \ (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ } \ } while(0) /* kexinit * Send SSH_MSG_KEXINIT packet */ static int kexinit(LIBSSH2_SESSION * session) { /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) + reserved(4) + length longs(40) */ size_t data_len = 62; unsigned char *data, *s; int rc; if(session->kexinit_state == libssh2_NB_state_idle) { uint32_t kex_len, hostkey_len; uint32_t crypt_cs_len, crypt_sc_len; uint32_t comp_cs_len, comp_sc_len; uint32_t mac_cs_len, mac_sc_len; uint32_t lang_cs_len, lang_sc_len; kex_len = LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods); hostkey_len = LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs, libssh2_hostkey_methods()); crypt_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs, libssh2_crypt_methods()); crypt_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs, libssh2_crypt_methods()); mac_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs, _libssh2_mac_methods()); mac_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs, _libssh2_mac_methods()); comp_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs, _libssh2_comp_methods(session)); comp_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs, _libssh2_comp_methods(session)); lang_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL); lang_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL); data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len + comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len + lang_cs_len + lang_sc_len; s = data = LIBSSH2_ALLOC(session, data_len); if(!data) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory"); } *(s++) = SSH_MSG_KEXINIT; if(_libssh2_random(s, 16)) { return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN, "Unable to get random bytes " "for KEXINIT cookie"); } s += 16; /* Ennumerating through these lists twice is probably (certainly?) inefficient from a CPU standpoint, but it saves multiple malloc/realloc calls */ LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs, libssh2_kex_methods); LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs, libssh2_hostkey_methods()); LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs, libssh2_crypt_methods()); LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs, libssh2_crypt_methods()); LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs, _libssh2_mac_methods()); LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs, _libssh2_mac_methods()); LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs, _libssh2_comp_methods(session)); LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs, _libssh2_comp_methods(session)); LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs, NULL); LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs, NULL); /* No optimistic KEX packet follows */ /* Deal with optimistic packets * session->flags |= KEXINIT_OPTIMISTIC * session->flags |= KEXINIT_METHODSMATCH */ *(s++) = 0; /* Reserved == 0 */ _libssh2_htonu32(s, 0); #ifdef LIBSSH2DEBUG { /* Funnily enough, they'll all "appear" to be '\0' terminated */ unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */ _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p)); p += kex_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p)); p += hostkey_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p)); p += crypt_cs_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p)); p += crypt_sc_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p)); p += mac_cs_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p)); p += mac_sc_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p)); p += comp_cs_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p)); p += comp_sc_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p)); p += lang_cs_len + 4; _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p)); p += lang_sc_len + 4; } #endif /* LIBSSH2DEBUG */ session->kexinit_state = libssh2_NB_state_created; } else { data = session->kexinit_data; data_len = session->kexinit_data_len; /* zap the variables to ensure there is NOT a double free later */ session->kexinit_data = NULL; session->kexinit_data_len = 0; } rc = _libssh2_transport_send(session, data, data_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { session->kexinit_data = data; session->kexinit_data_len = data_len; return rc; } else if(rc) { LIBSSH2_FREE(session, data); session->kexinit_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send KEXINIT packet to remote host"); } if(session->local.kexinit) { LIBSSH2_FREE(session, session->local.kexinit); } session->local.kexinit = data; session->local.kexinit_len = data_len; session->kexinit_state = libssh2_NB_state_idle; return 0; } /* kex_agree_instr * Kex specific variant of strstr() * Needle must be preceded by BOL or ',', and followed by ',' or EOL */ static unsigned char * kex_agree_instr(unsigned char *haystack, size_t haystack_len, const unsigned char *needle, size_t needle_len) { unsigned char *s; unsigned char *end_haystack; size_t left; if(!haystack || !needle) { return NULL; } /* Haystack too short to bother trying */ if(haystack_len < needle_len || needle_len == 0) { return NULL; } s = haystack; end_haystack = &haystack[haystack_len]; left = end_haystack - s; /* Needle at start of haystack */ if((strncmp((char *) haystack, (char *) needle, needle_len) == 0) && (needle_len == haystack_len || haystack[needle_len] == ',')) { return haystack; } /* Search until we run out of comas or we run out of haystack, whichever comes first */ /* !checksrc! disable EQUALSNULL 1 */ while((s = (unsigned char *) memchr((char *) s, ',', left)) != NULL) { /* Advance buffer past coma if we can */ left = end_haystack - s; if((left >= 1) && (left <= haystack_len) && (left > needle_len)) { s++; } else { return NULL; } /* Needle at X position */ if((strncmp((char *) s, (char *) needle, needle_len) == 0) && (((s - haystack) + needle_len) == haystack_len || s[needle_len] == ',')) { return s; } } return NULL; } /* kex_get_method_by_name */ static const LIBSSH2_COMMON_METHOD * kex_get_method_by_name(const char *name, size_t name_len, const LIBSSH2_COMMON_METHOD ** methodlist) { while(*methodlist) { if((strlen((*methodlist)->name) == name_len) && (strncmp((*methodlist)->name, name, name_len) == 0)) { return *methodlist; } methodlist++; } return NULL; } /* kex_agree_hostkey * Agree on a Hostkey which works with this kex */ static int kex_agree_hostkey(LIBSSH2_SESSION * session, size_t kex_flags, unsigned char *hostkey, size_t hostkey_len) { const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); unsigned char *s; if(session->hostkey_prefs) { s = (unsigned char *) session->hostkey_prefs; while(s && *s) { unsigned char *p = (unsigned char *) strchr((char *) s, ','); size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) { const LIBSSH2_HOSTKEY_METHOD *method = (const LIBSSH2_HOSTKEY_METHOD *) kex_get_method_by_name((char *) s, method_len, (const LIBSSH2_COMMON_METHOD **) hostkeyp); if(!method) { /* Invalid method -- Should never be reached */ return -1; } /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */ if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || (method->encrypt)) { /* Either this hostkey can do encryption or this kex just doesn't require it */ if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == 0) || (method->sig_verify)) { /* Either this hostkey can do signing or this kex just doesn't require it */ session->hostkey = method; return 0; } } } s = p ? p + 1 : NULL; } return -1; } while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) { s = kex_agree_instr(hostkey, hostkey_len, (unsigned char *) (*hostkeyp)->name, strlen((*hostkeyp)->name)); if(s) { /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */ if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || ((*hostkeyp)->encrypt)) { /* Either this hostkey can do encryption or this kex just doesn't require it */ if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == 0) || ((*hostkeyp)->sig_verify)) { /* Either this hostkey can do signing or this kex just doesn't require it */ session->hostkey = *hostkeyp; return 0; } } } hostkeyp++; } return -1; } /* kex_agree_kex_hostkey * Agree on a Key Exchange method and a hostkey encoding type */ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, size_t kex_len, unsigned char *hostkey, size_t hostkey_len) { const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; unsigned char *s; if(session->kex_prefs) { s = (unsigned char *) session->kex_prefs; while(s && *s) { unsigned char *q, *p = (unsigned char *) strchr((char *) s, ','); size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); q = kex_agree_instr(kex, kex_len, s, method_len); if(q) { const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *) kex_get_method_by_name((char *) s, method_len, (const LIBSSH2_COMMON_METHOD **) kexp); if(!method) { /* Invalid method -- Should never be reached */ return -1; } /* We've agreed on a key exchange method, * Can we agree on a hostkey that works with this kex? */ if(kex_agree_hostkey(session, method->flags, hostkey, hostkey_len) == 0) { session->kex = method; if(session->burn_optimistic_kexinit && (kex == q)) { /* Server sent an optimistic packet, and client agrees * with preference cancel burning the first KEX_INIT * packet that comes in */ session->burn_optimistic_kexinit = 0; } return 0; } } s = p ? p + 1 : NULL; } return -1; } while(*kexp && (*kexp)->name) { s = kex_agree_instr(kex, kex_len, (unsigned char *) (*kexp)->name, strlen((*kexp)->name)); if(s) { /* We've agreed on a key exchange method, * Can we agree on a hostkey that works with this kex? */ if(kex_agree_hostkey(session, (*kexp)->flags, hostkey, hostkey_len) == 0) { session->kex = *kexp; if(session->burn_optimistic_kexinit && (kex == s)) { /* Server sent an optimistic packet, and client agrees * with preference cancel burning the first KEX_INIT * packet that comes in */ session->burn_optimistic_kexinit = 0; } return 0; } } kexp++; } return -1; } /* kex_agree_crypt * Agree on a cipher algo */ static int kex_agree_crypt(LIBSSH2_SESSION * session, libssh2_endpoint_data *endpoint, unsigned char *crypt, size_t crypt_len) { const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); unsigned char *s; (void)session; if(endpoint->crypt_prefs) { s = (unsigned char *) endpoint->crypt_prefs; while(s && *s) { unsigned char *p = (unsigned char *) strchr((char *) s, ','); size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); if(kex_agree_instr(crypt, crypt_len, s, method_len)) { const LIBSSH2_CRYPT_METHOD *method = (const LIBSSH2_CRYPT_METHOD *) kex_get_method_by_name((char *) s, method_len, (const LIBSSH2_COMMON_METHOD **) cryptp); if(!method) { /* Invalid method -- Should never be reached */ return -1; } endpoint->crypt = method; return 0; } s = p ? p + 1 : NULL; } return -1; } while(*cryptp && (*cryptp)->name) { s = kex_agree_instr(crypt, crypt_len, (unsigned char *) (*cryptp)->name, strlen((*cryptp)->name)); if(s) { endpoint->crypt = *cryptp; return 0; } cryptp++; } return -1; } /* kex_agree_mac * Agree on a message authentication hash */ static int kex_agree_mac(LIBSSH2_SESSION * session, libssh2_endpoint_data * endpoint, unsigned char *mac, size_t mac_len) { const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods(); const LIBSSH2_MAC_METHOD *override; unsigned char *s; (void)session; override = _libssh2_mac_override(endpoint->crypt); if(override) { /* This crypto method has its own hmac method built-in, so a separate * negotiation (and use) of a separate hmac method is unnecessary */ endpoint->mac = override; return 0; } if(endpoint->mac_prefs) { s = (unsigned char *) endpoint->mac_prefs; while(s && *s) { unsigned char *p = (unsigned char *) strchr((char *) s, ','); size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); if(kex_agree_instr(mac, mac_len, s, method_len)) { const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *) kex_get_method_by_name((char *) s, method_len, (const LIBSSH2_COMMON_METHOD **) macp); if(!method) { /* Invalid method -- Should never be reached */ return -1; } endpoint->mac = method; return 0; } s = p ? p + 1 : NULL; } return -1; } while(*macp && (*macp)->name) { s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name, strlen((*macp)->name)); if(s) { endpoint->mac = *macp; return 0; } macp++; } return -1; } /* kex_agree_comp * Agree on a compression scheme */ static int kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *comp, size_t comp_len) { const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods(session); unsigned char *s; (void)session; if(endpoint->comp_prefs) { s = (unsigned char *) endpoint->comp_prefs; while(s && *s) { unsigned char *p = (unsigned char *) strchr((char *) s, ','); size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); if(kex_agree_instr(comp, comp_len, s, method_len)) { const LIBSSH2_COMP_METHOD *method = (const LIBSSH2_COMP_METHOD *) kex_get_method_by_name((char *) s, method_len, (const LIBSSH2_COMMON_METHOD **) compp); if(!method) { /* Invalid method -- Should never be reached */ return -1; } endpoint->comp = method; return 0; } s = p ? p + 1 : NULL; } return -1; } while(*compp && (*compp)->name) { s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name, strlen((*compp)->name)); if(s) { endpoint->comp = *compp; return 0; } compp++; } return -1; } /* TODO: When in server mode we need to turn this logic on its head * The Client gets to make the final call on "agreed methods" */ /* kex_agree_methods * Decide which specific method to use of the methods offered by each party */ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data, size_t data_len) { unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc, *mac_cs, *mac_sc; size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len; size_t comp_sc_len, mac_cs_len, mac_sc_len; struct string_buf buf; if(data_len < 17) return -1; buf.data = (unsigned char *)data; buf.len = data_len; buf.dataptr = buf.data; buf.dataptr++; /* advance past packet type */ /* Skip cookie, don't worry, it's preserved in the kexinit field */ buf.dataptr += 16; /* Locate each string */ if(_libssh2_get_string(&buf, &kex, &kex_len)) return -1; if(_libssh2_get_string(&buf, &hostkey, &hostkey_len)) return -1; if(_libssh2_get_string(&buf, &crypt_cs, &crypt_cs_len)) return -1; if(_libssh2_get_string(&buf, &crypt_sc, &crypt_sc_len)) return -1; if(_libssh2_get_string(&buf, &mac_cs, &mac_cs_len)) return -1; if(_libssh2_get_string(&buf, &mac_sc, &mac_sc_len)) return -1; if(_libssh2_get_string(&buf, &comp_cs, &comp_cs_len)) return -1; if(_libssh2_get_string(&buf, &comp_sc, &comp_sc_len)) return -1; /* If the server sent an optimistic packet, assume that it guessed wrong. * If the guess is determined to be right (by kex_agree_kex_hostkey) * This flag will be reset to zero so that it's not ignored */ if(_libssh2_check_length(&buf, 1)) { session->burn_optimistic_kexinit = *(buf.dataptr++); } else { return -1; } /* Next uint32 in packet is all zeros (reserved) */ if(kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) { return -1; } if(kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len) || kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) { return -1; } /* This must happen after kex_agree_crypt since some MACs depend on the negotiated crypto method */ if(kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) || kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) { return -1; } if(kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) || kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) { return -1; } #if 0 if(libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len) || libssh2_kex_agree_lang(session, &session->remote, lang_sc, lang_sc_len)) { return -1; } #endif _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s", session->kex->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s", session->hostkey->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s", session->local.crypt->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s", session->remote.crypt->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s", session->local.mac->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s", session->remote.mac->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s", session->local.comp->name)); _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s", session->remote.comp->name)); return 0; } /* _libssh2_kex_exchange * Exchange keys * Returns 0 on success, non-zero on failure * * Returns some errors without _libssh2_error() */ int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, key_exchange_state_t * key_state) { int rc = 0; int retcode; session->state |= LIBSSH2_STATE_KEX_ACTIVE; if(key_state->state == libssh2_NB_state_idle) { /* Prevent loop in packet_add() */ session->state |= LIBSSH2_STATE_EXCHANGING_KEYS; if(reexchange) { session->kex = NULL; if(session->hostkey && session->hostkey->dtor) { session->hostkey->dtor(session, &session->server_hostkey_abstract); } session->hostkey = NULL; } key_state->state = libssh2_NB_state_created; } if(!session->kex || !session->hostkey) { if(key_state->state == libssh2_NB_state_created) { /* Preserve in case of failure */ key_state->oldlocal = session->local.kexinit; key_state->oldlocal_len = session->local.kexinit_len; session->local.kexinit = NULL; key_state->state = libssh2_NB_state_sent; } if(key_state->state == libssh2_NB_state_sent) { retcode = kexinit(session); if(retcode == LIBSSH2_ERROR_EAGAIN) { session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; return retcode; } else if(retcode) { session->local.kexinit = key_state->oldlocal; session->local.kexinit_len = key_state->oldlocal_len; key_state->state = libssh2_NB_state_idle; session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; return -1; } key_state->state = libssh2_NB_state_sent1; } if(key_state->state == libssh2_NB_state_sent1) { retcode = _libssh2_packet_require(session, SSH_MSG_KEXINIT, &key_state->data, &key_state->data_len, 0, NULL, 0, &key_state->req_state); if(retcode == LIBSSH2_ERROR_EAGAIN) { session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; return retcode; } else if(retcode) { if(session->local.kexinit) { LIBSSH2_FREE(session, session->local.kexinit); } session->local.kexinit = key_state->oldlocal; session->local.kexinit_len = key_state->oldlocal_len; key_state->state = libssh2_NB_state_idle; session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; return -1; } if(session->remote.kexinit) { LIBSSH2_FREE(session, session->remote.kexinit); } session->remote.kexinit = key_state->data; session->remote.kexinit_len = key_state->data_len; if(kex_agree_methods(session, key_state->data, key_state->data_len)) rc = LIBSSH2_ERROR_KEX_FAILURE; key_state->state = libssh2_NB_state_sent2; } } else { key_state->state = libssh2_NB_state_sent2; } if(rc == 0 && session->kex) { if(key_state->state == libssh2_NB_state_sent2) { retcode = session->kex->exchange_keys(session, &key_state->key_state_low); if(retcode == LIBSSH2_ERROR_EAGAIN) { session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; return retcode; } else if(retcode) { rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, "Unrecoverable error exchanging keys"); } } } /* Done with kexinit buffers */ if(session->local.kexinit) { LIBSSH2_FREE(session, session->local.kexinit); session->local.kexinit = NULL; } if(session->remote.kexinit) { LIBSSH2_FREE(session, session->remote.kexinit); session->remote.kexinit = NULL; } session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; key_state->state = libssh2_NB_state_idle; return rc; } /* libssh2_session_method_pref * Set preferred method */ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type, const char *prefs) { char **prefvar, *s, *newprefs; size_t prefs_len = strlen(prefs); const LIBSSH2_COMMON_METHOD **mlist; switch(method_type) { case LIBSSH2_METHOD_KEX: prefvar = &session->kex_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_kex_methods; break; case LIBSSH2_METHOD_HOSTKEY: prefvar = &session->hostkey_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_hostkey_methods(); break; case LIBSSH2_METHOD_CRYPT_CS: prefvar = &session->local.crypt_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_crypt_methods(); break; case LIBSSH2_METHOD_CRYPT_SC: prefvar = &session->remote.crypt_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_crypt_methods(); break; case LIBSSH2_METHOD_MAC_CS: prefvar = &session->local.mac_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)_libssh2_mac_methods(); break; case LIBSSH2_METHOD_MAC_SC: prefvar = &session->remote.mac_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)_libssh2_mac_methods(); break; case LIBSSH2_METHOD_COMP_CS: prefvar = &session->local.comp_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)_libssh2_comp_methods(session); break; case LIBSSH2_METHOD_COMP_SC: prefvar = &session->remote.comp_prefs; mlist = (const LIBSSH2_COMMON_METHOD **)_libssh2_comp_methods(session); break; case LIBSSH2_METHOD_LANG_CS: prefvar = &session->local.lang_prefs; mlist = NULL; break; case LIBSSH2_METHOD_LANG_SC: prefvar = &session->remote.lang_prefs; mlist = NULL; break; case LIBSSH2_METHOD_SIGN_ALGO: prefvar = &session->sign_algo_prefs; mlist = NULL; break; default: return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type"); } s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1); if(!newprefs) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocated space for method preferences"); } memcpy(s, prefs, prefs_len + 1); while(s && *s && mlist) { char *p = strchr(s, ','); size_t method_len = (p ? (size_t)(p - s) : strlen(s)); if(!kex_get_method_by_name(s, method_len, mlist)) { /* Strip out unsupported method */ if(p) { memmove(s, p + 1, strlen(s) - method_len); } else { if(s > newprefs) { *(--s) = '\0'; } else { *s = '\0'; } } } else { s = p ? (p + 1) : NULL; } } if(!*newprefs) { LIBSSH2_FREE(session, newprefs); return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "The requested method(s) are not currently " "supported"); } if(*prefvar) { LIBSSH2_FREE(session, *prefvar); } *prefvar = newprefs; return 0; } /* * libssh2_session_supported_algs * returns a number of returned algorithms (a positive number) on success, * a negative number on failure */ LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, int method_type, const char ***algs) { unsigned int i; unsigned int j; unsigned int ialg; const LIBSSH2_COMMON_METHOD **mlist; /* to prevent coredumps due to dereferencing of NULL */ if(!algs) return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, "algs must not be NULL"); switch(method_type) { case LIBSSH2_METHOD_KEX: mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_kex_methods; break; case LIBSSH2_METHOD_HOSTKEY: mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_hostkey_methods(); break; case LIBSSH2_METHOD_CRYPT_CS: case LIBSSH2_METHOD_CRYPT_SC: mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_crypt_methods(); break; case LIBSSH2_METHOD_MAC_CS: case LIBSSH2_METHOD_MAC_SC: mlist = (const LIBSSH2_COMMON_METHOD **)_libssh2_mac_methods(); break; case LIBSSH2_METHOD_COMP_CS: case LIBSSH2_METHOD_COMP_SC: mlist = (const LIBSSH2_COMMON_METHOD **)_libssh2_comp_methods(session); break; case LIBSSH2_METHOD_SIGN_ALGO: /* no built-in supported list due to backend support */ mlist = NULL; break; default: return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unknown method type"); } /* switch */ /* weird situation */ if(!mlist) return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "No algorithm found"); /* mlist is looped through twice. The first time to find the number od supported algorithms (needed to allocate the proper size of array) and the second time to actually copy the pointers. Typically this function will not be called often (typically at the beginning of a session) and the number of algorithms (i.e. number of iterations in one loop) will not be high (typically it will not exceed 20) for quite a long time. So double looping really shouldn't be an issue and it is definitely a better solution than reallocation several times. */ /* count the number of supported algorithms */ for(i = 0, ialg = 0; mlist[i]; i++) { /* do not count fields with NULL name */ if(mlist[i]->name) ialg++; } /* weird situation, no algorithm found */ if(ialg == 0) return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "No algorithm found"); /* allocate buffer */ *algs = (const char **) LIBSSH2_ALLOC(session, ialg*sizeof(const char *)); if(!*algs) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Memory allocation failed"); } /* Past this point *algs must be deallocated in case of an error!! */ /* copy non-NULL pointers only */ for(i = 0, j = 0; mlist[i] && j < ialg; i++) { if(!mlist[i]->name) { /* maybe a weird situation but if it occurs, do not include NULL pointers */ continue; } /* note that [] has higher priority than * (dereferencing) */ (*algs)[j++] = mlist[i]->name; } /* correct number of pointers copied? (test the code above) */ if(j != ialg) { /* deallocate buffer */ LIBSSH2_FREE(session, (void *)*algs); *algs = NULL; return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, "Internal error"); } return ialg; } libssh2-1.11.0/src/session.h0000644000175000017500000000707514424650606012524 00000000000000#ifndef __LIBSSH2_SESSION_H #define __LIBSSH2_SESSION_H /* Copyright (c) 2004-2007 Sara Golemon * Copyright (c) 2009-2010 by Daniel Stenberg * Copyright (c) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* Conveniance-macros to allow code like this; int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock)); int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock)); The point being to make sure that while in non-blocking mode these always return no matter what the return code is, but in blocking mode it blocks if EAGAIN is the reason for the return from the underlying function. */ #define BLOCK_ADJUST(rc, sess, x) \ do { \ time_t entry_time = time(NULL); \ do { \ rc = x; \ /* the order of the check below is important to properly \ deal with the case when the 'sess' is freed */ \ if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \ break; \ rc = _libssh2_wait_socket(sess, entry_time); \ } while(!rc); \ } while(0) /* * For functions that returns a pointer, we need to check if the API is * non-blocking and return immediately. If the pointer is non-NULL we return * immediately. If the API is blocking and we get a NULL we check the errno * and *only* if that is EAGAIN we loop and wait for socket action. */ #define BLOCK_ADJUST_ERRNO(ptr, sess, x) \ do { \ time_t entry_time = time(NULL); \ int rc; \ do { \ ptr = x; \ if(!sess->api_block_mode || \ (ptr != NULL) || \ (libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN)) \ break; \ rc = _libssh2_wait_socket(sess, entry_time); \ } while(!rc); \ } while(0) int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time); /* this is the lib-internal set blocking function */ int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking); #endif /* __LIBSSH2_SESSION_H */ libssh2-1.11.0/src/mac.c0000644000175000017500000003151414424650606011567 00000000000000/* Copyright (c) 2004-2007, Sara Golemon * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "mac.h" #if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE) /* mac_none_MAC * * Minimalist MAC: No MAC. DO NOT USE. * * The SSH2 Transport allows implementations to forego a message * authentication code. While this is less of a security risk than using * a "none" cipher, it is still not recommended as disabling MAC hashes * removes a layer of security. * * Enabling this option will allow for "none" as a negotiable method, * however it still requires that the method be advertised by the remote * end and that no more-preferable methods are available. * */ static int mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { return 0; } static LIBSSH2_MAC_METHOD mac_method_none = { "none", 0, 0, NULL, mac_none_MAC, NULL, 0 }; #endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE) */ /* mac_method_common_init * Initialize simple mac methods */ static int mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key, int *free_key, void **abstract) { *abstract = key; *free_key = 0; (void)session; return 0; } /* mac_method_common_dtor * Cleanup simple mac methods */ static int mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) { if(*abstract) { LIBSSH2_FREE(session, *abstract); } *abstract = NULL; return 0; } #if LIBSSH2_HMAC_SHA512 /* mac_method_hmac_sha512_hash * Calculate hash using full sha512 value */ static int mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; (void)session; _libssh2_htonu32(seqno_buf, seqno); libssh2_hmac_ctx_init(ctx); libssh2_hmac_sha512_init(&ctx, *abstract, 64); libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, packet, packet_len); if(addtl && addtl_len) { libssh2_hmac_update(ctx, addtl, addtl_len); } libssh2_hmac_final(ctx, buf); libssh2_hmac_cleanup(&ctx); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { "hmac-sha2-512", 64, 64, mac_method_common_init, mac_method_hmac_sha2_512_hash, mac_method_common_dtor, 0 }; static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512_etm = { "hmac-sha2-512-etm@openssh.com", 64, 64, mac_method_common_init, mac_method_hmac_sha2_512_hash, mac_method_common_dtor, 1 }; #endif #if LIBSSH2_HMAC_SHA256 /* mac_method_hmac_sha256_hash * Calculate hash using full sha256 value */ static int mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; (void)session; _libssh2_htonu32(seqno_buf, seqno); libssh2_hmac_ctx_init(ctx); libssh2_hmac_sha256_init(&ctx, *abstract, 32); libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, packet, packet_len); if(addtl && addtl_len) { libssh2_hmac_update(ctx, addtl, addtl_len); } libssh2_hmac_final(ctx, buf); libssh2_hmac_cleanup(&ctx); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = { "hmac-sha2-256", 32, 32, mac_method_common_init, mac_method_hmac_sha2_256_hash, mac_method_common_dtor, 0 }; static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256_etm = { "hmac-sha2-256-etm@openssh.com", 32, 32, mac_method_common_init, mac_method_hmac_sha2_256_hash, mac_method_common_dtor, 1 }; #endif /* mac_method_hmac_sha1_hash * Calculate hash using full sha1 value */ static int mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; (void)session; _libssh2_htonu32(seqno_buf, seqno); libssh2_hmac_ctx_init(ctx); libssh2_hmac_sha1_init(&ctx, *abstract, 20); libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, packet, packet_len); if(addtl && addtl_len) { libssh2_hmac_update(ctx, addtl, addtl_len); } libssh2_hmac_final(ctx, buf); libssh2_hmac_cleanup(&ctx); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = { "hmac-sha1", 20, 20, mac_method_common_init, mac_method_hmac_sha1_hash, mac_method_common_dtor, 0 }; static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_etm = { "hmac-sha1-etm@openssh.com", 20, 20, mac_method_common_init, mac_method_hmac_sha1_hash, mac_method_common_dtor, 1 }; /* mac_method_hmac_sha1_96_hash * Calculate hash using first 96 bits of sha1 value */ static int mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { unsigned char temp[SHA_DIGEST_LENGTH]; mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); memcpy(buf, (char *) temp, 96 / 8); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = { "hmac-sha1-96", 12, 20, mac_method_common_init, mac_method_hmac_sha1_96_hash, mac_method_common_dtor, 0 }; #if LIBSSH2_MD5 /* mac_method_hmac_md5_hash * Calculate hash using full md5 value */ static int mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; (void)session; _libssh2_htonu32(seqno_buf, seqno); libssh2_hmac_ctx_init(ctx); libssh2_hmac_md5_init(&ctx, *abstract, 16); libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, packet, packet_len); if(addtl && addtl_len) { libssh2_hmac_update(ctx, addtl, addtl_len); } libssh2_hmac_final(ctx, buf); libssh2_hmac_cleanup(&ctx); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = { "hmac-md5", 16, 16, mac_method_common_init, mac_method_hmac_md5_hash, mac_method_common_dtor, 0 }; /* mac_method_hmac_md5_96_hash * Calculate hash using first 96 bits of md5 value */ static int mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { unsigned char temp[MD5_DIGEST_LENGTH]; mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); memcpy(buf, (char *) temp, 96 / 8); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = { "hmac-md5-96", 12, 16, mac_method_common_init, mac_method_hmac_md5_96_hash, mac_method_common_dtor, 0 }; #endif /* LIBSSH2_MD5 */ #if LIBSSH2_HMAC_RIPEMD /* mac_method_hmac_ripemd160_hash * Calculate hash using ripemd160 value */ static int mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; (void)session; _libssh2_htonu32(seqno_buf, seqno); libssh2_hmac_ctx_init(ctx); libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, packet, packet_len); if(addtl && addtl_len) { libssh2_hmac_update(ctx, addtl, addtl_len); } libssh2_hmac_final(ctx, buf); libssh2_hmac_cleanup(&ctx); return 0; } static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = { "hmac-ripemd160", 20, 20, mac_method_common_init, mac_method_hmac_ripemd160_hash, mac_method_common_dtor, 0 }; static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = { "hmac-ripemd160@openssh.com", 20, 20, mac_method_common_init, mac_method_hmac_ripemd160_hash, mac_method_common_dtor, 0 }; #endif /* LIBSSH2_HMAC_RIPEMD */ static const LIBSSH2_MAC_METHOD *mac_methods[] = { #if LIBSSH2_HMAC_SHA256 &mac_method_hmac_sha2_256, &mac_method_hmac_sha2_256_etm, #endif #if LIBSSH2_HMAC_SHA512 &mac_method_hmac_sha2_512, &mac_method_hmac_sha2_512_etm, #endif &mac_method_hmac_sha1, &mac_method_hmac_sha1_etm, &mac_method_hmac_sha1_96, #if LIBSSH2_MD5 &mac_method_hmac_md5, &mac_method_hmac_md5_96, #endif #if LIBSSH2_HMAC_RIPEMD &mac_method_hmac_ripemd160, &mac_method_hmac_ripemd160_openssh_com, #endif /* LIBSSH2_HMAC_RIPEMD */ #if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE) &mac_method_none, #endif NULL }; const LIBSSH2_MAC_METHOD ** _libssh2_mac_methods(void) { return mac_methods; } #if LIBSSH2_AES_GCM /* Stub for aes256-gcm@openssh.com crypto type, which has an integrated HMAC method. This must not be added to mac_methods[] since it cannot be negotiated separately. */ static const LIBSSH2_MAC_METHOD mac_method_hmac_aesgcm = { "INTEGRATED-AES-GCM", /* made up name for display only */ 16, 16, NULL, NULL, NULL, 0 }; #endif /* LIBSSH2_AES_GCM */ /* See if the negotiated crypto method has its own authentication scheme that * obviates the need for a separate negotiated hmac method */ const LIBSSH2_MAC_METHOD * _libssh2_mac_override(const LIBSSH2_CRYPT_METHOD *crypt) { #if LIBSSH2_AES_GCM if(!strcmp(crypt->name, "aes256-gcm@openssh.com") || !strcmp(crypt->name, "aes128-gcm@openssh.com")) return &mac_method_hmac_aesgcm; #else (void) crypt; #endif /* LIBSSH2_AES_GCM */ return NULL; } libssh2-1.11.0/src/libssh2.rc0000644000175000017500000000266614424650606012565 00000000000000/*************************************************************************** * libssh2 Windows resource file * ***************************************************************************/ #include #include "libssh2.h" LANGUAGE 0, 0 #define RC_VERSION LIBSSH2_VERSION_MAJOR, LIBSSH2_VERSION_MINOR, LIBSSH2_VERSION_PATCH, 0 VS_VERSION_INFO VERSIONINFO FILEVERSION RC_VERSION PRODUCTVERSION RC_VERSION FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #if defined(LIBSSH2DEBUG) || defined(_DEBUG) FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0 #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE 0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */ BEGIN VALUE "CompanyName", "The libssh2 library, https://www.libssh2.org/\0" VALUE "FileDescription", "libssh2 Shared Library\0" VALUE "FileVersion", LIBSSH2_VERSION "\0" VALUE "InternalName", "libssh2\0" VALUE "OriginalFilename", "libssh2.dll\0" VALUE "ProductName", "The libssh2 library\0" VALUE "ProductVersion", LIBSSH2_VERSION "\0" VALUE "LegalCopyright", "Copyright (C) " LIBSSH2_COPYRIGHT "\0" VALUE "License", "https://www.libssh2.org/license.html\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 0x04b0 /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */ END END libssh2-1.11.0/src/transport.h0000644000175000017500000000655314424650606013075 00000000000000#ifndef __LIBSSH2_TRANSPORT_H #define __LIBSSH2_TRANSPORT_H /* Copyright (C) 2007 The Written Word, Inc. All rights reserved. * Copyright (C) 2009-2010 by Daniel Stenberg * Author: Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file handles reading and writing to the SECSH transport layer. RFC4253. */ #include "libssh2_priv.h" #include "packet.h" /* * libssh2_transport_send * * Send a packet, encrypting it and adding a MAC code if necessary * Returns 0 on success, non-zero on failure. * * The data is provided as _two_ data areas that are combined by this * function. The 'data' part is sent immediately before 'data2'. 'data2' can * be set to NULL (or data2_len to 0) to only use a single part. * * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was * not sent yet. If it does so, the caller should call this function again as * soon as it is likely that more data can be sent, and this function MUST * then be called with the same argument set (same data pointer and same * data_len) until ERROR_NONE or failure is returned. * * This function DOES NOT call _libssh2_error() on any errors. */ int _libssh2_transport_send(LIBSSH2_SESSION *session, const unsigned char *data, size_t data_len, const unsigned char *data2, size_t data2_len); /* * _libssh2_transport_read * * Collect a packet into the input brigade block only controls whether or not * to wait for a packet to start. * * Returns packet type added to input brigade (PACKET_NONE if nothing added), * or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full * packet. */ /* * This function reads the binary stream as specified in chapter 6 of RFC4253 * "The Secure Shell (SSH) Transport Layer Protocol" */ int _libssh2_transport_read(LIBSSH2_SESSION * session); #endif /* __LIBSSH2_TRANSPORT_H */ libssh2-1.11.0/src/openssl.h0000644000175000017500000003630214434610011012502 00000000000000#ifndef __LIBSSH2_OPENSSL_H #define __LIBSSH2_OPENSSL_H /* Copyright (C) 2009, 2010 Simon Josefsson * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. * * Author: Simon Josefsson * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #define LIBSSH2_CRYPTO_ENGINE libssh2_openssl /* disable deprecated warnings in OpenSSL 3 */ #define OPENSSL_SUPPRESS_DEPRECATED #ifdef LIBSSH2_WOLFSSL #include #include #if defined(NO_DSA) || defined(HAVE_FIPS) #define OPENSSL_NO_DSA #endif #if defined(NO_MD5) || defined(HAVE_FIPS) #define OPENSSL_NO_MD5 #endif #if !defined(WOLFSSL_RIPEMD) || defined(HAVE_FIPS) #define OPENSSL_NO_RIPEMD #endif #if defined(NO_RC4) || defined(HAVE_FIPS) #define OPENSSL_NO_RC4 #endif #ifdef NO_DES3 #define OPENSSL_NO_DES #endif /* wolfSSL doesn't support Blowfish or CAST. */ #define OPENSSL_NO_BF #define OPENSSL_NO_CAST /* wolfSSL has no engine framework. */ #define OPENSSL_NO_ENGINE #endif /* LIBSSH2_WOLFSSL */ #include #include #include #ifndef OPENSSL_NO_ENGINE #include #endif #ifndef OPENSSL_NO_DSA #include #endif #ifndef OPENSSL_NO_MD5 #include #endif #include #include #include #include #include #include #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \ !defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) || \ LIBRESSL_VERSION_NUMBER >= 0x3050000fL /* For wolfSSL, whether the structs are truly opaque or not, it's best to not * rely on their internal data members being exposed publicly. */ # define HAVE_OPAQUE_STRUCTS 1 #endif #ifdef OPENSSL_NO_RSA # define LIBSSH2_RSA 0 # define LIBSSH2_RSA_SHA1 0 # define LIBSSH2_RSA_SHA2 0 #else # define LIBSSH2_RSA 1 # define LIBSSH2_RSA_SHA1 1 # define LIBSSH2_RSA_SHA2 1 #endif #ifdef OPENSSL_NO_DSA # define LIBSSH2_DSA 0 #else # define LIBSSH2_DSA 1 #endif #if defined(OPENSSL_NO_ECDSA) || defined(OPENSSL_NO_EC) # define LIBSSH2_ECDSA 0 #else # define LIBSSH2_ECDSA 1 #endif #if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \ !defined(LIBRESSL_VERSION_NUMBER)) || \ (defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER >= 0x3070000fL) # define LIBSSH2_ED25519 1 #else # define LIBSSH2_ED25519 0 #endif #ifdef OPENSSL_NO_MD5 # define LIBSSH2_MD5 0 #else # define LIBSSH2_MD5 1 #endif #if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160) # define LIBSSH2_HMAC_RIPEMD 0 #else # define LIBSSH2_HMAC_RIPEMD 1 #endif #define LIBSSH2_HMAC_SHA256 1 #define LIBSSH2_HMAC_SHA512 1 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)) || \ (defined(LIBSSH2_WOLFSSL) && defined(WOLFSSL_AES_COUNTER)) # define LIBSSH2_AES_CTR 1 # define LIBSSH2_AES_CBC 1 #else # define LIBSSH2_AES_CTR 0 # define LIBSSH2_AES_CBC 0 #endif #if (OPENSSL_VERSION_NUMBER >= 0x01010100fL && !defined(OPENSSL_NO_AES)) || \ (defined(LIBSSH2_WOLFSSL) && \ defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM)) # define LIBSSH2_AES_GCM 1 #else # define LIBSSH2_AES_GCM 0 #endif #ifdef OPENSSL_NO_BF # define LIBSSH2_BLOWFISH 0 #else # define LIBSSH2_BLOWFISH 1 #endif #ifdef OPENSSL_NO_RC4 # define LIBSSH2_RC4 0 #else # define LIBSSH2_RC4 1 #endif #ifdef OPENSSL_NO_CAST # define LIBSSH2_CAST 0 #else # define LIBSSH2_CAST 1 #endif #ifdef OPENSSL_NO_DES # define LIBSSH2_3DES 0 #else # define LIBSSH2_3DES 1 #endif #define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) #define _libssh2_random(buf, len) \ _libssh2_openssl_random((buf), (len)) #define libssh2_prepare_iovec(vec, len) /* Empty. */ #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha1_ctx EVP_MD_CTX * #else #define libssh2_sha1_ctx EVP_MD_CTX #endif /* returns 0 in case of failure */ int _libssh2_sha1_init(libssh2_sha1_ctx *ctx); #define libssh2_sha1_init(x) _libssh2_sha1_init(x) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) #define libssh2_sha1_final(ctx, out) do { \ EVP_DigestFinal(ctx, out, NULL); \ EVP_MD_CTX_free(ctx); \ } while(0) #else #define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) #define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) #endif int _libssh2_sha1(const unsigned char *message, size_t len, unsigned char *out); #define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha256_ctx EVP_MD_CTX * #else #define libssh2_sha256_ctx EVP_MD_CTX #endif /* returns 0 in case of failure */ int _libssh2_sha256_init(libssh2_sha256_ctx *ctx); #define libssh2_sha256_init(x) _libssh2_sha256_init(x) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) #define libssh2_sha256_final(ctx, out) do { \ EVP_DigestFinal(ctx, out, NULL); \ EVP_MD_CTX_free(ctx); \ } while(0) #else #define libssh2_sha256_update(ctx, data, len) \ EVP_DigestUpdate(&(ctx), data, len) #define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) #endif int _libssh2_sha256(const unsigned char *message, size_t len, unsigned char *out); #define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha384_ctx EVP_MD_CTX * #else #define libssh2_sha384_ctx EVP_MD_CTX #endif /* returns 0 in case of failure */ int _libssh2_sha384_init(libssh2_sha384_ctx *ctx); #define libssh2_sha384_init(x) _libssh2_sha384_init(x) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) #define libssh2_sha384_final(ctx, out) do { \ EVP_DigestFinal(ctx, out, NULL); \ EVP_MD_CTX_free(ctx); \ } while(0) #else #define libssh2_sha384_update(ctx, data, len) \ EVP_DigestUpdate(&(ctx), data, len) #define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) #endif int _libssh2_sha384(const unsigned char *message, size_t len, unsigned char *out); #define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha512_ctx EVP_MD_CTX * #else #define libssh2_sha512_ctx EVP_MD_CTX #endif /* returns 0 in case of failure */ int _libssh2_sha512_init(libssh2_sha512_ctx *ctx); #define libssh2_sha512_init(x) _libssh2_sha512_init(x) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) #define libssh2_sha512_final(ctx, out) do { \ EVP_DigestFinal(ctx, out, NULL); \ EVP_MD_CTX_free(ctx); \ } while(0) #else #define libssh2_sha512_update(ctx, data, len) \ EVP_DigestUpdate(&(ctx), data, len) #define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) #endif int _libssh2_sha512(const unsigned char *message, size_t len, unsigned char *out); #define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_md5_ctx EVP_MD_CTX * #else #define libssh2_md5_ctx EVP_MD_CTX #endif /* returns 0 in case of failure */ int _libssh2_md5_init(libssh2_md5_ctx *ctx); #define libssh2_md5_init(x) _libssh2_md5_init(x) #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) #define libssh2_md5_final(ctx, out) do { \ EVP_DigestFinal(ctx, out, NULL); \ EVP_MD_CTX_free(ctx); \ } while(0) #else #define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) #define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) #endif #ifdef HAVE_OPAQUE_STRUCTS #define libssh2_hmac_ctx HMAC_CTX * #define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new() #define libssh2_hmac_sha1_init(ctx, key, keylen) \ HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha1(), NULL) #define libssh2_hmac_md5_init(ctx, key, keylen) \ HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_md5(), NULL) #define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_ripemd160(), NULL) #define libssh2_hmac_sha256_init(ctx, key, keylen) \ HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha256(), NULL) #define libssh2_hmac_sha512_init(ctx, key, keylen) \ HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha512(), NULL) #ifdef LIBSSH2_WOLFSSL /* FIXME: upstream bug as of v5.6.0: datalen is int instead of size_t */ #define libssh2_hmac_update(ctx, data, datalen) \ HMAC_Update(ctx, data, (int)datalen) #else #define libssh2_hmac_update(ctx, data, datalen) \ HMAC_Update(ctx, data, datalen) #endif /* LIBSSH2_WOLFSSL */ #define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL) #define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx)) #else #define libssh2_hmac_ctx HMAC_CTX #define libssh2_hmac_ctx_init(ctx) \ HMAC_CTX_init(&ctx) #define libssh2_hmac_sha1_init(ctx, key, keylen) \ HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha1(), NULL) #define libssh2_hmac_md5_init(ctx, key, keylen) \ HMAC_Init_ex(ctx, key, (int)keylen, EVP_md5(), NULL) #define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ HMAC_Init_ex(ctx, key, (int)keylen, EVP_ripemd160(), NULL) #define libssh2_hmac_sha256_init(ctx, key, keylen) \ HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha256(), NULL) #define libssh2_hmac_sha512_init(ctx, key, keylen) \ HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha512(), NULL) #define libssh2_hmac_update(ctx, data, datalen) \ HMAC_Update(&(ctx), data, datalen) #define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL) #define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx) #endif extern void _libssh2_openssl_crypto_init(void); extern void _libssh2_openssl_crypto_exit(void); #define libssh2_crypto_init() _libssh2_openssl_crypto_init() #define libssh2_crypto_exit() _libssh2_openssl_crypto_exit() #if LIBSSH2_RSA #define libssh2_rsa_ctx RSA #define _libssh2_rsa_free(rsactx) RSA_free(rsactx) #endif #if LIBSSH2_DSA #define libssh2_dsa_ctx DSA #define _libssh2_dsa_free(dsactx) DSA_free(dsactx) #endif #if LIBSSH2_ECDSA #define libssh2_ecdsa_ctx EC_KEY #define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx) #define _libssh2_ec_key EC_KEY typedef enum { LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1, LIBSSH2_EC_CURVE_NISTP384 = NID_secp384r1, LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1 } libssh2_curve_type; #else #define _libssh2_ec_key void #endif /* LIBSSH2_ECDSA */ #if LIBSSH2_ED25519 #define libssh2_ed25519_ctx EVP_PKEY #define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx) #endif /* ED25519 */ #define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void) #ifdef HAVE_OPAQUE_STRUCTS #define _libssh2_cipher_ctx EVP_CIPHER_CTX * #else #define _libssh2_cipher_ctx EVP_CIPHER_CTX #endif #define _libssh2_cipher_aes256gcm EVP_aes_256_gcm #define _libssh2_cipher_aes128gcm EVP_aes_128_gcm #define _libssh2_cipher_aes256 EVP_aes_256_cbc #define _libssh2_cipher_aes192 EVP_aes_192_cbc #define _libssh2_cipher_aes128 EVP_aes_128_cbc #define _libssh2_cipher_aes128ctr EVP_aes_128_ctr #define _libssh2_cipher_aes192ctr EVP_aes_192_ctr #define _libssh2_cipher_aes256ctr EVP_aes_256_ctr #define _libssh2_cipher_blowfish EVP_bf_cbc #define _libssh2_cipher_arcfour EVP_rc4 #define _libssh2_cipher_cast5 EVP_cast5_cbc #define _libssh2_cipher_3des EVP_des_ede3_cbc #ifdef HAVE_OPAQUE_STRUCTS #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx)) #else #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) #endif #define _libssh2_bn BIGNUM #define _libssh2_bn_ctx BN_CTX #define _libssh2_bn_ctx_new() BN_CTX_new() #define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx) #define _libssh2_bn_init() BN_new() #define _libssh2_bn_init_from_bin() _libssh2_bn_init() #define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val) #define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, (int)len, bn) #define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val) #define _libssh2_bn_bytes(bn) BN_num_bytes(bn) #define _libssh2_bn_bits(bn) BN_num_bits(bn) #define _libssh2_bn_free(bn) BN_clear_free(bn) /* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ #define LIBSSH2_DH_GEX_MINGROUP 2048 #define LIBSSH2_DH_GEX_OPTGROUP 4096 #define LIBSSH2_DH_GEX_MAXGROUP 8192 #define LIBSSH2_DH_MAX_MODULUS_BITS 16384 #define _libssh2_dh_ctx BIGNUM * #define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) #define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ _libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) #define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ _libssh2_dh_secret(dhctx, secret, f, p, bnctx) #define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx); extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order, _libssh2_bn_ctx *bnctx); extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p, _libssh2_bn_ctx *bnctx); extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); extern int _libssh2_openssl_random(void *buf, size_t len); const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void); const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void); const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void); #endif /* __LIBSSH2_OPENSSL_H */ libssh2-1.11.0/src/wincng.c0000644000175000017500000024554314424650606012325 00000000000000/* * Copyright (C) 2013-2020 Marc Hoersken * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */ /* required for cross-compilation against the w64 mingw-runtime package */ #if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) #undef _WIN32_WINNT #endif #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0600 #endif #if !defined(LIBSSH2_WINCNG_DISABLE_WINCRYPT) && !defined(HAVE_LIBCRYPT32) #define HAVE_LIBCRYPT32 #endif /* specify the required libraries for dependencies using MSVC */ #ifdef _MSC_VER #pragma comment(lib, "bcrypt.lib") #ifdef HAVE_LIBCRYPT32 #pragma comment(lib, "crypt32.lib") #endif #endif #include #include #include #include #ifdef HAVE_LIBCRYPT32 #include /* for CryptDecodeObjectEx() */ #endif #define PEM_RSA_HEADER "-----BEGIN RSA PRIVATE KEY-----" #define PEM_RSA_FOOTER "-----END RSA PRIVATE KEY-----" #define PEM_DSA_HEADER "-----BEGIN DSA PRIVATE KEY-----" #define PEM_DSA_FOOTER "-----END DSA PRIVATE KEY-----" /* Define this manually to avoid including and thus clashing with symbols. */ #ifndef STATUS_NOT_SUPPORTED #define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BB) #endif /*******************************************************************/ /* * Windows CNG backend: Missing definitions (for MinGW[-w64]) */ #ifndef BCRYPT_SUCCESS #define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif #ifndef BCRYPT_RNG_ALGORITHM #define BCRYPT_RNG_ALGORITHM L"RNG" #endif #ifndef BCRYPT_MD5_ALGORITHM #define BCRYPT_MD5_ALGORITHM L"MD5" #endif #ifndef BCRYPT_SHA1_ALGORITHM #define BCRYPT_SHA1_ALGORITHM L"SHA1" #endif #ifndef BCRYPT_SHA256_ALGORITHM #define BCRYPT_SHA256_ALGORITHM L"SHA256" #endif #ifndef BCRYPT_SHA384_ALGORITHM #define BCRYPT_SHA384_ALGORITHM L"SHA384" #endif #ifndef BCRYPT_SHA512_ALGORITHM #define BCRYPT_SHA512_ALGORITHM L"SHA512" #endif #ifndef BCRYPT_RSA_ALGORITHM #define BCRYPT_RSA_ALGORITHM L"RSA" #endif #ifndef BCRYPT_DSA_ALGORITHM #define BCRYPT_DSA_ALGORITHM L"DSA" #endif #ifndef BCRYPT_AES_ALGORITHM #define BCRYPT_AES_ALGORITHM L"AES" #endif #ifndef BCRYPT_RC4_ALGORITHM #define BCRYPT_RC4_ALGORITHM L"RC4" #endif #ifndef BCRYPT_3DES_ALGORITHM #define BCRYPT_3DES_ALGORITHM L"3DES" #endif #ifndef BCRYPT_DH_ALGORITHM #define BCRYPT_DH_ALGORITHM L"DH" #endif /* BCRYPT_KDF_RAW_SECRET is available from Windows 8.1 and onwards */ #ifndef BCRYPT_KDF_RAW_SECRET #define BCRYPT_KDF_RAW_SECRET L"TRUNCATE" #endif #ifndef BCRYPT_ALG_HANDLE_HMAC_FLAG #define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008 #endif #ifndef BCRYPT_DSA_PUBLIC_BLOB #define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB" #endif #ifndef BCRYPT_DSA_PUBLIC_MAGIC #define BCRYPT_DSA_PUBLIC_MAGIC 0x42505344 /* DSPB */ #endif #ifndef BCRYPT_DSA_PRIVATE_BLOB #define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB" #endif #ifndef BCRYPT_DSA_PRIVATE_MAGIC #define BCRYPT_DSA_PRIVATE_MAGIC 0x56505344 /* DSPV */ #endif #ifndef BCRYPT_RSAPUBLIC_BLOB #define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB" #endif #ifndef BCRYPT_RSAPUBLIC_MAGIC #define BCRYPT_RSAPUBLIC_MAGIC 0x31415352 /* RSA1 */ #endif #ifndef BCRYPT_RSAFULLPRIVATE_BLOB #define BCRYPT_RSAFULLPRIVATE_BLOB L"RSAFULLPRIVATEBLOB" #endif #ifndef BCRYPT_RSAFULLPRIVATE_MAGIC #define BCRYPT_RSAFULLPRIVATE_MAGIC 0x33415352 /* RSA3 */ #endif #ifndef BCRYPT_KEY_DATA_BLOB #define BCRYPT_KEY_DATA_BLOB L"KeyDataBlob" #endif #ifndef BCRYPT_MESSAGE_BLOCK_LENGTH #define BCRYPT_MESSAGE_BLOCK_LENGTH L"MessageBlockLength" #endif #ifndef BCRYPT_NO_KEY_VALIDATION #define BCRYPT_NO_KEY_VALIDATION 0x00000008 #endif #ifndef BCRYPT_BLOCK_PADDING #define BCRYPT_BLOCK_PADDING 0x00000001 #endif #ifndef BCRYPT_PAD_NONE #define BCRYPT_PAD_NONE 0x00000001 #endif #ifndef BCRYPT_PAD_PKCS1 #define BCRYPT_PAD_PKCS1 0x00000002 #endif #ifndef BCRYPT_PAD_OAEP #define BCRYPT_PAD_OAEP 0x00000004 #endif #ifndef BCRYPT_PAD_PSS #define BCRYPT_PAD_PSS 0x00000008 #endif #ifndef CRYPT_STRING_ANY #define CRYPT_STRING_ANY 0x00000007 #endif #ifndef LEGACY_RSAPRIVATE_BLOB #define LEGACY_RSAPRIVATE_BLOB L"CAPIPRIVATEBLOB" #endif #ifndef PKCS_RSA_PRIVATE_KEY #define PKCS_RSA_PRIVATE_KEY (LPCSTR)43 #endif #if defined(_MSC_VER) && _MSC_VER < 1700 /* Workaround for warning C4306: 'type cast' : conversion from 'int' to 'LPCSTR' of greater size */ #undef X509_SEQUENCE_OF_ANY #undef X509_MULTI_BYTE_UINT #undef PKCS_RSA_PRIVATE_KEY #define X509_SEQUENCE_OF_ANY ((LPCSTR)(size_t)34) #define X509_MULTI_BYTE_UINT ((LPCSTR)(size_t)38) #define PKCS_RSA_PRIVATE_KEY ((LPCSTR)(size_t)43) #endif /*******************************************************************/ /* * Windows CNG backend: Generic functions */ struct _libssh2_wincng_ctx _libssh2_wincng; void _libssh2_wincng_init(void) { int ret; memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng)); ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, BCRYPT_RNG_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgRNG = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, BCRYPT_MD5_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHashMD5 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, BCRYPT_SHA1_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHashSHA1 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA256, BCRYPT_SHA256_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHashSHA256 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA384, BCRYPT_SHA384_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHashSHA384 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA512, BCRYPT_SHA512_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHashSHA512 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, BCRYPT_MD5_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHmacMD5 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, BCRYPT_SHA1_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHmacSHA1 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA256, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHmacSHA256 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA384, BCRYPT_SHA384_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHmacSHA384 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA512, BCRYPT_SHA512_ALGORITHM, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgHmacSHA512 = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, BCRYPT_RSA_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgRSA = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, BCRYPT_DSA_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgDSA = NULL; } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, BCRYPT_AES_ALGORITHM, NULL, 0); if(BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if(!BCRYPT_SUCCESS(ret)) { ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); if(BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgAES_CBC = NULL; } } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_ECB, BCRYPT_AES_ALGORITHM, NULL, 0); if(BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_ECB, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); if(!BCRYPT_SUCCESS(ret)) { ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_ECB, 0); if(BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgAES_ECB = NULL; } } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, BCRYPT_RC4_ALGORITHM, NULL, 0); if(BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_NA, sizeof(BCRYPT_CHAIN_MODE_NA), 0); if(!BCRYPT_SUCCESS(ret)) { ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); if(BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgRC4_NA = NULL; } } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, BCRYPT_3DES_ALGORITHM, NULL, 0); if(BCRYPT_SUCCESS(ret)) { ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if(!BCRYPT_SUCCESS(ret)) { ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); if(BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlg3DES_CBC = NULL; } } } ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDH, BCRYPT_DH_ALGORITHM, NULL, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng.hAlgDH = NULL; } } void _libssh2_wincng_free(void) { if(_libssh2_wincng.hAlgRNG) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0); if(_libssh2_wincng.hAlgHashMD5) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0); if(_libssh2_wincng.hAlgHashSHA1) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0); if(_libssh2_wincng.hAlgHashSHA256) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA256, 0); if(_libssh2_wincng.hAlgHashSHA384) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA384, 0); if(_libssh2_wincng.hAlgHashSHA512) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA512, 0); if(_libssh2_wincng.hAlgHmacMD5) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0); if(_libssh2_wincng.hAlgHmacSHA1) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0); if(_libssh2_wincng.hAlgHmacSHA256) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA256, 0); if(_libssh2_wincng.hAlgHmacSHA384) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA384, 0); if(_libssh2_wincng.hAlgHmacSHA512) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA512, 0); if(_libssh2_wincng.hAlgRSA) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0); if(_libssh2_wincng.hAlgDSA) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0); if(_libssh2_wincng.hAlgAES_CBC) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); if(_libssh2_wincng.hAlgRC4_NA) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); if(_libssh2_wincng.hAlg3DES_CBC) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); if(_libssh2_wincng.hAlgDH) (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDH, 0); memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng)); } int _libssh2_wincng_random(void *buf, size_t len) { int ret; if(len > ULONG_MAX) { return -1; } ret = BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, (ULONG)len, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; } static void _libssh2_wincng_safe_free(void *buf, size_t len) { if(!buf) return; if(len > 0) _libssh2_explicit_zero(buf, len); free(buf); } /* Copy a big endian set of bits from src to dest. * if the size of src is smaller than dest then pad the "left" (MSB) * end with zeroes and copy the bits into the "right" (LSB) end. */ static void memcpy_with_be_padding(unsigned char *dest, unsigned long dest_len, unsigned char *src, unsigned long src_len) { if(dest_len > src_len) { memset(dest, 0, dest_len - src_len); } memcpy((dest + dest_len) - src_len, src, src_len); } /*******************************************************************/ /* * Windows CNG backend: Hash functions */ int _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, unsigned char *key, unsigned long keylen) { BCRYPT_HASH_HANDLE hHash; unsigned char *pbHashObject; unsigned long dwHashObject, dwHash, cbData; int ret; ret = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (unsigned char *)&dwHash, sizeof(dwHash), &cbData, 0); if((!BCRYPT_SUCCESS(ret)) || dwHash != hashlen) { return -1; } ret = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (unsigned char *)&dwHashObject, sizeof(dwHashObject), &cbData, 0); if(!BCRYPT_SUCCESS(ret)) { return -1; } pbHashObject = malloc(dwHashObject); if(!pbHashObject) { return -1; } ret = BCryptCreateHash(hAlg, &hHash, pbHashObject, dwHashObject, key, keylen, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng_safe_free(pbHashObject, dwHashObject); return -1; } ctx->hHash = hHash; ctx->pbHashObject = pbHashObject; ctx->dwHashObject = dwHashObject; ctx->cbHash = dwHash; return 0; } int _libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, const unsigned char *data, unsigned long datalen) { int ret; ret = BCryptHashData(ctx->hHash, (unsigned char *)data, datalen, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; } int _libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, unsigned char *hash) { int ret; ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); BCryptDestroyHash(ctx->hHash); ctx->hHash = NULL; _libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject); ctx->pbHashObject = NULL; ctx->dwHashObject = 0; return BCRYPT_SUCCESS(ret) ? 0 : -1; } int _libssh2_wincng_hash(const unsigned char *data, unsigned long datalen, BCRYPT_ALG_HANDLE hAlg, unsigned char *hash, unsigned long hashlen) { _libssh2_wincng_hash_ctx ctx; int ret; ret = _libssh2_wincng_hash_init(&ctx, hAlg, hashlen, NULL, 0); if(!ret) { ret = _libssh2_wincng_hash_update(&ctx, data, datalen); ret |= _libssh2_wincng_hash_final(&ctx, hash); } return ret; } /*******************************************************************/ /* * Windows CNG backend: HMAC functions */ int _libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, unsigned char *hash) { int ret; ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); return BCRYPT_SUCCESS(ret) ? 0 : -1; } void _libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx) { BCryptDestroyHash(ctx->hHash); ctx->hHash = NULL; _libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject); ctx->pbHashObject = NULL; ctx->dwHashObject = 0; } /*******************************************************************/ /* * Windows CNG backend: Key functions */ int _libssh2_wincng_key_sha_verify(_libssh2_wincng_key_ctx *ctx, unsigned long hashlen, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, unsigned long flags) { BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1; BCRYPT_ALG_HANDLE hAlgHash; void *pPaddingInfo; unsigned char *data, *hash; unsigned long datalen; int ret; if(hashlen == SHA_DIGEST_LENGTH) { hAlgHash = _libssh2_wincng.hAlgHashSHA1; paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM; } else if(hashlen == SHA256_DIGEST_LENGTH) { hAlgHash = _libssh2_wincng.hAlgHashSHA256; paddingInfoPKCS1.pszAlgId = BCRYPT_SHA256_ALGORITHM; } else if(hashlen == SHA384_DIGEST_LENGTH) { hAlgHash = _libssh2_wincng.hAlgHashSHA384; paddingInfoPKCS1.pszAlgId = BCRYPT_SHA384_ALGORITHM; } else if(hashlen == SHA512_DIGEST_LENGTH) { hAlgHash = _libssh2_wincng.hAlgHashSHA512; paddingInfoPKCS1.pszAlgId = BCRYPT_SHA512_ALGORITHM; } else { return -1; } datalen = m_len; data = malloc(datalen); if(!data) { return -1; } hash = malloc(hashlen); if(!hash) { free(data); return -1; } memcpy(data, m, datalen); ret = _libssh2_wincng_hash(data, datalen, hAlgHash, hash, hashlen); _libssh2_wincng_safe_free(data, datalen); if(ret) { _libssh2_wincng_safe_free(hash, hashlen); return -1; } datalen = sig_len; data = malloc(datalen); if(!data) { _libssh2_wincng_safe_free(hash, hashlen); return -1; } if(flags & BCRYPT_PAD_PKCS1) { pPaddingInfo = &paddingInfoPKCS1; } else pPaddingInfo = NULL; memcpy(data, sig, datalen); ret = BCryptVerifySignature(ctx->hKey, pPaddingInfo, hash, hashlen, data, datalen, flags); _libssh2_wincng_safe_free(hash, hashlen); _libssh2_wincng_safe_free(data, datalen); return BCRYPT_SUCCESS(ret) ? 0 : -1; } #ifdef HAVE_LIBCRYPT32 static int _libssh2_wincng_load_pem(LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase, const char *headerbegin, const char *headerend, unsigned char **data, size_t *datalen) { FILE *fp; int ret; fp = fopen(filename, FOPEN_READTEXT); if(!fp) { return -1; } ret = _libssh2_pem_parse(session, headerbegin, headerend, passphrase, fp, data, datalen); fclose(fp); return ret; } static int _libssh2_wincng_load_private(LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase, unsigned char **ppbEncoded, size_t *pcbEncoded, int tryLoadRSA, int tryLoadDSA) { unsigned char *data = NULL; size_t datalen = 0; int ret = -1; if(ret && tryLoadRSA) { ret = _libssh2_wincng_load_pem(session, filename, passphrase, PEM_RSA_HEADER, PEM_RSA_FOOTER, &data, &datalen); } if(ret && tryLoadDSA) { ret = _libssh2_wincng_load_pem(session, filename, passphrase, PEM_DSA_HEADER, PEM_DSA_FOOTER, &data, &datalen); } if(!ret) { *ppbEncoded = data; *pcbEncoded = datalen; } return ret; } static int _libssh2_wincng_load_private_memory(LIBSSH2_SESSION *session, const char *privatekeydata, size_t privatekeydata_len, const unsigned char *passphrase, unsigned char **ppbEncoded, size_t *pcbEncoded, int tryLoadRSA, int tryLoadDSA) { unsigned char *data = NULL; size_t datalen = 0; int ret = -1; (void)passphrase; if(ret && tryLoadRSA) { ret = _libssh2_pem_parse_memory(session, PEM_RSA_HEADER, PEM_RSA_FOOTER, privatekeydata, privatekeydata_len, &data, &datalen); } if(ret && tryLoadDSA) { ret = _libssh2_pem_parse_memory(session, PEM_DSA_HEADER, PEM_DSA_FOOTER, privatekeydata, privatekeydata_len, &data, &datalen); } if(!ret) { *ppbEncoded = data; *pcbEncoded = datalen; } return ret; } static int _libssh2_wincng_asn_decode(unsigned char *pbEncoded, unsigned long cbEncoded, LPCSTR lpszStructType, unsigned char **ppbDecoded, unsigned long *pcbDecoded) { unsigned char *pbDecoded = NULL; unsigned long cbDecoded = 0; int ret; ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, lpszStructType, pbEncoded, cbEncoded, 0, NULL, NULL, &cbDecoded); if(!ret) { return -1; } pbDecoded = malloc(cbDecoded); if(!pbDecoded) { return -1; } ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, lpszStructType, pbEncoded, cbEncoded, 0, NULL, pbDecoded, &cbDecoded); if(!ret) { _libssh2_wincng_safe_free(pbDecoded, cbDecoded); return -1; } *ppbDecoded = pbDecoded; *pcbDecoded = cbDecoded; return 0; } static int _libssh2_wincng_bn_ltob(unsigned char *pbInput, unsigned long cbInput, unsigned char **ppbOutput, unsigned long *pcbOutput) { unsigned char *pbOutput; unsigned long cbOutput, index, offset, length; if(cbInput < 1) { return 0; } offset = 0; length = cbInput - 1; cbOutput = cbInput; if(pbInput[length] & (1 << 7)) { offset++; cbOutput += offset; } pbOutput = (unsigned char *)malloc(cbOutput); if(!pbOutput) { return -1; } pbOutput[0] = 0; for(index = 0; ((index + offset) < cbOutput) && (index < cbInput); index++) { pbOutput[index + offset] = pbInput[length - index]; } *ppbOutput = pbOutput; *pcbOutput = cbOutput; return 0; } static int _libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded, size_t cbEncoded, unsigned char **ppbDecoded, unsigned long *pcbDecoded) { unsigned char *pbDecoded = NULL; PCRYPT_DATA_BLOB pbInteger; unsigned long cbDecoded = 0, cbInteger; int ret; ret = _libssh2_wincng_asn_decode(pbEncoded, (unsigned long)cbEncoded, X509_MULTI_BYTE_UINT, (void *)&pbInteger, &cbInteger); if(!ret) { ret = _libssh2_wincng_bn_ltob(pbInteger->pbData, pbInteger->cbData, &pbDecoded, &cbDecoded); if(!ret) { *ppbDecoded = pbDecoded; *pcbDecoded = cbDecoded; } _libssh2_wincng_safe_free(pbInteger, cbInteger); } return ret; } static int _libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded, size_t cbEncoded, unsigned char ***prpbDecoded, unsigned long **prcbDecoded, unsigned long *pcbCount) { PCRYPT_DER_BLOB pBlob; unsigned char **rpbDecoded; PCRYPT_SEQUENCE_OF_ANY pbDecoded; unsigned long cbDecoded, *rcbDecoded, index, length; int ret; ret = _libssh2_wincng_asn_decode(pbEncoded, (unsigned long)cbEncoded, X509_SEQUENCE_OF_ANY, (void *)&pbDecoded, &cbDecoded); if(!ret) { length = pbDecoded->cValue; rpbDecoded = malloc(sizeof(PBYTE) * length); if(rpbDecoded) { rcbDecoded = malloc(sizeof(DWORD) * length); if(rcbDecoded) { for(index = 0; index < length; index++) { pBlob = &pbDecoded->rgValue[index]; ret = _libssh2_wincng_asn_decode_bn(pBlob->pbData, pBlob->cbData, &rpbDecoded[index], &rcbDecoded[index]); if(ret) break; } if(!ret) { *prpbDecoded = rpbDecoded; *prcbDecoded = rcbDecoded; *pcbCount = length; } else { for(length = 0; length < index; length++) { _libssh2_wincng_safe_free(rpbDecoded[length], rcbDecoded[length]); rpbDecoded[length] = NULL; rcbDecoded[length] = 0; } free(rpbDecoded); free(rcbDecoded); } } else { free(rpbDecoded); ret = -1; } } else { ret = -1; } _libssh2_wincng_safe_free(pbDecoded, cbDecoded); } return ret; } #endif /* HAVE_LIBCRYPT32 */ #if LIBSSH2_RSA || LIBSSH2_DSA static unsigned long _libssh2_wincng_bn_size(const unsigned char *bignum, unsigned long length) { unsigned long offset; if(!bignum) return 0; length--; offset = 0; while(!(*(bignum + offset)) && (offset < length)) offset++; length++; return length - offset; } #endif #if LIBSSH2_RSA /*******************************************************************/ /* * Windows CNG backend: RSA functions */ int _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { BCRYPT_KEY_HANDLE hKey; BCRYPT_RSAKEY_BLOB *rsakey; LPCWSTR lpszBlobType; unsigned long keylen, offset, mlen, p1len = 0, p2len = 0; int ret; mlen = max(_libssh2_wincng_bn_size(ndata, nlen), _libssh2_wincng_bn_size(ddata, dlen)); offset = sizeof(BCRYPT_RSAKEY_BLOB); keylen = offset + elen + mlen; if(ddata && dlen > 0) { p1len = max(_libssh2_wincng_bn_size(pdata, plen), _libssh2_wincng_bn_size(e1data, e1len)); p2len = max(_libssh2_wincng_bn_size(qdata, qlen), _libssh2_wincng_bn_size(e2data, e2len)); keylen += p1len * 3 + p2len * 2 + mlen; } rsakey = (BCRYPT_RSAKEY_BLOB *)malloc(keylen); if(!rsakey) { return -1; } memset(rsakey, 0, keylen); /* https://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ rsakey->BitLength = mlen * 8; rsakey->cbPublicExp = elen; rsakey->cbModulus = mlen; memcpy((unsigned char *)rsakey + offset, edata, elen); offset += elen; if(nlen < mlen) memcpy((unsigned char *)rsakey + offset + mlen - nlen, ndata, nlen); else memcpy((unsigned char *)rsakey + offset, ndata + nlen - mlen, mlen); if(ddata && dlen > 0) { offset += mlen; if(plen < p1len) memcpy((unsigned char *)rsakey + offset + p1len - plen, pdata, plen); else memcpy((unsigned char *)rsakey + offset, pdata + plen - p1len, p1len); offset += p1len; if(qlen < p2len) memcpy((unsigned char *)rsakey + offset + p2len - qlen, qdata, qlen); else memcpy((unsigned char *)rsakey + offset, qdata + qlen - p2len, p2len); offset += p2len; if(e1len < p1len) memcpy((unsigned char *)rsakey + offset + p1len - e1len, e1data, e1len); else memcpy((unsigned char *)rsakey + offset, e1data + e1len - p1len, p1len); offset += p1len; if(e2len < p2len) memcpy((unsigned char *)rsakey + offset + p2len - e2len, e2data, e2len); else memcpy((unsigned char *)rsakey + offset, e2data + e2len - p2len, p2len); offset += p2len; if(coefflen < p1len) memcpy((unsigned char *)rsakey + offset + p1len - coefflen, coeffdata, coefflen); else memcpy((unsigned char *)rsakey + offset, coeffdata + coefflen - p1len, p1len); offset += p1len; if(dlen < mlen) memcpy((unsigned char *)rsakey + offset + mlen - dlen, ddata, dlen); else memcpy((unsigned char *)rsakey + offset, ddata + dlen - mlen, mlen); lpszBlobType = BCRYPT_RSAFULLPRIVATE_BLOB; rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC; rsakey->cbPrime1 = p1len; rsakey->cbPrime2 = p2len; } else { lpszBlobType = BCRYPT_RSAPUBLIC_BLOB; rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsakey->cbPrime1 = 0; rsakey->cbPrime2 = 0; } ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, lpszBlobType, &hKey, (PUCHAR)rsakey, keylen, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng_safe_free(rsakey, keylen); return -1; } *rsa = malloc(sizeof(libssh2_rsa_ctx)); if(!(*rsa)) { BCryptDestroyKey(hKey); _libssh2_wincng_safe_free(rsakey, keylen); return -1; } (*rsa)->hKey = hKey; (*rsa)->pbKeyObject = rsakey; (*rsa)->cbKeyObject = keylen; return 0; } #ifdef HAVE_LIBCRYPT32 static int _libssh2_wincng_rsa_new_private_parse(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, unsigned char *pbEncoded, size_t cbEncoded) { BCRYPT_KEY_HANDLE hKey; unsigned char *pbStructInfo; unsigned long cbStructInfo; int ret; (void)session; ret = _libssh2_wincng_asn_decode(pbEncoded, (unsigned long)cbEncoded, PKCS_RSA_PRIVATE_KEY, &pbStructInfo, &cbStructInfo); _libssh2_wincng_safe_free(pbEncoded, cbEncoded); if(ret) { return -1; } ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, LEGACY_RSAPRIVATE_BLOB, &hKey, pbStructInfo, cbStructInfo, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng_safe_free(pbStructInfo, cbStructInfo); return -1; } *rsa = malloc(sizeof(libssh2_rsa_ctx)); if(!(*rsa)) { BCryptDestroyKey(hKey); _libssh2_wincng_safe_free(pbStructInfo, cbStructInfo); return -1; } (*rsa)->hKey = hKey; (*rsa)->pbKeyObject = pbStructInfo; (*rsa)->cbKeyObject = cbStructInfo; return 0; } #endif /* HAVE_LIBCRYPT32 */ int _libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase) { #ifdef HAVE_LIBCRYPT32 unsigned char *pbEncoded; size_t cbEncoded; int ret; (void)session; ret = _libssh2_wincng_load_private(session, filename, passphrase, &pbEncoded, &cbEncoded, 1, 0); if(ret) { return -1; } return _libssh2_wincng_rsa_new_private_parse(rsa, session, pbEncoded, cbEncoded); #else (void)rsa; (void)filename; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to load RSA key from private key file: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ } int _libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, const unsigned char *passphrase) { #ifdef HAVE_LIBCRYPT32 unsigned char *pbEncoded; size_t cbEncoded; int ret; (void)session; ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len, passphrase, &pbEncoded, &cbEncoded, 1, 0); if(ret) { return -1; } return _libssh2_wincng_rsa_new_private_parse(rsa, session, pbEncoded, cbEncoded); #else (void)rsa; (void)filedata; (void)filedata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unable to extract private key from memory: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ } #if LIBSSH2_RSA_SHA1 int _libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { return _libssh2_wincng_key_sha_verify(rsa, SHA_DIGEST_LENGTH, sig, (unsigned long)sig_len, m, (unsigned long)m_len, BCRYPT_PAD_PKCS1); } #endif #if LIBSSH2_RSA_SHA2 int _libssh2_wincng_rsa_sha2_verify(libssh2_rsa_ctx *rsa, size_t hash_len, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { return _libssh2_wincng_key_sha_verify(rsa, (unsigned long)hash_len, sig, (unsigned long)sig_len, m, (unsigned long)m_len, BCRYPT_PAD_PKCS1); } #endif int _libssh2_wincng_rsa_sha_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { BCRYPT_PKCS1_PADDING_INFO paddingInfo; unsigned char *data, *sig; unsigned long cbData, datalen, siglen; int ret; if(hash_len == SHA_DIGEST_LENGTH) paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM; else if(hash_len == SHA256_DIGEST_LENGTH) paddingInfo.pszAlgId = BCRYPT_SHA256_ALGORITHM; else if(hash_len == SHA384_DIGEST_LENGTH) paddingInfo.pszAlgId = BCRYPT_SHA384_ALGORITHM; else if(hash_len == SHA512_DIGEST_LENGTH) paddingInfo.pszAlgId = BCRYPT_SHA512_ALGORITHM; else { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unsupported hash digest length"); return -1; } datalen = (unsigned long)hash_len; data = malloc(datalen); if(!data) { return -1; } memcpy(data, hash, datalen); ret = BCryptSignHash(rsa->hKey, &paddingInfo, data, datalen, NULL, 0, &cbData, BCRYPT_PAD_PKCS1); if(BCRYPT_SUCCESS(ret)) { siglen = cbData; sig = LIBSSH2_ALLOC(session, siglen); if(sig) { ret = BCryptSignHash(rsa->hKey, &paddingInfo, data, datalen, sig, siglen, &cbData, BCRYPT_PAD_PKCS1); if(BCRYPT_SUCCESS(ret)) { *signature_len = siglen; *signature = sig; } else { LIBSSH2_FREE(session, sig); } } else ret = STATUS_NO_MEMORY; } _libssh2_wincng_safe_free(data, datalen); return BCRYPT_SUCCESS(ret) ? 0 : -1; } void _libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa) { if(!rsa) return; BCryptDestroyKey(rsa->hKey); rsa->hKey = NULL; _libssh2_wincng_safe_free(rsa->pbKeyObject, rsa->cbKeyObject); _libssh2_wincng_safe_free(rsa, sizeof(libssh2_rsa_ctx)); } #endif /*******************************************************************/ /* * Windows CNG backend: DSA functions */ #if LIBSSH2_DSA int _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *gdata, unsigned long glen, const unsigned char *ydata, unsigned long ylen, const unsigned char *xdata, unsigned long xlen) { BCRYPT_KEY_HANDLE hKey; BCRYPT_DSA_KEY_BLOB *dsakey; LPCWSTR lpszBlobType; unsigned long keylen, offset, length; int ret; length = max(max(_libssh2_wincng_bn_size(pdata, plen), _libssh2_wincng_bn_size(gdata, glen)), _libssh2_wincng_bn_size(ydata, ylen)); offset = sizeof(BCRYPT_DSA_KEY_BLOB); keylen = offset + length * 3; if(xdata && xlen > 0) keylen += 20; dsakey = (BCRYPT_DSA_KEY_BLOB *)malloc(keylen); if(!dsakey) { return -1; } memset(dsakey, 0, keylen); /* https://msdn.microsoft.com/library/windows/desktop/aa833126.aspx */ dsakey->cbKey = length; memset(dsakey->Count, -1, sizeof(dsakey->Count)); memset(dsakey->Seed, -1, sizeof(dsakey->Seed)); if(qlen < 20) memcpy(dsakey->q + 20 - qlen, qdata, qlen); else memcpy(dsakey->q, qdata + qlen - 20, 20); if(plen < length) memcpy((unsigned char *)dsakey + offset + length - plen, pdata, plen); else memcpy((unsigned char *)dsakey + offset, pdata + plen - length, length); offset += length; if(glen < length) memcpy((unsigned char *)dsakey + offset + length - glen, gdata, glen); else memcpy((unsigned char *)dsakey + offset, gdata + glen - length, length); offset += length; if(ylen < length) memcpy((unsigned char *)dsakey + offset + length - ylen, ydata, ylen); else memcpy((unsigned char *)dsakey + offset, ydata + ylen - length, length); if(xdata && xlen > 0) { offset += length; if(xlen < 20) memcpy((unsigned char *)dsakey + offset + 20 - xlen, xdata, xlen); else memcpy((unsigned char *)dsakey + offset, xdata + xlen - 20, 20); lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB; dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC; } else { lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB; dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; } ret = BCryptImportKeyPair(_libssh2_wincng.hAlgDSA, NULL, lpszBlobType, &hKey, (PUCHAR)dsakey, keylen, 0); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng_safe_free(dsakey, keylen); return -1; } *dsa = malloc(sizeof(libssh2_dsa_ctx)); if(!(*dsa)) { BCryptDestroyKey(hKey); _libssh2_wincng_safe_free(dsakey, keylen); return -1; } (*dsa)->hKey = hKey; (*dsa)->pbKeyObject = dsakey; (*dsa)->cbKeyObject = keylen; return 0; } #ifdef HAVE_LIBCRYPT32 static int _libssh2_wincng_dsa_new_private_parse(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, unsigned char *pbEncoded, size_t cbEncoded) { unsigned char **rpbDecoded; unsigned long *rcbDecoded, index, length; int ret; (void)session; ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, &rpbDecoded, &rcbDecoded, &length); _libssh2_wincng_safe_free(pbEncoded, cbEncoded); if(ret) { return -1; } if(length == 6) { ret = _libssh2_wincng_dsa_new(dsa, rpbDecoded[1], rcbDecoded[1], rpbDecoded[2], rcbDecoded[2], rpbDecoded[3], rcbDecoded[3], rpbDecoded[4], rcbDecoded[4], rpbDecoded[5], rcbDecoded[5]); } else { ret = -1; } for(index = 0; index < length; index++) { _libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]); rpbDecoded[index] = NULL; rcbDecoded[index] = 0; } free(rpbDecoded); free(rcbDecoded); return ret; } #endif /* HAVE_LIBCRYPT32 */ int _libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase) { #ifdef HAVE_LIBCRYPT32 unsigned char *pbEncoded; size_t cbEncoded; int ret; ret = _libssh2_wincng_load_private(session, filename, passphrase, &pbEncoded, &cbEncoded, 0, 1); if(ret) { return -1; } return _libssh2_wincng_dsa_new_private_parse(dsa, session, pbEncoded, cbEncoded); #else (void)dsa; (void)filename; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to load DSA key from private key file: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ } int _libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, const unsigned char *passphrase) { #ifdef HAVE_LIBCRYPT32 unsigned char *pbEncoded; size_t cbEncoded; int ret; ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len, passphrase, &pbEncoded, &cbEncoded, 0, 1); if(ret) { return -1; } return _libssh2_wincng_dsa_new_private_parse(dsa, session, pbEncoded, cbEncoded); #else (void)dsa; (void)filedata; (void)filedata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unable to extract private key from memory: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ } int _libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, const unsigned char *sig_fixed, const unsigned char *m, size_t m_len) { return _libssh2_wincng_key_sha_verify(dsa, SHA_DIGEST_LENGTH, sig_fixed, 40, m, (unsigned long)m_len, 0); } int _libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, const unsigned char *hash, unsigned long hash_len, unsigned char *sig_fixed) { unsigned char *data, *sig; unsigned long cbData, datalen, siglen; int ret; datalen = hash_len; data = malloc(datalen); if(!data) { return -1; } memcpy(data, hash, datalen); ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, NULL, 0, &cbData, 0); if(BCRYPT_SUCCESS(ret)) { siglen = cbData; if(siglen == 40) { sig = malloc(siglen); if(sig) { ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, sig, siglen, &cbData, 0); if(BCRYPT_SUCCESS(ret)) { memcpy(sig_fixed, sig, siglen); } _libssh2_wincng_safe_free(sig, siglen); } else ret = STATUS_NO_MEMORY; } else ret = STATUS_NO_MEMORY; } _libssh2_wincng_safe_free(data, datalen); return BCRYPT_SUCCESS(ret) ? 0 : -1; } void _libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa) { if(!dsa) return; BCryptDestroyKey(dsa->hKey); dsa->hKey = NULL; _libssh2_wincng_safe_free(dsa->pbKeyObject, dsa->cbKeyObject); _libssh2_wincng_safe_free(dsa, sizeof(libssh2_dsa_ctx)); } #endif /*******************************************************************/ /* * Windows CNG backend: Key functions */ #ifdef HAVE_LIBCRYPT32 static unsigned long _libssh2_wincng_pub_priv_write(unsigned char *key, unsigned long offset, const unsigned char *bignum, const unsigned long length) { _libssh2_htonu32(key + offset, length); offset += 4; memcpy(key + offset, bignum, length); offset += length; return offset; } static int _libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, unsigned char *pbEncoded, size_t cbEncoded) { unsigned char **rpbDecoded = NULL; unsigned long *rcbDecoded = NULL; unsigned char *key = NULL, *mth = NULL; unsigned long keylen = 0, mthlen = 0; unsigned long index, offset, length = 0; int ret; ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, &rpbDecoded, &rcbDecoded, &length); _libssh2_wincng_safe_free(pbEncoded, cbEncoded); if(ret) { return -1; } if(length == 9) { /* private RSA key */ mthlen = 7; mth = LIBSSH2_ALLOC(session, mthlen); if(mth) { memcpy(mth, "ssh-rsa", mthlen); } else { ret = -1; } keylen = 4 + mthlen + 4 + rcbDecoded[2] + 4 + rcbDecoded[1]; key = LIBSSH2_ALLOC(session, keylen); if(key) { offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); offset = _libssh2_wincng_pub_priv_write(key, offset, rpbDecoded[2], rcbDecoded[2]); _libssh2_wincng_pub_priv_write(key, offset, rpbDecoded[1], rcbDecoded[1]); } else { ret = -1; } } else if(length == 6) { /* private DSA key */ mthlen = 7; mth = LIBSSH2_ALLOC(session, mthlen); if(mth) { memcpy(mth, "ssh-dss", mthlen); } else { ret = -1; } keylen = 4 + mthlen + 4 + rcbDecoded[1] + 4 + rcbDecoded[2] + 4 + rcbDecoded[3] + 4 + rcbDecoded[4]; key = LIBSSH2_ALLOC(session, keylen); if(key) { offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); offset = _libssh2_wincng_pub_priv_write(key, offset, rpbDecoded[1], rcbDecoded[1]); offset = _libssh2_wincng_pub_priv_write(key, offset, rpbDecoded[2], rcbDecoded[2]); offset = _libssh2_wincng_pub_priv_write(key, offset, rpbDecoded[3], rcbDecoded[3]); _libssh2_wincng_pub_priv_write(key, offset, rpbDecoded[4], rcbDecoded[4]); } else { ret = -1; } } else { ret = -1; } for(index = 0; index < length; index++) { _libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]); rpbDecoded[index] = NULL; rcbDecoded[index] = 0; } free(rpbDecoded); free(rcbDecoded); if(ret) { if(mth) LIBSSH2_FREE(session, mth); if(key) LIBSSH2_FREE(session, key); } else { *method = mth; *method_len = mthlen; *pubkeydata = key; *pubkeydata_len = keylen; } return ret; } #endif /* HAVE_LIBCRYPT32 */ int _libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { #ifdef HAVE_LIBCRYPT32 unsigned char *pbEncoded; size_t cbEncoded; int ret; ret = _libssh2_wincng_load_private(session, privatekey, (const unsigned char *)passphrase, &pbEncoded, &cbEncoded, 1, 1); if(ret) { return -1; } return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len, pubkeydata, pubkeydata_len, pbEncoded, cbEncoded); #else (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)privatekey; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to load public key from private key file: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ } int _libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { #ifdef HAVE_LIBCRYPT32 unsigned char *pbEncoded; size_t cbEncoded; int ret; ret = _libssh2_wincng_load_private_memory(session, privatekeydata, privatekeydata_len, (const unsigned char *) passphrase, &pbEncoded, &cbEncoded, 1, 1); if(ret) { return -1; } return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len, pubkeydata, pubkeydata_len, pbEncoded, cbEncoded); #else (void)method; (void)method_len; (void)pubkeydata_len; (void)pubkeydata; (void)privatekeydata; (void)privatekeydata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unable to extract public key from private key in memory: " "Method unsupported in Windows CNG backend"); #endif /* HAVE_LIBCRYPT32 */ } int _libssh2_wincng_sk_pub_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)algorithm; (void)flags; (void)application; (void)key_handle; (void)handle_len; (void)privatekeydata; (void)privatekeydata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public SK key from private key file: " "Method unimplemented in Windows CNG backend"); } /*******************************************************************/ /* * Windows CNG backend: Cipher functions */ int _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), unsigned char *iv, unsigned char *secret, int encrypt) { BCRYPT_KEY_HANDLE hKey; BCRYPT_KEY_DATA_BLOB_HEADER *header; unsigned char *pbKeyObject, *pbIV, *pbCtr, *pbIVCopy; unsigned long dwKeyObject, dwIV, dwCtrLength, dwBlockLength, cbData, keylen; int ret; (void)encrypt; ret = BCryptGetProperty(*type.phAlg, BCRYPT_OBJECT_LENGTH, (unsigned char *)&dwKeyObject, sizeof(dwKeyObject), &cbData, 0); if(!BCRYPT_SUCCESS(ret)) { return -1; } ret = BCryptGetProperty(*type.phAlg, BCRYPT_BLOCK_LENGTH, (unsigned char *)&dwBlockLength, sizeof(dwBlockLength), &cbData, 0); if(!BCRYPT_SUCCESS(ret)) { return -1; } pbKeyObject = malloc(dwKeyObject); if(!pbKeyObject) { return -1; } keylen = (unsigned long)sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + type.dwKeyLength; header = (BCRYPT_KEY_DATA_BLOB_HEADER *)malloc(keylen); if(!header) { free(pbKeyObject); return -1; } header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; header->cbKeyData = type.dwKeyLength; memcpy((unsigned char *)header + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), secret, type.dwKeyLength); ret = BCryptImportKey(*type.phAlg, NULL, BCRYPT_KEY_DATA_BLOB, &hKey, pbKeyObject, dwKeyObject, (PUCHAR)header, keylen, 0); _libssh2_wincng_safe_free(header, keylen); if(!BCRYPT_SUCCESS(ret)) { _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); return -1; } pbIV = NULL; pbCtr = NULL; dwIV = 0; dwCtrLength = 0; if(type.useIV || type.ctrMode) { pbIVCopy = malloc(dwBlockLength); if(!pbIVCopy) { BCryptDestroyKey(hKey); _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); return -1; } memcpy(pbIVCopy, iv, dwBlockLength); if(type.ctrMode) { pbCtr = pbIVCopy; dwCtrLength = dwBlockLength; } else if(type.useIV) { pbIV = pbIVCopy; dwIV = dwBlockLength; } } ctx->hKey = hKey; ctx->pbKeyObject = pbKeyObject; ctx->pbIV = pbIV; ctx->pbCtr = pbCtr; ctx->dwKeyObject = dwKeyObject; ctx->dwIV = dwIV; ctx->dwBlockLength = dwBlockLength; ctx->dwCtrLength = dwCtrLength; return 0; } int _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), int encrypt, unsigned char *block, size_t blocklen, int firstlast) { unsigned char *pbOutput, *pbInput; unsigned long cbOutput, cbInput; int ret; (void)type; (void)firstlast; cbInput = (unsigned long)blocklen; if(type.ctrMode) { pbInput = ctx->pbCtr; } else { pbInput = block; } if(encrypt || type.ctrMode) { ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL, ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); } else { ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL, ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); } if(BCRYPT_SUCCESS(ret)) { pbOutput = malloc(cbOutput); if(pbOutput) { if(encrypt || type.ctrMode) { ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL, ctx->pbIV, ctx->dwIV, pbOutput, cbOutput, &cbOutput, 0); } else { ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL, ctx->pbIV, ctx->dwIV, pbOutput, cbOutput, &cbOutput, 0); } if(BCRYPT_SUCCESS(ret)) { if(type.ctrMode) { _libssh2_xor_data(block, block, pbOutput, blocklen); _libssh2_aes_ctr_increment(ctx->pbCtr, ctx->dwCtrLength); } else { memcpy(block, pbOutput, cbOutput); } } _libssh2_wincng_safe_free(pbOutput, cbOutput); } else ret = STATUS_NO_MEMORY; } return BCRYPT_SUCCESS(ret) ? 0 : -1; } void _libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx) { BCryptDestroyKey(ctx->hKey); ctx->hKey = NULL; _libssh2_wincng_safe_free(ctx->pbKeyObject, ctx->dwKeyObject); ctx->pbKeyObject = NULL; ctx->dwKeyObject = 0; _libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength); ctx->pbIV = NULL; ctx->dwBlockLength = 0; _libssh2_wincng_safe_free(ctx->pbCtr, ctx->dwCtrLength); ctx->pbCtr = NULL; ctx->dwCtrLength = 0; } /*******************************************************************/ /* * Windows CNG backend: BigNumber functions */ _libssh2_bn * _libssh2_wincng_bignum_init(void) { _libssh2_bn *bignum; bignum = (_libssh2_bn *)malloc(sizeof(_libssh2_bn)); if(bignum) { bignum->bignum = NULL; bignum->length = 0; } return bignum; } static int _libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length) { unsigned char *bignum; if(!bn) return -1; if(length == bn->length) return 0; if(bn->bignum && bn->length > 0 && length < bn->length) { _libssh2_explicit_zero(bn->bignum + length, bn->length - length); } bignum = realloc(bn->bignum, length); if(!bignum) return -1; bn->bignum = bignum; bn->length = length; return 0; } static int _libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom) { unsigned char *bignum; unsigned long length; if(!rnd) return -1; length = (unsigned long) (ceil(((double)bits) / 8.0) * sizeof(unsigned char)); if(_libssh2_wincng_bignum_resize(rnd, length)) return -1; bignum = rnd->bignum; if(_libssh2_wincng_random(bignum, length)) return -1; /* calculate significant bits in most significant byte */ bits %= 8; if(bits == 0) bits = 8; /* fill most significant byte with zero padding */ bignum[0] &= (unsigned char)((1 << bits) - 1); /* set most significant bits in most significant byte */ if(top == 0) bignum[0] |= (unsigned char)(1 << (bits - 1)); else if(top == 1) bignum[0] |= (unsigned char)(3 << (bits - 2)); /* make odd by setting first bit in least significant byte */ if(bottom) bignum[length - 1] |= 1; return 0; } static int _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m) { BCRYPT_KEY_HANDLE hKey; BCRYPT_RSAKEY_BLOB *rsakey; unsigned char *bignum; unsigned long keylen, offset, length; int ret; if(!r || !a || !p || !m) return -1; offset = sizeof(BCRYPT_RSAKEY_BLOB); keylen = offset + p->length + m->length; rsakey = (BCRYPT_RSAKEY_BLOB *)malloc(keylen); if(!rsakey) return -1; /* https://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsakey->BitLength = m->length * 8; rsakey->cbPublicExp = p->length; rsakey->cbModulus = m->length; rsakey->cbPrime1 = 0; rsakey->cbPrime2 = 0; memcpy((unsigned char *)rsakey + offset, p->bignum, p->length); offset += p->length; memcpy((unsigned char *)rsakey + offset, m->bignum, m->length); offset = 0; ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, BCRYPT_RSAPUBLIC_BLOB, &hKey, (PUCHAR)rsakey, keylen, 0); if(BCRYPT_SUCCESS(ret)) { ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0, NULL, 0, &length, BCRYPT_PAD_NONE); if(BCRYPT_SUCCESS(ret)) { if(!_libssh2_wincng_bignum_resize(r, length)) { length = max(a->length, length); bignum = malloc(length); if(bignum) { memcpy_with_be_padding(bignum, length, a->bignum, a->length); ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0, r->bignum, r->length, &offset, BCRYPT_PAD_NONE); _libssh2_wincng_safe_free(bignum, length); if(BCRYPT_SUCCESS(ret)) { _libssh2_wincng_bignum_resize(r, offset); } } else ret = STATUS_NO_MEMORY; } else ret = STATUS_NO_MEMORY; } BCryptDestroyKey(hKey); } _libssh2_wincng_safe_free(rsakey, keylen); return BCRYPT_SUCCESS(ret) ? 0 : -1; } int _libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word) { unsigned long offset, number, bits, length; if(!bn) return -1; bits = 0; number = word; while(number >>= 1) bits++; bits++; length = (unsigned long) (ceil(((double)bits) / 8.0) * sizeof(unsigned char)); if(_libssh2_wincng_bignum_resize(bn, length)) return -1; for(offset = 0; offset < length; offset++) bn->bignum[offset] = (word >> (offset * 8)) & 0xff; return 0; } unsigned long _libssh2_wincng_bignum_bits(const _libssh2_bn *bn) { unsigned char number; unsigned long offset, length, bits; if(!bn || !bn->bignum || !bn->length) return 0; offset = 0; length = bn->length - 1; while(!bn->bignum[offset] && offset < length) offset++; bits = (length - offset) * 8; number = bn->bignum[offset]; while(number >>= 1) bits++; bits++; return bits; } void _libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, const unsigned char *bin) { unsigned char *bignum; unsigned long offset, length, bits; if(!bn || !bin || !len) return; if(_libssh2_wincng_bignum_resize(bn, len)) return; memcpy(bn->bignum, bin, len); bits = _libssh2_wincng_bignum_bits(bn); length = (unsigned long) (ceil(((double)bits) / 8.0) * sizeof(unsigned char)); offset = bn->length - length; if(offset > 0) { memmove(bn->bignum, bn->bignum + offset, length); _libssh2_explicit_zero(bn->bignum + length, offset); bignum = realloc(bn->bignum, length); if(bignum) { bn->bignum = bignum; bn->length = length; } } } void _libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin) { if(bin && bn && bn->bignum && bn->length > 0) { memcpy(bin, bn->bignum, bn->length); } } void _libssh2_wincng_bignum_free(_libssh2_bn *bn) { if(bn) { if(bn->bignum) { _libssh2_wincng_safe_free(bn->bignum, bn->length); bn->bignum = NULL; } bn->length = 0; _libssh2_wincng_safe_free(bn, sizeof(_libssh2_bn)); } } /*******************************************************************/ /* * Windows CNG backend: Diffie-Hellman support. */ void _libssh2_dh_init(_libssh2_dh_ctx *dhctx) { /* Random from client */ dhctx->dh_handle = NULL; dhctx->dh_params = NULL; dhctx->dh_privbn = NULL; } void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) { if(dhctx->dh_handle) { BCryptDestroyKey(dhctx->dh_handle); dhctx->dh_handle = NULL; } if(dhctx->dh_params) { /* Since public dh_params are shared in clear text, * we don't need to securely zero them out here */ free(dhctx->dh_params); dhctx->dh_params = NULL; } if(dhctx->dh_privbn) { _libssh2_wincng_bignum_free(dhctx->dh_privbn); dhctx->dh_privbn = NULL; } } static int round_down(int number, int multiple) { return (number / multiple) * multiple; } /* Generates a Diffie-Hellman key pair using base `g', prime `p' and the given * `group_order'. Can use the given big number context `bnctx' if needed. The * private key is stored as opaque in the Diffie-Hellman context `*dhctx' and * the public key is returned in `public'. 0 is returned upon success, else * -1. */ int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order) { const int hasAlgDHwithKDF = _libssh2_wincng.hasAlgDHwithKDF; if(group_order < 0) return -1; while(_libssh2_wincng.hAlgDH && hasAlgDHwithKDF != -1) { BCRYPT_DH_PARAMETER_HEADER *dh_params; unsigned long dh_params_len; int status; /* Note that the DH provider requires that keys be multiples of 64 bits * in length. At the time of writing a practical observed group_order * value is 257, so we need to round down to 8 bytes of length (64/8) * in order for kex to succeed */ DWORD key_length_bytes = max((unsigned long)round_down(group_order, 8), max(g->length, p->length)); BCRYPT_DH_KEY_BLOB *dh_key_blob; LPCWSTR key_type; /* Prepare a key pair; pass the in the bit length of the key, * but the key is not ready for consumption until it is finalized. */ status = BCryptGenerateKeyPair(_libssh2_wincng.hAlgDH, &dhctx->dh_handle, key_length_bytes * 8, 0); if(!BCRYPT_SUCCESS(status)) { return -1; } dh_params_len = (unsigned long)sizeof(*dh_params) + 2 * key_length_bytes; dh_params = (BCRYPT_DH_PARAMETER_HEADER *)malloc(dh_params_len); if(!dh_params) { return -1; } /* Populate DH parameters blob; after the header follows the `p` * value and the `g` value. */ dh_params->cbLength = dh_params_len; dh_params->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC; dh_params->cbKeyLength = key_length_bytes; memcpy_with_be_padding((unsigned char *)dh_params + sizeof(*dh_params), key_length_bytes, p->bignum, p->length); memcpy_with_be_padding((unsigned char *)dh_params + sizeof(*dh_params) + key_length_bytes, key_length_bytes, g->bignum, g->length); status = BCryptSetProperty(dhctx->dh_handle, BCRYPT_DH_PARAMETERS, (PUCHAR)dh_params, dh_params_len, 0); if(hasAlgDHwithKDF == -1) { /* We know that the raw KDF is not supported, so discard this. */ free(dh_params); } else { /* Pass ownership to dhctx; these parameters will be freed when * the context is destroyed. We need to keep the parameters more * easily available so that we have access to the `g` value when * _libssh2_dh_secret() is called later. */ dhctx->dh_params = dh_params; } dh_params = NULL; if(!BCRYPT_SUCCESS(status)) { return -1; } status = BCryptFinalizeKeyPair(dhctx->dh_handle, 0); if(!BCRYPT_SUCCESS(status)) { return -1; } key_length_bytes = 0; if(hasAlgDHwithKDF == 1) { /* Now we need to extract the public portion of the key so that we * set it in the `public` bignum to satisfy our caller. * First measure up the size of the required buffer. */ key_type = BCRYPT_DH_PUBLIC_BLOB; } else { /* We also need to extract the private portion of the key to * set it in the `*dhctx' bignum if the raw KDF is not supported. * First measure up the size of the required buffer. */ key_type = BCRYPT_DH_PRIVATE_BLOB; } status = BCryptExportKey(dhctx->dh_handle, NULL, key_type, NULL, 0, &key_length_bytes, 0); if(!BCRYPT_SUCCESS(status)) { return -1; } dh_key_blob = (BCRYPT_DH_KEY_BLOB *)malloc(key_length_bytes); if(!dh_key_blob) { return -1; } status = BCryptExportKey(dhctx->dh_handle, NULL, key_type, (PUCHAR)dh_key_blob, key_length_bytes, &key_length_bytes, 0); if(!BCRYPT_SUCCESS(status)) { if(hasAlgDHwithKDF == 1) { /* We have no private data, because raw KDF is supported */ free(dh_key_blob); } else { /* we may have potentially private data, use secure free */ _libssh2_wincng_safe_free(dh_key_blob, key_length_bytes); } return -1; } if(hasAlgDHwithKDF == -1) { /* We know that the raw KDF is not supported, so discard this */ BCryptDestroyKey(dhctx->dh_handle); dhctx->dh_handle = NULL; } /* BCRYPT_DH_PUBLIC_BLOB corresponds to a BCRYPT_DH_KEY_BLOB header * followed by the Modulus, Generator and Public data. Those components * each have equal size, specified by dh_key_blob->cbKey. */ if(_libssh2_wincng_bignum_resize(public, dh_key_blob->cbKey)) { if(hasAlgDHwithKDF == 1) { /* We have no private data, because raw KDF is supported */ free(dh_key_blob); } else { /* we may have potentially private data, use secure free */ _libssh2_wincng_safe_free(dh_key_blob, key_length_bytes); } return -1; } /* Copy the public key data into the public bignum data buffer */ memcpy(public->bignum, (unsigned char *)dh_key_blob + sizeof(*dh_key_blob) + 2 * dh_key_blob->cbKey, dh_key_blob->cbKey); if(dh_key_blob->dwMagic == BCRYPT_DH_PRIVATE_MAGIC) { /* BCRYPT_DH_PRIVATE_BLOB additionally contains the Private data */ dhctx->dh_privbn = _libssh2_wincng_bignum_init(); if(!dhctx->dh_privbn) { _libssh2_wincng_safe_free(dh_key_blob, key_length_bytes); return -1; } if(_libssh2_wincng_bignum_resize(dhctx->dh_privbn, dh_key_blob->cbKey)) { _libssh2_wincng_safe_free(dh_key_blob, key_length_bytes); return -1; } /* Copy the private key data into the dhctx bignum data buffer */ memcpy(dhctx->dh_privbn->bignum, (unsigned char *)dh_key_blob + sizeof(*dh_key_blob) + 3 * dh_key_blob->cbKey, dh_key_blob->cbKey); /* Make sure the private key is an odd number, because only * odd primes can be used with the RSA-based fallback while * DH itself does not seem to care about it being odd or not. */ if(!(dhctx->dh_privbn->bignum[dhctx->dh_privbn->length-1] % 2)) { _libssh2_wincng_safe_free(dh_key_blob, key_length_bytes); /* discard everything first, then try again */ _libssh2_dh_dtor(dhctx); _libssh2_dh_init(dhctx); continue; } } _libssh2_wincng_safe_free(dh_key_blob, key_length_bytes); return 0; } /* Generate x and e */ dhctx->dh_privbn = _libssh2_wincng_bignum_init(); if(!dhctx->dh_privbn) return -1; if(_libssh2_wincng_bignum_rand(dhctx->dh_privbn, (group_order*8)-1, 0, -1)) return -1; if(_libssh2_wincng_bignum_mod_exp(public, g, dhctx->dh_privbn, p)) return -1; return 0; } /* Computes the Diffie-Hellman secret from the previously created context * `*dhctx', the public key `f' from the other party and the same prime `p' * used at context creation. The result is stored in `secret'. 0 is returned * upon success, else -1. */ int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p) { if(_libssh2_wincng.hAlgDH && _libssh2_wincng.hasAlgDHwithKDF != -1 && dhctx->dh_handle && dhctx->dh_params && f) { BCRYPT_KEY_HANDLE peer_public = NULL; BCRYPT_SECRET_HANDLE agreement = NULL; ULONG secret_len_bytes = 0; int status; unsigned char *start, *end; BCRYPT_DH_KEY_BLOB *public_blob; DWORD key_length_bytes = max(f->length, dhctx->dh_params->cbKeyLength); DWORD public_blob_len = (DWORD)(sizeof(*public_blob) + 3 * key_length_bytes); { /* Populate a BCRYPT_DH_KEY_BLOB; after the header follows the * Modulus, Generator and Public data. Those components must have * equal size in this representation. */ unsigned char *dest; unsigned char *src; public_blob = (BCRYPT_DH_KEY_BLOB *)malloc(public_blob_len); if(!public_blob) { return -1; } public_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC; public_blob->cbKey = key_length_bytes; dest = (unsigned char *)(public_blob + 1); src = (unsigned char *)(dhctx->dh_params + 1); /* Modulus (the p-value from the first call) */ memcpy_with_be_padding(dest, key_length_bytes, src, dhctx->dh_params->cbKeyLength); /* Generator (the g-value from the first call) */ memcpy_with_be_padding(dest + key_length_bytes, key_length_bytes, src + dhctx->dh_params->cbKeyLength, dhctx->dh_params->cbKeyLength); /* Public from the peer */ memcpy_with_be_padding(dest + 2*key_length_bytes, key_length_bytes, f->bignum, f->length); } /* Import the peer public key information */ status = BCryptImportKeyPair(_libssh2_wincng.hAlgDH, NULL, BCRYPT_DH_PUBLIC_BLOB, &peer_public, (PUCHAR)public_blob, public_blob_len, 0); if(!BCRYPT_SUCCESS(status)) { goto out; } /* Set up a handle that we can use to establish the shared secret * between ourselves (our saved dh_handle) and the peer. */ status = BCryptSecretAgreement(dhctx->dh_handle, peer_public, &agreement, 0); if(!BCRYPT_SUCCESS(status)) { goto out; } /* Compute the size of the buffer that is needed to hold the derived * shared secret. */ status = BCryptDeriveKey(agreement, BCRYPT_KDF_RAW_SECRET, NULL, NULL, 0, &secret_len_bytes, 0); if(!BCRYPT_SUCCESS(status)) { if(status == STATUS_NOT_SUPPORTED) { _libssh2_wincng.hasAlgDHwithKDF = -1; } goto out; } /* Expand the secret bignum to be ready to receive the derived secret * */ if(_libssh2_wincng_bignum_resize(secret, secret_len_bytes)) { status = STATUS_NO_MEMORY; goto out; } /* And populate the secret bignum */ status = BCryptDeriveKey(agreement, BCRYPT_KDF_RAW_SECRET, NULL, secret->bignum, secret_len_bytes, &secret_len_bytes, 0); if(!BCRYPT_SUCCESS(status)) { if(status == STATUS_NOT_SUPPORTED) { _libssh2_wincng.hasAlgDHwithKDF = -1; } goto out; } /* Counter to all the other data in the BCrypt APIs, the raw secret is * returned to us in host byte order, so we need to swap it to big * endian order. */ start = secret->bignum; end = secret->bignum + secret->length - 1; while(start < end) { unsigned char tmp = *end; *end = *start; *start = tmp; start++; end--; } status = 0; _libssh2_wincng.hasAlgDHwithKDF = 1; out: if(peer_public) { BCryptDestroyKey(peer_public); } if(agreement) { BCryptDestroySecret(agreement); } free(public_blob); if(status == STATUS_NOT_SUPPORTED && _libssh2_wincng.hasAlgDHwithKDF == -1) { goto fb; /* fallback to RSA-based implementation */ } return BCRYPT_SUCCESS(status) ? 0 : -1; } fb: /* Compute the shared secret */ return _libssh2_wincng_bignum_mod_exp(secret, f, dhctx->dh_privbn, p); } /* _libssh2_supported_key_sign_algorithms * * Return supported key hash algo upgrades, see crypto.h * */ const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len) { (void)session; #if LIBSSH2_RSA_SHA2 if(key_method_len == 7 && memcmp(key_method, "ssh-rsa", key_method_len) == 0) { return "rsa-sha2-512,rsa-sha2-256,ssh-rsa"; } #else (void)key_method; (void)key_method_len; #endif return NULL; } #endif /* LIBSSH2_CRYPTO_C */ libssh2-1.11.0/src/libgcrypt.c0000644000175000017500000004601714432741311013023 00000000000000/* Copyright (C) 2008, 2009, Simon Josefsson * Copyright (C) 2006, 2007, The Written Word, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */ #if LIBSSH2_RSA int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { int rc; (void)e1data; (void)e1len; (void)e2data; (void)e2len; if(ddata) { rc = gcry_sexp_build(rsa, NULL, "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", nlen, ndata, elen, edata, dlen, ddata, plen, pdata, qlen, qdata, coefflen, coeffdata); } else { rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))", nlen, ndata, elen, edata); } if(rc) { *rsa = NULL; return -1; } return 0; } #if LIBSSH2_RSA_SHA1 int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { unsigned char hash[SHA_DIGEST_LENGTH]; gcry_sexp_t s_sig, s_hash; int rc = -1; libssh2_sha1(m, m_len, hash); rc = gcry_sexp_build(&s_hash, NULL, "(data (flags pkcs1) (hash sha1 %b))", SHA_DIGEST_LENGTH, hash); if(rc) { return -1; } rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig); if(rc) { gcry_sexp_release(s_hash); return -1; } rc = gcry_pk_verify(s_sig, s_hash, rsa); gcry_sexp_release(s_sig); gcry_sexp_release(s_hash); return (rc == 0) ? 0 : -1; } #endif #endif #if LIBSSH2_DSA int _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, const unsigned char *p, unsigned long p_len, const unsigned char *q, unsigned long q_len, const unsigned char *g, unsigned long g_len, const unsigned char *y, unsigned long y_len, const unsigned char *x, unsigned long x_len) { int rc; if(x_len) { rc = gcry_sexp_build(dsactx, NULL, "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); } else { rc = gcry_sexp_build(dsactx, NULL, "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", p_len, p, q_len, q, g_len, g, y_len, y); } if(rc) { *dsactx = NULL; return -1; } return 0; } #endif #if LIBSSH2_RSA int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { (void)rsa; (void)filedata; (void)filedata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unable to extract private key from memory: " "Method unimplemented in libgcrypt backend"); } int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { FILE *fp; unsigned char *data, *save_data; size_t datalen; int ret; unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff; unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; fp = fopen(filename, FOPEN_READTEXT); if(!fp) { return -1; } ret = _libssh2_pem_parse(session, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----", passphrase, fp, &data, &datalen); fclose(fp); if(ret) { return -1; } save_data = data; if(_libssh2_pem_decode_sequence(&data, &datalen)) { ret = -1; goto fail; } /* First read Version field (should be 0). */ ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); if(ret || (nlen != 1 && *n != '\0')) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen); if(ret) { ret = -1; goto fail; } if(_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen, q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) { ret = -1; goto fail; } ret = 0; fail: LIBSSH2_FREE(session, save_data); return ret; } #endif #if LIBSSH2_DSA int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { (void)dsa; (void)filedata; (void)filedata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unable to extract private key from memory: " "Method unimplemented in libgcrypt backend"); } int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase) { FILE *fp; unsigned char *data, *save_data; size_t datalen; int ret; unsigned char *p, *q, *g, *y, *x; unsigned int plen, qlen, glen, ylen, xlen; fp = fopen(filename, FOPEN_READTEXT); if(!fp) { return -1; } ret = _libssh2_pem_parse(session, "-----BEGIN DSA PRIVATE KEY-----", "-----END DSA PRIVATE KEY-----", passphrase, fp, &data, &datalen); fclose(fp); if(ret) { return -1; } save_data = data; if(_libssh2_pem_decode_sequence(&data, &datalen)) { ret = -1; goto fail; } /* First read Version field (should be 0). */ ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); if(ret || (plen != 1 && *p != '\0')) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen); if(ret) { ret = -1; goto fail; } ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen); if(ret) { ret = -1; goto fail; } if(datalen) { ret = -1; goto fail; } if(_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) { ret = -1; goto fail; } ret = 0; fail: LIBSSH2_FREE(session, save_data); return ret; } #endif #if LIBSSH2_RSA #if LIBSSH2_RSA_SHA1 int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { gcry_sexp_t sig_sexp; gcry_sexp_t data; int rc; const char *tmp; size_t size; if(hash_len != SHA_DIGEST_LENGTH) { return -1; } if(gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))", hash_len, hash)) { return -1; } rc = gcry_pk_sign(&sig_sexp, data, rsactx); gcry_sexp_release(data); if(rc) { return -1; } data = gcry_sexp_find_token(sig_sexp, "s", 0); if(!data) { return -1; } tmp = gcry_sexp_nth_data(data, 1, &size); if(!tmp) { gcry_sexp_release(data); return -1; } if(tmp[0] == '\0') { tmp++; size--; } *signature = LIBSSH2_ALLOC(session, size); if(!*signature) { gcry_sexp_release(data); return -1; } memcpy(*signature, tmp, size); *signature_len = size; gcry_sexp_release(data); return rc; } #endif #endif #if LIBSSH2_DSA int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, const unsigned char *hash, unsigned long hash_len, unsigned char *sig) { unsigned char zhash[SHA_DIGEST_LENGTH + 1]; gcry_sexp_t sig_sexp; gcry_sexp_t data; int ret; const char *tmp; size_t size; if(hash_len != SHA_DIGEST_LENGTH) { return -1; } memcpy(zhash + 1, hash, hash_len); zhash[0] = 0; if(gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) { return -1; } ret = gcry_pk_sign(&sig_sexp, data, dsactx); gcry_sexp_release(data); if(ret) { return -1; } memset(sig, 0, 40); /* Extract R. */ data = gcry_sexp_find_token(sig_sexp, "r", 0); if(!data) goto err; tmp = gcry_sexp_nth_data(data, 1, &size); if(!tmp) goto err; if(tmp[0] == '\0') { tmp++; size--; } if(size < 1 || size > 20) goto err; memcpy(sig + (20 - size), tmp, size); gcry_sexp_release(data); /* Extract S. */ data = gcry_sexp_find_token(sig_sexp, "s", 0); if(!data) goto err; tmp = gcry_sexp_nth_data(data, 1, &size); if(!tmp) goto err; if(tmp[0] == '\0') { tmp++; size--; } if(size < 1 || size > 20) goto err; memcpy(sig + 20 + (20 - size), tmp, size); goto out; err: ret = -1; out: if(sig_sexp) { gcry_sexp_release(sig_sexp); } if(data) { gcry_sexp_release(data); } return ret; } int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, const unsigned char *sig, const unsigned char *m, size_t m_len) { unsigned char hash[SHA_DIGEST_LENGTH + 1]; gcry_sexp_t s_sig, s_hash; int rc = -1; libssh2_sha1(m, m_len, hash + 1); hash[0] = 0; if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))", SHA_DIGEST_LENGTH + 1, hash)) { return -1; } if(gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", 20, sig, 20, sig + 20)) { gcry_sexp_release(s_hash); return -1; } rc = gcry_pk_verify(s_sig, s_hash, dsactx); gcry_sexp_release(s_sig); gcry_sexp_release(s_hash); return (rc == 0) ? 0 : -1; } #endif int _libssh2_cipher_init(_libssh2_cipher_ctx * h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { int ret; int cipher = _libssh2_gcry_cipher(algo); int mode = _libssh2_gcry_mode(algo); size_t keylen = gcry_cipher_get_algo_keylen(cipher); (void)encrypt; ret = gcry_cipher_open(h, cipher, mode, 0); if(ret) { return -1; } ret = gcry_cipher_setkey(*h, secret, keylen); if(ret) { gcry_cipher_close(*h); return -1; } if(mode != GCRY_CIPHER_MODE_STREAM) { size_t blklen = gcry_cipher_get_algo_blklen(cipher); if(mode == GCRY_CIPHER_MODE_CTR) ret = gcry_cipher_setctr(*h, iv, blklen); else ret = gcry_cipher_setiv(*h, iv, blklen); if(ret) { gcry_cipher_close(*h); return -1; } } return 0; } int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blklen, int firstlast) { int ret; (void)algo; (void)firstlast; if(encrypt) { ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen); } else { ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen); } return ret; } int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)privatekeydata; (void)privatekeydata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unable to extract public key from private " "key in memory: " "Method unimplemented in libgcrypt backend"); } int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)privatekey; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key from private key file: " "Method unimplemented in libgcrypt backend"); } int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)algorithm; (void)flags; (void)application; (void)key_handle; (void)handle_len; (void)privatekeydata; (void)privatekeydata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public SK key from private key file: " "Method unimplemented in libgcrypt backend"); } void _libssh2_init_aes_ctr(void) { /* no implementation */ } void _libssh2_dh_init(_libssh2_dh_ctx *dhctx) { *dhctx = gcry_mpi_new(0); /* Random from client */ } int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order) { /* Generate x and e */ gcry_mpi_randomize(*dhctx, group_order * 8 - 1, GCRY_WEAK_RANDOM); gcry_mpi_powm(public, g, *dhctx, p); return 0; } int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p) { /* Compute the shared secret */ gcry_mpi_powm(secret, f, *dhctx, p); return 0; } void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) { gcry_mpi_release(*dhctx); *dhctx = NULL; } /* _libssh2_supported_key_sign_algorithms * * Return supported key hash algo upgrades, see crypto.h * */ const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len) { (void)session; (void)key_method; (void)key_method_len; return NULL; } #endif /* LIBSSH2_CRYPTO_C */ libssh2-1.11.0/src/scp.c0000644000175000017500000012521114432741311011603 00000000000000/* Copyright (c) 2009-2019 by Daniel Stenberg * Copyright (c) 2004-2008, Sara Golemon * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "channel.h" #include "session.h" #include /* strtoll(), _strtoi64(), strtol() */ #if defined(HAVE_STRTOLL) #define scpsize_strtol strtoll #elif defined(HAVE_STRTOI64) #define scpsize_strtol _strtoi64 #else #define scpsize_strtol strtol #endif /* Max. length of a quoted string after libssh2_shell_quotearg() processing */ #define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2) /* This function quotes a string in a way suitable to be used with a shell, e.g. the file name one two becomes 'one two' The resulting output string is crafted in a way that makes it usable with the two most common shell types: Bourne Shell derived shells (sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh). The following special cases are handled: o If the string contains an apostrophy itself, the apostrophy character is written in quotation marks, e.g. "'". The shell cannot handle the syntax 'doesn\'t', so we close the current argument word, add the apostrophe in quotation marks "", and open a new argument word instead (_ indicate the input string characters): _____ _ _ 'doesn' "'" 't' Sequences of apostrophes are combined in one pair of quotation marks: a'''b becomes _ ___ _ 'a'"'''"'b' o If the string contains an exclamation mark (!), the C-Shell interprets it as an event number. Using \! (not within quotation marks or single quotation marks) is a mechanism understood by both Bourne Shell and C-Shell. If a quotation was already started, the argument word is closed first: a!b become _ _ _ 'a'\!'b' The result buffer must be large enough for the expanded result. A bad case regarding expansion is alternating characters and apostrophes: a'b'c'd' (length 8) gets converted to 'a'"'"'b'"'"'c'"'"'d'"'" (length 24) This is the worst case. Maximum length of the result: 1 + 6 * (length(input) + 1) / 2) + 1 => 3 * length(input) + 2 Explanation: o leading apostrophe o one character / apostrophe pair (two characters) can get represented as 6 characters: a' -> a'"'"' o String terminator (+1) A result buffer three times the size of the input buffer + 2 characters should be safe. References: o csh-compatible quotation (special handling for '!' etc.), see https://www.grymoire.com/Unix/Csh.html#toc-uh-10 Return value: Length of the resulting string (not counting the terminating '\0'), or 0 in case of errors, e.g. result buffer too small Note: this function could possible be used elsewhere within libssh2, but until then it is kept static and in this source file. */ static size_t shell_quotearg(const char *path, unsigned char *buf, size_t bufsize) { const char *src; unsigned char *dst, *endp; /* * Processing States: * UQSTRING: unquoted string: ... -- used for quoting exclamation * marks. This is the initial state * SQSTRING: single-quoted-string: '... -- any character may follow * QSTRING: quoted string: "... -- only apostrophes may follow */ enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING; endp = &buf[bufsize]; src = path; dst = buf; while(*src && dst < endp - 1) { switch(*src) { /* * Special handling for apostrophe. * An apostrophe is always written in quotation marks, e.g. * ' -> "'". */ case '\'': switch(state) { case UQSTRING: /* Unquoted string */ if(dst + 1 >= endp) return 0; *dst++ = '"'; break; case QSTRING: /* Continue quoted string */ break; case SQSTRING: /* Close single quoted string */ if(dst + 2 >= endp) return 0; *dst++ = '\''; *dst++ = '"'; break; default: break; } state = QSTRING; break; /* * Special handling for exclamation marks. CSH interprets * exclamation marks even when quoted with apostrophes. We convert * it to the plain string \!, because both Bourne Shell and CSH * interpret that as a verbatim exclamation mark. */ case '!': switch(state) { case UQSTRING: if(dst + 1 >= endp) return 0; *dst++ = '\\'; break; case QSTRING: if(dst + 2 >= endp) return 0; *dst++ = '"'; /* Closing quotation mark */ *dst++ = '\\'; break; case SQSTRING: /* Close single quoted string */ if(dst + 2 >= endp) return 0; *dst++ = '\''; *dst++ = '\\'; break; default: break; } state = UQSTRING; break; /* * Ordinary character: prefer single-quoted string */ default: switch(state) { case UQSTRING: if(dst + 1 >= endp) return 0; *dst++ = '\''; break; case QSTRING: if(dst + 2 >= endp) return 0; *dst++ = '"'; /* Closing quotation mark */ *dst++ = '\''; break; case SQSTRING: /* Continue single quoted string */ break; default: break; } state = SQSTRING; /* Start single-quoted string */ break; } if(dst + 1 >= endp) return 0; *dst++ = *src++; } switch(state) { case UQSTRING: break; case QSTRING: /* Close quoted string */ if(dst + 1 >= endp) return 0; *dst++ = '"'; break; case SQSTRING: /* Close single quoted string */ if(dst + 1 >= endp) return 0; *dst++ = '\''; break; default: break; } if(dst + 1 >= endp) return 0; *dst = '\0'; /* The result cannot be larger than 3 * strlen(path) + 2 */ /* assert((dst - buf) <= (3 * (src - path) + 2)); */ return dst - buf; } /* * scp_recv * * Open a channel and request a remote file via SCP * */ static LIBSSH2_CHANNEL * scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb) { size_t cmd_len; int rc; int tmp_err_code; const char *tmp_err_msg; if(session->scpRecv_state == libssh2_NB_state_idle) { session->scpRecv_mode = 0; session->scpRecv_size = 0; session->scpRecv_mtime = 0; session->scpRecv_atime = 0; session->scpRecv_command_len = _libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb ? 1 : 0); session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len); if(!session->scpRecv_command) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for " "SCP session"); return NULL; } snprintf((char *)session->scpRecv_command, session->scpRecv_command_len, "scp -%sf ", sb ? "p" : ""); cmd_len = strlen((char *)session->scpRecv_command); if(!session->flag.quote_paths) { size_t path_len; path_len = strlen(path); /* no NUL-termination needed, so memcpy will do */ memcpy(&session->scpRecv_command[cmd_len], path, path_len); cmd_len += path_len; } else { cmd_len += shell_quotearg(path, &session->scpRecv_command[cmd_len], session->scpRecv_command_len - cmd_len); } /* the command to exec should _not_ be NUL-terminated */ session->scpRecv_command_len = cmd_len; _libssh2_debug((session, LIBSSH2_TRACE_SCP, "Opening channel for SCP receive")); session->scpRecv_state = libssh2_NB_state_created; } if(session->scpRecv_state == libssh2_NB_state_created) { /* Allocate a channel */ session->scpRecv_channel = _libssh2_channel_open(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if(!session->scpRecv_channel) { if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; session->scpRecv_state = libssh2_NB_state_idle; } else { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel"); } return NULL; } session->scpRecv_state = libssh2_NB_state_sent; } if(session->scpRecv_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *)session->scpRecv_command, session->scpRecv_command_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup"); return NULL; } else if(rc) { LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; goto scp_recv_error; } LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; _libssh2_debug((session, LIBSSH2_TRACE_SCP, "Sending initial wakeup")); /* SCP ACK */ session->scpRecv_response[0] = '\0'; session->scpRecv_state = libssh2_NB_state_sent1; } if(session->scpRecv_state == libssh2_NB_state_sent1) { rc = (int)_libssh2_channel_write(session->scpRecv_channel, 0, session->scpRecv_response, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup"); return NULL; } else if(rc != 1) { goto scp_recv_error; } /* Parse SCP response */ session->scpRecv_response_len = 0; session->scpRecv_state = libssh2_NB_state_sent2; } if((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) { while(sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { unsigned char *s, *p; if(session->scpRecv_state == libssh2_NB_state_sent2) { rc = (int)_libssh2_channel_read(session->scpRecv_channel, 0, (char *) session-> scpRecv_response + session->scpRecv_response_len, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response"); return NULL; } else if(rc < 0) { /* error, give up */ _libssh2_error(session, rc, "Failed reading SCP response"); goto scp_recv_error; } else if(rc == 0) goto scp_recv_empty_channel; session->scpRecv_response_len++; if(session->scpRecv_response[0] != 'T') { size_t err_len; char *err_msg; /* there can be 01 for warnings 02 for errors The following string MUST be newline terminated */ err_len = _libssh2_channel_packet_data_len(session-> scpRecv_channel, 0); err_msg = LIBSSH2_ALLOC(session, err_len + 1); if(!err_msg) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed to get memory "); goto scp_recv_error; } /* Read the remote error message */ (void)_libssh2_channel_read(session->scpRecv_channel, 0, err_msg, err_len); /* If it failed for any reason, we ignore it anyway. */ /* zero terminate the error */ err_msg[err_len] = 0; _libssh2_debug((session, LIBSSH2_TRACE_SCP, "got %02x %s", session->scpRecv_response[0], err_msg)); _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Failed to recv file"); LIBSSH2_FREE(session, err_msg); goto scp_recv_error; } if((session->scpRecv_response_len > 1) && ((session-> scpRecv_response[session->scpRecv_response_len - 1] < '0') || (session-> scpRecv_response[session->scpRecv_response_len - 1] > '9')) && (session-> scpRecv_response[session->scpRecv_response_len - 1] != ' ') && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\r') && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n')) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response"); goto scp_recv_error; } if((session->scpRecv_response_len < 9) || (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n')) { if(session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { /* You had your chance */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from " "SCP server"); goto scp_recv_error; } /* Way too short to be an SCP response, or not done yet, short circuit */ continue; } /* We're guaranteed not to go under response_len == 0 by the logic above */ while((session-> scpRecv_response[session->scpRecv_response_len - 1] == '\r') || (session-> scpRecv_response[session->scpRecv_response_len - 1] == '\n')) session->scpRecv_response_len--; session->scpRecv_response[session->scpRecv_response_len] = '\0'; if(session->scpRecv_response_len < 8) { /* EOL came too soon */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "too short"); goto scp_recv_error; } s = session->scpRecv_response + 1; p = (unsigned char *) strchr((char *) s, ' '); if(!p || ((p - s) <= 0)) { /* No spaces or space in the wrong spot */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "malformed mtime"); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ session->scpRecv_mtime = strtol((char *) s, NULL, 10); s = (unsigned char *) strchr((char *) p, ' '); if(!s || ((s - p) <= 0)) { /* No spaces or space in the wrong spot */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "malformed mtime.usec"); goto scp_recv_error; } /* Ignore mtime.usec */ s++; p = (unsigned char *) strchr((char *) s, ' '); if(!p || ((p - s) <= 0)) { /* No spaces or space in the wrong spot */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "too short or malformed"); goto scp_recv_error; } *p = '\0'; /* Make sure we don't get fooled by leftover values */ session->scpRecv_atime = strtol((char *) s, NULL, 10); /* SCP ACK */ session->scpRecv_response[0] = '\0'; session->scpRecv_state = libssh2_NB_state_sent3; } if(session->scpRecv_state == libssh2_NB_state_sent3) { rc = (int)_libssh2_channel_write(session->scpRecv_channel, 0, session->scpRecv_response, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK"); return NULL; } else if(rc != 1) { goto scp_recv_error; } _libssh2_debug((session, LIBSSH2_TRACE_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime)); /* We *should* check that atime.usec is valid, but why let that stop use? */ break; } } session->scpRecv_state = libssh2_NB_state_sent4; } if(session->scpRecv_state == libssh2_NB_state_sent4) { session->scpRecv_response_len = 0; session->scpRecv_state = libssh2_NB_state_sent5; } if((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) { while(session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { char *s, *p, *e = NULL; if(session->scpRecv_state == libssh2_NB_state_sent5) { rc = (int)_libssh2_channel_read(session->scpRecv_channel, 0, (char *) session-> scpRecv_response + session->scpRecv_response_len, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response"); return NULL; } else if(rc < 0) { /* error, bail out */ _libssh2_error(session, rc, "Failed reading SCP response"); goto scp_recv_error; } else if(rc == 0) goto scp_recv_empty_channel; session->scpRecv_response_len++; if(session->scpRecv_response[0] != 'C') { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server"); goto scp_recv_error; } if((session->scpRecv_response_len > 1) && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\r') && (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n') && (session-> scpRecv_response[session->scpRecv_response_len - 1] < 32)) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response"); goto scp_recv_error; } if((session->scpRecv_response_len < 7) || (session-> scpRecv_response[session->scpRecv_response_len - 1] != '\n')) { if(session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { /* You had your chance */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response " "from SCP server"); goto scp_recv_error; } /* Way too short to be an SCP response, or not done yet, short circuit */ continue; } /* We're guaranteed not to go under response_len == 0 by the logic above */ while((session-> scpRecv_response[session->scpRecv_response_len - 1] == '\r') || (session-> scpRecv_response[session->scpRecv_response_len - 1] == '\n')) { session->scpRecv_response_len--; } session->scpRecv_response[session->scpRecv_response_len] = '\0'; if(session->scpRecv_response_len < 6) { /* EOL came too soon */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "too short"); goto scp_recv_error; } s = (char *) session->scpRecv_response + 1; p = strchr(s, ' '); if(!p || ((p - s) <= 0)) { /* No spaces or space in the wrong spot */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "malformed mode"); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ session->scpRecv_mode = strtol(s, &e, 8); if(e && *e) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "invalid mode"); goto scp_recv_error; } s = strchr(p, ' '); if(!s || ((s - p) <= 0)) { /* No spaces or space in the wrong spot */ _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "too short or malformed"); goto scp_recv_error; } *s = '\0'; /* Make sure we don't get fooled by leftover values */ session->scpRecv_size = scpsize_strtol(p, &e, 10); if(e && *e) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, " "invalid size"); goto scp_recv_error; } /* SCP ACK */ session->scpRecv_response[0] = '\0'; session->scpRecv_state = libssh2_NB_state_sent6; } if(session->scpRecv_state == libssh2_NB_state_sent6) { rc = (int)_libssh2_channel_write(session->scpRecv_channel, 0, session->scpRecv_response, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK"); return NULL; } else if(rc != 1) { goto scp_recv_error; } _libssh2_debug((session, LIBSSH2_TRACE_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size)); /* We *should* check that basename is valid, but why let that stop us? */ break; } } session->scpRecv_state = libssh2_NB_state_sent7; } if(sb) { memset(sb, 0, sizeof(libssh2_struct_stat)); sb->st_mtime = session->scpRecv_mtime; sb->st_atime = session->scpRecv_atime; sb->st_size = session->scpRecv_size; sb->st_mode = (unsigned short)session->scpRecv_mode; } session->scpRecv_state = libssh2_NB_state_idle; return session->scpRecv_channel; scp_recv_empty_channel: /* the code only jumps here as a result of a zero read from channel_read() so we check EOF status to avoid getting stuck in a loop */ if(libssh2_channel_eof(session->scpRecv_channel)) _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unexpected channel close"); else return session->scpRecv_channel; /* fall-through */ scp_recv_error: tmp_err_code = session->err_code; tmp_err_msg = session->err_msg; while(libssh2_channel_free(session->scpRecv_channel) == LIBSSH2_ERROR_EAGAIN); session->err_code = tmp_err_code; session->err_msg = tmp_err_msg; session->scpRecv_channel = NULL; session->scpRecv_state = libssh2_NB_state_idle; return NULL; } /* * libssh2_scp_recv * * DEPRECATED * * Open a channel and request a remote file via SCP. This receives files * larger than 2 GB, but is unable to report the proper size on platforms * where the st_size member of struct stat is limited to 2 GB (e.g. windows). * */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb) { LIBSSH2_CHANNEL *ptr; /* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a struct to populate... */ libssh2_struct_stat sb_intl; libssh2_struct_stat *sb_ptr; memset(&sb_intl, 0, sizeof(sb_intl)); sb_ptr = sb ? &sb_intl : NULL; BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb_ptr)); /* ...and populate the caller's with as much info as fits. */ if(sb) { memset(sb, 0, sizeof(struct stat)); sb->st_mtime = sb_intl.st_mtime; sb->st_atime = sb_intl.st_atime; sb->st_size = (off_t)sb_intl.st_size; sb->st_mode = sb_intl.st_mode; } return ptr; } /* * libssh2_scp_recv2 * * Open a channel and request a remote file via SCP. This supports files > 2GB * on platforms that support it. * */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, libssh2_struct_stat *sb) { LIBSSH2_CHANNEL *ptr; BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb)); return ptr; } /* * scp_send * * Send a file using SCP * */ static LIBSSH2_CHANNEL * scp_send(LIBSSH2_SESSION * session, const char *path, int mode, libssh2_int64_t size, time_t mtime, time_t atime) { size_t cmd_len; int rc; int tmp_err_code; const char *tmp_err_msg; if(session->scpSend_state == libssh2_NB_state_idle) { session->scpSend_command_len = _libssh2_shell_quotedsize(path) + sizeof("scp -t ") + ((mtime || atime) ? 1 : 0); session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len); if(!session->scpSend_command) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for " "SCP session"); return NULL; } snprintf((char *)session->scpSend_command, session->scpSend_command_len, "scp -%st ", (mtime || atime) ? "p" : ""); cmd_len = strlen((char *)session->scpSend_command); if(!session->flag.quote_paths) { size_t path_len; path_len = strlen(path); /* no NUL-termination needed, so memcpy will do */ memcpy(&session->scpSend_command[cmd_len], path, path_len); cmd_len += path_len; } else { cmd_len += shell_quotearg(path, &session->scpSend_command[cmd_len], session->scpSend_command_len - cmd_len); } /* the command to exec should _not_ be NUL-terminated */ session->scpSend_command_len = cmd_len; _libssh2_debug((session, LIBSSH2_TRACE_SCP, "Opening channel for SCP send")); /* Allocate a channel */ session->scpSend_state = libssh2_NB_state_created; } if(session->scpSend_state == libssh2_NB_state_created) { session->scpSend_channel = _libssh2_channel_open(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if(!session->scpSend_channel) { if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_idle; } else { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel"); } return NULL; } session->scpSend_state = libssh2_NB_state_sent; } if(session->scpSend_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1, (char *)session->scpSend_command, session->scpSend_command_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup"); return NULL; } else if(rc) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string"); goto scp_send_error; } LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_sent1; } if(session->scpSend_state == libssh2_NB_state_sent1) { /* Wait for ACK */ rc = (int)_libssh2_channel_read(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote"); return NULL; } else if(rc < 0) { _libssh2_error(session, rc, "SCP failure"); goto scp_send_error; } else if(!rc) /* remain in the same state */ goto scp_send_empty_channel; else if(session->scpSend_response[0]) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote"); goto scp_send_error; } if(mtime || atime) { /* Send mtime and atime to be used for file */ session->scpSend_response_len = snprintf((char *) session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", (long)mtime, (long)atime); _libssh2_debug((session, LIBSSH2_TRACE_SCP, "Sent %s", session->scpSend_response)); } session->scpSend_state = libssh2_NB_state_sent2; } /* Send mtime and atime to be used for file */ if(mtime || atime) { if(session->scpSend_state == libssh2_NB_state_sent2) { rc = (int)_libssh2_channel_write(session->scpSend_channel, 0, session->scpSend_response, session->scpSend_response_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file"); return NULL; } else if(rc != (int)session->scpSend_response_len) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file"); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent3; } if(session->scpSend_state == libssh2_NB_state_sent3) { /* Wait for ACK */ rc = (int)_libssh2_channel_read(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response"); return NULL; } else if(rc < 0) { _libssh2_error(session, rc, "SCP failure"); goto scp_send_error; } else if(!rc) /* remain in the same state */ goto scp_send_empty_channel; else if(session->scpSend_response[0]) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid SCP ACK response"); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent4; } } else { if(session->scpSend_state == libssh2_NB_state_sent2) { session->scpSend_state = libssh2_NB_state_sent4; } } if(session->scpSend_state == libssh2_NB_state_sent4) { /* Send mode, size, and basename */ const char *base = strrchr(path, '/'); if(base) base++; else base = path; session->scpSend_response_len = snprintf((char *) session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %" LIBSSH2_INT64_T_FORMAT " %s\n", mode, size, base); _libssh2_debug((session, LIBSSH2_TRACE_SCP, "Sent %s", session->scpSend_response)); session->scpSend_state = libssh2_NB_state_sent5; } if(session->scpSend_state == libssh2_NB_state_sent5) { rc = (int)_libssh2_channel_write(session->scpSend_channel, 0, session->scpSend_response, session->scpSend_response_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file"); return NULL; } else if(rc != (int)session->scpSend_response_len) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file"); goto scp_send_error; } session->scpSend_state = libssh2_NB_state_sent6; } if(session->scpSend_state == libssh2_NB_state_sent6) { /* Wait for ACK */ rc = (int)_libssh2_channel_read(session->scpSend_channel, 0, (char *) session->scpSend_response, 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response"); return NULL; } else if(rc < 0) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote"); goto scp_send_error; } else if(rc == 0) goto scp_send_empty_channel; else if(session->scpSend_response[0]) { size_t err_len; char *err_msg; err_len = _libssh2_channel_packet_data_len(session->scpSend_channel, 0); err_msg = LIBSSH2_ALLOC(session, err_len + 1); if(!err_msg) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "failed to get memory"); goto scp_send_error; } /* Read the remote error message */ rc = (int)_libssh2_channel_read(session->scpSend_channel, 0, err_msg, err_len); if(rc > 0) { err_msg[err_len] = 0; _libssh2_debug((session, LIBSSH2_TRACE_SCP, "got %02x %s", session->scpSend_response[0], err_msg)); } LIBSSH2_FREE(session, err_msg); _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "failed to send file"); goto scp_send_error; } } session->scpSend_state = libssh2_NB_state_idle; return session->scpSend_channel; scp_send_empty_channel: /* the code only jumps here as a result of a zero read from channel_read() so we check EOF status to avoid getting stuck in a loop */ if(libssh2_channel_eof(session->scpSend_channel)) { _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unexpected channel close"); } else return session->scpSend_channel; /* fall-through */ scp_send_error: tmp_err_code = session->err_code; tmp_err_msg = session->err_msg; while(libssh2_channel_free(session->scpSend_channel) == LIBSSH2_ERROR_EAGAIN); session->err_code = tmp_err_code; session->err_msg = tmp_err_msg; session->scpSend_channel = NULL; session->scpSend_state = libssh2_NB_state_idle; return NULL; } /* * libssh2_scp_send_ex * * Send a file using SCP. Old API. */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime) { LIBSSH2_CHANNEL *ptr; BLOCK_ADJUST_ERRNO(ptr, session, scp_send(session, path, mode, size, (time_t)mtime, (time_t)atime)); return ptr; } /* * libssh2_scp_send64 * * Send a file using SCP */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, libssh2_int64_t size, time_t mtime, time_t atime) { LIBSSH2_CHANNEL *ptr; BLOCK_ADJUST_ERRNO(ptr, session, scp_send(session, path, mode, size, mtime, atime)); return ptr; } libssh2-1.11.0/src/libssh2_priv.h0000644000175000017500000012322214424650606013440 00000000000000#ifndef __LIBSSH2_PRIV_H #define __LIBSSH2_PRIV_H /* Copyright (c) 2004-2008, 2010, Sara Golemon * Copyright (c) 2009-2014 by Daniel Stenberg * Copyright (c) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* Header used by 'src' */ #define LIBSSH2_LIBRARY /* platform/compiler-specific setup */ #include "libssh2_setup.h" #include #include #include #include /* The following CPP block should really only be in session.c and packet.c. However, AIX have #define's for 'events' and 'revents' and we are using those names in libssh2.h, so we need to include the AIX headers first, to make sure all code is compiled with consistent names of these fields. While arguable the best would to change libssh2.h to use other names, that would break backwards compatibility. */ #ifdef HAVE_POLL # include #elif defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H) # include #endif /* Needed for struct iovec on some platforms */ #ifdef HAVE_SYS_UIO_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #include "libssh2.h" #include "libssh2_publickey.h" #include "libssh2_sftp.h" #include "misc.h" #ifdef WIN32 /* Detect Windows App environment which has a restricted access to the Win32 APIs. */ # if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ defined(WINAPI_FAMILY) # include # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # define LIBSSH2_WINDOWS_UWP # endif # endif #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif /* Use local implementation when not available */ #if !defined(HAVE_SNPRINTF) #undef snprintf #define snprintf _libssh2_snprintf #define LIBSSH2_SNPRINTF int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...); #endif #if !defined(HAVE_GETTIMEOFDAY) #define HAVE_GETTIMEOFDAY #undef gettimeofday #define gettimeofday _libssh2_gettimeofday #define LIBSSH2_GETTIMEOFDAY int _libssh2_gettimeofday(struct timeval *tp, void *tzp); #elif defined(HAVE_SYS_TIME_H) #include #endif /* "inline" keyword is valid only with C++ engine! */ #ifdef __GNUC__ #undef inline #define inline __inline__ #elif defined(_MSC_VER) #undef inline #define inline __inline #endif /* 3DS doesn't seem to have iovec */ #if defined(WIN32) || defined(_3DS) struct iovec { size_t iov_len; void *iov_base; }; #endif #ifdef __OS400__ /* Force parameter type. */ #define send(s, b, l, f) send((s), (unsigned char *) (b), (l), (f)) #endif #include "crypto.h" #ifndef SIZE_MAX #if _WIN64 #define SIZE_MAX 0xFFFFFFFFFFFFFFFF #else #define SIZE_MAX 0xFFFFFFFF #endif #endif #ifndef UINT_MAX #define UINT_MAX 0xFFFFFFFF #endif #define LIBSSH2_MAX(x, y) ((x) > (y) ? (x) : (y)) #define LIBSSH2_MIN(x, y) ((x) < (y) ? (x) : (y)) /* RFC4253 section 6.1 Maximum Packet Length says: * * "All implementations MUST be able to process packets with * uncompressed payload length of 32768 bytes or less and * total packet size of 35000 bytes or less (including length, * padding length, payload, padding, and MAC.)." */ #define MAX_SSH_PACKET_LEN 35000 #define MAX_SHA_DIGEST_LEN SHA512_DIGEST_LENGTH #define LIBSSH2_ALLOC(session, count) \ session->alloc((count), &(session)->abstract) #define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count) #define LIBSSH2_REALLOC(session, ptr, count) \ ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \ session->alloc((count), &(session)->abstract)) #define LIBSSH2_FREE(session, ptr) \ session->free((ptr), &(session)->abstract) #define LIBSSH2_IGNORE(session, data, datalen) \ session->ssh_msg_ignore((session), (data), (int)(datalen), \ &(session)->abstract) #define LIBSSH2_DEBUG(session, always_display, message, message_len, \ language, language_len) \ session->ssh_msg_debug((session), (always_display), \ (message), (int)(message_len), \ (language), (int)(language_len), \ &(session)->abstract) #define LIBSSH2_DISCONNECT(session, reason, message, message_len, \ language, language_len) \ session->ssh_msg_disconnect((session), (reason), \ (message), (int)(message_len), \ (language), (int)(language_len), \ &(session)->abstract) #define LIBSSH2_MACERROR(session, data, datalen) \ session->macerror((session), (data), (int)(datalen), &(session)->abstract) #define LIBSSH2_X11_OPEN(channel, shost, sport) \ channel->session->x11(((channel)->session), (channel), \ (shost), (sport), (&(channel)->session->abstract)) #define LIBSSH2_AUTHAGENT(channel) \ channel->session->authagent(((channel)->session), (channel), \ (&(channel)->session->abstract)) #define LIBSSH2_ADD_IDENTITIES(session, buffer, agentPath) \ session->addLocalIdentities((session), (buffer), \ (agentPath), (&(session->abstract))) #define LIBSSH2_AUTHAGENT_SIGN(session, blob, blen, \ data, dlen, sig, sigLen, \ agentPath) \ session->agentSignCallback((session), (blob), (blen), \ (data), (dlen), (sig), (sigLen), \ (agentPath), (&(session->abstract))) #define LIBSSH2_CHANNEL_CLOSE(session, channel) \ channel->close_cb((session), &(session)->abstract, \ (channel), &(channel)->abstract) #define LIBSSH2_SEND_FD(session, fd, buffer, length, flags) \ (session->send)(fd, buffer, length, flags, &session->abstract) #define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) \ (session->recv)(fd, buffer, length, flags, &session->abstract) #define LIBSSH2_SEND(session, buffer, length, flags) \ LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags) #define LIBSSH2_RECV(session, buffer, length, flags) \ LIBSSH2_RECV_FD(session, session->socket_fd, buffer, length, flags) typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD; typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD; typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET; typedef enum { libssh2_NB_state_idle = 0, libssh2_NB_state_allocated, libssh2_NB_state_created, libssh2_NB_state_sent, libssh2_NB_state_sent1, libssh2_NB_state_sent2, libssh2_NB_state_sent3, libssh2_NB_state_sent4, libssh2_NB_state_sent5, libssh2_NB_state_sent6, libssh2_NB_state_sent7, libssh2_NB_state_jump1, libssh2_NB_state_jump2, libssh2_NB_state_jump3, libssh2_NB_state_jump4, libssh2_NB_state_jump5, libssh2_NB_state_error_closing, libssh2_NB_state_end, libssh2_NB_state_jumpauthagent } libssh2_nonblocking_states; typedef struct packet_require_state_t { libssh2_nonblocking_states state; time_t start; } packet_require_state_t; typedef struct packet_requirev_state_t { time_t start; } packet_requirev_state_t; typedef struct kmdhgGPshakex_state_t { libssh2_nonblocking_states state; unsigned char *e_packet; unsigned char *s_packet; unsigned char *tmp; unsigned char h_sig_comp[MAX_SHA_DIGEST_LEN]; unsigned char c; size_t e_packet_len; size_t s_packet_len; size_t tmp_len; _libssh2_bn_ctx *ctx; _libssh2_dh_ctx x; _libssh2_bn *e; _libssh2_bn *f; _libssh2_bn *k; unsigned char *f_value; unsigned char *k_value; unsigned char *h_sig; size_t f_value_len; size_t k_value_len; size_t h_sig_len; void *exchange_hash; packet_require_state_t req_state; libssh2_nonblocking_states burn_state; } kmdhgGPshakex_state_t; typedef struct key_exchange_state_low_t { libssh2_nonblocking_states state; packet_require_state_t req_state; kmdhgGPshakex_state_t exchange_state; _libssh2_bn *p; /* SSH2 defined value (p_value) */ _libssh2_bn *g; /* SSH2 defined value (2) */ unsigned char request[256]; /* Must fit EC_MAX_POINT_LEN + data */ unsigned char *data; size_t request_len; size_t data_len; _libssh2_ec_key *private_key; /* SSH2 ecdh private key */ unsigned char *public_key_oct; /* SSH2 ecdh public key octal value */ size_t public_key_oct_len; /* SSH2 ecdh public key octal value length */ unsigned char *curve25519_public_key; /* curve25519 public key, 32 bytes */ unsigned char *curve25519_private_key; /* curve25519 private key, 32 bytes */ } key_exchange_state_low_t; typedef struct key_exchange_state_t { libssh2_nonblocking_states state; packet_require_state_t req_state; key_exchange_state_low_t key_state_low; unsigned char *data; size_t data_len; unsigned char *oldlocal; size_t oldlocal_len; } key_exchange_state_t; #define FwdNotReq "Forward not requested" typedef struct packet_queue_listener_state_t { libssh2_nonblocking_states state; unsigned char packet[17 + (sizeof(FwdNotReq) - 1)]; unsigned char *host; unsigned char *shost; uint32_t sender_channel; uint32_t initial_window_size; uint32_t packet_size; uint32_t port; uint32_t sport; uint32_t host_len; uint32_t shost_len; LIBSSH2_CHANNEL *channel; } packet_queue_listener_state_t; #define X11FwdUnAvil "X11 Forward Unavailable" typedef struct packet_x11_open_state_t { libssh2_nonblocking_states state; unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)]; unsigned char *shost; uint32_t sender_channel; uint32_t initial_window_size; uint32_t packet_size; uint32_t sport; uint32_t shost_len; LIBSSH2_CHANNEL *channel; } packet_x11_open_state_t; #define AuthAgentUnavail "Auth Agent unavailable" typedef struct packet_authagent_state_t { libssh2_nonblocking_states state; unsigned char packet[17 + (sizeof(AuthAgentUnavail) - 1)]; uint32_t sender_channel; uint32_t initial_window_size; uint32_t packet_size; LIBSSH2_CHANNEL *channel; } packet_authagent_state_t; typedef enum { libssh2_requires_size_decryption = (1 << 0), libssh2_requires_size_field_in_packet = (1 << 1) } libssh2_crypt_flags; struct _LIBSSH2_PACKET { struct list_node node; /* linked list header */ /* the raw unencrypted payload */ unsigned char *data; size_t data_len; /* Where to start reading data from, * used for channel data that's been partially consumed */ size_t data_head; }; typedef struct _libssh2_channel_data { /* Identifier */ uint32_t id; /* Limits and restrictions */ uint32_t window_size_initial, window_size, packet_size; /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ char close, eof, extended_data_ignore_mode; } libssh2_channel_data; struct _LIBSSH2_CHANNEL { struct list_node node; unsigned char *channel_type; unsigned channel_type_len; /* channel's program exit status */ int exit_status; /* channel's program exit signal (without the SIG prefix) */ char *exit_signal; libssh2_channel_data local, remote; /* Amount of bytes to be refunded to receive window (but not yet sent) */ uint32_t adjust_queue; /* Data immediately available for reading */ size_t read_avail; LIBSSH2_SESSION *session; void *abstract; LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); /* State variables used in libssh2_channel_setenv_ex() */ libssh2_nonblocking_states setenv_state; unsigned char *setenv_packet; size_t setenv_packet_len; unsigned char setenv_local_channel[4]; packet_requirev_state_t setenv_packet_requirev_state; /* State variables used in libssh2_channel_request_pty_ex() libssh2_channel_request_pty_size_ex() */ libssh2_nonblocking_states reqPTY_state; unsigned char reqPTY_packet[41 + 256]; size_t reqPTY_packet_len; unsigned char reqPTY_local_channel[4]; packet_requirev_state_t reqPTY_packet_requirev_state; /* State variables used in libssh2_channel_x11_req_ex() */ libssh2_nonblocking_states reqX11_state; unsigned char *reqX11_packet; size_t reqX11_packet_len; unsigned char reqX11_local_channel[4]; packet_requirev_state_t reqX11_packet_requirev_state; /* State variables used in libssh2_channel_process_startup() */ libssh2_nonblocking_states process_state; unsigned char *process_packet; size_t process_packet_len; unsigned char process_local_channel[4]; packet_requirev_state_t process_packet_requirev_state; /* State variables used in libssh2_channel_flush_ex() */ libssh2_nonblocking_states flush_state; size_t flush_refund_bytes; size_t flush_flush_bytes; /* State variables used in libssh2_channel_receive_window_adjust() */ libssh2_nonblocking_states adjust_state; unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ /* State variables used in libssh2_channel_read_ex() */ libssh2_nonblocking_states read_state; uint32_t read_local_id; /* State variables used in libssh2_channel_write_ex() */ libssh2_nonblocking_states write_state; unsigned char write_packet[13]; size_t write_packet_len; size_t write_bufwrite; /* State variables used in libssh2_channel_close() */ libssh2_nonblocking_states close_state; unsigned char close_packet[5]; /* State variables used in libssh2_channel_wait_closedeof() */ libssh2_nonblocking_states wait_eof_state; /* State variables used in libssh2_channel_wait_closed() */ libssh2_nonblocking_states wait_closed_state; /* State variables used in libssh2_channel_free() */ libssh2_nonblocking_states free_state; /* State variables used in libssh2_channel_handle_extended_data2() */ libssh2_nonblocking_states extData2_state; /* State variables used in libssh2_channel_request_auth_agent() */ libssh2_nonblocking_states req_auth_agent_try_state; libssh2_nonblocking_states req_auth_agent_state; unsigned char req_auth_agent_packet[36]; size_t req_auth_agent_packet_len; unsigned char req_auth_agent_local_channel[4]; packet_requirev_state_t req_auth_agent_requirev_state; /* State variables used in libssh2_channel_signal_ex() */ libssh2_nonblocking_states sendsignal_state; unsigned char *sendsignal_packet; size_t sendsignal_packet_len; }; struct _LIBSSH2_LISTENER { struct list_node node; /* linked list header */ LIBSSH2_SESSION *session; char *host; int port; /* a list of CHANNELs for this listener */ struct list_head queue; int queue_size; int queue_maxsize; /* State variables used in libssh2_channel_forward_cancel() */ libssh2_nonblocking_states chanFwdCncl_state; unsigned char *chanFwdCncl_data; size_t chanFwdCncl_data_len; }; typedef struct _libssh2_endpoint_data { unsigned char *banner; unsigned char *kexinit; size_t kexinit_len; const LIBSSH2_CRYPT_METHOD *crypt; void *crypt_abstract; const struct _LIBSSH2_MAC_METHOD *mac; uint32_t seqno; void *mac_abstract; const LIBSSH2_COMP_METHOD *comp; void *comp_abstract; /* Method Preferences -- NULL yields "load order" */ char *crypt_prefs; char *mac_prefs; char *comp_prefs; char *lang_prefs; } libssh2_endpoint_data; #define PACKETBUFSIZE MAX_SSH_PACKET_LEN struct transportpacket { /* ------------- for incoming data --------------- */ unsigned char buf[PACKETBUFSIZE]; unsigned char init[5]; /* first 5 bytes of the incoming data stream, still encrypted */ size_t writeidx; /* at what array index we do the next write into the buffer */ size_t readidx; /* at what array index we do the next read from the buffer */ uint32_t packet_length; /* the most recent packet_length as read from the network data */ uint8_t padding_length; /* the most recent padding_length as read from the network data */ size_t data_num; /* How much of the total package that has been read so far. */ size_t total_num; /* How much a total package is supposed to be, in number of bytes. A full package is packet_length + padding_length + 4 + mac_length. */ unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC() area to which we write incoming packet data which is not yet decrypted in etm mode. */ unsigned char *wptr; /* write pointer into the payload to where we are currently writing decrypted data */ /* ------------- for outgoing data --------------- */ unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* area for the outgoing data */ ssize_t ototal_num; /* size of outbuf in number of bytes */ const unsigned char *odata; /* original pointer to the data */ size_t olen; /* original size of the data we stored in outbuf */ size_t osent; /* number of bytes already sent */ }; struct _LIBSSH2_PUBLICKEY { LIBSSH2_CHANNEL *channel; uint32_t version; /* State variables used in libssh2_publickey_packet_receive() */ libssh2_nonblocking_states receive_state; unsigned char *receive_packet; size_t receive_packet_len; /* State variables used in libssh2_publickey_add_ex() */ libssh2_nonblocking_states add_state; unsigned char *add_packet; unsigned char *add_s; /* State variables used in libssh2_publickey_remove_ex() */ libssh2_nonblocking_states remove_state; unsigned char *remove_packet; unsigned char *remove_s; /* State variables used in libssh2_publickey_list_fetch() */ libssh2_nonblocking_states listFetch_state; unsigned char *listFetch_s; unsigned char listFetch_buffer[12]; unsigned char *listFetch_data; size_t listFetch_data_len; }; #define LIBSSH2_SCP_RESPONSE_BUFLEN 256 struct flags { int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ int compress; /* LIBSSH2_FLAG_COMPRESS */ int quote_paths; /* LIBSSH2_FLAG_QUOTE_PATHS */ }; struct _LIBSSH2_SESSION { /* Memory management callbacks */ void *abstract; LIBSSH2_ALLOC_FUNC((*alloc)); LIBSSH2_REALLOC_FUNC((*realloc)); LIBSSH2_FREE_FUNC((*free)); /* Other callbacks */ LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore)); LIBSSH2_DEBUG_FUNC((*ssh_msg_debug)); LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect)); LIBSSH2_MACERROR_FUNC((*macerror)); LIBSSH2_X11_OPEN_FUNC((*x11)); LIBSSH2_AUTHAGENT_FUNC((*authagent)); LIBSSH2_ADD_IDENTITIES_FUNC((*addLocalIdentities)); LIBSSH2_AUTHAGENT_SIGN_FUNC((*agentSignCallback)); LIBSSH2_SEND_FUNC((*send)); LIBSSH2_RECV_FUNC((*recv)); /* Method preferences -- NULL yields "load order" */ char *kex_prefs; char *hostkey_prefs; int state; /* Flag options */ struct flags flag; /* Agreed Key Exchange Method */ const LIBSSH2_KEX_METHOD *kex; unsigned int burn_optimistic_kexinit; unsigned char *session_id; uint32_t session_id_len; /* this is set to TRUE if a blocking API behavior is requested */ int api_block_mode; /* Timeout used when blocking API behavior is active */ long api_timeout; /* Server's public key */ const LIBSSH2_HOSTKEY_METHOD *hostkey; void *server_hostkey_abstract; /* Either set with libssh2_session_hostkey() (for server mode) * Or read from server in (eg) KEXDH_INIT (for client mode) */ unsigned char *server_hostkey; uint32_t server_hostkey_len; #if LIBSSH2_MD5 unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; int server_hostkey_md5_valid; #endif /* ! LIBSSH2_MD5 */ unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; int server_hostkey_sha1_valid; unsigned char server_hostkey_sha256[SHA256_DIGEST_LENGTH]; int server_hostkey_sha256_valid; /* public key algorithms accepted as comma separated list */ char *server_sign_algorithms; /* key signing algorithm preferences -- NULL yields server order */ char *sign_algo_prefs; /* (remote as source of data -- packet_read ) */ libssh2_endpoint_data remote; /* (local as source of data -- packet_write ) */ libssh2_endpoint_data local; /* Inbound Data linked list -- Sometimes the packet that comes in isn't the packet we're ready for */ struct list_head packets; /* Active connection channels */ struct list_head channels; uint32_t next_channel; struct list_head listeners; /* list of LIBSSH2_LISTENER structs */ /* Actual I/O socket */ libssh2_socket_t socket_fd; int socket_state; int socket_block_directions; int socket_prev_blockstate; /* stores the state of the socket blockiness when libssh2_session_startup() is called */ /* Error tracking */ const char *err_msg; int err_code; int err_flags; /* struct members for packet-level reading */ struct transportpacket packet; #ifdef LIBSSH2DEBUG int showmask; /* what debug/trace messages to display */ libssh2_trace_handler_func tracehandler; /* callback to display trace messages */ void *tracehandler_context; /* context for the trace handler */ #endif /* State variables used in libssh2_banner_send() */ libssh2_nonblocking_states banner_TxRx_state; char banner_TxRx_banner[256]; ssize_t banner_TxRx_total_send; /* State variables used in libssh2_kexinit() */ libssh2_nonblocking_states kexinit_state; unsigned char *kexinit_data; size_t kexinit_data_len; /* State variables used in libssh2_session_startup() */ libssh2_nonblocking_states startup_state; unsigned char *startup_data; size_t startup_data_len; unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1]; size_t startup_service_length; packet_require_state_t startup_req_state; key_exchange_state_t startup_key_state; /* State variables used in libssh2_session_free() */ libssh2_nonblocking_states free_state; /* State variables used in libssh2_session_disconnect_ex() */ libssh2_nonblocking_states disconnect_state; unsigned char disconnect_data[256 + 13]; size_t disconnect_data_len; /* State variables used in libssh2_packet_read() */ libssh2_nonblocking_states readPack_state; int readPack_encrypted; /* State variables used in libssh2_userauth_list() */ libssh2_nonblocking_states userauth_list_state; unsigned char *userauth_list_data; size_t userauth_list_data_len; char *userauth_banner; packet_requirev_state_t userauth_list_packet_requirev_state; /* State variables used in libssh2_userauth_password_ex() */ libssh2_nonblocking_states userauth_pswd_state; unsigned char *userauth_pswd_data; unsigned char userauth_pswd_data0; size_t userauth_pswd_data_len; char *userauth_pswd_newpw; int userauth_pswd_newpw_len; packet_requirev_state_t userauth_pswd_packet_requirev_state; /* State variables used in libssh2_userauth_hostbased_fromfile_ex() */ libssh2_nonblocking_states userauth_host_state; unsigned char *userauth_host_data; size_t userauth_host_data_len; unsigned char *userauth_host_packet; size_t userauth_host_packet_len; unsigned char *userauth_host_method; size_t userauth_host_method_len; unsigned char *userauth_host_s; packet_requirev_state_t userauth_host_packet_requirev_state; /* State variables used in libssh2_userauth_publickey_fromfile_ex() */ libssh2_nonblocking_states userauth_pblc_state; unsigned char *userauth_pblc_data; size_t userauth_pblc_data_len; unsigned char *userauth_pblc_packet; size_t userauth_pblc_packet_len; unsigned char *userauth_pblc_method; size_t userauth_pblc_method_len; unsigned char *userauth_pblc_s; unsigned char *userauth_pblc_b; packet_requirev_state_t userauth_pblc_packet_requirev_state; /* State variables used in libssh2_userauth_keyboard_interactive_ex() */ libssh2_nonblocking_states userauth_kybd_state; unsigned char *userauth_kybd_data; size_t userauth_kybd_data_len; unsigned char *userauth_kybd_packet; size_t userauth_kybd_packet_len; size_t userauth_kybd_auth_name_len; unsigned char *userauth_kybd_auth_name; size_t userauth_kybd_auth_instruction_len; unsigned char *userauth_kybd_auth_instruction; unsigned int userauth_kybd_num_prompts; int userauth_kybd_auth_failure; LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts; LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses; packet_requirev_state_t userauth_kybd_packet_requirev_state; /* State variables used in libssh2_channel_open_ex() */ libssh2_nonblocking_states open_state; packet_requirev_state_t open_packet_requirev_state; LIBSSH2_CHANNEL *open_channel; unsigned char *open_packet; size_t open_packet_len; unsigned char *open_data; size_t open_data_len; uint32_t open_local_channel; /* State variables used in libssh2_channel_direct_tcpip_ex() */ libssh2_nonblocking_states direct_state; unsigned char *direct_message; size_t direct_host_len; size_t direct_shost_len; size_t direct_message_len; /* State variables used in libssh2_channel_forward_listen_ex() */ libssh2_nonblocking_states fwdLstn_state; unsigned char *fwdLstn_packet; uint32_t fwdLstn_host_len; uint32_t fwdLstn_packet_len; packet_requirev_state_t fwdLstn_packet_requirev_state; /* State variables used in libssh2_publickey_init() */ libssh2_nonblocking_states pkeyInit_state; LIBSSH2_PUBLICKEY *pkeyInit_pkey; LIBSSH2_CHANNEL *pkeyInit_channel; unsigned char *pkeyInit_data; size_t pkeyInit_data_len; /* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */ unsigned char pkeyInit_buffer[19]; size_t pkeyInit_buffer_sent; /* how much of buffer that has been sent */ /* State variables used in libssh2_packet_add() */ libssh2_nonblocking_states packAdd_state; LIBSSH2_CHANNEL *packAdd_channelp; /* keeper of the channel during EAGAIN states */ packet_queue_listener_state_t packAdd_Qlstn_state; packet_x11_open_state_t packAdd_x11open_state; packet_authagent_state_t packAdd_authagent_state; /* State variables used in fullpacket() */ libssh2_nonblocking_states fullpacket_state; int fullpacket_macstate; size_t fullpacket_payload_len; int fullpacket_packet_type; /* State variables used in libssh2_sftp_init() */ libssh2_nonblocking_states sftpInit_state; LIBSSH2_SFTP *sftpInit_sftp; LIBSSH2_CHANNEL *sftpInit_channel; unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + version_id(4) */ size_t sftpInit_sent; /* number of bytes from the buffer that have been sent */ /* State variables used in libssh2_scp_recv() / libssh_scp_recv2() */ libssh2_nonblocking_states scpRecv_state; unsigned char *scpRecv_command; size_t scpRecv_command_len; unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; size_t scpRecv_response_len; long scpRecv_mode; libssh2_int64_t scpRecv_size; long scpRecv_mtime; long scpRecv_atime; LIBSSH2_CHANNEL *scpRecv_channel; /* State variables used in libssh2_scp_send_ex() */ libssh2_nonblocking_states scpSend_state; unsigned char *scpSend_command; size_t scpSend_command_len; unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; size_t scpSend_response_len; LIBSSH2_CHANNEL *scpSend_channel; /* Keepalive variables used by keepalive.c. */ int keepalive_interval; int keepalive_want_reply; time_t keepalive_last_sent; /* Configurable timeout for packets. Replaces LIBSSH2_READ_TIMEOUT */ long packet_read_timeout; }; /* session.state bits */ #define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 #define LIBSSH2_STATE_NEWKEYS 0x00000002 #define LIBSSH2_STATE_AUTHENTICATED 0x00000004 #define LIBSSH2_STATE_KEX_ACTIVE 0x00000008 /* session.flag helpers */ #ifdef MSG_NOSIGNAL #define LIBSSH2_SOCKET_SEND_FLAGS(session) \ (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) #define LIBSSH2_SOCKET_RECV_FLAGS(session) \ (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) #else /* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */ #define LIBSSH2_SOCKET_SEND_FLAGS(session) 0 #define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 #endif /* --------- */ /* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */ struct _LIBSSH2_KEX_METHOD { const char *name; /* Key exchange, populates session->* and returns 0 on success, non-0 on error */ int (*exchange_keys) (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state); long flags; }; struct _LIBSSH2_HOSTKEY_METHOD { const char *name; unsigned long hash_len; int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data, size_t hostkey_data_len, void **abstract); int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile, unsigned const char *passphrase, void **abstract); int (*initPEMFromMemory) (LIBSSH2_SESSION * session, const char *privkeyfiledata, size_t privkeyfiledata_len, unsigned const char *passphrase, void **abstract); int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract); int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract); int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst, size_t *dst_len, const unsigned char *src, size_t src_len, void **abstract); int (*dtor) (LIBSSH2_SESSION * session, void **abstract); }; struct _LIBSSH2_CRYPT_METHOD { const char *name; const char *pem_annotation; int blocksize; /* iv and key sizes (-1 for variable length) */ int iv_len; int secret_len; long flags; int (*init) (LIBSSH2_SESSION * session, const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract); int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block, size_t blocksize, void **abstract, int firstlast); int (*dtor) (LIBSSH2_SESSION * session, void **abstract); _libssh2_cipher_type(algo); }; /* Bit flags for _LIBSSH2_CRYPT_METHOD */ /* Crypto method has integrated message authentication */ #define LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC 1 /* Crypto method does not encrypt the packet length */ #define LIBSSH2_CRYPT_FLAG_PKTLEN_AAD 2 /* Convenience macros for accessing crypt flags */ /* Local crypto flags */ #define CRYPT_FLAG_L(session, flag) ((session)->local.crypt && \ ((session)->local.crypt->flags & LIBSSH2_CRYPT_FLAG_##flag)) /* Remote crypto flags */ #define CRYPT_FLAG_R(session, flag) ((session)->remote.crypt && \ ((session)->remote.crypt->flags & LIBSSH2_CRYPT_FLAG_##flag)) /* Values for firstlast */ #define FIRST_BLOCK 1 #define MIDDLE_BLOCK 0 #define LAST_BLOCK 2 /* Convenience macros for accessing firstlast */ #define IS_FIRST(firstlast) (firstlast & FIRST_BLOCK) #define IS_LAST(firstlast) (firstlast & LAST_BLOCK) struct _LIBSSH2_COMP_METHOD { const char *name; int compress; /* 1 if it does compress, 0 if it doesn't */ int use_in_auth; /* 1 if compression should be used in userauth */ int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract); int (*comp) (LIBSSH2_SESSION *session, unsigned char *dest, size_t *dest_len, const unsigned char *src, size_t src_len, void **abstract); int (*decomp) (LIBSSH2_SESSION *session, unsigned char **dest, size_t *dest_len, size_t payload_limit, const unsigned char *src, size_t src_len, void **abstract); int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract); }; #ifdef LIBSSH2DEBUG void _libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format, ...); #define _libssh2_debug(x) _libssh2_debug_low x #else #define _libssh2_debug(x) do {} while(0) #endif #define LIBSSH2_SOCKET_UNKNOWN 1 #define LIBSSH2_SOCKET_CONNECTED 0 #define LIBSSH2_SOCKET_DISCONNECTED -1 /* Initial packet state, prior to MAC check */ #define LIBSSH2_MAC_UNCONFIRMED 1 /* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */ #define LIBSSH2_MAC_CONFIRMED 0 /* Something very bad is going on */ #define LIBSSH2_MAC_INVALID -1 /* Flags for _libssh2_error_flags */ /* Error message is allocated on the heap */ #define LIBSSH2_ERR_FLAG_DUP 1 /* SSH Packet Types -- Defined by internet draft */ /* Transport Layer */ #define SSH_MSG_DISCONNECT 1 #define SSH_MSG_IGNORE 2 #define SSH_MSG_UNIMPLEMENTED 3 #define SSH_MSG_DEBUG 4 #define SSH_MSG_SERVICE_REQUEST 5 #define SSH_MSG_SERVICE_ACCEPT 6 #define SSH_MSG_EXT_INFO 7 #define SSH_MSG_KEXINIT 20 #define SSH_MSG_NEWKEYS 21 /* diffie-hellman-group1-sha1 */ #define SSH_MSG_KEXDH_INIT 30 #define SSH_MSG_KEXDH_REPLY 31 /* diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256 */ #define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 #define SSH_MSG_KEX_DH_GEX_REQUEST 34 #define SSH_MSG_KEX_DH_GEX_GROUP 31 #define SSH_MSG_KEX_DH_GEX_INIT 32 #define SSH_MSG_KEX_DH_GEX_REPLY 33 /* ecdh */ #define SSH2_MSG_KEX_ECDH_INIT 30 #define SSH2_MSG_KEX_ECDH_REPLY 31 /* User Authentication */ #define SSH_MSG_USERAUTH_REQUEST 50 #define SSH_MSG_USERAUTH_FAILURE 51 #define SSH_MSG_USERAUTH_SUCCESS 52 #define SSH_MSG_USERAUTH_BANNER 53 /* "public key" method */ #define SSH_MSG_USERAUTH_PK_OK 60 /* "password" method */ #define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 /* "keyboard-interactive" method */ #define SSH_MSG_USERAUTH_INFO_REQUEST 60 #define SSH_MSG_USERAUTH_INFO_RESPONSE 61 /* Channels */ #define SSH_MSG_GLOBAL_REQUEST 80 #define SSH_MSG_REQUEST_SUCCESS 81 #define SSH_MSG_REQUEST_FAILURE 82 #define SSH_MSG_CHANNEL_OPEN 90 #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 #define SSH_MSG_CHANNEL_OPEN_FAILURE 92 #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 #define SSH_MSG_CHANNEL_DATA 94 #define SSH_MSG_CHANNEL_EXTENDED_DATA 95 #define SSH_MSG_CHANNEL_EOF 96 #define SSH_MSG_CHANNEL_CLOSE 97 #define SSH_MSG_CHANNEL_REQUEST 98 #define SSH_MSG_CHANNEL_SUCCESS 99 #define SSH_MSG_CHANNEL_FAILURE 100 /* Error codes returned in SSH_MSG_CHANNEL_OPEN_FAILURE message (see RFC4254) */ #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1 #define SSH_OPEN_CONNECT_FAILED 2 #define SSH_OPEN_UNKNOWN_CHANNELTYPE 3 #define SSH_OPEN_RESOURCE_SHORTAGE 4 ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags, void **abstract); ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags, void **abstract); #define LIBSSH2_DEFAULT_READ_TIMEOUT 60 /* generic timeout in seconds used when waiting for more data to arrive */ int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, key_exchange_state_t * state); /* Let crypt.c/hostkey.c expose their method structs */ const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void); int _libssh2_bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen, uint8_t *key, size_t keylen, unsigned int rounds); /* pem.c */ int _libssh2_pem_parse(LIBSSH2_SESSION * session, const char *headerbegin, const char *headerend, const unsigned char *passphrase, FILE * fp, unsigned char **data, size_t *datalen); int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session, const char *headerbegin, const char *headerend, const char *filedata, size_t filedata_len, unsigned char **data, size_t *datalen); /* OpenSSL keys */ int _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session, const unsigned char *passphrase, FILE * fp, struct string_buf **decrypted_buf); int _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session, const unsigned char *passphrase, const char *filedata, size_t filedata_len, struct string_buf **decrypted_buf); int _libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen); int _libssh2_pem_decode_integer(unsigned char **data, size_t *datalen, unsigned char **i, unsigned int *ilen); /* global.c */ void _libssh2_init_if_needed(void); /* Utility function for certificate auth */ size_t plain_method(char *method, size_t method_len); #define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0])) /* define to output the libssh2_int64_t type in a *printf() */ #if defined(__BORLANDC__) || defined(_MSC_VER) #define LIBSSH2_INT64_T_FORMAT "I64d" #else #define LIBSSH2_INT64_T_FORMAT "lld" #endif /* In Windows the default file mode is text but an application can override it. Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 */ #if defined(WIN32) || defined(MSDOS) #define FOPEN_READTEXT "rt" #define FOPEN_WRITETEXT "wt" #define FOPEN_APPENDTEXT "at" #elif defined(__CYGWIN__) /* Cygwin has specific behavior we need to address when WIN32 is not defined. https://cygwin.com/cygwin-ug-net/using-textbinary.html For write we want our output to have line endings of LF and be compatible with other Cygwin utilities. For read we want to handle input that may have line endings either CRLF or LF so 't' is appropriate. */ #define FOPEN_READTEXT "rt" #define FOPEN_WRITETEXT "w" #define FOPEN_APPENDTEXT "a" #else #define FOPEN_READTEXT "r" #define FOPEN_WRITETEXT "w" #define FOPEN_APPENDTEXT "a" #endif #endif /* __LIBSSH2_PRIV_H */ libssh2-1.11.0/src/crypto.c0000644000175000017500000000053514432741311012337 00000000000000#define LIBSSH2_CRYPTO_C #include "libssh2_priv.h" #if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL) #include "openssl.c" #elif defined(LIBSSH2_LIBGCRYPT) #include "libgcrypt.c" #elif defined(LIBSSH2_MBEDTLS) #include "mbedtls.c" #elif defined(LIBSSH2_OS400QC3) #include "os400qc3.c" #elif defined(LIBSSH2_WINCNG) #include "wincng.c" #endif libssh2-1.11.0/src/publickey.c0000644000175000017500000013426114432741311013012 00000000000000/* Copyright (c) 2004-2007, Sara Golemon * Copyright (c) 2010-2014 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "libssh2_publickey.h" #include "channel.h" #include "session.h" #define LIBSSH2_PUBLICKEY_VERSION 2 /* Numericised response codes -- Not IETF, just local representation */ #define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0 #define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 #define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST { int code; const char *name; int name_len; } LIBSSH2_PUBLICKEY_CODE_LIST; static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] = { {LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}, {LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}, {LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1}, {0, NULL, 0} }; /* PUBLICKEY status codes -- IETF defined */ #define LIBSSH2_PUBLICKEY_SUCCESS 0 #define LIBSSH2_PUBLICKEY_ACCESS_DENIED 1 #define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED 2 #define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3 #define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND 4 #define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED 5 #define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT 6 #define LIBSSH2_PUBLICKEY_GENERAL_FAILURE 7 #define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8 #define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = { {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1}, {LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", sizeof("access denied") - 1}, {LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", sizeof("storage exceeded") - 1}, {LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", sizeof("version not supported") - 1}, {LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", sizeof("key not found") - 1}, {LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", sizeof("key not supported") - 1}, {LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", sizeof("key already present") - 1}, {LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", sizeof("general failure") - 1}, {LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", sizeof("request not supported") - 1}, {0, NULL, 0} }; /* * publickey_status_error * * Format an error message from a status code */ static void publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, unsigned long status) { const char *msg; /* GENERAL_FAILURE got remapped between version 1 and 2 */ if(status == 6 && pkey && pkey->version == 1) { status = 7; } if(status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { msg = "unknown"; } else { msg = publickey_status_codes[status].name; } _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, msg); } /* * publickey_packet_receive * * Read a packet from the subsystem */ static int publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey, unsigned char **data, size_t *data_len) { LIBSSH2_CHANNEL *channel = pkey->channel; LIBSSH2_SESSION *session = channel->session; unsigned char buffer[4]; ssize_t rc; *data = NULL; /* default to nothing returned */ *data_len = 0; if(pkey->receive_state == libssh2_NB_state_idle) { rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if(rc != 4) { return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem"); } pkey->receive_packet_len = _libssh2_ntohu32(buffer); pkey->receive_packet = LIBSSH2_ALLOC(session, pkey->receive_packet_len); if(!pkey->receive_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate publickey response " "buffer"); } pkey->receive_state = libssh2_NB_state_sent; } if(pkey->receive_state == libssh2_NB_state_sent) { rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet, pkey->receive_packet_len); if(rc == LIBSSH2_ERROR_EAGAIN) { return (int)rc; } else if(rc != (ssize_t)pkey->receive_packet_len) { LIBSSH2_FREE(session, pkey->receive_packet); pkey->receive_packet = NULL; pkey->receive_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem " "response packet"); } *data = pkey->receive_packet; *data_len = pkey->receive_packet_len; } pkey->receive_state = libssh2_NB_state_idle; return 0; } /* publickey_response_id * * Translate a string response name to a numeric code * Data will be incremented by 4 + response_len on success only */ static int publickey_response_id(unsigned char **pdata, size_t data_len) { size_t response_len; unsigned char *data = *pdata; const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes; if(data_len < 4) { /* Malformed response */ return -1; } response_len = _libssh2_ntohu32(data); data += 4; data_len -= 4; if(data_len < response_len) { /* Malformed response */ return -1; } while(codes->name) { if((unsigned long)codes->name_len == response_len && strncmp(codes->name, (char *) data, response_len) == 0) { *pdata = data + response_len; return codes->code; } codes++; } return -1; } /* publickey_response_success * * Generic helper routine to wait for success response and nothing else */ static int publickey_response_success(LIBSSH2_PUBLICKEY * pkey) { LIBSSH2_SESSION *session = pkey->channel->session; unsigned char *data, *s; size_t data_len; int response; for(;;) { int rc = publickey_packet_receive(pkey, &data, &data_len); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from " "publickey subsystem"); } if(data_len < 4) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Publickey response too small"); } s = data; response = publickey_response_id(&s, data_len); switch(response) { case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: /* Error, or processing complete */ { unsigned long status = 0; if(data_len < 8) { return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Publickey response too small"); } status = _libssh2_ntohu32(s); LIBSSH2_FREE(session, data); if(status == LIBSSH2_PUBLICKEY_SUCCESS) return 0; publickey_status_error(pkey, session, status); goto err_exit; } default: LIBSSH2_FREE(session, data); if(response < 0) { return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response"); } /* Unknown/Unexpected */ _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response"); data = NULL; } } err_exit: return -1; } /* ***************** * Publickey API * ***************** */ /* * publickey_init * * Startup the publickey subsystem */ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session) { int response; int rc; if(session->pkeyInit_state == libssh2_NB_state_idle) { session->pkeyInit_data = NULL; session->pkeyInit_pkey = NULL; session->pkeyInit_channel = NULL; _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Initializing publickey subsystem")); session->pkeyInit_state = libssh2_NB_state_allocated; } if(session->pkeyInit_state == libssh2_NB_state_allocated) { session->pkeyInit_channel = _libssh2_channel_open(session, "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if(!session->pkeyInit_channel) { if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) /* The error state is already set, so leave it */ return NULL; _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel"); goto err_exit; } session->pkeyInit_state = libssh2_NB_state_sent; } if(session->pkeyInit_state == libssh2_NB_state_sent) { rc = _libssh2_channel_process_startup(session->pkeyInit_channel, "subsystem", sizeof("subsystem") - 1, "publickey", sizeof("publickey") - 1); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting publickey subsystem"); return NULL; } else if(rc) { _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem"); goto err_exit; } session->pkeyInit_state = libssh2_NB_state_sent1; } if(session->pkeyInit_state == libssh2_NB_state_sent1) { unsigned char *s; rc = _libssh2_channel_extended_data(session->pkeyInit_channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting publickey subsystem"); return NULL; } session->pkeyInit_pkey = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); if(!session->pkeyInit_pkey) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new publickey structure"); goto err_exit; } session->pkeyInit_pkey->channel = session->pkeyInit_channel; session->pkeyInit_pkey->version = 0; s = session->pkeyInit_buffer; _libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); s += 4; _libssh2_htonu32(s, sizeof("version") - 1); s += 4; memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1; _libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); session->pkeyInit_buffer_sent = 0; _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Sending publickey advertising version %d support", (int) LIBSSH2_PUBLICKEY_VERSION)); session->pkeyInit_state = libssh2_NB_state_sent2; } if(session->pkeyInit_state == libssh2_NB_state_sent2) { ssize_t nwritten; nwritten = _libssh2_channel_write(session->pkeyInit_channel, 0, session->pkeyInit_buffer, 19 - session->pkeyInit_buffer_sent); if(nwritten == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending publickey version packet"); return NULL; } else if(nwritten < 0) { _libssh2_error(session, (int)nwritten, "Unable to send publickey version packet"); goto err_exit; } session->pkeyInit_buffer_sent += nwritten; if(session->pkeyInit_buffer_sent < 19) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Need to be called again to complete this"); return NULL; } session->pkeyInit_state = libssh2_NB_state_sent3; } if(session->pkeyInit_state == libssh2_NB_state_sent3) { for(;;) { unsigned char *s; rc = publickey_packet_receive(session->pkeyInit_pkey, &session->pkeyInit_data, &session->pkeyInit_data_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from " "publickey subsystem"); return NULL; } else if(rc) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from " "publickey subsystem"); goto err_exit; } s = session->pkeyInit_data; if((response = publickey_response_id(&s, session->pkeyInit_data_len)) < 0) { _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code"); goto err_exit; } if(session->pkeyInit_data_len < 4) { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Public key init data too small"); goto err_exit; } switch(response) { case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: /* Error */ { unsigned long status, descr_len, lang_len; if(session->pkeyInit_data_len >= 8) { status = _libssh2_ntohu32(s); s += 4; descr_len = _libssh2_ntohu32(s); s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Public key init data too small"); goto err_exit; } if(s + descr_len + 4 <= session->pkeyInit_data + session->pkeyInit_data_len) { /* description starts here */ s += descr_len; lang_len = _libssh2_ntohu32(s); s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Public key init data too small"); goto err_exit; } if(s + lang_len <= session->pkeyInit_data + session->pkeyInit_data_len) { /* lang starts here */ s += lang_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Public key init data too small"); goto err_exit; } if(s > session->pkeyInit_data + session->pkeyInit_data_len) { _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet"); goto err_exit; } publickey_status_error(NULL, session, status); goto err_exit; } case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: /* What we want */ session->pkeyInit_pkey->version = _libssh2_ntohu32(s); if(session->pkeyInit_pkey->version > LIBSSH2_PUBLICKEY_VERSION) { _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Truncate remote publickey version " "from %lu", session->pkeyInit_pkey->version)); session->pkeyInit_pkey->version = LIBSSH2_PUBLICKEY_VERSION; } _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Enabling publickey subsystem version %lu", session->pkeyInit_pkey->version)); LIBSSH2_FREE(session, session->pkeyInit_data); session->pkeyInit_data = NULL; session->pkeyInit_state = libssh2_NB_state_idle; return session->pkeyInit_pkey; default: /* Unknown/Unexpected */ _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, " "ignoring"); LIBSSH2_FREE(session, session->pkeyInit_data); session->pkeyInit_data = NULL; } } } /* Never reached except by direct goto */ err_exit: session->pkeyInit_state = libssh2_NB_state_sent4; if(session->pkeyInit_channel) { rc = _libssh2_channel_close(session->pkeyInit_channel); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block closing channel"); return NULL; } } if(session->pkeyInit_pkey) { LIBSSH2_FREE(session, session->pkeyInit_pkey); session->pkeyInit_pkey = NULL; } if(session->pkeyInit_data) { LIBSSH2_FREE(session, session->pkeyInit_data); session->pkeyInit_data = NULL; } session->pkeyInit_state = libssh2_NB_state_idle; return NULL; } /* * libssh2_publickey_init * * Startup the publickey subsystem */ LIBSSH2_API LIBSSH2_PUBLICKEY * libssh2_publickey_init(LIBSSH2_SESSION *session) { LIBSSH2_PUBLICKEY *ptr; BLOCK_ADJUST_ERRNO(ptr, session, publickey_init(session)); return ptr; } /* * libssh2_publickey_add_ex * * Add a new public key entry */ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len, char overwrite, unsigned long num_attrs, const libssh2_publickey_attribute attrs[]) { LIBSSH2_CHANNEL *channel; LIBSSH2_SESSION *session; /* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} blob_len(4) + {blob} */ unsigned long i, packet_len = 19 + name_len + blob_len; unsigned char *comment = NULL; unsigned long comment_len = 0; int rc; if(!pkey) return LIBSSH2_ERROR_BAD_USE; channel = pkey->channel; session = channel->session; if(pkey->add_state == libssh2_NB_state_idle) { pkey->add_packet = NULL; _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey", name)); if(pkey->version == 1) { for(i = 0; i < num_attrs; i++) { /* Search for a comment attribute */ if(attrs[i].name_len == (sizeof("comment") - 1) && strncmp(attrs[i].name, "comment", sizeof("comment") - 1) == 0) { comment = (unsigned char *) attrs[i].value; comment_len = attrs[i].value_len; break; } } packet_len += 4 + comment_len; } else { packet_len += 5; /* overwrite(1) + attribute_count(4) */ for(i = 0; i < num_attrs; i++) { packet_len += 9 + attrs[i].name_len + attrs[i].value_len; /* name_len(4) + value_len(4) + mandatory(1) */ } } pkey->add_packet = LIBSSH2_ALLOC(session, packet_len); if(!pkey->add_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "publickey \"add\" packet"); } pkey->add_s = pkey->add_packet; _libssh2_htonu32(pkey->add_s, (uint32_t)(packet_len - 4)); pkey->add_s += 4; _libssh2_htonu32(pkey->add_s, sizeof("add") - 1); pkey->add_s += 4; memcpy(pkey->add_s, "add", sizeof("add") - 1); pkey->add_s += sizeof("add") - 1; if(pkey->version == 1) { _libssh2_htonu32(pkey->add_s, (uint32_t)comment_len); pkey->add_s += 4; if(comment) { memcpy(pkey->add_s, comment, comment_len); pkey->add_s += comment_len; } _libssh2_htonu32(pkey->add_s, (uint32_t)name_len); pkey->add_s += 4; memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len; _libssh2_htonu32(pkey->add_s, (uint32_t)blob_len); pkey->add_s += 4; memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len; } else { /* Version == 2 */ _libssh2_htonu32(pkey->add_s, (uint32_t)name_len); pkey->add_s += 4; memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len; _libssh2_htonu32(pkey->add_s, (uint32_t)blob_len); pkey->add_s += 4; memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len; *(pkey->add_s++) = overwrite ? 0x01 : 0; _libssh2_htonu32(pkey->add_s, (uint32_t)num_attrs); pkey->add_s += 4; for(i = 0; i < num_attrs; i++) { _libssh2_htonu32(pkey->add_s, (uint32_t)attrs[i].name_len); pkey->add_s += 4; memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); pkey->add_s += attrs[i].name_len; _libssh2_htonu32(pkey->add_s, (uint32_t)attrs[i].value_len); pkey->add_s += 4; memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); pkey->add_s += attrs[i].value_len; *(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0; } } _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Sending publickey \"add\" packet: " "type=%s blob_len=%ld num_attrs=%ld", name, blob_len, num_attrs)); pkey->add_state = libssh2_NB_state_created; } if(pkey->add_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, pkey->add_packet, (pkey->add_s - pkey->add_packet)); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if((pkey->add_s - pkey->add_packet) != nwritten) { LIBSSH2_FREE(session, pkey->add_packet); pkey->add_packet = NULL; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet"); } LIBSSH2_FREE(session, pkey->add_packet); pkey->add_packet = NULL; pkey->add_state = libssh2_NB_state_sent; } rc = publickey_response_success(pkey); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } pkey->add_state = libssh2_NB_state_idle; return rc; } /* libssh2_publickey_remove_ex * Remove an existing publickey so that authentication can no longer be * performed using it */ LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len) { LIBSSH2_CHANNEL *channel; LIBSSH2_SESSION *session; /* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + blob_len(4) + {blob} */ unsigned long packet_len = 22 + name_len + blob_len; int rc; if(!pkey) return LIBSSH2_ERROR_BAD_USE; channel = pkey->channel; session = channel->session; if(pkey->remove_state == libssh2_NB_state_idle) { pkey->remove_packet = NULL; pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len); if(!pkey->remove_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "publickey \"remove\" packet"); } pkey->remove_s = pkey->remove_packet; _libssh2_htonu32(pkey->remove_s, (uint32_t)(packet_len - 4)); pkey->remove_s += 4; _libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); pkey->remove_s += 4; memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); pkey->remove_s += sizeof("remove") - 1; _libssh2_htonu32(pkey->remove_s, (uint32_t)name_len); pkey->remove_s += 4; memcpy(pkey->remove_s, name, name_len); pkey->remove_s += name_len; _libssh2_htonu32(pkey->remove_s, (uint32_t)blob_len); pkey->remove_s += 4; memcpy(pkey->remove_s, blob, blob_len); pkey->remove_s += blob_len; _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Sending publickey \"remove\" packet: " "type=%s blob_len=%ld", name, blob_len)); pkey->remove_state = libssh2_NB_state_created; } if(pkey->remove_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, pkey->remove_packet, (pkey->remove_s - pkey->remove_packet)); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if((pkey->remove_s - pkey->remove_packet) != nwritten) { LIBSSH2_FREE(session, pkey->remove_packet); pkey->remove_packet = NULL; pkey->remove_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet"); } LIBSSH2_FREE(session, pkey->remove_packet); pkey->remove_packet = NULL; pkey->remove_state = libssh2_NB_state_sent; } rc = publickey_response_success(pkey); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } pkey->remove_state = libssh2_NB_state_idle; return rc; } /* libssh2_publickey_list_fetch * Fetch a list of supported public key from a server */ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys, libssh2_publickey_list ** pkey_list) { LIBSSH2_CHANNEL *channel; LIBSSH2_SESSION *session; libssh2_publickey_list *list = NULL; unsigned long buffer_len = 12, keys = 0, max_keys = 0, i; /* 12 = packet_len(4) + list_len(4) + "list"(4) */ int response; int rc; if(!pkey) return LIBSSH2_ERROR_BAD_USE; channel = pkey->channel; session = channel->session; if(pkey->listFetch_state == libssh2_NB_state_idle) { pkey->listFetch_data = NULL; pkey->listFetch_s = pkey->listFetch_buffer; _libssh2_htonu32(pkey->listFetch_s, (uint32_t)(buffer_len - 4)); pkey->listFetch_s += 4; _libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); pkey->listFetch_s += 4; memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); pkey->listFetch_s += sizeof("list") - 1; _libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY, "Sending publickey \"list\" packet")); pkey->listFetch_state = libssh2_NB_state_created; } if(pkey->listFetch_state == libssh2_NB_state_created) { ssize_t nwritten; nwritten = _libssh2_channel_write(channel, 0, pkey->listFetch_buffer, (pkey->listFetch_s - pkey->listFetch_buffer)); if(nwritten == LIBSSH2_ERROR_EAGAIN) { return (int)nwritten; } else if((pkey->listFetch_s - pkey->listFetch_buffer) != nwritten) { pkey->listFetch_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet"); } pkey->listFetch_state = libssh2_NB_state_sent; } for(;;) { rc = publickey_packet_receive(pkey, &pkey->listFetch_data, &pkey->listFetch_data_len); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from " "publickey subsystem"); goto err_exit; } pkey->listFetch_s = pkey->listFetch_data; if((response = publickey_response_id(&pkey->listFetch_s, pkey->listFetch_data_len)) < 0) { _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code"); goto err_exit; } switch(response) { case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: /* Error, or processing complete */ { unsigned long status, descr_len, lang_len; if(pkey->listFetch_s + 8 <= pkey->listFetch_data + pkey->listFetch_data_len) { status = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; descr_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + descr_len + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { /* description starts at pkey->listFetch_s */ pkey->listFetch_s += descr_len; lang_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + lang_len <= pkey->listFetch_data + pkey->listFetch_data_len) { /* lang starts at pkey->listFetch_s */ pkey->listFetch_s += lang_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s > pkey->listFetch_data + pkey->listFetch_data_len) { _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet"); goto err_exit; } if(status == LIBSSH2_PUBLICKEY_SUCCESS) { LIBSSH2_FREE(session, pkey->listFetch_data); pkey->listFetch_data = NULL; *pkey_list = list; *num_keys = keys; pkey->listFetch_state = libssh2_NB_state_idle; return 0; } publickey_status_error(pkey, session, status); goto err_exit; } case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: /* What we want */ if(keys >= max_keys) { libssh2_publickey_list *newlist; /* Grow the key list if necessary */ max_keys += 8; newlist = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list)); if(!newlist) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "publickey list"); goto err_exit; } list = newlist; } if(pkey->version == 1) { unsigned long comment_len; if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { comment_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(comment_len) { list[keys].num_attrs = 1; list[keys].attrs = LIBSSH2_ALLOC(session, sizeof(libssh2_publickey_attribute)); if(!list[keys].attrs) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "publickey attributes"); goto err_exit; } list[keys].attrs[0].name = "comment"; list[keys].attrs[0].name_len = sizeof("comment") - 1; list[keys].attrs[0].value = (char *) pkey->listFetch_s; list[keys].attrs[0].value_len = comment_len; list[keys].attrs[0].mandatory = 0; pkey->listFetch_s += comment_len; } else { list[keys].num_attrs = 0; list[keys].attrs = NULL; } if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + list[keys].name_len <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + list[keys].blob_len <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } } else { /* Version == 2 */ if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + list[keys].name_len <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + list[keys].blob_len <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(list[keys].num_attrs) { list[keys].attrs = LIBSSH2_ALLOC(session, list[keys].num_attrs * sizeof(libssh2_publickey_attribute)); if(!list[keys].attrs) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "publickey attributes"); goto err_exit; } for(i = 0; i < list[keys].num_attrs; i++) { if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].attrs[i].name_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + list[keys].attrs[i].name_len <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].attrs[i].name = (char *) pkey->listFetch_s; pkey->listFetch_s += list[keys].attrs[i].name_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + 4 <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].attrs[i].value_len = _libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } if(pkey->listFetch_s + list[keys].attrs[i].value_len <= pkey->listFetch_data + pkey->listFetch_data_len) { list[keys].attrs[i].value = (char *) pkey->listFetch_s; pkey->listFetch_s += list[keys].attrs[i].value_len; } else { _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "ListFetch data too short"); goto err_exit; } /* actually an ignored value */ list[keys].attrs[i].mandatory = 0; } } else { list[keys].attrs = NULL; } } /* To be FREEd in libssh2_publickey_list_free() */ list[keys].packet = pkey->listFetch_data; keys++; list[keys].packet = NULL; /* Terminate the list */ pkey->listFetch_data = NULL; break; default: /* Unknown/Unexpected */ _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response"); LIBSSH2_FREE(session, pkey->listFetch_data); pkey->listFetch_data = NULL; } } /* Only reached via explicit goto */ err_exit: if(pkey->listFetch_data) { LIBSSH2_FREE(session, pkey->listFetch_data); pkey->listFetch_data = NULL; } if(list) { libssh2_publickey_list_free(pkey, list); } pkey->listFetch_state = libssh2_NB_state_idle; return -1; } /* libssh2_publickey_list_free * Free a previously fetched list of public keys */ LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey, libssh2_publickey_list * pkey_list) { LIBSSH2_SESSION *session; libssh2_publickey_list *p = pkey_list; if(!pkey || !p) return; session = pkey->channel->session; while(p->packet) { if(p->attrs) { LIBSSH2_FREE(session, p->attrs); } LIBSSH2_FREE(session, p->packet); p++; } LIBSSH2_FREE(session, pkey_list); } /* libssh2_publickey_shutdown * Shutdown the publickey subsystem */ LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) { LIBSSH2_SESSION *session; int rc; if(!pkey) return LIBSSH2_ERROR_BAD_USE; session = pkey->channel->session; /* * Make sure all memory used in the state variables are free */ if(pkey->receive_packet) { LIBSSH2_FREE(session, pkey->receive_packet); pkey->receive_packet = NULL; } if(pkey->add_packet) { LIBSSH2_FREE(session, pkey->add_packet); pkey->add_packet = NULL; } if(pkey->remove_packet) { LIBSSH2_FREE(session, pkey->remove_packet); pkey->remove_packet = NULL; } if(pkey->listFetch_data) { LIBSSH2_FREE(session, pkey->listFetch_data); pkey->listFetch_data = NULL; } rc = _libssh2_channel_free(pkey->channel); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; LIBSSH2_FREE(session, pkey); return 0; } libssh2-1.11.0/src/libgcrypt.h0000644000175000017500000002302114424650606013025 00000000000000#ifndef __LIBSSH2_LIBGCRYPT_H #define __LIBSSH2_LIBGCRYPT_H /* * Copyright (C) 2008, 2009, 2010 Simon Josefsson * Copyright (C) 2006, 2007, The Written Word, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #define LIBSSH2_CRYPTO_ENGINE libssh2_gcrypt #include #define LIBSSH2_MD5 1 #define LIBSSH2_HMAC_RIPEMD 1 #define LIBSSH2_HMAC_SHA256 1 #define LIBSSH2_HMAC_SHA512 1 #define LIBSSH2_AES_CBC 1 #define LIBSSH2_AES_CTR 1 #define LIBSSH2_AES_GCM 0 #define LIBSSH2_BLOWFISH 1 #define LIBSSH2_RC4 1 #define LIBSSH2_CAST 1 #define LIBSSH2_3DES 1 #define LIBSSH2_RSA 1 #define LIBSSH2_RSA_SHA1 1 #define LIBSSH2_RSA_SHA2 0 #define LIBSSH2_DSA 1 #define LIBSSH2_ECDSA 0 #define LIBSSH2_ED25519 0 #define MD5_DIGEST_LENGTH 16 #define SHA_DIGEST_LENGTH 20 #define SHA256_DIGEST_LENGTH 32 #define SHA384_DIGEST_LENGTH 48 #define SHA512_DIGEST_LENGTH 64 #define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) #define _libssh2_random(buf, len) \ (gcry_randomize((buf), (len), GCRY_STRONG_RANDOM), 0) #define libssh2_prepare_iovec(vec, len) /* Empty. */ #define libssh2_sha1_ctx gcry_md_hd_t /* returns 0 in case of failure */ #define libssh2_sha1_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0)) #define libssh2_sha1_update(ctx, data, len) \ gcry_md_write(ctx, (unsigned char *) data, len) #define libssh2_sha1_final(ctx, out) \ memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx) #define libssh2_sha1(message, len, out) \ gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len) #define libssh2_sha256_ctx gcry_md_hd_t #define libssh2_sha256_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0)) #define libssh2_sha256_update(ctx, data, len) \ gcry_md_write(ctx, (unsigned char *) data, len) #define libssh2_sha256_final(ctx, out) \ memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx) #define libssh2_sha256(message, len, out) \ gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len) #define libssh2_sha384_ctx gcry_md_hd_t #define libssh2_sha384_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0)) #define libssh2_sha384_update(ctx, data, len) \ gcry_md_write(ctx, (unsigned char *) data, len) #define libssh2_sha384_final(ctx, out) \ memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx) #define libssh2_sha384(message, len, out) \ gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len) #define libssh2_sha512_ctx gcry_md_hd_t #define libssh2_sha512_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0)) #define libssh2_sha512_update(ctx, data, len) \ gcry_md_write(ctx, (unsigned char *) data, len) #define libssh2_sha512_final(ctx, out) \ memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx) #define libssh2_sha512(message, len, out) \ gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len) #define libssh2_md5_ctx gcry_md_hd_t /* returns 0 in case of failure */ #define libssh2_md5_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0)) #define libssh2_md5_update(ctx, data, len) \ gcry_md_write(ctx, (unsigned char *) data, len) #define libssh2_md5_final(ctx, out) \ memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx) #define libssh2_md5(message, len, out) \ gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len) #define libssh2_hmac_ctx gcry_md_hd_t #define libssh2_hmac_ctx_init(ctx) #define libssh2_hmac_sha1_init(ctx, key, keylen) \ gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \ gcry_md_setkey(*ctx, key, keylen) #define libssh2_hmac_md5_init(ctx, key, keylen) \ gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \ gcry_md_setkey(*ctx, key, keylen) #define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \ gcry_md_setkey(*ctx, key, keylen) #define libssh2_hmac_sha256_init(ctx, key, keylen) \ gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \ gcry_md_setkey(*ctx, key, keylen) #define libssh2_hmac_sha512_init(ctx, key, keylen) \ gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \ gcry_md_setkey(*ctx, key, keylen) #define libssh2_hmac_update(ctx, data, datalen) \ gcry_md_write(ctx, (unsigned char *) data, datalen) #define libssh2_hmac_final(ctx, data) \ memcpy(data, gcry_md_read(ctx, 0), \ gcry_md_get_algo_dlen(gcry_md_get_algo(ctx))) #define libssh2_hmac_cleanup(ctx) gcry_md_close(*ctx) #define libssh2_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM) #define libssh2_crypto_exit() #define libssh2_rsa_ctx struct gcry_sexp #define _libssh2_rsa_free(rsactx) gcry_sexp_release(rsactx) #define libssh2_dsa_ctx struct gcry_sexp #define _libssh2_dsa_free(dsactx) gcry_sexp_release(dsactx) #if LIBSSH2_ECDSA #else #define _libssh2_ec_key void #endif #define _libssh2_cipher_type(name) int name #define _libssh2_cipher_ctx gcry_cipher_hd_t #define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m) #define _libssh2_gcry_cipher(c) (c >> 8) #define _libssh2_gcry_mode(m) (m & 0xFF) #define _libssh2_cipher_aes256ctr \ _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR) #define _libssh2_cipher_aes192ctr \ _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR) #define _libssh2_cipher_aes128ctr \ _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR) #define _libssh2_cipher_aes256 \ _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC) #define _libssh2_cipher_aes192 \ _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC) #define _libssh2_cipher_aes128 \ _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC) #define _libssh2_cipher_blowfish \ _libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC) #define _libssh2_cipher_arcfour \ _libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM) #define _libssh2_cipher_cast5 \ _libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC) #define _libssh2_cipher_3des \ _libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC) #define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) #define _libssh2_bn struct gcry_mpi #define _libssh2_bn_ctx int #define _libssh2_bn_ctx_new() 0 #define _libssh2_bn_ctx_free(bnctx) ((void)0) #define _libssh2_bn_init() gcry_mpi_new(0) #define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a new bignum */ #define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val) #define _libssh2_bn_from_bin(bn, len, val) \ gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL) #define _libssh2_bn_to_bin(bn, val) \ gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn) #define _libssh2_bn_bytes(bn) \ (gcry_mpi_get_nbits(bn) / 8 + \ ((gcry_mpi_get_nbits(bn) % 8 == 0) ? 0 : 1)) #define _libssh2_bn_bits(bn) gcry_mpi_get_nbits(bn) #define _libssh2_bn_free(bn) gcry_mpi_release(bn) /* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ #define LIBSSH2_DH_GEX_MINGROUP 2048 #define LIBSSH2_DH_GEX_OPTGROUP 4096 #define LIBSSH2_DH_GEX_MAXGROUP 8192 #define LIBSSH2_DH_MAX_MODULUS_BITS 16384 #define _libssh2_dh_ctx struct gcry_mpi * #define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) #define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ _libssh2_dh_key_pair(dhctx, public, g, p, group_order) #define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ _libssh2_dh_secret(dhctx, secret, f, p) #define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) extern void _libssh2_init_aes_ctr(void); extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx); extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order); extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p); extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); #endif /* __LIBSSH2_LIBGCRYPT_H */ libssh2-1.11.0/src/os400qc3.c0000644000175000017500000022042014424650606012277 00000000000000/* * Copyright (C) 2015-2016 Patrick Monnerat, D+H * Copyright (C) 2020-2023 Patrick Monnerat . * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */ #include #include #include #include #include #ifdef OS400_DEBUG /* In debug mode, all system library errors cause an exception. */ #define set_EC_length(ec, length) ((ec).Bytes_Provided = \ (ec).Bytes_Available = 0) #else #define set_EC_length(ec, length) ((ec).Bytes_Provided = (length)) #endif /* Ensure va_list operations are not on an array. */ typedef struct { va_list list; } valiststr; typedef int (*loadkeyproc)(LIBSSH2_SESSION *session, const unsigned char *data, unsigned int datalen, const unsigned char *passphrase, void *loadkeydata); /* Public key extraction data. */ typedef struct { const char * method; const unsigned char * data; unsigned int length; } loadpubkeydata; /* Support for ASN.1 elements. */ typedef struct { char * header; /* Pointer to header byte. */ char * beg; /* Pointer to element data. */ char * end; /* Pointer to 1st byte after element. */ unsigned char class; /* ASN.1 element class. */ unsigned char tag; /* ASN.1 element tag. */ unsigned char constructed; /* Element is constructed. */ } asn1Element; #define ASN1_INTEGER 2 #define ASN1_BIT_STRING 3 #define ASN1_OCTET_STRING 4 #define ASN1_NULL 5 #define ASN1_OBJ_ID 6 #define ASN1_SEQ 16 #define ASN1_CONSTRUCTED 0x20 /* rsaEncryption OID: 1.2.840.113549.1.1.1 */ static unsigned char OID_rsaEncryption[] = {9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 1, 1}; static int sshrsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, asn1Element *params, asn1Element *key, const char *method); #if LIBSSH2_DSA != 0 /* dsaEncryption OID: 1.2.840.10040.4.1 */ static unsigned char OID_dsaEncryption[] = {7, 40 + 2, 0x86, 0x48, 0xCE, 0x38, 4, 1}; static int sshdsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, asn1Element *params, asn1Element *key, const char *method); #endif static unsigned char OID_dhKeyAgreement[] = {9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 3, 1}; /* PKCS#5 support. */ typedef struct pkcs5params pkcs5params; struct pkcs5params { int cipher; /* Encryption cipher. */ int blocksize; /* Cipher block size. */ char mode; /* Block encryption mode. */ char padopt; /* Pad option. */ char padchar; /* Pad character. */ int (*kdf)(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, pkcs5params *pkcs5); int hash; /* KDF hash algorithm. */ size_t hashlen; /* KDF hash digest length. */ char * salt; /* Salt. */ size_t saltlen; /* Salt length. */ char * iv; /* Initialization vector. */ size_t ivlen; /* Initialization vector length. */ int itercount; /* KDF iteration count. */ int dklen; /* Derived key length (#bytes). */ int effkeysize; /* RC2 effective key size (#bits) or 0. */ }; typedef struct pkcs5algo pkcs5algo; struct pkcs5algo { const unsigned char * oid; int (*parse)(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); int cipher; /* Encryption cipher. */ size_t blocksize; /* Cipher block size. */ char mode; /* Block encryption mode. */ char padopt; /* Pad option. */ char padchar; /* Pad character. */ size_t keylen; /* Key length (#bytes). */ int hash; /* Hash algorithm. */ size_t hashlen; /* Hash digest length. */ size_t saltlen; /* Salt length. */ size_t ivlen; /* Initialisation vector length. */ int effkeysize; /* RC2 effective key size (#bits) or 0. */ }; /* id-PBES2 OID: 1.2.840.113549.1.5.13 */ static const unsigned char OID_id_PBES2[] = { 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D }; static int parse_pbes2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); static const pkcs5algo PBES2 = { OID_id_PBES2, parse_pbes2, 0, 0, '\0', '\0', '\0', 0, 0, 0, 0, 0, 0 }; /* id-PBKDF2 OID: 1.2.840.113549.1.5.12 */ static const unsigned char OID_id_PBKDF2[] = { 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C }; static int parse_pbkdf2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); static const pkcs5algo PBKDF2 = { OID_id_PBKDF2, parse_pbkdf2, 0, 0, '\0', '\0', '\0', SHA_DIGEST_LENGTH, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 8, 0 }; /* id-hmacWithSHA1 OID: 1.2.840.113549.2.7 */ static const unsigned char OID_id_hmacWithSHA1[] = { 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x07 }; static int parse_hmacWithSHA1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); static const pkcs5algo hmacWithSHA1 = { OID_id_hmacWithSHA1, parse_hmacWithSHA1, 0, 0, '\0', '\0', '\0', SHA_DIGEST_LENGTH, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 8, 0 }; /* desCBC OID: 1.3.14.3.2.7 */ static const unsigned char OID_desCBC[] = {5, 40 + 3, 0x0E, 0x03, 0x02, 0x07}; static int parse_iv(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); static const pkcs5algo desCBC = { OID_desCBC, parse_iv, Qc3_DES, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 8, 0, 0, 8, 8, 0 }; /* des-EDE3-CBC OID: 1.2.840.113549.3.7 */ static const unsigned char OID_des_EDE3_CBC[] = { 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07 }; static const pkcs5algo des_EDE3_CBC = { OID_des_EDE3_CBC, parse_iv, Qc3_TDES, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 24, 0, 0, 8, 8, 0 }; /* rc2CBC OID: 1.2.840.113549.3.2 */ static const unsigned char OID_rc2CBC[] = { 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x02 }; static int parse_rc2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); static const pkcs5algo rc2CBC = { OID_rc2CBC, parse_rc2, Qc3_RC2, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 0, 0, 0, 8, 0, 32 }; /* pbeWithMD5AndDES-CBC OID: 1.2.840.113549.1.5.3 */ static const unsigned char OID_pbeWithMD5AndDES_CBC[] = { 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x03 }; static int parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param); static const pkcs5algo pbeWithMD5AndDES_CBC = { OID_pbeWithMD5AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 8, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 0 }; /* pbeWithMD5AndRC2-CBC OID: 1.2.840.113549.1.5.6 */ static const unsigned char OID_pbeWithMD5AndRC2_CBC[] = { 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x06 }; static const pkcs5algo pbeWithMD5AndRC2_CBC = { OID_pbeWithMD5AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 0, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 64 }; /* pbeWithSHA1AndDES-CBC OID: 1.2.840.113549.1.5.10 */ static const unsigned char OID_pbeWithSHA1AndDES_CBC[] = { 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0A }; static const pkcs5algo pbeWithSHA1AndDES_CBC = { OID_pbeWithSHA1AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 8, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 0, 0 }; /* pbeWithSHA1AndRC2-CBC OID: 1.2.840.113549.1.5.11 */ static const unsigned char OID_pbeWithSHA1AndRC2_CBC[] = { 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0B }; static const pkcs5algo pbeWithSHA1AndRC2_CBC = { OID_pbeWithSHA1AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC, Qc3_Pad_Counter, '\0', 0, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 0, 64 }; /* rc5-CBC-PAD OID: 1.2.840.113549.3.9: RC5 not implemented in Qc3. */ /* pbeWithMD2AndDES-CBC OID: 1.2.840.113549.1.5.1: MD2 not implemented. */ /* pbeWithMD2AndRC2-CBC OID: 1.2.840.113549.1.5.4: MD2 not implemented. */ static const pkcs5algo * pbestable[] = { &pbeWithMD5AndDES_CBC, &pbeWithMD5AndRC2_CBC, &pbeWithSHA1AndDES_CBC, &pbeWithSHA1AndRC2_CBC, &PBES2, NULL }; static const pkcs5algo * pbkdf2table[] = { &PBKDF2, NULL }; static const pkcs5algo * pbes2enctable[] = { &desCBC, &des_EDE3_CBC, &rc2CBC, NULL }; static const pkcs5algo * kdf2prftable[] = { &hmacWithSHA1, NULL }; /* Public key extraction support. */ static struct { unsigned char *oid; int (*sshpubkey)(LIBSSH2_SESSION *session, char **pubkey, asn1Element *params, asn1Element *key, const char *method); const char * method; } pka[] = { #if LIBSSH2_RSA != 0 { OID_rsaEncryption, sshrsapubkey, "ssh-rsa" }, #endif #if LIBSSH2_DSA != 0 { OID_dsaEncryption, sshdsapubkey, "ssh-dss" }, #endif { NULL, NULL, NULL } }; /* Define ASCII strings. */ static const char beginencprivkeyhdr[] = "-----BEGIN ENCRYPTED PRIVATE KEY-----"; static const char endencprivkeyhdr[] = "-----END ENCRYPTED PRIVATE KEY-----"; static const char beginprivkeyhdr[] = "-----BEGIN PRIVATE KEY-----"; static const char endprivkeyhdr[] = "-----END PRIVATE KEY-----"; static const char beginrsaprivkeyhdr[] = "-----BEGIN RSA PRIVATE KEY-----"; static const char endrsaprivkeyhdr[] = "-----END RSA PRIVATE KEY-----"; static const char fopenrmode[] = "r"; static const char fopenrbmode[] = "rb"; /* The rest of character literals in this module are in EBCDIC. */ #pragma convert(37) #include #include #include #include #include #include #include #include #include #include #include #include static Qc3_Format_KEYD0100_T nulltoken = {""}; static int zero = 0; static int rsaprivate[] = { Qc3_RSA_Private }; static char anycsp[] = { Qc3_Any_CSP }; static char binstring[] = { Qc3_Bin_String }; static char berstring[] = { Qc3_BER_String }; static char qc3clear[] = { Qc3_Clear }; static const Qus_EC_t ecnull = {0}; /* Error causes an exception. */ static asn1Element lastbytebitcount = { (char *) &zero, NULL, (char *) &zero + 1 }; /******************************************************************* * * OS/400 QC3 crypto-library backend: big numbers support. * *******************************************************************/ int _libssh2_random(unsigned char *buf, size_t len) { Qus_EC_t errcode; set_EC_length(errcode, sizeof(errcode)); Qc3GenPRNs(buf, len, Qc3PRN_TYPE_NORMAL, Qc3PRN_NO_PARITY, (char *) &errcode); return errcode.Bytes_Available? -1: 0; } _libssh2_bn * _libssh2_bn_init(void) { _libssh2_bn *bignum; bignum = (_libssh2_bn *) malloc(sizeof(*bignum)); if(bignum) { bignum->bignum = NULL; bignum->length = 0; } return bignum; } void _libssh2_bn_free(_libssh2_bn *bn) { if(bn) { if(bn->bignum) { if(bn->length) _libssh2_explicit_zero(bn->bignum, bn->length); free(bn->bignum); } free((char *) bn); } } static int _libssh2_bn_resize(_libssh2_bn *bn, size_t newlen) { unsigned char *bignum; if(!bn) return -1; if(newlen == bn->length) return 0; if(!bn->bignum) bignum = (unsigned char *) malloc(newlen); else { if(newlen < bn->length) _libssh2_explicit_zero(bn->bignum + newlen, bn->length - newlen); if(!newlen) { free((char *) bn->bignum); bn->bignum = NULL; bn->length = 0; return 0; } bignum = (unsigned char *) realloc((char *) bn->bignum, newlen); } if(!bignum) return -1; if(newlen > bn->length) memset((char *) bignum + bn->length, 0, newlen - bn->length); bn->bignum = bignum; bn->length = newlen; return 0; } unsigned long _libssh2_bn_bits(_libssh2_bn *bn) { unsigned int i; unsigned char b; if(bn && bn->bignum) { for(i = bn->length; i--;) { b = bn->bignum[i]; if(b) { i *= 8; do { i++; } while(b >>= 1); return i; } } } return 0; } int _libssh2_bn_from_bin(_libssh2_bn *bn, int len, const unsigned char *val) { int i; if(!bn || (len && !val)) return -1; for(; len && !*val; len--) val++; if(_libssh2_bn_resize(bn, len)) return -1; for(i = len; i--;) bn->bignum[i] = *val++; return 0; } int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val) { val = htonl(val); return _libssh2_bn_from_bin(bn, sizeof(val), (unsigned char *) &val); } int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val) { int i; if(!bn || !val) return -1; for(i = bn->length; i--;) *val++ = bn->bignum[i]; return 0; } static int _libssh2_bn_from_bn(_libssh2_bn *to, _libssh2_bn *from) { int i; if(!to || !from) return -1; if(_libssh2_bn_resize(to, from->length)) return -1; for(i = to->length; i--;) to->bignum[i] = from->bignum[i]; return 0; } /******************************************************************* * * OS/400 QC3 crypto-library backend: ASN.1 support. * *******************************************************************/ static char * getASN1Element(asn1Element *elem, char *beg, char *end) { unsigned char b; unsigned long len; asn1Element lelem; /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg' * ending at `end'. * Returns a pointer in source string after the parsed element, or NULL * if an error occurs. */ if(beg >= end || !*beg) return NULL; /* Process header byte. */ elem->header = beg; b = (unsigned char) *beg++; elem->constructed = (b & 0x20) != 0; elem->class = (b >> 6) & 3; b &= 0x1F; if(b == 0x1F) return NULL; /* Long tag values not supported here. */ elem->tag = b; /* Process length. */ if(beg >= end) return NULL; b = (unsigned char) *beg++; if(!(b & 0x80)) len = b; else if(!(b &= 0x7F)) { /* Unspecified length. Since we have all the data, we can determine the * effective length by skipping element until an end element is * found. */ if(!elem->constructed) return NULL; elem->beg = beg; while(beg < end && *beg) { beg = getASN1Element(&lelem, beg, end); if(!beg) return NULL; } if(beg >= end) return NULL; elem->end = beg; return beg + 1; } else if(beg + b > end) return NULL; /* Does not fit in source. */ else { /* Get long length. */ len = 0; do { if(len & 0xFF000000L) return NULL; /* Lengths > 32 bits are not supported. */ len = (len << 8) | (unsigned char) *beg++; } while(--b); } if((unsigned long) (end - beg) < len) return NULL; /* Element data does not fit in source. */ elem->beg = beg; elem->end = beg + len; return elem->end; } static asn1Element * asn1_new(unsigned int type, unsigned int length) { asn1Element *e; unsigned int hdrl = 2; unsigned int i; unsigned char *buf; e = (asn1Element *) malloc(sizeof(*e)); if(e) { if(length >= 0x80) for(i = length; i; i >>= 8) hdrl++; buf = (unsigned char *) malloc(hdrl + length); if(buf) { e->header = buf; e->beg = buf + hdrl; e->end = e->beg + length; e->class = (type >> 6) & 0x03; e->tag = type & 0x1F; e->constructed = (type >> 5) & 0x01; e->header[0] = type; if(length < 0x80) e->header[1] = length; else { e->header[1] = (hdrl - 2) | 0x80; do { e->header[--hdrl] = length; length >>= 8; } while(length); } } else { free((char *) e); e = NULL; } } return e; } static asn1Element * asn1_new_from_bytes(const unsigned char *data, unsigned int length) { asn1Element *e; asn1Element te; getASN1Element(&te, (unsigned char *) data, (unsigned char *) data + length); e = asn1_new(te.tag, te.end - te.beg); if(e) memcpy(e->header, data, e->end - e->header); return e; } static void asn1delete(asn1Element *e) { if(e) { if(e->header) free((char *) e->header); free((char *) e); } } static asn1Element * asn1uint(_libssh2_bn *bn) { asn1Element *e; int bits; int length; unsigned char *p; if(!bn) return NULL; bits = _libssh2_bn_bits(bn); length = (bits + 8) >> 3; e = asn1_new(ASN1_INTEGER, length); if(e) { p = e->beg; if(!(bits & 0x07)) *p++ = 0; _libssh2_bn_to_bin(bn, p); } return e; } static asn1Element * asn1containerv(unsigned int type, valiststr args) { valiststr va; asn1Element *e; asn1Element *p; unsigned char *bp; unsigned int length = 0; memcpy((char *) &va, (char *) &args, sizeof(args)); while((p = va_arg(va.list, asn1Element *))) length += p->end - p->header; va_end(va.list); e = asn1_new(type, length); if(e) { bp = e->beg; while((p = va_arg(args.list, asn1Element *))) { memcpy(bp, p->header, p->end - p->header); bp += p->end - p->header; } } return e; } /* VARARGS1 */ static asn1Element * asn1container(unsigned int type, ...) { valiststr va; asn1Element *e; va_start(va.list, type); e = asn1containerv(type, va); va_end(va.list); return e; } static asn1Element * asn1bytes(unsigned int type, const unsigned char *bytes, unsigned int length) { asn1Element *e; e = asn1_new(type, length); if(e && length) memcpy(e->beg, bytes, length); return e; } static asn1Element * rsapublickey(_libssh2_bn *e, _libssh2_bn *m) { asn1Element *publicexponent; asn1Element *modulus; asn1Element *rsapubkey; /* Build a PKCS#1 RSAPublicKey. */ modulus = asn1uint(m); publicexponent = asn1uint(e); rsapubkey = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, modulus, publicexponent, NULL); asn1delete(modulus); asn1delete(publicexponent); if(!modulus || !publicexponent) { asn1delete(rsapubkey); rsapubkey = NULL; } return rsapubkey; } static asn1Element * rsaprivatekey(_libssh2_bn *e, _libssh2_bn *m, _libssh2_bn *d, _libssh2_bn *p, _libssh2_bn *q, _libssh2_bn *exp1, _libssh2_bn *exp2, _libssh2_bn *coeff) { asn1Element *version; asn1Element *modulus; asn1Element *publicexponent; asn1Element *privateexponent; asn1Element *prime1; asn1Element *prime2; asn1Element *exponent1; asn1Element *exponent2; asn1Element *coefficient; asn1Element *rsaprivkey; /* Build a PKCS#1 RSAPrivateKey. */ version = asn1bytes(ASN1_INTEGER, "\0", 1); modulus = asn1uint(m); publicexponent = asn1uint(e); privateexponent = asn1uint(d); prime1 = asn1uint(p); prime2 = asn1uint(q); exponent1 = asn1uint(exp1); exponent2 = asn1uint(exp2); coefficient = asn1uint(coeff); rsaprivkey = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, version, modulus, publicexponent, privateexponent, prime1, prime2, exponent1, exponent2, coefficient, NULL); asn1delete(version); asn1delete(modulus); asn1delete(publicexponent); asn1delete(privateexponent); asn1delete(prime1); asn1delete(prime2); asn1delete(exponent1); asn1delete(exponent2); asn1delete(coefficient); if(!version || !modulus || !publicexponent || !privateexponent || !prime1 || !prime2 || !exponent1 || !exponent2 || !coefficient) { asn1delete(rsaprivkey); rsaprivkey = NULL; } return rsaprivkey; } static asn1Element * subjectpublickeyinfo(asn1Element *pubkey, const unsigned char *algo, asn1Element *parameters) { asn1Element *subjpubkey; asn1Element *algorithm; asn1Element *algorithmid; asn1Element *subjpubkeyinfo; unsigned int algosize = *algo++; algorithm = asn1bytes(ASN1_OBJ_ID, algo, algosize); algorithmid = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, algorithm, parameters, NULL); subjpubkey = asn1container(ASN1_BIT_STRING, &lastbytebitcount, pubkey, NULL); subjpubkeyinfo = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, algorithmid, subjpubkey, NULL); asn1delete(algorithm); asn1delete(algorithmid); asn1delete(subjpubkey); if(!algorithm || !algorithmid || !subjpubkey) { asn1delete(subjpubkeyinfo); subjpubkeyinfo = NULL; } return subjpubkeyinfo; } static asn1Element * rsasubjectpublickeyinfo(asn1Element *pubkey) { asn1Element *parameters; asn1Element *subjpubkeyinfo; parameters = asn1bytes(ASN1_NULL, NULL, 0); subjpubkeyinfo = subjectpublickeyinfo(pubkey, OID_rsaEncryption, parameters); asn1delete(parameters); if(!parameters) { asn1delete(subjpubkeyinfo); subjpubkeyinfo = NULL; } return subjpubkeyinfo; } static asn1Element * privatekeyinfo(asn1Element *privkey, const unsigned char *algo, asn1Element *parameters) { asn1Element *version; asn1Element *privatekey; asn1Element *algorithm; asn1Element *privatekeyalgorithm; asn1Element *privkeyinfo; unsigned int algosize = *algo++; /* Build a PKCS#8 PrivateKeyInfo. */ version = asn1bytes(ASN1_INTEGER, "\0", 1); algorithm = asn1bytes(ASN1_OBJ_ID, algo, algosize); privatekeyalgorithm = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, algorithm, parameters, NULL); privatekey = asn1container(ASN1_OCTET_STRING, privkey, NULL); privkeyinfo = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, version, privatekeyalgorithm, privatekey, NULL); asn1delete(version); asn1delete(algorithm); asn1delete(privatekeyalgorithm); if(!version || !algorithm || !privatekeyalgorithm) { asn1delete(privkeyinfo); privkeyinfo = NULL; } return privkeyinfo; } static asn1Element * rsaprivatekeyinfo(asn1Element *privkey) { asn1Element *parameters; asn1Element *privkeyinfo; parameters = asn1bytes(ASN1_NULL, NULL, 0); privkeyinfo = privatekeyinfo(privkey, OID_rsaEncryption, parameters); asn1delete(parameters); if(!parameters) { asn1delete(privkeyinfo); privkeyinfo = NULL; } return privkeyinfo; } /******************************************************************* * * OS/400 QC3 crypto-library backend: crypto context support. * *******************************************************************/ static _libssh2_os400qc3_crypto_ctx * libssh2_init_crypto_ctx(_libssh2_os400qc3_crypto_ctx *ctx) { if(!ctx) ctx = (_libssh2_os400qc3_crypto_ctx *) malloc(sizeof(*ctx)); if(ctx) { memset((char *) ctx, 0, sizeof(*ctx)); ctx->hash.Final_Op_Flag = Qc3_Continue; } return ctx; } static int null_token(const char *token) { return !memcmp(token, nulltoken.Key_Context_Token, sizeof(nulltoken.Key_Context_Token)); } void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x) { if(!x) return; if(!null_token(x->hash.Alg_Context_Token)) { Qc3DestroyAlgorithmContext(x->hash.Alg_Context_Token, (char *) &ecnull); memset(x->hash.Alg_Context_Token, 0, sizeof(x->hash.Alg_Context_Token)); } if(!null_token(x->key.Key_Context_Token)) { Qc3DestroyKeyContext(x->key.Key_Context_Token, (char *) &ecnull); memset(x->key.Key_Context_Token, 0, sizeof(x->key.Key_Context_Token)); } if(x->kek) { _libssh2_os400qc3_crypto_dtor(x->kek); free((char *) x->kek); x->kek = NULL; } } /******************************************************************* * * OS/400 QC3 crypto-library backend: hash algorithms support. * *******************************************************************/ int libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algorithm) { Qc3_Format_ALGD0500_T algd; Qus_EC_t errcode; if(!x) return 0; memset((char *) x, 0, sizeof(*x)); x->Final_Op_Flag = Qc3_Continue; algd.Hash_Alg = algorithm; set_EC_length(errcode, sizeof(errcode)); Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Hash, x->Alg_Context_Token, &errcode); return errcode.Bytes_Available? 0: 1; } void libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, const unsigned char *data, int len) { char dummy[64]; ctx->Final_Op_Flag = Qc3_Continue; Qc3CalculateHash((char *) data, &len, Qc3_Data, (char *) ctx, Qc3_Alg_Token, anycsp, NULL, dummy, (char *) &ecnull); } void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, unsigned char *out) { char data; ctx->Final_Op_Flag = Qc3_Final; Qc3CalculateHash(&data, &zero, Qc3_Data, (char *) ctx, Qc3_Alg_Token, anycsp, NULL, (char *) out, (char *) &ecnull); Qc3DestroyAlgorithmContext(ctx->Alg_Context_Token, (char *) &ecnull); memset(ctx->Alg_Context_Token, 0, sizeof(ctx->Alg_Context_Token)); } int libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, unsigned char *out, unsigned int algo) { Qc3_Format_ALGD0100_T ctx; if(!libssh2_os400qc3_hash_init(&ctx, algo)) return 1; libssh2_os400qc3_hash_update(&ctx, message, len); libssh2_os400qc3_hash_final(&ctx, out); return 0; } void libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx, int algo, size_t minkeylen, void *key, int keylen) { if(keylen < minkeylen) { char *lkey = alloca(minkeylen); /* Pad key with zeroes if too short. */ if(!lkey) return; memcpy(lkey, (char *) key, keylen); memset(lkey + keylen, 0, minkeylen - keylen); key = (void *) lkey; keylen = minkeylen; } libssh2_os400qc3_hash_init(&ctx->hash, algo); Qc3CreateKeyContext((char *) key, &keylen, binstring, &algo, qc3clear, NULL, NULL, ctx->key.Key_Context_Token, (char *) &ecnull); } void libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, unsigned char *data, int len) { char dummy[64]; ctx->hash.Final_Op_Flag = Qc3_Continue; Qc3CalculateHMAC((char *) data, &len, Qc3_Data, (char *) &ctx->hash, Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, dummy, (char *) &ecnull); } void libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, unsigned char *out) { char data; ctx->hash.Final_Op_Flag = Qc3_Final; Qc3CalculateHMAC((char *) data, &zero, Qc3_Data, (char *) &ctx->hash, Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, (char *) out, (char *) &ecnull); } /******************************************************************* * * OS/400 QC3 crypto-library backend: cipher algorithms support. * *******************************************************************/ int _libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { Qc3_Format_ALGD0200_T algd; Qus_EC_t errcode; (void) encrypt; if(!h) return -1; libssh2_init_crypto_ctx(h); algd.Block_Cipher_Alg = algo.algo; algd.Block_Length = algo.size; algd.Mode = algo.mode; algd.Pad_Option = Qc3_No_Pad; algd.Pad_Character = 0; algd.Reserved = 0; algd.MAC_Length = 0; algd.Effective_Key_Size = 0; memset(algd.Init_Vector, 0, sizeof(algd.Init_Vector)); if(algo.mode != Qc3_ECB && algo.size) memcpy(algd.Init_Vector, iv, algo.size); set_EC_length(errcode, sizeof(errcode)); Qc3CreateAlgorithmContext((char *) &algd, algo.fmt, h->hash.Alg_Context_Token, &errcode); if(errcode.Bytes_Available) return -1; Qc3CreateKeyContext((char *) secret, &algo.keylen, binstring, &algo.algo, qc3clear, NULL, NULL, h->key.Key_Context_Token, (char *) &errcode); if(errcode.Bytes_Available) { _libssh2_os400qc3_crypto_dtor(h); return -1; } return 0; } int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize, int firstlast) { Qus_EC_t errcode; int outlen; int blksize = blocksize; (void) algo; set_EC_length(errcode, sizeof(errcode)); if(encrypt) Qc3EncryptData((char *) block, &blksize, Qc3_Data, ctx->hash.Alg_Context_Token, Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, (char *) block, &blksize, &outlen, (char *) &errcode); else Qc3DecryptData((char *) block, &blksize, ctx->hash.Alg_Context_Token, Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, (char *) block, &blksize, &outlen, (char *) &errcode); return errcode.Bytes_Available? -1: 0; } /******************************************************************* * * OS/400 QC3 crypto-library backend: RSA support. * *******************************************************************/ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { libssh2_rsa_ctx *ctx; _libssh2_bn *e = _libssh2_bn_init_from_bin(); _libssh2_bn *n = _libssh2_bn_init_from_bin(); _libssh2_bn *d = NULL; _libssh2_bn *p = NULL; _libssh2_bn *q = NULL; _libssh2_bn *e1 = NULL; _libssh2_bn *e2 = NULL; _libssh2_bn *coeff = NULL; asn1Element *key = NULL; asn1Element *structkey = NULL; int keytype; int ret = 0; int i; ctx = libssh2_init_crypto_ctx(NULL); if(!ctx) ret = -1; if(!ret) { _libssh2_bn_from_bin(e, elen, edata); _libssh2_bn_from_bin(n, nlen, ndata); if(!e || !n) ret = -1; } if(!ret && ddata) { /* Private key. */ d = _libssh2_bn_init_from_bin(); _libssh2_bn_from_bin(d, dlen, ddata); p = _libssh2_bn_init_from_bin(); _libssh2_bn_from_bin(p, plen, pdata); q = _libssh2_bn_init_from_bin(); _libssh2_bn_from_bin(q, qlen, qdata); e1 = _libssh2_bn_init_from_bin(); _libssh2_bn_from_bin(e1, e1len, e1data); e2 = _libssh2_bn_init_from_bin(); _libssh2_bn_from_bin(e2, e2len, e2data); coeff = _libssh2_bn_init_from_bin(); _libssh2_bn_from_bin(coeff, coefflen, coeffdata); if(!d || !p || !q ||!e1 || !e2 || !coeff) ret = -1; if(!ret) { /* Build a PKCS#8 private key. */ key = rsaprivatekey(e, n, d, p, q, e1, e2, coeff); structkey = rsaprivatekeyinfo(key); } keytype = Qc3_RSA_Private; } else if(!ret) { key = rsapublickey(e, n); structkey = rsasubjectpublickeyinfo(key); keytype = Qc3_RSA_Public; } if(!key || !structkey) ret = -1; /* Create the key context. */ if(!ret) { Qus_EC_t errcode; set_EC_length(errcode, sizeof(errcode)); i = structkey->end - structkey->header; Qc3CreateKeyContext(structkey->header, &i, berstring, &keytype, qc3clear, NULL, NULL, ctx->key.Key_Context_Token, (char *) &errcode); if(errcode.Bytes_Available) ret = -1; } _libssh2_bn_free(e); _libssh2_bn_free(n); _libssh2_bn_free(d); _libssh2_bn_free(p); _libssh2_bn_free(q); _libssh2_bn_free(e1); _libssh2_bn_free(e2); _libssh2_bn_free(coeff); asn1delete(key); asn1delete(structkey); if(ret && ctx) { _libssh2_rsa_free(ctx); ctx = NULL; } *rsa = ctx; return ret; } /******************************************************************* * * OS/400 QC3 crypto-library backend: Diffie-Hellman support. * *******************************************************************/ void _libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx) { memset((char *) dhctx, 0, sizeof(*dhctx)); } int _libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order) { asn1Element *prime; asn1Element *base; asn1Element *dhparameter; asn1Element *dhkeyagreement; asn1Element *pkcs3; int pkcs3len; char *pubkey; int pubkeysize; int pubkeylen; Qus_EC_t errcode; (void) group_order; /* Build the PKCS#3 structure. */ base = asn1uint(g); prime = asn1uint(p); dhparameter = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, prime, base, NULL); asn1delete(base); asn1delete(prime); dhkeyagreement = asn1bytes(ASN1_OBJ_ID, OID_dhKeyAgreement + 1, OID_dhKeyAgreement[0]); pkcs3 = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, dhkeyagreement, dhparameter, NULL); asn1delete(dhkeyagreement); asn1delete(dhparameter); if(!base || !prime || !dhparameter || !dhkeyagreement || !dhparameter || !pkcs3) { asn1delete(pkcs3); return -1; } pkcs3len = pkcs3->end - pkcs3->header; pubkeysize = (_libssh2_bn_bits(p) + 7) >> 3; pubkey = alloca(pubkeysize); set_EC_length(errcode, sizeof(errcode)); Qc3GenDHKeyPair((char *) pkcs3->header, &pkcs3len, anycsp, NULL, dhctx->token, pubkey, &pubkeysize, &pubkeylen, &errcode); asn1delete(pkcs3); if(errcode.Bytes_Available) return -1; return _libssh2_bn_from_bin(public, pubkeylen, (unsigned char *) pubkey); } int _libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p) { char *pubkey; int pubkeysize; char *secretbuf; int secretbufsize; int secretbuflen; Qus_EC_t errcode; pubkeysize = (_libssh2_bn_bits(f) + 7) >> 3; pubkey = alloca(pubkeysize); _libssh2_bn_to_bin(f, pubkey); secretbufsize = (_libssh2_bn_bits(p) + 7) >> 3; secretbuf = alloca(pubkeysize); set_EC_length(errcode, sizeof(errcode)); Qc3CalculateDHSecretKey(dhctx->token, pubkey, &pubkeysize, secretbuf, &secretbufsize, &secretbuflen, &errcode); if(errcode.Bytes_Available) return -1; return _libssh2_bn_from_bin(secret, secretbuflen, (unsigned char *) secretbuf); } void _libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx) { if(!null_token(dhctx->token)) { Qc3DestroyAlgorithmContext(dhctx->token, (char *) &ecnull); memset((char *) dhctx, 0, sizeof(*dhctx)); } } /******************************************************************* * * OS/400 QC3 crypto-library backend: PKCS#5 supplement. * *******************************************************************/ static int oidcmp(const asn1Element *e, const unsigned char *oid) { int i = e->end - e->beg - *oid++; if(*e->header != ASN1_OBJ_ID) return -2; if(!i) i = memcmp(e->beg, oid, oid[-1]); return i; } static int asn1getword(asn1Element *e, unsigned long *v) { unsigned long a; const unsigned char *cp; if(*e->header != ASN1_INTEGER) return -1; for(cp = e->beg; cp < e->end && !*cp; cp++) ; if(e->end - cp > sizeof(a)) return -1; for(a = 0; cp < e->end; cp++) a = (a << 8) | *cp; *v = a; return 0; } static int pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, pkcs5params *pkcs5) { int i; Qc3_Format_ALGD0100_T hctx; int len = pkcs5->saltlen; char *data = (char *) pkcs5->salt; *dk = NULL; if(pkcs5->dklen > pkcs5->hashlen) return -1; /* Allocate the derived key buffer. */ *dk = LIBSSH2_ALLOC(session, pkcs5->hashlen); if(!*dk) return -1; /* Initial hash. */ libssh2_os400qc3_hash_init(&hctx, pkcs5->hash); libssh2_os400qc3_hash_update(&hctx, passphrase, strlen(passphrase)); hctx.Final_Op_Flag = Qc3_Final; Qc3CalculateHash((char *) pkcs5->salt, &len, Qc3_Data, (char *) &hctx, Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); /* Iterate. */ len = pkcs5->hashlen; for(i = 1; i < pkcs5->itercount; i++) Qc3CalculateHash((char *) *dk, &len, Qc3_Data, (char *) &hctx, Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); /* Special stuff for PBES1: split derived key into 8-byte key and 8-byte initialization vector. */ pkcs5->dklen = 8; pkcs5->ivlen = 8; pkcs5->iv = *dk + 8; /* Clean-up and exit. */ Qc3DestroyAlgorithmContext(hctx.Alg_Context_Token, (char *) &ecnull); return 0; } static int pbkdf2(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, pkcs5params *pkcs5) { size_t i; size_t k; int j; int l; uint32_t ni; unsigned long long t; char *mac; char *buf; _libssh2_os400qc3_crypto_ctx hctx; *dk = NULL; t = ((unsigned long long) pkcs5->dklen + pkcs5->hashlen - 1) / pkcs5->hashlen; if(t > 0xFFFFFFFF) return -1; mac = alloca(pkcs5->hashlen); if(!mac) return -1; /* Allocate the derived key buffer. */ l = t; buf = LIBSSH2_ALLOC(session, l * pkcs5->hashlen); if(!buf) return -1; *dk = buf; /* Create an HMAC context for our computations. */ libssh2_os400qc3_hmac_init(&hctx, pkcs5->hash, pkcs5->hashlen, (void *) passphrase, strlen(passphrase)); /* Process each hLen-size blocks. */ for(i = 1; i <= l; i++) { ni = htonl(i); libssh2_os400qc3_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen); libssh2_os400qc3_hmac_update(&hctx, (char *) &ni, sizeof(ni)); libssh2_os400qc3_hmac_final(&hctx, mac); memcpy(buf, mac, pkcs5->hashlen); for(j = 1; j < pkcs5->itercount; j++) { libssh2_os400qc3_hmac_update(&hctx, mac, pkcs5->hashlen); libssh2_os400qc3_hmac_final(&hctx, mac); for(k = 0; k < pkcs5->hashlen; k++) buf[k] ^= mac[k]; } buf += pkcs5->hashlen; } /* Computation done. Release HMAC context. */ _libssh2_os400qc3_crypto_dtor(&hctx); return 0; } static int parse_pkcs5_algorithm(LIBSSH2_SESSION *session, pkcs5params *pkcs5, asn1Element *algid, pkcs5algo **algotable) { asn1Element oid; asn1Element param; char *cp; cp = getASN1Element(&oid, algid->beg, algid->end); if(!cp || *oid.header != ASN1_OBJ_ID) return -1; param.header = NULL; if(cp < algid->end) cp = getASN1Element(¶m, cp, algid->end); if(cp != algid->end) return -1; for(; *algotable; algotable++) if(!oidcmp(&oid, (*algotable)->oid)) return (*(*algotable)->parse)(session, pkcs5, *algotable, param.header? ¶m: NULL); return -1; } static int parse_pbes2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param) { asn1Element keyDerivationFunc; asn1Element encryptionScheme; char *cp; if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; cp = getASN1Element(&keyDerivationFunc, param->beg, param->end); if(!cp || *keyDerivationFunc.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; if(getASN1Element(&encryptionScheme, cp, param->end) != param->end || *encryptionScheme.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; if(parse_pkcs5_algorithm(session, pkcs5, &encryptionScheme, pbes2enctable)) return -1; if(parse_pkcs5_algorithm(session, pkcs5, &keyDerivationFunc, pbkdf2table)) return -1; return 0; } static int parse_pbkdf2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param) { asn1Element salt; asn1Element iterationCount; asn1Element keyLength; asn1Element prf; unsigned long itercount; char *cp; if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; cp = getASN1Element(&salt, param->beg, param->end); /* otherSource not supported. */ if(!cp || *salt.header != ASN1_OCTET_STRING) return -1; cp = getASN1Element(&iterationCount, cp, param->end); if(!cp || *iterationCount.header != ASN1_INTEGER) return -1; keyLength.header = prf.header = NULL; if(cp < param->end) { cp = getASN1Element(&prf, cp, param->end); if(!cp) return -1; if(*prf.header == ASN1_INTEGER) { keyLength = prf; prf.header = NULL; if(cp < param->end) cp = getASN1Element(&prf, cp, param->end); } if(cp != param->end) return -1; } pkcs5->hash = algo->hash; pkcs5->hashlen = algo->hashlen; if(prf.header) { if(*prf.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; if(parse_pkcs5_algorithm(session, pkcs5, &prf, kdf2prftable)) return -1; } pkcs5->saltlen = salt.end - salt.beg; pkcs5->salt = salt.beg; if(asn1getword(&iterationCount, &itercount) || !itercount || itercount > 100000) return -1; pkcs5->itercount = itercount; pkcs5->kdf = pbkdf2; return 0; } static int parse_hmacWithSHA1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param) { if(!param || *param->header != ASN1_NULL) return -1; pkcs5->hash = algo->hash; pkcs5->hashlen = algo->hashlen; return 0; } static int parse_iv(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param) { if(!param || *param->header != ASN1_OCTET_STRING || param->end - param->beg != algo->ivlen) return -1; pkcs5->cipher = algo->cipher; pkcs5->blocksize = algo->blocksize; pkcs5->mode = algo->mode; pkcs5->padopt = algo->padopt; pkcs5->padchar = algo->padchar; pkcs5->dklen = algo->keylen; pkcs5->ivlen = algo->ivlen; pkcs5->iv = param->beg; return 0; } static int parse_rc2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param) { asn1Element iv; unsigned long effkeysize; char *cp; if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; cp = getASN1Element(&iv, param->beg, param->end); if(!cp) return -1; effkeysize = algo->effkeysize; if(*iv.header == ASN1_INTEGER) { if(asn1getword(&iv, &effkeysize) || effkeysize > 1024) return -1; cp = getASN1Element(&iv, cp, param->end); if(effkeysize < 256) switch(effkeysize) { case 160: effkeysize = 40; case 120: effkeysize = 64; case 58: effkeysize = 128; break; default: return -1; } } if(effkeysize > 1024 || cp != param->end || *iv.header != ASN1_OCTET_STRING || iv.end - iv.beg != algo->ivlen) return -1; pkcs5->cipher = algo->cipher; pkcs5->blocksize = algo->blocksize; pkcs5->mode = algo->mode; pkcs5->padopt = algo->padopt; pkcs5->padchar = algo->padchar; pkcs5->ivlen = algo->ivlen; pkcs5->iv = iv.beg; pkcs5->effkeysize = effkeysize; pkcs5->dklen = (effkeysize + 8 - 1) / 8; return 0; } static int parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, pkcs5algo *algo, asn1Element *param) { asn1Element salt; asn1Element iterationCount; unsigned long itercount; char *cp; if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; cp = getASN1Element(&salt, param->beg, param->end); if(!cp || *salt.header != ASN1_OCTET_STRING || salt.end - salt.beg != algo->saltlen) return -1; if(getASN1Element(&iterationCount, cp, param->end) != param->end || *iterationCount.header != ASN1_INTEGER) return -1; if(asn1getword(&iterationCount, &itercount) || !itercount || itercount > 100000) return -1; pkcs5->cipher = algo->cipher; pkcs5->blocksize = algo->blocksize; pkcs5->mode = algo->mode; pkcs5->padopt = algo->padopt; pkcs5->padchar = algo->padchar; pkcs5->hash = algo->hash; pkcs5->hashlen = algo->hashlen; pkcs5->dklen = 16; pkcs5->saltlen = algo->saltlen; pkcs5->effkeysize = algo->effkeysize; pkcs5->salt = salt.beg; pkcs5->kdf = pbkdf1; pkcs5->itercount = itercount; return 0; } static int pkcs8kek(LIBSSH2_SESSION *session, _libssh2_os400qc3_crypto_ctx **ctx, const unsigned char *data, unsigned int datalen, const unsigned char *passphrase, asn1Element *privkeyinfo) { asn1Element encprivkeyinfo; asn1Element pkcs5alg; pkcs5params pkcs5; size_t pplen; char *cp; unsigned long t; int i; char *dk = NULL; Qc3_Format_ALGD0200_T algd; Qus_EC_t errcode; /* Determine if the PKCS#8 data is encrypted and, if so, set-up a key encryption key and algorithm in context. Return 1 if encrypted, 0, if not, -1 if error. */ *ctx = NULL; privkeyinfo->beg = (char *) data; privkeyinfo->end = privkeyinfo->beg + datalen; /* If no passphrase is given, it cannot be an encrypted key. */ if(!passphrase || !*passphrase) return 0; /* Parse PKCS#8 data, checking if ASN.1 format is PrivateKeyInfo or EncryptedPrivateKeyInfo. */ if(getASN1Element(&encprivkeyinfo, privkeyinfo->beg, privkeyinfo->end) != (char *) data + datalen || *encprivkeyinfo.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; cp = getASN1Element(&pkcs5alg, encprivkeyinfo.beg, encprivkeyinfo.end); if(!cp) return -1; switch(*pkcs5alg.header) { case ASN1_INTEGER: /* Version. */ return 0; /* This is a PrivateKeyInfo --> not encrypted. */ case ASN1_SEQ | ASN1_CONSTRUCTED: /* AlgorithIdentifier. */ break; /* This is an EncryptedPrivateKeyInfo --> encrypted. */ default: return -1; /* Unrecognized: error. */ } /* Get the encrypted key data. */ if(getASN1Element(privkeyinfo, cp, encprivkeyinfo.end) != encprivkeyinfo.end || *privkeyinfo->header != ASN1_OCTET_STRING) return -1; /* PKCS#5: parse the PBES AlgorithmIdentifier and recursively get all encryption parameters. */ memset((char *) &pkcs5, 0, sizeof(pkcs5)); if(parse_pkcs5_algorithm(session, &pkcs5, &pkcs5alg, pbestable)) return -1; /* Compute the derived key. */ if((*pkcs5.kdf)(session, &dk, passphrase, &pkcs5)) return -1; /* Prepare the algorithm descriptor. */ memset((char *) &algd, 0, sizeof(algd)); algd.Block_Cipher_Alg = pkcs5.cipher; algd.Block_Length = pkcs5.blocksize; algd.Mode = pkcs5.mode; algd.Pad_Option = pkcs5.padopt; algd.Pad_Character = pkcs5.padchar; algd.Effective_Key_Size = pkcs5.effkeysize; memcpy(algd.Init_Vector, pkcs5.iv, pkcs5.ivlen); /* Create the key and algorithm context tokens. */ *ctx = libssh2_init_crypto_ctx(NULL); if(!*ctx) { LIBSSH2_FREE(session, dk); return -1; } libssh2_init_crypto_ctx(*ctx); set_EC_length(errcode, sizeof(errcode)); Qc3CreateKeyContext(dk, &pkcs5.dklen, binstring, &algd.Block_Cipher_Alg, qc3clear, NULL, NULL, (*ctx)->key.Key_Context_Token, (char *) &errcode); LIBSSH2_FREE(session, dk); if(errcode.Bytes_Available) { free((char *) *ctx); *ctx = NULL; return -1; } Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Block_Cipher, (*ctx)->hash.Alg_Context_Token, &errcode); if(errcode.Bytes_Available) { Qc3DestroyKeyContext((*ctx)->key.Key_Context_Token, (char *) &ecnull); free((char *) *ctx); *ctx = NULL; return -1; } return 1; /* Tell it's encrypted. */ } static int rsapkcs8privkey(LIBSSH2_SESSION *session, const unsigned char *data, unsigned int datalen, const unsigned char *passphrase, void *loadkeydata) { libssh2_rsa_ctx *ctx = (libssh2_rsa_ctx *) loadkeydata; char keyform = Qc3_Clear; char *kek = NULL; char *kea = NULL; _libssh2_os400qc3_crypto_ctx *kekctx; asn1Element pki; int pkilen; Qus_EC_t errcode; switch(pkcs8kek(session, &kekctx, data, datalen, passphrase, &pki)) { case 1: keyform = Qc3_Encrypted; kek = kekctx->key.Key_Context_Token; kea = kekctx->hash.Alg_Context_Token; case 0: break; default: return -1; } set_EC_length(errcode, sizeof(errcode)); pkilen = pki.end - pki.beg; Qc3CreateKeyContext((unsigned char *) pki.beg, &pkilen, berstring, rsaprivate, &keyform, kek, kea, ctx->key.Key_Context_Token, (char *) &errcode); if(errcode.Bytes_Available) { if(kekctx) _libssh2_os400qc3_crypto_dtor(kekctx); return -1; } ctx->kek = kekctx; return 0; } static char * storewithlength(char *p, const char *data, int length) { _libssh2_htonu32(p, length); if(length) memcpy(p + 4, data, length); return p + 4 + length; } static int sshrsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, asn1Element *params, asn1Element *key, const char *method) { int methlen = strlen(method); asn1Element keyseq; asn1Element m; asn1Element e; int len; char *cp; if(getASN1Element(&keyseq, key->beg + 1, key->end) != key->end || *keyseq.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; if(!getASN1Element(&m, keyseq.beg, keyseq.end) || *m.header != ASN1_INTEGER) return -1; if(getASN1Element(&e, m.end, keyseq.end) != keyseq.end || *e.header != ASN1_INTEGER) return -1; len = 4 + methlen + 4 + (e.end - e.beg) + 4 + (m.end - m.beg); cp = LIBSSH2_ALLOC(session, len); if(!cp) return -1; *sshpubkey = cp; cp = storewithlength(cp, method, methlen); cp = storewithlength(cp, e.beg, e.end - e.beg); cp = storewithlength(cp, m.beg, m.end - m.beg); return len; } static int rsapkcs8pubkey(LIBSSH2_SESSION *session, const unsigned char *data, unsigned int datalen, const unsigned char *passphrase, void *loadkeydata) { loadpubkeydata *p = (loadpubkeydata *) loadkeydata; char *buf; int len; char *cp; int i; char keyform = Qc3_Clear; char *kek = NULL; char *kea = NULL; _libssh2_os400qc3_crypto_ctx *kekctx; asn1Element subjpubkeyinfo; asn1Element algorithmid; asn1Element algorithm; asn1Element subjpubkey; asn1Element parameters; asn1Element pki; int pkilen; Qus_EC_t errcode; buf = alloca(datalen); if(!buf) return -1; switch(pkcs8kek(session, &kekctx, data, datalen, passphrase, &pki)) { case 1: keyform = Qc3_Encrypted; kek = kekctx->key.Key_Context_Token; kea = kekctx->hash.Alg_Context_Token; case 0: break; default: return -1; } set_EC_length(errcode, sizeof(errcode)); pkilen = pki.end - pki.beg; Qc3ExtractPublicKey(pki.beg, &pkilen, berstring, &keyform, kek, kea, buf, (int *) &datalen, &len, &errcode); _libssh2_os400qc3_crypto_dtor(kekctx); if(errcode.Bytes_Available) return -1; /* Get the algorithm OID and key data from SubjectPublicKeyInfo. */ if(getASN1Element(&subjpubkeyinfo, buf, buf + len) != buf + len || *subjpubkeyinfo.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; cp = getASN1Element(&algorithmid, subjpubkeyinfo.beg, subjpubkeyinfo.end); if(!cp || *algorithmid.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) return -1; if(!getASN1Element(&algorithm, algorithmid.beg, algorithmid.end) || *algorithm.header != ASN1_OBJ_ID) return -1; if(getASN1Element(&subjpubkey, cp, subjpubkeyinfo.end) != subjpubkeyinfo.end || *subjpubkey.header != ASN1_BIT_STRING) return -1; /* Check for supported algorithm. */ for(i = 0; pka[i].oid; i++) if(!oidcmp(&algorithm, pka[i].oid)) { len = (*pka[i].sshpubkey)(session, &p->data, &algorithmid, &subjpubkey, pka[i].method); if(len < 0) return -1; p->length = len; p->method = pka[i].method; return 0; } return -1; /* Algorithm not supported. */ } static int pkcs1topkcs8(LIBSSH2_SESSION *session, const unsigned char **data8, unsigned int *datalen8, const unsigned char *data1, unsigned int datalen1) { asn1Element *prvk; asn1Element *pkcs8; unsigned char *data; *data8 = NULL; *datalen8 = 0; if(datalen1 < 2) return -1; prvk = asn1_new_from_bytes(data1, datalen1); if(!prvk) return -1; pkcs8 = rsaprivatekeyinfo(prvk); asn1delete(prvk); if(!prvk) { asn1delete(pkcs8); pkcs8 = NULL; } if(!pkcs8) return -1; data = (unsigned char *) LIBSSH2_ALLOC(session, pkcs8->end - pkcs8->header); if(!data) { asn1delete(pkcs8); return -1; } *data8 = data; *datalen8 = pkcs8->end - pkcs8->header; memcpy((char *) data, (char *) pkcs8->header, *datalen8); asn1delete(pkcs8); return 0; } static int rsapkcs1privkey(LIBSSH2_SESSION *session, const unsigned char *data, unsigned int datalen, const unsigned char *passphrase, void *loadkeydata) { const unsigned char *data8; unsigned int datalen8; int ret; if(pkcs1topkcs8(session, &data8, &datalen8, data, datalen)) return -1; ret = rsapkcs8privkey(session, data8, datalen8, passphrase, loadkeydata); LIBSSH2_FREE(session, (char *) data8); return ret; } static int rsapkcs1pubkey(LIBSSH2_SESSION *session, const unsigned char *data, unsigned int datalen, const unsigned char *passphrase, void *loadkeydata) { const unsigned char *data8; unsigned int datalen8; int ret; if(pkcs1topkcs8(session, &data8, &datalen8, data, datalen)) return -1; ret = rsapkcs8pubkey(session, data8, datalen8, passphrase, loadkeydata); LIBSSH2_FREE(session, (char *) data8); return ret; } static int try_pem_load(LIBSSH2_SESSION *session, FILE *fp, const unsigned char *passphrase, const char *header, const char *trailer, loadkeyproc proc, void *loadkeydata) { unsigned char *data = NULL; size_t datalen = 0; int c; int ret; fseek(fp, 0L, SEEK_SET); for(;;) { ret = _libssh2_pem_parse(session, header, trailer, passphrase, fp, &data, &datalen); if(!ret) { ret = (*proc)(session, data, datalen, passphrase, loadkeydata); if(!ret) return 0; } if(data) { LIBSSH2_FREE(session, data); data = NULL; } c = getc(fp); if(c == EOF) break; ungetc(c, fp); } return -1; } static int load_rsa_private_file(LIBSSH2_SESSION *session, const char *filename, unsigned const char *passphrase, loadkeyproc proc1, loadkeyproc proc8, void *loadkeydata) { FILE *fp = fopen(filename, fopenrmode); unsigned char *data = NULL; size_t datalen = 0; int ret; long filesize; if(!fp) return -1; /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. --> PKCS#8 EncryptedPrivateKeyInfo */ ret = try_pem_load(session, fp, passphrase, beginencprivkeyhdr, endencprivkeyhdr, proc8, loadkeydata); /* Try with "PRIVATE KEY" PEM armor. --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ if(ret) ret = try_pem_load(session, fp, passphrase, beginprivkeyhdr, endprivkeyhdr, proc8, loadkeydata); /* Try with "RSA PRIVATE KEY" PEM armor. --> PKCS#1 RSAPrivateKey */ if(ret) ret = try_pem_load(session, fp, passphrase, beginrsaprivkeyhdr, endrsaprivkeyhdr, proc1, loadkeydata); fclose(fp); if(ret) { /* Try DER encoding. */ fp = fopen(filename, fopenrbmode); fseek(fp, 0L, SEEK_END); filesize = ftell(fp); if(filesize <= 32768) { /* Limit to a reasonable size. */ datalen = filesize; data = (unsigned char *) alloca(datalen); if(data) { fseek(fp, 0L, SEEK_SET); fread(data, datalen, 1, fp); /* Try as PKCS#8 DER data. --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ ret = (*proc8)(session, data, datalen, passphrase, loadkeydata); /* Try as PKCS#1 DER data. --> PKCS#1 RSAPrivateKey */ if(ret) ret = (*proc1)(session, data, datalen, passphrase, loadkeydata); } } fclose(fp); } return ret; } int _libssh2_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, unsigned const char *passphrase) { libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL); int ret; if(!ctx) return -1; ret = load_rsa_private_file(session, filename, passphrase, rsapkcs1privkey, rsapkcs8privkey, (void *) ctx); if(ret) { _libssh2_os400qc3_crypto_dtor(ctx); ctx = NULL; } *rsa = ctx; return ret; } int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { loadpubkeydata p; int ret; *method = NULL; *method_len = 0; *pubkeydata = NULL; *pubkeydata_len = 0; ret = load_rsa_private_file(session, privatekey, passphrase, rsapkcs1pubkey, rsapkcs8pubkey, (void *) &p); if(!ret) { *method_len = strlen(p.method); *method = LIBSSH2_ALLOC(session, *method_len); if(*method) memcpy((char *) *method, p.method, *method_len); else ret = -1; } if(ret) { if(*method) LIBSSH2_FREE(session, *method); if(p.data) LIBSSH2_FREE(session, (void *) p.data); *method = NULL; *method_len = 0; } else { *pubkeydata = (unsigned char *) p.data; *pubkeydata_len = p.length; } return ret; } int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL); unsigned char *data = NULL; size_t datalen = 0; int ret; if(!ctx) return -1; /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. --> PKCS#8 EncryptedPrivateKeyInfo */ ret = _libssh2_pem_parse_memory(session, beginencprivkeyhdr, endencprivkeyhdr, filedata, filedata_len, &data, &datalen); /* Try with "PRIVATE KEY" PEM armor. --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ if(ret) ret = _libssh2_pem_parse_memory(session, beginprivkeyhdr, endprivkeyhdr, filedata, filedata_len, &data, &datalen); if(!ret) { /* Process PKCS#8. */ ret = rsapkcs8privkey(session, data, datalen, passphrase, (void *) &ctx); } else { /* Try with "RSA PRIVATE KEY" PEM armor. --> PKCS#1 RSAPrivateKey */ ret = _libssh2_pem_parse_memory(session, beginrsaprivkeyhdr, endrsaprivkeyhdr, filedata, filedata_len, &data, &datalen); if(!ret) ret = rsapkcs1privkey(session, data, datalen, passphrase, (void *) &ctx); } if(ret) { /* Try as PKCS#8 DER data. --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ ret = rsapkcs8privkey(session, filedata, filedata_len, passphrase, (void *) &ctx); /* Try as PKCS#1 DER data. --> PKCS#1 RSAPrivateKey */ if(ret) ret = rsapkcs1privkey(session, filedata, filedata_len, passphrase, (void *) &ctx); } if(data) LIBSSH2_FREE(session, data); if(ret) { _libssh2_os400qc3_crypto_dtor(ctx); ctx = NULL; } *rsa = ctx; return ret; } int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { loadpubkeydata p; unsigned char *data = NULL; size_t datalen = 0; const char *meth; int ret; *method = NULL; *method_len = 0; *pubkeydata = NULL; *pubkeydata_len = 0; /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. --> PKCS#8 EncryptedPrivateKeyInfo */ ret = _libssh2_pem_parse_memory(session, beginencprivkeyhdr, endencprivkeyhdr, privatekeydata, privatekeydata_len, &data, &datalen); /* Try with "PRIVATE KEY" PEM armor. --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ if(ret) ret = _libssh2_pem_parse_memory(session, beginprivkeyhdr, endprivkeyhdr, privatekeydata, privatekeydata_len, &data, &datalen); if(!ret) { /* Process PKCS#8. */ ret = rsapkcs8pubkey(session, data, datalen, passphrase, (void *) &p); } else { /* Try with "RSA PRIVATE KEY" PEM armor. --> PKCS#1 RSAPrivateKey */ ret = _libssh2_pem_parse_memory(session, beginrsaprivkeyhdr, endrsaprivkeyhdr, privatekeydata, privatekeydata_len, &data, &datalen); if(!ret) ret = rsapkcs1pubkey(session, data, datalen, passphrase, (void *) &p); } if(ret) { /* Try as PKCS#8 DER data. --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ ret = rsapkcs8pubkey(session, privatekeydata, privatekeydata_len, passphrase, (void *) &p); /* Try as PKCS#1 DER data. --> PKCS#1 RSAPrivateKey */ if(ret) ret = rsapkcs1pubkey(session, privatekeydata, privatekeydata_len, passphrase, (void *) &p); } if(data) LIBSSH2_FREE(session, data); if(!ret) { *method_len = strlen(p.method); *method = LIBSSH2_ALLOC(session, *method_len); if(*method) memcpy((char *) *method, p.method, *method_len); else ret = -1; } if(ret) { if(*method) LIBSSH2_FREE(session, *method); if(p.data) LIBSSH2_FREE(session, (void *) p.data); *method = NULL; *method_len = 0; } else { *pubkeydata = (unsigned char *) p.data; *pubkeydata_len = p.length; } return ret; } int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public SK key from private key file: " "Method unimplemented in OS/400 QC3 backend"); } int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx *rsa, size_t hash_len, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { Qus_EC_t errcode; Qc3_Format_ALGD0400_T algd; int slen = (int)sig_len; int mlen = (int)m_len; memset(&algd, 0, sizeof(algd)); algd.Public_Key_Alg = Qc3_RSA; algd.PKA_Block_Format = Qc3_PKCS1_01; switch(hash_len) { case SHA_DIGEST_LENGTH: algd.Signing_Hash_Alg = Qc3_SHA1; break; case SHA256_DIGEST_LENGTH: algd.Signing_Hash_Alg = Qc3_SHA256; break; case SHA512_DIGEST_LENGTH: algd.Signing_Hash_Alg = Qc3_SHA512; break; default: return -1; } set_EC_length(errcode, sizeof(errcode)); Qc3VerifySignature((char *) sig, &slen, (char *) m, &mlen, Qc3_Data, (char *) &algd, Qc3_Alg_Public_Key, (char *) &rsa->key, Qc3_Key_Token, anycsp, NULL, (char *) &errcode); return errcode.Bytes_Available? -1: 0; } int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len) { return _libssh2_rsa_sha2_verify(rsa, SHA_DIGEST_LENGTH, sig, sig_len, m, m_len); } int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec vector[], libssh2_rsa_ctx *ctx) { Qus_EC_t errcode; Qc3_Format_ALGD0400_T algd; int siglen; unsigned char *sig; char sigbuf[8192]; int sigbufsize = sizeof(sigbuf); algd.Public_Key_Alg = Qc3_RSA; algd.PKA_Block_Format = Qc3_PKCS1_01; memset(algd.Reserved, 0, sizeof(algd.Reserved)); algd.Signing_Hash_Alg = algo; set_EC_length(errcode, sizeof(errcode)); Qc3CalculateSignature((char *) vector, &veccount, Qc3_Array, (char *) &algd, Qc3_Alg_Public_Key, (char *) &ctx->key, Qc3_Key_Token, anycsp, NULL, sigbuf, &sigbufsize, &siglen, (char *) &errcode); if(errcode.Bytes_Available) return -1; sig = LIBSSH2_ALLOC(session, siglen); if(!sig) return -1; memcpy((char *) sig, sigbuf, siglen); *signature = sig; *signature_len = siglen; return 0; } /* _libssh2_supported_key_sign_algorithms * * Return supported key hash algo upgrades, see crypto.h * */ const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len) { (void)session; if(key_method_len == 7 && memcmp(key_method, "ssh-rsa", key_method_len) == 0) { return "rsa-sha2-512,rsa-sha2-256,ssh-rsa"; } return NULL; } #endif /* LIBSSH2_CRYPTO_C */ /* vim: set expandtab ts=4 sw=4: */ libssh2-1.11.0/src/mac.h0000644000175000017500000000502114424650606011566 00000000000000#ifndef __LIBSSH2_MAC_H #define __LIBSSH2_MAC_H /* Copyright (C) 2009-2010 by Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ #include "libssh2_priv.h" struct _LIBSSH2_MAC_METHOD { const char *name; /* The length of a given MAC packet */ int mac_len; /* integrity key length */ int key_len; /* Message Authentication Code Hashing algo */ int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key, void **abstract); int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf, uint32_t seqno, const unsigned char *packet, size_t packet_len, const unsigned char *addtl, size_t addtl_len, void **abstract); int (*dtor) (LIBSSH2_SESSION * session, void **abstract); int etm; /* encrypt-then-mac */ }; typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD; const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void); const LIBSSH2_MAC_METHOD *_libssh2_mac_override( const LIBSSH2_CRYPT_METHOD *crypt); #endif /* __LIBSSH2_MAC_H */ libssh2-1.11.0/src/CMakeLists.txt0000644000175000017500000001770214435416425013427 00000000000000# Copyright (c) 2014 Alexander Lamaison # Copyright (c) 2023 Viktor Szakats # # Redistribution and use in source and binary forms, # with or without modification, are permitted provided # that the following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the # following disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # # Neither the name of the copyright holder nor the names # of any other contributors may be used to endorse or # promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. if(CRYPTO_BACKEND) list(APPEND PRIVATE_COMPILE_DEFINITIONS ${CRYPTO_BACKEND_DEFINE}) list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CRYPTO_BACKEND_INCLUDE_DIR}) else() message(FATAL_ERROR "No suitable cryptography backend found.") endif() ## Options option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON) if(NOT CLEAR_MEMORY) list(APPEND libssh2_DEFINITIONS LIBSSH2_NO_CLEAR_MEMORY) endif() option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression") add_feature_info(Compression ENABLE_ZLIB_COMPRESSION "using zlib for compression") if(ENABLE_ZLIB_COMPRESSION) find_package(ZLIB REQUIRED) list(APPEND libssh2_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS}) list(APPEND LIBRARIES ${ZLIB_LIBRARIES}) list(APPEND PC_REQUIRES_PRIVATE zlib) if(ZLIB_FOUND) list(APPEND libssh2_DEFINITIONS LIBSSH2_HAVE_ZLIB) endif() endif() list(APPEND LIBRARIES ${SOCKET_LIBRARIES}) if(WIN32) list(APPEND PC_LIBS -lws2_32) endif() # to find generated header list(APPEND libssh2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}) if(MSVC) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od") set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") endif() ## Sources include(GNUInstallDirs) transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") # Get 'CSOURCES' and 'HHEADERS' variables include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) set(SOURCES ${CSOURCES} ${HHEADERS}) ## Library definition # Ensure that the static library and import library filenames are different, # when building both static and shared library. On Windows, with certain # toolchains (e.g. MSVC) these libraries get the same by default, overwriting # each other. MinGW is not affected. if(WIN32 AND BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS AND NOT STATIC_LIB_SUFFIX AND NOT IMPORT_LIB_SUFFIX AND CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX) set(STATIC_LIB_SUFFIX "_static") endif() # we want it to be called libssh2 on all platforms if(BUILD_STATIC_LIBS) list(APPEND libssh2_export ${LIB_STATIC}) add_library(${LIB_STATIC} STATIC ${SOURCES}) target_compile_definitions(${LIB_STATIC} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${libssh2_DEFINITIONS}) target_link_libraries(${LIB_STATIC} PRIVATE ${LIBRARIES}) set_target_properties(${LIB_STATIC} PROPERTIES PREFIX "" OUTPUT_NAME "libssh2") set_target_properties(${LIB_STATIC} PROPERTIES SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}") target_include_directories(${LIB_STATIC} PRIVATE "${PROJECT_SOURCE_DIR}/include/" ${libssh2_INCLUDE_DIRS} ${PRIVATE_INCLUDE_DIRECTORIES} PUBLIC $ $/${CMAKE_INSTALL_INCLUDEDIR}>) endif() if(BUILD_SHARED_LIBS) list(APPEND libssh2_export ${LIB_SHARED}) add_library(${LIB_SHARED} SHARED ${SOURCES}) if(WIN32) set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES libssh2.rc) endif() target_compile_definitions(${LIB_SHARED} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${libssh2_DEFINITIONS} ${LIB_SHARED_DEFINITIONS}) target_compile_options(${LIB_SHARED} PRIVATE ${LIB_SHARED_C_FLAGS}) target_link_libraries(${LIB_SHARED} PRIVATE ${LIBRARIES}) set_target_properties(${LIB_SHARED} PROPERTIES PREFIX "" IMPORT_PREFIX "" OUTPUT_NAME "libssh2") set_target_properties(${LIB_SHARED} PROPERTIES IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}") set_target_properties(${LIB_SHARED} PROPERTIES POSITION_INDEPENDENT_CODE ON) target_include_directories(${LIB_SHARED} PRIVATE "${PROJECT_SOURCE_DIR}/include/" ${libssh2_INCLUDE_DIRS} ${PRIVATE_INCLUDE_DIRECTORIES} PUBLIC $ $/${CMAKE_INSTALL_INCLUDEDIR}>) endif() ## Installation install(FILES ${PROJECT_SOURCE_DIR}/include/libssh2.h ${PROJECT_SOURCE_DIR}/include/libssh2_publickey.h ${PROJECT_SOURCE_DIR}/include/libssh2_sftp.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(BUILD_STATIC_LIBS) install(TARGETS ${LIB_STATIC} EXPORT Libssh2Config RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() if(BUILD_SHARED_LIBS) install(TARGETS ${LIB_SHARED} EXPORT Libssh2Config RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) list(APPEND _RUNTIME_DEPENDENCIES $) endif() set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL "Files that must be in the same directory as the executables at runtime.") # Package config ## During package installation, install Libssh2Config.cmake install(EXPORT Libssh2Config NAMESPACE Libssh2:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libssh2) ## During build, register directly from build tree # create Libssh2Config.cmake export(TARGETS ${libssh2_export} NAMESPACE Libssh2:: FILE Libssh2Config.cmake) export(PACKAGE Libssh2) # register it ## Export a .pc file for client projects not using CMaek if(PC_REQUIRES_PRIVATE) string(REPLACE ";" "," PC_REQUIRES_PRIVATE "${PC_REQUIRES_PRIVATE}") endif() if(PC_LIBS) string(REPLACE ";" " " PC_LIBS "${PC_LIBS}") endif() set(LIBSSH2VER ${LIBSSH2_VERSION}) set(LIBSREQUIRED ${PC_REQUIRES_PRIVATE}) set(LIBS ${PC_LIBS}) set(prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix "\${prefix}") set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}") set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") configure_file(${CMAKE_SOURCE_DIR}/libssh2.pc.in libssh2.pc @ONLY) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) ## Versioning set(LIBSSH2_SOVERSION 1) set(LIBSSH2_VERSION 1.0.1) if(BUILD_STATIC_LIBS) set_target_properties(${LIB_STATIC} PROPERTIES SOVERSION ${LIBSSH2_SOVERSION} VERSION ${LIBSSH2_VERSION}) endif() if(BUILD_SHARED_LIBS) set_target_properties(${LIB_SHARED} PROPERTIES SOVERSION ${LIBSSH2_SOVERSION} VERSION ${LIBSSH2_VERSION}) endif() include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}" COMPATIBILITY SameMajorVersion) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libssh2) libssh2-1.11.0/src/hostkey.c0000644000175000017500000011464514424650606012524 00000000000000/* Copyright (c) 2004-2006, Sara Golemon * Copyright (c) 2009-2019 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" /* Needed for struct iovec on some platforms */ #ifdef HAVE_SYS_UIO_H #include #endif #if LIBSSH2_RSA /* *********** * ssh-rsa * *********** */ static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract); /* * hostkey_method_ssh_rsa_init * * Initialize the server hostkey working area with e/n pair */ static int hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session, const unsigned char *hostkey_data, size_t hostkey_data_len, void **abstract) { libssh2_rsa_ctx *rsactx; unsigned char *e, *n, *type; size_t e_len, n_len, type_len; struct string_buf buf; if(*abstract) { hostkey_method_ssh_rsa_dtor(session, abstract); *abstract = NULL; } if(hostkey_data_len < 19) { _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "host key length too short")); return -1; } buf.data = (unsigned char *)hostkey_data; buf.dataptr = buf.data; buf.len = hostkey_data_len; if(_libssh2_get_string(&buf, &type, &type_len)) { return -1; } /* we accept one of 3 header types */ #if LIBSSH2_RSA_SHA1 if(type_len == 7 && strncmp("ssh-rsa", (char *)type, 7) == 0) { /* ssh-rsa */ } else #endif #if LIBSSH2_RSA_SHA2 if(type_len == 12 && strncmp("rsa-sha2-256", (char *)type, 12) == 0) { /* rsa-sha2-256 */ } else if(type_len == 12 && strncmp("rsa-sha2-512", (char *)type, 12) == 0) { /* rsa-sha2-512 */ } else #endif { _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "unexpected rsa type: %.*s", type_len, type)); return -1; } if(_libssh2_get_string(&buf, &e, &e_len)) return -1; if(_libssh2_get_string(&buf, &n, &n_len)) return -1; if(!_libssh2_eob(&buf)) return -1; if(_libssh2_rsa_new(&rsactx, e, (unsigned long)e_len, n, (unsigned long)n_len, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) { return -1; } *abstract = rsactx; return 0; } /* * hostkey_method_ssh_rsa_initPEM * * Load a Private Key from a PEM file */ static int hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session, const char *privkeyfile, unsigned const char *passphrase, void **abstract) { libssh2_rsa_ctx *rsactx; int ret; if(*abstract) { hostkey_method_ssh_rsa_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase); if(ret) { return -1; } *abstract = rsactx; return 0; } /* * hostkey_method_ssh_rsa_initPEMFromMemory * * Load a Private Key from a memory */ static int hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session, const char *privkeyfiledata, size_t privkeyfiledata_len, unsigned const char *passphrase, void **abstract) { libssh2_rsa_ctx *rsactx; int ret; if(*abstract) { hostkey_method_ssh_rsa_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_rsa_new_private_frommemory(&rsactx, session, privkeyfiledata, privkeyfiledata_len, passphrase); if(ret) { return -1; } *abstract = rsactx; return 0; } #if LIBSSH2_RSA_SHA1 /* * hostkey_method_ssh_rsa_sign * * Verify signature created by remote */ static int hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); (void)session; /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ if(sig_len < 15) return -1; sig += 15; sig_len -= 15; return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len); } /* * hostkey_method_ssh_rsa_signv * * Construct a signature from an array of vectors */ static int hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); #ifdef _libssh2_rsa_sha1_signv return _libssh2_rsa_sha1_signv(session, signature, signature_len, veccount, datavec, rsactx); #else int ret; int i; unsigned char hash[SHA_DIGEST_LENGTH]; libssh2_sha1_ctx ctx; (void)libssh2_sha1_init(&ctx); for(i = 0; i < veccount; i++) { libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); } libssh2_sha1_final(ctx, hash); ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, signature, signature_len); if(ret) { return -1; } return 0; #endif } #endif /* * hostkey_method_ssh_rsa_sha2_256_sig_verify * * Verify signature created by remote */ #if LIBSSH2_RSA_SHA2 static int hostkey_method_ssh_rsa_sha2_256_sig_verify(LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); (void)session; /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-256"} + signature_len(4) */ if(sig_len < 20) return -1; sig += 20; sig_len -= 20; return _libssh2_rsa_sha2_verify(rsactx, SHA256_DIGEST_LENGTH, sig, sig_len, m, m_len); } /* * hostkey_method_ssh_rsa_sha2_256_signv * * Construct a signature from an array of vectors */ static int hostkey_method_ssh_rsa_sha2_256_signv(LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); #ifdef _libssh2_rsa_sha2_256_signv return _libssh2_rsa_sha2_256_signv(session, signature, signature_len, veccount, datavec, rsactx); #else int ret; int i; unsigned char hash[SHA256_DIGEST_LENGTH]; libssh2_sha256_ctx ctx; if(!libssh2_sha256_init(&ctx)) { return -1; } for(i = 0; i < veccount; i++) { libssh2_sha256_update(ctx, datavec[i].iov_base, datavec[i].iov_len); } libssh2_sha256_final(ctx, hash); ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA256_DIGEST_LENGTH, signature, signature_len); if(ret) { return -1; } return 0; #endif } /* * hostkey_method_ssh_rsa_sha2_512_sig_verify * * Verify signature created by remote */ static int hostkey_method_ssh_rsa_sha2_512_sig_verify(LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); (void)session; /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-512"} + signature_len(4) */ if(sig_len < 20) return -1; sig += 20; sig_len -= 20; return _libssh2_rsa_sha2_verify(rsactx, SHA512_DIGEST_LENGTH, sig, sig_len, m, m_len); } /* * hostkey_method_ssh_rsa_sha2_512_signv * * Construct a signature from an array of vectors */ static int hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); #ifdef _libssh2_rsa_sha2_512_signv return _libssh2_rsa_sha2_512_signv(session, signature, signature_len, veccount, datavec, rsactx); #else int ret; int i; unsigned char hash[SHA512_DIGEST_LENGTH]; libssh2_sha512_ctx ctx; if(!libssh2_sha512_init(&ctx)) { return -1; } for(i = 0; i < veccount; i++) { libssh2_sha512_update(ctx, datavec[i].iov_base, datavec[i].iov_len); } libssh2_sha512_final(ctx, hash); ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA512_DIGEST_LENGTH, signature, signature_len); if(ret) { return -1; } return 0; #endif } #endif /* LIBSSH2_RSA_SHA2 */ /* * hostkey_method_ssh_rsa_dtor * * Shutdown the hostkey */ static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract) { libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); (void)session; _libssh2_rsa_free(rsactx); *abstract = NULL; return 0; } #if LIBSSH2_RSA_SHA1 static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = { "ssh-rsa", SHA_DIGEST_LENGTH, hostkey_method_ssh_rsa_init, hostkey_method_ssh_rsa_initPEM, hostkey_method_ssh_rsa_initPEMFromMemory, hostkey_method_ssh_rsa_sig_verify, hostkey_method_ssh_rsa_signv, NULL, /* encrypt */ hostkey_method_ssh_rsa_dtor, }; #endif /* LIBSSH2_RSA_SHA1 */ #if LIBSSH2_RSA_SHA2 static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_256 = { "rsa-sha2-256", SHA256_DIGEST_LENGTH, hostkey_method_ssh_rsa_init, hostkey_method_ssh_rsa_initPEM, hostkey_method_ssh_rsa_initPEMFromMemory, hostkey_method_ssh_rsa_sha2_256_sig_verify, hostkey_method_ssh_rsa_sha2_256_signv, NULL, /* encrypt */ hostkey_method_ssh_rsa_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_512 = { "rsa-sha2-512", SHA512_DIGEST_LENGTH, hostkey_method_ssh_rsa_init, hostkey_method_ssh_rsa_initPEM, hostkey_method_ssh_rsa_initPEMFromMemory, hostkey_method_ssh_rsa_sha2_512_sig_verify, hostkey_method_ssh_rsa_sha2_512_signv, NULL, /* encrypt */ hostkey_method_ssh_rsa_dtor, }; #endif /* LIBSSH2_RSA_SHA2 */ #if LIBSSH2_RSA_SHA1 static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_cert = { "ssh-rsa-cert-v01@openssh.com", SHA_DIGEST_LENGTH, NULL, hostkey_method_ssh_rsa_initPEM, hostkey_method_ssh_rsa_initPEMFromMemory, NULL, hostkey_method_ssh_rsa_signv, NULL, /* encrypt */ hostkey_method_ssh_rsa_dtor, }; #endif /* LIBSSH2_RSA_SHA1 */ #endif /* LIBSSH2_RSA */ #if LIBSSH2_DSA /* *********** * ssh-dss * *********** */ static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract); /* * hostkey_method_ssh_dss_init * * Initialize the server hostkey working area with p/q/g/y set */ static int hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session, const unsigned char *hostkey_data, size_t hostkey_data_len, void **abstract) { libssh2_dsa_ctx *dsactx; unsigned char *p, *q, *g, *y; size_t p_len, q_len, g_len, y_len; struct string_buf buf; if(*abstract) { hostkey_method_ssh_dss_dtor(session, abstract); *abstract = NULL; } if(hostkey_data_len < 27) { _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "host key length too short")); return -1; } buf.data = (unsigned char *)hostkey_data; buf.dataptr = buf.data; buf.len = hostkey_data_len; if(_libssh2_match_string(&buf, "ssh-dss")) return -1; if(_libssh2_get_string(&buf, &p, &p_len)) return -1; if(_libssh2_get_string(&buf, &q, &q_len)) return -1; if(_libssh2_get_string(&buf, &g, &g_len)) return -1; if(_libssh2_get_string(&buf, &y, &y_len)) return -1; if(!_libssh2_eob(&buf)) return -1; if(_libssh2_dsa_new(&dsactx, p, (unsigned long)p_len, q, (unsigned long)q_len, g, (unsigned long)g_len, y, (unsigned long)y_len, NULL, 0)) { return -1; } *abstract = dsactx; return 0; } /* * hostkey_method_ssh_dss_initPEM * * Load a Private Key from a PEM file */ static int hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session, const char *privkeyfile, unsigned const char *passphrase, void **abstract) { libssh2_dsa_ctx *dsactx; int ret; if(*abstract) { hostkey_method_ssh_dss_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase); if(ret) { return -1; } *abstract = dsactx; return 0; } /* * hostkey_method_ssh_dss_initPEMFromMemory * * Load a Private Key from memory */ static int hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session, const char *privkeyfiledata, size_t privkeyfiledata_len, unsigned const char *passphrase, void **abstract) { libssh2_dsa_ctx *dsactx; int ret; if(*abstract) { hostkey_method_ssh_dss_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_dsa_new_private_frommemory(&dsactx, session, privkeyfiledata, privkeyfiledata_len, passphrase); if(ret) { return -1; } *abstract = dsactx; return 0; } /* * libssh2_hostkey_method_ssh_dss_sign * * Verify signature created by remote */ static int hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract) { libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ if(sig_len != 55) { return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length"); } sig += 15; sig_len -= 15; return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); } /* * hostkey_method_ssh_dss_signv * * Construct a signature from an array of vectors */ static int hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract) { libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); unsigned char hash[SHA_DIGEST_LENGTH]; libssh2_sha1_ctx ctx; int i; *signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH); if(!*signature) { return -1; } *signature_len = 2 * SHA_DIGEST_LENGTH; (void)libssh2_sha1_init(&ctx); for(i = 0; i < veccount; i++) { libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); } libssh2_sha1_final(ctx, hash); if(_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { LIBSSH2_FREE(session, *signature); return -1; } return 0; } /* * libssh2_hostkey_method_ssh_dss_dtor * * Shutdown the hostkey method */ static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract) { libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); (void)session; _libssh2_dsa_free(dsactx); *abstract = NULL; return 0; } static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = { "ssh-dss", SHA_DIGEST_LENGTH, hostkey_method_ssh_dss_init, hostkey_method_ssh_dss_initPEM, hostkey_method_ssh_dss_initPEMFromMemory, hostkey_method_ssh_dss_sig_verify, hostkey_method_ssh_dss_signv, NULL, /* encrypt */ hostkey_method_ssh_dss_dtor, }; #endif /* LIBSSH2_DSA */ #if LIBSSH2_ECDSA /* *********** * ecdsa-sha2-nistp256/384/521 * *********** */ static int hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, void **abstract); /* * hostkey_method_ssh_ecdsa_init * * Initialize the server hostkey working area with e/n pair */ static int hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session, const unsigned char *hostkey_data, size_t hostkey_data_len, void **abstract) { libssh2_ecdsa_ctx *ecdsactx = NULL; unsigned char *type_str, *domain, *public_key; size_t key_len, len; libssh2_curve_type type; struct string_buf buf; if(abstract && *abstract) { hostkey_method_ssh_ecdsa_dtor(session, abstract); *abstract = NULL; } if(hostkey_data_len < 39) { _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "host key length too short")); return -1; } buf.data = (unsigned char *)hostkey_data; buf.dataptr = buf.data; buf.len = hostkey_data_len; if(_libssh2_get_string(&buf, &type_str, &len) || len != 19) return -1; if(strncmp((char *) type_str, "ecdsa-sha2-nistp256", 19) == 0) { type = LIBSSH2_EC_CURVE_NISTP256; } else if(strncmp((char *) type_str, "ecdsa-sha2-nistp384", 19) == 0) { type = LIBSSH2_EC_CURVE_NISTP384; } else if(strncmp((char *) type_str, "ecdsa-sha2-nistp521", 19) == 0) { type = LIBSSH2_EC_CURVE_NISTP521; } else { return -1; } if(_libssh2_get_string(&buf, &domain, &len) || len != 8) return -1; if(type == LIBSSH2_EC_CURVE_NISTP256 && strncmp((char *)domain, "nistp256", 8) != 0) { return -1; } else if(type == LIBSSH2_EC_CURVE_NISTP384 && strncmp((char *)domain, "nistp384", 8) != 0) { return -1; } else if(type == LIBSSH2_EC_CURVE_NISTP521 && strncmp((char *)domain, "nistp521", 8) != 0) { return -1; } /* public key */ if(_libssh2_get_string(&buf, &public_key, &key_len)) return -1; if(!_libssh2_eob(&buf)) return -1; if(_libssh2_ecdsa_curve_name_with_octal_new(&ecdsactx, public_key, key_len, type)) return -1; if(abstract) *abstract = ecdsactx; return 0; } /* * hostkey_method_ssh_ecdsa_initPEM * * Load a Private Key from a PEM file */ static int hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session, const char *privkeyfile, unsigned const char *passphrase, void **abstract) { libssh2_ecdsa_ctx *ec_ctx = NULL; int ret; if(abstract && *abstract) { hostkey_method_ssh_ecdsa_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_ecdsa_new_private(&ec_ctx, session, privkeyfile, passphrase); if(abstract) *abstract = ec_ctx; return ret; } /* * hostkey_method_ssh_ecdsa_initPEMFromMemory * * Load a Private Key from memory */ static int hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session, const char *privkeyfiledata, size_t privkeyfiledata_len, unsigned const char *passphrase, void **abstract) { libssh2_ecdsa_ctx *ec_ctx = NULL; int ret; if(abstract && *abstract) { hostkey_method_ssh_ecdsa_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_ecdsa_new_private_frommemory(&ec_ctx, session, privkeyfiledata, privkeyfiledata_len, passphrase); if(ret) { return -1; } if(abstract) *abstract = ec_ctx; return 0; } /* * hostkey_method_ecdsa_sig_verify * * Verify signature created by remote */ static int hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract) { unsigned char *r, *s, *name; size_t r_len, s_len, name_len; uint32_t len; struct string_buf buf; libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract); (void)session; if(sig_len < 35) return -1; /* keyname_len(4) + keyname(19){"ecdsa-sha2-nistp256"} + signature_len(4) */ buf.data = (unsigned char *)sig; buf.dataptr = buf.data; buf.len = sig_len; if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19) return -1; if(_libssh2_get_u32(&buf, &len) != 0 || len < 8) return -1; if(_libssh2_get_string(&buf, &r, &r_len)) return -1; if(_libssh2_get_string(&buf, &s, &s_len)) return -1; return _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len); } #define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \ do { \ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ libssh2_sha##digest_type##_ctx ctx; \ int i; \ (void)libssh2_sha##digest_type##_init(&ctx); \ for(i = 0; i < veccount; i++) { \ libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \ datavec[i].iov_len); \ } \ libssh2_sha##digest_type##_final(ctx, hash); \ ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \ SHA##digest_type##_DIGEST_LENGTH, \ signature, signature_len); \ } while(0) /* * hostkey_method_ecdsa_signv * * Construct a signature from an array of vectors */ static int hostkey_method_ssh_ecdsa_signv(LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract) { libssh2_ecdsa_ctx *ec_ctx = (libssh2_ecdsa_ctx *) (*abstract); libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_ctx); int ret = 0; if(type == LIBSSH2_EC_CURVE_NISTP256) { LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(256); } else if(type == LIBSSH2_EC_CURVE_NISTP384) { LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(384); } else if(type == LIBSSH2_EC_CURVE_NISTP521) { LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(512); } else { return -1; } return ret; } /* * hostkey_method_ssh_ecdsa_dtor * * Shutdown the hostkey by freeing EC_KEY context */ static int hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, void **abstract) { libssh2_ecdsa_ctx *keyctx = (libssh2_ecdsa_ctx *) (*abstract); (void)session; if(keyctx) _libssh2_ecdsa_free(keyctx); *abstract = NULL; return 0; } static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp256 = { "ecdsa-sha2-nistp256", SHA256_DIGEST_LENGTH, hostkey_method_ssh_ecdsa_init, hostkey_method_ssh_ecdsa_initPEM, hostkey_method_ssh_ecdsa_initPEMFromMemory, hostkey_method_ssh_ecdsa_sig_verify, hostkey_method_ssh_ecdsa_signv, NULL, /* encrypt */ hostkey_method_ssh_ecdsa_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp384 = { "ecdsa-sha2-nistp384", SHA384_DIGEST_LENGTH, hostkey_method_ssh_ecdsa_init, hostkey_method_ssh_ecdsa_initPEM, hostkey_method_ssh_ecdsa_initPEMFromMemory, hostkey_method_ssh_ecdsa_sig_verify, hostkey_method_ssh_ecdsa_signv, NULL, /* encrypt */ hostkey_method_ssh_ecdsa_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521 = { "ecdsa-sha2-nistp521", SHA512_DIGEST_LENGTH, hostkey_method_ssh_ecdsa_init, hostkey_method_ssh_ecdsa_initPEM, hostkey_method_ssh_ecdsa_initPEMFromMemory, hostkey_method_ssh_ecdsa_sig_verify, hostkey_method_ssh_ecdsa_signv, NULL, /* encrypt */ hostkey_method_ssh_ecdsa_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp256_cert = { "ecdsa-sha2-nistp256-cert-v01@openssh.com", SHA256_DIGEST_LENGTH, NULL, hostkey_method_ssh_ecdsa_initPEM, hostkey_method_ssh_ecdsa_initPEMFromMemory, NULL, hostkey_method_ssh_ecdsa_signv, NULL, /* encrypt */ hostkey_method_ssh_ecdsa_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp384_cert = { "ecdsa-sha2-nistp384-cert-v01@openssh.com", SHA384_DIGEST_LENGTH, NULL, hostkey_method_ssh_ecdsa_initPEM, hostkey_method_ssh_ecdsa_initPEMFromMemory, NULL, hostkey_method_ssh_ecdsa_signv, NULL, /* encrypt */ hostkey_method_ssh_ecdsa_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521_cert = { "ecdsa-sha2-nistp521-cert-v01@openssh.com", SHA512_DIGEST_LENGTH, NULL, hostkey_method_ssh_ecdsa_initPEM, hostkey_method_ssh_ecdsa_initPEMFromMemory, NULL, hostkey_method_ssh_ecdsa_signv, NULL, /* encrypt */ hostkey_method_ssh_ecdsa_dtor, }; #endif /* LIBSSH2_ECDSA */ #if LIBSSH2_ED25519 /* *********** * ed25519 * *********** */ static int hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, void **abstract); /* * hostkey_method_ssh_ed25519_init * * Initialize the server hostkey working area with e/n pair */ static int hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session, const unsigned char *hostkey_data, size_t hostkey_data_len, void **abstract) { size_t key_len; unsigned char *key; libssh2_ed25519_ctx *ctx = NULL; struct string_buf buf; if(*abstract) { hostkey_method_ssh_ed25519_dtor(session, abstract); *abstract = NULL; } if(hostkey_data_len < 19) { _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "host key length too short")); return -1; } buf.data = (unsigned char *)hostkey_data; buf.dataptr = buf.data; buf.len = hostkey_data_len; if(_libssh2_match_string(&buf, "ssh-ed25519")) return -1; /* public key */ if(_libssh2_get_string(&buf, &key, &key_len)) return -1; if(!_libssh2_eob(&buf)) return -1; if(_libssh2_ed25519_new_public(&ctx, session, key, key_len) != 0) { return -1; } *abstract = ctx; return 0; } /* * hostkey_method_ssh_ed25519_initPEM * * Load a Private Key from a PEM file */ static int hostkey_method_ssh_ed25519_initPEM(LIBSSH2_SESSION * session, const char *privkeyfile, unsigned const char *passphrase, void **abstract) { libssh2_ed25519_ctx *ec_ctx = NULL; int ret; if(*abstract) { hostkey_method_ssh_ed25519_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_ed25519_new_private(&ec_ctx, session, privkeyfile, passphrase); if(ret) { return -1; } *abstract = ec_ctx; return ret; } /* * hostkey_method_ssh_ed25519_initPEMFromMemory * * Load a Private Key from memory */ static int hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session, const char *privkeyfiledata, size_t privkeyfiledata_len, unsigned const char *passphrase, void **abstract) { libssh2_ed25519_ctx *ed_ctx = NULL; int ret; if(abstract && *abstract) { hostkey_method_ssh_ed25519_dtor(session, abstract); *abstract = NULL; } ret = _libssh2_ed25519_new_private_frommemory(&ed_ctx, session, privkeyfiledata, privkeyfiledata_len, passphrase); if(ret) { return -1; } if(abstract) *abstract = ed_ctx; return 0; } /* * hostkey_method_ssh_ed25519_sig_verify * * Verify signature created by remote */ static int hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len, void **abstract) { libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract); (void)session; if(sig_len < 19) return -1; /* Skip past keyname_len(4) + keyname(11){"ssh-ed25519"} + signature_len(4) */ sig += 19; sig_len -= 19; if(sig_len != LIBSSH2_ED25519_SIG_LEN) return -1; return _libssh2_ed25519_verify(ctx, sig, sig_len, m, m_len); } /* * hostkey_method_ssh_ed25519_signv * * Construct a signature from an array of vectors */ static int hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec datavec[], void **abstract) { libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract); if(veccount != 1) { return -1; } return _libssh2_ed25519_sign(ctx, session, signature, signature_len, datavec[0].iov_base, datavec[0].iov_len); } /* * hostkey_method_ssh_ed25519_dtor * * Shutdown the hostkey by freeing key context */ static int hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, void **abstract) { libssh2_ed25519_ctx *keyctx = (libssh2_ed25519_ctx*) (*abstract); (void)session; if(keyctx) _libssh2_ed25519_free(keyctx); *abstract = NULL; return 0; } static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519 = { "ssh-ed25519", SHA256_DIGEST_LENGTH, hostkey_method_ssh_ed25519_init, hostkey_method_ssh_ed25519_initPEM, hostkey_method_ssh_ed25519_initPEMFromMemory, hostkey_method_ssh_ed25519_sig_verify, hostkey_method_ssh_ed25519_signv, NULL, /* encrypt */ hostkey_method_ssh_ed25519_dtor, }; static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519_cert = { "ssh-ed25519-cert-v01@openssh.com", SHA256_DIGEST_LENGTH, hostkey_method_ssh_ed25519_init, hostkey_method_ssh_ed25519_initPEM, hostkey_method_ssh_ed25519_initPEMFromMemory, hostkey_method_ssh_ed25519_sig_verify, hostkey_method_ssh_ed25519_signv, NULL, /* encrypt */ hostkey_method_ssh_ed25519_dtor, }; #endif /* LIBSSH2_ED25519 */ static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = { #if LIBSSH2_ECDSA &hostkey_method_ecdsa_ssh_nistp256, &hostkey_method_ecdsa_ssh_nistp384, &hostkey_method_ecdsa_ssh_nistp521, &hostkey_method_ecdsa_ssh_nistp256_cert, &hostkey_method_ecdsa_ssh_nistp384_cert, &hostkey_method_ecdsa_ssh_nistp521_cert, #endif #if LIBSSH2_ED25519 &hostkey_method_ssh_ed25519, &hostkey_method_ssh_ed25519_cert, #endif #if LIBSSH2_RSA #if LIBSSH2_RSA_SHA2 &hostkey_method_ssh_rsa_sha2_512, &hostkey_method_ssh_rsa_sha2_256, #endif /* LIBSSH2_RSA_SHA2 */ #if LIBSSH2_RSA_SHA1 &hostkey_method_ssh_rsa, &hostkey_method_ssh_rsa_cert, #endif /* LIBSSH2_RSA_SHA1 */ #endif /* LIBSSH2_RSA */ #if LIBSSH2_DSA &hostkey_method_ssh_dss, #endif /* LIBSSH2_DSA */ NULL }; const LIBSSH2_HOSTKEY_METHOD ** libssh2_hostkey_methods(void) { return hostkey_methods; } /* * libssh2_hostkey_hash * * Returns hash signature * Returned buffer should NOT be freed * Length of buffer is determined by hash type * i.e. MD5 == 16, SHA1 == 20, SHA256 == 32 */ LIBSSH2_API const char * libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type) { switch(hash_type) { #if LIBSSH2_MD5 case LIBSSH2_HOSTKEY_HASH_MD5: return (session->server_hostkey_md5_valid) ? (char *) session->server_hostkey_md5 : NULL; break; #endif /* LIBSSH2_MD5 */ case LIBSSH2_HOSTKEY_HASH_SHA1: return (session->server_hostkey_sha1_valid) ? (char *) session->server_hostkey_sha1 : NULL; break; case LIBSSH2_HOSTKEY_HASH_SHA256: return (session->server_hostkey_sha256_valid) ? (char *) session->server_hostkey_sha256 : NULL; break; default: return NULL; } } static int hostkey_type(const unsigned char *hostkey, size_t len) { static const unsigned char rsa[] = { 0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a' }; static const unsigned char dss[] = { 0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's' }; static const unsigned char ecdsa_256[] = { 0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-', 'n', 'i', 's', 't', 'p', '2', '5', '6' }; static const unsigned char ecdsa_384[] = { 0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-', 'n', 'i', 's', 't', 'p', '3', '8', '4' }; static const unsigned char ecdsa_521[] = { 0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-', 'n', 'i', 's', 't', 'p', '5', '2', '1' }; static const unsigned char ed25519[] = { 0, 0, 0, 0x0b, 's', 's', 'h', '-', 'e', 'd', '2', '5', '5', '1', '9' }; if(len < 11) return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; if(!memcmp(rsa, hostkey, 11)) return LIBSSH2_HOSTKEY_TYPE_RSA; if(!memcmp(dss, hostkey, 11)) return LIBSSH2_HOSTKEY_TYPE_DSS; if(len < 15) return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; if(!memcmp(ed25519, hostkey, 15)) return LIBSSH2_HOSTKEY_TYPE_ED25519; if(len < 23) return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; if(!memcmp(ecdsa_256, hostkey, 23)) return LIBSSH2_HOSTKEY_TYPE_ECDSA_256; if(!memcmp(ecdsa_384, hostkey, 23)) return LIBSSH2_HOSTKEY_TYPE_ECDSA_384; if(!memcmp(ecdsa_521, hostkey, 23)) return LIBSSH2_HOSTKEY_TYPE_ECDSA_521; return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; } /* * libssh2_session_hostkey * * Returns the server key and length. * */ LIBSSH2_API const char * libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type) { if(session->server_hostkey_len) { if(len) *len = session->server_hostkey_len; if(type) *type = hostkey_type(session->server_hostkey, session->server_hostkey_len); return (char *) session->server_hostkey; } if(len) *len = 0; return NULL; } libssh2-1.11.0/src/knownhost.c0000644000175000017500000012341214432741311013051 00000000000000/* * Copyright (c) 2009-2019 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" struct known_host { struct list_node node; char *name; /* points to the name or the hash (allocated) */ size_t name_len; /* needed for hashed data */ int port; /* if non-zero, a specific port this key is for on this host */ int typemask; /* plain, sha1, custom, ... */ char *salt; /* points to binary salt (allocated) */ size_t salt_len; /* size of salt */ char *key; /* the (allocated) associated key. This is kept base64 encoded in memory. */ char *key_type_name; /* the (allocated) key type name */ size_t key_type_len; /* size of key_type_name */ char *comment; /* the (allocated) optional comment text, may be NULL */ size_t comment_len; /* the size of comment */ /* this is the struct we expose externally */ struct libssh2_knownhost external; }; struct _LIBSSH2_KNOWNHOSTS { LIBSSH2_SESSION *session; /* the session this "belongs to" */ struct list_head head; }; static void free_host(LIBSSH2_SESSION *session, struct known_host *entry) { if(entry) { if(entry->comment) LIBSSH2_FREE(session, entry->comment); if(entry->key_type_name) LIBSSH2_FREE(session, entry->key_type_name); if(entry->key) LIBSSH2_FREE(session, entry->key); if(entry->salt) LIBSSH2_FREE(session, entry->salt); if(entry->name) LIBSSH2_FREE(session, entry->name); LIBSSH2_FREE(session, entry); } } /* * libssh2_knownhost_init * * Init a collection of known hosts. Returns the pointer to a collection. * */ LIBSSH2_API LIBSSH2_KNOWNHOSTS * libssh2_knownhost_init(LIBSSH2_SESSION *session) { LIBSSH2_KNOWNHOSTS *knh = LIBSSH2_ALLOC(session, sizeof(struct _LIBSSH2_KNOWNHOSTS)); if(!knh) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for known-hosts " "collection"); return NULL; } knh->session = session; _libssh2_list_init(&knh->head); return knh; } #define KNOWNHOST_MAGIC 0xdeadcafe /* * knownhost_to_external * * Copies data from the internal to the external representation struct. * */ static struct libssh2_knownhost *knownhost_to_external(struct known_host *node) { struct libssh2_knownhost *ext = &node->external; ext->magic = KNOWNHOST_MAGIC; ext->node = node; ext->name = ((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == LIBSSH2_KNOWNHOST_TYPE_PLAIN) ? node->name : NULL; ext->key = node->key; ext->typemask = node->typemask; return ext; } static int knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, const char *host, const char *salt, const char *key_type_name, size_t key_type_len, const char *key, size_t keylen, const char *comment, size_t commentlen, int typemask, struct libssh2_knownhost **store) { struct known_host *entry; size_t hostlen = strlen(host); int rc; char *ptr; size_t ptrlen; /* make sure we have a key type set */ if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK)) return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, "No key type set"); entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host)); if(!entry) return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for known host " "entry"); entry->typemask = typemask; switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { case LIBSSH2_KNOWNHOST_TYPE_PLAIN: case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: entry->name = LIBSSH2_ALLOC(hosts->session, hostlen + 1); if(!entry->name) { rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for host name"); goto error; } memcpy(entry->name, host, hostlen + 1); entry->name_len = hostlen; break; case LIBSSH2_KNOWNHOST_TYPE_SHA1: rc = _libssh2_base64_decode(hosts->session, &ptr, &ptrlen, host, hostlen); if(rc) goto error; entry->name = ptr; entry->name_len = ptrlen; rc = _libssh2_base64_decode(hosts->session, &ptr, &ptrlen, salt, strlen(salt)); if(rc) goto error; entry->salt = ptr; entry->salt_len = ptrlen; break; default: rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unknown host name type"); goto error; } if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) { /* the provided key is base64 encoded already */ if(!keylen) keylen = strlen(key); entry->key = LIBSSH2_ALLOC(hosts->session, keylen + 1); if(!entry->key) { rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for key"); goto error; } memcpy(entry->key, key, keylen + 1); entry->key[keylen] = 0; /* force a terminating zero trailer */ } else { /* key is raw, we base64 encode it and store it as such */ size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, &ptr); if(!nlen) { rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "base64-encoded key"); goto error; } entry->key = ptr; } if(key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) == LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) { entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len + 1); if(!entry->key_type_name) { rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for key type"); goto error; } memcpy(entry->key_type_name, key_type_name, key_type_len); entry->key_type_name[key_type_len] = 0; entry->key_type_len = key_type_len; } if(comment) { entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen + 1); if(!entry->comment) { rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for comment"); goto error; } memcpy(entry->comment, comment, commentlen + 1); entry->comment[commentlen] = 0; /* force a terminating zero trailer */ entry->comment_len = commentlen; } else { entry->comment = NULL; } /* add this new host to the big list of known hosts */ _libssh2_list_add(&hosts->head, &entry->node); if(store) *store = knownhost_to_external(entry); return LIBSSH2_ERROR_NONE; error: free_host(hosts->session, entry); return rc; } /* * libssh2_knownhost_add * * Add a host and its associated key to the collection of known hosts. * * The 'type' argument specifies on what format the given host and keys are: * * plain - ascii "hostname.domain.tld" * sha1 - SHA1( ) base64-encoded! * custom - another hash * * If 'sha1' is selected as type, the salt must be provided to the salt * argument. This too base64 encoded. * * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If * a custom type is used, salt is ignored and you must provide the host * pre-hashed when checking for it in the libssh2_knownhost_check() function. * * The keylen parameter may be omitted (zero) if the key is provided as a * NULL-terminated base64-encoded string. */ LIBSSH2_API int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, const char *host, const char *salt, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **store) { return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL, 0, typemask, store); } /* * libssh2_knownhost_addc * * Add a host and its associated key to the collection of known hosts. * * Takes a comment argument that may be NULL. A NULL comment indicates * there is no comment and the entry will end directly after the key * when written out to a file. An empty string "" comment will indicate an * empty comment which will cause a single space to be written after the key. * * The 'type' argument specifies on what format the given host and keys are: * * plain - ascii "hostname.domain.tld" * sha1 - SHA1( ) base64-encoded! * custom - another hash * * If 'sha1' is selected as type, the salt must be provided to the salt * argument. This too base64 encoded. * * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If * a custom type is used, salt is ignored and you must provide the host * pre-hashed when checking for it in the libssh2_knownhost_check() function. * * The keylen parameter may be omitted (zero) if the key is provided as a * NULL-terminated base64-encoded string. */ LIBSSH2_API int libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, const char *host, const char *salt, const char *key, size_t keylen, const char *comment, size_t commentlen, int typemask, struct libssh2_knownhost **store) { return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, comment, commentlen, typemask, store); } /* * knownhost_check * * Check a host and its associated key against the collection of known hosts. * * The typemask is the type/format of the given host name and key * * plain - ascii "hostname.domain.tld" * sha1 - NOT SUPPORTED AS INPUT * custom - prehashed base64 encoded. Note that this cannot use any salts. * * Returns: * * LIBSSH2_KNOWNHOST_CHECK_FAILURE * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND * LIBSSH2_KNOWNHOST_CHECK_MATCH * LIBSSH2_KNOWNHOST_CHECK_MISMATCH */ static int knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, const char *hostp, int port, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **ext) { struct known_host *node; struct known_host *badkey = NULL; int type = typemask & LIBSSH2_KNOWNHOST_TYPE_MASK; char *keyalloc = NULL; int rc = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND; char hostbuff[270]; /* most host names can't be longer than like 256 */ const char *host; int numcheck; /* number of host combos to check */ int match = 0; if(type == LIBSSH2_KNOWNHOST_TYPE_SHA1) /* we can't work with a sha1 as given input */ return LIBSSH2_KNOWNHOST_CHECK_MISMATCH; /* if a port number is given, check for a '[host]:port' first before the plain 'host' */ if(port >= 0) { int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port); if(len < 0 || len >= (int)sizeof(hostbuff)) { _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Known-host write buffer too small"); return LIBSSH2_KNOWNHOST_CHECK_FAILURE; } host = hostbuff; numcheck = 2; /* check both combos, start with this */ } else { host = hostp; numcheck = 1; /* only check this host version */ } if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) { /* we got a raw key input, convert it to base64 for the checks below */ size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, &keyalloc); if(!nlen) { _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for base64-encoded " "key"); return LIBSSH2_KNOWNHOST_CHECK_FAILURE; } /* make the key point to this */ key = keyalloc; } do { node = _libssh2_list_first(&hosts->head); while(node) { switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { case LIBSSH2_KNOWNHOST_TYPE_PLAIN: if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) match = !strcmp(host, node->name); break; case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: if(type == LIBSSH2_KNOWNHOST_TYPE_CUSTOM) match = !strcmp(host, node->name); break; case LIBSSH2_KNOWNHOST_TYPE_SHA1: if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) { /* when we have the sha1 version stored, we can use a plain input to produce a hash to compare with the stored hash. */ unsigned char hash[SHA_DIGEST_LENGTH]; libssh2_hmac_ctx ctx; libssh2_hmac_ctx_init(ctx); if(SHA_DIGEST_LENGTH != node->name_len) { /* the name hash length must be the sha1 size or we can't match it */ break; } libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt, node->salt_len); libssh2_hmac_update(ctx, (unsigned char *)host, strlen(host)); libssh2_hmac_final(ctx, hash); libssh2_hmac_cleanup(&ctx); if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH)) /* this is a node we're interested in */ match = 1; } break; default: /* unsupported type */ break; } if(match) { int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK; int known_key_type = node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK; /* match on key type as follows: - never match on an unknown key type - if key_type is set to zero, ignore it an match always - otherwise match when both key types are equal */ if(host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN && (host_key_type == 0 || host_key_type == known_key_type)) { /* host name and key type match, now compare the keys */ if(!strcmp(key, node->key)) { /* they match! */ if(ext) *ext = knownhost_to_external(node); badkey = NULL; rc = LIBSSH2_KNOWNHOST_CHECK_MATCH; break; } else { /* remember the first node that had a host match but a failed key match since we continue our search from here */ if(!badkey) badkey = node; } } match = 0; /* don't count this as a match anymore */ } node = _libssh2_list_next(&node->node); } host = hostp; } while(!match && --numcheck); if(badkey) { /* key mismatch */ if(ext) *ext = knownhost_to_external(badkey); rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH; } if(keyalloc) LIBSSH2_FREE(hosts->session, keyalloc); return rc; } /* * libssh2_knownhost_check * * Check a host and its associated key against the collection of known hosts. * * The typemask is the type/format of the given host name and key * * plain - ascii "hostname.domain.tld" * sha1 - NOT SUPPORTED AS INPUT * custom - prehashed base64 encoded. Note that this cannot use any salts. * * Returns: * * LIBSSH2_KNOWNHOST_CHECK_FAILURE * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND * LIBSSH2_KNOWNHOST_CHECK_MATCH * LIBSSH2_KNOWNHOST_CHECK_MISMATCH */ LIBSSH2_API int libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, const char *hostp, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **ext) { return knownhost_check(hosts, hostp, -1, key, keylen, typemask, ext); } /* * libssh2_knownhost_checkp * * Check a host+port and its associated key against the collection of known * hosts. * * Note that if 'port' is specified as greater than zero, the check function * will be able to check for a dedicated key for this particular host+port * combo, and if 'port' is negative it only checks for the generic host key. * * The typemask is the type/format of the given host name and key * * plain - ascii "hostname.domain.tld" * sha1 - NOT SUPPORTED AS INPUT * custom - prehashed base64 encoded. Note that this cannot use any salts. * * Returns: * * LIBSSH2_KNOWNHOST_CHECK_FAILURE * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND * LIBSSH2_KNOWNHOST_CHECK_MATCH * LIBSSH2_KNOWNHOST_CHECK_MISMATCH */ LIBSSH2_API int libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, const char *hostp, int port, const char *key, size_t keylen, int typemask, struct libssh2_knownhost **ext) { return knownhost_check(hosts, hostp, port, key, keylen, typemask, ext); } /* * libssh2_knownhost_del * * Remove a host from the collection of known hosts. * */ LIBSSH2_API int libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost *entry) { struct known_host *node; /* check that this was retrieved the right way or get out */ if(!entry || (entry->magic != KNOWNHOST_MAGIC)) return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, "Invalid host information"); /* get the internal node pointer */ node = entry->node; /* unlink from the list of all hosts */ _libssh2_list_remove(&node->node); /* clear the struct now since the memory in which it is allocated is about to be freed! */ memset(entry, 0, sizeof(struct libssh2_knownhost)); /* free all resources */ free_host(hosts->session, node); return 0; } /* * libssh2_knownhost_free * * Free an entire collection of known hosts. * */ LIBSSH2_API void libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts) { struct known_host *node; struct known_host *next; for(node = _libssh2_list_first(&hosts->head); node; node = next) { next = _libssh2_list_next(&node->node); free_host(hosts->session, node); } LIBSSH2_FREE(hosts->session, hosts); } /* old style plain text: [name]([,][name])* for the sake of simplicity, we add them as separate hosts with the same key */ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts, const char *host, size_t hostlen, const char *key_type_name, size_t key_type_len, const char *key, size_t keylen, int key_type, const char *comment, size_t commentlen) { int rc = 0; size_t namelen = 0; const char *name = host + hostlen; if(hostlen < 1) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Failed to parse known_hosts line " "(no host names)"); while(name > host) { --name; ++namelen; /* when we get the the start or see a comma coming up, add the host name to the collection */ if((name == host) || (*(name-1) == ',')) { char hostbuf[256]; /* make sure we don't overflow the buffer */ if(namelen >= sizeof(hostbuf)-1) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Failed to parse known_hosts line " "(unexpected length)"); /* copy host name to the temp buffer and zero terminate */ memcpy(hostbuf, name, namelen); hostbuf[namelen] = 0; rc = knownhost_add(hosts, hostbuf, NULL, key_type_name, key_type_len, key, keylen, comment, commentlen, key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); if(rc) return rc; if(name > host) { namelen = 0; --name; /* skip comma */ } } } return rc; } /* |1|[salt]|[hash] */ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts, const char *host, size_t hostlen, const char *key_type_name, size_t key_type_len, const char *key, size_t keylen, int key_type, const char *comment, size_t commentlen) { const char *p; char saltbuf[32]; char hostbuf[256]; const char *salt = &host[3]; /* skip the magic marker */ hostlen -= 3; /* deduct the marker */ /* this is where the salt starts, find the end of it */ for(p = salt; *p && (*p != '|'); p++) ; if(*p == '|') { const char *hash = NULL; size_t saltlen = p - salt; if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */ return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Failed to parse known_hosts line " "(unexpectedly long salt)"); memcpy(saltbuf, salt, saltlen); saltbuf[saltlen] = 0; /* zero terminate */ salt = saltbuf; /* point to the stack based buffer */ hash = p + 1; /* the host hash is after the separator */ /* now make the host point to the hash */ host = hash; hostlen -= saltlen + 1; /* deduct the salt and separator */ /* check that the lengths seem sensible */ if(hostlen >= sizeof(hostbuf)-1) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Failed to parse known_hosts line " "(unexpected length)"); memcpy(hostbuf, host, hostlen); hostbuf[hostlen] = 0; return knownhost_add(hosts, hostbuf, salt, key_type_name, key_type_len, key, keylen, comment, commentlen, key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 | LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); } else return 0; /* XXX: This should be an error, shouldn't it? */ } /* * hostline * * Parse a single known_host line pre-split into host and key. * * The key part may include an optional comment which will be parsed here * for ssh-rsa and ssh-dsa keys. Comments in other key types aren't handled. * * The function assumes new-lines have already been removed from the arguments. */ static int hostline(LIBSSH2_KNOWNHOSTS *hosts, const char *host, size_t hostlen, const char *key, size_t keylen) { const char *comment = NULL; const char *key_type_name = NULL; size_t commentlen = 0; size_t key_type_len = 0; int key_type; /* make some checks that the lengths seem sensible */ if(keylen < 20) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Failed to parse known_hosts line " "(key too short)"); switch(key[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': key_type = LIBSSH2_KNOWNHOST_KEY_RSA1; /* Note that the old-style keys (RSA1) aren't truly base64, but we * claim it is for now since we can get away with strcmp()ing the * entire anything anyway! We need to check and fix these to make them * work properly. */ break; default: key_type_name = key; while(keylen && *key && (*key != ' ') && (*key != '\t')) { key++; keylen--; } key_type_len = key - key_type_name; if(!strncmp(key_type_name, "ssh-dss", key_type_len)) key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS; else if(!strncmp(key_type_name, "ssh-rsa", key_type_len)) key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA; else if(!strncmp(key_type_name, "ecdsa-sha2-nistp256", key_type_len)) key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_256; else if(!strncmp(key_type_name, "ecdsa-sha2-nistp384", key_type_len)) key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_384; else if(!strncmp(key_type_name, "ecdsa-sha2-nistp521", key_type_len)) key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_521; else if(!strncmp(key_type_name, "ssh-ed25519", key_type_len)) key_type = LIBSSH2_KNOWNHOST_KEY_ED25519; else key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN; /* skip whitespaces */ while((*key ==' ') || (*key == '\t')) { key++; keylen--; } comment = key; commentlen = keylen; /* move over key */ while(commentlen && *comment && (*comment != ' ') && (*comment != '\t')) { comment++; commentlen--; } /* reduce key by comment length */ keylen -= commentlen; /* Distinguish empty comment (a space) from no comment (no space) */ if(commentlen == 0) comment = NULL; /* skip whitespaces */ while(commentlen && *comment && ((*comment ==' ') || (*comment == '\t'))) { comment++; commentlen--; } break; } /* Figure out host format */ if((hostlen > 2) && memcmp(host, "|1|", 3)) { /* old style plain text: [name]([,][name])* for the sake of simplicity, we add them as separate hosts with the same key */ return oldstyle_hostline(hosts, host, hostlen, key_type_name, key_type_len, key, keylen, key_type, comment, commentlen); } else { /* |1|[salt]|[hash] */ return hashed_hostline(hosts, host, hostlen, key_type_name, key_type_len, key, keylen, key_type, comment, commentlen); } } /* * libssh2_knownhost_readline * * Pass in a line of a file of 'type'. * * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. * * OpenSSH line format: * * * * Where the two parts can be created like: * * can be either * or * * consists of * [name] optionally followed by [,name] one or more times * * consists of * |1||hash * * can be one of: * [RSA bits] [e] [n as a decimal number] * 'ssh-dss' [base64-encoded-key] * 'ssh-rsa' [base64-encoded-key] * */ LIBSSH2_API int libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, const char *line, size_t len, int type) { const char *cp; const char *hostp; const char *keyp; size_t hostlen; size_t keylen; int rc; if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unsupported type of known-host information " "store"); cp = line; /* skip leading whitespaces */ while(len && ((*cp == ' ') || (*cp == '\t'))) { cp++; len--; } if(!len || !*cp || (*cp == '#') || (*cp == '\n')) /* comment or empty line */ return LIBSSH2_ERROR_NONE; /* the host part starts here */ hostp = cp; /* move over the host to the separator */ while(len && *cp && (*cp != ' ') && (*cp != '\t')) { cp++; len--; } hostlen = cp - hostp; /* the key starts after the whitespaces */ while(len && *cp && ((*cp == ' ') || (*cp == '\t'))) { cp++; len--; } if(!*cp || !len) /* illegal line */ return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Failed to parse known_hosts line"); keyp = cp; /* the key starts here */ keylen = len; /* check if the line (key) ends with a newline and if so kill it */ while(len && *cp && (*cp != '\n')) { cp++; len--; } /* zero terminate where the newline is */ if(*cp == '\n') keylen--; /* don't include this in the count */ /* deal with this one host+key line */ rc = hostline(hosts, hostp, hostlen, keyp, keylen); if(rc) return rc; /* failed */ return LIBSSH2_ERROR_NONE; /* success */ } /* * libssh2_knownhost_readfile * * Read hosts+key pairs from a given file. * * Returns a negative value for error or number of successfully added hosts. * */ LIBSSH2_API int libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, const char *filename, int type) { FILE *file; int num = 0; char buf[4092]; if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unsupported type of known-host information " "store"); file = fopen(filename, FOPEN_READTEXT); if(file) { while(fgets(buf, sizeof(buf), file)) { if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) { num = _libssh2_error(hosts->session, LIBSSH2_ERROR_KNOWN_HOSTS, "Failed to parse known hosts file"); break; } num++; } fclose(file); } else return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, "Failed to open file"); return num; } /* * knownhost_writeline * * Ask libssh2 to convert a known host to an output line for storage. * * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given * output buffer is too small to hold the desired output. The 'outlen' field * will then contain the size libssh2 wanted to store, which then is the * smallest sufficient buffer it would require. * */ static int knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, struct known_host *node, char *buf, size_t buflen, size_t *outlen, int type) { size_t required_size; const char *key_type_name; size_t key_type_len; /* we only support this single file type for now, bail out on all other attempts */ if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unsupported type of known-host information " "store"); switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { case LIBSSH2_KNOWNHOST_KEY_RSA1: key_type_name = NULL; key_type_len = 0; break; case LIBSSH2_KNOWNHOST_KEY_SSHRSA: key_type_name = "ssh-rsa"; key_type_len = 7; break; case LIBSSH2_KNOWNHOST_KEY_SSHDSS: key_type_name = "ssh-dss"; key_type_len = 7; break; case LIBSSH2_KNOWNHOST_KEY_ECDSA_256: key_type_name = "ecdsa-sha2-nistp256"; key_type_len = 19; break; case LIBSSH2_KNOWNHOST_KEY_ECDSA_384: key_type_name = "ecdsa-sha2-nistp384"; key_type_len = 19; break; case LIBSSH2_KNOWNHOST_KEY_ECDSA_521: key_type_name = "ecdsa-sha2-nistp521"; key_type_len = 19; break; case LIBSSH2_KNOWNHOST_KEY_ED25519: key_type_name = "ssh-ed25519"; key_type_len = 11; break; case LIBSSH2_KNOWNHOST_KEY_UNKNOWN: key_type_name = node->key_type_name; if(key_type_name) { key_type_len = node->key_type_len; break; } /* otherwise fallback to default and error */ /* FALL-THROUGH */ default: return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unsupported type of known-host entry"); } /* When putting together the host line there are three aspects to consider: - Hashed (SHA1) or unhashed hostname - key name or no key name (RSA1) - comment or no comment This means there are 2^3 different formats: ("|1|%s|%s %s %s %s\n", salt, hashed_host, key_name, key, comment) ("|1|%s|%s %s %s\n", salt, hashed_host, key_name, key) ("|1|%s|%s %s %s\n", salt, hashed_host, key, comment) ("|1|%s|%s %s\n", salt, hashed_host, key) ("%s %s %s %s\n", host, key_name, key, comment) ("%s %s %s\n", host, key_name, key) ("%s %s %s\n", host, key, comment) ("%s %s\n", host, key) Even if the buffer is too small, we have to set outlen to the number of characters the complete line would have taken. We also don't write anything to the buffer unless we are sure we can write everything to the buffer. */ required_size = strlen(node->key); if(key_type_len) required_size += key_type_len + 1; /* ' ' = 1 */ if(node->comment) required_size += node->comment_len + 1; /* ' ' = 1 */ if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == LIBSSH2_KNOWNHOST_TYPE_SHA1) { char *namealloc; size_t name_base64_len; char *saltalloc; size_t salt_base64_len; name_base64_len = _libssh2_base64_encode(hosts->session, node->name, node->name_len, &namealloc); if(!name_base64_len) return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "base64-encoded host name"); salt_base64_len = _libssh2_base64_encode(hosts->session, node->salt, node->salt_len, &saltalloc); if(!salt_base64_len) { LIBSSH2_FREE(hosts->session, namealloc); return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "base64-encoded salt"); } required_size += salt_base64_len + name_base64_len + 7; /* |1| + | + ' ' + \n + \0 = 7 */ if(required_size <= buflen) { if(node->comment && key_type_len) snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc, namealloc, key_type_name, node->key, node->comment); else if(node->comment) snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, node->key, node->comment); else if(key_type_len) snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, key_type_name, node->key); else snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc, node->key); } LIBSSH2_FREE(hosts->session, namealloc); LIBSSH2_FREE(hosts->session, saltalloc); } else { required_size += node->name_len + 3; /* ' ' + '\n' + \0 = 3 */ if(required_size <= buflen) { if(node->comment && key_type_len) snprintf(buf, buflen, "%s %s %s %s\n", node->name, key_type_name, node->key, node->comment); else if(node->comment) snprintf(buf, buflen, "%s %s %s\n", node->name, node->key, node->comment); else if(key_type_len) snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name, node->key); else snprintf(buf, buflen, "%s %s\n", node->name, node->key); } } /* we report the full length of the data with the trailing zero excluded */ *outlen = required_size-1; if(required_size <= buflen) return LIBSSH2_ERROR_NONE; else return _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, "Known-host write buffer too small"); } /* * libssh2_knownhost_writeline * * Ask libssh2 to convert a known host to an output line for storage. * * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given * output buffer is too small to hold the desired output. */ LIBSSH2_API int libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost *known, char *buffer, size_t buflen, size_t *outlen, /* the amount of written data */ int type) { struct known_host *node; if(known->magic != KNOWNHOST_MAGIC) return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, "Invalid host information"); node = known->node; return knownhost_writeline(hosts, node, buffer, buflen, outlen, type); } /* * libssh2_knownhost_writefile * * Write hosts+key pairs to the given file. */ LIBSSH2_API int libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, const char *filename, int type) { struct known_host *node; FILE *file; int rc = LIBSSH2_ERROR_NONE; char buffer[4092]; /* we only support this single file type for now, bail out on all other attempts */ if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) return _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "Unsupported type of known-host information " "store"); file = fopen(filename, FOPEN_WRITETEXT); if(!file) return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, "Failed to open file"); for(node = _libssh2_list_first(&hosts->head); node; node = _libssh2_list_next(&node->node)) { size_t wrote = 0; size_t nwrote; rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote, type); if(rc) break; nwrote = fwrite(buffer, 1, wrote, file); if(nwrote != wrote) { /* failed to write the whole thing, bail out */ rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, "Write failed"); break; } } fclose(file); return rc; } /* * libssh2_knownhost_get * * Traverse the internal list of known hosts. Pass NULL to 'prev' to get * the first one. * * Returns: * 0 if a fine host was stored in 'store' * 1 if end of hosts * [negative] on errors */ LIBSSH2_API int libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost **ext, struct libssh2_knownhost *oprev) { struct known_host *node; if(oprev && oprev->node) { /* we have a starting point */ struct known_host *prev = oprev->node; /* get the next node in the list */ node = _libssh2_list_next(&prev->node); } else node = _libssh2_list_first(&hosts->head); if(!node) /* no (more) node */ return 1; *ext = knownhost_to_external(node); return 0; } libssh2-1.11.0/src/libssh2_setup.h0000644000175000017500000000500214435416425013614 00000000000000/* Copyright (c) 2023 Viktor Szakats */ #ifndef LIBSSH2_SETUP_H #define LIBSSH2_SETUP_H /* Header for platform/compiler-specific initialization. Used by 'src', 'example', 'tests' */ #if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif /* Define mingw-w64 version macros, eg __MINGW{32,64}_{MINOR,MAJOR}_VERSION */ #ifdef __MINGW32__ #include <_mingw.h> #endif /* Configuration provided by build tools (autotools and CMake), and via platform-specific directories for os400 and vms */ #if defined(HAVE_CONFIG_H) || defined(__OS400__) || defined(__VMS) #include "libssh2_config.h" /* Hand-crafted configuration for platforms which lack config tool. Keep this synced with root CMakeLists.txt */ #elif defined(WIN32) #define HAVE_SELECT #define HAVE_SNPRINTF #ifdef __MINGW32__ # define HAVE_UNISTD_H # define HAVE_INTTYPES_H # define HAVE_SYS_TIME_H # define HAVE_SYS_PARAM_H # define HAVE_GETTIMEOFDAY # define HAVE_STRTOLL #elif defined(_MSC_VER) # if _MSC_VER >= 1800 # define HAVE_INTTYPES_H # define HAVE_STRTOLL # else # define HAVE_STRTOI64 # endif # if _MSC_VER < 1900 # undef HAVE_SNPRINTF # endif #endif #endif /* defined(HAVE_CONFIG_H) */ /* Below applies to both auto-detected and hand-crafted configs */ #ifdef WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef NOGDI #define NOGDI #endif #ifndef NONLS #define NONLS #endif #ifdef __MINGW32__ # ifdef __MINGW64_VERSION_MAJOR /* Number of bits in a file offset, on hosts where this is settable. */ # ifndef _FILE_OFFSET_BITS # define _FILE_OFFSET_BITS 64 # endif # endif #elif defined(_MSC_VER) # ifndef _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS /* for fopen(), getenv() */ # endif # if !defined(LIBSSH2_LIBRARY) || defined(LIBSSH2_TESTS) /* apply to examples and tests only */ # ifndef _CRT_NONSTDC_NO_DEPRECATE # define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write() */ # endif # ifndef _WINSOCK_DEPRECATED_NO_WARNINGS # define _WINSOCK_DEPRECATED_NO_WARNINGS /* for inet_addr() */ # endif /* we cannot access our internal snprintf() implementation in examples and tests when linking to a shared libssh2. */ # if _MSC_VER < 1900 # undef HAVE_SNPRINTF # define HAVE_SNPRINTF # define snprintf _snprintf # endif # endif # if _MSC_VER < 1500 # define vsnprintf _vsnprintf # endif # if _MSC_VER < 1900 # define strdup _strdup /* Silence bogus warning C4127: conditional expression is constant */ # pragma warning(disable:4127) # endif #endif #endif /* WIN32 */ #endif /* LIBSSH2_SETUP_H */ libssh2-1.11.0/src/transport.c0000644000175000017500000013033214432741311013052 00000000000000/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. * Copyright (C) 2009-2010 by Daniel Stenberg * Author: Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ /* * This file handles reading and writing to the SECSH transport layer. RFC4253. */ #include "libssh2_priv.h" #include #include #include #include "transport.h" #include "mac.h" #define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ #define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */ #ifdef LIBSSH2DEBUG #define UNPRINTABLE_CHAR '.' static void debugdump(LIBSSH2_SESSION * session, const char *desc, const unsigned char *ptr, size_t size) { size_t i; size_t c; unsigned int width = 0x10; char buffer[256]; /* Must be enough for width*4 + about 30 or so */ size_t used; static const char *hex_chars = "0123456789ABCDEF"; if(!(session->showmask & LIBSSH2_TRACE_TRANS)) { /* not asked for, bail out */ return; } used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n", desc, (int) size); if(session->tracehandler) (session->tracehandler)(session, session->tracehandler_context, buffer, used); else fprintf(stderr, "%s", buffer); for(i = 0; i < size; i += width) { used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i); /* hex not disabled, show it */ for(c = 0; c < width; c++) { if(i + c < size) { buffer[used++] = hex_chars[(ptr[i + c] >> 4) & 0xF]; buffer[used++] = hex_chars[ptr[i + c] & 0xF]; } else { buffer[used++] = ' '; buffer[used++] = ' '; } buffer[used++] = ' '; if((width/2) - 1 == c) buffer[used++] = ' '; } buffer[used++] = ':'; buffer[used++] = ' '; for(c = 0; (c < width) && (i + c < size); c++) { buffer[used++] = isprint(ptr[i + c]) ? ptr[i + c] : UNPRINTABLE_CHAR; } buffer[used++] = '\n'; buffer[used] = 0; if(session->tracehandler) (session->tracehandler)(session, session->tracehandler_context, buffer, used); else fprintf(stderr, "%s", buffer); } } #else #define debugdump(a,x,y,z) do {} while(0) #endif /* decrypt() decrypts 'len' bytes from 'source' to 'dest' in units of * blocksize. * * returns 0 on success and negative on failure */ static int decrypt(LIBSSH2_SESSION * session, unsigned char *source, unsigned char *dest, ssize_t len, int firstlast) { struct transportpacket *p = &session->packet; int blocksize = session->remote.crypt->blocksize; /* if we get called with a len that isn't an even number of blocksizes we risk losing those extra bytes. AAD is an exception, since those first few bytes aren't encrypted so it throws off the rest of the count. */ if(!CRYPT_FLAG_L(session, PKTLEN_AAD)) assert((len % blocksize) == 0); while(len > 0) { /* normally decrypt up to blocksize bytes at a time */ ssize_t decryptlen = LIBSSH2_MIN(blocksize, len); /* The first block is special (since it needs to be decoded to get the length of the remainder of the block) and takes priority. When the length finally gets to the last blocksize bytes, and there's no more data to come, it's the end. */ int lowerfirstlast = IS_FIRST(firstlast) ? FIRST_BLOCK : ((len <= blocksize) ? firstlast : MIDDLE_BLOCK); /* If the last block would be less than a whole blocksize, combine it with the previous block to make it larger. This ensures that the whole MAC is included in a single decrypt call. */ if(CRYPT_FLAG_L(session, PKTLEN_AAD) && IS_LAST(firstlast) && (len < blocksize*2)) { decryptlen = len; lowerfirstlast = LAST_BLOCK; } if(session->remote.crypt->crypt(session, source, decryptlen, &session->remote.crypt_abstract, lowerfirstlast)) { LIBSSH2_FREE(session, p->payload); return LIBSSH2_ERROR_DECRYPT; } /* if the crypt() function would write to a given address it wouldn't have to memcpy() and we could avoid this memcpy() too */ memcpy(dest, source, decryptlen); len -= decryptlen; /* less bytes left */ dest += decryptlen; /* advance write pointer */ source += decryptlen; /* advance read pointer */ } return LIBSSH2_ERROR_NONE; /* all is fine */ } /* * fullpacket() gets called when a full packet has been received and properly * collected. */ static int fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) { unsigned char macbuf[MAX_MACSIZE]; struct transportpacket *p = &session->packet; int rc; int compressed; if(session->fullpacket_state == libssh2_NB_state_idle) { session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; session->fullpacket_payload_len = p->packet_length - 1; if(encrypted && !CRYPT_FLAG_L(session, INTEGRATED_MAC)) { /* Calculate MAC hash */ int etm = session->remote.mac->etm; size_t mac_len = session->remote.mac->mac_len; if(etm) { /* store hash here */ session->remote.mac->hash(session, macbuf, session->remote.seqno, p->payload, p->total_num - mac_len, NULL, 0, &session->remote.mac_abstract); } else { /* store hash here */ session->remote.mac->hash(session, macbuf, session->remote.seqno, p->init, 5, p->payload, session->fullpacket_payload_len, &session->remote.mac_abstract); } /* Compare the calculated hash with the MAC we just read from * the network. The read one is at the very end of the payload * buffer. Note that 'payload_len' here is the packet_length * field which includes the padding but not the MAC. */ if(memcmp(macbuf, p->payload + p->total_num - mac_len, mac_len)) { _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Failed MAC check")); session->fullpacket_macstate = LIBSSH2_MAC_INVALID; } else if(etm) { /* MAC was ok and we start by decrypting the first block that contains padding length since this allows us to decrypt all other blocks to the right location in memory avoiding moving a larger block of memory one byte. */ unsigned char first_block[MAX_BLOCKSIZE]; ssize_t decrypt_size; unsigned char *decrypt_buffer; int blocksize = session->remote.crypt->blocksize; rc = decrypt(session, p->payload + 4, first_block, blocksize, FIRST_BLOCK); if(rc) { return rc; } /* we need buffer for decrypt */ decrypt_size = p->total_num - mac_len - 4; decrypt_buffer = LIBSSH2_ALLOC(session, decrypt_size); if(!decrypt_buffer) { return LIBSSH2_ERROR_ALLOC; } /* grab padding length and copy anything else into target buffer */ p->padding_length = first_block[0]; if(blocksize > 1) { memcpy(decrypt_buffer, first_block + 1, blocksize - 1); } /* decrypt all other blocks packet */ if(blocksize < decrypt_size) { rc = decrypt(session, p->payload + blocksize + 4, decrypt_buffer + blocksize - 1, decrypt_size - blocksize, LAST_BLOCK); if(rc) { LIBSSH2_FREE(session, decrypt_buffer); return rc; } } /* replace encrypted payload with plain text payload */ LIBSSH2_FREE(session, p->payload); p->payload = decrypt_buffer; } } session->remote.seqno++; /* ignore the padding */ session->fullpacket_payload_len -= p->padding_length; /* Check for and deal with decompression */ compressed = session->local.comp && session->local.comp->compress && ((session->state & LIBSSH2_STATE_AUTHENTICATED) || session->local.comp->use_in_auth); if(compressed && session->remote.comp_abstract) { /* * The buffer for the decompression (remote.comp_abstract) is * initialised in time when it is needed so as long it is NULL we * cannot decompress. */ unsigned char *data; size_t data_len; rc = session->remote.comp->decomp(session, &data, &data_len, LIBSSH2_PACKET_MAXDECOMP, p->payload, session->fullpacket_payload_len, &session->remote.comp_abstract); LIBSSH2_FREE(session, p->payload); if(rc) return rc; p->payload = data; session->fullpacket_payload_len = data_len; } session->fullpacket_packet_type = p->payload[0]; debugdump(session, "libssh2_transport_read() plain", p->payload, session->fullpacket_payload_len); session->fullpacket_state = libssh2_NB_state_created; } if(session->fullpacket_state == libssh2_NB_state_created) { rc = _libssh2_packet_add(session, p->payload, session->fullpacket_payload_len, session->fullpacket_macstate); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; if(rc) { session->fullpacket_state = libssh2_NB_state_idle; return rc; } } session->fullpacket_state = libssh2_NB_state_idle; return session->fullpacket_packet_type; } /* * _libssh2_transport_read * * Collect a packet into the input queue. * * Returns packet type added to input queue (0 if nothing added), or a * negative error number. */ /* * This function reads the binary stream as specified in chapter 6 of RFC4253 * "The Secure Shell (SSH) Transport Layer Protocol" * * DOES NOT call _libssh2_error() for ANY error case. */ int _libssh2_transport_read(LIBSSH2_SESSION * session) { int rc; struct transportpacket *p = &session->packet; ssize_t remainpack; /* how much there is left to add to the current payload package */ ssize_t remainbuf; /* how much data there is remaining in the buffer to deal with before we should read more from the network */ ssize_t numbytes; /* how much data to deal with from the buffer on this iteration through the loop */ ssize_t numdecrypt; /* number of bytes to decrypt this iteration */ unsigned char block[MAX_BLOCKSIZE]; /* working block buffer */ int blocksize; /* minimum number of bytes we need before we can use them */ int encrypted = 1; /* whether the packet is encrypted or not */ int firstlast = FIRST_BLOCK; /* if the first or last block to decrypt */ /* default clear the bit */ session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; /* * All channels, systems, subsystems, etc eventually make it down here * when looking for more incoming data. If a key exchange is going on * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will * ONLY send key exchange related traffic. In non-blocking mode, there is * a chance to break out of the kex_exchange function with an EAGAIN * status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is * active, then we must redirect to the key exchange. However, if * kex_exchange is active (as in it is the one that calls this execution * of packet_read, then don't redirect, as that would be an infinite loop! */ if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS && !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { /* Whoever wants a packet won't get anything until the key re-exchange * is done! */ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Redirecting into the" " key re-exchange from _libssh2_transport_read")); rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); if(rc) return rc; } /* * =============================== NOTE =============================== * I know this is very ugly and not a really good use of "goto", but * this case statement would be even uglier to do it any other way */ if(session->readPack_state == libssh2_NB_state_jump1) { session->readPack_state = libssh2_NB_state_idle; encrypted = session->readPack_encrypted; goto libssh2_transport_read_point1; } do { int etm; if(session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { return LIBSSH2_ERROR_SOCKET_DISCONNECT; } if(session->state & LIBSSH2_STATE_NEWKEYS) { blocksize = session->remote.crypt->blocksize; } else { encrypted = 0; /* not encrypted */ blocksize = 5; /* not strictly true, but we can use 5 here to make the checks below work fine still */ } etm = encrypted && session->local.mac ? session->local.mac->etm : 0; /* read/use a whole big chunk into a temporary area stored in the LIBSSH2_SESSION struct. We will decrypt data from that buffer into the packet buffer so this temp one doesn't have to be able to keep a whole SSH packet, just be large enough so that we can read big chunks from the network layer. */ /* how much data there is remaining in the buffer to deal with before we should read more from the network */ remainbuf = p->writeidx - p->readidx; /* if remainbuf turns negative we have a bad internal error */ assert(remainbuf >= 0); if(remainbuf < blocksize) { /* If we have less than a blocksize left, it is too little data to deal with, read more */ ssize_t nread; /* move any remainder to the start of the buffer so that we can do a full refill */ if(remainbuf) { memmove(p->buf, &p->buf[p->readidx], remainbuf); p->readidx = 0; p->writeidx = remainbuf; } else { /* nothing to move, just zero the indexes */ p->readidx = p->writeidx = 0; } /* now read a big chunk from the network into the temp buffer */ nread = LIBSSH2_RECV(session, &p->buf[remainbuf], PACKETBUFSIZE - remainbuf, LIBSSH2_SOCKET_RECV_FLAGS(session)); if(nread <= 0) { /* check if this is due to EAGAIN and return the special return code if so, error out normally otherwise */ if((nread < 0) && (nread == -EAGAIN)) { session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_INBOUND; return LIBSSH2_ERROR_EAGAIN; } _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Error recving %d bytes (got %d)", PACKETBUFSIZE - remainbuf, -nread)); return LIBSSH2_ERROR_SOCKET_RECV; } _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Recved %d/%d bytes to %p+%d", nread, PACKETBUFSIZE - remainbuf, p->buf, remainbuf)); debugdump(session, "libssh2_transport_read() raw", &p->buf[remainbuf], nread); /* advance write pointer */ p->writeidx += nread; /* update remainbuf counter */ remainbuf = p->writeidx - p->readidx; } /* how much data to deal with from the buffer */ numbytes = remainbuf; if(!p->total_num) { size_t total_num; /* the number of bytes following the initial (5 bytes) packet length and padding length fields */ /* packet length is not encrypted in encode-then-mac mode and we donøt need to decrypt first block */ ssize_t required_size = etm ? 4 : blocksize; /* No payload package area allocated yet. To know the size of this payload, we need enough to decrypt the first blocksize data. */ if(numbytes < required_size) { /* we can't act on anything less than blocksize, but this check is only done for the initial block since once we have got the start of a block we can in fact deal with fractions */ session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_INBOUND; return LIBSSH2_ERROR_EAGAIN; } if(etm) { p->packet_length = _libssh2_ntohu32(&p->buf[p->readidx]); } else { if(encrypted) { /* first decrypted block */ rc = decrypt(session, &p->buf[p->readidx], block, blocksize, FIRST_BLOCK); if(rc != LIBSSH2_ERROR_NONE) { return rc; } /* Save the first 5 bytes of the decrypted package, to be used in the hash calculation later down. This is ignored in the INTEGRATED_MAC case. */ memcpy(p->init, block, 5); } else { /* the data is plain, just copy it verbatim to the working block buffer */ memcpy(block, &p->buf[p->readidx], blocksize); } /* advance the read pointer */ p->readidx += blocksize; /* we now have the initial blocksize bytes decrypted, * and we can extract packet and padding length from it */ p->packet_length = _libssh2_ntohu32(block); } if(p->packet_length < 1) { return LIBSSH2_ERROR_DECRYPT; } else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) { return LIBSSH2_ERROR_OUT_OF_BOUNDARY; } if(etm) { /* we collect entire undecrypted packet including the packet length field that we run MAC over */ total_num = 4 + p->packet_length + session->remote.mac->mac_len; } else { /* padding_length has not been authenticated yet, but it won't actually be used (except for the sanity check immediately following) until after the entire packet is authenticated, so this is safe. */ p->padding_length = block[4]; if(p->padding_length > p->packet_length - 1) { return LIBSSH2_ERROR_DECRYPT; } /* total_num is the number of bytes following the initial (5 bytes) packet length and padding length fields */ total_num = p->packet_length - 1 + (encrypted ? session->remote.mac->mac_len : 0); } /* RFC4253 section 6.1 Maximum Packet Length says: * * "All implementations MUST be able to process * packets with uncompressed payload length of 32768 * bytes or less and total packet size of 35000 bytes * or less (including length, padding length, payload, * padding, and MAC.)." */ if(total_num > LIBSSH2_PACKET_MAXPAYLOAD || total_num == 0) { return LIBSSH2_ERROR_OUT_OF_BOUNDARY; } /* Get a packet handle put data into. We get one to hold all data, including padding and MAC. */ p->payload = LIBSSH2_ALLOC(session, total_num); if(!p->payload) { return LIBSSH2_ERROR_ALLOC; } p->total_num = total_num; /* init write pointer to start of payload buffer */ p->wptr = p->payload; if(!etm && blocksize > 5) { /* copy the data from index 5 to the end of the blocksize from the temporary buffer to the start of the decrypted buffer */ if(blocksize - 5 <= (int) total_num) { memcpy(p->wptr, &block[5], blocksize - 5); p->wptr += blocksize - 5; /* advance write pointer */ if(etm) { /* advance past unencrypted packet length */ p->wptr += 4; } } else { if(p->payload) LIBSSH2_FREE(session, p->payload); return LIBSSH2_ERROR_OUT_OF_BOUNDARY; } } /* init the data_num field to the number of bytes of the package read so far */ p->data_num = p->wptr - p->payload; /* we already dealt with a blocksize worth of data */ if(!etm) numbytes -= blocksize; } /* how much there is left to add to the current payload package */ remainpack = p->total_num - p->data_num; if(numbytes > remainpack) { /* if we have more data in the buffer than what is going into this particular packet, we limit this round to this packet only */ numbytes = remainpack; } if(encrypted && !etm) { /* At the end of the incoming stream, there is a MAC, and we don't want to decrypt that since we need it "raw". We MUST however decrypt the padding data since it is used for the hash later on. */ int skip = session->remote.mac->mac_len; if(CRYPT_FLAG_R(session, INTEGRATED_MAC)) /* This crypto method DOES need the MAC to go through decryption so it can be authenticated. */ skip = 0; /* if what we have plus numbytes is bigger than the total minus the skip margin, we should lower the amount to decrypt even more */ if((p->data_num + numbytes) >= (p->total_num - skip)) { /* decrypt the entire rest of the package */ numdecrypt = LIBSSH2_MAX(0, (int)(p->total_num - skip) - (int)p->data_num); firstlast = LAST_BLOCK; } else { ssize_t frac; numdecrypt = numbytes; frac = numdecrypt % blocksize; if(frac) { /* not an aligned amount of blocks, align it by reducing the number of bytes processed this loop */ numdecrypt -= frac; /* and make it no unencrypted data after it */ numbytes = 0; } if(CRYPT_FLAG_R(session, INTEGRATED_MAC)) { /* Make sure that we save enough bytes to make the last * block large enough to hold the entire integrated MAC */ numdecrypt = LIBSSH2_MIN(numdecrypt, (int)(p->total_num - skip - blocksize - p->data_num)); numbytes = 0; } firstlast = MIDDLE_BLOCK; } } else { /* unencrypted data should not be decrypted at all */ numdecrypt = 0; } assert(numdecrypt >= 0); /* if there are bytes to decrypt, do that */ if(numdecrypt > 0) { /* now decrypt the lot */ rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt, firstlast); if(rc != LIBSSH2_ERROR_NONE) { p->total_num = 0; /* no packet buffer available */ return rc; } /* advance the read pointer */ p->readidx += numdecrypt; /* advance write pointer */ p->wptr += numdecrypt; /* increase data_num */ p->data_num += numdecrypt; /* bytes left to take care of without decryption */ numbytes -= numdecrypt; } /* if there are bytes to copy that aren't decrypted, copy them as-is to the target buffer */ if(numbytes > 0) { if((size_t)numbytes <= (p->total_num - (p->wptr - p->payload))) { memcpy(p->wptr, &p->buf[p->readidx], numbytes); } else { if(p->payload) LIBSSH2_FREE(session, p->payload); return LIBSSH2_ERROR_OUT_OF_BOUNDARY; } /* advance the read pointer */ p->readidx += numbytes; /* advance write pointer */ p->wptr += numbytes; /* increase data_num */ p->data_num += numbytes; } /* now check how much data there's left to read to finish the current packet */ remainpack = p->total_num - p->data_num; if(!remainpack) { /* we have a full packet */ libssh2_transport_read_point1: rc = fullpacket(session, encrypted); if(rc == LIBSSH2_ERROR_EAGAIN) { if(session->packAdd_state != libssh2_NB_state_idle) { /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if * libssh2_packet_add() returns LIBSSH2_ERROR_EAGAIN. If * that returns LIBSSH2_ERROR_EAGAIN but the packAdd_state * is idle, then the packet has been added to the brigade, * but some immediate action that was taken based on the * packet type (such as key re-exchange) is not yet * complete. Clear the way for a new packet to be read * in. */ session->readPack_encrypted = encrypted; session->readPack_state = libssh2_NB_state_jump1; } return rc; } p->total_num = 0; /* no packet buffer available */ return rc; } } while(1); /* loop */ return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */ } static int send_existing(LIBSSH2_SESSION *session, const unsigned char *data, size_t data_len, ssize_t *ret) { ssize_t rc; ssize_t length; struct transportpacket *p = &session->packet; if(!p->olen) { *ret = 0; return LIBSSH2_ERROR_NONE; } /* send as much as possible of the existing packet */ if((data != p->odata) || (data_len != p->olen)) { /* When we are about to complete the sending of a packet, it is vital that the caller doesn't try to send a new/different packet since we don't add this one up until the previous one has been sent. To make the caller really notice his/hers flaw, we return error for this case */ _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Address is different, but will resume nonetheless")); } *ret = 1; /* set to make our parent return */ /* number of bytes left to send */ length = p->ototal_num - p->osent; rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length, LIBSSH2_SOCKET_SEND_FLAGS(session)); if(rc < 0) _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Error sending %d bytes: %d", length, -rc)); else { _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p+%d", rc, length, p->outbuf, p->osent)); debugdump(session, "libssh2_transport_write send()", &p->outbuf[p->osent], rc); } if(rc == length) { /* the remainder of the package was sent */ p->ototal_num = 0; p->olen = 0; /* we leave *ret set so that the parent returns as we MUST return back a send success now, so that we don't risk sending EAGAIN later which then would confuse the parent function */ return LIBSSH2_ERROR_NONE; } else if(rc < 0) { /* nothing was sent */ if(rc != -EAGAIN) /* send failure! */ return LIBSSH2_ERROR_SOCKET_SEND; session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; return LIBSSH2_ERROR_EAGAIN; } p->osent += rc; /* we sent away this much data */ return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE; } /* * libssh2_transport_send * * Send a packet, encrypting it and adding a MAC code if necessary * Returns 0 on success, non-zero on failure. * * The data is provided as _two_ data areas that are combined by this * function. The 'data' part is sent immediately before 'data2'. 'data2' may * be set to NULL to only use a single part. * * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was * not sent yet. If it does so, the caller should call this function again as * soon as it is likely that more data can be sent, and this function MUST * then be called with the same argument set (same data pointer and same * data_len) until ERROR_NONE or failure is returned. * * This function DOES NOT call _libssh2_error() on any errors. */ int _libssh2_transport_send(LIBSSH2_SESSION *session, const unsigned char *data, size_t data_len, const unsigned char *data2, size_t data2_len) { int blocksize = (session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->blocksize : 8; ssize_t padding_length; size_t packet_length; ssize_t total_length; #ifdef LIBSSH2_RANDOM_PADDING int rand_max; int seed = data[0]; /* FIXME: make this random */ #endif struct transportpacket *p = &session->packet; int encrypted; int compressed; int etm; ssize_t ret; int rc; const unsigned char *orgdata = data; size_t orgdata_len = data_len; size_t crypt_offset, etm_crypt_offset; /* * If the last read operation was interrupted in the middle of a key * exchange, we must complete that key exchange before continuing to write * further data. * * See the similar block in _libssh2_transport_read for more details. */ if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS && !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { /* Don't write any new packets if we're still in the middle of a key * exchange. */ _libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Redirecting into the" " key re-exchange from _libssh2_transport_send")); rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); if(rc) return rc; } debugdump(session, "libssh2_transport_write plain", data, data_len); if(data2) debugdump(session, "libssh2_transport_write plain2", data2, data2_len); /* FIRST, check if we have a pending write to complete. send_existing only sanity-check data and data_len and not data2 and data2_len!! */ rc = send_existing(session, data, data_len, &ret); if(rc) return rc; session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; if(ret) /* set by send_existing if data was sent */ return rc; encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0; etm = encrypted && session->local.mac ? session->local.mac->etm : 0; compressed = session->local.comp && session->local.comp->compress && ((session->state & LIBSSH2_STATE_AUTHENTICATED) || session->local.comp->use_in_auth); if(encrypted && compressed && session->local.comp_abstract) { /* the idea here is that these function must fail if the output gets larger than what fits in the assigned buffer so thus they don't check the input size as we don't know how much it compresses */ size_t dest_len = MAX_SSH_PACKET_LEN-5-256; size_t dest2_len = dest_len; /* compress directly to the target buffer */ rc = session->local.comp->comp(session, &p->outbuf[5], &dest_len, data, data_len, &session->local.comp_abstract); if(rc) return rc; /* compression failure */ if(data2 && data2_len) { /* compress directly to the target buffer right after where the previous call put data */ dest2_len -= dest_len; rc = session->local.comp->comp(session, &p->outbuf[5 + dest_len], &dest2_len, data2, data2_len, &session->local.comp_abstract); } else dest2_len = 0; if(rc) return rc; /* compression failure */ data_len = dest_len + dest2_len; /* use the combined length */ } else { if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100)) /* too large packet, return error for this until we make this function split it up and send multiple SSH packets */ return LIBSSH2_ERROR_INVAL; /* copy the payload data */ memcpy(&p->outbuf[5], data, data_len); if(data2 && data2_len) memcpy(&p->outbuf[5 + data_len], data2, data2_len); data_len += data2_len; /* use the combined length */ } /* RFC4253 says: Note that the length of the concatenation of 'packet_length', 'padding_length', 'payload', and 'random padding' MUST be a multiple of the cipher block size or 8, whichever is larger. */ /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ packet_length = data_len + 1 + 4; /* 1 is for padding_length field 4 for the packet_length field */ /* subtract 4 bytes of the packet_length field when padding AES-GCM or with ETM */ crypt_offset = (etm || (encrypted && CRYPT_FLAG_R(session, PKTLEN_AAD))) ? 4 : 0; etm_crypt_offset = etm ? 4 : 0; /* at this point we have it all except the padding */ /* first figure out our minimum padding amount to make it an even block size */ padding_length = blocksize - ((packet_length - crypt_offset) % blocksize); /* if the padding becomes too small we add another blocksize worth of it (taken from the original libssh2 where it didn't have any real explanation) */ if(padding_length < 4) { padding_length += blocksize; } #ifdef LIBSSH2_RANDOM_PADDING /* FIXME: we can add padding here, but that also makes the packets bigger etc */ /* now we can add 'blocksize' to the padding_length N number of times (to "help thwart traffic analysis") but it must be less than 255 in total */ rand_max = (255 - padding_length) / blocksize + 1; padding_length += blocksize * (seed % rand_max); #endif packet_length += padding_length; /* append the MAC length to the total_length size */ total_length = packet_length + (encrypted ? session->local.mac->mac_len : 0); /* store packet_length, which is the size of the whole packet except the MAC and the packet_length field itself */ _libssh2_htonu32(p->outbuf, (uint32_t)(packet_length - 4)); /* store padding_length */ p->outbuf[4] = (unsigned char)padding_length; /* fill the padding area with random junk */ if(_libssh2_random(p->outbuf + 5 + data_len, padding_length)) { return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN, "Unable to get random bytes for packet padding"); } if(encrypted) { size_t i; /* Calculate MAC hash. Put the output at index packet_length, since that size includes the whole packet. The MAC is calculated on the entire unencrypted packet, including all fields except the MAC field itself. This is skipped in the INTEGRATED_MAC case, where the crypto algorithm also does its own hash. */ if(!etm && !CRYPT_FLAG_R(session, INTEGRATED_MAC)) { session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length, NULL, 0, &session->local.mac_abstract); } /* Encrypt the whole packet data, one block size at a time. The MAC field is not encrypted unless INTEGRATED_MAC. */ /* Some crypto back-ends could handle a single crypt() call for encryption, but (presumably) others cannot, so break it up into blocksize-sized chunks to satisfy them all. */ for(i = etm_crypt_offset; i < packet_length; i += session->local.crypt->blocksize) { unsigned char *ptr = &p->outbuf[i]; size_t bsize = LIBSSH2_MIN(session->local.crypt->blocksize, (int)(packet_length-i)); /* The INTEGRATED_MAC case always has an extra call below, so it will never be LAST_BLOCK up here. */ int firstlast = i == 0 ? FIRST_BLOCK : (!CRYPT_FLAG_L(session, INTEGRATED_MAC) && (i == packet_length - session->local.crypt->blocksize) ? LAST_BLOCK: MIDDLE_BLOCK); /* In the AAD case, the last block would be only 4 bytes because everything is offset by 4 since the initial packet_length isn't encrypted. In this case, combine that last short packet with the previous one since AES-GCM crypt() assumes that the entire MAC is available in that packet so it can set that to the authentication tag. */ if(!CRYPT_FLAG_L(session, INTEGRATED_MAC)) if(i > packet_length - 2*bsize) { /* increase the final block size */ bsize = packet_length - i; /* advance the loop counter by the extra amount */ i += bsize - session->local.crypt->blocksize; } _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "crypting bytes %d-%d", i, i + session->local.crypt->blocksize - 1)); if(session->local.crypt->crypt(session, ptr, bsize, &session->local.crypt_abstract, firstlast)) return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ } /* Call crypt() one last time so it can be filled in with the MAC */ if(CRYPT_FLAG_L(session, INTEGRATED_MAC)) { int authlen = session->local.mac->mac_len; assert((size_t)total_length <= packet_length + session->local.crypt->blocksize); if(session->local.crypt->crypt(session, &p->outbuf[packet_length], authlen, &session->local.crypt_abstract, LAST_BLOCK)) return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ } if(etm) { /* Calculate MAC hash. Put the output at index packet_length, since that size includes the whole packet. The MAC is calculated on the entire packet (length plain the rest encrypted), including all fields except the MAC field itself. */ session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length, NULL, 0, &session->local.mac_abstract); } } session->local.seqno++; ret = LIBSSH2_SEND(session, p->outbuf, total_length, LIBSSH2_SOCKET_SEND_FLAGS(session)); if(ret < 0) _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Error sending %d bytes: %d", total_length, -ret)); else { _libssh2_debug((session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p", ret, total_length, p->outbuf)); debugdump(session, "libssh2_transport_write send()", p->outbuf, ret); } if(ret != total_length) { if(ret >= 0 || ret == -EAGAIN) { /* the whole packet could not be sent, save the rest */ session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; p->odata = orgdata; p->olen = orgdata_len; p->osent = ret <= 0 ? 0 : ret; p->ototal_num = total_length; return LIBSSH2_ERROR_EAGAIN; } return LIBSSH2_ERROR_SOCKET_SEND; } /* the whole thing got sent away */ p->odata = NULL; p->olen = 0; return LIBSSH2_ERROR_NONE; /* all is good */ } libssh2-1.11.0/src/keepalive.c0000644000175000017500000000664414424650606013002 00000000000000/* Copyright (C) 2010 Simon Josefsson * Author: Simon Josefsson * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ #include "libssh2_priv.h" #include "transport.h" /* _libssh2_transport_write */ /* Keep-alive stuff. */ LIBSSH2_API void libssh2_keepalive_config(LIBSSH2_SESSION *session, int want_reply, unsigned interval) { if(interval == 1) session->keepalive_interval = 2; else session->keepalive_interval = interval; session->keepalive_want_reply = want_reply ? 1 : 0; } LIBSSH2_API int libssh2_keepalive_send(LIBSSH2_SESSION *session, int *seconds_to_next) { time_t now; if(!session->keepalive_interval) { if(seconds_to_next) *seconds_to_next = 0; return 0; } now = time(NULL); if(session->keepalive_last_sent + session->keepalive_interval <= now) { /* Format is "SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */ unsigned char keepalive_data[] = "\x50\x00\x00\x00\x15keepalive@libssh2.orgW"; size_t len = sizeof(keepalive_data) - 1; int rc; keepalive_data[len - 1] = (unsigned char)session->keepalive_want_reply; rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0); /* Silently ignore PACKET_EAGAIN here: if the write buffer is already full, sending another keepalive is not useful. */ if(rc && rc != LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keepalive message"); return rc; } session->keepalive_last_sent = now; if(seconds_to_next) *seconds_to_next = session->keepalive_interval; } else if(seconds_to_next) { *seconds_to_next = (int) (session->keepalive_last_sent - now) + session->keepalive_interval; } return 0; } libssh2-1.11.0/src/sftp.h0000644000175000017500000001700314424650606012005 00000000000000#ifndef __LIBSSH2_SFTP_H #define __LIBSSH2_SFTP_H /* * Copyright (C) 2010 - 2012 by Daniel Stenberg * Author: Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ /* * MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the * amount of data sent in each FXP_WRITE packet */ #define MAX_SFTP_OUTGOING_SIZE 30000 /* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ * packets. */ #define MAX_SFTP_READ_SIZE 30000 struct sftp_pipeline_chunk { struct list_node node; libssh2_uint64_t offset; /* READ: offset at which to start reading WRITE: not used */ size_t len; /* WRITE: size of the data to write READ: how many bytes that was asked for */ size_t sent; ssize_t lefttosend; /* if 0, the entire packet has been sent off */ uint32_t request_id; unsigned char packet[1]; /* data */ }; struct sftp_zombie_requests { struct list_node node; uint32_t request_id; }; struct _LIBSSH2_SFTP_PACKET { struct list_node node; /* linked list header */ uint32_t request_id; unsigned char *data; size_t data_len; /* payload size */ }; typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET; #define SFTP_HANDLE_MAXLEN 256 /* according to spec! */ struct _LIBSSH2_SFTP_HANDLE { struct list_node node; LIBSSH2_SFTP *sftp; char handle[SFTP_HANDLE_MAXLEN]; size_t handle_len; enum { LIBSSH2_SFTP_HANDLE_FILE, LIBSSH2_SFTP_HANDLE_DIR } handle_type; union _libssh2_sftp_handle_data { struct _libssh2_sftp_handle_file_data { libssh2_uint64_t offset; libssh2_uint64_t offset_sent; size_t acked; /* container for acked data that hasn't been returned to caller yet, used for sftp_write */ /* 'data' is used by sftp_read() and is allocated data that has been received already from the server but wasn't returned to the caller yet. It is of size 'data_len' and 'data_left is the number of bytes not yet returned, counted from the end of the buffer. */ unsigned char *data; size_t data_len; size_t data_left; char eof; /* we have read to the end */ } file; struct _libssh2_sftp_handle_dir_data { uint32_t names_left; void *names_packet; char *next_name; size_t names_packet_len; } dir; } u; /* State variables used in libssh2_sftp_close_handle() */ libssh2_nonblocking_states close_state; uint32_t close_request_id; unsigned char *close_packet; /* list of outstanding packets sent to server */ struct list_head packet_list; }; struct _LIBSSH2_SFTP { LIBSSH2_CHANNEL *channel; uint32_t request_id, version; struct list_head packets; /* List of FXP_READ responses to ignore because EOF already received. */ struct list_head zombie_requests; /* a list of _LIBSSH2_SFTP_HANDLE structs */ struct list_head sftp_handles; uint32_t last_errno; /* Holder for partial packet, use in libssh2_sftp_packet_read() */ unsigned char packet_header[9]; /* packet size (4) packet type (1) request id (4) */ size_t packet_header_len; /* packet_header length */ unsigned char *partial_packet; /* The data, with header */ uint32_t partial_len; /* Desired number of bytes */ size_t partial_received; /* Bytes received so far */ /* Time that libssh2_sftp_packet_requirev() started reading */ time_t requirev_start; /* State variables used in libssh2_sftp_open_ex() */ libssh2_nonblocking_states open_state; unsigned char *open_packet; uint32_t open_packet_len; /* 32 bit on the wire */ size_t open_packet_sent; uint32_t open_request_id; /* State variable used in sftp_read() */ libssh2_nonblocking_states read_state; /* State variable used in sftp_packet_read() */ libssh2_nonblocking_states packet_state; /* State variable used in sftp_write() */ libssh2_nonblocking_states write_state; /* State variables used in sftp_fsync() */ libssh2_nonblocking_states fsync_state; unsigned char *fsync_packet; uint32_t fsync_request_id; /* State variables used in libssh2_sftp_readdir() */ libssh2_nonblocking_states readdir_state; unsigned char *readdir_packet; uint32_t readdir_request_id; /* State variables used in libssh2_sftp_fstat_ex() */ libssh2_nonblocking_states fstat_state; unsigned char *fstat_packet; uint32_t fstat_request_id; /* State variables used in libssh2_sftp_unlink_ex() */ libssh2_nonblocking_states unlink_state; unsigned char *unlink_packet; uint32_t unlink_request_id; /* State variables used in libssh2_sftp_rename_ex() */ libssh2_nonblocking_states rename_state; unsigned char *rename_packet; unsigned char *rename_s; uint32_t rename_request_id; /* State variables used in libssh2_sftp_fstatvfs() */ libssh2_nonblocking_states fstatvfs_state; unsigned char *fstatvfs_packet; uint32_t fstatvfs_request_id; /* State variables used in libssh2_sftp_statvfs() */ libssh2_nonblocking_states statvfs_state; unsigned char *statvfs_packet; uint32_t statvfs_request_id; /* State variables used in libssh2_sftp_mkdir() */ libssh2_nonblocking_states mkdir_state; unsigned char *mkdir_packet; uint32_t mkdir_request_id; /* State variables used in libssh2_sftp_rmdir() */ libssh2_nonblocking_states rmdir_state; unsigned char *rmdir_packet; uint32_t rmdir_request_id; /* State variables used in libssh2_sftp_stat() */ libssh2_nonblocking_states stat_state; unsigned char *stat_packet; uint32_t stat_request_id; /* State variables used in libssh2_sftp_symlink() */ libssh2_nonblocking_states symlink_state; unsigned char *symlink_packet; uint32_t symlink_request_id; }; #endif /* __LIBSSH2_SFTP_H */ libssh2-1.11.0/src/Makefile.am0000644000175000017500000000353014424650606012714 00000000000000AUTOMAKE_OPTIONS = foreign nostdinc # Get the CSOURCES, HHEADERS and EXTRA_DIST defines include Makefile.inc libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS) if HAVE_WINDRES libssh2_la_SOURCES += libssh2.rc endif EXTRA_DIST += libssh2_config.h.in libssh2_config_cmake.h.in CMakeLists.txt lib_LTLIBRARIES = libssh2.la # srcdir/include for the shipped headers # builddir/src for the generated config header when building out of the source # tree AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/include VERSION=-version-info 1:1:0 # This flag accepts an argument of the form current[:revision[:age]]. So, # passing -version-info 3:12:1 sets current to 3, revision to 12, and age to # 1. # # If either revision or age are omitted, they default to 0. Also note that age # must be less than or equal to the current interface number. # # Here are a set of rules to help you update your library version information: # # 1.Start with version information of 0:0:0 for each libtool library. # # 2.Update the version information only immediately before a public release of # your software. More frequent updates are unnecessary, and only guarantee # that the current interface number gets larger faster. # # 3.If the library source code has changed at all since the last update, then # increment revision (c:r+1:a) # # 4.If any interfaces have been added, removed, or changed since the last # update, increment current, and set revision to 0. (c+1:r=0:a) # # 5.If any interfaces have been added since the last public release, then # increment age. (c:r:a+1) # # 6.If any interfaces have been removed since the last public release, then # set age to 0. (c:r:a=0) # libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ -export-symbols-regex '^libssh2_.*' \ $(LTLIBZ) if HAVE_WINDRES .rc.lo: $(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@ endif libssh2-1.11.0/src/crypt.c0000644000175000017500000003050314424650606012165 00000000000000/* Copyright (c) 2009, 2010 Simon Josefsson * Copyright (c) 2004-2007, Sara Golemon * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE) /* crypt_none_crypt * Minimalist cipher: no encryption. DO NOT USE. * * The SSH2 Transport allows for unencrypted data transmission using * the "none" cipher. Because this is such a huge security hole, it is * typically disabled on SSH2 implementations and is disabled in libssh2 * by default as well. * * Enabling this option will allow for "none" as a negotiable method, * however it still requires that the method be advertised by the remote * end and that no more-preferable methods are available. * */ static int crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf, void **abstract, int firstlast) { /* Do nothing to the data! */ return 0; } static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { "none", "DEK-Info: NONE", 8, /* blocksize (SSH2 defines minimum blocksize as 8) */ 0, /* iv_len */ 0, /* secret_len */ 0, /* flags */ NULL, crypt_none_crypt, NULL }; #endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE) */ struct crypt_ctx { int encrypt; _libssh2_cipher_type(algo); _libssh2_cipher_ctx h; }; static int crypt_init(LIBSSH2_SESSION * session, const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract) { struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, sizeof(struct crypt_ctx)); if(!ctx) return LIBSSH2_ERROR_ALLOC; ctx->encrypt = encrypt; ctx->algo = method->algo; if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) { LIBSSH2_FREE(session, ctx); return -1; } *abstract = ctx; *free_iv = 1; *free_secret = 1; return 0; } static int crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block, size_t blocksize, void **abstract, int firstlast) { struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; (void) session; return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, blocksize, firstlast); } static int crypt_dtor(LIBSSH2_SESSION * session, void **abstract) { struct crypt_ctx **cctx = (struct crypt_ctx **) abstract; if(cctx && *cctx) { _libssh2_cipher_dtor(&(*cctx)->h); LIBSSH2_FREE(session, *cctx); *abstract = NULL; } return 0; } #if LIBSSH2_AES_GCM static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_gcm = { "aes256-gcm@openssh.com", "", 16, /* blocksize */ 12, /* initial value length */ 32, /* secret length -- 32*8 == 256bit */ LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD, &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes256gcm }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_gcm = { "aes128-gcm@openssh.com", "", 16, /* blocksize */ 12, /* initial value length */ 16, /* secret length -- 16*8 == 128bit */ LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD, &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes128gcm }; #endif #if LIBSSH2_AES_CTR static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = { "aes128-ctr", "", 16, /* blocksize */ 16, /* initial value length */ 16, /* secret length -- 16*8 == 128bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes128ctr }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = { "aes192-ctr", "", 16, /* blocksize */ 16, /* initial value length */ 24, /* secret length -- 24*8 == 192bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes192ctr }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = { "aes256-ctr", "", 16, /* blocksize */ 16, /* initial value length */ 32, /* secret length -- 32*8 == 256bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes256ctr }; #endif #if LIBSSH2_AES_CBC static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { "aes128-cbc", "DEK-Info: AES-128-CBC", 16, /* blocksize */ 16, /* initial value length */ 16, /* secret length -- 16*8 == 128bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes128 }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { "aes192-cbc", "DEK-Info: AES-192-CBC", 16, /* blocksize */ 16, /* initial value length */ 24, /* secret length -- 24*8 == 192bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes192 }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { "aes256-cbc", "DEK-Info: AES-256-CBC", 16, /* blocksize */ 16, /* initial value length */ 32, /* secret length -- 32*8 == 256bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes256 }; /* rijndael-cbc@lysator.liu.se == aes256-cbc */ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { "rijndael-cbc@lysator.liu.se", "DEK-Info: AES-256-CBC", 16, /* blocksize */ 16, /* initial value length */ 32, /* secret length -- 32*8 == 256bit */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_aes256 }; #endif /* LIBSSH2_AES_CBC */ #if LIBSSH2_BLOWFISH static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { "blowfish-cbc", "", 8, /* blocksize */ 8, /* initial value length */ 16, /* secret length */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_blowfish }; #endif /* LIBSSH2_BLOWFISH */ #if LIBSSH2_RC4 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { "arcfour", "DEK-Info: RC4", 8, /* blocksize */ 8, /* initial value length */ 16, /* secret length */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_arcfour }; static int crypt_init_arcfour128(LIBSSH2_SESSION * session, const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract) { int rc; rc = crypt_init(session, method, iv, free_iv, secret, free_secret, encrypt, abstract); if(rc == 0) { struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; unsigned char block[8]; size_t discard = 1536; for(; discard; discard -= 8) _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, method->blocksize, MIDDLE_BLOCK); /* Not all middle, but here it doesn't matter */ } return rc; } static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = { "arcfour128", "", 8, /* blocksize */ 8, /* initial value length */ 16, /* secret length */ 0, /* flags */ &crypt_init_arcfour128, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_arcfour }; #endif /* LIBSSH2_RC4 */ #if LIBSSH2_CAST static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { "cast128-cbc", "", 8, /* blocksize */ 8, /* initial value length */ 16, /* secret length */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_cast5 }; #endif /* LIBSSH2_CAST */ #if LIBSSH2_3DES static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { "3des-cbc", "DEK-Info: DES-EDE3-CBC", 8, /* blocksize */ 8, /* initial value length */ 24, /* secret length */ 0, /* flags */ &crypt_init, &crypt_encrypt, &crypt_dtor, _libssh2_cipher_3des }; #endif /* These are the crypt methods that are available to be negotiated. Methods towards the start are chosen in preference to ones further down the list. */ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { #if LIBSSH2_AES_GCM &libssh2_crypt_method_aes256_gcm, &libssh2_crypt_method_aes128_gcm, #endif /* LIBSSH2_AES_GCM */ #if LIBSSH2_AES_CTR &libssh2_crypt_method_aes256_ctr, &libssh2_crypt_method_aes192_ctr, &libssh2_crypt_method_aes128_ctr, #endif /* LIBSSH2_AES_CTR */ #if LIBSSH2_AES_CBC &libssh2_crypt_method_aes256_cbc, &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ &libssh2_crypt_method_aes192_cbc, &libssh2_crypt_method_aes128_cbc, #endif /* LIBSSH2_AES_CBC */ #if LIBSSH2_BLOWFISH &libssh2_crypt_method_blowfish_cbc, #endif /* LIBSSH2_BLOWFISH */ #if LIBSSH2_RC4 &libssh2_crypt_method_arcfour128, &libssh2_crypt_method_arcfour, #endif /* LIBSSH2_RC4 */ #if LIBSSH2_CAST &libssh2_crypt_method_cast128_cbc, #endif /* LIBSSH2_CAST */ #if LIBSSH2_3DES &libssh2_crypt_method_3des_cbc, #endif /* LIBSSH2_DES */ #if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE) &libssh2_crypt_method_none, #endif NULL }; /* Expose to kex.c */ const LIBSSH2_CRYPT_METHOD ** libssh2_crypt_methods(void) { return _libssh2_crypt_methods; } libssh2-1.11.0/src/libssh2_config.h.in0000644000175000017500000001366714424651703014344 00000000000000/* src/libssh2_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define to 1 if using 'alloca.c'. */ #undef C_ALLOCA /* Define to 1 if you have 'alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if works. */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the `explicit_bzero' function. */ #undef HAVE_EXPLICIT_BZERO /* Define to 1 if you have the `explicit_memset' function. */ #undef HAVE_EXPLICIT_MEMSET /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* use FIONBIO for non-blocking sockets */ #undef HAVE_FIONBIO /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* use Ioctlsocket() for non-blocking sockets */ #undef HAVE_IOCTLSOCKET_CASE /* Define if you have the bcrypt library. */ #undef HAVE_LIBBCRYPT /* Define if you have the gcrypt library. */ #undef HAVE_LIBGCRYPT /* Define if you have the mbedcrypto library. */ #undef HAVE_LIBMBEDCRYPTO /* Define if you have the ssl library. */ #undef HAVE_LIBSSL /* Define if you have the wolfssl library. */ #undef HAVE_LIBWOLFSSL /* Define if you have the z library. */ #undef HAVE_LIBZ /* Define to 1 if you have the `memset_s' function. */ #undef HAVE_MEMSET_S /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* use O_NONBLOCK for non-blocking sockets */ #undef HAVE_O_NONBLOCK /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL /* Define to 1 if you have the select function. */ #undef HAVE_SELECT /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* use SO_NONBLOCK for non-blocking sockets */ #undef HAVE_SO_NONBLOCK /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UN_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* to make a symbol visible */ #undef LIBSSH2_API /* Compile in zlib support */ #undef LIBSSH2_HAVE_ZLIB /* Use libgcrypt */ #undef LIBSSH2_LIBGCRYPT /* Use mbedtls */ #undef LIBSSH2_MBEDTLS /* Disable clearing of memory before being freed */ #undef LIBSSH2_NO_CLEAR_MEMORY /* Use openssl */ #undef LIBSSH2_OPENSSL /* Use wincng */ #undef LIBSSH2_WINCNG /* Use wolfssl */ #undef LIBSSH2_WOLFSSL /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ #undef NEED_REENTRANT /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `unsigned int' if does not define. */ #undef size_t libssh2-1.11.0/src/channel.c0000644000175000017500000031752514432741311012441 00000000000000/* Copyright (c) 2004-2007 Sara Golemon * Copyright (c) 2005 Mikhail Gusarov * Copyright (c) 2008-2019 by Daniel Stenberg * * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #include #include "channel.h" #include "transport.h" #include "packet.h" #include "session.h" /* * _libssh2_channel_nextid * * Determine the next channel ID we can use at our end */ uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session) { uint32_t id = session->next_channel; LIBSSH2_CHANNEL *channel; channel = _libssh2_list_first(&session->channels); while(channel) { if(channel->local.id > id) { id = channel->local.id; } channel = _libssh2_list_next(&channel->node); } /* This is a shortcut to avoid waiting for close packets on channels we've * forgotten about, This *could* be a problem if we request and close 4 * billion or so channels in too rapid succession for the remote end to * respond, but the worst case scenario is that some data meant for * another channel Gets picked up by the new one.... Pretty unlikely all * told... */ session->next_channel = id + 1; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Allocated new channel ID#%lu", id)); return id; } /* * _libssh2_channel_locate * * Locate a channel pointer by number */ LIBSSH2_CHANNEL * _libssh2_channel_locate(LIBSSH2_SESSION *session, uint32_t channel_id) { LIBSSH2_CHANNEL *channel; LIBSSH2_LISTENER *l; for(channel = _libssh2_list_first(&session->channels); channel; channel = _libssh2_list_next(&channel->node)) { if(channel->local.id == channel_id) return channel; } /* We didn't find the channel in the session, let's then check its listeners since each listener may have its own set of pending channels */ for(l = _libssh2_list_first(&session->listeners); l; l = _libssh2_list_next(&l->node)) { for(channel = _libssh2_list_first(&l->queue); channel; channel = _libssh2_list_next(&channel->node)) { if(channel->local.id == channel_id) return channel; } } return NULL; } /* * _libssh2_channel_open * * Establish a generic session channel */ LIBSSH2_CHANNEL * _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, uint32_t channel_type_len, uint32_t window_size, uint32_t packet_size, const unsigned char *message, size_t message_len) { static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE, 0 }; unsigned char *s; int rc; if(session->open_state == libssh2_NB_state_idle) { session->open_channel = NULL; session->open_packet = NULL; session->open_data = NULL; /* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) + * window_size(4) + packet_size(4) */ session->open_packet_len = channel_type_len + 17; session->open_local_channel = _libssh2_channel_nextid(session); /* Zero the whole thing out */ memset(&session->open_packet_requirev_state, 0, sizeof(session->open_packet_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Opening Channel - win %d pack %d", window_size, packet_size)); session->open_channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); if(!session->open_channel) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate space for channel data"); return NULL; } session->open_channel->channel_type_len = channel_type_len; session->open_channel->channel_type = LIBSSH2_ALLOC(session, channel_type_len); if(!session->open_channel->channel_type) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating memory for channel type name"); LIBSSH2_FREE(session, session->open_channel); session->open_channel = NULL; return NULL; } memcpy(session->open_channel->channel_type, channel_type, channel_type_len); /* REMEMBER: local as in locally sourced */ session->open_channel->local.id = session->open_local_channel; session->open_channel->remote.window_size = window_size; session->open_channel->remote.window_size_initial = window_size; session->open_channel->remote.packet_size = packet_size; session->open_channel->session = session; _libssh2_list_add(&session->channels, &session->open_channel->node); s = session->open_packet = LIBSSH2_ALLOC(session, session->open_packet_len); if(!session->open_packet) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate temporary space for packet"); goto channel_error; } *(s++) = SSH_MSG_CHANNEL_OPEN; _libssh2_store_str(&s, channel_type, channel_type_len); _libssh2_store_u32(&s, session->open_local_channel); _libssh2_store_u32(&s, window_size); _libssh2_store_u32(&s, packet_size); /* Do not copy the message */ session->open_state = libssh2_NB_state_created; } if(session->open_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->open_packet, session->open_packet_len, message, message_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending channel-open request"); return NULL; } else if(rc) { _libssh2_error(session, rc, "Unable to send channel-open request"); goto channel_error; } session->open_state = libssh2_NB_state_sent; } if(session->open_state == libssh2_NB_state_sent) { rc = _libssh2_packet_requirev(session, reply_codes, &session->open_data, &session->open_data_len, 1, session->open_packet + 5 + channel_type_len, 4, &session->open_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return NULL; } else if(rc) { _libssh2_error(session, rc, "Unexpected error"); goto channel_error; } if(session->open_data_len < 1) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); goto channel_error; } if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { if(session->open_data_len < 17) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); goto channel_error; } session->open_channel->remote.id = _libssh2_ntohu32(session->open_data + 5); session->open_channel->local.window_size = _libssh2_ntohu32(session->open_data + 9); session->open_channel->local.window_size_initial = _libssh2_ntohu32(session->open_data + 9); session->open_channel->local.packet_size = _libssh2_ntohu32(session->open_data + 13); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Connection Established - ID: %lu/%lu win: %lu/%lu" " pack: %lu/%lu", session->open_channel->local.id, session->open_channel->remote.id, session->open_channel->local.window_size, session->open_channel->remote.window_size, session->open_channel->local.packet_size, session->open_channel->remote.packet_size)); LIBSSH2_FREE(session, session->open_packet); session->open_packet = NULL; LIBSSH2_FREE(session, session->open_data); session->open_data = NULL; session->open_state = libssh2_NB_state_idle; return session->open_channel; } if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { unsigned int reason_code = _libssh2_ntohu32(session->open_data + 5); switch(reason_code) { case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED: _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure " "(administratively prohibited)"); break; case SSH_OPEN_CONNECT_FAILED: _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure (connect failed)"); break; case SSH_OPEN_UNKNOWN_CHANNELTYPE: _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure (unknown channel type)"); break; case SSH_OPEN_RESOURCE_SHORTAGE: _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure (resource shortage)"); break; default: _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure"); } } } channel_error: if(session->open_data) { LIBSSH2_FREE(session, session->open_data); session->open_data = NULL; } if(session->open_packet) { LIBSSH2_FREE(session, session->open_packet); session->open_packet = NULL; } if(session->open_channel) { unsigned char channel_id[4]; LIBSSH2_FREE(session, session->open_channel->channel_type); _libssh2_list_remove(&session->open_channel->node); /* Clear out packets meant for this channel */ _libssh2_htonu32(channel_id, session->open_channel->local.id); while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &session->open_data, &session->open_data_len, 1, channel_id, 4) >= 0) || (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &session->open_data, &session->open_data_len, 1, channel_id, 4) >= 0)) { LIBSSH2_FREE(session, session->open_data); session->open_data = NULL; } LIBSSH2_FREE(session, session->open_channel); session->open_channel = NULL; } session->open_state = libssh2_NB_state_idle; return NULL; } /* * libssh2_channel_open_ex * * Establish a generic session channel */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *type, unsigned int type_len, unsigned int window_size, unsigned int packet_size, const char *msg, unsigned int msg_len) { LIBSSH2_CHANNEL *ptr; if(!session) return NULL; BLOCK_ADJUST_ERRNO(ptr, session, _libssh2_channel_open(session, type, type_len, window_size, packet_size, (unsigned char *)msg, msg_len)); return ptr; } /* * libssh2_channel_direct_tcpip_ex * * Tunnel TCP/IP connect through the SSH session to direct host/port */ static LIBSSH2_CHANNEL * channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host, int port, const char *shost, int sport) { LIBSSH2_CHANNEL *channel; unsigned char *s; if(session->direct_state == libssh2_NB_state_idle) { session->direct_host_len = strlen(host); session->direct_shost_len = strlen(shost); /* host_len(4) + port(4) + shost_len(4) + sport(4) */ session->direct_message_len = session->direct_host_len + session->direct_shost_len + 16; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Requesting direct-tcpip session from %s:%d to %s:%d", shost, sport, host, port)); s = session->direct_message = LIBSSH2_ALLOC(session, session->direct_message_len); if(!session->direct_message) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "direct-tcpip connection"); return NULL; } _libssh2_store_str(&s, host, session->direct_host_len); _libssh2_store_u32(&s, port); _libssh2_store_str(&s, shost, session->direct_shost_len); _libssh2_store_u32(&s, sport); } channel = _libssh2_channel_open(session, "direct-tcpip", sizeof("direct-tcpip") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, session->direct_message, session->direct_message_len); if(!channel && libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { /* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state to created to avoid re-creating the package on next invoke */ session->direct_state = libssh2_NB_state_created; return NULL; } /* by default we set (keep?) idle state... */ session->direct_state = libssh2_NB_state_idle; LIBSSH2_FREE(session, session->direct_message); session->direct_message = NULL; return channel; } /* * libssh2_channel_direct_tcpip_ex * * Tunnel TCP/IP connect through the SSH session to direct host/port */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport) { LIBSSH2_CHANNEL *ptr; if(!session) return NULL; BLOCK_ADJUST_ERRNO(ptr, session, channel_direct_tcpip(session, host, port, shost, sport)); return ptr; } /* * libssh2_channel_direct_streamlocal_ex * * Tunnel TCP/IP connect through the SSH session to direct UNIX socket */ static LIBSSH2_CHANNEL * channel_direct_streamlocal(LIBSSH2_SESSION * session, const char *socket_path, const char *shost, int sport) { LIBSSH2_CHANNEL *channel; unsigned char *s; if(session->direct_state == libssh2_NB_state_idle) { session->direct_host_len = strlen(socket_path); session->direct_shost_len = strlen(shost); session->direct_message_len = session->direct_host_len + session->direct_shost_len + 12; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Requesting direct-streamlocal session to %s", socket_path)); s = session->direct_message = LIBSSH2_ALLOC(session, session->direct_message_len); if(!session->direct_message) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for direct-streamlocal connection"); return NULL; } _libssh2_store_str(&s, socket_path, session->direct_host_len); _libssh2_store_str(&s, shost, session->direct_shost_len); _libssh2_store_u32(&s, sport); } channel = _libssh2_channel_open(session, "direct-streamlocal@openssh.com", sizeof("direct-streamlocal@openssh.com") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, session->direct_message, session->direct_message_len); if(!channel && libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { /* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state to created to avoid re-creating the package on next invoke */ session->direct_state = libssh2_NB_state_created; return NULL; } /* by default we set (keep?) idle state... */ session->direct_state = libssh2_NB_state_idle; LIBSSH2_FREE(session, session->direct_message); session->direct_message = NULL; return channel; } /* * libssh2_channel_direct_streamlocal_ex * * Tunnel TCP/IP connect through the SSH session to direct UNIX socket */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_direct_streamlocal_ex(LIBSSH2_SESSION * session, const char *socket_path, const char *shost, int sport) { LIBSSH2_CHANNEL *ptr; if(!session) return NULL; BLOCK_ADJUST_ERRNO(ptr, session, channel_direct_streamlocal(session, socket_path, shost, sport)); return ptr; } /* * channel_forward_listen * * Bind a port on the remote host and listen for connections */ static LIBSSH2_LISTENER * channel_forward_listen(LIBSSH2_SESSION * session, const char *host, int port, int *bound_port, int queue_maxsize) { unsigned char *s; static const unsigned char reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; int rc; if(!host) host = "0.0.0.0"; if(session->fwdLstn_state == libssh2_NB_state_idle) { session->fwdLstn_host_len = (uint32_t)strlen(host); /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ session->fwdLstn_packet_len = session->fwdLstn_host_len + (uint32_t)(sizeof("tcpip-forward") - 1) + 14; /* Zero the whole thing out */ memset(&session->fwdLstn_packet_requirev_state, 0, sizeof(session->fwdLstn_packet_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Requesting tcpip-forward session for %s:%d", host, port)); s = session->fwdLstn_packet = LIBSSH2_ALLOC(session, session->fwdLstn_packet_len); if(!session->fwdLstn_packet) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for setenv packet"); return NULL; } *(s++) = SSH_MSG_GLOBAL_REQUEST; _libssh2_store_str(&s, "tcpip-forward", sizeof("tcpip-forward") - 1); *(s++) = 0x01; /* want_reply */ _libssh2_store_str(&s, host, session->fwdLstn_host_len); _libssh2_store_u32(&s, port); session->fwdLstn_state = libssh2_NB_state_created; } if(session->fwdLstn_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->fwdLstn_packet, session->fwdLstn_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending global-request packet for " "forward listen request"); return NULL; } else if(rc) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward " "listen request"); LIBSSH2_FREE(session, session->fwdLstn_packet); session->fwdLstn_packet = NULL; session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } LIBSSH2_FREE(session, session->fwdLstn_packet); session->fwdLstn_packet = NULL; session->fwdLstn_state = libssh2_NB_state_sent; } if(session->fwdLstn_state == libssh2_NB_state_sent) { unsigned char *data; size_t data_len; rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, 0, NULL, 0, &session->fwdLstn_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return NULL; } else if(rc || (data_len < 1)) { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown"); session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } if(data[0] == SSH_MSG_REQUEST_SUCCESS) { LIBSSH2_LISTENER *listener; listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER)); if(!listener) _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue"); else { listener->host = LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); if(!listener->host) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory " "for listener queue"); LIBSSH2_FREE(session, listener); listener = NULL; } else { listener->session = session; memcpy(listener->host, host, session->fwdLstn_host_len); listener->host[session->fwdLstn_host_len] = 0; if(data_len >= 5 && !port) { listener->port = _libssh2_ntohu32(data + 1); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Dynamic tcpip-forward port " "allocated: %d", listener->port)); } else listener->port = port; listener->queue_size = 0; listener->queue_maxsize = queue_maxsize; /* append this to the parent's list of listeners */ _libssh2_list_add(&session->listeners, &listener->node); if(bound_port) { *bound_port = listener->port; } } } LIBSSH2_FREE(session, data); session->fwdLstn_state = libssh2_NB_state_idle; return listener; } else if(data[0] == SSH_MSG_REQUEST_FAILURE) { LIBSSH2_FREE(session, data); _libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, "Unable to complete request for forward-listen"); session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } } session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } /* * libssh2_channel_forward_listen_ex * * Bind a port on the remote host and listen for connections */ LIBSSH2_API LIBSSH2_LISTENER * libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize) { LIBSSH2_LISTENER *ptr; if(!session) return NULL; BLOCK_ADJUST_ERRNO(ptr, session, channel_forward_listen(session, host, port, bound_port, queue_maxsize)); return ptr; } /* * _libssh2_channel_forward_cancel * * Stop listening on a remote port and free the listener * Toss out any pending (un-accept()ed) connections * * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error */ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) { LIBSSH2_SESSION *session = listener->session; LIBSSH2_CHANNEL *queued; unsigned char *packet, *s; size_t host_len = strlen(listener->host); /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ size_t packet_len = host_len + 14 + sizeof("cancel-tcpip-forward") - 1; int rc; int retcode = 0; if(listener->chanFwdCncl_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Cancelling tcpip-forward session for %s:%d", listener->host, listener->port)); s = packet = LIBSSH2_ALLOC(session, packet_len); if(!packet) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for setenv packet"); return LIBSSH2_ERROR_ALLOC; } *(s++) = SSH_MSG_GLOBAL_REQUEST; _libssh2_store_str(&s, "cancel-tcpip-forward", sizeof("cancel-tcpip-forward") - 1); *(s++) = 0x00; /* want_reply */ _libssh2_store_str(&s, listener->host, host_len); _libssh2_store_u32(&s, listener->port); listener->chanFwdCncl_state = libssh2_NB_state_created; } else { packet = listener->chanFwdCncl_data; } if(listener->chanFwdCncl_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, packet, packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending forward request"); listener->chanFwdCncl_data = packet; return rc; } else if(rc) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward " "listen request"); /* set the state to something we don't check for, for the unfortunate situation where we get an EAGAIN further down when trying to bail out due to errors! */ listener->chanFwdCncl_state = libssh2_NB_state_sent; retcode = LIBSSH2_ERROR_SOCKET_SEND; } LIBSSH2_FREE(session, packet); listener->chanFwdCncl_state = libssh2_NB_state_sent; } queued = _libssh2_list_first(&listener->queue); while(queued) { LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node); rc = _libssh2_channel_free(queued); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } queued = next; } LIBSSH2_FREE(session, listener->host); /* remove this entry from the parent's list of listeners */ _libssh2_list_remove(&listener->node); LIBSSH2_FREE(session, listener); return retcode; } /* * libssh2_channel_forward_cancel * * Stop listening on a remote port and free the listener * Toss out any pending (un-accept()ed) connections * * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error */ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) { int rc; if(!listener) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, listener->session, _libssh2_channel_forward_cancel(listener)); return rc; } /* * channel_forward_accept * * Accept a connection */ static LIBSSH2_CHANNEL * channel_forward_accept(LIBSSH2_LISTENER *listener) { int rc; do { rc = _libssh2_transport_read(listener->session); } while(rc > 0); if(_libssh2_list_first(&listener->queue)) { LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue); /* detach channel from listener's queue */ _libssh2_list_remove(&channel->node); listener->queue_size--; /* add channel to session's channel list */ _libssh2_list_add(&channel->session->channels, &channel->node); return channel; } if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for packet"); } else _libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, "Channel not found"); return NULL; } /* * libssh2_channel_forward_accept * * Accept a connection */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) { LIBSSH2_CHANNEL *ptr; if(!listener) return NULL; BLOCK_ADJUST_ERRNO(ptr, listener->session, channel_forward_accept(listener)); return ptr; } /* * channel_setenv * * Set an environment variable prior to requesting a shell/program/subsystem */ static int channel_setenv(LIBSSH2_CHANNEL *channel, const char *varname, unsigned int varname_len, const char *value, unsigned int value_len) { LIBSSH2_SESSION *session = channel->session; unsigned char *s, *data; static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; size_t data_len; int rc; if(channel->setenv_state == libssh2_NB_state_idle) { /* 21 = packet_type(1) + channel_id(4) + request_len(4) + * request(3)"env" + want_reply(1) + varname_len(4) + value_len(4) */ channel->setenv_packet_len = varname_len + value_len + 21; /* Zero the whole thing out */ memset(&channel->setenv_packet_requirev_state, 0, sizeof(channel->setenv_packet_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Setting remote environment variable: %s=%s on " "channel %lu/%lu", varname, value, channel->local.id, channel->remote.id)); s = channel->setenv_packet = LIBSSH2_ALLOC(session, channel->setenv_packet_len); if(!channel->setenv_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory " "for setenv packet"); } *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, "env", sizeof("env") - 1); *(s++) = 0x01; _libssh2_store_str(&s, varname, varname_len); _libssh2_store_str(&s, value, value_len); channel->setenv_state = libssh2_NB_state_created; } if(channel->setenv_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->setenv_packet, channel->setenv_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending setenv request"); return rc; } else if(rc) { LIBSSH2_FREE(session, channel->setenv_packet); channel->setenv_packet = NULL; channel->setenv_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel-request packet for " "setenv request"); } LIBSSH2_FREE(session, channel->setenv_packet); channel->setenv_packet = NULL; _libssh2_htonu32(channel->setenv_local_channel, channel->local.id); channel->setenv_state = libssh2_NB_state_sent; } if(channel->setenv_state == libssh2_NB_state_sent) { rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, 1, channel->setenv_local_channel, 4, &channel-> setenv_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } if(rc) { channel->setenv_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Failed getting response for " "channel-setenv"); } else if(data_len < 1) { channel->setenv_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); } if(data[0] == SSH_MSG_CHANNEL_SUCCESS) { LIBSSH2_FREE(session, data); channel->setenv_state = libssh2_NB_state_idle; return 0; } LIBSSH2_FREE(session, data); } channel->setenv_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-setenv"); } /* * libssh2_channel_setenv_ex * * Set an environment variable prior to requesting a shell/program/subsystem */ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, const char *varname, unsigned int varname_len, const char *value, unsigned int value_len) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_setenv(channel, varname, varname_len, value, value_len)); return rc; } /* * channel_request_pty * Duh... Request a PTY */ static int channel_request_pty(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px) { LIBSSH2_SESSION *session = channel->session; unsigned char *s; static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; int rc; if(channel->reqPTY_state == libssh2_NB_state_idle) { /* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + * want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) + * height_px(4) + modes_len(4) */ if(term_len + modes_len > 256) { return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "term + mode lengths too large"); } channel->reqPTY_packet_len = term_len + modes_len + 41; /* Zero the whole thing out */ memset(&channel->reqPTY_packet_requirev_state, 0, sizeof(channel->reqPTY_packet_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Allocating tty on channel %lu/%lu", channel->local.id, channel->remote.id)); s = channel->reqPTY_packet; *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, (char *)"pty-req", sizeof("pty-req") - 1); *(s++) = 0x01; _libssh2_store_str(&s, term, term_len); _libssh2_store_u32(&s, width); _libssh2_store_u32(&s, height); _libssh2_store_u32(&s, width_px); _libssh2_store_u32(&s, height_px); _libssh2_store_str(&s, modes, modes_len); channel->reqPTY_state = libssh2_NB_state_created; } if(channel->reqPTY_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->reqPTY_packet, channel->reqPTY_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending pty request"); return rc; } else if(rc) { channel->reqPTY_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send pty-request packet"); } _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); channel->reqPTY_state = libssh2_NB_state_sent; } if(channel->reqPTY_state == libssh2_NB_state_sent) { unsigned char *data; size_t data_len; unsigned char code; rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, 1, channel->reqPTY_local_channel, 4, &channel->reqPTY_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc || data_len < 1) { channel->reqPTY_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Failed to require the PTY package"); } code = data[0]; LIBSSH2_FREE(session, data); channel->reqPTY_state = libssh2_NB_state_idle; if(code == SSH_MSG_CHANNEL_SUCCESS) return 0; } return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for " "channel request-pty"); } /** * channel_request_auth_agent * The actual re-entrant method which requests an auth agent. * */ static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel, const char *request_str, int request_str_len) { LIBSSH2_SESSION *session = channel->session; unsigned char *s; static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; int rc; if(channel->req_auth_agent_state == libssh2_NB_state_idle) { /* Only valid options are "auth-agent-req" and * "auth-agent-req_at_openssh.com" so we make sure it is not * actually longer than the longest possible. */ if(request_str_len > 26) { return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "request_str length too large"); } /* * Length: 24 or 36 = packet_type(1) + channel(4) + req_len(4) + * request_str (variable) + want_reply (1) */ channel->req_auth_agent_packet_len = 10 + request_str_len; /* Zero out the requireev state to reset */ memset(&channel->req_auth_agent_requirev_state, 0, sizeof(channel->req_auth_agent_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Requesting auth agent on channel %lu/%lu", channel->local.id, channel->remote.id)); /* * byte SSH_MSG_CHANNEL_REQUEST * uint32 recipient channel * string "auth-agent-req" * boolean want reply * */ s = channel->req_auth_agent_packet; *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, (char *)request_str, request_str_len); *(s++) = 0x01; channel->req_auth_agent_state = libssh2_NB_state_created; } if(channel->req_auth_agent_state == libssh2_NB_state_created) { /* Send the packet, we can use sizeof() on the packet because it * is always completely filled; there are no variable length fields. */ rc = _libssh2_transport_send(session, channel->req_auth_agent_packet, channel->req_auth_agent_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending auth-agent request"); return rc; } else if(rc) { channel->req_auth_agent_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send auth-agent request"); } _libssh2_htonu32(channel->req_auth_agent_local_channel, channel->local.id); channel->req_auth_agent_state = libssh2_NB_state_sent; } if(channel->req_auth_agent_state == libssh2_NB_state_sent) { unsigned char *data; size_t data_len; unsigned char code; rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, 1, channel->req_auth_agent_local_channel, 4, &channel->req_auth_agent_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc) { channel->req_auth_agent_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Failed to request auth-agent"); } code = data[0]; LIBSSH2_FREE(session, data); channel->req_auth_agent_state = libssh2_NB_state_idle; if(code == SSH_MSG_CHANNEL_SUCCESS) return 0; } return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for auth-agent"); } /* * libssh2_channel_request_auth_agent * * Requests that agent forwarding be enabled for the session. The * request must be sent over a specific channel, which starts the agent * listener on the remote side. Once the channel is closed, the agent * listener continues to exist. */ LIBSSH2_API int libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; rc = LIBSSH2_ERROR_CHANNEL_UNKNOWN; /* The current RFC draft for agent forwarding says you're supposed to * send "auth-agent-req," but most SSH servers out there right now * actually expect "auth-agent-req@openssh.com", so we try that * first. */ if(channel->req_auth_agent_try_state == libssh2_NB_state_idle) { BLOCK_ADJUST(rc, channel->session, channel_request_auth_agent(channel, "auth-agent-req@openssh.com", 26)); /* If we failed (but not with EAGAIN), then we move onto * the next step to try another request type. */ if(rc != LIBSSH2_ERROR_NONE && rc != LIBSSH2_ERROR_EAGAIN) channel->req_auth_agent_try_state = libssh2_NB_state_sent; } if(channel->req_auth_agent_try_state == libssh2_NB_state_sent) { BLOCK_ADJUST(rc, channel->session, channel_request_auth_agent(channel, "auth-agent-req", 14)); /* If we failed without an EAGAIN, then move on with this * state machine. */ if(rc != LIBSSH2_ERROR_NONE && rc != LIBSSH2_ERROR_EAGAIN) channel->req_auth_agent_try_state = libssh2_NB_state_sent1; } /* If things are good, reset the try state. */ if(rc == LIBSSH2_ERROR_NONE) channel->req_auth_agent_try_state = libssh2_NB_state_idle; return rc; } /* * libssh2_channel_request_pty_ex * Duh... Request a PTY */ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_request_pty(channel, term, term_len, modes, modes_len, width, height, width_px, height_px)); return rc; } static int channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width, int height, int width_px, int height_px) { LIBSSH2_SESSION *session = channel->session; unsigned char *s; int rc; int retcode = LIBSSH2_ERROR_PROTO; if(channel->reqPTY_state == libssh2_NB_state_idle) { channel->reqPTY_packet_len = 39; /* Zero the whole thing out */ memset(&channel->reqPTY_packet_requirev_state, 0, sizeof(channel->reqPTY_packet_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "changing tty size on channel %lu/%lu", channel->local.id, channel->remote.id)); s = channel->reqPTY_packet; *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, (char *)"window-change", sizeof("window-change") - 1); *(s++) = 0x00; /* Don't reply */ _libssh2_store_u32(&s, width); _libssh2_store_u32(&s, height); _libssh2_store_u32(&s, width_px); _libssh2_store_u32(&s, height_px); channel->reqPTY_state = libssh2_NB_state_created; } if(channel->reqPTY_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->reqPTY_packet, channel->reqPTY_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending window-change request"); return rc; } else if(rc) { channel->reqPTY_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send window-change packet"); } _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); retcode = LIBSSH2_ERROR_NONE; } channel->reqPTY_state = libssh2_NB_state_idle; return retcode; } LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, int width, int height, int width_px, int height_px) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_request_pty_size(channel, width, height, width_px, height_px)); return rc; } /* Keep this an even number */ #define LIBSSH2_X11_RANDOM_COOKIE_LEN 32 /* * channel_x11_req * Request X11 forwarding */ static int channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number) { LIBSSH2_SESSION *session = channel->session; unsigned char *s; static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; size_t proto_len = auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); size_t cookie_len = auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; int rc; if(channel->reqX11_state == libssh2_NB_state_idle) { /* 30 = packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + * want_reply(1) + single_cnx(1) + proto_len(4) + cookie_len(4) + * screen_num(4) */ channel->reqX11_packet_len = proto_len + cookie_len + 30; /* Zero the whole thing out */ memset(&channel->reqX11_packet_requirev_state, 0, sizeof(channel->reqX11_packet_requirev_state)); _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Requesting x11-req for channel %lu/%lu: single=%d " "proto=%s cookie=%s screen=%d", channel->local.id, channel->remote.id, single_connection, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", auth_cookie ? auth_cookie : "", screen_number)); s = channel->reqX11_packet = LIBSSH2_ALLOC(session, channel->reqX11_packet_len); if(!channel->reqX11_packet) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request"); } *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, "x11-req", sizeof("x11-req") - 1); *(s++) = 0x01; /* want_reply */ *(s++) = single_connection ? 0x01 : 0x00; _libssh2_store_str(&s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", proto_len); _libssh2_store_u32(&s, (uint32_t)cookie_len); if(auth_cookie) { memcpy(s, auth_cookie, cookie_len); } else { int i; /* note: the extra +1 below is necessary since the sprintf() loop will always write 3 bytes so the last one will write the trailing zero at the LIBSSH2_X11_RANDOM_COOKIE_LEN/2 border */ unsigned char buffer[(LIBSSH2_X11_RANDOM_COOKIE_LEN / 2) + 1]; if(_libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2)) { return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN, "Unable to get random bytes " "for x11-req cookie"); } for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { snprintf((char *)&s[i*2], 3, "%02X", buffer[i]); } } s += cookie_len; _libssh2_store_u32(&s, screen_number); channel->reqX11_state = libssh2_NB_state_created; } if(channel->reqX11_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->reqX11_packet, channel->reqX11_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending X11-req packet"); return rc; } if(rc) { LIBSSH2_FREE(session, channel->reqX11_packet); channel->reqX11_packet = NULL; channel->reqX11_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send x11-req packet"); } LIBSSH2_FREE(session, channel->reqX11_packet); channel->reqX11_packet = NULL; _libssh2_htonu32(channel->reqX11_local_channel, channel->local.id); channel->reqX11_state = libssh2_NB_state_sent; } if(channel->reqX11_state == libssh2_NB_state_sent) { size_t data_len; unsigned char *data; unsigned char code; rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, 1, channel->reqX11_local_channel, 4, &channel->reqX11_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc || data_len < 1) { channel->reqX11_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "waiting for x11-req response packet"); } code = data[0]; LIBSSH2_FREE(session, data); channel->reqX11_state = libssh2_NB_state_idle; if(code == SSH_MSG_CHANNEL_SUCCESS) return 0; } return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel x11-req"); } /* * libssh2_channel_x11_req_ex * Request X11 forwarding */ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_x11_req(channel, single_connection, auth_proto, auth_cookie, screen_number)); return rc; } /* * _libssh2_channel_process_startup * * Primitive for libssh2_channel_(shell|exec|subsystem) */ int _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, size_t request_len, const char *message, size_t message_len) { LIBSSH2_SESSION *session = channel->session; unsigned char *s; static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; int rc; if(channel->process_state == libssh2_NB_state_end) { return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, "Channel can not be reused"); } if(channel->process_state == libssh2_NB_state_idle) { /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ channel->process_packet_len = request_len + 10; /* Zero the whole thing out */ memset(&channel->process_packet_requirev_state, 0, sizeof(channel->process_packet_requirev_state)); if(message) channel->process_packet_len += + 4; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "starting request(%s) on channel %lu/%lu, message=%s", request, channel->local.id, channel->remote.id, message ? message : "")); s = channel->process_packet = LIBSSH2_ALLOC(session, channel->process_packet_len); if(!channel->process_packet) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory " "for channel-process request"); *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, request, request_len); *(s++) = 0x01; if(message) _libssh2_store_u32(&s, (uint32_t)message_len); channel->process_state = libssh2_NB_state_created; } if(channel->process_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->process_packet, channel->process_packet_len, (unsigned char *)message, message_len); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending channel request"); return rc; } else if(rc) { LIBSSH2_FREE(session, channel->process_packet); channel->process_packet = NULL; channel->process_state = libssh2_NB_state_end; return _libssh2_error(session, rc, "Unable to send channel request"); } LIBSSH2_FREE(session, channel->process_packet); channel->process_packet = NULL; _libssh2_htonu32(channel->process_local_channel, channel->local.id); channel->process_state = libssh2_NB_state_sent; } if(channel->process_state == libssh2_NB_state_sent) { unsigned char *data; size_t data_len; unsigned char code; rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, 1, channel->process_local_channel, 4, &channel->process_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc || data_len < 1) { channel->process_state = libssh2_NB_state_end; return _libssh2_error(session, rc, "Failed waiting for channel success"); } code = data[0]; LIBSSH2_FREE(session, data); channel->process_state = libssh2_NB_state_end; if(code == SSH_MSG_CHANNEL_SUCCESS) return 0; } return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for " "channel-process-startup"); } /* * libssh2_channel_process_startup * * Primitive for libssh2_channel_(shell|exec|subsystem) */ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *req, unsigned int req_len, const char *msg, unsigned int msg_len) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_process_startup(channel, req, req_len, msg, msg_len)); return rc; } /* * libssh2_channel_set_blocking * * Set a channel's BEHAVIOR blocking on or off. The socket will remain non- * blocking. */ LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking) { if(channel) (void)_libssh2_session_set_blocking(channel->session, blocking); } /* * _libssh2_channel_flush * * Flush data from one (or all) stream * Returns number of bytes flushed, or negative on failure */ int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid) { if(channel->flush_state == libssh2_NB_state_idle) { LIBSSH2_PACKET *packet = _libssh2_list_first(&channel->session->packets); channel->flush_refund_bytes = 0; channel->flush_flush_bytes = 0; while(packet) { unsigned char packet_type; LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node); if(packet->data_len < 1) { packet = next; _libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR, "Unexpected packet length")); continue; } packet_type = packet->data[0]; if(((packet_type == SSH_MSG_CHANNEL_DATA) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && ((packet->data_len >= 5) && (_libssh2_ntohu32(packet->data + 1) == channel->local.id))) { /* It's our channel at least */ int packet_stream_id; if(packet_type == SSH_MSG_CHANNEL_DATA) { packet_stream_id = 0; } else if(packet->data_len >= 9) { packet_stream_id = _libssh2_ntohu32(packet->data + 5); } else { channel->flush_state = libssh2_NB_state_idle; return _libssh2_error(channel->session, LIBSSH2_ERROR_PROTO, "Unexpected packet length"); } if((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) || (streamid == packet_stream_id))) || ((packet_type == SSH_MSG_CHANNEL_DATA) && (streamid == 0))) { size_t bytes_to_flush = packet->data_len - packet->data_head; _libssh2_debug((channel->session, LIBSSH2_TRACE_CONN, "Flushing %d bytes of data from stream " "%lu on channel %lu/%lu", bytes_to_flush, packet_stream_id, channel->local.id, channel->remote.id)); /* It's one of the streams we wanted to flush */ channel->flush_refund_bytes += packet->data_len - 13; channel->flush_flush_bytes += bytes_to_flush; LIBSSH2_FREE(channel->session, packet->data); /* remove this packet from the parent's list */ _libssh2_list_remove(&packet->node); LIBSSH2_FREE(channel->session, packet); } } packet = next; } channel->flush_state = libssh2_NB_state_created; } channel->read_avail -= channel->flush_flush_bytes; channel->remote.window_size -= (uint32_t)channel->flush_flush_bytes; if(channel->flush_refund_bytes) { int rc = _libssh2_channel_receive_window_adjust(channel, (uint32_t)channel->flush_refund_bytes, 1, NULL); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; } channel->flush_state = libssh2_NB_state_idle; return (int)channel->flush_flush_bytes; } /* * libssh2_channel_flush_ex * * Flush data from one (or all) stream * Returns number of bytes flushed, or negative on failure */ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int stream) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_flush(channel, stream)); return rc; } /* * libssh2_channel_get_exit_status * * Return the channel's program exit status. Note that the actual protocol * provides the full 32bit this function returns. We cannot abuse it to * return error values in case of errors so we return a zero if channel is * NULL. */ LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL *channel) { if(!channel) return 0; return channel->exit_status; } /* * libssh2_channel_get_exit_signal * * Get exit signal (without leading "SIG"), error message, and language * tag into newly allocated buffers of indicated length. Caller can * use NULL pointers to indicate that the value should not be set. The * *_len variables are set if they are non-NULL even if the * corresponding string parameter is NULL. Returns LIBSSH2_ERROR_NONE * on success, or an API error code. */ LIBSSH2_API int libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel, char **exitsignal, size_t *exitsignal_len, char **errmsg, size_t *errmsg_len, char **langtag, size_t *langtag_len) { size_t namelen = 0; if(channel) { LIBSSH2_SESSION *session = channel->session; if(channel->exit_signal) { namelen = strlen(channel->exit_signal); if(exitsignal) { *exitsignal = LIBSSH2_ALLOC(session, namelen + 1); if(!*exitsignal) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for signal name"); } memcpy(*exitsignal, channel->exit_signal, namelen); (*exitsignal)[namelen] = '\0'; } if(exitsignal_len) *exitsignal_len = namelen; } else { if(exitsignal) *exitsignal = NULL; if(exitsignal_len) *exitsignal_len = 0; } /* TODO: set error message and language tag */ if(errmsg) *errmsg = NULL; if(errmsg_len) *errmsg_len = 0; if(langtag) *langtag = NULL; if(langtag_len) *langtag_len = 0; } return LIBSSH2_ERROR_NONE; } /* * _libssh2_channel_receive_window_adjust * * Adjust the receive window for a channel by adjustment bytes. If the amount * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the * adjustment amount will be queued for a later packet. * * Calls _libssh2_error() ! */ int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, uint32_t adjustment, unsigned char force, unsigned int *store) { int rc; if(store) *store = channel->remote.window_size; if(channel->adjust_state == libssh2_NB_state_idle) { if(!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) { _libssh2_debug((channel->session, LIBSSH2_TRACE_CONN, "Queueing %lu bytes for receive window adjustment " "for channel %lu/%lu", adjustment, channel->local.id, channel->remote.id)); channel->adjust_queue += adjustment; return 0; } if(!adjustment && !channel->adjust_queue) { return 0; } adjustment += channel->adjust_queue; channel->adjust_queue = 0; /* Adjust the window based on the block we just freed */ channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; _libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id); _libssh2_htonu32(&channel->adjust_adjust[5], adjustment); _libssh2_debug((channel->session, LIBSSH2_TRACE_CONN, "Adjusting window %lu bytes for data on " "channel %lu/%lu", adjustment, channel->local.id, channel->remote.id)); channel->adjust_state = libssh2_NB_state_created; } rc = _libssh2_transport_send(channel->session, channel->adjust_adjust, 9, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(channel->session, rc, "Would block sending window adjust"); return rc; } else if(rc) { channel->adjust_queue = adjustment; return _libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment " "packet, deferring"); } else { channel->remote.window_size += adjustment; } channel->adjust_state = libssh2_NB_state_idle; return 0; } /* * libssh2_channel_receive_window_adjust * * DEPRECATED * * Adjust the receive window for a channel by adjustment bytes. If the amount * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the * adjustment amount will be queued for a later packet. * * Returns the new size of the receive window (as understood by remote end). * Note that it might return EAGAIN too which is highly stupid. * */ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adj, unsigned char force) { unsigned int window; int rc; if(!channel) return (unsigned long)LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_receive_window_adjust(channel, (uint32_t)adj, force, &window)); /* stupid - but this is how it was made to work before and this is just kept for backwards compatibility */ return rc ? (unsigned long)rc : window; } /* * libssh2_channel_receive_window_adjust2 * * Adjust the receive window for a channel by adjustment bytes. If the amount * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the * adjustment amount will be queued for a later packet. * * Stores the new size of the receive window in the data 'window' points to. * * Returns the "normal" error code: 0 for success, negative for failure. */ LIBSSH2_API int libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, unsigned long adj, unsigned char force, unsigned int *window) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_receive_window_adjust(channel, (uint32_t)adj, force, window)); return rc; } int _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) { if(channel->extData2_state == libssh2_NB_state_idle) { _libssh2_debug((channel->session, LIBSSH2_TRACE_CONN, "Setting channel %lu/%lu handle_extended_data" " mode to %d", channel->local.id, channel->remote.id, ignore_mode)); channel->remote.extended_data_ignore_mode = (char)ignore_mode; channel->extData2_state = libssh2_NB_state_created; } if(channel->extData2_state == libssh2_NB_state_idle) { if(ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { int rc = _libssh2_channel_flush(channel, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA); if(LIBSSH2_ERROR_EAGAIN == rc) return rc; } } channel->extData2_state = libssh2_NB_state_idle; return 0; } /* * libssh2_channel_handle_extended_data2 * */ LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int mode) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_extended_data(channel, mode)); return rc; } /* * libssh2_channel_handle_extended_data * * DEPRECATED DO NOTE USE! * * How should extended data look to the calling app? Keep it in separate * channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the * standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss * out packets as they come in]? (IGNORE) */ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) { (void)libssh2_channel_handle_extended_data2(channel, ignore_mode); } /* * _libssh2_channel_read * * Read data from a channel * * It is important to not return 0 until the currently read channel is * complete. If we read stuff from the wire but it was no payload data to fill * in the buffer with, we MUST make sure to return LIBSSH2_ERROR_EAGAIN. * * The receive window must be maintained (enlarged) by the user of this * function. */ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen) { LIBSSH2_SESSION *session = channel->session; int rc; size_t bytes_read = 0; size_t bytes_want; int unlink_packet; LIBSSH2_PACKET *read_packet; LIBSSH2_PACKET *read_next; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "channel_read() wants %d bytes from channel %lu/%lu " "stream #%d", (int) buflen, channel->local.id, channel->remote.id, stream_id)); /* expand the receiving window first if it has become too narrow */ if((channel->read_state == libssh2_NB_state_jump1) || (channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen)) { uint32_t adjustment = (uint32_t)(channel->remote.window_size_initial + buflen - channel->remote.window_size); if(adjustment < LIBSSH2_CHANNEL_MINADJUST) adjustment = LIBSSH2_CHANNEL_MINADJUST; /* the actual window adjusting may not finish so we need to deal with this special state here */ channel->read_state = libssh2_NB_state_jump1; rc = _libssh2_channel_receive_window_adjust(channel, adjustment, 0, NULL); if(rc) return rc; channel->read_state = libssh2_NB_state_idle; } /* Process all pending incoming packets. Tests prove that this way produces faster transfers. */ do { rc = _libssh2_transport_read(session); } while(rc > 0); if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) return _libssh2_error(session, rc, "transport read"); read_packet = _libssh2_list_first(&session->packets); while(read_packet && (bytes_read < buflen)) { /* previously this loop condition also checked for !channel->remote.close but we cannot let it do this: We may have a series of packets to read that are still pending even if a close has been received. Acknowledging the close too early makes us flush buffers prematurely and loose data. */ LIBSSH2_PACKET *readpkt = read_packet; /* In case packet gets destroyed during this iteration */ read_next = _libssh2_list_next(&readpkt->node); if(readpkt->data_len < 5) { read_packet = read_next; if(readpkt->data_len != 1 || readpkt->data[0] != SSH_MSG_REQUEST_FAILURE) { _libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR, "Unexpected packet length")); } continue; } channel->read_local_id = _libssh2_ntohu32(readpkt->data + 1); /* * Either we asked for a specific extended data stream * (and data was available), * or the standard stream (and data was available), * or the standard stream with extended_data_merge * enabled and data was available */ if((stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == channel->read_local_id) && (readpkt->data_len >= 9) && (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5))) || (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA) && (channel->local.id == channel->read_local_id)) || (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == channel->read_local_id) && (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { /* figure out much more data we want to read */ bytes_want = buflen - bytes_read; unlink_packet = FALSE; if(bytes_want >= (readpkt->data_len - readpkt->data_head)) { /* we want more than this node keeps, so adjust the number and delete this node after the copy */ bytes_want = readpkt->data_len - readpkt->data_head; unlink_packet = TRUE; } _libssh2_debug((session, LIBSSH2_TRACE_CONN, "channel_read() got %d of data from %lu/%lu/%d%s", bytes_want, channel->local.id, channel->remote.id, stream_id, unlink_packet?" [ul]":"")); /* copy data from this struct to the target buffer */ memcpy(&buf[bytes_read], &readpkt->data[readpkt->data_head], bytes_want); /* advance pointer and counter */ readpkt->data_head += bytes_want; bytes_read += bytes_want; /* if drained, remove from list */ if(unlink_packet) { /* detach readpkt from session->packets list */ _libssh2_list_remove(&readpkt->node); LIBSSH2_FREE(session, readpkt->data); LIBSSH2_FREE(session, readpkt); } } /* check the next struct in the chain */ read_packet = read_next; } if(!bytes_read) { /* If the channel is already at EOF or even closed, we need to signal that back. We may have gotten that info while draining the incoming transport layer until EAGAIN so we must not be fooled by that return code. */ if(channel->remote.eof || channel->remote.close) return 0; else if(rc != LIBSSH2_ERROR_EAGAIN) return 0; /* if the transport layer said EAGAIN then we say so as well */ return _libssh2_error(session, rc, "would block"); } channel->read_avail -= bytes_read; channel->remote.window_size -= (uint32_t)bytes_read; return bytes_read; } /* * libssh2_channel_read_ex * * Read data from a channel (blocking or non-blocking depending on set state) * * When this is done non-blocking, it is important to not return 0 until the * currently read channel is complete. If we read stuff from the wire but it * was no payload data to fill in the buffer with, we MUST make sure to return * LIBSSH2_ERROR_EAGAIN. * * This function will first make sure there's a receive window enough to * receive a full buffer's wort of contents. An application may choose to * adjust the receive window more to increase transfer performance. */ LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen) { ssize_t rc; unsigned long recv_window; if(!channel) return LIBSSH2_ERROR_BAD_USE; recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); if(buflen > recv_window) { BLOCK_ADJUST(rc, channel->session, _libssh2_channel_receive_window_adjust(channel, (uint32_t)buflen, 1, NULL)); } BLOCK_ADJUST(rc, channel->session, _libssh2_channel_read(channel, stream_id, buf, buflen)); return rc; } /* * _libssh2_channel_packet_data_len * * Return the size of the data block of the current packet, or 0 if there * isn't a packet. */ size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id) { LIBSSH2_SESSION *session = channel->session; LIBSSH2_PACKET *read_packet; LIBSSH2_PACKET *next_packet; uint32_t read_local_id; read_packet = _libssh2_list_first(&session->packets); if(!read_packet) return 0; while(read_packet) { next_packet = _libssh2_list_next(&read_packet->node); if(read_packet->data_len < 5) { read_packet = next_packet; _libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR, "Unexpected packet length")); continue; } read_local_id = _libssh2_ntohu32(read_packet->data + 1); /* * Either we asked for a specific extended data stream * (and data was available), * or the standard stream (and data was available), * or the standard stream with extended_data_merge * enabled and data was available */ if((stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == read_local_id) && (read_packet->data_len >= 9) && (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5))) || (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA) && (channel->local.id == read_local_id)) || (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == read_local_id) && (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { return read_packet->data_len - read_packet->data_head; } read_packet = next_packet; } return 0; } /* * _libssh2_channel_write * * Send data to a channel. Note that if this returns EAGAIN, the caller must * call this function again with the SAME input arguments. * * Returns: number of bytes sent, or if it returns a negative number, that is * the error code! */ ssize_t _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, const unsigned char *buf, size_t buflen) { int rc = 0; LIBSSH2_SESSION *session = channel->session; ssize_t wrote = 0; /* counter for this specific this call */ /* In theory we could split larger buffers into several smaller packets * but it turns out to be really hard and nasty to do while still offering * the API/prototype. * * Instead we only deal with the first 32K in this call and for the parent * function to call it again with the remainder! 32K is a conservative * limit based on the text in RFC4253 section 6.1. */ if(buflen > 32700) buflen = 32700; if(channel->write_state == libssh2_NB_state_idle) { unsigned char *s = channel->write_packet; _libssh2_debug((channel->session, LIBSSH2_TRACE_CONN, "Writing %d bytes on channel %lu/%lu, stream #%d", (int) buflen, channel->local.id, channel->remote.id, stream_id)); if(channel->local.close) return _libssh2_error(channel->session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We have already closed this channel"); else if(channel->local.eof) return _libssh2_error(channel->session, LIBSSH2_ERROR_CHANNEL_EOF_SENT, "EOF has already been received, " "data might be ignored"); /* drain the incoming flow first, mostly to make sure we get all * pending window adjust packets */ do rc = _libssh2_transport_read(session); while(rc > 0); if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { return _libssh2_error(channel->session, rc, "Failure while draining incoming flow"); } if(channel->local.window_size <= 0) { /* there's no room for data so we stop */ /* Waiting on the socket to be writable would be wrong because we * would be back here immediately, but a readable socket might * herald an incoming window adjustment. */ session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND; return rc == LIBSSH2_ERROR_EAGAIN ? rc : 0; } channel->write_bufwrite = buflen; *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA; _libssh2_store_u32(&s, channel->remote.id); if(stream_id) _libssh2_store_u32(&s, stream_id); /* Don't exceed the remote end's limits */ /* REMEMBER local means local as the SOURCE of the data */ if(channel->write_bufwrite > channel->local.window_size) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Splitting write block due to %lu byte " "window_size on %lu/%lu/%d", channel->local.window_size, channel->local.id, channel->remote.id, stream_id)); channel->write_bufwrite = channel->local.window_size; } if(channel->write_bufwrite > channel->local.packet_size) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Splitting write block due to %lu byte " "packet_size on %lu/%lu/%d", channel->local.packet_size, channel->local.id, channel->remote.id, stream_id)); channel->write_bufwrite = channel->local.packet_size; } /* store the size here only, the buffer is passed in as-is to _libssh2_transport_send() */ _libssh2_store_u32(&s, (uint32_t)channel->write_bufwrite); channel->write_packet_len = s - channel->write_packet; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Sending %d bytes on channel %lu/%lu, stream_id=%d", (int) channel->write_bufwrite, channel->local.id, channel->remote.id, stream_id)); channel->write_state = libssh2_NB_state_created; } if(channel->write_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->write_packet, channel->write_packet_len, buf, channel->write_bufwrite); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, rc, "Unable to send channel data"); } else if(rc) { channel->write_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send channel data"); } /* Shrink local window size */ channel->local.window_size -= (uint32_t)channel->write_bufwrite; wrote += channel->write_bufwrite; /* Since _libssh2_transport_write() succeeded, we must return now to allow the caller to provide the next chunk of data. We cannot move on to send the next piece of data that may already have been provided in this same function call, as we risk getting EAGAIN for that and we can't return information both about sent data as well as EAGAIN. So, by returning short now, the caller will call this function again with new data to send */ channel->write_state = libssh2_NB_state_idle; return wrote; } return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */ } /* * libssh2_channel_write_ex * * Send data to a channel */ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen) { ssize_t rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_write(channel, stream_id, (unsigned char *)buf, buflen)); return rc; } /* * channel_send_eof * * Send EOF on channel */ static int channel_send_eof(LIBSSH2_CHANNEL *channel) { LIBSSH2_SESSION *session = channel->session; unsigned char packet[5]; /* packet_type(1) + channelno(4) */ int rc; _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Sending EOF on channel %lu/%lu", channel->local.id, channel->remote.id)); packet[0] = SSH_MSG_CHANNEL_EOF; _libssh2_htonu32(packet + 1, channel->remote.id); rc = _libssh2_transport_send(session, packet, 5, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending EOF"); return rc; } else if(rc) { return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send EOF on channel"); } channel->local.eof = 1; return 0; } /* * libssh2_channel_send_eof * * Send EOF on channel */ LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_send_eof(channel)); return rc; } /* * libssh2_channel_eof * * Read channel's eof status */ LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL * channel) { LIBSSH2_SESSION *session; LIBSSH2_PACKET *packet; LIBSSH2_PACKET *next_packet; if(!channel) return LIBSSH2_ERROR_BAD_USE; session = channel->session; packet = _libssh2_list_first(&session->packets); while(packet) { next_packet = _libssh2_list_next(&packet->node); if(packet->data_len < 1) { packet = next_packet; _libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR, "Unexpected packet length")); continue; } if(((packet->data[0] == SSH_MSG_CHANNEL_DATA) || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) && ((packet->data_len >= 5) && (channel->local.id == _libssh2_ntohu32(packet->data + 1)))) { /* There's data waiting to be read yet, mask the EOF status */ return 0; } packet = next_packet; } return channel->remote.eof; } /* * channel_wait_eof * * Awaiting channel EOF */ static int channel_wait_eof(LIBSSH2_CHANNEL *channel) { LIBSSH2_SESSION *session = channel->session; int rc; if(channel->wait_eof_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Awaiting EOF for channel %lu/%lu", channel->local.id, channel->remote.id)); channel->wait_eof_state = libssh2_NB_state_created; } /* * While channel is not eof, read more packets from the network. * Either the EOF will be set or network timeout will occur. */ do { if(channel->remote.eof) { break; } if((channel->remote.window_size == channel->read_avail) && session->api_block_mode) return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_FULL, "Receiving channel window " "has been exhausted"); rc = _libssh2_transport_read(session); if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } else if(rc < 0) { channel->wait_eof_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "_libssh2_transport_read() bailed out!"); } } while(1); channel->wait_eof_state = libssh2_NB_state_idle; return 0; } /* * libssh2_channel_wait_eof * * Awaiting channel EOF */ LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_wait_eof(channel)); return rc; } int _libssh2_channel_close(LIBSSH2_CHANNEL * channel) { LIBSSH2_SESSION *session = channel->session; int rc = 0; if(channel->local.close) { /* Already closed, act like we sent another close, * even though we didn't... shhhhhh */ channel->close_state = libssh2_NB_state_idle; return 0; } if(!channel->local.eof) { rc = channel_send_eof(channel); if(rc) { if(rc == LIBSSH2_ERROR_EAGAIN) { return rc; } _libssh2_error(session, rc, "Unable to send EOF, but closing channel anyway"); } } /* ignore if we have received a remote eof or not, as it is now too late for us to wait for it. Continue closing! */ if(channel->close_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu", channel->local.id, channel->remote.id)); channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE; _libssh2_htonu32(channel->close_packet + 1, channel->remote.id); channel->close_state = libssh2_NB_state_created; } if(channel->close_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, channel->close_packet, 5, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending close-channel"); return rc; } else if(rc) { _libssh2_error(session, rc, "Unable to send close-channel request, " "but closing anyway"); /* skip waiting for the response and fall through to LIBSSH2_CHANNEL_CLOSE below */ } else channel->close_state = libssh2_NB_state_sent; } if(channel->close_state == libssh2_NB_state_sent) { /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */ while(!channel->remote.close && !rc && (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED)) rc = _libssh2_transport_read(session); } if(rc != LIBSSH2_ERROR_EAGAIN) { /* set the local close state first when we're perfectly confirmed to not do any more EAGAINs */ channel->local.close = 1; /* We call the callback last in this function to make it keep the local data as long as EAGAIN is returned. */ if(channel->close_cb) { LIBSSH2_CHANNEL_CLOSE(session, channel); } channel->close_state = libssh2_NB_state_idle; } /* return 0 or an error */ return rc >= 0 ? 0 : rc; } /* * libssh2_channel_close * * Close a channel */ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel)); return rc; } /* * channel_wait_closed * * Awaiting channel close after EOF */ static int channel_wait_closed(LIBSSH2_CHANNEL *channel) { LIBSSH2_SESSION *session = channel->session; int rc; if(!channel->remote.eof) { return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "libssh2_channel_wait_closed() invoked when " "channel is not in EOF state"); } if(channel->wait_closed_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Awaiting close of channel %lu/%lu", channel->local.id, channel->remote.id)); channel->wait_closed_state = libssh2_NB_state_created; } /* * While channel is not closed, read more packets from the network. * Either the channel will be closed or network timeout will occur. */ if(!channel->remote.close) { do { rc = _libssh2_transport_read(session); if(channel->remote.close) /* it is now closed, move on! */ break; } while(rc > 0); if(rc < 0) return rc; } channel->wait_closed_state = libssh2_NB_state_idle; return 0; } /* * libssh2_channel_wait_closed * * Awaiting channel close after EOF */ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_wait_closed(channel)); return rc; } /* * _libssh2_channel_free * * Make sure a channel is closed, then remove the channel from the session * and free its resource(s) * * Returns 0 on success, negative on failure */ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel) { LIBSSH2_SESSION *session = channel->session; unsigned char channel_id[4]; unsigned char *data; size_t data_len; int rc; assert(session); if(channel->free_state == libssh2_NB_state_idle) { _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Freeing channel %lu/%lu resources", channel->local.id, channel->remote.id)); channel->free_state = libssh2_NB_state_created; } /* Allow channel freeing even when the socket has lost its connection */ if(!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) { rc = _libssh2_channel_close(channel); if(rc == LIBSSH2_ERROR_EAGAIN) return rc; /* ignore all other errors as they otherwise risk blocking the channel free from happening */ } channel->free_state = libssh2_NB_state_idle; if(channel->exit_signal) { LIBSSH2_FREE(session, channel->exit_signal); } /* * channel->remote.close *might* not be set yet, Well... * We've sent the close packet, what more do you want? * Just let packet_add ignore it when it finally arrives */ /* Clear out packets meant for this channel */ _libssh2_htonu32(channel_id, channel->local.id); while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4) >= 0) || (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1, channel_id, 4) >= 0)) { LIBSSH2_FREE(session, data); } /* free "channel_type" */ if(channel->channel_type) { LIBSSH2_FREE(session, channel->channel_type); } /* Unlink from channel list */ _libssh2_list_remove(&channel->node); /* * Make sure all memory used in the state variables are free */ if(channel->setenv_packet) { LIBSSH2_FREE(session, channel->setenv_packet); } if(channel->reqX11_packet) { LIBSSH2_FREE(session, channel->reqX11_packet); } if(channel->process_packet) { LIBSSH2_FREE(session, channel->process_packet); } LIBSSH2_FREE(session, channel); return 0; } /* * libssh2_channel_free * * Make sure a channel is closed, then remove the channel from the session * and free its resource(s) * * Returns 0 on success, negative on failure */ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, _libssh2_channel_free(channel)); return rc; } /* * libssh2_channel_window_read_ex * * Check the status of the read window. Returns the number of bytes which the * remote end may send without overflowing the window limit read_avail (if * passed) will be populated with the number of bytes actually available to be * read window_size_initial (if passed) will be populated with the * window_size_initial as defined by the channel_open request */ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, /* FIXME: -> size_t */ unsigned long *read_avail, unsigned long *window_size_initial) { if(!channel) return 0; /* no channel, no window! */ if(window_size_initial) { *window_size_initial = channel->remote.window_size_initial; } if(read_avail) { size_t bytes_queued = 0; LIBSSH2_PACKET *next_packet; LIBSSH2_PACKET *packet = _libssh2_list_first(&channel->session->packets); while(packet) { unsigned char packet_type; next_packet = _libssh2_list_next(&packet->node); if(packet->data_len < 1) { packet = next_packet; _libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR, "Unexpected packet length")); continue; } packet_type = packet->data[0]; if(((packet_type == SSH_MSG_CHANNEL_DATA) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && ((packet->data_len >= 5) && (_libssh2_ntohu32(packet->data + 1) == channel->local.id))) { bytes_queued += packet->data_len - packet->data_head; } packet = next_packet; } *read_avail = (unsigned long)bytes_queued; } return channel->remote.window_size; } /* * libssh2_channel_window_write_ex * * Check the status of the write window Returns the number of bytes which may * be safely written on the channel without blocking window_size_initial (if * passed) will be populated with the size of the initial window as defined by * the channel_open request */ LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial) { if(!channel) return 0; /* no channel, no window! */ if(window_size_initial) { /* For locally initiated channels this is very often 0, so it's not * *that* useful as information goes */ *window_size_initial = channel->local.window_size_initial; } return channel->local.window_size; } /* A signal can be delivered to the remote process/service using the following message. Some systems may not implement signals, in which case they SHOULD ignore this message. byte SSH_MSG_CHANNEL_REQUEST uint32 recipient channel string "signal" boolean FALSE string signal name (without the "SIG" prefix) 'signal name' values will be encoded as discussed in the passage describing SSH_MSG_CHANNEL_REQUEST messages using "exit-signal" in this section. */ static int channel_signal(LIBSSH2_CHANNEL *channel, const char *signame, size_t signame_len) { LIBSSH2_SESSION *session = channel->session; int retcode = LIBSSH2_ERROR_PROTO; if(channel->sendsignal_state == libssh2_NB_state_idle) { unsigned char *s; /* 20 = packet_type(1) + channel(4) + signal_len + sizeof(signal) - 1 + want_reply(1) + signame_len_len(4) */ channel->sendsignal_packet_len = 20 + signame_len; s = channel->sendsignal_packet = LIBSSH2_ALLOC(session, channel->sendsignal_packet_len); if(!channel->sendsignal_packet) return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "signal request"); *(s++) = SSH_MSG_CHANNEL_REQUEST; _libssh2_store_u32(&s, channel->remote.id); _libssh2_store_str(&s, "signal", sizeof("signal") - 1); *(s++) = 0x00; /* Don't reply */ _libssh2_store_str(&s, signame, signame_len); channel->sendsignal_state = libssh2_NB_state_created; } if(channel->sendsignal_state == libssh2_NB_state_created) { int rc; rc = _libssh2_transport_send(session, channel->sendsignal_packet, channel->sendsignal_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, rc, "Would block sending signal request"); return rc; } else if(rc) { LIBSSH2_FREE(session, channel->sendsignal_packet); channel->sendsignal_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Unable to send signal packet"); } LIBSSH2_FREE(session, channel->sendsignal_packet); retcode = LIBSSH2_ERROR_NONE; } channel->sendsignal_state = libssh2_NB_state_idle; return retcode; } LIBSSH2_API int libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel, const char *signame, size_t signame_len) { int rc; if(!channel) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, channel->session, channel_signal(channel, signame, signame_len)); return rc; } libssh2-1.11.0/src/userauth_kbd_packet.h0000644000175000017500000000345014204645624015041 00000000000000/* Copyright (c) 2022, Xaver Loppenstedt * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifndef __LIBSSH2_USERAUTH_KBD_PARSE_H #define __LIBSSH2_USERAUTH_KBD_PARSE_H int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *); #endif /* __LIBSSH2_USERAUTH_KBD_PARSE_H */ libssh2-1.11.0/src/userauth.h0000644000175000017500000000423114424650606012670 00000000000000#ifndef __LIBSSH2_USERAUTH_H #define __LIBSSH2_USERAUTH_H /* Copyright (c) 2004-2007, Sara Golemon * Copyright (c) 2009-2010 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ int _libssh2_userauth_publickey(LIBSSH2_SESSION *session, const char *username, size_t username_len, const unsigned char *pubkeydata, size_t pubkeydata_len, LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC ((*sign_callback)), void *abstract); #endif /* __LIBSSH2_USERAUTH_H */ libssh2-1.11.0/src/misc.c0000644000175000017500000006077414432741311011765 00000000000000/* Copyright (c) 2004-2007 Sara Golemon * Copyright (c) 2009-2019 by Daniel Stenberg * Copyright (c) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include "misc.h" #ifdef HAVE_UNISTD_H #include #endif #include #include #ifdef WIN32 /* Force parameter type. */ #define recv(s, b, l, f) recv((s), (b), (int)(l), (f)) #define send(s, b, l, f) send((s), (b), (int)(l), (f)) #endif /* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible. We provide a safe wrapper if snprintf not found */ #ifdef LIBSSH2_SNPRINTF #include /* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1 * then assume cp is pointing to a null char and do nothing. Returns number * number of chars placed in cp excluding the trailing null char. So for * cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len * <= 0 the return value is 0 (and no chars are written to cp). */ int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...) { va_list args; int n; if(cp_max_len < 2) return 0; va_start(args, fmt); n = vsnprintf(cp, cp_max_len, fmt, args); va_end(args); return (n < (int)cp_max_len) ? n : (int)(cp_max_len - 1); } #endif int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char *errmsg, int errflags) { if(!session) { if(errmsg) fprintf(stderr, "Session is NULL, error: %s\n", errmsg); return errcode; } if(session->err_flags & LIBSSH2_ERR_FLAG_DUP) LIBSSH2_FREE(session, (char *)session->err_msg); session->err_code = errcode; session->err_flags = 0; if(errmsg && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) { size_t len = strlen(errmsg); char *copy = LIBSSH2_ALLOC(session, len + 1); if(copy) { memcpy(copy, errmsg, len + 1); session->err_flags = LIBSSH2_ERR_FLAG_DUP; session->err_msg = copy; } else /* Out of memory: this code path is very unlikely */ session->err_msg = "former error forgotten (OOM)"; } else session->err_msg = errmsg; #ifdef LIBSSH2DEBUG if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode) /* if this is EAGAIN and we're in non-blocking mode, don't generate a debug output for this */ return errcode; _libssh2_debug((session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code, session->err_msg)); #endif return errcode; } int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg) { return _libssh2_error_flags(session, errcode, errmsg, 0); } #ifdef WIN32 static int wsa2errno(void) { switch(WSAGetLastError()) { case WSAEWOULDBLOCK: return EAGAIN; case WSAENOTSOCK: return EBADF; case WSAEINTR: return EINTR; default: /* It is most important to ensure errno does not stay at EAGAIN * when a different error occurs so just set errno to a generic * error */ return EIO; } } #endif /* _libssh2_recv * * Replacement for the standard recv, return -errno on failure. */ ssize_t _libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract) { ssize_t rc; (void)abstract; rc = recv(sock, buffer, length, flags); #ifdef WIN32 if(rc < 0) return -wsa2errno(); #else if(rc < 0) { /* Sometimes the first recv() function call sets errno to ENOENT on Solaris and HP-UX */ if(errno == ENOENT) return -EAGAIN; #ifdef EWOULDBLOCK /* For VMS and other special unixes */ else if(errno == EWOULDBLOCK) return -EAGAIN; #endif else return -errno; } #endif return rc; } /* _libssh2_send * * Replacement for the standard send, return -errno on failure. */ ssize_t _libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length, int flags, void **abstract) { ssize_t rc; (void)abstract; rc = send(sock, buffer, length, flags); #ifdef WIN32 if(rc < 0) return -wsa2errno(); #else if(rc < 0) { #ifdef EWOULDBLOCK /* For VMS and other special unixes */ if(errno == EWOULDBLOCK) return -EAGAIN; #endif return -errno; } #endif return rc; } /* libssh2_ntohu32 */ uint32_t _libssh2_ntohu32(const unsigned char *buf) { return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]); } /* _libssh2_ntohu64 */ libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf) { return ((libssh2_uint64_t)buf[0] << 56) | ((libssh2_uint64_t)buf[1] << 48) | ((libssh2_uint64_t)buf[2] << 40) | ((libssh2_uint64_t)buf[3] << 32) | ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16) | ((libssh2_uint64_t)buf[6] << 8) | ((libssh2_uint64_t)buf[7]); } /* _libssh2_htonu32 */ void _libssh2_htonu32(unsigned char *buf, uint32_t value) { buf[0] = (unsigned char)((value >> 24) & 0xFF); buf[1] = (value >> 16) & 0xFF; buf[2] = (value >> 8) & 0xFF; buf[3] = value & 0xFF; } /* _libssh2_store_u32 */ void _libssh2_store_u32(unsigned char **buf, uint32_t value) { _libssh2_htonu32(*buf, value); *buf += sizeof(uint32_t); } /* _libssh2_store_str */ int _libssh2_store_str(unsigned char **buf, const char *str, size_t len) { uint32_t len_stored = (uint32_t)len; _libssh2_store_u32(buf, len_stored); if(len_stored) { memcpy(*buf, str, len_stored); *buf += len_stored; } assert(len_stored == len); return len_stored == len; } /* _libssh2_store_bignum2_bytes */ int _libssh2_store_bignum2_bytes(unsigned char **buf, const unsigned char *bytes, size_t len) { uint32_t len_stored; uint32_t extraByte; const unsigned char *p; for(p = bytes; len > 0 && *p == 0; --len, ++p) {} extraByte = (len > 0 && (p[0] & 0x80) != 0); len_stored = (uint32_t)len; if(extraByte && len_stored == 0xffffffff) len_stored--; _libssh2_store_u32(buf, len_stored + extraByte); if(extraByte) { *buf[0] = 0; *buf += 1; } if(len_stored) { memcpy(*buf, p, len_stored); *buf += len_stored; } assert(len_stored == len); return len_stored == len; } /* Base64 Conversion */ static const short base64_reverse_table[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; /* libssh2_base64_decode * * Legacy public function. DEPRECATED. */ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen, const char *src, unsigned int src_len) { int rc; size_t dlen; rc = _libssh2_base64_decode(session, data, &dlen, src, src_len); if(datalen) *datalen = (unsigned int)dlen; return rc; } /* _libssh2_base64_decode * * Decode a base64 chunk and store it into a newly alloc'd buffer */ int _libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, size_t *datalen, const char *src, size_t src_len) { unsigned char *d; const char *s; short v; ssize_t i = 0, len = 0; *data = LIBSSH2_ALLOC(session, ((src_len / 4) * 3) + 1); d = (unsigned char *) *data; if(!d) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for base64 decoding"); } for(s = src; s < (src + src_len); s++) { v = base64_reverse_table[(unsigned char)*s]; if(v < 0) continue; switch(i % 4) { case 0: d[len] = (unsigned char)(v << 2); break; case 1: d[len++] |= (unsigned char)(v >> 4); d[len] = (unsigned char)(v << 4); break; case 2: d[len++] |= (unsigned char)(v >> 2); d[len] = (unsigned char)(v << 6); break; case 3: d[len++] |= (unsigned char)v; break; } i++; } if((i % 4) == 1) { /* Invalid -- We have a byte which belongs exclusively to a partial octet */ LIBSSH2_FREE(session, *data); *data = NULL; return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64"); } *datalen = len; return 0; } /* ---- Base64 Encoding/Decoding Table --- */ static const char table64[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* * _libssh2_base64_encode * * Returns the length of the newly created base64 string. The third argument * is a pointer to an allocated area holding the base64 data. If something * went wrong, 0 is returned. * */ size_t _libssh2_base64_encode(LIBSSH2_SESSION *session, const char *inp, size_t insize, char **outptr) { unsigned char ibuf[3]; unsigned char obuf[4]; int i; int inputparts; char *output; char *base64data; const char *indata = inp; *outptr = NULL; /* set to NULL in case of failure before we reach the end */ if(insize == 0) insize = strlen(indata); base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4); if(!output) return 0; while(insize > 0) { for(i = inputparts = 0; i < 3; i++) { if(insize > 0) { inputparts++; ibuf[i] = *indata; indata++; insize--; } else ibuf[i] = 0; } obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ ((ibuf[1] & 0xF0) >> 4)); obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ ((ibuf[2] & 0xC0) >> 6)); obuf[3] = (unsigned char) (ibuf[2] & 0x3F); switch(inputparts) { case 1: /* only one byte read */ output[0] = table64[obuf[0]]; output[1] = table64[obuf[1]]; output[2] = '='; output[3] = '='; break; case 2: /* two bytes read */ output[0] = table64[obuf[0]]; output[1] = table64[obuf[1]]; output[2] = table64[obuf[2]]; output[3] = '='; break; default: output[0] = table64[obuf[0]]; output[1] = table64[obuf[1]]; output[2] = table64[obuf[2]]; output[3] = table64[obuf[3]]; break; } output += 4; } *output = 0; *outptr = base64data; /* make it return the actual data memory */ return strlen(base64data); /* return the length of the new data */ } /* ---- End of Base64 Encoding ---- */ LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr) { LIBSSH2_FREE(session, ptr); } #ifdef LIBSSH2DEBUG #include LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION * session, int bitmask) { session->showmask = bitmask; return 0; } LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context, libssh2_trace_handler_func callback) { session->tracehandler = callback; session->tracehandler_context = handler_context; return 0; } void _libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format, ...) { char buffer[1536]; int len, msglen, buflen = sizeof(buffer); va_list vargs; struct timeval now; static long firstsec; static const char *const contexts[] = { "Unknown", "Transport", "Key Ex", "Userauth", "Conn", "SCP", "SFTP", "Failure Event", "Publickey", "Socket", }; const char *contexttext = contexts[0]; unsigned int contextindex; if(!(session->showmask & context)) { /* no such output asked for */ return; } /* Find the first matching context string for this message */ for(contextindex = 0; contextindex < ARRAY_SIZE(contexts); contextindex++) { if((context & (1 << contextindex)) != 0) { contexttext = contexts[contextindex]; break; } } gettimeofday(&now, NULL); if(!firstsec) { firstsec = now.tv_sec; } now.tv_sec -= firstsec; len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ", (int)now.tv_sec, (int)now.tv_usec, contexttext); if(len >= buflen) msglen = buflen - 1; else { buflen -= len; msglen = len; va_start(vargs, format); len = vsnprintf(buffer + msglen, buflen, format, vargs); va_end(vargs); msglen += len < buflen ? len : buflen - 1; } if(session->tracehandler) (session->tracehandler)(session, session->tracehandler_context, buffer, msglen); else fprintf(stderr, "%s\n", buffer); } #else LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION * session, int bitmask) { (void)session; (void)bitmask; return 0; } LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context, libssh2_trace_handler_func callback) { (void)session; (void)handler_context; (void)callback; return 0; } #endif /* init the list head */ void _libssh2_list_init(struct list_head *head) { head->first = head->last = NULL; } /* add a node to the list */ void _libssh2_list_add(struct list_head *head, struct list_node *entry) { /* store a pointer to the head */ entry->head = head; /* we add this entry at the "top" so it has no next */ entry->next = NULL; /* make our prev point to what the head thinks is last */ entry->prev = head->last; /* and make head's last be us now */ head->last = entry; /* make sure our 'prev' node points to us next */ if(entry->prev) entry->prev->next = entry; else head->first = entry; } /* return the "first" node in the list this head points to */ void *_libssh2_list_first(struct list_head *head) { return head->first; } /* return the next node in the list */ void *_libssh2_list_next(struct list_node *node) { return node->next; } /* return the prev node in the list */ void *_libssh2_list_prev(struct list_node *node) { return node->prev; } /* remove this node from the list */ void _libssh2_list_remove(struct list_node *entry) { if(entry->prev) entry->prev->next = entry->next; else entry->head->first = entry->next; if(entry->next) entry->next->prev = entry->prev; else entry->head->last = entry->prev; } #if 0 /* insert a node before the given 'after' entry */ void _libssh2_list_insert(struct list_node *after, /* insert before this */ struct list_node *entry) { /* 'after' is next to 'entry' */ bentry->next = after; /* entry's prev is then made to be the prev after current has */ entry->prev = after->prev; /* the node that is now before 'entry' was previously before 'after' and must be made to point to 'entry' correctly */ if(entry->prev) entry->prev->next = entry; else /* there was no node before this, so we make sure we point the head pointer to this node */ after->head->first = entry; /* after's prev entry points back to entry */ after->prev = entry; /* after's next entry is still the same as before */ /* entry's head is the same as after's */ entry->head = after->head; } #endif /* Defined in libssh2_priv.h for the correct platforms */ #ifdef LIBSSH2_GETTIMEOFDAY /* * _libssh2_gettimeofday * Implementation according to: * The Open Group Base Specifications Issue 6 * IEEE Std 1003.1, 2004 Edition */ /* * THIS SOFTWARE IS NOT COPYRIGHTED * * This source code is offered for use in the public domain. You may * use, modify or distribute it freely. * * This code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Contributed by: * Danny Smith */ int _libssh2_gettimeofday(struct timeval *tp, void *tzp) { (void)tzp; if(tp) { #ifdef WIN32 /* Offset between 1601-01-01 and 1970-01-01 in 100 nanosec units */ #define _WIN32_FT_OFFSET (116444736000000000) union { libssh2_uint64_t ns100; /* time since 1 Jan 1601 in 100ns units */ FILETIME ft; } _now; GetSystemTimeAsFileTime(&_now.ft); tp->tv_usec = (long)((_now.ns100 / 10) % 1000000); tp->tv_sec = (long)((_now.ns100 - _WIN32_FT_OFFSET) / 10000000); #else /* Platforms without a native implementation or local replacement */ tp->tv_usec = 0; tp->tv_sec = 0; #endif } /* Always return 0 as per Open Group Base Specifications Issue 6. Do not set errno on error. */ return 0; } #endif void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size) { void *p = LIBSSH2_ALLOC(session, size); if(p) { memset(p, 0, size); } return p; } /* XOR operation on buffers input1 and input2, result in output. It is safe to use an input buffer as the output buffer. */ void _libssh2_xor_data(unsigned char *output, const unsigned char *input1, const unsigned char *input2, size_t length) { size_t i; for(i = 0; i < length; i++) *output++ = *input1++ ^ *input2++; } /* Increments an AES CTR buffer to prepare it for use with the next AES block. */ void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length) { unsigned char *pc; unsigned int val, carry; pc = ctr + length - 1; carry = 1; while(pc >= ctr) { val = (unsigned int)*pc + carry; *pc-- = val & 0xFF; carry = val >> 8; } } #ifdef LIBSSH2_MEMZERO static void * (* const volatile memset_libssh)(void *, int, size_t) = memset; void _libssh2_memzero(void *buf, size_t size) { memset_libssh(buf, 0, size); } #endif /* String buffer */ struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session) { struct string_buf *ret; ret = _libssh2_calloc(session, sizeof(*ret)); if(!ret) return NULL; return ret; } void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf) { if(!buf) return; if(buf->data) LIBSSH2_FREE(session, buf->data); LIBSSH2_FREE(session, buf); buf = NULL; } int _libssh2_get_byte(struct string_buf *buf, unsigned char *out) { if(!_libssh2_check_length(buf, 1)) { return -1; } *out = buf->dataptr[0]; buf->dataptr += 1; return 0; } int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out) { if(!_libssh2_check_length(buf, 1)) { return -1; } *out = buf->dataptr[0] == 0 ? 0 : 1; buf->dataptr += 1; return 0; } int _libssh2_get_u32(struct string_buf *buf, uint32_t *out) { if(!_libssh2_check_length(buf, 4)) { return -1; } *out = _libssh2_ntohu32(buf->dataptr); buf->dataptr += 4; return 0; } int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out) { if(!_libssh2_check_length(buf, 8)) { return -1; } *out = _libssh2_ntohu64(buf->dataptr); buf->dataptr += 8; return 0; } int _libssh2_match_string(struct string_buf *buf, const char *match) { unsigned char *out; size_t len = 0; if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) || strncmp((char *)out, match, strlen(match)) != 0) { return -1; } return 0; } int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf, size_t *outlen) { uint32_t data_len; if(!buf || _libssh2_get_u32(buf, &data_len) != 0) { return -1; } if(!_libssh2_check_length(buf, data_len)) { return -1; } *outbuf = buf->dataptr; buf->dataptr += data_len; if(outlen) *outlen = (size_t)data_len; return 0; } int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf, unsigned char **outbuf, size_t *outlen) { size_t str_len; unsigned char *str; if(_libssh2_get_string(buf, &str, &str_len)) { return -1; } if(str_len) { *outbuf = LIBSSH2_ALLOC(session, str_len); if(*outbuf) { memcpy(*outbuf, str, str_len); } else { return -1; } } else { *outlen = 0; *outbuf = NULL; } if(outlen) *outlen = str_len; return 0; } int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf, size_t *outlen) { uint32_t data_len; uint32_t bn_len; unsigned char *bnptr; if(_libssh2_get_u32(buf, &data_len)) { return -1; } if(!_libssh2_check_length(buf, data_len)) { return -1; } bn_len = data_len; bnptr = buf->dataptr; /* trim leading zeros */ while(bn_len > 0 && *bnptr == 0x00) { bn_len--; bnptr++; } *outbuf = bnptr; buf->dataptr += data_len; if(outlen) *outlen = (size_t)bn_len; return 0; } /* Given the current location in buf, _libssh2_check_length ensures callers can read the next len number of bytes out of the buffer before reading the buffer content */ int _libssh2_check_length(struct string_buf *buf, size_t len) { unsigned char *endp = &buf->data[buf->len]; size_t left = endp - buf->dataptr; return (len <= left) && (left <= buf->len); } int _libssh2_eob(struct string_buf *buf) { unsigned char *endp = &buf->data[buf->len]; return buf->dataptr >= endp; } libssh2-1.11.0/src/global.c0000644000175000017500000000452714424650606012273 00000000000000/* Copyright (c) 2010 Lars Nordin * Copyright (C) 2010 Simon Josefsson * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" static int _libssh2_initialized = 0; static int _libssh2_init_flags = 0; LIBSSH2_API int libssh2_init(int flags) { if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) { libssh2_crypto_init(); } _libssh2_initialized++; _libssh2_init_flags |= flags; return 0; } LIBSSH2_API void libssh2_exit(void) { if(_libssh2_initialized == 0) return; _libssh2_initialized--; if(_libssh2_initialized == 0 && !(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) { libssh2_crypto_exit(); } return; } void _libssh2_init_if_needed(void) { if(_libssh2_initialized == 0) (void)libssh2_init(0); } libssh2-1.11.0/src/os400qc3.h0000644000175000017500000004674214424650606012321 00000000000000#ifndef __LIBSSH2_OS400QC3_H #define __LIBSSH2_OS400QC3_H /* * Copyright (C) 2015-2016 Patrick Monnerat, D+H * Copyright (C) 2020-2023 Patrick Monnerat . * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #define LIBSSH2_CRYPTO_ENGINE libssh2_os400qc3 #include #include #include /* Redefine character/string literals as always EBCDIC. */ #undef Qc3_Alg_Token #define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */ #undef Qc3_Alg_Block_Cipher #define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */ #undef Qc3_Alg_Block_CipherAuth #define Qc3_Alg_Block_CipherAuth \ "\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */ #undef Qc3_Alg_Stream_Cipher #define Qc3_Alg_Stream_Cipher \ "\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */ #undef Qc3_Alg_Public_Key #define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */ #undef Qc3_Alg_Hash #define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */ #undef Qc3_Data #define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */ #undef Qc3_Array #define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */ #undef Qc3_Key_Token #define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */ #undef Qc3_Key_Parms #define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */ #undef Qc3_Key_KSLabel #define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */ #undef Qc3_Key_PKCS5 #define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */ #undef Qc3_Key_PEMCert #define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */ #undef Qc3_Key_CSLabel #define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */ #undef Qc3_Key_CSDN #define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */ #undef Qc3_Key_AppID #define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */ #undef Qc3_ECB #define Qc3_ECB '\xF0' /* '0' */ #undef Qc3_CBC #define Qc3_CBC '\xF1' /* '1' */ #undef Qc3_OFB #define Qc3_OFB '\xF2' /* '2' */ #undef Qc3_CFB1Bit #define Qc3_CFB1Bit '\xF3' /* '3' */ #undef Qc3_CFB8Bit #define Qc3_CFB8Bit '\xF4' /* '4' */ #undef Qc3_CFB64Bit #define Qc3_CFB64Bit '\xF5' /* '5' */ #undef Qc3_CUSP #define Qc3_CUSP '\xF6' /* '6' */ #undef Qc3_CTR #define Qc3_CTR '\xF7' /* '7' */ #undef Qc3_CCM #define Qc3_CCM '\xF8' /* '8' */ #undef Qc3_No_Pad #define Qc3_No_Pad '\xF0' /* '0' */ #undef Qc3_Pad_Char #define Qc3_Pad_Char '\xF1' /* '1' */ #undef Qc3_Pad_Counter #define Qc3_Pad_Counter '\xF2' /* '2' */ #undef Qc3_PKCS1_00 #define Qc3_PKCS1_00 '\xF0' /* '0' */ #undef Qc3_PKCS1_01 #define Qc3_PKCS1_01 '\xF1' /* '1' */ #undef Qc3_PKCS1_02 #define Qc3_PKCS1_02 '\xF2' /* '2' */ #undef Qc3_ISO9796 #define Qc3_ISO9796 '\xF3' /* '3' */ #undef Qc3_Zero_Pad #define Qc3_Zero_Pad '\xF4' /* '4' */ #undef Qc3_ANSI_X931 #define Qc3_ANSI_X931 '\xF5' /* '5' */ #undef Qc3_OAEP #define Qc3_OAEP '\xF6' /* '6' */ #undef Qc3_Bin_String #define Qc3_Bin_String '\xF0' /* '0' */ #undef Qc3_BER_String #define Qc3_BER_String '\xF1' /* '1' */ #undef Qc3_MK_Struct #define Qc3_MK_Struct '\xF3' /* '3' */ #undef Qc3_KSLabel_Struct #define Qc3_KSLabel_Struct '\xF4' /* '4' */ #undef Qc3_PKCS5_Struct #define Qc3_PKCS5_Struct '\xF5' /* '5' */ #undef Qc3_PEMCert_String #define Qc3_PEMCert_String '\xF6' /* '6' */ #undef Qc3_CSLabel_String #define Qc3_CSLabel_String '\xF7' /* '7' */ #undef Qc3_CSDN_String #define Qc3_CSDN_String '\xF8' /* '8' */ #undef Qc3_Clear #define Qc3_Clear '\xF0' /* '0' */ #undef Qc3_Encrypted #define Qc3_Encrypted '\xF1' /* '1' */ #undef Qc3_MK_Encrypted #define Qc3_MK_Encrypted '\xF2' /* '2' */ #undef Qc3_Any_CSP #define Qc3_Any_CSP '\xF0' /* '0' */ #undef Qc3_Sfw_CSP #define Qc3_Sfw_CSP '\xF1' /* '1' */ #undef Qc3_Hdw_CSP #define Qc3_Hdw_CSP '\xF2' /* '2' */ #undef Qc3_Continue #define Qc3_Continue '\xF0' /* '0' */ #undef Qc3_Final #define Qc3_Final '\xF1' /* '1' */ #undef Qc3_MK_New #define Qc3_MK_New '\xF0' /* '0' */ #undef Qc3_MK_Current #define Qc3_MK_Current '\xF1' /* '1' */ #undef Qc3_MK_Old #define Qc3_MK_Old '\xF2' /* '2' */ #undef Qc3_MK_Pending #define Qc3_MK_Pending '\xF3' /* '3' */ /* Define which features are supported. */ #define LIBSSH2_MD5 1 #define LIBSSH2_HMAC_RIPEMD 0 #define LIBSSH2_HMAC_SHA256 1 #define LIBSSH2_HMAC_SHA512 1 #define LIBSSH2_AES_CBC 1 #define LIBSSH2_AES_CTR 1 #define LIBSSH2_AES_GCM 0 #define LIBSSH2_BLOWFISH 0 #define LIBSSH2_RC4 1 #define LIBSSH2_CAST 0 #define LIBSSH2_3DES 1 #define LIBSSH2_RSA 1 #define LIBSSH2_RSA_SHA1 1 #define LIBSSH2_RSA_SHA2 1 #define LIBSSH2_DSA 0 #define LIBSSH2_ECDSA 0 #define LIBSSH2_ED25519 0 #define MD5_DIGEST_LENGTH 16 #define SHA_DIGEST_LENGTH 20 #define SHA256_DIGEST_LENGTH 32 #define SHA384_DIGEST_LENGTH 48 #define SHA512_DIGEST_LENGTH 64 #define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) #if LIBSSH2_ECDSA #else #define _libssh2_ec_key void #endif /******************************************************************* * * OS/400 QC3 crypto-library backend: global handles structures. * *******************************************************************/ /* HMAC & private key algorithms support structure. */ typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx; struct _libssh2_os400qc3_crypto_ctx { Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */ Qc3_Format_KEYD0100_T key; /* Key. */ _libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */ }; typedef struct { /* Big number. */ unsigned char * bignum; /* Number bits, little-endian. */ unsigned int length; /* Length of bignum (# bytes). */ } _libssh2_bn; typedef struct { /* Algorithm description. */ char * fmt; /* Format of Qc3 structure. */ int algo; /* Algorithm identifier. */ unsigned char size; /* Block length. */ unsigned char mode; /* Block mode. */ int keylen; /* Key length. */ } _libssh2_os400qc3_cipher_t; typedef struct { /* Diffie-Hellman context. */ char token[8]; /* Context token. */ } _libssh2_os400qc3_dh_ctx; /******************************************************************* * * OS/400 QC3 crypto-library backend: Define global types/codes. * *******************************************************************/ #define libssh2_crypto_init() #define libssh2_crypto_exit() #define libssh2_sha1_ctx Qc3_Format_ALGD0100_T #define libssh2_sha256_ctx Qc3_Format_ALGD0100_T #define libssh2_sha384_ctx Qc3_Format_ALGD0100_T #define libssh2_sha512_ctx Qc3_Format_ALGD0100_T #define libssh2_md5_ctx Qc3_Format_ALGD0100_T #define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx #define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx #define libssh2_sha1_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA1) #define libssh2_sha1_update(ctx, data, len) \ libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha1_final(ctx, out) \ libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha256_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA256) #define libssh2_sha256_update(ctx, data, len) \ libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha256_final(ctx, out) \ libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha256(message, len, out) \ libssh2_os400qc3_hash(message, len, out, \ Qc3_SHA256) #define libssh2_sha384_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA384) #define libssh2_sha384_update(ctx, data, len) \ libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha384_final(ctx, out) \ libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha384(message, len, out) \ libssh2_os400qc3_hash(message, len, out, \ Qc3_SHA384) #define libssh2_sha512_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA512) #define libssh2_sha512_update(ctx, data, len) \ libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha512_final(ctx, out) \ libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha512(message, len, out) \ libssh2_os400qc3_hash(message, len, out, \ Qc3_SHA512) #define libssh2_md5_init(x) libssh2_os400qc3_hash_init(x, Qc3_MD5) #define libssh2_md5_update(ctx, data, len) \ libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_md5_final(ctx, out) \ libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_hmac_ctx_init(ctx) \ memset((char *) &(ctx), 0, \ sizeof(libssh2_hmac_ctx)) #define libssh2_hmac_md5_init(ctx, key, keylen) \ libssh2_os400qc3_hmac_init(ctx, Qc3_MD5, \ MD5_DIGEST_LENGTH, \ key, keylen) #define libssh2_hmac_sha1_init(ctx, key, keylen) \ libssh2_os400qc3_hmac_init(ctx, Qc3_SHA1, \ SHA_DIGEST_LENGTH, \ key, keylen) #define libssh2_hmac_sha256_init(ctx, key, keylen) \ libssh2_os400qc3_hmac_init(ctx, Qc3_SHA256, \ SHA256_DIGEST_LENGTH, \ key, keylen) #define libssh2_hmac_sha512_init(ctx, key, keylen) \ libssh2_os400qc3_hmac_init(ctx, Qc3_SHA512, \ SHA512_DIGEST_LENGTH, \ key, keylen) #define libssh2_hmac_update(ctx, data, datalen) \ libssh2_os400qc3_hmac_update(&(ctx), \ data, datalen) #define libssh2_hmac_final(ctx, data) \ libssh2_os400qc3_hmac_final(&(ctx), data) #define libssh2_hmac_cleanup(ctx) \ _libssh2_os400qc3_crypto_dtor(ctx) #define _libssh2_bn_ctx int /* Not used. */ #define _libssh2_bn_ctx_new() 0 #define _libssh2_bn_ctx_free(bnctx) ((void) 0) #define _libssh2_bn_init_from_bin() _libssh2_bn_init() #define _libssh2_bn_bytes(bn) ((bn)->length) #define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name #define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ Qc3_CBC, 16} #define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ Qc3_CBC, 24} #define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ Qc3_CBC, 32} #define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ Qc3_CTR, 16} #define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ Qc3_CTR, 24} #define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ Qc3_CTR, 32} #define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 8, \ Qc3_CBC, 24} #define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16} #define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx) #define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx #define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \ free((char *) ctx)) #define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \ (len) * sizeof(struct iovec)) #define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \ _libssh2_os400qc3_rsa_signv(session, Qc3_SHA1, sig, siglen, \ count, vector, ctx) #define _libssh2_rsa_sha2_256_signv(session, sig, siglen, cnt, vector, ctx) \ _libssh2_os400qc3_rsa_signv(session, Qc3_SHA256, sig, siglen, \ cnt, vector, ctx) #define _libssh2_rsa_sha2_512_signv(session, sig, siglen, cnt, vector, ctx) \ _libssh2_os400qc3_rsa_signv(session, Qc3_SHA512, sig, siglen, \ cnt, vector, ctx) /* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 Qc3 is limited to a maximum 2048-bit modulus/key size. */ #define LIBSSH2_DH_GEX_MINGROUP 1024 #define LIBSSH2_DH_GEX_OPTGROUP 1536 #define LIBSSH2_DH_GEX_MAXGROUP 2048 #define LIBSSH2_DH_MAX_MODULUS_BITS 2048 #define _libssh2_dh_ctx _libssh2_os400qc3_dh_ctx #define libssh2_dh_init(dhctx) _libssh2_os400qc3_dh_init(dhctx) #define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ _libssh2_os400qc3_dh_key_pair(dhctx, public, g, p, group_order) #define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ _libssh2_os400qc3_dh_secret(dhctx, secret, f, p) #define libssh2_dh_dtor(dhctx) _libssh2_os400qc3_dh_dtor(dhctx) /******************************************************************* * * OS/400 QC3 crypto-library backend: Support procedure prototypes. * *******************************************************************/ extern _libssh2_bn * _libssh2_bn_init(void); extern void _libssh2_bn_free(_libssh2_bn *bn); extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn); extern int _libssh2_bn_from_bin(_libssh2_bn *bn, int len, const unsigned char *v); extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val); extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val); extern int _libssh2_random(unsigned char *buf, size_t len); extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x); extern int libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algo); extern void libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, const unsigned char *data, int len); extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, unsigned char *out); extern int libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, unsigned char *out, unsigned int algo); extern void libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *x, int algo, size_t minkeylen, void *key, int keylen); extern void libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, const unsigned char *data, int len); extern void libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, unsigned char *out); extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo, unsigned char **signature, size_t *signature_len, int veccount, const struct iovec vector[], libssh2_rsa_ctx *ctx); extern void _libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx); extern int _libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order); extern int _libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p); extern void _libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx); #endif /* __LIBSSH2_OS400QC3_H */ /* vim: set expandtab ts=4 sw=4: */ libssh2-1.11.0/src/packet.h0000644000175000017500000000666213665456506012322 00000000000000#ifndef __LIBSSH2_PACKET_H #define __LIBSSH2_PACKET_H /* * Copyright (C) 2010 by Daniel Stenberg * Author: Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ int _libssh2_packet_read(LIBSSH2_SESSION * session); int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len); int _libssh2_packet_askv(LIBSSH2_SESSION * session, const unsigned char *packet_types, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len); int _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len, packet_require_state_t * state); int _libssh2_packet_requirev(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, size_t *data_len, int match_ofs, const unsigned char *match_buf, size_t match_len, packet_requirev_state_t * state); int _libssh2_packet_burn(LIBSSH2_SESSION * session, libssh2_nonblocking_states * state); int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data, unsigned long data_len); int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, size_t datalen, int macstate); #endif /* __LIBSSH2_PACKET_H */ libssh2-1.11.0/src/blowfish.c0000644000175000017500000007507114424650606012652 00000000000000/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */ /* * Blowfish for OpenBSD - a fast block cipher designed by Bruce Schneier * * Copyright 1997 Niels Provos * All rights reserved. * * Implementation advice by David Mazieres . * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This code is derived from section 14.3 and the given source * in section V of Applied Cryptography, second edition. * Blowfish is an unpatented fast block cipher designed by * Bruce Schneier. */ #if defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH) #if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ !defined(HAVE_BLOWFISH_EXPAND0STATE) || \ !defined(HAVE_BLF_ENC)) #ifdef _DEBUG_BLOWFISH #include #include #include #endif /* Schneier specifies a maximum key length of 56 bytes. * This ensures that every key bit affects every cipher * bit. However, the subkeys can hold up to 72 bytes. * Warning: For normal blowfish encryption only 56 bytes * of the key affect all cipherbits. */ #define BLF_N 16 /* Number of Subkeys */ #define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ #define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */ /* Blowfish context */ typedef struct BlowfishContext { uint32_t S[4][256]; /* S-Boxes */ uint32_t P[BLF_N + 2]; /* Subkeys */ } blf_ctx; /* Raw access to customized Blowfish * blf_key is just: * Blowfish_initstate( state ) * Blowfish_expand0state( state, key, keylen ) */ static void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *); #ifdef _DEBUG_BLOWFISH static void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *); #endif static void Blowfish_initstate(blf_ctx *); static void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t); static void Blowfish_expandstate (blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t); /* Standard Blowfish */ #ifdef _DEBUG_BLOWFISH static void blf_key(blf_ctx *, const uint8_t *, uint16_t); #endif static void blf_enc(blf_ctx *, uint32_t *, uint16_t); #ifdef _DEBUG_BLOWFISH static void blf_dec(blf_ctx *, uint32_t *, uint16_t); #endif #if 0 static void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t); static void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t); static void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t); static void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t); #endif /* Converts uint8_t to uint32_t */ static uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *); /* Function for Feistel Networks */ #define F(s, x) ((((s)[ (((x) >> 24) & 0xFF)] \ + (s)[0x100 + (((x) >> 16) & 0xFF)]) \ ^ (s)[0x200 + (((x) >> 8) & 0xFF)]) \ + (s)[0x300 + ( (x) & 0xFF)]) #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) static void Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr) { uint32_t Xl; uint32_t Xr; uint32_t *s = c->S[0]; uint32_t *p = c->P; Xl = *xl; Xr = *xr; Xl ^= p[0]; BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); *xl = Xr ^ p[17]; *xr = Xl; } #ifdef _DEBUG_BLOWFISH static void Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr) { uint32_t Xl; uint32_t Xr; uint32_t *s = c->S[0]; uint32_t *p = c->P; Xl = *xl; Xr = *xr; Xl ^= p[17]; BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); *xl = Xr ^ p[0]; *xr = Xl; } #endif static void Blowfish_initstate(blf_ctx *c) { /* P-box and S-box tables initialized with digits of Pi */ static const blf_ctx initstate = { { { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, { 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, { 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, { 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} }, { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b } }; *c = initstate; } static uint32_t Blowfish_stream2word(const uint8_t *data, uint16_t databytes, uint16_t *current) { uint8_t i; uint16_t j; uint32_t temp; temp = 0x00000000; j = *current; for(i = 0; i < 4; i++, j++) { if(j >= databytes) j = 0; temp = (temp << 8) | data[j]; } *current = j; return temp; } static void Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes) { int i; int k; uint16_t j; uint32_t temp; uint32_t datal; uint32_t datar; j = 0; for(i = 0; i < BLF_N + 2; i++) { /* Extract 4 int8 to 1 int32 from keystream */ temp = Blowfish_stream2word(key, keybytes, &j); c->P[i] = c->P[i] ^ temp; } j = 0; datal = 0x00000000; datar = 0x00000000; for(i = 0; i < BLF_N + 2; i += 2) { Blowfish_encipher(c, &datal, &datar); c->P[i] = datal; c->P[i + 1] = datar; } for(i = 0; i < 4; i++) { for(k = 0; k < 256; k += 2) { Blowfish_encipher(c, &datal, &datar); c->S[i][k] = datal; c->S[i][k + 1] = datar; } } } static void Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes, const uint8_t *key, uint16_t keybytes) { int i; int k; uint16_t j; uint32_t temp; uint32_t datal; uint32_t datar; j = 0; for(i = 0; i < BLF_N + 2; i++) { /* Extract 4 int8 to 1 int32 from keystream */ temp = Blowfish_stream2word(key, keybytes, &j); c->P[i] = c->P[i] ^ temp; } j = 0; datal = 0x00000000; datar = 0x00000000; for(i = 0; i < BLF_N + 2; i += 2) { datal ^= Blowfish_stream2word(data, databytes, &j); datar ^= Blowfish_stream2word(data, databytes, &j); Blowfish_encipher(c, &datal, &datar); c->P[i] = datal; c->P[i + 1] = datar; } for(i = 0; i < 4; i++) { for(k = 0; k < 256; k += 2) { datal ^= Blowfish_stream2word(data, databytes, &j); datar ^= Blowfish_stream2word(data, databytes, &j); Blowfish_encipher(c, &datal, &datar); c->S[i][k] = datal; c->S[i][k + 1] = datar; } } } #ifdef _DEBUG_BLOWFISH static void blf_key(blf_ctx *c, const uint8_t *k, uint16_t len) { /* Initialize S-boxes and subkeys with Pi */ Blowfish_initstate(c); /* Transform S-boxes and subkeys with key */ Blowfish_expand0state(c, k, len); } #endif static void blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks) { uint32_t *d; uint16_t i; d = data; for(i = 0; i < blocks; i++) { Blowfish_encipher(c, d, d + 1); d += 2; } } #ifdef _DEBUG_BLOWFISH static void blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks) { uint32_t *d; uint16_t i; d = data; for(i = 0; i < blocks; i++) { Blowfish_decipher(c, d, d + 1); d += 2; } } #endif #if 0 static void blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len) { uint32_t l, r; uint32_t i; for(i = 0; i < len; i += 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_encipher(c, &l, &r); data[0] = (uint8_t)(l >> 24 & 0xff); data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = (uint8_t)(r >> 24 & 0xff); data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; data += 8; } } static void blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len) { uint32_t l, r; uint32_t i; for(i = 0; i < len; i += 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_decipher(c, &l, &r); data[0] = (uint8_t)(l >> 24 & 0xff); data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = (uint8_t)(r >> 24 & 0xff); data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; data += 8; } } static void blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len) { uint32_t l, r; uint32_t i, j; for(i = 0; i < len; i += 8) { for(j = 0; j < 8; j++) data[j] ^= iv[j]; l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_encipher(c, &l, &r); data[0] = (uint8_t)(l >> 24 & 0xff); data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = (uint8_t)(r >> 24 & 0xff); data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; iv = data; data += 8; } } static void blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len) { uint32_t l, r; uint8_t *iv; uint32_t i, j; iv = data + len - 16; data = data + len - 8; for(i = len - 8; i >= 8; i -= 8) { l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_decipher(c, &l, &r); data[0] = (uint8_t)(l >> 24 & 0xff); data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = (uint8_t)(r >> 24 & 0xff); data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; for(j = 0; j < 8; j++) data[j] ^= iv[j]; iv -= 8; data -= 8; } l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; Blowfish_decipher(c, &l, &r); data[0] = (uint8_t)(l >> 24 & 0xff); data[1] = l >> 16 & 0xff; data[2] = l >> 8 & 0xff; data[3] = l & 0xff; data[4] = (uint8_t)(r >> 24 & 0xff); data[5] = r >> 16 & 0xff; data[6] = r >> 8 & 0xff; data[7] = r & 0xff; for(j = 0; j < 8; j++) data[j] ^= iva[j]; } #endif #ifdef _DEBUG_BLOWFISH static void report(uint32_t data[], uint16_t len) { int i; for(i = 0; i < len; i += 2) printf("Block %d: 0x%08lx 0x%08lx.\n", i / 2, (unsigned long)data[i], (unsigned long)data[i + 1]); } int main(void) { blf_ctx c; char key[] = "AAAAA"; char key2[] = "abcdefghijklmnopqrstuvwxyz"; uint32_t data[10]; uint32_t data2[] = {0x424c4f57l, 0x46495348l}; uint16_t i; /* First test */ for(i = 0; i < 10; i++) data[i] = i; blf_key(&c, (uint8_t *) key, 5); blf_enc(&c, data, 5); blf_dec(&c, data, 1); blf_dec(&c, data + 2, 4); printf("Should read as 0 - 9.\n"); report(data, 10); /* Second test */ blf_key(&c, (uint8_t *) key2, (uint16_t)strlen(key2)); blf_enc(&c, data2, 1); printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); report(data2, 2); blf_dec(&c, data2, 1); printf("\nShould read as: 0x424c4f57 0x46495348.\n"); report(data2, 2); return 0; } #endif #endif /* !defined(HAVE_BCRYPT_PBKDF) && \ (!defined(HAVE_BLOWFISH_INITSTATE) || \ !defined(HAVE_BLOWFISH_EXPAND0STATE) || \ '!defined(HAVE_BLF_ENC)) */ #endif /* defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH) */ libssh2-1.11.0/src/comp.h0000644000175000017500000000336413665456506012005 00000000000000#ifndef __LIBSSH2_COMP_H #define __LIBSSH2_COMP_H /* Copyright (C) 2009-2010 by Daniel Stenberg * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ #include "libssh2_priv.h" const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session); #endif /* __LIBSSH2_COMP_H */ libssh2-1.11.0/src/misc.h0000644000175000017500000001306614432741311011762 00000000000000#ifndef __LIBSSH2_MISC_H #define __LIBSSH2_MISC_H /* Copyright (c) 2009-2019 by Daniel Stenberg * * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef LIBSSH2_NO_CLEAR_MEMORY #define _libssh2_explicit_zero(buf, size) do { \ (void)(buf); \ (void)(size); \ } while(0) #else #ifdef WIN32 #define _libssh2_explicit_zero(buf, size) SecureZeroMemory(buf, size) #elif defined(HAVE_EXPLICIT_BZERO) #define _libssh2_explicit_zero(buf, size) explicit_bzero(buf, size) #elif defined(HAVE_EXPLICIT_MEMSET) #define _libssh2_explicit_zero(buf, size) (void)explicit_memset(buf, 0, size) #elif defined(HAVE_MEMSET_S) #define _libssh2_explicit_zero(buf, size) (void)memset_s(buf, size, 0, size) #else #define LIBSSH2_MEMZERO void _libssh2_memzero(void *buf, size_t size); #define _libssh2_explicit_zero(buf, size) _libssh2_memzero(buf, size) #endif #endif struct list_head { struct list_node *last; struct list_node *first; }; struct list_node { struct list_node *next; struct list_node *prev; struct list_head *head; }; struct string_buf { unsigned char *data; unsigned char *dataptr; size_t len; }; int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char *errmsg, int errflags); int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg); void _libssh2_list_init(struct list_head *head); /* add a node last in the list */ void _libssh2_list_add(struct list_head *head, struct list_node *entry); /* return the "first" node in the list this head points to */ void *_libssh2_list_first(struct list_head *head); /* return the next node in the list */ void *_libssh2_list_next(struct list_node *node); /* return the prev node in the list */ void *_libssh2_list_prev(struct list_node *node); /* remove this node from the list */ void _libssh2_list_remove(struct list_node *entry); int _libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, size_t *datalen, const char *src, size_t src_len); size_t _libssh2_base64_encode(LIBSSH2_SESSION *session, const char *inp, size_t insize, char **outptr); uint32_t _libssh2_ntohu32(const unsigned char *buf); libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf); void _libssh2_htonu32(unsigned char *buf, uint32_t val); void _libssh2_store_u32(unsigned char **buf, uint32_t value); int _libssh2_store_str(unsigned char **buf, const char *str, size_t len); int _libssh2_store_bignum2_bytes(unsigned char **buf, const unsigned char *bytes, size_t len); void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size); struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session); void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf); int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out); int _libssh2_get_byte(struct string_buf *buf, unsigned char *out); int _libssh2_get_u32(struct string_buf *buf, uint32_t *out); int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out); int _libssh2_match_string(struct string_buf *buf, const char *match); int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf, size_t *outlen); int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf, unsigned char **outbuf, size_t *outlen); int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf, size_t *outlen); int _libssh2_check_length(struct string_buf *buf, size_t requested_len); int _libssh2_eob(struct string_buf *buf); void _libssh2_xor_data(unsigned char *output, const unsigned char *input1, const unsigned char *input2, size_t length); void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length); #endif /* _LIBSSH2_MISC_H */ libssh2-1.11.0/src/mbedtls.h0000644000175000017500000005547014432741311012466 00000000000000#ifndef __LIBSSH2_MBEDTLS_H #define __LIBSSH2_MBEDTLS_H /* Copyright (c) 2016, Art * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #define LIBSSH2_CRYPTO_ENGINE libssh2_mbedtls #include #include #include #include #include #ifdef MBEDTLS_ECDH_C # include #endif #ifdef MBEDTLS_ECDSA_C # include #endif #include #include #include #include /* Define which features are supported. */ #define LIBSSH2_MD5 1 #define LIBSSH2_HMAC_RIPEMD 1 #define LIBSSH2_HMAC_SHA256 1 #define LIBSSH2_HMAC_SHA512 1 #define LIBSSH2_AES_CBC 1 #define LIBSSH2_AES_CTR 1 #define LIBSSH2_AES_GCM 0 #ifdef MBEDTLS_CIPHER_BLOWFISH_CBC # define LIBSSH2_BLOWFISH 1 #else # define LIBSSH2_BLOWFISH 0 #endif #ifdef MBEDTLS_CIPHER_ARC4_128 # define LIBSSH2_RC4 1 #else # define LIBSSH2_RC4 0 #endif #define LIBSSH2_CAST 0 #define LIBSSH2_3DES 1 #define LIBSSH2_RSA 1 #define LIBSSH2_RSA_SHA1 1 #define LIBSSH2_RSA_SHA2 1 #define LIBSSH2_DSA 0 #ifdef MBEDTLS_ECDSA_C # define LIBSSH2_ECDSA 1 #else # define LIBSSH2_ECDSA 0 #endif #define LIBSSH2_ED25519 0 #define MD5_DIGEST_LENGTH 16 #define SHA_DIGEST_LENGTH 20 #define SHA256_DIGEST_LENGTH 32 #define SHA384_DIGEST_LENGTH 48 #define SHA512_DIGEST_LENGTH 64 #define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) /*******************************************************************/ /* * mbedTLS backend: Generic functions */ #define libssh2_crypto_init() \ _libssh2_mbedtls_init() #define libssh2_crypto_exit() \ _libssh2_mbedtls_free() #define _libssh2_random(buf, len) \ _libssh2_mbedtls_random(buf, len) #define libssh2_prepare_iovec(vec, len) /* Empty. */ /*******************************************************************/ /* * mbedTLS backend: HMAC functions */ #define libssh2_hmac_ctx mbedtls_md_context_t #define libssh2_hmac_ctx_init(ctx) #define libssh2_hmac_cleanup(pctx) \ mbedtls_md_free(pctx) #define libssh2_hmac_update(ctx, data, datalen) \ mbedtls_md_hmac_update(&ctx, (const unsigned char *) data, datalen) #define libssh2_hmac_final(ctx, hash) \ mbedtls_md_hmac_finish(&ctx, hash) #define libssh2_hmac_sha1_init(pctx, key, keylen) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, key, keylen) #define libssh2_hmac_md5_init(pctx, key, keylen) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, key, keylen) #define libssh2_hmac_ripemd160_init(pctx, key, keylen) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen) #define libssh2_hmac_sha256_init(pctx, key, keylen) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen) #define libssh2_hmac_sha384_init(pctx, key, keylen) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, key, keylen) #define libssh2_hmac_sha512_init(pctx, key, keylen) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen) /*******************************************************************/ /* * mbedTLS backend: SHA1 functions */ #define libssh2_sha1_ctx mbedtls_md_context_t #define libssh2_sha1_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0) #define libssh2_sha1_update(ctx, data, datalen) \ mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) #define libssh2_sha1_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha1(data, datalen, hash) \ _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash) /*******************************************************************/ /* * mbedTLS backend: SHA256 functions */ #define libssh2_sha256_ctx mbedtls_md_context_t #define libssh2_sha256_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0) #define libssh2_sha256_update(ctx, data, datalen) \ mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) #define libssh2_sha256_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha256(data, datalen, hash) \ _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash) /*******************************************************************/ /* * mbedTLS backend: SHA384 functions */ #define libssh2_sha384_ctx mbedtls_md_context_t #define libssh2_sha384_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0) #define libssh2_sha384_update(ctx, data, datalen) \ mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) #define libssh2_sha384_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha384(data, datalen, hash) \ _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash) /*******************************************************************/ /* * mbedTLS backend: SHA512 functions */ #define libssh2_sha512_ctx mbedtls_md_context_t #define libssh2_sha512_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0) #define libssh2_sha512_update(ctx, data, datalen) \ mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) #define libssh2_sha512_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha512(data, datalen, hash) \ _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash) /*******************************************************************/ /* * mbedTLS backend: MD5 functions */ #define libssh2_md5_ctx mbedtls_md_context_t #define libssh2_md5_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0) #define libssh2_md5_update(ctx, data, datalen) \ mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) #define libssh2_md5_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_md5(data, datalen, hash) \ _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash) /*******************************************************************/ /* * mbedTLS backend: RSA functions */ #define libssh2_rsa_ctx mbedtls_rsa_context #define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ d, d_len, p, p_len, q, q_len, \ e1, e1_len, e2, e2_len, c, c_len) \ _libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \ d, d_len, p, p_len, q, q_len, \ e1, e1_len, e2, e2_len, c, c_len) #define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ _libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase) #define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \ filedata_len, passphrase) \ _libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \ filedata_len, passphrase) #define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ _libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) #define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \ _libssh2_mbedtls_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) #define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ _libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) #define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \ _libssh2_mbedtls_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) #define _libssh2_rsa_free(rsactx) \ _libssh2_mbedtls_rsa_free(rsactx) /*******************************************************************/ /* * mbedTLS backend: ECDSA structures */ #if LIBSSH2_ECDSA typedef enum { #ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_SECP256R1, #else LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_NONE, #endif #ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_SECP384R1, #else LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_NONE, #endif #ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_SECP521R1 #else LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_NONE, #endif } libssh2_curve_type; # define _libssh2_ec_key mbedtls_ecp_keypair #else # define _libssh2_ec_key void #endif /* LIBSSH2_ECDSA */ /*******************************************************************/ /* * mbedTLS backend: ECDSA functions */ #if LIBSSH2_ECDSA #define libssh2_ecdsa_ctx mbedtls_ecdsa_context #define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \ pubkey_octal_len, curve) \ _libssh2_mbedtls_ecdsa_create_key(session, privkey, pubkey_octal, \ pubkey_octal_len, curve) #define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \ _libssh2_mbedtls_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) #define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \ _libssh2_mbedtls_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) #define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \ _libssh2_mbedtls_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) #define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \ _libssh2_mbedtls_ecdsa_new_private(ctx, session, filename, passphrase) #define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \ filedata_len, passphrase) \ _libssh2_mbedtls_ecdsa_new_private_frommemory(ctx, session, filedata, \ filedata_len, passphrase) #define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \ _libssh2_mbedtls_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) #define _libssh2_ecdsa_get_curve_type(ctx) \ _libssh2_mbedtls_ecdsa_get_curve_type(ctx) #define _libssh2_ecdsa_free(ctx) \ _libssh2_mbedtls_ecdsa_free(ctx) #endif /* LIBSSH2_ECDSA */ /*******************************************************************/ /* * mbedTLS backend: Key functions */ #define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ _libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) #define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ pk, pk_len, pw) \ _libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ pk, pk_len, pw) #define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \ f, kh, kh_len, pk, pk_len, pw) \ _libssh2_mbedtls_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \ f, kh, kh_len, pk, pk_len, pw) /*******************************************************************/ /* * mbedTLS backend: Cipher Context structure */ #define _libssh2_cipher_ctx mbedtls_cipher_context_t #define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo #define _libssh2_cipher_aes256ctr MBEDTLS_CIPHER_AES_256_CTR #define _libssh2_cipher_aes192ctr MBEDTLS_CIPHER_AES_192_CTR #define _libssh2_cipher_aes128ctr MBEDTLS_CIPHER_AES_128_CTR #define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC #define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC #define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC #ifdef MBEDTLS_CIPHER_BLOWFISH_CBC #define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC #endif #ifdef MBEDTLS_CIPHER_ARC4_128 #define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128 #endif #define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC /*******************************************************************/ /* * mbedTLS backend: Cipher functions */ #define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ _libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt) #define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \ _libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) #define _libssh2_cipher_dtor(ctx) \ _libssh2_mbedtls_cipher_dtor(ctx) /*******************************************************************/ /* * mbedTLS backend: BigNumber Support */ #define _libssh2_bn_ctx int /* not used */ #define _libssh2_bn_ctx_new() 0 /* not used */ #define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ #define _libssh2_bn mbedtls_mpi #define _libssh2_bn_init() \ _libssh2_mbedtls_bignum_init() #define _libssh2_bn_init_from_bin() \ _libssh2_mbedtls_bignum_init() #define _libssh2_bn_set_word(bn, word) \ mbedtls_mpi_lset(bn, word) #define _libssh2_bn_from_bin(bn, len, bin) \ mbedtls_mpi_read_binary(bn, bin, len) #define _libssh2_bn_to_bin(bn, bin) \ mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn)) #define _libssh2_bn_bytes(bn) \ mbedtls_mpi_size(bn) #define _libssh2_bn_bits(bn) \ mbedtls_mpi_bitlen(bn) #define _libssh2_bn_free(bn) \ _libssh2_mbedtls_bignum_free(bn) /*******************************************************************/ /* * mbedTLS backend: Diffie-Hellman support. */ /* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ #define LIBSSH2_DH_GEX_MINGROUP 2048 #define LIBSSH2_DH_GEX_OPTGROUP 4096 #define LIBSSH2_DH_GEX_MAXGROUP 8192 #define LIBSSH2_DH_MAX_MODULUS_BITS 16384 #define _libssh2_dh_ctx mbedtls_mpi * #define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) #define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ _libssh2_dh_key_pair(dhctx, public, g, p, group_order) #define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ _libssh2_dh_secret(dhctx, secret, f, p) #define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) /*******************************************************************/ /* * mbedTLS backend: forward declarations */ void _libssh2_mbedtls_init(void); void _libssh2_mbedtls_free(void); int _libssh2_mbedtls_random(unsigned char *buf, size_t len); int _libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), unsigned char *iv, unsigned char *secret, int encrypt); int _libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(type), int encrypt, unsigned char *block, size_t blocklen, int firstlast); void _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx); int _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, mbedtls_md_type_t mdtype, const unsigned char *key, unsigned long keylen); int _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash); int _libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, mbedtls_md_type_t mdtype, unsigned char *hash); _libssh2_bn * _libssh2_mbedtls_bignum_init(void); void _libssh2_mbedtls_bignum_free(_libssh2_bn *bn); int _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen); int _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase); int _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); int _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len); int _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); int _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, size_t hash_len, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len); int _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); void _libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa); int _libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase); int _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase); #if LIBSSH2_ECDSA int _libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session, _libssh2_ec_key **privkey, unsigned char **pubkey_octal, size_t *pubkey_octal_len, libssh2_curve_type curve); int _libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx, const unsigned char *k, size_t k_len, libssh2_curve_type curve); int _libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *privkey, const unsigned char *server_pubkey, size_t server_pubkey_len); int _libssh2_mbedtls_ecdsa_verify(libssh2_ecdsa_ctx *ctx, const unsigned char *r, size_t r_len, const unsigned char *s, size_t s_len, const unsigned char *m, size_t m_len); int _libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase); int _libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, const unsigned char *passphrase); int _libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ctx, const unsigned char *hash, unsigned long hash_len, unsigned char **signature, size_t *signature_len); libssh2_curve_type _libssh2_mbedtls_ecdsa_key_get_curve_type(libssh2_ecdsa_ctx *ctx); int _libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name, libssh2_curve_type *type); void _libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx); #endif /* LIBSSH2_ECDSA */ extern void _libssh2_init_aes_ctr(void); extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx); extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order); extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p); extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); #endif /* __LIBSSH2_MBEDTLS_H */ libssh2-1.11.0/src/mbedtls.c0000644000175000017500000012016314432741311012451 00000000000000/* Copyright (c) 2016, Art * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */ #include #if MBEDTLS_VERSION_NUMBER < 0x03000000 #define mbedtls_cipher_info_get_key_bitlen(c) (c->key_bitlen) #define mbedtls_cipher_info_get_iv_size(c) (c->iv_size) #define mbedtls_rsa_get_len(rsa) (rsa->len) #define MBEDTLS_PRIVATE(m) m #endif /*******************************************************************/ /* * mbedTLS backend: Global context handles */ static mbedtls_entropy_context _libssh2_mbedtls_entropy; static mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg; /*******************************************************************/ /* * mbedTLS backend: Generic functions */ void _libssh2_mbedtls_init(void) { int ret; mbedtls_entropy_init(&_libssh2_mbedtls_entropy); mbedtls_ctr_drbg_init(&_libssh2_mbedtls_ctr_drbg); ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg, mbedtls_entropy_func, &_libssh2_mbedtls_entropy, NULL, 0); if(ret) mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); } void _libssh2_mbedtls_free(void) { mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); mbedtls_entropy_free(&_libssh2_mbedtls_entropy); } int _libssh2_mbedtls_random(unsigned char *buf, size_t len) { int ret; ret = mbedtls_ctr_drbg_random(&_libssh2_mbedtls_ctr_drbg, buf, len); return ret == 0 ? 0 : -1; } static void _libssh2_mbedtls_safe_free(void *buf, size_t len) { if(!buf) return; if(len > 0) _libssh2_explicit_zero(buf, len); mbedtls_free(buf); } int _libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { const mbedtls_cipher_info_t *cipher_info; int ret, op; if(!ctx) return -1; op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; cipher_info = mbedtls_cipher_info_from_type(algo); if(!cipher_info) return -1; mbedtls_cipher_init(ctx); ret = mbedtls_cipher_setup(ctx, cipher_info); if(!ret) ret = mbedtls_cipher_setkey(ctx, secret, (int)mbedtls_cipher_info_get_key_bitlen(cipher_info), op); if(!ret) ret = mbedtls_cipher_set_iv(ctx, iv, mbedtls_cipher_info_get_iv_size(cipher_info)); return ret == 0 ? 0 : -1; } int _libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocklen, int firstlast) { int ret; unsigned char *output; size_t osize, olen, finish_olen; (void)encrypt; (void)algo; (void)firstlast; osize = blocklen + mbedtls_cipher_get_block_size(ctx); output = (unsigned char *)mbedtls_calloc(osize, sizeof(char)); if(output) { ret = mbedtls_cipher_reset(ctx); if(!ret) ret = mbedtls_cipher_update(ctx, block, blocklen, output, &olen); if(!ret) ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen); if(!ret) { olen += finish_olen; memcpy(block, output, olen); } _libssh2_mbedtls_safe_free(output, osize); } else ret = -1; return ret == 0 ? 0 : -1; } void _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) { mbedtls_cipher_free(ctx); } int _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, mbedtls_md_type_t mdtype, const unsigned char *key, unsigned long keylen) { const mbedtls_md_info_t *md_info; int ret, hmac; md_info = mbedtls_md_info_from_type(mdtype); if(!md_info) return 0; hmac = key ? 1 : 0; mbedtls_md_init(ctx); ret = mbedtls_md_setup(ctx, md_info, hmac); if(!ret) { if(hmac) ret = mbedtls_md_hmac_starts(ctx, key, keylen); else ret = mbedtls_md_starts(ctx); } return ret == 0 ? 1 : 0; } int _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) { int ret; ret = mbedtls_md_finish(ctx, hash); mbedtls_md_free(ctx); return ret == 0 ? 0 : -1; } int _libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, mbedtls_md_type_t mdtype, unsigned char *hash) { const mbedtls_md_info_t *md_info; int ret; md_info = mbedtls_md_info_from_type(mdtype); if(!md_info) return 0; ret = mbedtls_md(md_info, data, datalen, hash); return ret == 0 ? 0 : -1; } /*******************************************************************/ /* * mbedTLS backend: BigNumber functions */ _libssh2_bn * _libssh2_mbedtls_bignum_init(void) { _libssh2_bn *bignum; bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn)); if(bignum) { mbedtls_mpi_init(bignum); } return bignum; } void _libssh2_mbedtls_bignum_free(_libssh2_bn *bn) { if(bn) { mbedtls_mpi_free(bn); mbedtls_free(bn); } } static int _libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom) { size_t len; int err; size_t i; if(!bn || bits <= 0) return -1; len = (bits + 7) >> 3; err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); if(err) return -1; /* Zero unused bits above the most significant bit */ for(i = len*8 - 1; (size_t)bits <= i; --i) { err = mbedtls_mpi_set_bit(bn, i, 0); if(err) return -1; } /* If `top` is -1, the most significant bit of the random number can be zero. If top is 0, the most significant bit of the random number is set to 1, and if top is 1, the two most significant bits of the number will be set to 1, so that the product of two such random numbers will always have 2*bits length. */ if(top >= 0) { for(i = 0; i <= (size_t)top; ++i) { err = mbedtls_mpi_set_bit(bn, bits-i-1, 1); if(err) return -1; } } /* make odd by setting first bit in least significant byte */ if(bottom) { err = mbedtls_mpi_set_bit(bn, 0, 1); if(err) return -1; } return 0; } /*******************************************************************/ /* * mbedTLS backend: RSA functions */ int _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { int ret; libssh2_rsa_ctx *ctx; ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); if(ctx) { #if MBEDTLS_VERSION_NUMBER >= 0x03000000 mbedtls_rsa_init(ctx); #else mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0); #endif } else return -1; /* !checksrc! disable ASSIGNWITHINCONDITION 1 */ if((ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(E)), edata, elen)) || (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(N)), ndata, nlen))) { ret = -1; } if(!ret) { ctx->MBEDTLS_PRIVATE(len) = mbedtls_mpi_size(&(ctx->MBEDTLS_PRIVATE(N))); } if(!ret && ddata) { /* !checksrc! disable ASSIGNWITHINCONDITION 1 */ if((ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(D)), ddata, dlen)) || (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(P)), pdata, plen)) || (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(Q)), qdata, qlen)) || (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(DP)), e1data, e1len)) || (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(DQ)), e2data, e2len)) || (ret = mbedtls_mpi_read_binary(&(ctx->MBEDTLS_PRIVATE(QP)), coeffdata, coefflen))) { ret = -1; } ret = mbedtls_rsa_check_privkey(ctx); } else if(!ret) { ret = mbedtls_rsa_check_pubkey(ctx); } if(ret && ctx) { _libssh2_mbedtls_rsa_free(ctx); ctx = NULL; } *rsa = ctx; return ret; } int _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, const unsigned char *passphrase) { int ret; mbedtls_pk_context pkey; mbedtls_rsa_context *pk_rsa; *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx)); if(!*rsa) return -1; #if MBEDTLS_VERSION_NUMBER >= 0x03000000 mbedtls_rsa_init(*rsa); #else mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0); #endif mbedtls_pk_init(&pkey); #if MBEDTLS_VERSION_NUMBER >= 0x03000000 ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); #else ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase); #endif if(ret || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { mbedtls_pk_free(&pkey); mbedtls_rsa_free(*rsa); LIBSSH2_FREE(session, *rsa); *rsa = NULL; return -1; } pk_rsa = mbedtls_pk_rsa(pkey); mbedtls_rsa_copy(*rsa, pk_rsa); mbedtls_pk_free(&pkey); return 0; } int _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase) { int ret; mbedtls_pk_context pkey; mbedtls_rsa_context *pk_rsa; void *filedata_nullterm; size_t pwd_len; *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); if(!*rsa) return -1; /* mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" private-key from memory will fail if the last byte is not a null byte */ filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1); if(!filedata_nullterm) { return -1; } memcpy(filedata_nullterm, filedata, filedata_len); mbedtls_pk_init(&pkey); pwd_len = passphrase ? strlen((const char *)passphrase) : 0; #if MBEDTLS_VERSION_NUMBER >= 0x03000000 ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm, filedata_len + 1, passphrase, pwd_len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); #else ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm, filedata_len + 1, passphrase, pwd_len); #endif _libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len); if(ret || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { mbedtls_pk_free(&pkey); mbedtls_rsa_free(*rsa); LIBSSH2_FREE(session, *rsa); *rsa = NULL; return -1; } pk_rsa = mbedtls_pk_rsa(pkey); mbedtls_rsa_copy(*rsa, pk_rsa); mbedtls_pk_free(&pkey); return 0; } int _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, size_t hash_len, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len) { int ret; int md_type; unsigned char *hash; if(sig_len < mbedtls_rsa_get_len(rsactx)) return -1; hash = malloc(hash_len); if(!hash) return -1; if(hash_len == SHA_DIGEST_LENGTH) { md_type = MBEDTLS_MD_SHA1; } else if(hash_len == SHA256_DIGEST_LENGTH) { md_type = MBEDTLS_MD_SHA256; } else if(hash_len == SHA512_DIGEST_LENGTH) { md_type = MBEDTLS_MD_SHA512; } else{ free(hash); return -1; /* unsupported digest */ } ret = _libssh2_mbedtls_hash(m, m_len, md_type, hash); if(ret) { free(hash); return -1; /* failure */ } #if MBEDTLS_VERSION_NUMBER >= 0x03000000 ret = mbedtls_rsa_pkcs1_verify(rsactx, md_type, (unsigned int)hash_len, hash, sig); #else ret = mbedtls_rsa_pkcs1_verify(rsactx, NULL, NULL, MBEDTLS_RSA_PUBLIC, md_type, (unsigned int)hash_len, hash, sig); #endif free(hash); return (ret == 0) ? 0 : -1; } int _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len) { return _libssh2_mbedtls_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, sig, sig_len, m, m_len); } int _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { int ret; unsigned char *sig; size_t sig_len; int md_type; sig_len = mbedtls_rsa_get_len(rsa); sig = LIBSSH2_ALLOC(session, sig_len); if(!sig) { return -1; } ret = 0; if(hash_len == SHA_DIGEST_LENGTH) { md_type = MBEDTLS_MD_SHA1; } else if(hash_len == SHA256_DIGEST_LENGTH) { md_type = MBEDTLS_MD_SHA256; } else if(hash_len == SHA512_DIGEST_LENGTH) { md_type = MBEDTLS_MD_SHA512; } else { _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unsupported hash digest length"); ret = -1; } if(ret == 0) { #if MBEDTLS_VERSION_NUMBER >= 0x03000000 ret = mbedtls_rsa_pkcs1_sign(rsa, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg, md_type, (unsigned int)hash_len, hash, sig); #else ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, md_type, (unsigned int)hash_len, hash, sig); #endif } if(ret) { LIBSSH2_FREE(session, sig); return -1; } *signature = sig; *signature_len = sig_len; return (ret == 0) ? 0 : -1; } int _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) { return _libssh2_mbedtls_rsa_sha2_sign(session, rsactx, hash, hash_len, signature, signature_len); } void _libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *ctx) { mbedtls_rsa_free(ctx); mbedtls_free(ctx); } static unsigned char * gen_publickey_from_rsa(LIBSSH2_SESSION *session, mbedtls_rsa_context *rsa, size_t *keylen) { uint32_t e_bytes, n_bytes; uint32_t len; unsigned char *key; unsigned char *p; e_bytes = (uint32_t)mbedtls_mpi_size(&rsa->MBEDTLS_PRIVATE(E)); n_bytes = (uint32_t)mbedtls_mpi_size(&rsa->MBEDTLS_PRIVATE(N)); /* Key form is "ssh-rsa" + e + n. */ len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; key = LIBSSH2_ALLOC(session, len); if(!key) { return NULL; } /* Process key encoding. */ p = key; _libssh2_htonu32(p, 7); /* Key type. */ p += 4; memcpy(p, "ssh-rsa", 7); p += 7; _libssh2_htonu32(p, e_bytes); p += 4; mbedtls_mpi_write_binary(&rsa->MBEDTLS_PRIVATE(E), p, e_bytes); _libssh2_htonu32(p, n_bytes); p += 4; mbedtls_mpi_write_binary(&rsa->MBEDTLS_PRIVATE(N), p, n_bytes); *keylen = (size_t)(p - key); return key; } static int _libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, mbedtls_pk_context *pkey) { unsigned char *key = NULL, *mth = NULL; size_t keylen = 0, mthlen = 0; int ret; mbedtls_rsa_context *rsa; if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA) { mbedtls_pk_free(pkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Key type not supported"); } /* write method */ mthlen = 7; mth = LIBSSH2_ALLOC(session, mthlen); if(mth) { memcpy(mth, "ssh-rsa", mthlen); } else { ret = -1; } rsa = mbedtls_pk_rsa(*pkey); key = gen_publickey_from_rsa(session, rsa, &keylen); if(!key) { ret = -1; } /* write output */ if(ret) { if(mth) LIBSSH2_FREE(session, mth); if(key) LIBSSH2_FREE(session, key); } else { *method = mth; *method_len = mthlen; *pubkeydata = key; *pubkeydata_len = keylen; } return ret; } int _libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { mbedtls_pk_context pkey; char buf[1024]; int ret; mbedtls_pk_init(&pkey); #if MBEDTLS_VERSION_NUMBER >= 0x03000000 ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); #else ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase); #endif if(ret) { mbedtls_strerror(ret, (char *)buf, sizeof(buf)); mbedtls_pk_free(&pkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); } ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, pubkeydata, pubkeydata_len, &pkey); mbedtls_pk_free(&pkey); return ret; } int _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { mbedtls_pk_context pkey; char buf[1024]; int ret; void *privatekeydata_nullterm; size_t pwd_len; /* mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" private-key from memory will fail if the last byte is not a null byte */ privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1); if(!privatekeydata_nullterm) { return -1; } memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len); mbedtls_pk_init(&pkey); pwd_len = passphrase ? strlen((const char *)passphrase) : 0; #if MBEDTLS_VERSION_NUMBER >= 0x03000000 ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)privatekeydata_nullterm, privatekeydata_len + 1, (const unsigned char *)passphrase, pwd_len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); #else ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)privatekeydata_nullterm, privatekeydata_len + 1, (const unsigned char *)passphrase, pwd_len); #endif _libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len); if(ret) { mbedtls_strerror(ret, (char *)buf, sizeof(buf)); mbedtls_pk_free(&pkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); } ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, pubkeydata, pubkeydata_len, &pkey); mbedtls_pk_free(&pkey); return ret; } int _libssh2_mbedtls_sk_pub_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, int *algorithm, unsigned char *flags, const char **application, const unsigned char **key_handle, size_t *handle_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { (void)method; (void)method_len; (void)pubkeydata; (void)pubkeydata_len; (void)algorithm; (void)flags; (void)application; (void)key_handle; (void)handle_len; (void)privatekeydata; (void)privatekeydata_len; (void)passphrase; return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public SK key from private key file: " "Method unimplemented in mbedTLS backend"); } void _libssh2_init_aes_ctr(void) { /* no implementation */ } /*******************************************************************/ /* * mbedTLS backend: Diffie-Hellman functions */ void _libssh2_dh_init(_libssh2_dh_ctx *dhctx) { *dhctx = _libssh2_mbedtls_bignum_init(); /* Random from client */ } int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order) { /* Generate x and e */ _libssh2_mbedtls_bignum_random(*dhctx, group_order * 8 - 1, 0, -1); mbedtls_mpi_exp_mod(public, g, *dhctx, p, NULL); return 0; } int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p) { /* Compute the shared secret */ mbedtls_mpi_exp_mod(secret, f, *dhctx, p, NULL); return 0; } void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) { _libssh2_mbedtls_bignum_free(*dhctx); *dhctx = NULL; } #if LIBSSH2_ECDSA /*******************************************************************/ /* * mbedTLS backend: ECDSA functions */ /* * _libssh2_ecdsa_create_key * * Creates a local private key based on input curve * and returns octal value and octal length * */ int _libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session, _libssh2_ec_key **privkey, unsigned char **pubkey_oct, size_t *pubkey_oct_len, libssh2_curve_type curve) { size_t plen = 0; *privkey = LIBSSH2_ALLOC(session, sizeof(mbedtls_ecp_keypair)); if(!*privkey) goto failed; mbedtls_ecdsa_init(*privkey); if(mbedtls_ecdsa_genkey(*privkey, (mbedtls_ecp_group_id)curve, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg)) goto failed; plen = 2 * mbedtls_mpi_size(&(*privkey)->MBEDTLS_PRIVATE(grp).P) + 1; *pubkey_oct = LIBSSH2_ALLOC(session, plen); if(!*pubkey_oct) goto failed; if(mbedtls_ecp_point_write_binary(&(*privkey)->MBEDTLS_PRIVATE(grp), &(*privkey)->MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, pubkey_oct_len, *pubkey_oct, plen) == 0) return 0; failed: _libssh2_mbedtls_ecdsa_free(*privkey); _libssh2_mbedtls_safe_free(*pubkey_oct, plen); *privkey = NULL; return -1; } /* _libssh2_ecdsa_curve_name_with_octal_new * * Creates a new public key given an octal string, length and type * */ int _libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx, const unsigned char *k, size_t k_len, libssh2_curve_type curve) { *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair)); if(!*ctx) goto failed; mbedtls_ecdsa_init(*ctx); if(mbedtls_ecp_group_load(&(*ctx)->MBEDTLS_PRIVATE(grp), (mbedtls_ecp_group_id)curve)) goto failed; if(mbedtls_ecp_point_read_binary(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(Q), k, k_len)) goto failed; if(mbedtls_ecp_check_pubkey(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(Q)) == 0) return 0; failed: _libssh2_mbedtls_ecdsa_free(*ctx); *ctx = NULL; return -1; } /* _libssh2_ecdh_gen_k * * Computes the shared secret K given a local private key, * remote public key and length */ int _libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *privkey, const unsigned char *server_pubkey, size_t server_pubkey_len) { mbedtls_ecp_point pubkey; int rc = 0; if(!*k) return -1; mbedtls_ecp_point_init(&pubkey); if(mbedtls_ecp_point_read_binary(&privkey->MBEDTLS_PRIVATE(grp), &pubkey, server_pubkey, server_pubkey_len)) { rc = -1; goto cleanup; } if(mbedtls_ecdh_compute_shared(&privkey->MBEDTLS_PRIVATE(grp), *k, &pubkey, &privkey->MBEDTLS_PRIVATE(d), mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg)) { rc = -1; goto cleanup; } if(mbedtls_ecp_check_privkey(&privkey->MBEDTLS_PRIVATE(grp), *k)) rc = -1; cleanup: mbedtls_ecp_point_free(&pubkey); return rc; } #define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \ do { \ unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \ \ if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \ rc = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hsh, \ SHA##digest_type##_DIGEST_LENGTH, \ &ctx->MBEDTLS_PRIVATE(Q), &pr, &ps); \ } \ } while(0) /* _libssh2_ecdsa_sign * * Verifies the ECDSA signature of a hashed message * */ int _libssh2_mbedtls_ecdsa_verify(libssh2_ecdsa_ctx *ctx, const unsigned char *r, size_t r_len, const unsigned char *s, size_t s_len, const unsigned char *m, size_t m_len) { mbedtls_mpi pr, ps; int rc = -1; mbedtls_mpi_init(&pr); mbedtls_mpi_init(&ps); if(mbedtls_mpi_read_binary(&pr, r, r_len)) goto cleanup; if(mbedtls_mpi_read_binary(&ps, s, s_len)) goto cleanup; switch(_libssh2_ecdsa_get_curve_type(ctx)) { case LIBSSH2_EC_CURVE_NISTP256: LIBSSH2_MBEDTLS_ECDSA_VERIFY(256); break; case LIBSSH2_EC_CURVE_NISTP384: LIBSSH2_MBEDTLS_ECDSA_VERIFY(384); break; case LIBSSH2_EC_CURVE_NISTP521: LIBSSH2_MBEDTLS_ECDSA_VERIFY(512); break; default: rc = -1; } cleanup: mbedtls_mpi_free(&pr); mbedtls_mpi_free(&ps); return (rc == 0) ? 0 : -1; } static int _libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx **ctx, mbedtls_pk_context *pkey, LIBSSH2_SESSION *session, const unsigned char *data, size_t data_len, const unsigned char *pwd) { size_t pwd_len; pwd_len = pwd ? strlen((const char *) pwd) : 0; #if MBEDTLS_VERSION_NUMBER >= 0x03000000 if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg)) goto failed; #else if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len)) goto failed; #endif if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_ECKEY) goto failed; *ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx)); if(!*ctx) goto failed; mbedtls_ecdsa_init(*ctx); if(mbedtls_ecdsa_from_keypair(*ctx, mbedtls_pk_ec(*pkey)) == 0) return 0; failed: _libssh2_mbedtls_ecdsa_free(*ctx); *ctx = NULL; return -1; } static int _libssh2_mbedtls_parse_openssh_key(libssh2_ecdsa_ctx **ctx, LIBSSH2_SESSION *session, const unsigned char *data, size_t data_len, const unsigned char *pwd) { libssh2_curve_type type; unsigned char *name = NULL; struct string_buf *decrypted = NULL; size_t curvelen, exponentlen, pointlen; unsigned char *curve, *exponent, *point_buf; if(_libssh2_openssh_pem_parse_memory(session, pwd, (const char *)data, data_len, &decrypted)) goto failed; if(_libssh2_get_string(decrypted, &name, NULL)) goto failed; if(_libssh2_mbedtls_ecdsa_curve_type_from_name((const char *)name, &type)) goto failed; if(_libssh2_get_string(decrypted, &curve, &curvelen)) goto failed; if(_libssh2_get_string(decrypted, &point_buf, &pointlen)) goto failed; if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen)) goto failed; *ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx)); if(!*ctx) goto failed; mbedtls_ecdsa_init(*ctx); if(mbedtls_ecp_group_load(&(*ctx)->MBEDTLS_PRIVATE(grp), (mbedtls_ecp_group_id)type)) goto failed; if(mbedtls_mpi_read_binary(&(*ctx)->MBEDTLS_PRIVATE(d), exponent, exponentlen)) goto failed; if(mbedtls_ecp_mul(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(Q), &(*ctx)->MBEDTLS_PRIVATE(d), &(*ctx)->MBEDTLS_PRIVATE(grp).G, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg)) goto failed; if(mbedtls_ecp_check_privkey(&(*ctx)->MBEDTLS_PRIVATE(grp), &(*ctx)->MBEDTLS_PRIVATE(d)) == 0) goto cleanup; failed: _libssh2_mbedtls_ecdsa_free(*ctx); *ctx = NULL; cleanup: if(decrypted) { _libssh2_string_buf_free(session, decrypted); } return *ctx ? 0 : -1; } /* _libssh2_ecdsa_new_private * * Creates a new private key given a file path and password * */ int _libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx, LIBSSH2_SESSION *session, const char *filename, const unsigned char *pwd) { mbedtls_pk_context pkey; unsigned char *data; size_t data_len; if(mbedtls_pk_load_file(filename, &data, &data_len)) goto cleanup; mbedtls_pk_init(&pkey); if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session, data, data_len, pwd) == 0) goto cleanup; _libssh2_mbedtls_parse_openssh_key(ctx, session, data, data_len, pwd); cleanup: mbedtls_pk_free(&pkey); _libssh2_mbedtls_safe_free(data, data_len); return *ctx ? 0 : -1; } /* _libssh2_ecdsa_new_private * * Creates a new private key given a file data and password * */ int _libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx, LIBSSH2_SESSION *session, const char *data, size_t data_len, const unsigned char *pwd) { unsigned char *ntdata; mbedtls_pk_context pkey; mbedtls_pk_init(&pkey); ntdata = LIBSSH2_ALLOC(session, data_len + 1); if(!ntdata) goto cleanup; memcpy(ntdata, data, data_len); if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session, ntdata, data_len + 1, pwd) == 0) goto cleanup; _libssh2_mbedtls_parse_openssh_key(ctx, session, ntdata, data_len + 1, pwd); cleanup: mbedtls_pk_free(&pkey); _libssh2_mbedtls_safe_free(ntdata, data_len); return *ctx ? 0 : -1; } static unsigned char * _libssh2_mbedtls_mpi_write_binary(unsigned char *buf, const mbedtls_mpi *mpi, size_t bytes) { unsigned char *p = buf; uint32_t size = (uint32_t)bytes; if(sizeof(&p) / sizeof(p[0]) < 4) { goto done; } p += 4; *p = 0; if(size > 0) { mbedtls_mpi_write_binary(mpi, p + 1, size - 1); } if(size > 0 && !(*(p + 1) & 0x80)) { memmove(p, p + 1, --size); } _libssh2_htonu32(p - 4, size); done: return p + size; } /* _libssh2_ecdsa_sign * * Computes the ECDSA signature of a previously-hashed message * */ int _libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ctx, const unsigned char *hash, unsigned long hash_len, unsigned char **sign, size_t *sign_len) { size_t r_len, s_len, tmp_sign_len = 0; unsigned char *sp, *tmp_sign = NULL; mbedtls_mpi pr, ps; mbedtls_mpi_init(&pr); mbedtls_mpi_init(&ps); if(mbedtls_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &pr, &ps, &ctx->MBEDTLS_PRIVATE(d), hash, hash_len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg)) goto cleanup; r_len = mbedtls_mpi_size(&pr) + 1; s_len = mbedtls_mpi_size(&ps) + 1; tmp_sign_len = r_len + s_len + 8; tmp_sign = LIBSSH2_CALLOC(session, tmp_sign_len); if(!tmp_sign) goto cleanup; sp = tmp_sign; sp = _libssh2_mbedtls_mpi_write_binary(sp, &pr, r_len); sp = _libssh2_mbedtls_mpi_write_binary(sp, &ps, s_len); *sign_len = (size_t)(sp - tmp_sign); *sign = LIBSSH2_CALLOC(session, *sign_len); if(!*sign) goto cleanup; memcpy(*sign, tmp_sign, *sign_len); cleanup: mbedtls_mpi_free(&pr); mbedtls_mpi_free(&ps); _libssh2_mbedtls_safe_free(tmp_sign, tmp_sign_len); return *sign ? 0 : -1; } /* _libssh2_ecdsa_get_curve_type * * returns key curve type that maps to libssh2_curve_type * */ libssh2_curve_type _libssh2_mbedtls_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ctx) { return (libssh2_curve_type) ctx->MBEDTLS_PRIVATE(grp).id; } /* _libssh2_ecdsa_curve_type_from_name * * returns 0 for success, key curve type that maps to libssh2_curve_type * */ int _libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name, libssh2_curve_type *out_type) { int ret = 0; libssh2_curve_type type; if(!name || strlen(name) != 19) return -1; if(strcmp(name, "ecdsa-sha2-nistp256") == 0) type = LIBSSH2_EC_CURVE_NISTP256; else if(strcmp(name, "ecdsa-sha2-nistp384") == 0) type = LIBSSH2_EC_CURVE_NISTP384; else if(strcmp(name, "ecdsa-sha2-nistp521") == 0) type = LIBSSH2_EC_CURVE_NISTP521; else { ret = -1; } if(ret == 0 && out_type) { *out_type = type; } return ret; } void _libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx) { mbedtls_ecdsa_free(ctx); mbedtls_free(ctx); } #endif /* LIBSSH2_ECDSA */ /* _libssh2_supported_key_sign_algorithms * * Return supported key hash algo upgrades, see crypto.h * */ const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len) { (void)session; #if LIBSSH2_RSA_SHA2 if(key_method_len == 7 && memcmp(key_method, "ssh-rsa", key_method_len) == 0) { return "rsa-sha2-512,rsa-sha2-256,ssh-rsa"; } #endif return NULL; } #endif /* LIBSSH2_CRYPTO_C */ libssh2-1.11.0/src/userauth.c0000644000175000017500000027450714432741311012673 00000000000000/* Copyright (c) 2004-2007, Sara Golemon * Copyright (c) 2005 Mikhail Gusarov * Copyright (c) 2009-2014 by Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the copyright holder nor the names * of any other contributors may be used to endorse or * promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ #include "libssh2_priv.h" #include /* Needed for struct iovec on some platforms */ #ifdef HAVE_SYS_UIO_H #include #endif #include "transport.h" #include "session.h" #include "userauth.h" #include "userauth_kbd_packet.h" /* userauth_list * * List authentication methods * Will yield successful login if "none" happens to be allowable for this user * Not a common configuration for any SSH server though * username should be NULL, or a null terminated string */ static char *userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len) { unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_BANNER, 0 }; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + method_len(4) = 27 */ unsigned long methods_len; unsigned int banner_len; unsigned char *s; int rc; if(session->userauth_list_state == libssh2_NB_state_idle) { /* Zero the whole thing out */ memset(&session->userauth_list_packet_requirev_state, 0, sizeof(session->userauth_list_packet_requirev_state)); session->userauth_list_data_len = username_len + 27; s = session->userauth_list_data = LIBSSH2_ALLOC(session, session->userauth_list_data_len); if(!session->userauth_list_data) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth_list"); return NULL; } *(s++) = SSH_MSG_USERAUTH_REQUEST; _libssh2_store_str(&s, username, username_len); _libssh2_store_str(&s, "ssh-connection", 14); _libssh2_store_u32(&s, 4); /* send "none" separately */ session->userauth_list_state = libssh2_NB_state_created; } if(session->userauth_list_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->userauth_list_data, session->userauth_list_data_len, (unsigned char *)"none", 4); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting userauth list"); return NULL; } /* now free the packet that was sent */ LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; if(rc) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-none request"); session->userauth_list_state = libssh2_NB_state_idle; return NULL; } session->userauth_list_state = libssh2_NB_state_sent; } if(session->userauth_list_state == libssh2_NB_state_sent) { rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_list_data, &session->userauth_list_data_len, 0, NULL, 0, &session->userauth_list_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting userauth list"); return NULL; } else if(rc || (session->userauth_list_data_len < 1)) { _libssh2_error(session, rc, "Failed getting response"); session->userauth_list_state = libssh2_NB_state_idle; return NULL; } if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_BANNER) { if(session->userauth_list_data_len < 5) { LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); return NULL; } banner_len = _libssh2_ntohu32(session->userauth_list_data + 1); if(banner_len > session->userauth_list_data_len - 5) { LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, "Unexpected userauth banner size"); return NULL; } session->userauth_banner = LIBSSH2_ALLOC(session, banner_len + 1); if(!session->userauth_banner) { LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth_banner"); return NULL; } memcpy(session->userauth_banner, session->userauth_list_data + 5, banner_len); session->userauth_banner[banner_len] = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Banner: %s", session->userauth_banner)); LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; /* SSH_MSG_USERAUTH_BANNER has been handled */ reply_codes[2] = 0; rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_list_data, &session->userauth_list_data_len, 0, NULL, 0, &session->userauth_list_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting userauth list"); return NULL; } else if(rc || (session->userauth_list_data_len < 1)) { _libssh2_error(session, rc, "Failed getting response"); session->userauth_list_state = libssh2_NB_state_idle; return NULL; } } if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) { /* Wow, who'dve thought... */ _libssh2_error(session, LIBSSH2_ERROR_NONE, "No error"); LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; session->userauth_list_state = libssh2_NB_state_idle; return NULL; } if(session->userauth_list_data_len < 5) { LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); return NULL; } methods_len = _libssh2_ntohu32(session->userauth_list_data + 1); if(methods_len >= session->userauth_list_data_len - 5) { _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, "Unexpected userauth list size"); return NULL; } /* Do note that the memory areas overlap! */ memmove(session->userauth_list_data, session->userauth_list_data + 5, methods_len); session->userauth_list_data[methods_len] = '\0'; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Permitted auth methods: %s", session->userauth_list_data)); } session->userauth_list_state = libssh2_NB_state_idle; return (char *)session->userauth_list_data; } /* libssh2_userauth_list * * List authentication methods * Will yield successful login if "none" happens to be allowable for this user * Not a common configuration for any SSH server though * username should be NULL, or a null terminated string */ LIBSSH2_API char * libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user, unsigned int user_len) { char *ptr; BLOCK_ADJUST_ERRNO(ptr, session, userauth_list(session, user, user_len)); return ptr; } /* libssh2_userauth_banner * * Retrieve banner message from server, if available. * When no such message is sent by server or if no authentication attempt has * been made, this function returns LIBSSH2_ERROR_MISSING_AUTH_BANNER. */ LIBSSH2_API int libssh2_userauth_banner(LIBSSH2_SESSION *session, char **banner) { if(!session) return LIBSSH2_ERROR_MISSING_USERAUTH_BANNER; if(!session->userauth_banner) { return _libssh2_error(session, LIBSSH2_ERROR_MISSING_USERAUTH_BANNER, "Missing userauth banner"); } if(banner) *banner = session->userauth_banner; return LIBSSH2_ERROR_NONE; } /* * libssh2_userauth_authenticated * * Returns: 0 if not yet authenticated * 1 if already authenticated */ LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION * session) { return (session->state & LIBSSH2_STATE_AUTHENTICATED) ? 1 : 0; } /* userauth_password * Plain ol' login */ static int userauth_password(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const unsigned char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) { unsigned char *s; static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 }; int rc; if(session->userauth_pswd_state == libssh2_NB_state_idle) { /* Zero the whole thing out */ memset(&session->userauth_pswd_packet_requirev_state, 0, sizeof(session->userauth_pswd_packet_requirev_state)); /* * 40 = packet_type(1) + username_len(4) + service_len(4) + * service(14)"ssh-connection" + method_len(4) + method(8)"password" + * chgpwdbool(1) + password_len(4) */ session->userauth_pswd_data_len = username_len + 40; session->userauth_pswd_data0 = (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; /* TODO: remove this alloc with a fixed buffer in the session struct */ s = session->userauth_pswd_data = LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); if(!session->userauth_pswd_data) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "userauth-password request"); } *(s++) = SSH_MSG_USERAUTH_REQUEST; _libssh2_store_str(&s, username, username_len); _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); _libssh2_store_str(&s, "password", sizeof("password") - 1); *s++ = '\0'; _libssh2_store_u32(&s, password_len); /* 'password' is sent separately */ _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Attempting to login using password authentication")); session->userauth_pswd_state = libssh2_NB_state_created; } if(session->userauth_pswd_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->userauth_pswd_data, session->userauth_pswd_data_len, password, password_len); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block writing password request"); } /* now free the sent packet */ LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; if(rc) { session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request"); } session->userauth_pswd_state = libssh2_NB_state_sent; } password_response: if((session->userauth_pswd_state == libssh2_NB_state_sent) || (session->userauth_pswd_state == libssh2_NB_state_sent1) || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { if(session->userauth_pswd_state == libssh2_NB_state_sent) { rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_pswd_data, &session->userauth_pswd_data_len, 0, NULL, 0, &session-> userauth_pswd_packet_requirev_state); if(rc) { if(rc != LIBSSH2_ERROR_EAGAIN) session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, rc, "Waiting for password response"); } else if(session->userauth_pswd_data_len < 1) { session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); } if(session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Password authentication successful")); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; session->userauth_pswd_state = libssh2_NB_state_idle; return 0; } else if(session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_FAILURE) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Password authentication failed")); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, "Authentication failed " "(username/password)"); } session->userauth_pswd_newpw = NULL; session->userauth_pswd_newpw_len = 0; session->userauth_pswd_state = libssh2_NB_state_sent1; } if(session->userauth_pswd_data_len < 1) { session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unexpected packet size"); } if((session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) || (session->userauth_pswd_data0 == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) { session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; if((session->userauth_pswd_state == libssh2_NB_state_sent1) || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { if(session->userauth_pswd_state == libssh2_NB_state_sent1) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Password change required")); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; } if(passwd_change_cb) { if(session->userauth_pswd_state == libssh2_NB_state_sent1) { passwd_change_cb(session, &session->userauth_pswd_newpw, &session->userauth_pswd_newpw_len, &session->abstract); if(!session->userauth_pswd_newpw) { return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password expired, and " "callback failed"); } /* basic data_len + newpw_len(4) */ if(username_len + password_len + 44 <= UINT_MAX) { session->userauth_pswd_data_len = username_len + password_len + 44; s = session->userauth_pswd_data = LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); } else { s = session->userauth_pswd_data = NULL; session->userauth_pswd_data_len = 0; } if(!session->userauth_pswd_data) { LIBSSH2_FREE(session, session->userauth_pswd_newpw); session->userauth_pswd_newpw = NULL; return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory " "for userauth password " "change request"); } *(s++) = SSH_MSG_USERAUTH_REQUEST; _libssh2_store_str(&s, username, username_len); _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); _libssh2_store_str(&s, "password", sizeof("password") - 1); *s++ = 0x01; _libssh2_store_str(&s, (char *)password, password_len); _libssh2_store_u32(&s, session->userauth_pswd_newpw_len); /* send session->userauth_pswd_newpw separately */ session->userauth_pswd_state = libssh2_NB_state_sent2; } if(session->userauth_pswd_state == libssh2_NB_state_sent2) { rc = _libssh2_transport_send(session, session->userauth_pswd_data, session->userauth_pswd_data_len, (unsigned char *) session->userauth_pswd_newpw, session->userauth_pswd_newpw_len); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting"); } /* free the allocated packets again */ LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; LIBSSH2_FREE(session, session->userauth_pswd_newpw); session->userauth_pswd_newpw = NULL; if(rc) { return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth " "password-change request"); } /* * Ugliest use of goto ever. Blame it on the * askN => requirev migration. */ session->userauth_pswd_state = libssh2_NB_state_sent; goto password_response; } } } else { session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password Expired, and no callback " "specified"); } } } /* FAILURE */ LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; session->userauth_pswd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, "Authentication failed"); } /* * libssh2_userauth_password_ex * * Plain ol' login */ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC ((*passwd_change_cb))) { int rc; BLOCK_ADJUST(rc, session, userauth_password(session, username, username_len, (unsigned char *)password, password_len, passwd_change_cb)); return rc; } static int memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *pubkeyfiledata, size_t pubkeyfiledata_len) { unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; size_t pubkey_len = pubkeyfiledata_len; size_t tmp_len; if(pubkeyfiledata_len <= 1) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid data in public key file"); } pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len); if(!pubkey) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for public key data"); } memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len); /* * Remove trailing whitespace */ while(pubkey_len && isspace(pubkey[pubkey_len - 1])) pubkey_len--; if(!pubkey_len) { LIBSSH2_FREE(session, pubkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data"); } sp1 = memchr(pubkey, ' ', pubkey_len); if(!sp1) { LIBSSH2_FREE(session, pubkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid public key data"); } sp1++; sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey)); if(!sp2) { /* Assume that the id string is missing, but that it's okay */ sp2 = pubkey + pubkey_len; } if(_libssh2_base64_decode(session, (char **)&tmp, &tmp_len, (const char *)sp1, sp2 - sp1)) { LIBSSH2_FREE(session, pubkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid key data, not base64 encoded"); } /* Wasting some bytes here (okay, more than some), but since it's likely * to be freed soon anyway, we'll just avoid the extra free/alloc and call * it a wash */ *method = pubkey; *method_len = sp1 - pubkey - 1; *pubkeydata = tmp; *pubkeydata_len = tmp_len; return 0; } /* * file_read_publickey * * Read a public key from an id_???.pub style file * * Returns an allocated string containing the decoded key in *pubkeydata * on success. * Returns an allocated string containing the key method (e.g. "ssh-dss") * in method on success. */ static int file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *pubkeyfile) { FILE *fd; char c; unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; size_t pubkey_len = 0, sp_len; size_t tmp_len; _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s", pubkeyfile)); /* Read Public Key */ fd = fopen(pubkeyfile, FOPEN_READTEXT); if(!fd) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open public key file"); } while(!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') { pubkey_len++; } rewind(fd); if(pubkey_len <= 1) { fclose(fd); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid data in public key file"); } pubkey = LIBSSH2_ALLOC(session, pubkey_len); if(!pubkey) { fclose(fd); return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for public key data"); } if(fread(pubkey, 1, pubkey_len, fd) != pubkey_len) { LIBSSH2_FREE(session, pubkey); fclose(fd); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to read public key from file"); } fclose(fd); /* * Remove trailing whitespace */ while(pubkey_len && isspace(pubkey[pubkey_len - 1])) { pubkey_len--; } if(!pubkey_len) { LIBSSH2_FREE(session, pubkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data"); } sp1 = memchr(pubkey, ' ', pubkey_len); if(!sp1) { LIBSSH2_FREE(session, pubkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid public key data"); } sp1++; sp_len = sp1 > pubkey ? (sp1 - pubkey) : 0; sp2 = memchr(sp1, ' ', pubkey_len - sp_len); if(!sp2) { /* Assume that the id string is missing, but that it's okay */ sp2 = pubkey + pubkey_len; } if(_libssh2_base64_decode(session, (char **)&tmp, &tmp_len, (const char *)sp1, sp2 - sp1)) { LIBSSH2_FREE(session, pubkey); return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid key data, not base64 encoded"); } /* Wasting some bytes here (okay, more than some), but since it's likely * to be freed soon anyway, we'll just avoid the extra free/alloc and call * it a wash */ *method = pubkey; *method_len = sp1 - pubkey - 1; *pubkeydata = tmp; *pubkeydata_len = tmp_len; return 0; } static int memory_read_privatekey(LIBSSH2_SESSION * session, const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, void **hostkey_abstract, const unsigned char *method, size_t method_len, const char *privkeyfiledata, size_t privkeyfiledata_len, const char *passphrase) { const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = libssh2_hostkey_methods(); *hostkey_method = NULL; *hostkey_abstract = NULL; while(*hostkey_methods_avail && (*hostkey_methods_avail)->name) { if((*hostkey_methods_avail)->initPEMFromMemory && strncmp((*hostkey_methods_avail)->name, (const char *) method, method_len) == 0) { *hostkey_method = *hostkey_methods_avail; break; } hostkey_methods_avail++; } if(!*hostkey_method) { return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No handler for specified private key"); } if((*hostkey_method)-> initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len, (unsigned char *) passphrase, hostkey_abstract)) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to initialize private key from memory"); } return 0; } /* libssh2_file_read_privatekey * Read a PEM encoded private key from an id_??? style file */ static int file_read_privatekey(LIBSSH2_SESSION * session, const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, void **hostkey_abstract, const unsigned char *method, size_t method_len, const char *privkeyfile, const char *passphrase) { const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = libssh2_hostkey_methods(); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Loading private key file: %s", privkeyfile)); *hostkey_method = NULL; *hostkey_abstract = NULL; while(*hostkey_methods_avail && (*hostkey_methods_avail)->name) { if((*hostkey_methods_avail)->initPEM && strncmp((*hostkey_methods_avail)->name, (const char *) method, method_len) == 0) { *hostkey_method = *hostkey_methods_avail; break; } hostkey_methods_avail++; } if(!*hostkey_method) { return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No handler for specified private key"); } if((*hostkey_method)-> initPEM(session, privkeyfile, (unsigned char *) passphrase, hostkey_abstract)) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to initialize private key from file"); } return 0; } struct privkey_file { const char *filename; const char *passphrase; }; static int sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) { struct privkey_file *pk_file = (struct privkey_file *) (*abstract); const LIBSSH2_HOSTKEY_METHOD *privkeyobj; void *hostkey_abstract; struct iovec datavec; int rc; rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract, session->userauth_pblc_method, session->userauth_pblc_method_len, pk_file->filename, strlen(pk_file->filename), pk_file->passphrase); if(rc) return rc; libssh2_prepare_iovec(&datavec, 1); datavec.iov_base = (void *)data; datavec.iov_len = data_len; if(privkeyobj->signv(session, sig, sig_len, 1, &datavec, &hostkey_abstract)) { if(privkeyobj->dtor) { privkeyobj->dtor(session, &hostkey_abstract); } return -1; } if(privkeyobj->dtor) { privkeyobj->dtor(session, &hostkey_abstract); } return 0; } static int sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) { struct privkey_file *privkey_file = (struct privkey_file *) (*abstract); const LIBSSH2_HOSTKEY_METHOD *privkeyobj; void *hostkey_abstract; struct iovec datavec; int rc; rc = file_read_privatekey(session, &privkeyobj, &hostkey_abstract, session->userauth_pblc_method, session->userauth_pblc_method_len, privkey_file->filename, privkey_file->passphrase); if(rc) return rc; libssh2_prepare_iovec(&datavec, 1); datavec.iov_base = (void *)data; datavec.iov_len = data_len; if(privkeyobj->signv(session, sig, sig_len, 1, &datavec, &hostkey_abstract)) { if(privkeyobj->dtor) { privkeyobj->dtor(session, &hostkey_abstract); } return -1; } if(privkeyobj->dtor) { privkeyobj->dtor(session, &hostkey_abstract); } return 0; } int libssh2_sign_sk(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) { int rc = LIBSSH2_ERROR_DECRYPT; LIBSSH2_PRIVKEY_SK *sk_info = (LIBSSH2_PRIVKEY_SK *) (*abstract); LIBSSH2_SK_SIG_INFO sig_info = { 0 }; if(sk_info->handle_len <= 0) { return LIBSSH2_ERROR_DECRYPT; } rc = sk_info->sign_callback(session, &sig_info, data, data_len, sk_info->algorithm, sk_info->flags, sk_info->application, sk_info->key_handle, sk_info->handle_len, sk_info->orig_abstract); if(rc == 0 && sig_info.sig_r_len > 0 && sig_info.sig_r) { unsigned char *p = NULL; if(sig_info.sig_s_len > 0 && sig_info.sig_s) { /* sig length, sig_r, sig_s, flags, counter, plus 4 bytes for each component's length, and up to 1 extra byte for each component */ *sig_len = 4 + 5 + sig_info.sig_r_len + 5 + sig_info.sig_s_len + 5; *sig = LIBSSH2_ALLOC(session, *sig_len); if(*sig) { unsigned char *x = *sig; p = *sig; _libssh2_store_u32(&p, 0); _libssh2_store_bignum2_bytes(&p, sig_info.sig_r, sig_info.sig_r_len); _libssh2_store_bignum2_bytes(&p, sig_info.sig_s, sig_info.sig_s_len); *sig_len = p - *sig; _libssh2_store_u32(&x, (uint32_t)(*sig_len - 4)); } else { _libssh2_debug((session, LIBSSH2_ERROR_ALLOC, "Unable to allocate ecdsa-sk signature.")); rc = LIBSSH2_ERROR_ALLOC; } } else { /* sig, flags, counter, plus 4 bytes for sig length. */ *sig_len = 4 + sig_info.sig_r_len + 1 + 4; *sig = LIBSSH2_ALLOC(session, *sig_len); if(*sig) { p = *sig; _libssh2_store_str(&p, (const char *)sig_info.sig_r, sig_info.sig_r_len); } else { _libssh2_debug((session, LIBSSH2_ERROR_ALLOC, "Unable to allocate ed25519-sk signature.")); rc = LIBSSH2_ERROR_ALLOC; } } if(p) { *p = sig_info.flags; ++p; _libssh2_store_u32(&p, sig_info.counter); *sig_len = p - *sig; } LIBSSH2_FREE(session, sig_info.sig_r); if(sig_info.sig_s) { LIBSSH2_FREE(session, sig_info.sig_s); } } else { _libssh2_debug((session, LIBSSH2_ERROR_DECRYPT, "sign_callback failed or returned invalid signature.")); *sig_len = 0; } return rc; } /* userauth_hostbased_fromfile * Authenticate using a keypair found in the named files */ static int userauth_hostbased_fromfile(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickey, const char *privatekey, const char *passphrase, const char *hostname, size_t hostname_len, const char *local_username, size_t local_username_len) { int rc; if(session->userauth_host_state == libssh2_NB_state_idle) { const LIBSSH2_HOSTKEY_METHOD *privkeyobj; unsigned char *pubkeydata = NULL; unsigned char *sig = NULL; size_t pubkeydata_len = 0; size_t sig_len = 0; void *abstract; unsigned char buf[5]; struct iovec datavec[4]; /* Zero the whole thing out */ memset(&session->userauth_host_packet_requirev_state, 0, sizeof(session->userauth_host_packet_requirev_state)); if(publickey) { rc = file_read_publickey(session, &session->userauth_host_method, &session->userauth_host_method_len, &pubkeydata, &pubkeydata_len, publickey); if(rc) /* Note: file_read_publickey() calls _libssh2_error() */ return rc; } else { /* Compute public key from private key. */ rc = _libssh2_pub_priv_keyfile(session, &session->userauth_host_method, &session->userauth_host_method_len, &pubkeydata, &pubkeydata_len, privatekey, passphrase); if(rc) /* libssh2_pub_priv_keyfile() calls _libssh2_error() */ return rc; } /* * 52 = packet_type(1) + username_len(4) + servicename_len(4) + * service_name(14)"ssh-connection" + authmethod_len(4) + * authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + * hostname_len(4) + local_username_len(4) */ session->userauth_host_packet_len = username_len + session->userauth_host_method_len + hostname_len + local_username_len + pubkeydata_len + 52; /* * Preallocate space for an overall length, method name again, * and the signature, which won't be any larger than the size of * the publickeydata itself */ session->userauth_host_s = session->userauth_host_packet = LIBSSH2_ALLOC(session, session->userauth_host_packet_len + 4 + (4 + session->userauth_host_method_len) + (4 + pubkeydata_len)); if(!session->userauth_host_packet) { LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; LIBSSH2_FREE(session, pubkeydata); return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory"); } *(session->userauth_host_s++) = SSH_MSG_USERAUTH_REQUEST; _libssh2_store_str(&session->userauth_host_s, username, username_len); _libssh2_store_str(&session->userauth_host_s, "ssh-connection", 14); _libssh2_store_str(&session->userauth_host_s, "hostbased", 9); _libssh2_store_str(&session->userauth_host_s, (const char *)session->userauth_host_method, session->userauth_host_method_len); _libssh2_store_str(&session->userauth_host_s, (const char *)pubkeydata, pubkeydata_len); LIBSSH2_FREE(session, pubkeydata); _libssh2_store_str(&session->userauth_host_s, hostname, hostname_len); _libssh2_store_str(&session->userauth_host_s, local_username, local_username_len); rc = file_read_privatekey(session, &privkeyobj, &abstract, session->userauth_host_method, session->userauth_host_method_len, privatekey, passphrase); if(rc) { /* Note: file_read_privatekey() calls _libssh2_error() */ LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; return rc; } _libssh2_htonu32(buf, session->session_id_len); libssh2_prepare_iovec(datavec, 4); datavec[0].iov_base = (void *)buf; datavec[0].iov_len = 4; datavec[1].iov_base = (void *)session->session_id; datavec[1].iov_len = session->session_id_len; datavec[2].iov_base = (void *)session->userauth_host_packet; datavec[2].iov_len = session->userauth_host_packet_len; if(privkeyobj && privkeyobj->signv && privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) { LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; if(privkeyobj->dtor) { privkeyobj->dtor(session, &abstract); } return -1; } if(privkeyobj && privkeyobj->dtor) { privkeyobj->dtor(session, &abstract); } if(sig_len > pubkeydata_len) { unsigned char *newpacket; /* Should *NEVER* happen, but...well.. better safe than sorry */ newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, session->userauth_host_packet_len + 4 + (4 + session->userauth_host_method_len) + (4 + sig_len)); /* PK sigblob */ if(!newpacket) { LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for " "userauth-hostbased packet"); } session->userauth_host_packet = newpacket; } session->userauth_host_s = session->userauth_host_packet + session->userauth_host_packet_len; _libssh2_store_u32(&session->userauth_host_s, (uint32_t)(4 + session->userauth_host_method_len + 4 + sig_len)); _libssh2_store_str(&session->userauth_host_s, (const char *)session->userauth_host_method, session->userauth_host_method_len); LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; _libssh2_store_str(&session->userauth_host_s, (const char *)sig, sig_len); LIBSSH2_FREE(session, sig); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Attempting hostbased authentication")); session->userauth_host_state = libssh2_NB_state_created; } if(session->userauth_host_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->userauth_host_packet, session->userauth_host_s - session->userauth_host_packet, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } else if(rc) { LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; session->userauth_host_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request"); } LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; session->userauth_host_state = libssh2_NB_state_sent; } if(session->userauth_host_state == libssh2_NB_state_sent) { static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; size_t data_len; rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_host_data, &data_len, 0, NULL, 0, &session-> userauth_host_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } session->userauth_host_state = libssh2_NB_state_idle; if(rc || data_len < 1) { return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Auth failed"); } if(session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Hostbased authentication successful")); /* We are us and we've proved it. */ LIBSSH2_FREE(session, session->userauth_host_data); session->userauth_host_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; return 0; } } /* This public key is not allowed for this user on this server */ LIBSSH2_FREE(session, session->userauth_host_data); session->userauth_host_data = NULL; return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad " "username/public key combination"); } /* libssh2_userauth_hostbased_fromfile_ex * Authenticate using a keypair found in the named files */ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *user, unsigned int user_len, const char *publickey, const char *privatekey, const char *passphrase, const char *host, unsigned int host_len, const char *localuser, unsigned int localuser_len) { int rc; BLOCK_ADJUST(rc, session, userauth_hostbased_fromfile(session, user, user_len, publickey, privatekey, passphrase, host, host_len, localuser, localuser_len)); return rc; } size_t plain_method(char *method, size_t method_len) { if(!strncmp("ssh-rsa-cert-v01@openssh.com", method, method_len)) { return 7; } if(!strncmp("ecdsa-sha2-nistp256-cert-v01@openssh.com", method, method_len) || !strncmp("ecdsa-sha2-nistp384-cert-v01@openssh.com", method, method_len) || !strncmp("ecdsa-sha2-nistp521-cert-v01@openssh.com", method, method_len)) { return 19; } if(!strncmp("ssh-ed25519-cert-v01@openssh.com", method, method_len)) { return 11; } if(!strncmp("sk-ecdsa-sha2-nistp256-cert-v01@openssh.com", method, method_len)) { const char *new_method = "sk-ecdsa-sha2-nistp256@openssh.com"; memcpy(method, new_method, strlen(new_method)); return strlen(new_method); } if(!strncmp("sk-ssh-ed25519-cert-v01@openssh.com", method, method_len)) { const char *new_method = "sk-ssh-ed25519@openssh.com"; memcpy(method, new_method, strlen(new_method)); return strlen(new_method); } return method_len; } /** * @function _libssh2_key_sign_algorithm * @abstract Upgrades the algorithm used for public key signing RFC 8332 * @discussion Based on the incoming key_method value, this function * will upgrade the key method input based on user preferences, * server support algos and crypto backend support * @related _libssh2_supported_key_sign_algorithms() * @param key_method current key method, usually the default key sig method * @param key_method_len length of the key method buffer * @result error code or zero on success */ static int _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session, unsigned char **key_method, size_t *key_method_len) { const char *s = NULL; const char *a = NULL; const char *match = NULL; const char *p = NULL; const char *f = NULL; char *i = NULL; size_t p_len = 0; size_t f_len = 0; int rc = 0; size_t match_len = 0; char *filtered_algs = NULL; const char *supported_algs = _libssh2_supported_key_sign_algorithms(session, *key_method, *key_method_len); if(!supported_algs || !session->server_sign_algorithms) { /* no upgrading key algorithm supported, do nothing */ return LIBSSH2_ERROR_NONE; } filtered_algs = LIBSSH2_ALLOC(session, strlen(supported_algs) + 1); if(!filtered_algs) { rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate filtered algs"); return rc; } s = session->server_sign_algorithms; i = filtered_algs; /* this walks the server algo list and the supported algo list and creates a filtered list that includes matches */ while(s && *s) { p = strchr(s, ','); p_len = (p ? (size_t)(p - s) : strlen(s)); a = supported_algs; while(a && *a) { f = strchr(a, ','); f_len = (f ? (size_t)(f - a) : strlen(a)); if(f_len == p_len && memcmp(a, s, p_len) == 0) { if(i != filtered_algs) { memcpy(i, ",", 1); i += 1; } memcpy(i, s, p_len); i += p_len; } a = f ? (f + 1) : NULL; } s = p ? (p + 1) : NULL; } filtered_algs[i - filtered_algs] = '\0'; if(session->sign_algo_prefs) { s = session->sign_algo_prefs; } else { s = supported_algs; } /* now that we have the possible supported algos, match based on the prefs or what is supported by the crypto backend, look for a match */ while(s && *s && !match) { p = strchr(s, ','); p_len = (p ? (size_t)(p - s) : strlen(s)); a = filtered_algs; while(a && *a && !match) { f = strchr(a, ','); f_len = (f ? (size_t)(f - a) : strlen(a)); if(f_len == p_len && memcmp(a, s, p_len) == 0) { /* found a match, upgrade key method */ match = s; match_len = p_len; } else { a = f ? (f + 1) : NULL; } } s = p ? (p + 1) : NULL; } if(match) { if(*key_method) LIBSSH2_FREE(session, *key_method); *key_method = LIBSSH2_ALLOC(session, match_len); if(key_method) { memcpy(*key_method, match, match_len); *key_method_len = match_len; } else { *key_method_len = 0; rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate key method upgrade"); } } else { /* no match was found */ rc = _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No signing signature matched"); } if(filtered_algs) LIBSSH2_FREE(session, filtered_algs); return rc; } int _libssh2_userauth_publickey(LIBSSH2_SESSION *session, const char *username, size_t username_len, const unsigned char *pubkeydata, size_t pubkeydata_len, LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC ((*sign_callback)), void *abstract) { unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PK_OK, 0 }; int rc; unsigned char *s; int auth_attempts = 0; retry_auth: auth_attempts++; if(session->userauth_pblc_state == libssh2_NB_state_idle) { /* * The call to _libssh2_ntohu32 later relies on pubkeydata having at * least 4 valid bytes containing the length of the method name. */ if(pubkeydata_len < 4) return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid public key, too short"); /* Zero the whole thing out */ memset(&session->userauth_pblc_packet_requirev_state, 0, sizeof(session->userauth_pblc_packet_requirev_state)); /* * As an optimisation, userauth_publickey_fromfile reuses a * previously allocated copy of the method name to avoid an extra * allocation/free. * For other uses, we allocate and populate it here. */ if(!session->userauth_pblc_method) { session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata); if(session->userauth_pblc_method_len > pubkeydata_len - 4) /* the method length cannot be longer than the entire passed in data, so we use this to detect crazy input data */ return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid public key"); session->userauth_pblc_method = LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); if(!session->userauth_pblc_method) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory " "for public key data"); } memcpy(session->userauth_pblc_method, pubkeydata + 4, session->userauth_pblc_method_len); } /* upgrade key signing algo if it is supported and * it is our first auth attempt, otherwise fallback to * the key default algo */ if(auth_attempts == 1) { rc = _libssh2_key_sign_algorithm(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len); if(rc) return rc; } if(session->userauth_pblc_method_len && session->userauth_pblc_method) { _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Signing using %.*s", session->userauth_pblc_method_len, session->userauth_pblc_method)); } /* * 45 = packet_type(1) + username_len(4) + servicename_len(4) + * service_name(14)"ssh-connection" + authmethod_len(4) + * authmethod(9)"publickey" + sig_included(1)'\0' + algmethod_len(4) + * publickey_len(4) */ session->userauth_pblc_packet_len = username_len + session->userauth_pblc_method_len + pubkeydata_len + 45; /* * Preallocate space for an overall length, method name again, and the * signature, which won't be any larger than the size of the * publickeydata itself. * * Note that the 'pubkeydata_len' extra bytes allocated here will not * be used in this first send, but will be used in the later one where * this same allocation is re-used. */ s = session->userauth_pblc_packet = LIBSSH2_ALLOC(session, session->userauth_pblc_packet_len + 4 + (4 + session->userauth_pblc_method_len) + (4 + pubkeydata_len)); if(!session->userauth_pblc_packet) { LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory"); } *s++ = SSH_MSG_USERAUTH_REQUEST; _libssh2_store_str(&s, username, username_len); _libssh2_store_str(&s, "ssh-connection", 14); _libssh2_store_str(&s, "publickey", 9); session->userauth_pblc_b = s; /* Not sending signature with *this* packet */ *s++ = 0; _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, session->userauth_pblc_method_len); _libssh2_store_str(&s, (const char *)pubkeydata, pubkeydata_len); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Attempting publickey authentication")); session->userauth_pblc_state = libssh2_NB_state_created; } if(session->userauth_pblc_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->userauth_pblc_packet, session->userauth_pblc_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); else if(rc) { LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request"); } session->userauth_pblc_state = libssh2_NB_state_sent; } if(session->userauth_pblc_state == libssh2_NB_state_sent) { rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_pblc_data, &session->userauth_pblc_data_len, 0, NULL, 0, &session-> userauth_pblc_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } else if(rc || (session->userauth_pblc_data_len < 1)) { LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Waiting for USERAUTH response"); } if(session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Pubkey authentication prematurely successful")); /* * God help any SSH server that allows an UNVERIFIED * public key to validate the user */ LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; session->userauth_pblc_state = libssh2_NB_state_idle; return 0; } if(session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_FAILURE) { /* This public key is not allowed for this user on this server */ LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, "Username/PublicKey combination invalid"); } /* Semi-Success! */ LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; *session->userauth_pblc_b = 0x01; session->userauth_pblc_state = libssh2_NB_state_sent1; } if(session->userauth_pblc_state == libssh2_NB_state_sent1) { unsigned char *buf; unsigned char *sig; size_t sig_len; s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len + session->userauth_pblc_packet_len); if(!buf) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "userauth-publickey signed data"); } _libssh2_store_str(&s, (const char *)session->session_id, session->session_id_len); memcpy(s, session->userauth_pblc_packet, session->userauth_pblc_packet_len); s += session->userauth_pblc_packet_len; rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract); LIBSSH2_FREE(session, buf); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } else if(rc == LIBSSH2_ERROR_ALGO_UNSUPPORTED && auth_attempts == 1) { /* try again with the default key algo */ LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; rc = LIBSSH2_ERROR_NONE; goto retry_auth; } else if(rc) { LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Callback returned error"); } /* * If this function was restarted, pubkeydata_len might still be 0 * which will cause an unnecessary but harmless realloc here. */ if(sig_len > pubkeydata_len) { unsigned char *newpacket; /* Should *NEVER* happen, but...well.. better safe than sorry */ newpacket = LIBSSH2_REALLOC(session, session->userauth_pblc_packet, session->userauth_pblc_packet_len + 4 + (4 + session->userauth_pblc_method_len) + (4 + sig_len)); /* PK sigblob */ if(!newpacket) { LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for " "userauth-publickey packet"); } session->userauth_pblc_packet = newpacket; } s = session->userauth_pblc_packet + session->userauth_pblc_packet_len; session->userauth_pblc_b = NULL; session->userauth_pblc_method_len = plain_method((char *)session->userauth_pblc_method, session->userauth_pblc_method_len); if(strncmp((const char *)session->userauth_pblc_method, "sk-ecdsa-sha2-nistp256@openssh.com", session->userauth_pblc_method_len) == 0 || strncmp((const char *)session->userauth_pblc_method, "sk-ssh-ed25519@openssh.com", session->userauth_pblc_method_len) == 0) { _libssh2_store_u32(&s, (uint32_t)(4 + session->userauth_pblc_method_len + sig_len)); _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, session->userauth_pblc_method_len); memcpy(s, sig, sig_len); s += sig_len; } else { _libssh2_store_u32(&s, (uint32_t)(4 + session->userauth_pblc_method_len + 4 + sig_len)); _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, session->userauth_pblc_method_len); _libssh2_store_str(&s, (const char *)sig, sig_len); } LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; LIBSSH2_FREE(session, sig); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Attempting publickey authentication -- phase 2")); session->userauth_pblc_s = s; session->userauth_pblc_state = libssh2_NB_state_sent2; } if(session->userauth_pblc_state == libssh2_NB_state_sent2) { rc = _libssh2_transport_send(session, session->userauth_pblc_packet, session->userauth_pblc_s - session->userauth_pblc_packet, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } else if(rc) { LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request"); } LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; session->userauth_pblc_state = libssh2_NB_state_sent3; } /* PK_OK is no longer valid */ reply_codes[2] = 0; rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_pblc_data, &session->userauth_pblc_data_len, 0, NULL, 0, &session->userauth_pblc_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting userauth list"); } else if(rc || session->userauth_pblc_data_len < 1) { session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Waiting for publickey USERAUTH response"); } if(session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Publickey authentication successful")); /* We are us and we've proved it. */ LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; session->userauth_pblc_state = libssh2_NB_state_idle; return 0; } /* This public key is not allowed for this user on this server */ LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad " "username/public key combination"); } /* * userauth_publickey_frommemory * Authenticate using a keypair from memory */ static int userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeydata, size_t publickeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) { unsigned char *pubkeydata = NULL; size_t pubkeydata_len = 0; struct privkey_file privkey_file; void *abstract = &privkey_file; int rc; privkey_file.filename = privatekeydata; privkey_file.passphrase = passphrase; if(session->userauth_pblc_state == libssh2_NB_state_idle) { if(publickeydata_len && publickeydata) { rc = memory_read_publickey(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len, publickeydata, publickeydata_len); if(rc) return rc; } else if(privatekeydata_len && privatekeydata) { /* Compute public key from private key. */ rc = _libssh2_pub_priv_keyfilememory(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len, privatekeydata, privatekeydata_len, passphrase); if(rc) return rc; } else { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid data in public and private key."); } } rc = _libssh2_userauth_publickey(session, username, username_len, pubkeydata, pubkeydata_len, sign_frommemory, &abstract); if(pubkeydata) LIBSSH2_FREE(session, pubkeydata); return rc; } /* * userauth_publickey_fromfile * Authenticate using a keypair found in the named files */ static int userauth_publickey_fromfile(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickey, const char *privatekey, const char *passphrase) { unsigned char *pubkeydata = NULL; size_t pubkeydata_len = 0; struct privkey_file privkey_file; void *abstract = &privkey_file; int rc; privkey_file.filename = privatekey; privkey_file.passphrase = passphrase; if(session->userauth_pblc_state == libssh2_NB_state_idle) { if(publickey) { rc = file_read_publickey(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len, publickey); if(rc) return rc; } else { /* Compute public key from private key. */ rc = _libssh2_pub_priv_keyfile(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len, privatekey, passphrase); /* _libssh2_pub_priv_keyfile calls _libssh2_error() */ if(rc) return rc; } } rc = _libssh2_userauth_publickey(session, username, username_len, pubkeydata, pubkeydata_len, sign_fromfile, &abstract); if(pubkeydata) LIBSSH2_FREE(session, pubkeydata); return rc; } /* libssh2_userauth_publickey_frommemory * Authenticate using a keypair from memory */ LIBSSH2_API int libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *user, size_t user_len, const char *publickeyfiledata, size_t publickeyfiledata_len, const char *privatekeyfiledata, size_t privatekeyfiledata_len, const char *passphrase) { int rc; if(!passphrase) /* if given a NULL pointer, make it point to a zero-length string to save us from having to check this all over */ passphrase = ""; BLOCK_ADJUST(rc, session, userauth_publickey_frommemory(session, user, user_len, publickeyfiledata, publickeyfiledata_len, privatekeyfiledata, privatekeyfiledata_len, passphrase)); return rc; } /* libssh2_userauth_publickey_fromfile_ex * Authenticate using a keypair found in the named files */ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *user, unsigned int user_len, const char *publickey, const char *privatekey, const char *passphrase) { int rc; if(!passphrase) /* if given a NULL pointer, make it point to a zero-length string to save us from having to check this all over */ passphrase = ""; BLOCK_ADJUST(rc, session, userauth_publickey_fromfile(session, user, user_len, publickey, privatekey, passphrase)); return rc; } /* libssh2_userauth_publickey_ex * Authenticate using an external callback function */ LIBSSH2_API int libssh2_userauth_publickey(LIBSSH2_SESSION *session, const char *user, const unsigned char *pubkeydata, size_t pubkeydata_len, LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC ((*sign_callback)), void **abstract) { int rc; if(!session) return LIBSSH2_ERROR_BAD_USE; BLOCK_ADJUST(rc, session, _libssh2_userauth_publickey(session, user, strlen(user), pubkeydata, pubkeydata_len, sign_callback, abstract)); return rc; } /* * userauth_keyboard_interactive * * Authenticate using a challenge-response authentication */ static int userauth_keyboard_interactive(LIBSSH2_SESSION * session, const char *username, unsigned int username_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC ((*response_callback))) { unsigned char *s; int rc; static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 }; unsigned int i; if(session->userauth_kybd_state == libssh2_NB_state_idle) { session->userauth_kybd_auth_name = NULL; session->userauth_kybd_auth_instruction = NULL; session->userauth_kybd_num_prompts = 0; session->userauth_kybd_auth_failure = 1; session->userauth_kybd_prompts = NULL; session->userauth_kybd_responses = NULL; /* Zero the whole thing out */ memset(&session->userauth_kybd_packet_requirev_state, 0, sizeof(session->userauth_kybd_packet_requirev_state)); session->userauth_kybd_packet_len = 1 /* byte SSH_MSG_USERAUTH_REQUEST */ + 4 + username_len /* string user name (ISO-10646 UTF-8, as defined in [RFC-3629]) */ + 4 + 14 /* string service name (US-ASCII) */ + 4 + 20 /* string "keyboard-interactive" (US-ASCII) */ + 4 + 0 /* string language tag (as defined in [RFC-3066]) */ + 4 + 0 /* string submethods (ISO-10646 UTF-8) */ ; session->userauth_kybd_data = s = LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); if(!s) { return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for " "keyboard-interactive authentication"); } *s++ = SSH_MSG_USERAUTH_REQUEST; /* user name */ _libssh2_store_str(&s, username, username_len); /* service name */ _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); /* "keyboard-interactive" */ _libssh2_store_str(&s, "keyboard-interactive", sizeof("keyboard-interactive") - 1); /* language tag */ _libssh2_store_u32(&s, 0); /* submethods */ _libssh2_store_u32(&s, 0); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Attempting keyboard-interactive authentication")); session->userauth_kybd_state = libssh2_NB_state_created; } if(session->userauth_kybd_state == libssh2_NB_state_created) { rc = _libssh2_transport_send(session, session->userauth_kybd_data, session->userauth_kybd_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } else if(rc) { LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; session->userauth_kybd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive" " request"); } LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; session->userauth_kybd_state = libssh2_NB_state_sent; } for(;;) { if(session->userauth_kybd_state == libssh2_NB_state_sent) { rc = _libssh2_packet_requirev(session, reply_codes, &session->userauth_kybd_data, &session->userauth_kybd_data_len, 0, NULL, 0, &session-> userauth_kybd_packet_requirev_state); if(rc == LIBSSH2_ERROR_EAGAIN) { return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); } else if(rc || session->userauth_kybd_data_len < 1) { session->userauth_kybd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, "Waiting for keyboard " "USERAUTH response"); } if(session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Keyboard-interactive " "authentication successful")); LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; session->userauth_kybd_state = libssh2_NB_state_idle; return 0; } if(session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) { _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Keyboard-interactive authentication failed")); LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; session->userauth_kybd_state = libssh2_NB_state_idle; return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, "Authentication failed " "(keyboard-interactive)"); } /* server requested PAM-like conversation */ if(userauth_keyboard_interactive_decode_info_request(session) < 0) { goto cleanup; } response_callback((const char *)session->userauth_kybd_auth_name, (int)session->userauth_kybd_auth_name_len, (const char *) session->userauth_kybd_auth_instruction, (int)session->userauth_kybd_auth_instruction_len, session->userauth_kybd_num_prompts, session->userauth_kybd_prompts, session->userauth_kybd_responses, &session->abstract); _libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Keyboard-interactive response callback function" " invoked")); session->userauth_kybd_packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ + 4 /* int num-responses */ ; for(i = 0; i < session->userauth_kybd_num_prompts; i++) { /* string response[1] (ISO-10646 UTF-8) */ if(session->userauth_kybd_responses[i].length <= (SIZE_MAX - 4 - session->userauth_kybd_packet_len)) { session->userauth_kybd_packet_len += 4 + session->userauth_kybd_responses[i].length; } else { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-" "interactive response packet"); goto cleanup; } } /* A new userauth_kybd_data area is to be allocated, free the former one. */ LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = s = LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); if(!s) { _libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-" "interactive response packet"); goto cleanup; } *s = SSH_MSG_USERAUTH_INFO_RESPONSE; s++; _libssh2_store_u32(&s, session->userauth_kybd_num_prompts); for(i = 0; i < session->userauth_kybd_num_prompts; i++) { _libssh2_store_str(&s, session->userauth_kybd_responses[i].text, session->userauth_kybd_responses[i].length); } session->userauth_kybd_state = libssh2_NB_state_sent1; } if(session->userauth_kybd_state == libssh2_NB_state_sent1) { rc = _libssh2_transport_send(session, session->userauth_kybd_data, session->userauth_kybd_packet_len, NULL, 0); if(rc == LIBSSH2_ERROR_EAGAIN) return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); if(rc) { _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-keyboard-interactive" " request"); goto cleanup; } session->userauth_kybd_auth_failure = 0; } cleanup: /* * It's safe to clean all the data here, because unallocated pointers * are filled by zeroes */ LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; if(session->userauth_kybd_prompts) { for(i = 0; i < session->userauth_kybd_num_prompts; i++) { LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text); session->userauth_kybd_prompts[i].text = NULL; } } if(session->userauth_kybd_responses) { for(i = 0; i < session->userauth_kybd_num_prompts; i++) { LIBSSH2_FREE(session, session->userauth_kybd_responses[i].text); session->userauth_kybd_responses[i].text = NULL; } } if(session->userauth_kybd_prompts) { LIBSSH2_FREE(session, session->userauth_kybd_prompts); session->userauth_kybd_prompts = NULL; } if(session->userauth_kybd_responses) { LIBSSH2_FREE(session, session->userauth_kybd_responses); session->userauth_kybd_responses = NULL; } if(session->userauth_kybd_auth_name) { LIBSSH2_FREE(session, session->userauth_kybd_auth_name); session->userauth_kybd_auth_name = NULL; } if(session->userauth_kybd_auth_instruction) { LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); session->userauth_kybd_auth_instruction = NULL; } if(session->userauth_kybd_auth_failure) { session->userauth_kybd_state = libssh2_NB_state_idle; return -1; } session->userauth_kybd_state = libssh2_NB_state_sent; } } /* * libssh2_userauth_keyboard_interactive_ex * * Authenticate using a challenge-response authentication */ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *user, unsigned int user_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC ((*response_callback))) { int rc; BLOCK_ADJUST(rc, session, userauth_keyboard_interactive(session, user, user_len, response_callback)); return rc; } /* * libssh2_userauth_publickey_sk * * Authenticate using an external callback function */ LIBSSH2_API int libssh2_userauth_publickey_sk(LIBSSH2_SESSION *session, const char *username, size_t username_len, const unsigned char *publickeydata, size_t publickeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase, LIBSSH2_USERAUTH_SK_SIGN_FUNC ((*sign_callback)), void **abstract) { int rc = LIBSSH2_ERROR_NONE; unsigned char *tmp_method = NULL; size_t tmp_method_len = 0; unsigned char *tmp_publickeydata = NULL; size_t tmp_publickeydata_len = 0; unsigned char *pubkeydata = NULL; size_t pubkeydata_len = 0; LIBSSH2_PRIVKEY_SK sk_info = { 0 }; void *sign_abstract = &sk_info; sk_info.sign_callback = sign_callback; sk_info.orig_abstract = abstract; if(privatekeydata_len && privatekeydata) { if(_libssh2_sk_pub_keyfilememory(session, &tmp_method, &tmp_method_len, &tmp_publickeydata, &tmp_publickeydata_len, &(sk_info.algorithm), &(sk_info.flags), &(sk_info.application), &(sk_info.key_handle), &(sk_info.handle_len), privatekeydata, privatekeydata_len, passphrase)) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key."); } else if(publickeydata_len == 0 || !publickeydata) { session->userauth_pblc_method = tmp_method; session->userauth_pblc_method_len = tmp_method_len; pubkeydata_len = tmp_publickeydata_len; pubkeydata = tmp_publickeydata; } else { const char *ecdsa = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"; const char *ed25519 = "sk-ssh-ed25519-cert-v01@openssh.com"; if(tmp_method) { LIBSSH2_FREE(session, tmp_method); } if(!strncmp((char *)publickeydata, ecdsa, strlen(ecdsa))) { session->userauth_pblc_method_len = strlen(ecdsa); session->userauth_pblc_method = LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); memcpy(session->userauth_pblc_method, ecdsa, session->userauth_pblc_method_len); } else if(!strncmp((char *)publickeydata, ed25519, strlen(ed25519))) { session->userauth_pblc_method_len = strlen(ed25519); session->userauth_pblc_method = LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); memcpy(session->userauth_pblc_method, ed25519, session->userauth_pblc_method_len); } rc = memory_read_publickey(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len, (char *)publickeydata, publickeydata_len); } } else { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid data in public and private key."); } if(rc == LIBSSH2_ERROR_NONE) { rc = _libssh2_userauth_publickey(session, username, username_len, pubkeydata, pubkeydata_len, libssh2_sign_sk, &sign_abstract); while(rc == LIBSSH2_ERROR_EAGAIN) { rc = _libssh2_userauth_publickey(session, username, username_len, pubkeydata, pubkeydata_len, libssh2_sign_sk, &sign_abstract); } } if(tmp_publickeydata) LIBSSH2_FREE(session, tmp_publickeydata); if(sk_info.application) { LIBSSH2_FREE(session, (void *)sk_info.application); } return rc; } libssh2-1.11.0/docs/0000755000175000017500000000000014435416503011076 500000000000000libssh2-1.11.0/docs/libssh2_channel_write_ex.30000644000175000017500000000375614424650606016063 00000000000000.TH libssh2_channel_write_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_write_ex - write data to a channel stream blocking .SH SYNOPSIS .nf #include ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen); .fi .SH DESCRIPTION Write data to a channel stream. All channel streams have one standard I/O substream (stream_id == 0), and may have up to 2^32 extended data streams as identified by the selected \fIstream_id\fP. The SSH2 protocol currently defines a stream ID of 1 to be the stderr substream. \fIchannel\fP - active channel stream to write to. \fIstream_id\fP - substream ID number (e.g. 0 or SSH_EXTENDED_DATA_STDERR) \fIbuf\fP - pointer to buffer to write \fIbuflen\fP - size of the data to write \fIlibssh2_channel_write(3)\fP and \fIlibssh2_channel_write_stderr(3)\fP are convenience macros for this function. \fIlibssh2_channel_write_ex(3)\fP will use as much as possible of the buffer and put it into a single SSH protocol packet. This means that to get maximum performance when sending larger files, you should try to always pass in at least 32K of data to this function. .SH RETURN VALUE Actual number of bytes written or negative on failure. LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_CHANNEL_CLOSED\fP - The channel has been closed. \fILIBSSH2_ERROR_CHANNEL_EOF_SENT\fP - The channel has been requested to be \fILIBSSH2_ERROR_BAD_USE\fP - This can be returned if you ignored a previous return for LIBSSH2_ERROR_EAGAIN and rather than sending the original buffer with the original size, you sent a new buffer with a different size. closed. .SH SEE ALSO .BR libssh2_channel_open_ex(3) .BR libssh2_channel_read_ex(3) libssh2-1.11.0/docs/libssh2_channel_write_stderr.30000644000175000017500000000117114424650606016737 00000000000000.TH libssh2_channel_write_stderr 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_write_stderr - convenience macro for \fIlibssh2_channel_write_ex(3)\fP .SH SYNOPSIS .nf #include ssize_t libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel, const char *buf, size_t buflen); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_write_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_write_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_write_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_write_ex(3) libssh2-1.11.0/docs/libssh2_publickey_add.30000644000175000017500000000144214424650606015332 00000000000000.TH libssh2_publickey_add 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_publickey_add - convenience macro for \fIlibssh2_publickey_add_ex(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_publickey_add(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, const unsigned char *blob, unsigned long blob_len, char overwrite, unsigned long num_attrs, const libssh2_publickey_attribute attrs[]); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_publickey_add_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_publickey_add_ex(3)\fP .SH ERRORS See \fIlibssh2_publickey_add_ex(3)\fP .SH SEE ALSO .BR libssh2_publickey_add_ex(3) libssh2-1.11.0/docs/libssh2_channel_read_ex.30000644000175000017500000000323314424650606015632 00000000000000.TH libssh2_channel_read_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_read_ex - read data from a channel stream .SH SYNOPSIS .nf #include ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen); ssize_t libssh2_channel_read(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen); ssize_t libssh2_channel_read_stderr(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen); .fi .SH DESCRIPTION Attempt to read data from an active channel stream. All channel streams have one standard I/O substream (stream_id == 0), and may have up to 2^32 extended data streams as identified by the selected \fIstream_id\fP. The SSH2 protocol currently defines a stream ID of 1 to be the stderr substream. \fIchannel\fP - active channel stream to read from. \fIstream_id\fP - substream ID number (e.g. 0 or SSH_EXTENDED_DATA_STDERR) \fIbuf\fP - pointer to storage buffer to read data into \fIbuflen\fP - size of the buf storage \fIlibssh2_channel_read(3)\fP and \fIlibssh2_channel_read_stderr(3)\fP are macros. .SH RETURN VALUE Actual number of bytes read or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. Note that a return value of zero (0) can in fact be a legitimate value and only signals that no payload data was read. It is not an error. .SH ERRORS \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_CHANNEL_CLOSED\fP - The channel has been closed. .SH SEE ALSO .BR libssh2_poll_channel_read(3) libssh2-1.11.0/docs/libssh2_channel_request_pty.30000644000175000017500000000115314424650606016606 00000000000000.TH libssh2_channel_request_pty 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_request_pty - convenience macro for \fIlibssh2_channel_request_pty_ex(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_channel_request_pty(LIBSSH2_SESSION *session, const char *term); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_request_pty_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_request_pty_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_request_pty_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_request_pty_ex(3) libssh2-1.11.0/docs/libssh2_session_startup.30000644000175000017500000000254014424650606016000 00000000000000.TH libssh2_session_startup 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_startup - begin transport layer .SH SYNOPSIS .nf #include int libssh2_session_startup(LIBSSH2_SESSION *session, int socket); .fi .SH DESCRIPTION Starting in libssh2 version 1.2.8 this function is considered deprecated. Use \fIlibssh2_session_handshake(3)\fP instead. \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIsocket\fP - Connected socket descriptor. Typically a TCP connection though the protocol allows for any reliable transport and the library will attempt to use any berkeley socket. Begin transport layer protocol negotiation with the connected host. .SH RETURN VALUE Returns 0 on success, negative on failure. .SH ERRORS \fILIBSSH2_ERROR_SOCKET_NONE\fP - The socket is invalid. \fILIBSSH2_ERROR_BANNER_SEND\fP - Unable to send banner to remote host. \fILIBSSH2_ERROR_KEX_FAILURE\fP - Encryption key exchange with the remote host failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_DISCONNECT\fP - The socket was disconnected. \fILIBSSH2_ERROR_PROTO\fP - An invalid SSH protocol response was received on the socket. \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO .BR libssh2_session_free(3) .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_scp_recv.30000644000175000017500000000175314424650606014344 00000000000000.TH libssh2_scp_recv 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_scp_recv - request a remote file via SCP .SH SYNOPSIS .nf #include LIBSSH2_CHANNEL * libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb); .fi .SH DESCRIPTION This function is \fBDEPRECATED\fP. Use \fIlibssh2_scp_recv2(3)\fP instead! \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIpath\fP - Full path and filename of file to transfer. That is the remote file name. \fIsb\fP - Populated with remote file's size, mode, mtime, and atime Request a file from the remote host via SCP. .SH RETURN VALUE Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SCP_PROTOCOL\fP - \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO .BR libssh2_session_init_ex(3) .BR libssh2_channel_open_ex(3) libssh2-1.11.0/docs/libssh2_channel_exec.30000644000175000017500000000113614424650606015147 00000000000000.TH libssh2_channel_exec 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_exec - convenience macro for \fIlibssh2_channel_process_startup(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_channel_exec(LIBSSH2_CHANNEL *channel, const char *command); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_process_startup(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_process_startup(3)\fP .SH ERRORS See \fIlibssh2_channel_process_startup(3)\fP .SH SEE ALSO .BR libssh2_channel_process_startup(3) libssh2-1.11.0/docs/libssh2_sftp_stat.30000644000175000017500000000114614424650606014543 00000000000000.TH libssh2_sftp_stat 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_stat - convenience macro for \fIlibssh2_sftp_fstat_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_fstat_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_fstat_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_fstat_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_fstat_ex(3) libssh2-1.11.0/docs/libssh2_channel_request_pty_ex.30000644000175000017500000000321414424650606017302 00000000000000.TH libssh2_channel_request_pty_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_request_pty_ex - short function description .SH SYNOPSIS .nf #include int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px); int libssh2_channel_request_pty(LIBSSH2_CHANNEL *channel, const char *term); .fi .SH DESCRIPTION \fIchannel\fP - Previously opened channel instance such as returned by .BR libssh2_channel_open_ex(3) \fIterm\fP - Terminal emulation (e.g. vt102, ansi, etc...) \fIterm_len\fP - Length of term parameter \fImodes\fP - Terminal mode modifier values \fImodes_len\fP - Length of modes parameter. \fIwidth\fP - Width of pty in characters \fIheight\fP - Height of pty in characters \fIwidth_px\fP - Width of pty in pixels \fIheight_px\fP - Height of pty in pixels Request a PTY on an established channel. Note that this does not make sense for all channel types and may be ignored by the server despite returning success. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP - .SH SEE ALSO .BR libssh2_channel_open_ex(3) libssh2-1.11.0/docs/libssh2_channel_read_stderr.30000644000175000017500000000116014424650606016516 00000000000000.TH libssh2_channel_read_stderr 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_read_stderr - convenience macro for \fIlibssh2_channel_read_ex(3)\fP calls .SH SYNOPSIS .nf #include ssize_t libssh2_channel_read_stderr(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_read_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_read_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_read_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_read_ex(3) libssh2-1.11.0/docs/libssh2_session_abstract.30000644000175000017500000000133214424650606016077 00000000000000.TH libssh2_session_abstract 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_abstract - return a pointer to a session's abstract pointer .SH SYNOPSIS .nf #include void ** libssh2_session_abstract(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) Return a pointer to where the abstract pointer provided to \fBlibssh2_session_init_ex(3)\fP is stored. By providing a doubly de-referenced pointer, the internal storage of the session instance may be modified in place. .SH RETURN VALUE A pointer to session internal storage whose contents point to previously provided abstract data. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_sftp_rename.30000644000175000017500000000122414424650606015034 00000000000000.TH libssh2_sftp_rename 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_rename - convenience macro for \fIlibssh2_sftp_rename_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename, const char *destination_filename); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_rename_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_rename_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_rename_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_rename_ex(3) libssh2-1.11.0/docs/libssh2_userauth_password_ex.30000644000175000017500000000426114424650606017013 00000000000000.TH libssh2_userauth_password_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_userauth_password_ex - authenticate a session with username and password .SH SYNOPSIS .nf #include int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))); #define libssh2_userauth_password(session, username, password) \\ libssh2_userauth_password_ex((session), (username), \\ strlen(username), \\ (password), strlen(password), NULL) .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIusername\fP - Name of user to attempt plain password authentication for. \fIusername_len\fP - Length of username parameter. \fIpassword\fP - Password to use for authenticating username. \fIpassword_len\fP - Length of password parameter. \fIpasswd_change_cb\fP - If the host accepts authentication but requests that the password be changed, this callback will be issued. If no callback is defined, but server required password change, authentication will fail. Attempt basic password authentication. Note that many SSH servers which appear to support ordinary password authentication actually have it disabled and use Keyboard Interactive authentication (routed via PAM or another authentication backed) instead. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS Some of the errors this function may return include: \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_PASSWORD_EXPIRED\fP - \fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/password or public/private key. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_userauth_hostbased_fromfile_ex.30000644000175000017500000000033014424650606021001 00000000000000.TH libssh2_userauth_hostbased_fromfile_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_userauth_hostbased_fromfile_ex - TODO .SH SYNOPSIS .nf .fi .SH DESCRIPTION .SH RETURN VALUE .SH ERRORS .SH SEE ALSO libssh2-1.11.0/docs/libssh2_publickey_add_ex.30000644000175000017500000000137514424650606016033 00000000000000.TH libssh2_publickey_add_ex 3 "1 Jun 2007" "libssh2" "libssh2" .SH NAME libssh2_publickey_add_ex - Add a public key entry .SH SYNOPSIS .nf #include int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len, char overwrite, unsigned long num_attrs, const libssh2_publickey_attribute attrs[]) .fi .SH DESCRIPTION TBD .SH RETURN VALUE Returns 0 on success, negative on failure. .SH ERRORS LIBSSH2_ERROR_BAD_USE LIBSSH2_ERROR_ALLOC, LIBSSH2_ERROR_EAGAIN LIBSSH2_ERROR_SOCKET_SEND, LIBSSH2_ERROR_SOCKET_TIMEOUT, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, .SH SEE ALSO libssh2-1.11.0/docs/libssh2_session_set_blocking.30000644000175000017500000000204314424650606016737 00000000000000.TH libssh2_session_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_set_blocking - set or clear blocking mode on session .SH SYNOPSIS .nf #include void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking); .fi .SH DESCRIPTION \fIsession\fP - session instance as returned by .BR libssh2_session_init_ex(3) \fIblocking\fP - Set to a non-zero value to make the channel block, or zero to make it non-blocking. Set or clear blocking mode on the selected on the session. This will instantly affect any channels associated with this session. If a read is performed on a session with no data currently available, a blocking session will wait for data to arrive and return what it receives. A non-blocking session will return immediately with an empty buffer. If a write is performed on a session with no room for more data, a blocking session will wait for room. A non-blocking session will return immediately without writing anything. .SH RETURN VALUE None .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_sftp_unlink_ex.30000644000175000017500000000233214424650606015562 00000000000000.TH libssh2_sftp_unlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_unlink_ex - unlink an SFTP file .SH SYNOPSIS .nf #include #include int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len); int libssh2_sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) \fIfilename\fP - Path and name of the existing filesystem entry \fIfilename_len\fP - Length of the path and name of the existing filesystem entry Unlink (delete) a file from the remote filesystem. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. .SH SEE ALSO .BR libssh2_sftp_init(3) libssh2-1.11.0/docs/libssh2_agent_get_identity.30000644000175000017500000000224514424650606016403 00000000000000.\" .\" Copyright (c) 2009 by Daiki Ueno .\" .TH libssh2_agent_get_identity 3 "23 Dec 2009" "libssh2" "libssh2" .SH NAME libssh2_agent_get_identity - get a public key off the collection of public keys managed by ssh-agent .SH SYNOPSIS .nf #include int libssh2_agent_get_identity(LIBSSH2_AGENT *agent, struct libssh2_agent_publickey **store, struct libssh2_agent_publickey *prev); .fi .SH DESCRIPTION \fIlibssh2_agent_get_identity(3)\fP allows an application to iterate over all public keys in the collection managed by ssh-agent. \fIstore\fP should point to a pointer that gets filled in to point to the public key data. \fIprev\fP is a pointer to a previous 'struct libssh2_agent_publickey' as returned by a previous invoke of this function, or NULL to get the first entry in the internal collection. .SH RETURN VALUE Returns 0 if everything is fine and information about a host was stored in the \fIstore\fP struct. Returns 1 if it reached the end of public keys. Returns negative values for error .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_agent_list_identities(3) .BR libssh2_agent_userauth(3) libssh2-1.11.0/docs/libssh2_agent_set_identity_path.30000644000175000017500000000107514424650606017433 00000000000000.\" .\" Copyright (c) 2019 by Will Cosgrove .\" .TH libssh2_agent_set_identity_path 3 "6 Mar 2019" "libssh2" "libssh2" .SH NAME libssh2_agent_set_identity_path - set an ssh-agent socket path on disk .SH SYNOPSIS .nf #include void libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, const char *path); .fi .SH DESCRIPTION Allows a custom agent identity socket path instead of the default SSH_AUTH_SOCK env value .SH RETURN VALUE Returns void .SH AVAILABILITY Added in libssh2 1.9 .SH SEE ALSO .BR libssh2_agent_init(3) .BR libssh2_agent_get_identity_path(3) libssh2-1.11.0/docs/libssh2_sftp_open_ex.30000644000175000017500000000455014424650606015227 00000000000000.TH libssh2_sftp_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_open_ex - open filehandle for file on SFTP. .SH SYNOPSIS .nf #include #include LIBSSH2_SFTP_HANDLE * libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP \fIfilename\fP - Remote file/directory resource to open \fIfilename_len\fP - Length of filename \fIflags\fP - Any reasonable combination of the LIBSSH2_FXF_* constants: .RS .IP LIBSSH2_FXF_READ Open the file for reading. .IP LIBSSH2_FXF_WRITE Open the file for writing. If both this and LIBSSH2_FXF_READ are specified, the file is opened for both reading and writing. .IP LIBSSH2_FXF_APPEND Force all writes to append data at the end of the file. .IP LIBSSH2_FXF_CREAT, If this flag is specified, then a new file will be created if one does not already exist (if LIBSSH2_FXF_TRUNC is specified, the new file will be truncated to zero length if it previously exists) .IP LIBSSH2_FXF_TRUNC Forces an existing file with the same name to be truncated to zero length when creating a file by specifying LIBSSH2_FXF_CREAT. LIBSSH2_FXF_CREAT MUST also be specified if this flag is used. .IP LIBSSH2_FXF_EXCL Causes the request to fail if the named file already exists. LIBSSH2_FXF_CREAT MUST also be specified if this flag is used. .RE \fImode\fP - POSIX file permissions to assign if the file is being newly created. See the LIBSSH2_SFTP_S_* convenience defines in \fIopen_type\fP - Either of LIBSSH2_SFTP_OPENFILE (to open a file) or LIBSSH2_SFTP_OPENDIR (to open a directory). .SH RETURN VALUE A pointer to the newly created LIBSSH2_SFTP_HANDLE instance or NULL on failure. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO .BR libssh2_sftp_close_handle(3) libssh2-1.11.0/docs/libssh2_agent_userauth.30000644000175000017500000000164114424650606015552 00000000000000.\" .\" Copyright (c) 2009 by Daiki Ueno .\" .TH libssh2_agent_userauth 3 "23 Dec 2009" "libssh2" "libssh2" .SH NAME libssh2_agent_userauth - authenticate a session with a public key, with the help of ssh-agent .SH SYNOPSIS .nf #include int libssh2_agent_userauth(LIBSSH2_AGENT *agent, const char *username, struct libssh2_agent_publickey *identity); .fi .SH DESCRIPTION \fIagent\fP - ssh-agent handle as returned by .BR libssh2_agent_init(3) \fIusername\fP - Remote user name to authenticate as. \fIidentity\fP - Public key to authenticate with, as returned by .BR libssh2_agent_get_identity(3) Attempt public key authentication with the help of ssh-agent. .SH RETURN VALUE Returns 0 if succeeded, or a negative value for error. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_agent_init(3) .BR libssh2_agent_get_identity(3) .BR libssh2_agent_sign(3) libssh2-1.11.0/docs/libssh2_channel_setenv_ex.30000644000175000017500000000270614424650606016227 00000000000000.TH libssh2_channel_setenv_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_setenv_ex - set an environment variable on the channel .SH SYNOPSIS .nf #include int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, unsigned int value_len); int libssh2_channel_setenv(LIBSSH2_CHANNEL *channel, char *varname, const char *value); .fi .SH DESCRIPTION \fIchannel\fP - Previously opened channel instance such as returned by .BR libssh2_channel_open_ex(3) \fIvarname\fP - Name of environment variable to set on the remote channel instance. \fIvarname_len\fP - Length of passed varname parameter. \fIvalue\fP - Value to set varname to. \fIvalue_len\fP - Length of value parameter. Set an environment variable in the remote channel's process space. Note that this does not make sense for all channel types and may be ignored by the server despite returning success. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP - .SH SEE ALSO .BR libssh2_channel_open_ex(3) libssh2-1.11.0/docs/libssh2_poll.30000644000175000017500000000170714424650606013505 00000000000000.TH libssh2_poll 3 "14 Dec 2006" "libssh2 0.15" "libssh2" .SH NAME libssh2_poll - poll for activity on a socket, channel or listener .SH SYNOPSIS .nf #include int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout); .fi .SH DESCRIPTION This function is deprecated. Do note use. We encourage users to instead use the \fIpoll(3)\fP or \fIselect(3)\fP functions to check for socket activity or when specific sockets are ready to get received from or send to. Poll for activity on a socket, channel, listener, or any combination of these three types. The calling semantics for this function generally match \fIpoll(2)\fP however the structure of fds is somewhat more complex in order to accommodate the disparate datatypes, POLLFD constants have been namespaced to avoid platform discrepancies, and revents has additional values defined. .SH "RETURN VALUE" Number of fds with interesting events. .SH SEE ALSO .BR libssh2_poll_channel_read(3) libssh2-1.11.0/docs/libssh2_sftp_shutdown.30000644000175000017500000000122714424650606015443 00000000000000.TH libssh2_sftp_shutdown 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_shutdown - shut down an SFTP session .SH SYNOPSIS .nf #include #include int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) Destroys a previously initialized SFTP session and frees all resources associated with it. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH SEE ALSO .BR libssh2_sftp_init(3) libssh2-1.11.0/docs/libssh2_sftp_rmdir_ex.30000644000175000017500000000224714424650606015404 00000000000000.TH libssh2_sftp_rmdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_rmdir_ex - remove an SFTP directory .SH SYNOPSIS .nf #include #include int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len); .fi .SH DESCRIPTION Remove a directory from the remote file system. \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) \fIsourcefile\fP - Full path of the existing directory to remove. \fIsourcefile_len\fP - Length of the full path of the existing directory to remove. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. .SH SEE ALSO .BR libssh2_sftp_init(3) libssh2-1.11.0/docs/libssh2_channel_flush_stderr.30000644000175000017500000000107614424650606016732 00000000000000.TH libssh2_channel_flush_stderr 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_flush_stderr - convenience macro for \fIlibssh2_channel_flush_ex(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_channel_flush_stderr(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_flush_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_flush_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_flush_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_flush_ex(3) libssh2-1.11.0/docs/libssh2_base64_decode.30000644000175000017500000000170014424650606015117 00000000000000.TH libssh2_base64_decode 3 "23 Dec 2008" "libssh2 1.0" "libssh2" .SH NAME libssh2_base64_decode - decode a base64 encoded string .SH SYNOPSIS .nf #include int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, unsigned int *dest_len, const char *src, unsigned int src_len); .fi .SH DESCRIPTION This function is deemed DEPRECATED and will be removed from libssh2 in a future version. Do not use it! Decode a base64 chunk and store it into a newly allocated buffer. 'dest_len' will be set to hold the length of the returned buffer that '*dest' will point to. The returned buffer is allocated by this function, but it is not clear how to free that memory! .SH BUGS The memory that *dest points to is allocated by the malloc function libssh2 uses, but there is no way for an application to free this data in a safe and reliable way! .SH RETURN VALUE 0 if successful, \-1 if any error occurred. libssh2-1.11.0/docs/libssh2_session_set_timeout.30000644000175000017500000000121014424650606016630 00000000000000.TH libssh2_session_set_timeout 3 "4 May 2011" "libssh2" "libssh2" .SH NAME libssh2_session_set_timeout - set timeout for blocking functions .SH SYNOPSIS .nf #include void libssh2_session_set_timeout(LIBSSH2_SESSION *session, long timeout); .fi .SH DESCRIPTION Set the \fBtimeout\fP in milliseconds for how long a blocking the libssh2 function calls may wait until they consider the situation an error and return LIBSSH2_ERROR_TIMEOUT. By default or if you set the timeout to zero, libssh2 has no timeout for blocking functions. .SH RETURN VALUE Nothing .SH AVAILABILITY Added in 1.2.9 .SH SEE ALSO .BR libssh2_session_get_timeout(3) libssh2-1.11.0/docs/libssh2_sftp_fstat_ex.30000644000175000017500000000674114424650606015413 00000000000000.TH libssh2_sftp_fstat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_fstat_ex - get or set attributes on an SFTP file handle .SH SYNOPSIS .nf #include #include int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) #define libssh2_sftp_fstat(handle, attrs) \\ libssh2_sftp_fstat_ex((handle), (attrs), 0) #define libssh2_sftp_fsetstat(handle, attrs) \\ libssh2_sftp_fstat_ex((handle), (attrs), 1) .fi .SH DESCRIPTION \fIhandle\fP - SFTP File Handle as returned by .BR libssh2_sftp_open_ex(3) \fIattrs\fP - Pointer to an LIBSSH2_SFTP_ATTRIBUTES structure to set file metadata from or into depending on the value of setstat. \fIsetstat\fP - When non-zero, the file's metadata will be updated with the data found in attrs according to the values of attrs->flags and other relevant member attributes. Get or Set statbuf type data for a given LIBSSH2_SFTP_HANDLE instance. .SH DATA TYPES LIBSSH2_SFTP_ATTRIBUTES is a typedefed struct that is defined as below .nf struct _LIBSSH2_SFTP_ATTRIBUTES { /* If flags & ATTR_* bit is set, then the value in this * struct will be meaningful Otherwise it should be ignored */ unsigned long flags; /* size of file, in bytes */ libssh2_uint64_t filesize; /* numerical representation of the user and group owner of * the file */ unsigned long uid, gid; /* bitmask of permissions */ unsigned long permissions; /* access time and modified time of file */ unsigned long atime, mtime; }; .fi You will find a full set of defines and macros to identify flags and permissions on the \fBlibssh2_sftp.h\fP header file, but some of the most common ones are: To check for specific user permissions, the set of defines are in the pattern LIBSSH2_SFTP_S_I where is R, W or X for read, write and executable and is USR, GRP and OTH for user, group and other. So, you check for a user readable file, use the bit \fILIBSSH2_SFTP_S_IRUSR\fP while you want to see if it is executable for other, you use \fILIBSSH2_SFTP_S_IXOTH\fP and so on. To check for specific file types, you would previously (before libssh2 1.2.5) use the standard posix S_IS***() macros, but since 1.2.5 libssh2 offers its own set of macros for this functionality: .IP LIBSSH2_SFTP_S_ISLNK Test for a symbolic link .IP LIBSSH2_SFTP_S_ISREG Test for a regular file .IP LIBSSH2_SFTP_S_ISDIR Test for a directory .IP LIBSSH2_SFTP_S_ISCHR Test for a character special file .IP LIBSSH2_SFTP_S_ISBLK Test for a block special file .IP LIBSSH2_SFTP_S_ISFIFO Test for a pipe or FIFO special file .IP LIBSSH2_SFTP_S_ISSOCK Test for a socket .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. .SH AVAILABILITY This function has been around since forever, but most of the LIBSSH2_SFTP_S_* defines were introduced in libssh2 0.14 and the LIBSSH2_SFTP_S_IS***() macros were introduced in libssh2 1.2.5. .SH SEE ALSO .BR libssh2_sftp_open_ex(3) libssh2-1.11.0/docs/libssh2_knownhost_addc.30000644000175000017500000000514514424650606015544 00000000000000.\" .\" Copyright (c) 2009, 2010 by Daniel Stenberg .\" .TH libssh2_knownhost_addc 3 "28 May 2009" "libssh2 1.2" "libssh2" .SH NAME libssh2_knownhost_addc - add a known host .SH SYNOPSIS .nf #include int libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, char *host, char *salt, char *key, size_t keylen, const char *comment, size_t commentlen, int typemask, struct libssh2_knownhost **store); .fi .SH DESCRIPTION Adds a known host to the collection of known hosts identified by the 'hosts' handle. \fIhost\fP is a pointer the host name in plain text or hashed. If hashed, it must be provided base64 encoded. The host name can be the IP numerical address of the host or the full name. If you want to add a key for a specific port number for the given host, you must provide the host name like '[host]:port' with the actual characters '[' and ']' enclosing the host name and a colon separating the host part from the port number. For example: \&"[host.example.com]:222". \fIsalt\fP is a pointer to the salt used for the host hashing, if the host is provided hashed. If the host is provided in plain text, salt has no meaning. The salt has to be provided base64 encoded with a trailing zero byte. \fIkey\fP is a pointer to the key for the given host. \fIkeylen\fP is the total size in bytes of the key pointed to by the \fIkey\fP argument \fIcomment\fP is a pointer to a comment for the key. \fIcommentlen\fP is the total size in bytes of the comment pointed to by the \fIcomment\fP argument \fItypemask\fP is a bitmask that specifies format and info about the data passed to this function. Specifically, it details what format the host name is, what format the key is and what key type it is. The host name is given as one of the following types: LIBSSH2_KNOWNHOST_TYPE_PLAIN, LIBSSH2_KNOWNHOST_TYPE_SHA1 or LIBSSH2_KNOWNHOST_TYPE_CUSTOM. The key is encoded using one of the following encodings: LIBSSH2_KNOWNHOST_KEYENC_RAW or LIBSSH2_KNOWNHOST_KEYENC_BASE64. The key is using one of these algorithms: LIBSSH2_KNOWNHOST_KEY_RSA1, LIBSSH2_KNOWNHOST_KEY_SSHRSA or LIBSSH2_KNOWNHOST_KEY_SSHDSS. \fIstore\fP should point to a pointer that gets filled in to point to the known host data after the addition. NULL can be passed if you do not care about this pointer. .SH RETURN VALUE Returns a regular libssh2 error code, where negative values are error codes and 0 indicates success. .SH AVAILABILITY Added in libssh2 1.2.5 .SH SEE ALSO .BR libssh2_knownhost_init(3) .BR libssh2_knownhost_free(3) .BR libssh2_knownhost_check(3) libssh2-1.11.0/docs/libssh2_session_supported_algs.30000644000175000017500000000524214424650606017333 00000000000000.TH libssh2_session_supported_algs 3 "23 Oct 2011" "libssh2" "libssh2" .SH NAME libssh2_session_supported_algs - get list of supported algorithms .SH SYNOPSIS .nf #include int libssh2_session_supported_algs(LIBSSH2_SESSION* session, int method_type, const char*** algs); .fi .SH DESCRIPTION \fIsession\fP - An instance of initialized LIBSSH2_SESSION (the function will use its pointer to the memory allocation function). \fImethod_type\fP - Method type. See \fIlibssh2_session_method_pref(3)\fP. \fIalgs\fP - Address of a pointer that will point to an array of returned algorithms Get a list of supported algorithms for the given \fImethod_type\fP. The method_type parameter is equivalent to method_type in \fIlibssh2_session_method_pref(3)\fP. If successful, the function will allocate the appropriate amount of memory. When not needed anymore, it must be deallocated by calling \fIlibssh2_free(3)\fP. When this function is unsuccessful, this must not be done. In order to get a list of all supported compression algorithms, libssh2_session_flag(session, LIBSSH2_FLAG_COMPRESS, 1) must be called before calling this function, otherwise only "none" will be returned. If successful, the function will allocate and fill the array with supported algorithms (the same names as defined in RFC 4253). The array is not NULL terminated. .SH EXAMPLE .nf #include "libssh2.h" const char **algorithms; int rc, i; LIBSSH2_SESSION *session; /* initialize session */ session = libssh2_session_init(); rc = libssh2_session_supported_algs(session, LIBSSH2_METHOD_CRYPT_CS, &algorithms); if(rc > 0) { /* the call succeeded, do sth. with the list of algorithms (e.g. list them)... */ printf("Supported symmetric algorithms:\\n"); for(i = 0; i < rc; i++) printf("\\t%s\\n", algorithms[i]); /* ... and free the allocated memory when not needed anymore */ libssh2_free(session, algorithms); } else { /* call failed, error handling */ } .fi .SH RETURN VALUE On success, a number of returned algorithms (i.e a positive number will be returned). In case of a failure, an error code (a negative number, see below) is returned. 0 should never be returned. .SH ERRORS \fILIBSSH2_ERROR_BAD_USE\fP - Invalid address of algs. \fILIBSSH2_ERROR_METHOD_NOT_SUPPORTED\fP - Unknown method type. \fILIBSSH2_ERROR_INVAL\fP - Internal error (normally should not occur). \fILIBSSH2_ERROR_ALLOC\fP - Allocation of memory failed. .SH AVAILABILITY Added in 1.4.0 .SH SEE ALSO .BR libssh2_session_methods(3), .BR libssh2_session_method_pref(3) .BR libssh2_free(3) libssh2-1.11.0/docs/libssh2_session_get_blocking.30000644000175000017500000000067714424650606016736 00000000000000.TH libssh2_session_get_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_get_blocking - TODO .SH SYNOPSIS .nf #include int libssh2_session_get_blocking(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION Returns 0 if the state of the session has previously be set to non-blocking and it returns 1 if the state was set to blocking. .SH RETURN VALUE See description. .SH SEE ALSO .BR libssh2_session_set_blocking(3) libssh2-1.11.0/docs/libssh2_sftp_fstatvfs.30000644000175000017500000000004011376575676015440 00000000000000.so man3/libssh2_sftp_statvfs.3 libssh2-1.11.0/docs/libssh2_userauth_password.30000644000175000017500000000125114424650606016313 00000000000000.TH libssh2_userauth_password 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_userauth_password - convenience macro for \fIlibssh2_userauth_password_ex(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_userauth_password(LIBSSH2_SESSION *session, const char *username, const char *password); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_userauth_password_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_userauth_password_ex(3)\fP .SH ERRORS See \fIlibssh2_userauth_password_ex(3)\fP .SH SEE ALSO .BR libssh2_userauth_password_ex(3) libssh2-1.11.0/docs/libssh2_crypto_engine.30000644000175000017500000000051214424650606015375 00000000000000.TH libssh2_crypto_engine 3 "22 Nov 2021" "libssh2" "libssh2" .SH NAME libssh2_crypto_engine - retrieve used crypto engine .SH SYNOPSIS .nf #include libssh2_crypto_engine_t libssh2_crypto_engine(void); .fi .SH DESCRIPTION Returns currently used crypto engine, as en enum value. .SH AVAILABILITY Added in libssh2 1.11 libssh2-1.11.0/docs/libssh2_sftp_open_ex_r.30000644000175000017500000000512214424650606015544 00000000000000.TH libssh2_sftp_open_ex_r 3 "10 Apr 2023" "libssh2" "libssh2" .SH NAME libssh2_sftp_open_ex_r - open filehandle for file on SFTP. .SH SYNOPSIS .nf #include #include LIBSSH2_SFTP_HANDLE * libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp, const char *filename, size_t filename_len, unsigned long flags, long mode, int open_type, LIBSSH2_SFTP_ATTRIBUTES *attrs); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP \fIfilename\fP - Remote file/directory resource to open \fIfilename_len\fP - Length of filename \fIflags\fP - Any reasonable combination of the LIBSSH2_FXF_* constants: .RS .IP LIBSSH2_FXF_READ Open the file for reading. .IP LIBSSH2_FXF_WRITE Open the file for writing. If both this and LIBSSH2_FXF_READ are specified, the file is opened for both reading and writing. .IP LIBSSH2_FXF_APPEND Force all writes to append data at the end of the file. .IP LIBSSH2_FXF_CREAT, If this flag is specified, then a new file will be created if one does not already exist (if LIBSSH2_FXF_TRUNC is specified, the new file will be truncated to zero length if it previously exists) .IP LIBSSH2_FXF_TRUNC Forces an existing file with the same name to be truncated to zero length when creating a file by specifying LIBSSH2_FXF_CREAT. LIBSSH2_FXF_CREAT MUST also be specified if this flag is used. .IP LIBSSH2_FXF_EXCL Causes the request to fail if the named file already exists. LIBSSH2_FXF_CREAT MUST also be specified if this flag is used. .RE \fImode\fP - POSIX file permissions to assign if the file is being newly created. See the LIBSSH2_SFTP_S_* convenience defines in \fIopen_type\fP - Either of LIBSSH2_SFTP_OPENFILE (to open a file) or LIBSSH2_SFTP_OPENDIR (to open a directory). \fIattrs\fP - Pointer to LIBSSH2_SFTP_ATTRIBUTES struct. See libssh2_sftp_fstat_ex for detailed usage. .SH RETURN VALUE A pointer to the newly created LIBSSH2_SFTP_HANDLE instance or NULL on failure. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH AVAILABILITY Added in libssh2 1.11.0 .SH SEE ALSO .BR libssh2_sftp_close_handle(3) .BR libssh2_sftp_fstat_ex(3) libssh2-1.11.0/docs/libssh2_sftp_rewind.30000644000175000017500000000104714424650606015060 00000000000000.TH libssh2_sftp_rewind 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_rewind - convenience macro for \fIlibssh2_sftp_seek64(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_rewind(LIBSSH2_SFTP_HANDLE *handle); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_seek64(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_seek64(3)\fP .SH ERRORS See \fIlibssh2_sftp_seek64(3)\fP .SH SEE ALSO .BR libssh2_sftp_seek64(3) libssh2-1.11.0/docs/libssh2_channel_flush_ex.30000644000175000017500000000202514424650606016036 00000000000000.TH libssh2_channel_flush_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_flush_ex - flush a channel .SH SYNOPSIS .nf #include int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid); int libssh2_channel_flush(LIBSSH2_CHANNEL *channel); int libssh2_channel_flush_stderr(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION \fIchannel\fP - Active channel stream to flush. \fIstreamid\fP - Specific substream number to flush. Groups of substreams may be flushed by passing on of the following Constants. .br \fBLIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA\fP: Flush all extended data substreams .br \fBLIBSSH2_CHANNEL_FLUSH_ALL\fP: Flush all substreams Flush the read buffer for a given channel instance. Individual substreams may be flushed by number or using one of the provided macros. .SH RETURN VALUE Return the number of bytes flushed or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. libssh2-1.11.0/docs/libssh2_channel_window_read_ex.30000644000175000017500000000170714424650606017225 00000000000000.TH libssh2_channel_window_read_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_window_read_ex - Check the status of the read window .SH SYNOPSIS .nf #include unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial) .fi .SH DESCRIPTION Check the status of the read window. Returns the number of bytes which the remote end may send without overflowing the window limit read_avail (if passed) will be populated with the number of bytes actually available to be read window_size_initial (if passed) will be populated with the window_size_initial as defined by the channel_open request .SH RETURN VALUE The number of bytes which the remote end may send without overflowing the window limit .SH ERRORS .SH SEE ALSO .BR libssh2_channel_receive_window_adjust(3), .BR libssh2_channel_window_write_ex(3) libssh2-1.11.0/docs/libssh2_publickey_remove.30000644000175000017500000000133014424650606016073 00000000000000.TH libssh2_publickey_remove 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_publickey_remove - convenience macro for \fIlibssh2_publickey_remove_ex(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_publickey_remove(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_publickey_remove_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_publickey_remove_ex(3)\fP .SH ERRORS See \fIlibssh2_publickey_remove_ex(3)\fP .SH SEE ALSO .BR libssh2_publickey_remove_ex(3) libssh2-1.11.0/docs/libssh2_userauth_publickey_fromfile_ex.30000644000175000017500000000347414424650606021030 00000000000000.TH libssh2_userauth_publickey_fromfile_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_userauth_publickey_fromfile_ex - authenticate a session with a public key, read from a file .SH SYNOPSIS .nf #include int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *publickey, const char *privatekey, const char *passphrase); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by \fBlibssh2_session_init_ex(3)\fP \fIusername\fP - Pointer to user name to authenticate as. \fIusername_len\fP - Length of \fIusername\fP. \fIpublickey\fP - Path name of the public key file. (e.g. /etc/ssh/hostkey.pub). If libssh2 is built against OpenSSL, this option can be set to NULL. \fIprivatekey\fP - Path name of the private key file. (e.g. /etc/ssh/hostkey) \fIpassphrase\fP - Passphrase to use when decoding \fIprivatekey\fP. Attempt public key authentication using a PEM encoded private key file stored on disk .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key combination was invalid. \fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the supplied public key was not accepted. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_scp_recv2.30000644000175000017500000000164414424650606014425 00000000000000.TH libssh2_scp_recv2 3 "29 Jun 2015" "libssh2 1.6.1" "libssh2" .SH NAME libssh2_scp_recv2 - request a remote file via SCP .SH SYNOPSIS .nf #include LIBSSH2_CHANNEL * libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, struct_stat *sb); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIpath\fP - Full path and filename of file to transfer. That is the remote file name. \fIsb\fP - Populated with remote file's size, mode, mtime, and atime Request a file from the remote host via SCP. .SH RETURN VALUE Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SCP_PROTOCOL\fP - \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO .BR libssh2_session_init_ex(3) .BR libssh2_channel_open_ex(3) libssh2-1.11.0/docs/libssh2_session_free.30000644000175000017500000000123114424650606015213 00000000000000.TH libssh2_session_free 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_free - frees resources associated with a session instance .SH SYNOPSIS .nf #include int libssh2_session_free(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION Frees all resources associated with a session instance. Typically called after .BR libssh2_session_disconnect_ex(3) .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH SEE ALSO .BR libssh2_session_init_ex(3) .BR libssh2_session_disconnect_ex(3) libssh2-1.11.0/docs/libssh2_agent_list_identities.30000644000175000017500000000126114424650606017104 00000000000000.\" .\" Copyright (c) 2009 by Daiki Ueno .\" .TH libssh2_agent_list_identities 3 "23 Dec 2009" "libssh2" "libssh2" .SH NAME libssh2_agent_list_identities - request an ssh-agent to list of public keys. .SH SYNOPSIS .nf #include int libssh2_agent_list_identities(LIBSSH2_AGENT *agent); .fi .SH DESCRIPTION Request an ssh-agent to list of public keys, and stores them in the internal collection of the handle. Call \fIlibssh2_agent_get_identity(3)\fP to get a public key off the collection. .SH RETURN VALUE Returns 0 if succeeded, or a negative value for error. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_agent_connect(3) .BR libssh2_agent_get_identity(3) libssh2-1.11.0/docs/libssh2_agent_connect.30000644000175000017500000000112214424650606015335 00000000000000.\" .\" Copyright (c) 2009 by Daiki Ueno .\" .TH libssh2_agent_connect 3 "23 Dec 2009" "libssh2" "libssh2" .SH NAME libssh2_agent_connect - connect to an ssh-agent .SH SYNOPSIS .nf #include int libssh2_agent_connect(LIBSSH2_AGENT *agent); .fi .SH DESCRIPTION Connect to an ssh-agent running on the system. Call \fBlibssh2_agent_disconnect(3)\fP to close the connection after you are doing using it. .SH RETURN VALUE Returns 0 if succeeded, or a negative value for error. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_agent_init(3) .BR libssh2_agent_disconnect(3) libssh2-1.11.0/docs/libssh2_keepalive_config.30000644000175000017500000000163014424650606016024 00000000000000.TH libssh2_keepalive_config 3 "12 Apr 2011" "libssh2" "libssh2" .SH NAME libssh2_keepalive_config - short function description .SH SYNOPSIS .nf #include void libssh2_keepalive_config(LIBSSH2_SESSION *session, int want_reply, unsigned interval); .fi .SH DESCRIPTION Set how often keepalive messages should be sent. \fBwant_reply\fP indicates whether the keepalive messages should request a response from the server. \fBinterval\fP is number of seconds that can pass without any I/O, use 0 (the default) to disable keepalives. To avoid some busy-loop corner-cases, if you specify an interval of 1 it will be treated as 2. Note that non-blocking applications are responsible for sending the keepalive messages using \fBlibssh2_keepalive_send(3)\fP. .SH RETURN VALUE Nothing .SH AVAILABILITY Added in libssh2 1.2.5 .SH SEE ALSO .BR libssh2_keepalive_send(3) libssh2-1.11.0/docs/libssh2_knownhost_free.30000644000175000017500000000075514424650606015574 00000000000000.\" .\" Copyright (c) 2009 by Daniel Stenberg .\" .TH libssh2_knownhost_free 3 "28 May 2009" "libssh2" "libssh2" .SH NAME libssh2_knownhost_free - free a collection of known hosts .SH SYNOPSIS .nf #include void libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts); .fi .SH DESCRIPTION Free a collection of known hosts. .SH RETURN VALUE None. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_knownhost_init(3) .BR libssh2_knownhost_add(3) .BR libssh2_knownhost_check(3) libssh2-1.11.0/docs/libssh2_channel_receive_window_adjust.30000644000175000017500000000237414424650606020613 00000000000000.TH libssh2_channel_receive_window_adjust 3 "15 Mar 2009" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_receive_window_adjust - adjust the channel window .SH SYNOPSIS .nf #include unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, unsigned long adjustment, unsigned char force); .fi .SH DESCRIPTION This function is deprecated in 1.1. Use \fIlibssh2_channel_receive_window_adjust2(3)\fP! Adjust the receive window for a channel by adjustment bytes. If the amount to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the adjustment amount will be queued for a later packet. .SH RETURN VALUE Returns the new size of the receive window (as understood by remote end). Note that the window value sent over the wire is strictly 32bit, but this API is made to return a 'long' which may not be 32 bit on all platforms. .SH ERRORS In 1.0 and earlier, this function returns LIBSSH2_ERROR_EAGAIN for non-blocking channels where it would otherwise block. However, that is a negative number and this function only returns an unsigned value and this then leads to a very strange value being returned. .SH SEE ALSO .BR libssh2_channel_window_read_ex(3) libssh2-1.11.0/docs/Makefile.in0000644000175000017500000005344714424651703013101 00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = docs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" NROFF = nroff MANS = $(dist_man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in AUTHORS TODO DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@ HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBWOLFSSL = @HAVE_LIBWOLFSSL@ HAVE_LIBZ = @HAVE_LIBZ@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBCRYPT = @LIBBCRYPT@ LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSREQUIRED = @LIBSREQUIRED@ LIBSSH2VER = @LIBSSH2VER@ LIBSSL = @LIBSSL@ LIBSSL_PREFIX = @LIBSSL_PREFIX@ LIBTOOL = @LIBTOOL@ LIBWOLFSSL = @LIBWOLFSSL@ LIBWOLFSSL_PREFIX = @LIBWOLFSSL_PREFIX@ LIBZ = @LIBZ@ LIBZ_PREFIX = @LIBZ_PREFIX@ LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@ LTLIBOBJS = @LTLIBOBJS@ LTLIBSSL = @LTLIBSSL@ LTLIBWOLFSSL = @LTLIBWOLFSSL@ LTLIBZ = @LTLIBZ@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ RC = @RC@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSHD = @SSHD@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = template.3 AUTHORS BINDINGS.md HACKING.md HACKING-CRYPTO \ INSTALL_AUTOTOOLS INSTALL_CMAKE.md SECURITY.md TODO CMakeLists.txt dist_man_MANS = \ libssh2_agent_connect.3 \ libssh2_agent_disconnect.3 \ libssh2_agent_free.3 \ libssh2_agent_get_identity.3 \ libssh2_agent_get_identity_path.3 \ libssh2_agent_init.3 \ libssh2_agent_list_identities.3 \ libssh2_agent_set_identity_path.3 \ libssh2_agent_sign.3 \ libssh2_agent_userauth.3 \ libssh2_banner_set.3 \ libssh2_base64_decode.3 \ libssh2_channel_close.3 \ libssh2_channel_direct_streamlocal_ex.3 \ libssh2_channel_direct_tcpip.3 \ libssh2_channel_direct_tcpip_ex.3 \ libssh2_channel_eof.3 \ libssh2_channel_exec.3 \ libssh2_channel_flush.3 \ libssh2_channel_flush_ex.3 \ libssh2_channel_flush_stderr.3 \ libssh2_channel_forward_accept.3 \ libssh2_channel_forward_cancel.3 \ libssh2_channel_forward_listen.3 \ libssh2_channel_forward_listen_ex.3 \ libssh2_channel_free.3 \ libssh2_channel_get_exit_signal.3 \ libssh2_channel_get_exit_status.3 \ libssh2_channel_handle_extended_data.3 \ libssh2_channel_handle_extended_data2.3 \ libssh2_channel_ignore_extended_data.3 \ libssh2_channel_open_ex.3 \ libssh2_channel_open_session.3 \ libssh2_channel_process_startup.3 \ libssh2_channel_read.3 \ libssh2_channel_read_ex.3 \ libssh2_channel_read_stderr.3 \ libssh2_channel_receive_window_adjust.3 \ libssh2_channel_receive_window_adjust2.3 \ libssh2_channel_request_auth_agent.3 \ libssh2_channel_request_pty.3 \ libssh2_channel_request_pty_ex.3 \ libssh2_channel_request_pty_size.3 \ libssh2_channel_request_pty_size_ex.3 \ libssh2_channel_send_eof.3 \ libssh2_channel_set_blocking.3 \ libssh2_channel_setenv.3 \ libssh2_channel_setenv_ex.3 \ libssh2_channel_shell.3 \ libssh2_channel_signal_ex.3 \ libssh2_channel_subsystem.3 \ libssh2_channel_wait_closed.3 \ libssh2_channel_wait_eof.3 \ libssh2_channel_window_read.3 \ libssh2_channel_window_read_ex.3 \ libssh2_channel_window_write.3 \ libssh2_channel_window_write_ex.3 \ libssh2_channel_write.3 \ libssh2_channel_write_ex.3 \ libssh2_channel_write_stderr.3 \ libssh2_channel_x11_req.3 \ libssh2_channel_x11_req_ex.3 \ libssh2_crypto_engine.3 \ libssh2_exit.3 \ libssh2_free.3 \ libssh2_hostkey_hash.3 \ libssh2_init.3 \ libssh2_keepalive_config.3 \ libssh2_keepalive_send.3 \ libssh2_knownhost_add.3 \ libssh2_knownhost_addc.3 \ libssh2_knownhost_check.3 \ libssh2_knownhost_checkp.3 \ libssh2_knownhost_del.3 \ libssh2_knownhost_free.3 \ libssh2_knownhost_get.3 \ libssh2_knownhost_init.3 \ libssh2_knownhost_readfile.3 \ libssh2_knownhost_readline.3 \ libssh2_knownhost_writefile.3 \ libssh2_knownhost_writeline.3 \ libssh2_poll.3 \ libssh2_poll_channel_read.3 \ libssh2_publickey_add.3 \ libssh2_publickey_add_ex.3 \ libssh2_publickey_init.3 \ libssh2_publickey_list_fetch.3 \ libssh2_publickey_list_free.3 \ libssh2_publickey_remove.3 \ libssh2_publickey_remove_ex.3 \ libssh2_publickey_shutdown.3 \ libssh2_scp_recv.3 \ libssh2_scp_recv2.3 \ libssh2_scp_send.3 \ libssh2_scp_send64.3 \ libssh2_scp_send_ex.3 \ libssh2_session_abstract.3 \ libssh2_session_banner_get.3 \ libssh2_session_banner_set.3 \ libssh2_session_block_directions.3 \ libssh2_session_callback_set.3 \ libssh2_session_disconnect.3 \ libssh2_session_disconnect_ex.3 \ libssh2_session_flag.3 \ libssh2_session_free.3 \ libssh2_session_get_blocking.3 \ libssh2_session_get_read_timeout.3 \ libssh2_session_get_timeout.3 \ libssh2_session_handshake.3 \ libssh2_session_hostkey.3 \ libssh2_session_init.3 \ libssh2_session_init_ex.3 \ libssh2_session_last_errno.3 \ libssh2_session_last_error.3 \ libssh2_session_method_pref.3 \ libssh2_session_methods.3 \ libssh2_session_set_blocking.3 \ libssh2_session_set_last_error.3 \ libssh2_session_set_read_timeout.3 \ libssh2_session_set_timeout.3 \ libssh2_session_startup.3 \ libssh2_session_supported_algs.3 \ libssh2_sftp_close.3 \ libssh2_sftp_close_handle.3 \ libssh2_sftp_closedir.3 \ libssh2_sftp_fsetstat.3 \ libssh2_sftp_fstat.3 \ libssh2_sftp_fstat_ex.3 \ libssh2_sftp_fstatvfs.3 \ libssh2_sftp_fsync.3 \ libssh2_sftp_get_channel.3 \ libssh2_sftp_init.3 \ libssh2_sftp_last_error.3 \ libssh2_sftp_lstat.3 \ libssh2_sftp_mkdir.3 \ libssh2_sftp_mkdir_ex.3 \ libssh2_sftp_open.3 \ libssh2_sftp_open_ex.3 \ libssh2_sftp_open_ex_r.3 \ libssh2_sftp_open_r.3 \ libssh2_sftp_opendir.3 \ libssh2_sftp_read.3 \ libssh2_sftp_readdir.3 \ libssh2_sftp_readdir_ex.3 \ libssh2_sftp_readlink.3 \ libssh2_sftp_realpath.3 \ libssh2_sftp_rename.3 \ libssh2_sftp_rename_ex.3 \ libssh2_sftp_rewind.3 \ libssh2_sftp_rmdir.3 \ libssh2_sftp_rmdir_ex.3 \ libssh2_sftp_seek.3 \ libssh2_sftp_seek64.3 \ libssh2_sftp_setstat.3 \ libssh2_sftp_shutdown.3 \ libssh2_sftp_stat.3 \ libssh2_sftp_stat_ex.3 \ libssh2_sftp_statvfs.3 \ libssh2_sftp_symlink.3 \ libssh2_sftp_symlink_ex.3 \ libssh2_sftp_tell.3 \ libssh2_sftp_tell64.3 \ libssh2_sftp_unlink.3 \ libssh2_sftp_unlink_ex.3 \ libssh2_sftp_write.3 \ libssh2_sign_sk.3 \ libssh2_trace.3 \ libssh2_trace_sethandler.3 \ libssh2_userauth_authenticated.3 \ libssh2_userauth_banner.3 \ libssh2_userauth_hostbased_fromfile.3 \ libssh2_userauth_hostbased_fromfile_ex.3 \ libssh2_userauth_keyboard_interactive.3 \ libssh2_userauth_keyboard_interactive_ex.3 \ libssh2_userauth_list.3 \ libssh2_userauth_password.3 \ libssh2_userauth_password_ex.3 \ libssh2_userauth_publickey.3 \ libssh2_userauth_publickey_fromfile.3 \ libssh2_userauth_publickey_fromfile_ex.3 \ libssh2_userauth_publickey_frommemory.3 \ libssh2_userauth_publickey_sk.3 \ libssh2_version.3 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man3: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man3dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.3[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ done; } uninstall-man3: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man3dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.3[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man3dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man3 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man3 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man3 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags-am uninstall uninstall-am uninstall-man \ uninstall-man3 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libssh2-1.11.0/docs/libssh2_channel_forward_listen_ex.30000644000175000017500000000347014424650606017744 00000000000000.TH libssh2_channel_forward_listen_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_forward_listen_ex - listen to inbound connections .SH SYNOPSIS .nf #include LIBSSH2_LISTENER * libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, char *host, int port, int *bound_port, int queue_maxsize); LIBSSH2_LISTENER * libssh2_channel_forward_listen(LIBSSH2_SESSION *session, int port); .fi .SH DESCRIPTION Instruct the remote SSH server to begin listening for inbound TCP/IP connections. New connections will be queued by the library until accepted by \fIlibssh2_channel_forward_accept(3)\fP. \fIsession\fP - instance as returned by libssh2_session_init(). \fIhost\fP - specific address to bind to on the remote host. Binding to 0.0.0.0 (default when NULL is passed) will bind to all available addresses. \fIport\fP - port to bind to on the remote host. When 0 is passed, the remote host will select the first available dynamic port. \fIbound_port\fP - Populated with the actual port bound on the remote host. Useful when requesting dynamic port numbers. \fIqueue_maxsize\fP - Maximum number of pending connections to queue before rejecting further attempts. \fIlibssh2_channel_forward_listen(3)\fP is a macro. .SH RETURN VALUE A newly allocated LIBSSH2_LISTENER instance or NULL on failure. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_PROTO\fP - An invalid SSH protocol response was received on the socket. \fILIBSSH2_ERROR_REQUEST_DENIED\fP - The remote server refused the request. \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO .BR libssh2_channel_forward_accept(3) libssh2-1.11.0/docs/libssh2_knownhost_readline.30000644000175000017500000000171414424650606016432 00000000000000.\" .\" Copyright (c) 2009 by Daniel Stenberg .\" .TH libssh2_knownhost_readline 3 "28 May 2009" "libssh2" "libssh2" .SH NAME libssh2_knownhost_readline - read a known host line .SH SYNOPSIS .nf #include int libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, const char *line, size_t len, int type): .fi .SH DESCRIPTION Tell libssh2 to read a buffer as it if is a line from a known hosts file. \fIline\fP points to the start of the line \fIlen\fP is the length of the line in bytes \fItype\fP specifies what file type it is, and \fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported format. This file is normally found named ~/.ssh/known_hosts .SH RETURN VALUE Returns a regular libssh2 error code, where negative values are error codes and 0 indicates success. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_knownhost_get(3) .BR libssh2_knownhost_writeline(3) .BR libssh2_knownhost_readfile(3) libssh2-1.11.0/docs/HACKING-CRYPTO0000644000175000017500000011637014424650606013035 00000000000000 Definitions needed to implement a specific crypto library This document offers some hints about implementing a new crypto library interface. A crypto library interface consists of at least a header file, defining entities referenced from the libssh2 core modules. Real code implementation (if needed), is left at the implementor's choice. This document lists the entities that must/may be defined in the header file. Procedures listed as "void" may indeed have a result type: the void indication indicates the libssh2 core modules never use the function result. 0) Build system. Adding a crypto backend to the autotools build system (./configure) is easy: 0.1) Add one new line in configure.ac m4_set_add([crypto_backends], [newname]) This automatically creates a --with-crypto=newname option. 0.2) Add an m4_case stanza to LIBSSH2_CRYPTO_CHECK in acinclude.m4 This must check for all required libraries, and if found set and AC_SUBST a variable with the library linking flags. The recommended method is to use LIBSSH2_LIB_HAVE_LINKFLAGS from LIBSSH2_CRYPTO_CHECK, which automatically creates and handles a --with-$newname-prefix option and sets an LTLIBNEWNAME variable on success. 0.3) Add new header to src/Makefile.inc 0.4) Include new source in src/crypto.c 0.5) Add a new block in configure.ac ``` elif test "$found_crypto" = "newname"; then LIBS="${LIBS} ${LTLIBNEWNAME}" ``` 0.6) Add CMake detection logic to CMakeLists.txt 0.7) Add manual config logic to Makefile.mk 1) Crypto library initialization/termination. void libssh2_crypto_init(void); Initializes the crypto library. May be an empty macro if not needed. void libssh2_crypto_exit(void); Terminates the crypto library use. May be an empty macro if not needed. 1.1) Crypto runtime detection The libssh2_crypto_engine_t enum must include the new engine, and libssh2_crypto_engine() must return it when it is built in. 2) HMAC libssh2_hmac_ctx Type of an HMAC computation context. Generally a struct. Used for all hash algorithms. void libssh2_hmac_ctx_init(libssh2_hmac_ctx ctx); Initializes the HMAC computation context ctx. Called before setting-up the hash algorithm. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_hmac_update(libssh2_hmac_ctx ctx, const unsigned char *data, int datalen); Continue computation of an HMAC on datalen bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_hmac_final(libssh2_hmac_ctx ctx, unsigned char output[]); Get the computed HMAC from context ctx into the output buffer. The minimum data buffer size depends on the HMAC hash algorithm. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx); Releases the HMAC computation context at ctx. 3) Hash algorithms. 3.1) SHA-1 Must always be implemented. SHA_DIGEST_LENGTH #define to 20, the SHA-1 digest length. libssh2_sha1_ctx Type of an SHA-1 computation context. Generally a struct. int libssh2_sha1_init(libssh2_sha1_ctx *x); Initializes the SHA-1 computation context at x. Returns 1 for success and 0 for failure void libssh2_sha1_update(libssh2_sha1_ctx ctx, const unsigned char *data, size_t len); Continue computation of SHA-1 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_sha1_final(libssh2_sha1_ctx ctx, unsigned char output[SHA_DIGEST_LEN]); Get the computed SHA-1 signature from context ctx and store it into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx, const void *key, int keylen); Setup the HMAC computation context ctx for an HMAC-SHA-1 computation using the keylen-byte key. Is invoked just after libssh2_hmac_ctx_init(). 3.2) SHA-256 Must always be implemented. SHA256_DIGEST_LENGTH #define to 32, the SHA-256 digest length. libssh2_sha256_ctx Type of an SHA-256 computation context. Generally a struct. int libssh2_sha256_init(libssh2_sha256_ctx *x); Initializes the SHA-256 computation context at x. Returns 1 for success and 0 for failure void libssh2_sha256_update(libssh2_sha256_ctx ctx, const unsigned char *data, size_t len); Continue computation of SHA-256 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_sha256_final(libssh2_sha256_ctx ctx, unsigned char output[SHA256_DIGEST_LENGTH]); Gets the computed SHA-256 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. int libssh2_sha256(const unsigned char *message, size_t len, unsigned char output[SHA256_DIGEST_LENGTH]); Computes the SHA-256 signature over the given message of length len and store the result into the output buffer. Return 1 if error, else 0. Note: Seems unused in current code, but defined in each crypto library backend. LIBSSH2_HMAC_SHA256 #define as 1 if the crypto library supports HMAC-SHA-256, else 0. If defined as 0, the rest of this section can be omitted. void libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx, const void *key, int keylen); Setup the HMAC computation context ctx for an HMAC-256 computation using the keylen-byte key. Is invoked just after libssh2_hmac_ctx_init(). 3.3) SHA-384 Mandatory if ECDSA is implemented. Can be omitted otherwise. SHA384_DIGEST_LENGTH #define to 48, the SHA-384 digest length. libssh2_sha384_ctx Type of an SHA-384 computation context. Generally a struct. int libssh2_sha384_init(libssh2_sha384_ctx *x); Initializes the SHA-384 computation context at x. Returns 1 for success and 0 for failure void libssh2_sha384_update(libssh2_sha384_ctx ctx, const unsigned char *data, size_t len); Continue computation of SHA-384 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_sha384_final(libssh2_sha384_ctx ctx, unsigned char output[SHA384_DIGEST_LENGTH]); Gets the computed SHA-384 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. int libssh2_sha384(const unsigned char *message, size_t len, unsigned char output[SHA384_DIGEST_LENGTH]); Computes the SHA-384 signature over the given message of length len and store the result into the output buffer. Return 1 if error, else 0. 3.4) SHA-512 Must always be implemented. SHA512_DIGEST_LENGTH #define to 64, the SHA-512 digest length. libssh2_sha512_ctx Type of an SHA-512 computation context. Generally a struct. int libssh2_sha512_init(libssh2_sha512_ctx *x); Initializes the SHA-512 computation context at x. Returns 1 for success and 0 for failure void libssh2_sha512_update(libssh2_sha512_ctx ctx, const unsigned char *data, size_t len); Continue computation of SHA-512 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_sha512_final(libssh2_sha512_ctx ctx, unsigned char output[SHA512_DIGEST_LENGTH]); Gets the computed SHA-512 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. int libssh2_sha512(const unsigned char *message, size_t len, unsigned char output[SHA512_DIGEST_LENGTH]); Computes the SHA-512 signature over the given message of length len and store the result into the output buffer. Return 1 if error, else 0. Note: Seems unused in current code, but defined in each crypto library backend. LIBSSH2_HMAC_SHA512 #define as 1 if the crypto library supports HMAC-SHA-512, else 0. If defined as 0, the rest of this section can be omitted. void libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx, const void *key, int keylen); Setup the HMAC computation context ctx for an HMAC-512 computation using the keylen-byte key. Is invoked just after libssh2_hmac_ctx_init(). 3.5) MD5 LIBSSH2_MD5 #define to 1 if the crypto library supports MD5, else 0. If defined as 0, the rest of this section can be omitted. MD5_DIGEST_LENGTH #define to 16, the MD5 digest length. libssh2_md5_ctx Type of an MD5 computation context. Generally a struct. int libssh2_md5_init(libssh2_md5_ctx *x); Initializes the MD5 computation context at x. Returns 1 for success and 0 for failure void libssh2_md5_update(libssh2_md5_ctx ctx, const unsigned char *data, size_t len); Continues computation of MD5 on len bytes at data using context ctx. Returns 1 for success and 0 for failure. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_md5_final(libssh2_md5_ctx ctx, unsigned char output[MD5_DIGEST_LENGTH]); Gets the computed MD5 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. void libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx, const void *key, int keylen); Setup the HMAC computation context ctx for an HMAC-MD5 computation using the keylen-byte key. Is invoked just after libssh2_hmac_ctx_init(). 3.6) RIPEMD-160 LIBSSH2_HMAC_RIPEMD #define as 1 if the crypto library supports HMAC-RIPEMD-160, else 0. If defined as 0, the rest of this section can be omitted. void libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx, const void *key, int keylen); Setup the HMAC computation context ctx for an HMAC-RIPEMD-160 computation using the keylen-byte key. Is invoked just after libssh2_hmac_ctx_init(). Returns 1 for success and 0 for failure. 4) Bidirectional key ciphers. _libssh2_cipher_ctx Type of a cipher computation context. _libssh2_cipher_type(name); Macro defining name as storage identifying a cipher algorithm for the crypto library interface. No trailing semicolon. int _libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt); Creates a cipher context for the given algorithm with the initialization vector iv and the secret key secret. Prepare for encryption or decryption depending on encrypt. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize, int firstlast); Encrypt or decrypt in-place data at (block, blocksize) using the given context and/or algorithm. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. void _libssh2_cipher_dtor(_libssh2_cipher_ctx *ctx); Release cipher context at ctx. 4.1) AES 4.1.1) AES in CBC block mode. LIBSSH2_AES #define as 1 if the crypto library supports AES in CBC mode, else 0. If defined as 0, the rest of this section can be omitted. _libssh2_cipher_aes128 AES-128-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). _libssh2_cipher_aes192 AES-192-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). _libssh2_cipher_aes256 AES-256-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). 4.1.2) AES in CTR block mode. LIBSSH2_AES_CTR #define as 1 if the crypto library supports AES in CTR mode, else 0. If defined as 0, the rest of this section can be omitted. _libssh2_cipher_aes128ctr AES-128-CTR algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). _libssh2_cipher_aes192ctr AES-192-CTR algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). _libssh2_cipher_aes256ctr AES-256-CTR algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). 4.2) Blowfish in CBC block mode. LIBSSH2_BLOWFISH #define as 1 if the crypto library supports blowfish in CBC mode, else 0. If defined as 0, the rest of this section can be omitted. _libssh2_cipher_blowfish Blowfish-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). 4.3) RC4. LIBSSH2_RC4 #define as 1 if the crypto library supports RC4 (arcfour), else 0. If defined as 0, the rest of this section can be omitted. _libssh2_cipher_arcfour RC4 algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). 4.4) CAST5 in CBC block mode. LIBSSH2_CAST #define 1 if the crypto library supports cast, else 0. If defined as 0, the rest of this section can be omitted. _libssh2_cipher_cast5 CAST5-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). 4.5) Triple DES in CBC block mode. LIBSSH2_3DES #define as 1 if the crypto library supports TripleDES in CBC mode, else 0. If defined as 0, the rest of this section can be omitted. _libssh2_cipher_3des TripleDES-CBC algorithm identifier initializer. #define with constant value of type _libssh2_cipher_type(). 5) Diffie-Hellman support. LIBSSH2_DH_GEX_MINGROUP The minimum Diffie-Hellman group length in bits supported by the backend. Usually defined as 2048. LIBSSH2_DH_GEX_OPTGROUP The preferred Diffie-Hellman group length in bits. Usually defined as 4096. LIBSSH2_DH_GEX_MAXGROUP The maximum Diffie-Hellman group length in bits supported by the backend. Usually defined as 8192. LIBSSH2_DH_MAX_MODULUS_BITS The maximum Diffie-Hellman modulus bit count accepted from the server. This value must be supported by the backend. Usually 16384. 5.1) Diffie-Hellman context. _libssh2_dh_ctx Type of a Diffie-Hellman computation context. Must always be defined. 5.2) Diffie-Hellman computation procedures. void libssh2_dh_init(_libssh2_dh_ctx *dhctx); Initializes the Diffie-Hellman context at `dhctx'. No effective context creation needed here. int libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, _libssh2_bn *g, _libssh2_bn *p, int group_order, _libssh2_bn_ctx *bnctx); Generates a Diffie-Hellman key pair using base `g', prime `p' and the given `group_order'. Can use the given big number context `bnctx' if needed. The private key is stored as opaque in the Diffie-Hellman context `*dhctx' and the public key is returned in `public'. 0 is returned upon success, else -1. int libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, _libssh2_bn *f, _libssh2_bn *p, _libssh2_bn_ctx * bnctx) Computes the Diffie-Hellman secret from the previously created context `*dhctx', the public key `f' from the other party and the same prime `p' used at context creation. The result is stored in `secret'. 0 is returned upon success, else -1. void libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) Destroys Diffie-Hellman context at `dhctx' and resets its storage. 6) Big numbers. Positive multi-byte integers support is sufficient. 6.1) Computation contexts. This has a real meaning if the big numbers computations need some context storage. If not, use a dummy type and functions (macros). _libssh2_bn_ctx Type of multiple precision computation context. May not be empty. if not used, #define as char, for example. _libssh2_bn_ctx _libssh2_bn_ctx_new(void); Returns a new multiple precision computation context. void _libssh2_bn_ctx_free(_libssh2_bn_ctx ctx); Releases a multiple precision computation context. 6.2) Computation support. _libssh2_bn Type of multiple precision numbers (aka bignumbers or huge integers) for the crypto library. _libssh2_bn * _libssh2_bn_init(void); Creates a multiple precision number (preset to zero). _libssh2_bn * _libssh2_bn_init_from_bin(void); Create a multiple precision number intended to be set by the _libssh2_bn_from_bin() function (see below). Unlike _libssh2_bn_init(), this code may be a dummy initializer if the _libssh2_bn_from_bin() actually allocates the number. Returns a value of type _libssh2_bn *. void _libssh2_bn_free(_libssh2_bn *bn); Destroys the multiple precision number at bn. unsigned long _libssh2_bn_bytes(_libssh2_bn *bn); Get the number of bytes needed to store the bits of the multiple precision number at bn. unsigned long _libssh2_bn_bits(_libssh2_bn *bn); Returns the number of bits of multiple precision number at bn. int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val); Sets the value of bn to val. Returns 1 on success, 0 otherwise. _libssh2_bn * _libssh2_bn_from_bin(_libssh2_bn *bn, int len, const unsigned char *val); Converts the positive integer in big-endian form of length len at val into a _libssh2_bn and place it in bn. If bn is NULL, a new _libssh2_bn is created. Returns a pointer to target _libssh2_bn or NULL if error. int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val); Converts the absolute value of bn into big-endian form and store it at val. val must point to _libssh2_bn_bytes(bn) bytes of memory. Returns the length of the big-endian number. 7) Private key algorithms. Format of an RSA public key: a) "ssh-rsa". b) RSA exponent, MSB first, with high order bit = 0. c) RSA modulus, MSB first, with high order bit = 0. Each item is preceded by its 32-bit byte length, MSB first. Format of a DSA public key: a) "ssh-dss". b) p, MSB first, with high order bit = 0. c) q, MSB first, with high order bit = 0. d) g, MSB first, with high order bit = 0. e) pub_key, MSB first, with high order bit = 0. Each item is preceded by its 32-bit byte length, MSB first. Format of an ECDSA public key: a) "ecdsa-sha2-nistp256" or "ecdsa-sha2-nistp384" or "ecdsa-sha2-nistp521". b) domain: "nistp256", "nistp384" or "nistp521" matching a). c) raw public key ("octal"). Each item is preceded by its 32-bit byte length, MSB first. Format of an ED25519 public key: a) "ssh-ed25519". b) raw key (32 bytes). Each item is preceded by its 32-bit byte length, MSB first. int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase); Reads a private key from file privatekey and extract the public key --> (pubkeydata, pubkeydata_len). Store the associated method (ssh-rsa or ssh-dss) into (method, method_len). Both buffers have to be allocated using LIBSSH2_ALLOC(). Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase); Gets a private key from bytes at (privatekeydata, privatekeydata_len) and extract the public key --> (pubkeydata, pubkeydata_len). Store the associated method (ssh-rsa or ssh-dss) into (method, method_len). Both buffers have to be allocated using LIBSSH2_ALLOC(). Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. 7.1) RSA LIBSSH2_RSA #define as 1 if the crypto library supports RSA, else 0. If defined as 0, the rest of this section can be omitted. libssh2_rsa_ctx Type of an RSA computation context. Generally a struct. int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen); Creates a new context for RSA computations from key source values: pdata, plen Prime number p. Only used if private key known (ddata). qdata, qlen Prime number q. Only used if private key known (ddata). ndata, nlen Modulus n. edata, elen Exponent e. ddata, dlen e^-1 % phi(n) = private key. May be NULL if unknown. e1data, e1len dp = d % (p-1). Only used if private key known (dtata). e2data, e2len dq = d % (q-1). Only used if private key known (dtata). coeffdata, coefflen q^-1 % p. Only used if private key known. Returns 0 if OK. This procedure is already prototyped in crypto.h. Note: the current generic code only calls this function with e and n (public key parameters): unless used internally by the backend, it is not needed to support the private key and the other parameters here. int _libssh2_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, unsigned const char *passphrase); Reads an RSA private key from file filename into a new RSA context. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *data, size_t data_len, unsigned const char *passphrase); Gets an RSA private key from data into a new RSA context. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len); Verify (sig, sig_len) signature of (m, m_len) using an SHA-1 hash and the RSA context. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_rsa_sha1_signv(LIBSSH2_SESSION *session, unsigned char **sig, size_t *siglen, int count, const struct iovec vector[], libssh2_rsa_ctx *ctx); RSA signs the SHA-1 hash computed over the count data chunks in vector. Signature is stored at (sig, siglen). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. Note: this procedure is optional: if provided, it MUST be defined as a macro. int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); RSA signs the (hash, hashlen) SHA-1 hash bytes and stores the allocated signature at (signature, signature_len). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. Note: this procedure is not used if macro _libssh2_rsa_sha1_signv() is defined. void _libssh2_rsa_free(libssh2_rsa_ctx *rsactx); Releases the RSA computation context at rsactx. LIBSSH2_RSA_SHA2 #define as 1 if the crypto library supports RSA SHA2 256/512, else 0. If defined as 0, the rest of this section can be omitted. int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session, libssh2_rsa_ctx * rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len); RSA signs the (hash, hashlen) SHA-2 hash bytes based on hash length and stores the allocated signature at (signature, signature_len). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. Note: this procedure is not used if both macros _libssh2_rsa_sha2_256_signv() and _libssh2_rsa_sha2_512_signv are defined. int _libssh2_rsa_sha2_256_signv(LIBSSH2_SESSION *session, unsigned char **sig, size_t *siglen, int count, const struct iovec vector[], libssh2_rsa_ctx *ctx); RSA signs the SHA-256 hash computed over the count data chunks in vector. Signature is stored at (sig, siglen). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. Note: this procedure is optional: if provided, it MUST be defined as a macro. int _libssh2_rsa_sha2_512_signv(LIBSSH2_SESSION *session, unsigned char **sig, size_t *siglen, int count, const struct iovec vector[], libssh2_rsa_ctx *ctx); RSA signs the SHA-512 hash computed over the count data chunks in vector. Signature is stored at (sig, siglen). Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. Note: this procedure is optional: if provided, it MUST be defined as a macro. int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa, size_t hash_len, const unsigned char *sig, size_t sig_len, const unsigned char *m, size_t m_len); Verify (sig, sig_len) signature of (m, m_len) using an SHA-2 hash based on hash length and the RSA context. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. 7.2) DSA LIBSSH2_DSA #define as 1 if the crypto library supports DSA, else 0. If defined as 0, the rest of this section can be omitted. libssh2_dsa_ctx Type of a DSA computation context. Generally a struct. int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *gdata, unsigned long glen, const unsigned char *ydata, unsigned long ylen, const unsigned char *x, unsigned long x_len); Creates a new context for DSA computations from source key values: pdata, plen Prime number p. Only used if private key known (ddata). qdata, qlen Prime number q. Only used if private key known (ddata). gdata, glen G number. ydata, ylen Public key. xdata, xlen Private key. Only taken if xlen non-zero. Returns 0 if OK. This procedure is already prototyped in crypto.h. int _libssh2_dsa_new_private(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, const char *filename, unsigned const char *passphrase); Gets a DSA private key from file filename into a new DSA context. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, LIBSSH2_SESSION *session, const char *data, size_t data_len, unsigned const char *passphrase); Gets a DSA private key from the data_len-bytes data into a new DSA context. Must call _libssh2_init_if_needed(). Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, const unsigned char *sig, const unsigned char *m, size_t m_len); Verify (sig, siglen) signature of (m, m_len) using an SHA-1 hash and the DSA context. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, const unsigned char *hash, size_t hash_len, unsigned char *sig); DSA signs the (hash, hash_len) data using SHA-1 and store the signature at sig. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. void _libssh2_dsa_free(libssh2_dsa_ctx *dsactx); Releases the DSA computation context at dsactx. 7.3) ECDSA LIBSSH2_ECDSA #define as 1 if the crypto library supports ECDSA, else 0. If defined as 0, _libssh2_ec_key should be defined as void and the rest of this section can be omitted. EC_MAX_POINT_LEN Maximum point length. Usually defined as ((528 * 2 / 8) + 1) (= 133). libssh2_ecdsa_ctx Type of an ECDSA computation context. Generally a struct. _libssh2_ec_key Type of an elliptic curve key. libssh2_curve_type An enum type defining curve types. Current supported identifiers are: LIBSSH2_EC_CURVE_NISTP256 LIBSSH2_EC_CURVE_NISTP384 LIBSSH2_EC_CURVE_NISTP521 int _libssh2_ecdsa_create_key(_libssh2_ec_key **out_private_key, unsigned char **out_public_key_octal, size_t *out_public_key_octal_len, libssh2_curve_type curve_type); Create a new ECDSA private key of type curve_type and return it at out_private_key. If out_public_key_octal is not NULL, store an allocated pointer to the associated public key in "octal" form in it and its length at out_public_key_octal_len. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx **ec_ctx, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase); Reads an ECDSA private key from PEM file filename into a new ECDSA context. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx, LIBSSH2_SESSION * session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); Builds an ECDSA private key from PEM data at filedata of length filedata_len into a new ECDSA context stored at ec_ctx. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ecdsactx, const unsigned char *k, size_t k_len, libssh2_curve_type type); Stores at ecdsactx a new ECDSA context associated with the given curve type and with "octal" form public key (k, k_len). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx **ec_ctx, LIBSSH2_SESSION * session, const char *filename, unsigned const char *passphrase); Reads a PEM-encoded ECDSA private key from file filename encrypted with passphrase and stores at ec_ctx a new ECDSA context for it. Return 0 if OK, else -1. Currently used only from openssl backend (ought to be private). This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx, const unsigned char *hash, unsigned long hash_len, unsigned char **signature, size_t *signature_len); ECDSA signs the (hash, hashlen) hash bytes and stores the allocated signature at (signature, signature_len). Hash algorithm used should be SHA-256, SHA-384 or SHA-512 depending on type stored in ECDSA context at ec_ctx. Signature buffer must be allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_verify(libssh2_ecdsa_ctx *ctx, const unsigned char *r, size_t r_len, const unsigned char *s, size_t s_len, const unsigned char *m, size_t m_len); Verify the ECDSA signature made of (r, r_len) and (s, s_len) of (m, m_len) using the hash algorithm configured in the ECDSA context ctx. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. libssh2_curve_type _libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ecdsactx); Returns the curve type associated with given context. This procedure is already prototyped in crypto.h. int _libssh2_ecdsa_curve_type_from_name(const char *name, libssh2_curve_type *out_type); Stores in out_type the curve type matching string name of the form "ecdsa-sha2-nistpxxx". Return 0 if OK, else -1. Currently used only from openssl backend (ought to be private). This procedure is already prototyped in crypto.h. void _libssh2_ecdsa_free(libssh2_ecdsa_ctx *ecdsactx); Releases the ECDSA computation context at ecdsactx. 7.4) ED25519 LIBSSH2_ED25519 #define as 1 if the crypto library supports ED25519, else 0. If defined as 0, the rest of this section can be omitted. libssh2_ed25519_ctx Type of an ED25519 computation context. Generally a struct. int _libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_ed25519_ctx **ctx, uint8_t **out_public_key, uint8_t **out_private_key); Generates an ED25519 key pair, stores a pointer to them at out_private_key and out_public_key respectively and stores at ctx a new ED25519 context for this key. Argument ctx, out_private_key and out_public key may be NULL to disable storing the corresponding value. Length of each key is LIBSSH2_ED25519_KEY_LEN (32 bytes). Key buffers are allocated and should be released by caller after use. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const char *filename, const uint8_t *passphrase); Reads an ED25519 private key from PEM file filename into a new ED25519 context. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const unsigned char *raw_pub_key, const size_t key_len); Stores at ed_ctx a new ED25519 key context for raw public key (raw_pub_key, key_len). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx, LIBSSH2_SESSION *session, const char *filedata, size_t filedata_len, unsigned const char *passphrase); Builds an ED25519 private key from PEM data at filedata of length filedata_len into a new ED25519 context stored at ed_ctx. Must call _libssh2_init_if_needed(). Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session, uint8_t **out_sig, size_t *out_sig_len, const uint8_t *message, size_t message_len); ED25519 signs the (message, message_len) bytes and stores the allocated signature at (sig, sig_len). Signature buffer is allocated from the given session. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s, size_t s_len, const uint8_t *m, size_t m_len); Verify (s, s_len) signature of (m, m_len) using the given ED25519 context. Return 0 if OK, else -1. This procedure is already prototyped in crypto.h. int _libssh2_curve25519_gen_k(_libssh2_bn **k, uint8_t private_key[LIBSSH2_ED25519_KEY_LEN], uint8_t srvr_public_key[LIBSSH2_ED25519_KEY_LEN]); Computes a shared ED25519 secret key from the given raw server public key and raw client public key and stores it as a big number in *k. Big number should have been initialized before calling this function. Returns 0 if OK, else -1. This procedure is already prototyped in crypto.h. void _libssh2_ed25519_free(libssh2_ed25519_ctx *ed25519ctx); Releases the ED25519 computation context at ed25519ctx. 8) Miscellaneous void libssh2_prepare_iovec(struct iovec *vector, unsigned int len); Prepare len consecutive iovec slots before using them. In example, this is needed to preset unused structure slacks on platforms requiring it. If this is not needed, it should be defined as an empty macro. int _libssh2_random(unsigned char *buf, size_t len); Store len random bytes at buf. Returns 0 if OK, else -1. const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session, unsigned char *key_method, size_t key_method_len); This function is for implementing key hash upgrading as defined in RFC 8332. Based on the incoming key_method value, this function will return a list of supported algorithms that can upgrade the original key method algorithm as a comma separated list, if there is no upgrade option this function should return NULL. libssh2-1.11.0/docs/libssh2_userauth_publickey_sk.30000644000175000017500000001235514424650606017144 00000000000000.TH libssh2_userauth_publickey_sk 3 "1 Jun 2022" "libssh2" "libssh2" .SH NAME libssh2_userauth_publickey_sk - authenticate a session with a FIDO2 authenticator .SH SYNOPSIS .nf #include int libssh2_userauth_publickey_sk(LIBSSH2_SESSION *session, const char *username, size_t username_len, const unsigned char *publickeydata, size_t publickeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase, LIBSSH2_USERAUTH_SK_SIGN_FUNC((*sign_callback)), void **abstract); .fi .SH CALLBACK .nf #define LIBSSH2_SK_PRESENCE_REQUIRED 0x01 #define LIBSSH2_SK_VERIFICATION_REQUIRED 0x04 typedef struct _LIBSSH2_SK_SIG_INFO { uint8_t flags; uint32_t counter; unsigned char *sig_r; size_t sig_r_len; unsigned char *sig_s; size_t sig_s_len; } LIBSSH2_SK_SIG_INFO; int name(LIBSSH2_SESSION *session, LIBSSH2_SK_SIG_INFO *sig_info, const unsigned char *data, size_t data_len, int algorithm, uint8_t flags, const char *application, const unsigned char *key_handle, size_t handle_len, void **abstract); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIusername\fP - Name of user to attempt authentication for. \fIusername_len\fP - Length of username parameter. \fIpublickeydata\fP - Buffer containing the contents of a public key file. If NULL, the public key will be extracted from the privatekeydata. When using certificate authentication, this buffer should contain the public certificate data. \fIpublickeydata_len\fP - Length of public key data. \fIprivatekeydata\fP - Buffer containing the contents of a private key file. \fIprivatekeydata_len\fP - Length of private key data. \fIpassphrase\fP - Passphrase to use when decoding private key file. \fIsign_callback\fP - Callback to communicate with FIDO2 authenticator. \fIabstract\fP - User-provided data to pass to callback. Attempt FIDO2 authentication. using either the sk-ssh-ed25519@openssh.com or sk-ecdsa-sha2-nistp256@openssh.com key exchange algorithms. This function is only supported when libssh2 is backed by OpenSSL. .SH CALLBACK DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIsig_info\fP - Filled in by the callback with the signature and accompanying information from the authenticator. \fIdata\fP - The data to sign. \fIdata_len\fP - The length of the data parameter. \fIalgorithm\fP - The signing algorithm to use. Possible values are LIBSSH2_HOSTKEY_TYPE_ED25519 and LIBSSH2_HOSTKEY_TYPE_ECDSA_256. \fIflags\fP - A bitmask specifying options for the authenticator. When LIBSSH2_SK_PRESENCE_REQUIRED is set, the authenticator requires a touch. When LIBSSH2_SK_VERIFICATION_REQUIRED is set, the authenticator requires a PIN. Many servers and authenticators do not work properly when LIBSSH2_SK_PRESENCE_REQUIRED is not set. \fIapplication\fP - A user-defined string to use as the RP name for the authenticator. Usually "ssh:". \fIkey_handle\fP - The key handle to use for the authenticator's allow list. \fIhandle_len\fP - The length of the key_handle parameter. \fIabstract\fP - User-defined data. When a PIN is required, use this to pass in the PIN, or a function pointer to retrieve the PIN. The \fIsign_callback\fP is responsible for communicating with the hardware authenticator to generate a signature. On success, the signature information must be placed in the `\fIsig_info\fP sig_info parameter and the callback must return 0. On failure, it should return a negative number. The fields of the LIBSSH2_SK_SIG_INFO are as follows. \fIflags\fP - A bitmask specifying options for the authenticator. This should be read from the authenticator and not merely copied from the flags parameter to the callback. \fIcounter\fP - A value returned from the authenticator. \fIsig_r\fP - For Ed25519 signatures, this contains the entire signature, as returned directly from the authenticator. For ECDSA signatures, this contains the r component of the signature in a big-endian binary representation. For both algorithms, use LIBSSH2_ALLOC to allocate memory. It will be freed by the caller. \fIsig_r_len\fP - The length of the sig_r parameter. \fIsig_s\fP - For ECDSA signatures, this contains the s component of the signature in a big-endian binary representation. Use LIBSSH2_ALLOC to allocate memory. It will be freed by the caller. For Ed25519 signatures, set this to NULL. \fIsig_s_len\fP - The length of the sig_s parameter. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS Some of the errors this function may return include: \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/key. .SH AVAILABILITY Added in libssh2 1.10.0 .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_userauth_authenticated.30000644000175000017500000000102114424650606017266 00000000000000.TH libssh2_userauth_authenticated 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_userauth_authenticated - return authentication status .SH SYNOPSIS .nf #include int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) Indicates whether or not the named session has been successfully authenticated. .SH RETURN VALUE Returns 1 if authenticated and 0 if not. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_agent_get_identity_path.30000644000175000017500000000111314424650606017410 00000000000000.\" .\" Copyright (c) 2019 by Will Cosgrove .\" .TH libssh2_agent_get_identity_path 3 "6 Mar 2019" "libssh2" "libssh2" .SH NAME libssh2_agent_get_identity_path - gets the custom ssh-agent socket path .SH SYNOPSIS .nf #include const char * libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent); .fi .SH DESCRIPTION Returns the custom agent identity socket path if set using libssh2_agent_set_identity_path() .SH RETURN VALUE Returns the socket path on disk. .SH AVAILABILITY Added in libssh2 1.9 .SH SEE ALSO .BR libssh2_agent_init(3) .BR libssh2_agent_set_identity_path(3) libssh2-1.11.0/docs/libssh2_channel_free.30000644000175000017500000000141714424650606015146 00000000000000.TH libssh2_channel_free 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_free - free all resources associated with a channel .SH SYNOPSIS .nf #include int libssh2_channel_free(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION \fIchannel\fP - Channel stream to free. Release all resources associated with a channel stream. If the channel has not yet been closed with .BR libssh2_channel_close(3) , it will be called automatically so that the remote end may know that it can safely free its own resources. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH SEE ALSO .BR libssh2_channel_close(3) libssh2-1.11.0/docs/libssh2_session_get_timeout.30000644000175000017500000000120214424650606016615 00000000000000.TH libssh2_session_get_timeout 3 "4 May 2011" "libssh2" "libssh2" .SH NAME libssh2_session_get_timeout - get the timeout for blocking functions .SH SYNOPSIS .nf #include long libssh2_session_get_timeout(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION Returns the \fBtimeout\fP (in milliseconds) for how long a blocking the libssh2 function calls may wait until they consider the situation an error and return LIBSSH2_ERROR_TIMEOUT. By default libssh2 has no timeout (zero) for blocking functions. .SH RETURN VALUE The value of the timeout setting. .SH AVAILABILITY Added in 1.2.9 .SH SEE ALSO .BR libssh2_session_set_timeout(3) libssh2-1.11.0/docs/libssh2_channel_open_ex.30000644000175000017500000000364314424650606015665 00000000000000.TH libssh2_channel_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_open_ex - establish a generic session channel .SH SYNOPSIS .nf #include LIBSSH2_CHANNEL * libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len); LIBSSH2_CHANNEL * libssh2_channel_open_session(session); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIchannel_type\fP - Channel type to open. Typically one of session, direct-tcpip, or tcpip-forward. The SSH2 protocol allowed for additional types including local, custom channel types. \fIchannel_type_len\fP - Length of channel_type \fIwindow_size\fP - Maximum amount of unacknowledged data remote host is allowed to send before receiving an SSH_MSG_CHANNEL_WINDOW_ADJUST packet. \fIpacket_size\fP - Maximum number of bytes remote host is allowed to send in a single SSH_MSG_CHANNEL_DATA or SSG_MSG_CHANNEL_EXTENDED_DATA packet. \fImessage\fP - Additional data as required by the selected channel_type. \fImessage_len\fP - Length of message parameter. Allocate a new channel for exchanging data with the server. This method is typically called through its macroized form: .BR libssh2_channel_open_session(3) or via .BR libssh2_channel_direct_tcpip(3) or .BR libssh2_channel_forward_listen(3) .SH RETURN VALUE Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_CHANNEL_FAILURE\fP - \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO Add related functions libssh2-1.11.0/docs/libssh2_channel_open_session.30000644000175000017500000000110714424650606016725 00000000000000.TH libssh2_channel_open_session 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_open_session - convenience macro for \fIlibssh2_channel_open_ex(3)\fP calls .SH SYNOPSIS .nf #include LIBSSH2_CHANNEL * libssh2_channel_open_session(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_open_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_open_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_open_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_open_ex(3) libssh2-1.11.0/docs/libssh2_channel_close.30000644000175000017500000000175414424650606015336 00000000000000.TH libssh2_channel_close 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_close - close a channel .SH SYNOPSIS .nf #include int libssh2_channel_close(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION \fIchannel\fP - active channel stream to set closed status on. Close an active data channel. In practice this means sending an SSH_MSG_CLOSE packet to the remote host which serves as instruction that no further data will be sent to it. The remote host may still send data back until it sends its own close message in response. To wait for the remote end to close its connection as well, follow this command with .BR libssh2_channel_wait_closed(3) .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. .SH SEE ALSO .BR libssh2_channel_open_ex(3) libssh2-1.11.0/docs/libssh2_sftp_mkdir_ex.30000644000175000017500000000265614424650606015401 00000000000000.TH libssh2_sftp_mkdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_mkdir_ex - create a directory on the remote file system .SH SYNOPSIS .nf #include #include int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode); int libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, long mode); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) \fIpath\fP - full path of the new directory to create. Note that the new directory's parents must all exist prior to making this call. \fIpath_len\fP - length of the full path of the new directory to create. \fImode\fP - directory creation mode (e.g. 0755). Create a directory on the remote file system. .SH RETURN VALUE Return 0 on success or negative on failure. LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. .SH SEE ALSO .BR libssh2_sftp_open_ex(3) libssh2-1.11.0/docs/libssh2_sftp_lstat.30000644000175000017500000000114514424650606014716 00000000000000.TH libssh2_sftp_lstat 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_lstat - convenience macro for \fIlibssh2_sftp_stat_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_lstat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_stat_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_stat_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_stat_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_stat_ex(3) libssh2-1.11.0/docs/libssh2_session_set_last_error.30000644000175000017500000000175714424650606017336 00000000000000.TH libssh2_session_set_last_error 3 "26 Oct 2015" "libssh2" "libssh2" .SH NAME libssh2_session_set_last_error - sets the internal error state .SH SYNOPSIS .nf #include int libssh2_session_set_last_error(LIBSSH2_SESSION *session, int errcode, const char *errmsg) .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIerrcode\fP - One of the error codes as defined in the public libssh2 header file. \fIerrmsg\fP - If not NULL, a copy of the given string is stored inside the session object as the error message. This function is provided for high level language wrappers (i.e. Python or Perl) and other libraries that may extend libssh2 with additional features while still relying on its error reporting mechanism. .SH RETURN VALUE Numeric error code corresponding to the the Error Code constants. .SH AVAILABILITY Added in 1.6.1 .SH SEE ALSO .BR libssh2_session_last_error(3) .BR libssh2_session_last_errno(3) libssh2-1.11.0/docs/libssh2_session_handshake.30000644000175000017500000000242714424650606016230 00000000000000.TH libssh2_session_handshake 3 "7 Oct 2010" "libssh2" "libssh2" .SH NAME libssh2_session_handshake - perform the SSH handshake .SH SYNOPSIS .nf #include int libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t socket); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIsocket\fP - Connected socket descriptor. Typically a TCP connection though the protocol allows for any reliable transport and the library will attempt to use any berkeley socket. Begin transport layer protocol negotiation with the connected host. .SH RETURN VALUE Returns 0 on success, negative on failure. .SH ERRORS \fILIBSSH2_ERROR_SOCKET_NONE\fP - The socket is invalid. \fILIBSSH2_ERROR_BANNER_SEND\fP - Unable to send banner to remote host. \fILIBSSH2_ERROR_KEX_FAILURE\fP - Encryption key exchange with the remote host failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_DISCONNECT\fP - The socket was disconnected. \fILIBSSH2_ERROR_PROTO\fP - An invalid SSH protocol response was received on the socket. \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH AVAILABILITY Added in 1.2.8 .SH SEE ALSO .BR libssh2_session_free(3) .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_channel_direct_tcpip_ex.30000644000175000017500000000252414424650606017372 00000000000000.TH libssh2_channel_direct_tcpip_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_direct_tcpip_ex - Tunnel a TCP connection through an SSH session .SH SYNOPSIS .nf #include LIBSSH2_CHANNEL * libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport); LIBSSH2_CHANNEL * libssh2_channel_direct_tcpip(LIBSSH2_SESSION *session, const char *host, int port); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIhost\fP - Third party host to connect to using the SSH host as a proxy. \fIport\fP - Port on third party host to connect to. \fIshost\fP - Host to tell the SSH server the connection originated on. \fIsport\fP - Port to tell the SSH server the connection originated from. Tunnel a TCP/IP connection through the SSH transport via the remote host to a third party. Communication from the client to the SSH server remains encrypted, communication from the server to the 3rd party host travels in cleartext. .SH RETURN VALUE Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_session_callback_set.30000644000175000017500000001164514424650606016713 00000000000000.TH libssh2_session_callback_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_callback_set - set a callback function .SH SYNOPSIS .nf #include void * libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback); .fi .SH DESCRIPTION Sets a custom callback handler for a previously initialized session object. Callbacks are triggered by the receipt of special packets at the Transport layer. To disable a callback, set it to NULL. \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIcbtype\fP - Callback type. One of the types listed in Callback Types. \fIcallback\fP - Pointer to custom callback function. The prototype for this function must match the associated callback declaration macro. .SH CALLBACK TYPES .IP LIBSSH2_CALLBACK_IGNORE Called when a SSH_MSG_IGNORE message is received .IP LIBSSH2_CALLBACK_DEBUG Called when a SSH_MSG_DEBUG message is received .IP LIBSSH2_CALLBACK_DISCONNECT Called when a SSH_MSG_DISCONNECT message is received .IP LIBSSH2_CALLBACK_MACERROR Called when a mismatched MAC has been detected in the transport layer. If the function returns 0, the packet will be accepted nonetheless. .IP LIBSSH2_CALLBACK_X11 Called when an X11 connection has been accepted .IP LIBSSH2_CALLBACK_SEND Called when libssh2 wants to send data on the connection. Can be set to a custom function to handle I/O your own way. The prototype of the callback: .nf ssize_t sendcb(libssh2_socket_t sockfd, const void *buffer, size_t length, int flags, void **abstract); .fi \fBsockfd\fP is the socket to write to, \fBbuffer\fP points to the data to send, \fBlength\fP is the size of the data, \fBflags\fP is the flags that would have been used to a \fIsend()\fP call and \fBabstract\fP is a pointer to the abstract pointer set in the \fIlibssh2_session_init_ex(3)\fP call. The callback returns the number of bytes sent, or -1 for error. The special return code \fB-EAGAIN\fP can be returned to signal that the send was aborted to prevent getting blocked and it needs to be called again. .IP LIBSSH2_CALLBACK_RECV Called when libssh2 wants to read data from the connection. Can be set to a custom function to handle I/O your own way. The prototype of the callback: .nf ssize_t recvcb(libssh2_socket_t sockfd, void *buffer, size_t length, int flags, void **abstract); .fi \fBsockfd\fP is the socket to read from, \fBbuffer\fP where to store received data into, \fBlength\fP is the size of the buffer, \fBflags\fP is the flags that would have been used to a \fIrecv()\fP call and \fBabstract\fP is a pointer to the abstract pointer set in the \fIlibssh2_session_init_ex(3)\fP call. The callback returns the number of bytes read, or -1 for error. The special return code \fB-EAGAIN\fP can be returned to signal that the read was aborted to prevent getting blocked and it needs to be called again. .IP LIBSSH2_CALLBACK_AUTHAGENT Called during authentication process to allow the client to connect to the ssh-agent and perform any setup, such as configuring the agent or adding keys. The prototype of the callback: .nf void authagent(LIBSSH2_SESSION* session, LIBSSH2_CHANNEL *channel, void **abstract); .fi .IP LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES Not called by libssh2. The client is responsible for calling this method when a SSH2_AGENTC_REQUEST_IDENTITIES message has been received. The prototype of the callback: .nf void identities(LIBSSH2_SESSION* session, void *buffer, const char *agent_path, void **abstract) .fi \fBbuffer\fP must be filled in by the callback. Different clients may implement this differently. For example, one client may pass in an unsigned char ** for this parameter, while another may pass in a pointer to a struct. Regardless of the type of buffer used, the client will need to send back a list of identities in the following format. uint32 buffer length uint32 number of entries entries Where each entry in the entries list is of the format: string data cstring comment \fBagent_path\fP The path to a running ssh-agent on the client machine, from which identities can be listed. .IP LIBSSH2_CALLBACK_AUTHAGENT_SIGN Not called by libssh2. The client is responsible for calling this method when a SSH2_AGENTC_SIGN_REQUEST message has been received. The prototype of the callback: .nf void sign(LIBSSH2_SESSION* session, unsigned char *blob, unsigned int blen, const unsigned char *data, unsigned int dlen, unsigned char **sig, unsigned int *sig_len, const char *agent_path, void **abstract); .fi When interfacing with an ssh-agent installed on the client system, this method can call libssh2_agent_sign(3) to perform signing. .SH RETURN VALUE Pointer to previous callback handler. Returns NULL if no prior callback handler was set or the callback type was unknown. .SH SEE ALSO .BR libssh2_session_init_ex(3) .BR libssh2_agent_sign(3) libssh2-1.11.0/docs/libssh2_session_method_pref.30000644000175000017500000000262614424650606016577 00000000000000.TH libssh2_session_method_pref 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_method_pref - set preferred key exchange method .SH SYNOPSIS .nf #include int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fImethod_type\fP - One of the Method Type constants. \fIprefs\fP - Coma delimited list of preferred methods to use with the most preferred listed first and the least preferred listed last. If a method is listed which is not supported by libssh2 it will be ignored and not sent to the remote host during protocol negotiation. Set preferred methods to be negotiated. These preferences must be set prior to calling .BR libssh2_session_handshake(3) as they are used during the protocol initiation phase. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_INVAL\fP - The requested method type was invalid. \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_METHOD_NOT_SUPPORTED\fP - The requested method is not supported. .SH SEE ALSO .BR libssh2_session_init_ex(3) .BR libssh2_session_handshake(3) libssh2-1.11.0/docs/libssh2_init.30000644000175000017500000000107414424650606013477 00000000000000.TH libssh2_init 3 "19 Mar 2010" "libssh2" "libssh2" .SH NAME libssh2_init - global library initialization .SH SYNOPSIS .nf #include #define LIBSSH2_INIT_NO_CRYPTO 0x0001 int libssh2_init(int flags); .fi .SH DESCRIPTION Initialize the libssh2 functions. This typically initialize the crypto library. It uses a global state, and is not thread safe -- you must make sure this function is not called concurrently. .SH RETURN VALUE Returns 0 if succeeded, or a negative value for error. .SH AVAILABILITY Added in libssh2 1.2.5 .SH SEE ALSO .BR libssh2_exit(3) libssh2-1.11.0/docs/libssh2_channel_signal_ex.30000644000175000017500000000203414424650606016172 00000000000000.TH libssh2_channel_signal_ex 3 "20 Apr 2023" "libssh2 1.11.0" "libssh2" .SH NAME libssh2_channel_signal_ex -- Send a signal to process previously opened on channel. .SH SYNOPSIS .nf #include int libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel, const char *signame, size_t signame_len) .fi .SH DESCRIPTION A signal can be delivered to the remote process/service. Some servers or systems may not implement signals, in which case they will probably ignore this message. \fIchannel\fP - Previously opened channel instance such as returned by .BR libssh2_channel_open_ex(3) \fIsigname\fP - The signal name is the same as the signal name constant, without the leading "SIG". \fIsigname_len\fP - Length of passed signal name parameter. There is also a macro \fIlibssh2_channel_signal(channel, signame)\fP that supplies the strlen of the signame. .SH RETURN VALUE Normal channel error codes. LIBSSH2_ERROR_EAGAIN when it would block. .SH SEE ALSO .BR libssh2_channel_get_exit_signal(3) libssh2-1.11.0/docs/libssh2_channel_handle_extended_data.30000644000175000017500000000235414424650606020332 00000000000000.TH libssh2_channel_handle_extended_data 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_handle_extended_data - set extended data handling mode .SH SYNOPSIS .nf #include void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); .fi .SH DESCRIPTION This function is deprecated. Use the \fIlibssh2_channel_handle_extended_data2(3)\fP function instead! \fIchannel\fP - Active channel stream to change extended data handling on. \fIignore_mode\fP - One of the three LIBSSH2_CHANNEL_EXTENDED_DATA_* Constants. .br \fBLIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL\fP: Queue extended data for eventual reading .br \fBLIBSSH2_CHANNEL_EXTENDED_DATA_MERGE\fP: Treat extended data and ordinary data the same. Merge all substreams such that calls to \fIlibssh2_channel_read(3)\fP will pull from all substreams on a first-in/first-out basis. .br \fBLIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE\fP: Discard all extended data as it arrives. Change how a channel deals with extended data packets. By default all extended data is queued until read by \fIlibssh2_channel_read_ex(3)\fP .SH RETURN VALUE None. .SH SEE ALSO .BR libssh2_channel_handle_extended_data2(3) .BR libssh2_channel_read_ex(3) libssh2-1.11.0/docs/libssh2_agent_init.30000644000175000017500000000155514424650606014661 00000000000000.\" .\" Copyright (c) 2009 by Daiki Ueno .\" .TH libssh2_agent_init 3 "23 Dec 2009" "libssh2" "libssh2" .SH NAME libssh2_agent_init - init an ssh-agent handle .SH SYNOPSIS .nf #include LIBSSH2_AGENT * libssh2_agent_init(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION Init an ssh-agent handle. Returns the handle to an internal representation of an ssh-agent connection. After the successful initialization, an application can call \fBlibssh2_agent_connect(3)\fP to connect to a running ssh-agent. Call \fBlibssh2_agent_free(3)\fP to free the handle again after you are doing using it. .SH RETURN VALUE Returns a handle pointer or NULL if something went wrong. The returned handle is used as input to all other ssh-agent related functions libssh2 provides. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_agent_connect(3) .BR libssh2_agent_free(3) libssh2-1.11.0/docs/libssh2_knownhost_readfile.30000644000175000017500000000173014424650606016420 00000000000000.\" .\" Copyright (c) 2009-2011 by Daniel Stenberg .\" .TH libssh2_knownhost_readfile 3 "28 May 2009" "libssh2" "libssh2" .SH NAME libssh2_knownhost_readfile - parse a file of known hosts .SH SYNOPSIS .nf #include int libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, const char *filename, int type); .fi .SH DESCRIPTION Reads a collection of known hosts from a specified file and adds them to the collection of known hosts. \fIfilename\fP specifies which file to read \fItype\fP specifies what file type it is, and \fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported format. This file is normally found named ~/.ssh/known_hosts .SH RETURN VALUE Returns a negative value, a regular libssh2 error code for errors, or a positive number as number of parsed known hosts in the file. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_knownhost_init(3) .BR libssh2_knownhost_free(3) .BR libssh2_knownhost_check(3) libssh2-1.11.0/docs/libssh2_userauth_publickey_frommemory.30000644000175000017500000000425014424650606020716 00000000000000.TH libssh2_userauth_publickey_frommemory 3 "1 Sep 2014" "libssh2" "libssh2" .SH NAME libssh2_userauth_publickey_frommemory - authenticate a session with a public key, read from memory .SH SYNOPSIS .nf #include int libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, const char *username, size_t username_len, const char *publickeydata, size_t publickeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase); .fi .SH DESCRIPTION This function allows to authenticate a session with a public key read from memory. It is only supported when libssh2 is backed by OpenSSL. \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIusername\fP - Remote user name to authenticate as. \fIusername_len\fP - Length of username. \fIpublickeydata\fP - Buffer containing the contents of a public key file. \fIpublickeydata_len\fP - Length of public key data. \fIprivatekeydata\fP - Buffer containing the contents of a private key file. \fIprivatekeydata_len\fP - Length of private key data. \fIpassphrase\fP - Passphrase to use when decoding private key file. Attempt public key authentication using a PEM encoded private key file stored in memory. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key combination was invalid. \fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the supplied public key was not accepted. .SH AVAILABILITY libssh2_userauth_publickey_frommemory was added in libssh2 1.6.0 .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/TODO0000644000175000017500000001414214424650606011512 00000000000000Things TODO =========== * Fix the numerous malloc+copy operations for sending data, see "Buffering Improvements" below for details * make sure the windowing code adapts better to slow situations so that it does not then use as much memory as today. Possibly by an app-controllable "Window mode"? * Decrease the number of mallocs. Everywhere. Will get easier once the buffering improvements have been done. * Use SO_NOSIGPIPE for Mac OS/BSD systems where MSG_NOSIGNAL does not exist/work * Extend the test suite to actually test lots of aspects of libssh2 * Update public API to drop casts added to fix compiler warnings * Expose error messages sent by the server * select() is troublesome with libssh2 when using multiple channels over the same session. See "New Transport API" below for more details. At next SONAME bump =================== * stop using #defined macros as part of the official API. The macros should either be turned into real functions or discarded from the API. * fix the parts of the API where object pointers and function pointers are mixed like libssh2_session_callback_set() * remove the following functions from the API/ABI libssh2_base64_decode() libssh2_session_flag() libssh2_channel_handle_extended_data() libssh2_channel_receive_window_adjust() libssh2_poll() libssh2_poll_channel_read() libssh2_session_startup() (libssh2_session_handshake() is the replacement) libssh2_banner_set() (libssh2_session_banner_set() is the replacement) * Rename a few function: libssh2_hostkey_hash => libssh2_session_hostkey_hash libssh2_banner_set => libssh2_session_banner_set * change 'int' to 'libssh2_socket_t' in the public API for sockets. * Use 'size_t' for string lengths in all functions. * Add a comment field to struct libssh2_knownhost. * remove the existing libssh2_knownhost_add() function and rename libssh2_knownhost_addc to become the new libssh2_knownhost_add instead * remove the existing libssh2_scp_send_ex() function and rename libssh2_scp_send64 to become the new libssh2_scp_send instead. * remove the existing libssh2_knownhost_check() function and rename libssh2_knownhost_checkp() to become the new libssh2_knownhost_check instead Buffering Improvements ====================== transport_write - If this function gets called with a total packet size that is larger than 32K, it should create more than one SSH packet so that it keeps the largest one below 32K sftp_write - should not copy/allocate anything for the data, only create a header chunk and pass on the payload data to channel_write "pointed to" New Transport API ================= THE PROBLEM The problem in a nutshell is that when an application opens up multiple channels over a single session, those are all using the same socket. If the application is then using select() to wait for traffic (like any sensible app does) and wants to act on the data when select() tells there is something to for example read, what does an application do? With our current API, you have to loop over all the channels and read from them to see if they have data. This effectively makes blocking reads impossible. If the app has many channels in a setup like this, it even becomes slow. (The original API had the libssh2_poll_channel_read() and libssh2_poll() to somewhat overcome this hurdle, but they too have pretty much the same problems plus a few others.) Traffic in the other direction is similarly limited: the app has to try sending to all channels, even though some of them may very well not accept any data at that point. A SOLUTION I suggest we introduce two new helper functions: libssh2_transport_read() - Read "a bunch" of data from the given socket and returns information to the app about what channels that are now readable (ie they will not block when read from). The function can be called over and over and it will repeatedly return info about what channels that are readable at that moment. libssh2_transport_write() - Returns information about what channels that are writable, in the sense that they have windows set from the remote side that allows data to get sent. Writing to one of those channels will not block. Of course, the underlying socket may only accept a certain amount of data, so at the first short return, nothing more should be attempted to get sent until select() (or equivalent) has been used on the master socket again. I have not yet figured out a sensible API for how these functions should return that info, but if we agree on the general principles I guess we can work that out. VOLUNTARY I wanted to mention that these two helper functions would not be mandatory in any way. They would just be there for those who want them, and existing programs can remain using the old functions only if they prefer to. New SFTP API ============ PURPOSE Provide API functions that explicitly tells at once that a (full) SFTP file transfer is wanted, to allow libssh2 to leverage on that knowledge to speed up things internally. It can for example do read ahead, buffer writes (merge small writes into larger chunks), better tune the SSH window and more. This sort of API is already provided for SCP transfers. API New functions: LIBSSH2_SFTP_HANDLE *libssh2_sftp_send(SFTP_SESSION *sftp, uint64_t filesize, char *remote_path, size_t remote_path_len, long mode); Tell libssh2 that a local file with a given size is about to get sent to the SFTP server. LIBSSH2_SFTP_HANDLE *libssh2_sftp_recv(); Tell libssh2 that a remote file is requested to get downloaded from the SFTP server. Only the setup of the file transfer is different from an application's point of view. Depending on direction of the transfer(s), the following already existing functions should then be used until the transfer is complete: libssh2_sftp_read() libssh2_sftp_write() HOW TO USE 1. Setup the transfer using one of the two new functions. 2. Loop through the reading or writing of data. 3. Cleanup the transfer libssh2-1.11.0/docs/libssh2_channel_wait_eof.30000644000175000017500000000111114424650606016011 00000000000000.TH libssh2_channel_wait_eof 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_wait_eof - wait for the remote to reply to an EOF request .SH SYNOPSIS .nf #include int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION Wait for the remote end to send EOF. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH SEE ALSO .BR libssh2_channel_send_eof(3) .BR libssh2_channel_eof(3) libssh2-1.11.0/docs/libssh2_channel_set_blocking.30000644000175000017500000000131714424650606016667 00000000000000.TH libssh2_channel_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_set_blocking - set or clear blocking mode on channel .SH SYNOPSIS .nf #include void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking); .fi .SH DESCRIPTION \fIchannel\fP - channel stream to set or clean blocking status on. \fIblocking\fP - Set to a non-zero value to make the channel block, or zero to make it non-blocking. Currently this is a short cut call to .BR libssh2_session_set_blocking(3) and therefore will affect the session and all channels. .SH RETURN VALUE None .SH SEE ALSO .BR libssh2_session_set_blocking(3) .BR libssh2_channel_read_ex(3) .BR libssh2_channel_write_ex(3) libssh2-1.11.0/docs/libssh2_knownhost_writefile.30000644000175000017500000000154514424650606016643 00000000000000.\" .\" Copyright (c) 2009 by Daniel Stenberg .\" .TH libssh2_knownhost_writefile 3 "28 May 2009" "libssh2" "libssh2" .SH NAME libssh2_knownhost_writefile - write a collection of known hosts to a file .SH SYNOPSIS .nf #include int libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, const char *filename, int type); .fi .SH DESCRIPTION Writes all the known hosts to the specified file using the specified file format. \fIfilename\fP specifies what filename to create \fItype\fP specifies what file type it is, and \fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported format. .SH RETURN VALUE Returns a regular libssh2 error code, where negative values are error codes and 0 indicates success. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_knownhost_readfile(3) .BR libssh2_knownhost_add(3) libssh2-1.11.0/docs/libssh2_userauth_keyboard_interactive_ex.30000644000175000017500000000445014424650606021346 00000000000000.TH libssh2_userauth_keyboard_interactive_ex 3 "8 Mar 2008" "libssh2 0.19" "libssh2" .SH NAME libssh2_userauth_keyboard_interactive_ex - authenticate a session using keyboard-interactive authentication .SH SYNOPSIS .nf #include int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(*response_callback)); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by \fIlibssh2_session_init_ex(3)\fP. \fIusername\fP - Name of user to attempt keyboard-interactive authentication for. \fIusername_len\fP - Length of username parameter. \fIresponse_callback\fP - As authentication proceeds, the host issues several (1 or more) challenges and requires responses. This callback will be called at this moment. The callback is responsible to obtain responses for the challenges, fill the provided data structure and then return control. Responses will be sent to the host. String values will be free(3)ed by the library. The callback prototype must match this: .nf void response(const char *name, int name_len, const char *instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract); .fi Attempts keyboard-interactive (challenge/response) authentication. Note that many SSH servers will always issue a single "password" challenge, requesting actual password as response, but it is not required by the protocol, and various authentication schemes, such as smartcard authentication may use keyboard-interactive authentication type too. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/password or public/private key. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_sftp_get_channel.30000644000175000017500000000104314424650606016033 00000000000000.TH libssh2_sftp_get_channel 3 "9 Sep 2011" "libssh2 1.4.0" "libssh2" .SH NAME libssh2_sftp_get_channel - return the channel of sftp .SH SYNOPSIS .nf #include #include LIBSSH2_CHANNEL * libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) Return the channel of the given sftp handle. .SH RETURN VALUE The channel of the SFTP instance or NULL if something was wrong. .SH AVAILABILITY Added in 1.4.0 .SH SEE ALSO .BR libssh2_sftp_init(3) libssh2-1.11.0/docs/libssh2_agent_free.30000644000175000017500000000075114424650606014634 00000000000000.\" .\" Copyright (c) 2009 by Daiki Ueno .\" .TH libssh2_agent_free 3 "28 May 2009" "libssh2" "libssh2" .SH NAME libssh2_agent_free - free an ssh-agent handle .SH SYNOPSIS .nf #include void libssh2_agent_free(LIBSSH2_AGENT *agent); .fi .SH DESCRIPTION Free an ssh-agent handle. This function also frees the internal collection of public keys. .SH RETURN VALUE None. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_agent_init(3) .BR libssh2_agent_disconnect(3) libssh2-1.11.0/docs/libssh2_sftp_last_error.30000644000175000017500000000135514424650606015746 00000000000000.TH libssh2_sftp_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_last_error - return the last SFTP-specific error code .SH SYNOPSIS .nf #include #include unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); .fi .SH DESCRIPTION \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) Returns the last error code produced by the SFTP layer. Note that this only returns a sensible error code if libssh2 returned LIBSSH2_ERROR_SFTP_PROTOCOL in a previous call. Using \fBlibssh2_sftp_last_error(3)\fP without a preceding SFTP protocol error, it will return an unspecified value. .SH RETURN VALUE Current error code state of the SFTP instance. .SH SEE ALSO .BR libssh2_sftp_init(3) libssh2-1.11.0/docs/libssh2_session_block_directions.30000644000175000017500000000223414424650606017613 00000000000000.TH libssh2_session_block_directions 3 "1 Oct 2008" "libssh2" "libssh2" .SH NAME libssh2_session_block_directions - get directions to wait for .SH SYNOPSIS .nf #include int libssh2_session_block_directions(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by \fBlibssh2_session_init_ex(3)\fP When any of libssh2 functions return \fBLIBSSH2_ERROR_EAGAIN\fP an application should wait for the socket to have data available for reading or writing. Depending on the return value of \fIlibssh2_session_block_directions(3)\fP an application should wait for read, write or both. .SH RETURN VALUE Returns the set of directions as a binary mask. Can be a combination of: LIBSSH2_SESSION_BLOCK_INBOUND: Inbound direction blocked. LIBSSH2_SESSION_BLOCK_OUTBOUND: Outbound direction blocked. Application should wait for data to be available for socket prior to calling a libssh2 function again. If \fBLIBSSH2_SESSION_BLOCK_INBOUND\fP is set select should contain the session socket in readfds set. Correspondingly in case of \fBLIBSSH2_SESSION_BLOCK_OUTBOUND\fP writefds set should contain the socket. .SH AVAILABILITY Added in 1.0 libssh2-1.11.0/docs/libssh2_sftp_init.30000644000175000017500000000251114424650606014530 00000000000000.TH libssh2_sftp_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_init - open SFTP channel for the given SSH session. .SH SYNOPSIS .nf #include #include LIBSSH2_SFTP * libssh2_sftp_init(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) Open a channel and initialize the SFTP subsystem. Although the SFTP subsystem operates over the same type of channel as those exported by the Channel API, the protocol itself implements its own unique binary packet protocol which must be managed with the libssh2_sftp_*() family of functions. When an SFTP session is complete, it must be destroyed using the .BR libssh2_sftp_shutdown(3) function. .SH RETURN VALUE A pointer to the newly allocated SFTP instance or NULL on failure. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. \fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block. .SH SEE ALSO .BR libssh2_sftp_shutdown(3) .BR libssh2_sftp_open_ex(3) libssh2-1.11.0/docs/libssh2_sftp_readdir_ex.30000644000175000017500000000517114424650606015700 00000000000000.TH libssh2_sftp_readdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_readdir_ex - read directory data from an SFTP handle .SH SYNOPSIS .nf #include #include int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, char *longentry, size_t longentry_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs); .fi .SH DESCRIPTION Reads a block of data from a LIBSSH2_SFTP_HANDLE and returns file entry information for the next entry, if any. \fIhandle\fP - is the SFTP File Handle as returned by .BR libssh2_sftp_open_ex(3) \fIbuffer\fP - is a pointer to a pre-allocated buffer of at least \fIbuffer_maxlen\fP bytes to read data into. \fIbuffer_maxlen\fP - is the length of buffer in bytes. If the length of the filename is longer than the space provided by buffer_maxlen it will be truncated to fit. \fIlongentry\fP - is a pointer to a pre-allocated buffer of at least \fIlongentry_maxlen\fP bytes to read data into. The format of the `longname' field is unspecified by SFTP protocol. It MUST be suitable for use in the output of a directory listing command (in fact, the recommended operation for a directory listing command is to display this data). \fIlongentry_maxlen\fP - is the length of longentry in bytes. If the length of the full directory entry is longer than the space provided by \fIlongentry_maxlen\fP it will be truncated to fit. \fIattrs\fP - is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate statbuf style data into. .SH RETURN VALUE Number of bytes actually populated into buffer (not counting the terminating zero), or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH BUG Passing in a too small buffer for 'buffer' or 'longentry' when receiving data only results in libssh2 1.2.7 or earlier to not copy the entire data amount, and it is not possible for the application to tell when it happens! .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. From 1.2.8, LIBSSH2_ERROR_BUFFER_TOO_SMALL is returned if any of the given 'buffer' or 'longentry' buffers are too small to fit the requested object name. .SH SEE ALSO .BR libssh2_sftp_open_ex(3), .BR libssh2_sftp_close_handle(3) libssh2-1.11.0/docs/libssh2_sftp_readlink.30000644000175000017500000000134314424650606015360 00000000000000.TH libssh2_sftp_readlink 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_readlink - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP .SH SYNOPSIS .nf #include #include #define libssh2_sftp_readlink(sftp, path, target, maxlen) \\ libssh2_sftp_symlink_ex((sftp), (path), strlen(path), \\ (target), (maxlen), \\ LIBSSH2_SFTP_READLINK) .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_symlink_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_symlink_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_symlink_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_symlink_ex(3) libssh2-1.11.0/docs/libssh2_banner_set.30000644000175000017500000000211514424650606014651 00000000000000.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_banner_set - set the SSH protocol banner for the local client .SH SYNOPSIS .nf #include int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner); .fi .SH DESCRIPTION This function is \fBDEPRECATED\fP. Use \fIlibssh2_session_banner_set(3)\fP instead! \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIbanner\fP - A pointer to a user defined banner Set the banner that will be sent to the remote host when the SSH session is started with .BR libssh2_session_handshake(3) This is optional; a banner corresponding to the protocol and libssh2 version will be sent by default. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH AVAILABILITY Marked as deprecated since 1.4.0 .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. .SH SEE ALSO .BR libssh2_session_handshake(3) libssh2-1.11.0/docs/libssh2_channel_x11_req_ex.30000644000175000017500000000303114424650606016173 00000000000000.TH libssh2_channel_x11_req_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_x11_req_ex - request an X11 forwarding channel .SH SYNOPSIS .nf #include int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number); int libssh2_channel_x11_req(LIBSSH2_CHANNEL *channel, int screen_number); .fi .SH DESCRIPTION \fIchannel\fP - Previously opened channel instance such as returned by .BR libssh2_channel_open_ex(3) \fIsingle_connection\fP - non-zero to only forward a single connection. \fIauth_proto\fP - X11 authentication protocol to use \fIauth_cookie\fP - the cookie (hexadecimal encoded). \fIscreen_number\fP - the XLL screen to forward Request an X11 forwarding on \fIchannel\fP. To use X11 forwarding, .BR libssh2_session_callback_set(3) must first be called to set \fBLIBSSH2_CALLBACK_X11\fP. This callback will be invoked when the remote host accepts the X11 forwarding. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP - .SH SEE ALSO .BR libssh2_channel_open_ex(3) .BR libssh2_session_callback_set(3) libssh2-1.11.0/docs/libssh2_session_set_read_timeout.30000644000175000017500000000122114424650606017625 00000000000000.TH libssh2_session_set_read_timeout 3 "13 Jan 2023" "libssh2" "libssh2" .SH NAME libssh2_session_set_read_timeout - set timeout for packet read functions .SH SYNOPSIS .nf #include void libssh2_session_set_read_timeout(LIBSSH2_SESSION *session, long timeout); .fi .SH DESCRIPTION Set the \fBtimeout\fP in seconds for how long libssh2 packet read function calls may wait until they consider the situation an error and return LIBSSH2_ERROR_TIMEOUT. By default or if you set the timeout to zero, the timeout will be set to 60 seconds. .SH RETURN VALUE Nothing .SH AVAILABILITY Added in 1.10.1 .SH SEE ALSO .BR libssh2_session_get_read_timeout(3) libssh2-1.11.0/docs/libssh2_version.30000644000175000017500000000232014424650606014214 00000000000000.TH libssh2_version 3 "23 Feb 2009" "libssh2" "libssh2" .SH NAME libssh2_version - return the libssh2 version number .SH SYNOPSIS .nf #include const char * libssh2_version(int required_version); .fi .SH DESCRIPTION If \fIrequired_version\fP is lower than or equal to the version number of the libssh2 in use, the version number of libssh2 is returned as a pointer to a zero terminated string. The \fIrequired_version\fP should be the version number as constructed by the LIBSSH2_VERSION_NUM define in the libssh2.h public header file, which is a 24 bit number in the 0xMMmmpp format. MM for major, mm for minor and pp for patch number. .SH RETURN VALUE The version number of libssh2 is returned as a pointer to a zero terminated string or NULL if the \fIrequired_version\fP is not fulfilled. .SH EXAMPLE To make sure you run with the correct libssh2 version: .nf if(!libssh2_version(LIBSSH2_VERSION_NUM)) { fprintf(stderr, \&"Runtime libssh2 version too old!\&"); exit(1); } .fi Unconditionally get the version number: .nf printf(\&"libssh2 version: %s\&", libssh2_version(0)); .fi .SH AVAILABILITY This function was added in libssh2 1.1, in previous versions there way no way to extract this info in run-time. libssh2-1.11.0/docs/SECURITY.md0000644000175000017500000001060714424650606012615 00000000000000libssh2 security ================ This document is intended to provide guidance on how security vulnerabilities should be handled in the libssh2 project. Publishing Information ---------------------- All known and public libssh2 vulnerabilities will be listed on [the libssh2 web site](https://www.libssh2.org/). Security vulnerabilities should not be entered in the project's public bug tracker unless the necessary configuration is in place to limit access to the issue to only the reporter and the project's security team. Vulnerability Handling ---------------------- The typical process for handling a new security vulnerability is as follows. No information should be made public about a vulnerability until it is formally announced at the end of this process. That means, for example that a bug tracker entry must NOT be created to track the issue since that will make the issue public and it should not be discussed on the project's public mailing list. Also messages associated with any commits should not make any reference to the security nature of the commit if done prior to the public announcement. - The person discovering the issue, the reporter, reports the vulnerability privately to `libssh2-security@haxx.se`. That is an email alias that reaches a handful of selected and trusted people. - Messages that do not relate to the reporting or managing of an undisclosed security vulnerability in libssh2 are ignored and no further action is required. - A person in the security team sends an e-mail to the original reporter to acknowledge the report. - The security team investigates the report and either rejects it or accepts it. - If the report is rejected, the team writes to the reporter to explain why. - If the report is accepted, the team writes to the reporter to let him/her know it is accepted and that they are working on a fix. - The security team discusses the problem, works out a fix, considers the impact of the problem and suggests a release schedule. This discussion should involve the reporter as much as possible. - The release of the information should be "as soon as possible" and is most often synced with an upcoming release that contains the fix. If the reporter, or anyone else, thinks the next planned release is too far away then a separate earlier release for security reasons should be considered. - Write a security advisory draft about the problem that explains what the problem is, its impact, which versions it affects, solutions or workarounds, when the release is out and make sure to credit all contributors properly. - Request a CVE number from [distros@openwall](https://oss-security.openwall.org/wiki/mailing-lists/distros) when also informing and preparing them for the upcoming public security vulnerability announcement - attach the advisory draft for information. Note that 'distros' will not accept an embargo longer than 14 days. - Update the "security advisory" with the CVE number. - The security team commits the fix in a private branch. The commit message should ideally contain the CVE number. This fix is usually also distributed to the 'distros' mailing list to allow them to use the fix prior to the public announcement. - At the day of the next release, the private branch is merged into the master branch and pushed. Once pushed, the information is accessible to the public and the actual release should follow suit immediately afterwards. - The project team creates a release that includes the fix. - The project team announces the release and the vulnerability to the world in the same manner we always announce releases. It gets sent to the libssh2 mailing list and the oss-security mailing list. - The security web page on the web site should get the new vulnerability mentioned. LIBSSH2-SECURITY (at haxx dot se) -------------------------------- Who is on this list? There are a couple of criteria you must meet, and then we might ask you to join the list or you can ask to join it. It really is not very formal. We basically only require that you have a long-term presence in the libssh2 project and you have shown an understanding for the project and its way of working. You must have been around for a good while and you should have no plans in vanishing in the near future. We do not make the list of participants public mostly because it tends to vary somewhat over time and a list somewhere will only risk getting outdated. libssh2-1.11.0/docs/libssh2_sftp_readdir.30000644000175000017500000000125414424650606015202 00000000000000.TH libssh2_sftp_readdir 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_readdir - convenience macro for \fIlibssh2_sftp_readdir_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_readdir_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_readdir_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_readdir_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_readdir_ex(3) libssh2-1.11.0/docs/libssh2_sign_sk.30000644000175000017500000000577514424650606014205 00000000000000.TH libssh2_sign_sk 3 "1 Jun 2022" "libssh2 1.10.0" "libssh2" .SH NAME libssh2_sign_sk - Create a signature from a FIDO2 authenticator. .SH SYNOPSIS .nf #include int libssh2_sign_sk(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract); typedef struct _LIBSSH2_PRIVKEY_SK { int algorithm; uint8_t flags; const char *application; const unsigned char *key_handle; size_t handle_len; LIBSSH2_USERAUTH_SK_SIGN_FUNC((*sign_callback)); void **orig_abstract; } LIBSSH2_PRIVKEY_SK; .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIsig\fP - A pointer to a buffer in which to place the signature. The caller is responsible for freeing the signature with LIBSSH2_FREE. \fIsig_len\fP - A pointer to the length of the sig parameter. \fIdata\fP - The data to sign. \fIdata_len\fP - The length of the data parameter. \fIabstract\fP - A pointer to a pointer to a LIBSSH2_PRIVKEY_SK. See description below. Create a signature from a FIDO2 authenticator, using either the sk-ssh-ed25519@openssh.com or sk-ecdsa-sha2-nistp256@openssh.com key exchange algorithms. The abstract parameter is a pointer to a pointer due to the internal workings of libssh2. The LIBSSH2_PRIVKEY_SK must be completely filled out, and the caller is responsible for all memory management of its fields. \fIalgorithm\fP - The signing algorithm to use. Possible values are LIBSSH2_HOSTKEY_TYPE_ED25519 and LIBSSH2_HOSTKEY_TYPE_ECDSA_256. \fIflags\fP - A bitmask specifying options for the authenticator. When LIBSSH2_SK_PRESENCE_REQUIRED is set, the authenticator requires a touch. When LIBSSH2_SK_VERIFICATION_REQUIRED is set, the authenticator requires a PIN. Many servers and authenticators do not work properly when LIBSSH2_SK_PRESENCE_REQUIRED is not set. \fIapplication\fP - A user-defined string to use as the RP name for the authenticator. Usually "ssh:". \fIkey_handle\fP - The key handle to use for the authenticator's allow list. \fIhandle_len\fP - The length of the key_handle parameter. \fIabstract\fP - User-defined data. When a PIN is required, use this to pass in the PIN, or a function pointer to retrieve the PIN. \fIkey_handle\fP The decoded key handle from the private key file. \fIhandle_len\fP The length of the key_handle parameter. \fIsign_callback\fP - Responsible for communicating with the hardware authenticator to generate a signature. On success, the signature information must be placed in the `\fIsig_info\fP sig_info parameter and the callback must return 0. On failure, it should return a negative number. See .BR libssh2_userauth_publickey_sk(3) for more information. \fIorig_abstract\fP - User-defined data. When a PIN is required, use this to pass in the PIN, or a function pointer to retrieve the PIN. .SH RETURN VALUE Return 0 on success or negative on failure. .SH SEE ALSO .BR libssh2_userauth_publickey_sk(3) libssh2-1.11.0/docs/libssh2_publickey_list_free.30000644000175000017500000000034514424650606016557 00000000000000.TH libssh2_publickey_list_free 3 "1 Jun 2007" "libssh2" "libssh2" .SH NAME libssh2_publickey_list_free - TODO .SH SYNOPSIS .nf .fi .SH DESCRIPTION .SH RETURN VALUE .SH ERRORS .SH AVAILABILITY Added in libssh2 ?.?.? .SH SEE ALSO libssh2-1.11.0/docs/libssh2_knownhost_writeline.30000644000175000017500000000313014424650606016643 00000000000000.\" .\" Copyright (c) 2009 by Daniel Stenberg .\" .TH libssh2_knownhost_writeline 3 "28 May 2009" "libssh2" "libssh2" .SH NAME libssh2_knownhost_writeline - convert a known host to a line for storage .SH SYNOPSIS .nf #include int libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, struct libssh2_knownhost *known, char *buffer, size_t buflen, size_t *outlen, int type); .fi .SH DESCRIPTION Converts a single known host to a single line of output for storage, using the 'type' output format. \fIknown\fP identifies which particular known host \fIbuffer\fP points to an allocated buffer \fIbuflen\fP is the size of the \fIbuffer\fP. See RETURN VALUE about the size. \fIoutlen\fP must be a pointer to a size_t variable that will get the output length of the stored data chunk. The number does not included the trailing zero! \fItype\fP specifies what file type it is, and \fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported format. .SH RETURN VALUE Returns a regular libssh2 error code, where negative values are error codes and 0 indicates success. If the provided buffer is deemed too small to fit the data libssh2 wants to store in it, LIBSSH2_ERROR_BUFFER_TOO_SMALL will be returned. The application is then advised to call the function again with a larger buffer. The \fIoutlen\fP size will then hold the requested size. .SH AVAILABILITY Added in libssh2 1.2 .SH SEE ALSO .BR libssh2_knownhost_get(3) .BR libssh2_knownhost_readline(3) .BR libssh2_knownhost_writefile(3) libssh2-1.11.0/docs/libssh2_session_banner_get.30000644000175000017500000000143314424650606016402 00000000000000.TH libssh2_session_banner_get 3 "9 Sep 2011" "libssh2" "libssh2" .SH NAME libssh2_session_banner_get - get the remote banner .SH SYNOPSIS .nf #include const char * libssh2_session_banner_get(oLIBSSH2_SESSION *session); .fi .SH DESCRIPTION Once the session has been setup and \fIlibssh2_session_handshake(3)\fP has completed successfully, this function can be used to get the server id from the banner each server presents. .SH RETURN VALUE A pointer to a string or NULL if something failed. The data pointed to will be allocated and associated to the session handle and will be freed by libssh2 when \fIlibssh2_session_free(3)\fP is used. .SH AVAILABILITY Added in 1.4.0 .SH SEE ALSO .BR libssh2_session_banner_set(3), .BR libssh2_session_handshake(3), .BR libssh2_session_free(3) libssh2-1.11.0/docs/AUTHORS0000644000175000017500000000230314435416425012067 00000000000000 libssh2 is the result of many friendly people. This list is an attempt to mention all contributors. If we have missed anyone, tell us! This list of names is a-z sorted. Adam Gobiowski Alexander Holyapin Alexander Lamaison Alfred Gebert Ben Kibbey Bjorn Stenborg Carlo Bramini Cristian Rodríguez Daiki Ueno Dan Casey Dan Fandrich Daniel Stenberg Dave Hayden Dave McCaldon David J Sullivan David Robins Dmitry Smirnov Douglas Masterson Edink Kadribasic Erik Brossler Francois Dupoux Gellule Xg Grubsky Grigory Guenter Knauf Heiner Steven Henrik Nordstrom James Housleys Jasmeet Bagga Jean-Louis Charton Jernej Kovacic Joey Degges John Little Jose Baars Jussi Mononen Kamil Dudka Lars Nordin Mark McPherson Mark Smith Markus Moeller Matt Lilley Matthew Booth Maxime Larocque Mike Protts Mikhail Gusarov Neil Gierman Olivier Hervieu Paul Howarth Paul Querna Paul Veldkamp Peter Krempa Peter O'Gorman Peter Stuge Pierre Joye Rafael Kitover Romain Bondue Sara Golemon Satish Mittal Sean Peterson Selcuk Gueney Simon Hart Simon Josefsson Sofian Brabez Steven Ayre Steven Dake Steven Van Ingelgem TJ Saunders Tommy Lindgren Tor Arntsen Viktor Szakats Vincent Jaulin Vincent Torri Vlad Grachov Wez Furlong Yang Tse Zl Liu libssh2-1.11.0/docs/libssh2_sftp_symlink_ex.30000644000175000017500000000535214424650606015755 00000000000000.TH libssh2_sftp_symlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_symlink_ex - read or set a symbolic link .SH SYNOPSIS .nf #include #include int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type); .fi .SH DESCRIPTION Create a symlink or read out symlink information from the remote side. \fIsftp\fP - SFTP instance as returned by .BR libssh2_sftp_init(3) \fIpath\fP - Remote filesystem object to create a symlink from or resolve. \fIpath_len\fP - Length of the name of the remote filesystem object to create a symlink from or resolve. \fItarget\fP - a pointer to a buffer. The buffer has different uses depending what the \fIlink_type\fP argument is set to. .br \fBLIBSSH2_SFTP_SYMLINK\fP: Remote filesystem object to link to. .br \fBLIBSSH2_SFTP_READLINK\fP: Pre-allocated buffer to resolve symlink target into. .br \fBLIBSSH2_SFTP_REALPATH\fP: Pre-allocated buffer to resolve realpath target into. \fItarget_len\fP - Length of the name of the remote filesystem target object. \fIlink_type\fP - One of the three previously mentioned constants which determines the resulting behavior of this function. These are convenience macros: .BR libssh2_sftp_symlink(3) : Create a symbolic link between two filesystem objects. .br .BR libssh2_sftp_readlink(3) : Resolve a symbolic link filesystem object to its next target. .br .BR libssh2_sftp_realpath(3) : Resolve a complex, relative, or symlinked filepath to its effective target. .SH RETURN VALUE When using LIBSSH2_SFTP_SYMLINK, this function returns 0 on success or negative on failure. When using LIBSSH2_SFTP_READLINK or LIBSSH2_SFTP_REALPATH, it returns the number of bytes it copied to the target buffer (not including the terminating zero) or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. From 1.2.8, LIBSSH2_ERROR_BUFFER_TOO_SMALL is returned if the given 'target' buffer is too small to fit the requested object name. .SH BUG Passing in a too small buffer when receiving data only results in libssh2 1.2.7 or earlier to not copy the entire data amount, and it is not possible for the application to tell when it happens! .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. .SH SEE ALSO .BR libssh2_sftp_init(3) libssh2-1.11.0/docs/libssh2_sftp_unlink.30000644000175000017500000000110314424650606015061 00000000000000.TH libssh2_sftp_unlink 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_unlink - convenience macro for \fIlibssh2_sftp_unlink_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_unlink_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_unlink_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_unlink_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_unlink_ex(3) libssh2-1.11.0/docs/libssh2_session_disconnect_ex.30000644000175000017500000000256014424650606017125 00000000000000.TH libssh2_session_disconnect_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_disconnect_ex - terminate transport layer .SH SYNOPSIS .nf #include int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang); int libssh2_session_disconnect(LIBSSH2_SESSION *session, const char *description); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) \fIreason\fP - One of the Disconnect Reason constants. \fIdescription\fP - Human readable reason for disconnection. \fIlang\fP - Localization string describing the language/encoding of the description provided. Send a disconnect message to the remote host associated with \fIsession\fP, along with a \fIreason\fP symbol and a verbose \fIdescription\fP. As a convenience, the macro .BR libssh2_session_disconnect(3) is provided. It calls .BR libssh2_session_disconnect_ex(3) with \fIreason\fP set to SSH_DISCONNECT_BY_APPLICATION and \fIlang\fP set to an empty string. .SH RETURN VALUE Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_sftp_mkdir.30000644000175000017500000000112514424650606014673 00000000000000.TH libssh2_sftp_mkdir 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_mkdir - convenience macro for \fIlibssh2_sftp_mkdir_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, long mode); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_mkdir_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_mkdir_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_mkdir_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_mkdir_ex(3) libssh2-1.11.0/docs/libssh2_publickey_list_fetch.30000644000175000017500000000034714424650606016731 00000000000000.TH libssh2_publickey_list_fetch 3 "1 Jun 2007" "libssh2" "libssh2" .SH NAME libssh2_publickey_list_fetch - TODO .SH SYNOPSIS .nf .fi .SH DESCRIPTION .SH RETURN VALUE .SH ERRORS .SH AVAILABILITY Added in libssh2 ?.?.? .SH SEE ALSO libssh2-1.11.0/docs/libssh2_channel_write.30000644000175000017500000000113514424650606015354 00000000000000.TH libssh2_channel_write 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_write - convenience macro for \fIlibssh2_channel_write_ex(3)\fP .SH SYNOPSIS .nf #include ssize_t libssh2_channel_write(LIBSSH2_CHANNEL *channel, const char *buf, size_t buflen); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_write_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_write_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_write_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_write_ex(3) libssh2-1.11.0/docs/libssh2_channel_eof.30000644000175000017500000000077314424650606015002 00000000000000.TH libssh2_channel_eof 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_eof - check a channel's EOF status .SH SYNOPSIS .nf #include int libssh2_channel_eof(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION \fIchannel\fP - active channel stream to set closed status on. Check if the remote host has sent an EOF status for the selected stream. .SH RETURN VALUE Returns 1 if the remote host has sent EOF, otherwise 0. Negative on failure. .SH SEE ALSO .BR libssh2_channel_close(3) libssh2-1.11.0/docs/libssh2_sftp_write.30000644000175000017500000000564314424650606014730 00000000000000.TH libssh2_sftp_write 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_write - write SFTP data .SH SYNOPSIS .nf #include #include ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count); .fi .SH DESCRIPTION \fBlibssh2_sftp_write(3)\fP writes a block of data to the SFTP server. This method is modeled after the POSIX write() function and uses the same calling semantics. \fIhandle\fP - SFTP file handle as returned by \fIlibssh2_sftp_open_ex(3)\fP. \fIbuffer\fP - points to the data to send off. \fIcount\fP - Number of bytes from 'buffer' to write. Note that it may not be possible to write all bytes as requested. \fIlibssh2_sftp_handle(3)\fP will use as much as possible of the buffer and put it into a single SFTP protocol packet. This means that to get maximum performance when sending larger files, you should try to always pass in at least 32K of data to this function. .SH WRITE AHEAD Starting in libssh2 version 1.2.8, the default behavior of libssh2 is to create several smaller outgoing packets for all data you pass to this function and it will return a positive number as soon as the first packet is acknowledged from the server. This has the effect that sometimes more data has been sent off but is not acked yet when this function returns, and when this function is subsequently called again to write more data, libssh2 will immediately figure out that the data is already received remotely. In most normal situation this should not cause any problems, but it should be noted that if you have once called libssh2_sftp_write() with data and it returns short, you MUST still assume that the rest of the data might have been cached so you need to make sure you do not alter that data and think that the version you have in your next function invoke will be detected or used. The reason for this funny behavior is that SFTP can only send 32K data in each packet and it gets all packets acked individually. This means we cannot use a simple serial approach if we want to reach high performance even on high latency connections. And we want that. .SH RETURN VALUE Actual number of bytes written or negative on failure. If used in non-blocking mode, it returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it is not really a failure per se. If this function returns 0 (zero) it should not be considered an error, but that there was no error but yet no payload data got sent to the other end. .SH ERRORS \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket. \fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP - \fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was received on the socket, or an SFTP operation caused an errorcode to be returned by the server. .SH SEE ALSO .BR libssh2_sftp_open_ex(3) libssh2-1.11.0/docs/libssh2_sftp_fstat.30000644000175000017500000000114114424650606014704 00000000000000.TH libssh2_sftp_fstat 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_fstat - convenience macro for \fIlibssh2_sftp_fstat_ex(3)\fP calls .SH SYNOPSIS .nf #include #include int libssh2_sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_fstat_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_fstat_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_fstat_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_fstat_ex(3) libssh2-1.11.0/docs/libssh2_sftp_rmdir.30000644000175000017500000000112514424650606014702 00000000000000.TH libssh2_sftp_rmdir 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_sftp_rmdir - convenience macro for \fIlibssh2_sftp_rmdir_ex(3)\fP .SH SYNOPSIS .nf #include #include #define libssh2_sftp_rmdir(sftp, path) \\ libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_sftp_rmdir_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_sftp_rmdir_ex(3)\fP .SH ERRORS See \fIlibssh2_sftp_rmdir_ex(3)\fP .SH SEE ALSO .BR libssh2_sftp_rmdir_ex(3) libssh2-1.11.0/docs/INSTALL_AUTOTOOLS0000644000175000017500000002703414424650606013530 00000000000000Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. When Building directly from Master ================================== If you want to build directly from the git repository, you must first generate the configure script and Makefile using autotools. Make sure that autoconf, automake and libtool are installed on your system, then execute: autoreconf -fi After executing this script, you can build the project as usual: ./configure make Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or shortly `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you do not want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you are using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it does not, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' is not included in this package, then this package does not need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Here is a another example: /bin/bash ./configure CONFIG_SHELL=/bin/bash Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent configuration-related scripts to be executed by `/bin/bash'. `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. More configure options ====================== Some ./configure options deserve additional comments: * --with-libgcrypt * --without-libgcrypt * --with-libgcrypt-prefix=DIR libssh2 can use the Libgcrypt library (https://www.gnupg.org/) for cryptographic operations. One of the cryptographic libraries is required. Configure will attempt to locate Libgcrypt automatically. If your installation of Libgcrypt is in another location, specify it using --with-libgcrypt-prefix. * --with-openssl * --without-openssl * --with-libssl-prefix=[DIR] libssh2 can use the OpenSSL library (https://www.openssl.org) for cryptographic operations. One of the cryptographic libraries is required. Configure will attempt to locate OpenSSL in the default location. If your installation of OpenSSL is in another location, specify it using --with-libssl-prefix. * --with-mbedtls * --without-mbedtls * --with-libmbedtls-prefix=[DIR] libssh2 can use the mbedTLS library (https://tls.mbed.org) for cryptographic operations. One of the cryptographic libraries is required. Configure will attempt to locate mbedTLS in the default location. If your installation of mbedTLS is in another location, specify it using --with-libmbedtls-prefix. * --with-libz * --without-libz * --with-libz-prefix=[DIR] If present, libssh2 will attempt to use the zlib (https://zlib.net/) for payload compression, however zlib is not required. If your installation of Libz is in another location, specify it using --with-libz-prefix. * --enable-debug Will make the build use more pedantic and strict compiler options as well as enable the libssh2_trace() function (for showing debug traces). libssh2-1.11.0/docs/libssh2_channel_window_write_ex.30000644000175000017500000000145214424650606017441 00000000000000.TH libssh2_channel_window_write_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_channel_window_write_ex - Check the status of the write window .SH SYNOPSIS .nf #include unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial) .fi .SH DESCRIPTION Check the status of the write window Returns the number of bytes which may be safely written on the channel without blocking. 'window_size_initial' (if passed) will be populated with the size of the initial window as defined by the channel_open request .SH RETURN VALUE Number of bytes which may be safely written on the channel without blocking. .SH ERRORS .SH SEE ALSO .BR libssh2_channel_window_read_ex(3), .BR libssh2_channel_receive_window_adjust(3) libssh2-1.11.0/docs/libssh2_sftp_tell.30000644000175000017500000000121514424650606014525 00000000000000.TH libssh2_sftp_tell 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_sftp_tell - get the current read/write position indicator for a file .SH SYNOPSIS .nf #include #include size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle); .fi .SH DESCRIPTION \fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open_ex(3)\fP. Returns the current offset of the file handle's internal pointer. Note that this is now deprecated. Use the newer \fBlibssh2_sftp_tell64(3)\fP instead! .SH RETURN VALUE Current offset from beginning of file in bytes. .SH SEE ALSO .BR libssh2_sftp_open_ex(3), .BR libssh2_sftp_tell64(3) libssh2-1.11.0/docs/libssh2_session_last_errno.30000644000175000017500000000104614424650606016446 00000000000000.TH libssh2_session_last_errno 3 "1 Jun 2007" "libssh2 0.15" "libssh2" .SH NAME libssh2_session_last_errno - get the most recent error number .SH SYNOPSIS .nf #include int libssh2_session_last_errno(LIBSSH2_SESSION *session); .fi .SH DESCRIPTION \fIsession\fP - Session instance as returned by .BR libssh2_session_init_ex(3) Determine the most recent error condition. .SH RETURN VALUE Numeric error code corresponding to the the Error Code constants. .SH SEE ALSO .BR libssh2_session_last_error(3) .BR libssh2_session_set_last_error(3) libssh2-1.11.0/docs/libssh2_free.30000644000175000017500000000113614424650606013454 00000000000000.TH libssh2_free 3 "13 Oct 2010" "libssh2" "libssh2" .SH NAME libssh2_free - deallocate libssh2 memory .SH SYNOPSIS .nf #include void libssh2_free(LIBSSH2_SESSION *session, void *ptr); .fi .SH DESCRIPTION Deallocate memory allocated by earlier call to libssh2 functions. It uses the memory allocation callbacks provided by the application, if any. Otherwise, this will call free(). This function is mostly useful under Windows when libssh2 is linked to one run-time library and the application to another. .SH AVAILABILITY Added in libssh2 1.2.8 .SH SEE ALSO .BR libssh2_session_init_ex(3) libssh2-1.11.0/docs/libssh2_channel_forward_listen.30000644000175000017500000000117314424650606017246 00000000000000.TH libssh2_channel_forward_listen 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_forward_listen - convenience macro for \fIlibssh2_channel_forward_listen_ex(3)\fP calls .SH SYNOPSIS .nf #include int libssh2_channel_forward_listen(LIBSSH2_SESSION *session, int port); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_forward_listen_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_forward_listen_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_forward_listen_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_forward_listen_ex(3) libssh2-1.11.0/docs/libssh2_channel_window_write.30000644000175000017500000000115314424650606016743 00000000000000.TH libssh2_channel_window_write 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2" .SH NAME libssh2_channel_window_write - convenience macro for \fIlibssh2_channel_window_write_ex(3)\fP calls .SH SYNOPSIS .nf #include unsigned long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel); .fi .SH DESCRIPTION This is a macro defined in a public libssh2 header file that is using the underlying function \fIlibssh2_channel_window_write_ex(3)\fP. .SH RETURN VALUE See \fIlibssh2_channel_window_write_ex(3)\fP .SH ERRORS See \fIlibssh2_channel_window_write_ex(3)\fP .SH SEE ALSO .BR libssh2_channel_window_write_ex(3) libssh2-1.11.0/docs/INSTALL_CMAKE.md0000644000175000017500000001110614424650606013347 00000000000000License: see COPYING Source code: https://github.com/libssh2/libssh2 Web site source code: https://github.com/libssh2/www Installation instructions are in docs/INSTALL ======= To build libssh2 you will need CMake v3.1 or later [1] and one of the following cryptography libraries: * OpenSSL * wolfSSL * Libgcrypt * WinCNG * mbedTLS Getting started --------------- If you are happy with the default options, make a new build directory, change to it, configure the build environment and build the project: ``` mkdir bin cd bin cmake .. cmake --build . ``` libssh2 will be built as a static library and will use any cryptography library available. The library binary will be put in `bin/src`, with the examples in `bin/example` and the tests in `bin/tests`. Customising the build --------------------- You might want to customise the build options. You can pass the options to CMake on the command line: cmake -D