Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nxssh
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Konstantin Artyushkin
nxssh
Commits
9553287a
Commit
9553287a
authored
8 years ago
by
Stas Korobeynikov
Committed by
Pavel Vainerman
7 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add ssh webproxy connect function
parent
1445232a
master
ci/latest-build
fix-openssl-1.1.patch-bug12901
7.5-alt13
7.5-alt12
7.5-alt11
7.5-alt10
7.5-alt9
7.5-alt8
7.5-alt7
7.5-alt6
7.5-alt5
7.5-alt4
7.5-alt3
7.5-alt2
7.5-alt1
7.5-alt0.5
7.5-alt0.4
7.5-alt0.3
7.5-alt0.2
7.5-alt0.M80P.0.5
No related merge requests found
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
319 additions
and
1 deletion
+319
-1
sshconnect.c
sshconnect.c
+315
-1
sshconnect.h
sshconnect.h
+4
-0
No files found.
sshconnect.c
View file @
9553287a
...
...
@@ -91,6 +91,17 @@ extern uid_t original_effective_uid;
static
int
show_other_keys
(
struct
hostkeys
*
,
Key
*
);
static
void
warn_changed_key
(
Key
*
);
static
const
char
*
sockaddr_ntop
(
struct
sockaddr
*
sa
,
socklen_t
salen
)
{
static
char
addrbuf
[
NI_MAXHOST
];
if
(
getnameinfo
(
sa
,
salen
,
addrbuf
,
sizeof
(
addrbuf
),
NULL
,
0
,
NI_NUMERICHOST
)
!=
0
)
fatal
(
"sockaddr_ntop: getnameinfo NI_NUMERICHOST failed"
);
return
addrbuf
;
}
/* Expand a proxy command */
static
char
*
expand_proxy_command
(
const
char
*
proxy_command
,
const
char
*
user
,
...
...
@@ -420,6 +431,309 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
return
(
result
);
}
int
ssh_webproxy_connect
(
const
char
*
proxy_host
,
u_short
proxy_port
,
const
char
*
proxy_username
,
const
char
*
proxy_passwd
,
const
char
*
host
,
struct
sockaddr_storage
*
hostaddr
,
u_short
port
,
int
family
,
int
connection_attempts
,
int
needpriv
)
{
int
gaierr
;
int
on
=
1
;
int
sock
=
-
1
,
attempt
;
char
ntop
[
NI_MAXHOST
],
strport
[
NI_MAXSERV
];
struct
addrinfo
hints
,
*
ai
,
*
aitop
;
struct
servent
*
sp
;
char
readbuf
[
1024
];
char
writebuf
[
1024
];
fd_set
fds
;
struct
timeval
tv
;
int
sel_ret
;
int
i
,
r
;
/*
* Did we get only other errors than "Connection refused" (which
* should block fallback to rsh and similar), or did we get at least
* one "Connection refused"?
*/
int
full_failure
=
1
;
debug2
(
"ssh_webproxy_connect: needpriv %d"
,
needpriv
);
/* Get default port if port has not been set. */
if
(
proxy_port
==
0
)
{
proxy_port
=
3128
;
}
if
(
port
==
0
)
{
sp
=
getservbyname
(
SSH_SERVICE_NAME
,
"tcp"
);
if
(
sp
)
{
port
=
ntohs
(
sp
->
s_port
);
}
else
{
port
=
SSH_DEFAULT_PORT
;
}
}
memset
(
&
hints
,
0
,
sizeof
(
hints
));
hints
.
ai_family
=
family
;
hints
.
ai_socktype
=
SOCK_STREAM
;
snprintf
(
strport
,
sizeof
strport
,
"%u"
,
proxy_port
);
if
((
gaierr
=
getaddrinfo
(
proxy_host
,
strport
,
&
hints
,
&
aitop
))
!=
0
)
{
if
(
NxAdminModeEnabled
)
{
fprintf
(
stdout
,
"NX> 207 %s: %.100s: %s
\n
"
,
__progname
,
proxy_host
,
gai_strerror
(
gaierr
));
fatal
(
"%s: %.100s: %s"
,
__progname
,
proxy_host
,
gai_strerror
(
gaierr
));
}
else
if
(
NxAuthOnlyModeEnabled
)
{
fatal
(
"NX> 207 %s: %.100s: %s"
,
__progname
,
proxy_host
,
gai_strerror
(
gaierr
));
}
else
{
fatal
(
"%s: %.100s: %s"
,
__progname
,
proxy_host
,
gai_strerror
(
gaierr
));
}
}
/*
* Try to connect several times. On some machines, the first time
* will sometimes fail. In general socket code appears to behave
* quite magically on many machines.
*/
for
(
attempt
=
0
;
;)
{
if
(
attempt
>
0
)
{
debug
(
"Trying again..."
);
}
/* Loop through addresses for this host, and try each one in
sequence until the connection succeeds. */
for
(
ai
=
aitop
;
ai
;
ai
=
ai
->
ai_next
)
{
if
(
ai
->
ai_family
!=
AF_INET
&&
ai
->
ai_family
!=
AF_INET6
)
{
continue
;
}
if
(
getnameinfo
(
ai
->
ai_addr
,
ai
->
ai_addrlen
,
ntop
,
sizeof
(
ntop
),
strport
,
sizeof
(
strport
),
NI_NUMERICHOST
|
NI_NUMERICSERV
)
!=
0
)
{
error
(
"ssh_connect: getnameinfo failed"
);
continue
;
}
debug
(
"Connecting to web proxy %.200s [%.100s] port %s."
,
proxy_host
,
ntop
,
strport
);
/* Create a socket for connecting. */
sock
=
ssh_create_socket
(
needpriv
,
ai
);
if
(
sock
<
0
)
{
/* Any error is already output */
continue
;
}
if
(
timeout_connect
(
sock
,
ai
->
ai_addr
,
ai
->
ai_addrlen
,
options
.
connection_timeout
)
>=
0
)
{
/* Successful connection. */
memcpy
(
hostaddr
,
ai
->
ai_addr
,
ai
->
ai_addrlen
);
break
;
}
else
{
if
(
errno
==
ECONNREFUSED
)
{
full_failure
=
0
;
}
if
(
NxAdminModeEnabled
)
{
fprintf
(
stdout
,
"NX> 207 nxssh: connect to address %s port %s: %s
\n
"
,
sockaddr_ntop
(
ai
->
ai_addr
,
ai
->
ai_addrlen
),
strport
,
strerror
(
errno
));
}
else
if
(
NxAuthOnlyModeEnabled
)
{
fprintf
(
stdout
,
"NX> 207 nxssh: connect to address %s port %s: %s"
,
sockaddr_ntop
(
ai
->
ai_addr
,
ai
->
ai_addrlen
),
strport
,
strerror
(
errno
));
}
else
{
debug
(
"connect to address %s port %s: %s"
,
ntop
,
strport
,
strerror
(
errno
));
}
/*
* Close the failed socket; there appear to
* be some problems when reusing a socket for
* which connect() has already returned an
* error.
*/
close
(
sock
);
}
}
if
(
ai
)
{
if
(
NxModeEnabled
)
{
logit
(
"NX> 200 Connected to web proxy at address: %.200s on port: %.200s"
,
ntop
,
strport
);
}
break
;
/* Successful connection. */
}
attempt
++
;
if
(
attempt
>=
connection_attempts
)
{
break
;
}
/* Sleep a moment before retrying. */
sleep
(
1
);
}
freeaddrinfo
(
aitop
);
/* Return failure if we didn't get a successful connection. */
if
(
attempt
>=
connection_attempts
)
{
logit
(
"ssh: connect to host %s port %s: %s"
,
proxy_host
,
strport
,
strerror
(
errno
));
return
full_failure
?
ECONNABORTED
:
ECONNREFUSED
;
}
debug
(
"Connection to web proxy established."
);
#ifdef TEST
logit
(
"NX> 280 SSH connection established with fd: %d"
,
sock
);
#endif
/* Set SO_KEEPALIVE if requested. */
if
(
options
.
tcp_keep_alive
&&
setsockopt
(
sock
,
SOL_SOCKET
,
SO_KEEPALIVE
,
(
void
*
)
&
on
,
sizeof
(
on
))
<
0
)
{
error
(
"setsockopt SO_KEEPALIVE: %.100s"
,
strerror
(
errno
));
}
if
(
strcspn
(
host
,
"
\r\n\t
[]:"
)
!=
strlen
(
host
))
{
fatal
(
"ssh_webproxy_connect: invalid hostname %.100s"
,
host
);
}
if
(
strchr
(
host
,
':'
)
!=
NULL
)
{
r
=
snprintf
(
writebuf
,
sizeof
(
writebuf
),
"CONNECT [%s]:%u HTTP/1.0
\r\n
"
,
host
,
port
);
}
else
{
r
=
snprintf
(
writebuf
,
sizeof
(
writebuf
),
"CONNECT %s:%u HTTP/1.0
\r\n
"
,
host
,
port
);
}
if
(
r
==
-
1
||
(
size_t
)
r
>=
sizeof
(
writebuf
))
{
fatal
(
"ssh_webproxy_connect: hostname too long %.100s"
,
host
);
}
debug
(
"ssh_webproxy_connect: write %.100s"
,
writebuf
);
write
(
sock
,
writebuf
,
strlen
(
writebuf
));
if
(
strlen
(
proxy_username
)
&&
strlen
(
proxy_passwd
))
{
char
encodedUsrNamePasswd
[
1024
]
=
""
;
char
usrNamePasswd
[
1024
];
snprintf
(
usrNamePasswd
,
sizeof
(
usrNamePasswd
),
"%s:%s"
,
proxy_username
,
proxy_passwd
);
uuencode
(
usrNamePasswd
,
strlen
(
usrNamePasswd
),
encodedUsrNamePasswd
,
1024
);
r
=
snprintf
(
writebuf
,
sizeof
(
writebuf
),
"Proxy-Authorization: Basic %s
\r\n\r\n
"
,
encodedUsrNamePasswd
);
}
else
{
r
=
snprintf
(
writebuf
,
sizeof
(
writebuf
),
"
\r\n
"
);
}
if
(
r
==
-
1
||
(
size_t
)
r
>=
sizeof
(
writebuf
))
{
fatal
(
"ssh_webproxy_connect: username and password too long %.100s"
,
proxy_username
);
}
debug
(
"ssh_webproxy_connect: write %.100s"
,
writebuf
);
write
(
sock
,
writebuf
,
strlen
(
writebuf
));
FD_ZERO
(
&
fds
);
FD_SET
(
sock
,
&
fds
);
tv
.
tv_sec
=
30
;
tv
.
tv_usec
=
0
;
/* Read proxy repsonse. */
for
(
r
=
0
;
r
<
HTTP_MAXHDRS
;
r
++
)
{
sel_ret
=
select
(
sock
+
1
,
&
fds
,
NULL
,
NULL
,
&
tv
);
if
(
sel_ret
==
0
)
{
exit
(
1
);
}
for
(
i
=
0
;
i
<
sizeof
(
readbuf
)
-
1
;
i
++
)
{
int
len
=
read
(
sock
,
&
readbuf
[
i
],
1
);
if
(
len
<
0
)
{
fatal
(
"web proxy handshaking: read: %.100s"
,
strerror
(
errno
));
}
if
(
len
!=
1
)
{
fatal
(
"web proxy handshaking: Connection closed by remote host"
);
}
if
(
readbuf
[
i
]
==
'\r'
)
{
continue
;
/**XXX wait for \n */
}
if
(
readbuf
[
i
]
==
'\n'
)
{
readbuf
[
i
]
=
0
;
break
;
}
}
debug
(
"ssh_webproxy_connect: read %.100s"
,
readbuf
);
if
(
r
==
0
&&
strncmp
(
readbuf
,
"HTTP/1.0 200 "
,
13
)
!=
0
&&
strncmp
(
readbuf
,
"HTTP/1.1 200 "
,
13
)
!=
0
)
{
fatal
(
"web proxy handshaking: proxy error: %.100s"
,
readbuf
);
}
if
(
*
readbuf
==
'\0'
||
*
readbuf
==
'\r'
)
{
break
;
}
}
/* Set the connection. */
packet_set_connection
(
sock
,
sock
);
return
0
;
}
/*
* Opens a TCP/IP connection to the remote server on the given host.
* The address of the remote host will be returned in hostaddr.
...
...
@@ -783,7 +1097,7 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
* using a proxy command
*/
if
(
hostfile_ipaddr
!=
NULL
)
{
if
(
options
.
proxy_command
==
NULL
)
{
if
(
options
.
proxy_command
==
NULL
&&
webproxy_flag
==
0
)
{
if
(
getnameinfo
(
hostaddr
,
addrlen
,
ntop
,
sizeof
(
ntop
),
NULL
,
0
,
NI_NUMERICHOST
)
!=
0
)
fatal
(
"%s: getnameinfo failed"
,
__func__
);
...
...
This diff is collapsed.
Click to expand it.
sshconnect.h
View file @
9553287a
...
...
@@ -34,6 +34,10 @@ struct Sensitive {
struct
addrinfo
;
int
ssh_connect
(
const
char
*
,
struct
addrinfo
*
,
struct
sockaddr_storage
*
,
u_short
,
int
,
int
,
int
*
,
int
,
int
);
int
ssh_webproxy_connect
(
const
char
*
,
u_short
,
const
char
*
,
const
char
*
,
const
char
*
,
struct
sockaddr_storage
*
,
u_short
,
int
,
int
,
int
);
void
ssh_kill_proxy_command
(
void
);
void
ssh_login
(
Sensitive
*
,
const
char
*
,
struct
sockaddr
*
,
u_short
,
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment