CURLOPT_SSH_KEYFUNCTION.md (4566B)
1 --- 2 c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 3 SPDX-License-Identifier: curl 4 Title: CURLOPT_SSH_KEYFUNCTION 5 Section: 3 6 Source: libcurl 7 See-also: 8 - CURLOPT_SSH_KEYDATA (3) 9 - CURLOPT_SSH_KNOWNHOSTS (3) 10 Protocol: 11 - SFTP 12 - SCP 13 Added-in: 7.19.6 14 --- 15 16 # NAME 17 18 CURLOPT_SSH_KEYFUNCTION - callback for known host matching logic 19 20 # SYNOPSIS 21 22 ~~~c 23 #include <curl/curl.h> 24 25 enum curl_khstat { 26 CURLKHSTAT_FINE_ADD_TO_FILE, 27 CURLKHSTAT_FINE, 28 CURLKHSTAT_REJECT, /* reject the connection, return an error */ 29 CURLKHSTAT_DEFER, /* do not accept it, but we cannot answer right 30 now. Causes a CURLE_PEER_FAILED_VERIFICATION error but 31 the connection is left intact */ 32 CURLKHSTAT_FINE_REPLACE 33 }; 34 35 enum curl_khmatch { 36 CURLKHMATCH_OK, /* match */ 37 CURLKHMATCH_MISMATCH, /* host found, key mismatch */ 38 CURLKHMATCH_MISSING, /* no matching host/key found */ 39 }; 40 41 struct curl_khkey { 42 const char *key; /* points to a null-terminated string encoded with 43 base64 if len is zero, otherwise to the "raw" 44 data */ 45 size_t len; 46 enum curl_khtype keytype; 47 }; 48 49 int ssh_keycallback(CURL *easy, 50 const struct curl_khkey *knownkey, 51 const struct curl_khkey *foundkey, 52 enum curl_khmatch match, 53 void *clientp); 54 55 CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSH_KEYFUNCTION, 56 ssh_keycallback); 57 ~~~ 58 59 # DESCRIPTION 60 61 Pass a pointer to your callback function, which should match the prototype 62 shown above. 63 64 It gets called when the known_host matching has been done, to allow the 65 application to act and decide for libcurl how to proceed. The callback is only 66 called if CURLOPT_SSH_KNOWNHOSTS(3) is also set. 67 68 This callback function gets passed the curl handle, the key from the 69 known_hosts file *knownkey*, the key from the remote site *foundkey*, info 70 from libcurl on the matching status and a custom pointer (set with 71 CURLOPT_SSH_KEYDATA(3)). It MUST return one of the following return codes to 72 tell libcurl how to act: 73 74 ## CURLKHSTAT_FINE_REPLACE 75 76 The new host+key is accepted and libcurl replaces the old host+key into the 77 known_hosts file before continuing with the connection. This also adds the new 78 host+key combo to the known_host pool kept in memory if it was not already 79 present there. The adding of data to the file is done by completely replacing 80 the file with a new copy, so the permissions of the file must allow 81 this. (Added in 7.73.0) 82 83 ## CURLKHSTAT_FINE_ADD_TO_FILE 84 85 The host+key is accepted and libcurl appends it to the known_hosts file before 86 continuing with the connection. This also adds the host+key combo to the 87 known_host pool kept in memory if it was not already present there. The adding 88 of data to the file is done by completely replacing the file with a new copy, 89 so the permissions of the file must allow this. 90 91 ## CURLKHSTAT_FINE 92 93 The host+key is accepted libcurl continues with the connection. This also adds 94 the host+key combo to the known_host pool kept in memory if it was not already 95 present there. 96 97 ## CURLKHSTAT_REJECT 98 99 The host+key is rejected. libcurl denies the connection to continue and it is 100 closed. 101 102 ## CURLKHSTAT_DEFER 103 104 The host+key is rejected, but the SSH connection is asked to be kept alive. 105 This feature could be used when the app wants to return and act on the 106 host+key situation and then retry without needing the overhead of setting it 107 up from scratch again. 108 109 # DEFAULT 110 111 NULL 112 113 # %PROTOCOLS% 114 115 # EXAMPLE 116 117 ~~~c 118 struct mine { 119 void *custom; 120 }; 121 122 static int keycb(CURL *easy, 123 const struct curl_khkey *knownkey, 124 const struct curl_khkey *foundkey, 125 enum curl_khmatch match, 126 void *clientp) 127 { 128 /* 'clientp' points to the callback_data struct */ 129 /* investigate the situation and return the correct value */ 130 return CURLKHSTAT_FINE_ADD_TO_FILE; 131 } 132 133 int main(void) 134 { 135 CURL *curl = curl_easy_init(); 136 if(curl) { 137 struct mine callback_data; 138 curl_easy_setopt(curl, CURLOPT_URL, "sftp://example.com/thisfile.txt"); 139 curl_easy_setopt(curl, CURLOPT_SSH_KEYFUNCTION, keycb); 140 curl_easy_setopt(curl, CURLOPT_SSH_KEYDATA, &callback_data); 141 curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/home/user/known_hosts"); 142 143 curl_easy_perform(curl); 144 } 145 } 146 ~~~ 147 148 # %AVAILABILITY% 149 150 # RETURN VALUE 151 152 curl_easy_setopt(3) returns a CURLcode indicating success or error. 153 154 CURLE_OK (0) means everything was OK, non-zero means an error occurred, see 155 libcurl-errors(3).