Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
TLMSP curl
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CYBER - Cyber Security
TS 103 523 MSP
TLMSP
TLMSP curl
Commits
98696688
Commit
98696688
authored
14 years ago
by
Daniel Stenberg
Browse files
Options
Downloads
Patches
Plain Diff
SSH: move knownhost logic to separate function
parent
b903186f
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lib/ssh.c
+126
-112
126 additions, 112 deletions
lib/ssh.c
with
126 additions
and
112 deletions
lib/ssh.c
+
126
−
112
View file @
98696688
...
...
@@ -504,6 +504,129 @@ static int sshkeycallback(CURL *easy,
#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
#endif
static
CURLcode
ssh_knownhost
(
struct
connectdata
*
conn
)
{
struct
SessionHandle
*
data
=
conn
->
data
;
CURLcode
result
=
CURLE_OK
;
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
if
(
data
->
set
.
str
[
STRING_SSH_KNOWNHOSTS
])
{
/* we're asked to verify the host against a file */
struct
ssh_conn
*
sshc
=
&
conn
->
proto
.
sshc
;
int
rc
;
int
keytype
;
size_t
keylen
;
const
char
*
remotekey
=
libssh2_session_hostkey
(
sshc
->
ssh_session
,
&
keylen
,
&
keytype
);
int
keycheck
;
int
keybit
;
if
(
remotekey
)
{
/*
* A subject to figure out is what host name we need to pass in here.
* What host name does OpenSSH store in its file if an IDN name is
* used?
*/
struct
libssh2_knownhost
*
host
;
enum
curl_khmatch
keymatch
;
curl_sshkeycallback
func
=
data
->
set
.
ssh_keyfunc
?
data
->
set
.
ssh_keyfunc
:
sshkeycallback
;
struct
curl_khkey
knownkey
;
struct
curl_khkey
*
knownkeyp
=
NULL
;
struct
curl_khkey
foundkey
;
keybit
=
(
keytype
==
LIBSSH2_HOSTKEY_TYPE_RSA
)
?
LIBSSH2_KNOWNHOST_KEY_SSHRSA:
LIBSSH2_KNOWNHOST_KEY_SSHDSS
;
keycheck
=
libssh2_knownhost_check
(
sshc
->
kh
,
conn
->
host
.
name
,
remotekey
,
keylen
,
LIBSSH2_KNOWNHOST_TYPE_PLAIN
|
LIBSSH2_KNOWNHOST_KEYENC_RAW
|
keybit
,
&
host
);
infof
(
data
,
"SSH host check: %d, key: %s
\n
"
,
keycheck
,
(
keycheck
<=
LIBSSH2_KNOWNHOST_CHECK_MISMATCH
)
?
host
->
key
:
"<none>"
);
/* setup 'knownkey' */
if
(
keycheck
<=
LIBSSH2_KNOWNHOST_CHECK_MISMATCH
)
{
knownkey
.
key
=
host
->
key
;
knownkey
.
len
=
0
;
knownkey
.
keytype
=
(
keytype
==
LIBSSH2_HOSTKEY_TYPE_RSA
)
?
CURLKHTYPE_RSA
:
CURLKHTYPE_DSS
;
knownkeyp
=
&
knownkey
;
}
/* setup 'foundkey' */
foundkey
.
key
=
remotekey
;
foundkey
.
len
=
keylen
;
foundkey
.
keytype
=
(
keytype
==
LIBSSH2_HOSTKEY_TYPE_RSA
)
?
CURLKHTYPE_RSA
:
CURLKHTYPE_DSS
;
/*
* if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
* curl_khmatch enum are ever modified, we need to introduce a
* translation table here!
*/
keymatch
=
(
enum
curl_khmatch
)
keycheck
;
/* Ask the callback how to behave */
rc
=
func
(
data
,
knownkeyp
,
/* from the knownhosts file */
&
foundkey
,
/* from the remote host */
keymatch
,
data
->
set
.
ssh_keyfunc_userp
);
}
else
/* no remotekey means failure! */
rc
=
CURLKHSTAT_REJECT
;
switch
(
rc
)
{
default:
/* unknown return codes will equal reject */
case
CURLKHSTAT_REJECT
:
state
(
conn
,
SSH_SESSION_FREE
);
case
CURLKHSTAT_DEFER
:
/* DEFER means bail out but keep the SSH_HOSTKEY state */
result
=
sshc
->
actualcode
=
CURLE_PEER_FAILED_VERIFICATION
;
break
;
case
CURLKHSTAT_FINE
:
case
CURLKHSTAT_FINE_ADD_TO_FILE
:
/* proceed */
if
(
keycheck
!=
LIBSSH2_KNOWNHOST_CHECK_MATCH
)
{
/* the found host+key didn't match but has been told to be fine
anyway so we add it in memory */
int
addrc
=
libssh2_knownhost_add
(
sshc
->
kh
,
conn
->
host
.
name
,
NULL
,
remotekey
,
keylen
,
LIBSSH2_KNOWNHOST_TYPE_PLAIN
|
LIBSSH2_KNOWNHOST_KEYENC_RAW
|
keybit
,
NULL
);
if
(
addrc
)
infof
(
data
,
"Warning adding the known host %s failed!
\n
"
,
conn
->
host
.
name
);
else
if
(
rc
==
CURLKHSTAT_FINE_ADD_TO_FILE
)
{
/* now we write the entire in-memory list of known hosts to the
known_hosts file */
int
wrc
=
libssh2_knownhost_writefile
(
sshc
->
kh
,
data
->
set
.
str
[
STRING_SSH_KNOWNHOSTS
],
LIBSSH2_KNOWNHOST_FILE_OPENSSH
);
if
(
wrc
)
{
infof
(
data
,
"Warning, writing %s failed!
\n
"
,
data
->
set
.
str
[
STRING_SSH_KNOWNHOSTS
]);
}
}
}
break
;
}
}
#else
/* HAVE_LIBSSH2_KNOWNHOST_API */
(
void
)
conn
;
#endif
return
result
;
}
/*
* ssh_statemach_act() runs the SSH state machine as far as it can without
* blocking and without reaching the end. The data the pointer 'block' points
...
...
@@ -595,118 +718,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
}
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
if
(
data
->
set
.
str
[
STRING_SSH_KNOWNHOSTS
])
{
/* we're asked to verify the host against a file */
int
keytype
;
size_t
keylen
;
const
char
*
remotekey
=
libssh2_session_hostkey
(
sshc
->
ssh_session
,
&
keylen
,
&
keytype
);
int
keycheck
;
int
keybit
;
if
(
remotekey
)
{
/*
* A subject to figure out is what host name we need to pass in here.
* What host name does OpenSSH store in its file if an IDN name is
* used?
*/
struct
libssh2_knownhost
*
host
;
enum
curl_khmatch
keymatch
;
curl_sshkeycallback
func
=
data
->
set
.
ssh_keyfunc
?
data
->
set
.
ssh_keyfunc
:
sshkeycallback
;
struct
curl_khkey
knownkey
;
struct
curl_khkey
*
knownkeyp
=
NULL
;
struct
curl_khkey
foundkey
;
keybit
=
(
keytype
==
LIBSSH2_HOSTKEY_TYPE_RSA
)
?
LIBSSH2_KNOWNHOST_KEY_SSHRSA:
LIBSSH2_KNOWNHOST_KEY_SSHDSS
;
keycheck
=
libssh2_knownhost_check
(
sshc
->
kh
,
conn
->
host
.
name
,
remotekey
,
keylen
,
LIBSSH2_KNOWNHOST_TYPE_PLAIN
|
LIBSSH2_KNOWNHOST_KEYENC_RAW
|
keybit
,
&
host
);
infof
(
data
,
"SSH host check: %d, key: %s
\n
"
,
keycheck
,
(
keycheck
<=
LIBSSH2_KNOWNHOST_CHECK_MISMATCH
)
?
host
->
key
:
"<none>"
);
/* setup 'knownkey' */
if
(
keycheck
<=
LIBSSH2_KNOWNHOST_CHECK_MISMATCH
)
{
knownkey
.
key
=
host
->
key
;
knownkey
.
len
=
0
;
knownkey
.
keytype
=
(
keytype
==
LIBSSH2_HOSTKEY_TYPE_RSA
)
?
CURLKHTYPE_RSA
:
CURLKHTYPE_DSS
;
knownkeyp
=
&
knownkey
;
}
/* setup 'foundkey' */
foundkey
.
key
=
remotekey
;
foundkey
.
len
=
keylen
;
foundkey
.
keytype
=
(
keytype
==
LIBSSH2_HOSTKEY_TYPE_RSA
)
?
CURLKHTYPE_RSA
:
CURLKHTYPE_DSS
;
/*
* if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
* curl_khmatch enum are ever modified, we need to introduce a
* translation table here!
*/
keymatch
=
(
enum
curl_khmatch
)
keycheck
;
/* Ask the callback how to behave */
rc
=
func
(
data
,
knownkeyp
,
/* from the knownhosts file */
&
foundkey
,
/* from the remote host */
keymatch
,
data
->
set
.
ssh_keyfunc_userp
);
}
else
/* no remotekey means failure! */
rc
=
CURLKHSTAT_REJECT
;
switch
(
rc
)
{
default:
/* unknown return codes will equal reject */
case
CURLKHSTAT_REJECT
:
state
(
conn
,
SSH_SESSION_FREE
);
case
CURLKHSTAT_DEFER
:
/* DEFER means bail out but keep the SSH_HOSTKEY state */
result
=
sshc
->
actualcode
=
CURLE_PEER_FAILED_VERIFICATION
;
break
;
case
CURLKHSTAT_FINE
:
case
CURLKHSTAT_FINE_ADD_TO_FILE
:
/* proceed */
if
(
keycheck
!=
LIBSSH2_KNOWNHOST_CHECK_MATCH
)
{
/* the found host+key didn't match but has been told to be fine
anyway so we add it in memory */
int
addrc
=
libssh2_knownhost_add
(
sshc
->
kh
,
conn
->
host
.
name
,
NULL
,
remotekey
,
keylen
,
LIBSSH2_KNOWNHOST_TYPE_PLAIN
|
LIBSSH2_KNOWNHOST_KEYENC_RAW
|
keybit
,
NULL
);
if
(
addrc
)
infof
(
data
,
"Warning adding the known host %s failed!
\n
"
,
conn
->
host
.
name
);
else
if
(
rc
==
CURLKHSTAT_FINE_ADD_TO_FILE
)
{
/* now we write the entire in-memory list of known hosts to the
known_hosts file */
int
wrc
=
libssh2_knownhost_writefile
(
sshc
->
kh
,
data
->
set
.
str
[
STRING_SSH_KNOWNHOSTS
],
LIBSSH2_KNOWNHOST_FILE_OPENSSH
);
if
(
wrc
)
{
infof
(
data
,
"Warning, writing %s failed!
\n
"
,
data
->
set
.
str
[
STRING_SSH_KNOWNHOSTS
]);
}
}
}
break
;
}
}
#endif
/* HAVE_LIBSSH2_KNOWNHOST_API */
state
(
conn
,
SSH_AUTHLIST
);
result
=
ssh_knownhost
(
conn
);
if
(
!
result
)
state
(
conn
,
SSH_AUTHLIST
);
break
;
case
SSH_AUTHLIST
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment