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