Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
LSH
lsh
Commits
0d0f58bf
Commit
0d0f58bf
authored
Sep 11, 1998
by
Niels Möller
Browse files
Work in progress.
Rev: src/connection.h:1.9 Rev: src/keyexchange.c:1.6 Rev: src/keyexchange.h:1.7
parent
62ea4b3c
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/connection.h
View file @
0d0f58bf
...
...
@@ -24,9 +24,14 @@ struct packet_handler
#define HANDLE_PACKET(closure, connection, packet) \
((closure)->handler((closure), (connection), (packet)))
#define CONNECTION_SERVER 0
#define CONNECTION_CLIENT 1
struct
ssh_connection
{
struct
abstract_write
super
;
int
type
;
/* CONNECTION_SERVER or CONNECTION_CLIENT */
/* Sent and recieved version strings */
struct
lsh_string
*
client_version
;
...
...
@@ -49,9 +54,12 @@ struct ssh_connection
UINT32
max_packet
;
/* Key exchange */
struct
kexinit
*
recieved_kexinit
;
struct
kexinit
*
sent_kexinit
;
int
kex_state
;
/* First element is the kexinit sent by the server */
struct
kexinit
*
kexinits
[
2
];
int
ignore_one_packet
;
int
provides_privacy
;
int
provides_integrity
;
};
...
...
src/keyexchange.c
View file @
0d0f58bf
/* keyexchange.c
*
*
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Mller
*
* 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 of the
* License, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include
"abstract_io.h"
...
...
@@ -59,32 +80,17 @@ struct kexinit *parse_kexinit(struct lsh_string *packet)
res
->
kex_algorithms
=
lists
[
0
];
res
->
server_host_key_algorithms
=
lists
[
1
];
res
->
encryption_algorithms_client_to_server
=
lists
[
2
];
res
->
encryption_algorithms_server_to_client
=
lists
[
3
];
res
->
mac_algorithms_client_to_server
=
lists
[
4
];
res
->
mac_algorithms_server_to_client
=
lists
[
5
];
res
->
compression_algorithms_client_to_server
=
lists
[
6
];
res
->
compression_algorithms_server_to_client
=
lists
[
7
];
for
(
i
=
0
;
i
<
KEX_PARAMETERS
;
i
++
)
res
->
parameters
[
i
]
=
lists
[
2
+
i
];
res
->
languages_client_to_server
=
lists
[
8
];
res
->
languages_server_to_client
=
lists
[
9
];
return
res
;
}
static
int
do_handle_kexinit
(
struct
abstract_write
**
w
,
struct
lsh_string
*
packet
)
{
struct
handle_kexinit_packet
*
closure
=
(
struct
handle_kexinit_packet
*
)
*
w
;
struct
kexinit
*
msg
=
parse_kexinit
(
packet
);
if
(
!
msg
)
return
0
;
lsh_free
(
packet
);
return
HANDLE_KEXINIT
(
closure
->
handler
,
msg
);
}
#if 0
struct abstract_write *make_packet_kexinit(struct handle_kexinit *handler)
{
struct handle_kexinit_packet *closure
...
...
@@ -95,6 +101,7 @@ struct abstract_write *make_packet_kexinit(struct handle_kexinit *handler)
return &closure->super;
}
#endif
struct
lsh_string
*
format_kex
(
struct
kexinit
*
kex
)
{
...
...
@@ -103,12 +110,12 @@ struct lsh_string *format_kex(struct kexinit *kex)
16
,
kex
->
cookie
,
kex
->
kex_algorithms
,
kex
->
server_host_key_algorithms
,
kex
->
encryption_algorithms_client_to_server
,
kex
->
encryption_algorithms_server_to_client
,
kex
->
mac_algorithms_client_to_server
,
kex
->
mac_algorithms_server_to_client
,
kex
->
compression_algorithms_client_to_server
,
kex
->
compression_algorithms_server_to_client
,
kex
->
parameters
[
KEX_ENCRYPTION_CLIENT_TO_SERVER
]
,
kex
->
parameters
[
KEX_ENCRYPTION_SERVER_TO_CLIENT
]
,
kex
->
parameters
[
KEX_MAC_CLIENT_TO_SERVER
]
,
kex
->
parameters
[
KEX_MAC_SERVER_TO_CLIENT
]
,
kex
->
parameters
[
KEX_COMPRESSION_CLIENT_TO_SERVER
]
,
kex
->
parameters
[
KEX_COMPRESSION_SERVER_TO_CLIENT
]
,
kex
->
languages_client_to_server
,
kex
->
languages_server_to_client
,
kex
->
first_kex_packet_follows
,
0
);
...
...
@@ -132,4 +139,126 @@ int initiate_keyexchange(struct ssh_connection *connection,
return
res
;
}
int
select_algorithm
(
int
*
server_list
,
int
*
client_list
)
{
/* FIXME: This quadratic complexity algorithm should do as long as
* the lists are short. */
int
i
,
j
;
for
(
i
=
0
;
client_list
[
i
]
>=
0
;
i
++
)
{
if
(
!
client_list
[
i
])
/* Unknown algorithm */
continue
;
for
(
j
=
0
;
server_list
[
j
]
>
0
;
j
++
)
if
(
client_list
[
i
]
=
server_list
[
j
])
return
client_list
[
i
];
}
return
0
;
}
int
send_disconnect
(
struct
ssh_conection
,
char
*
msg
)
{
return
A_WRITE
(
connection
->
write
,
ssh_format
(
"%c%i%z%z"
,
SSH_MSG_DISCONNECT
,
SSH_DISCONNECT_KEY_EXCHANGE_FAILED
,
msg
,
""
));
}
static
int
do_handle_kexinit
(
struct
packet_hander
*
c
,
struct
ssh_connection
*
connection
,
struct
lsh_string
*
packet
)
{
struct
handle_kexinit
*
closure
=
(
struct
handle_kexinit_packet
*
)
c
;
struct
kexinit
*
msg
=
parse_kexinit
(
packet
);
int
kex_algorithm
;
int
hostkey_algorithm
;
int
parameters
[
KEX_PARAMETERS
];
void
**
algorithms
;
struct
packet_handler
newkeys
;
int
i
;
if
(
!
msg
)
return
0
;
lsh_free
(
packet
);
connection
->
kexinits
[
!
connection
->
type
]
=
msg
;
/* Have we sent a kexinit message? */
if
(
!
connection
->
kexinits
[
connection
->
type
])
{
int
res
;
struct
kexinit
*
sent
=
GENERATE_KEXINIT
(
closure
->
init
);
connection
->
kexinits
[
connection
->
type
]
=
sent
;
res
=
A_WRITE
(
connection
->
write
,
format_kex
(
sent
));
if
(
res
!=
WRITE_OK
)
return
res
;
}
/* Select key exchange algorithms */
if
(
connection
->
kexinits
[
0
]
->
kex_algorithms
[
0
]
==
connection
->
kexinits
[
1
]
->
kex_algorithms
[
1
])
{
/* Use this algorithm */
kex_algorithm
=
connection
->
sent_kexinit
->
kex_algorithms
[
0
];
}
else
{
if
(
msg
->
first_kex_packet_follows
)
{
/* Wrong guess */
connection
->
ignore_one_packet
=
1
;
}
/* FIXME: Ignores that some keyechange algorithms require
* certain features of the host key algorithms. */
kex_algorithm
=
select_algorithm
(
connection
->
kexinits
[
0
]
->
kex_algorithm
,
connection
->
kexinits
[
1
]
->
kex_algorithm
);
if
(
!
kex_algorithm
)
{
send_disconnect
(
connection
,
"No common key exchange method.
\r\n
"
);
/* FIXME: We want the disconnect message to be sent
* before the socket is closed. How? */
return
WRITE_CLOSED
;
}
hostkey_algorithm
=
select_algorithm
(
connection
->
kexinits
[
0
]
->
server_hostkey_algorithms
,
connection
->
kexinits
[
1
]
->
server_hostkey_algorithms
);
for
(
i
=
0
;
i
<
KEX_PARAMETERS
;
i
++
)
{
parameters
[
i
]
=
select_algorithm
(
connection
->
kexinits
[
0
]
->
parameters
[
i
],
connection
->
kexinits
[
1
]
->
parameters
[
i
]);
if
(
!
parameters
[
i
])
{
send_disconnect
(
connection
,
""
);
return
wRITE_CLOSED
;
}
}
algorithms
=
xalloc
(
KEX_PARAMETERS
*
sizeof
(
void
*
));
for
(
i
=
0
;
i
<
KEX_PARAMETERS
;
i
++
)
algorithms
[
i
]
=
ALIST_GET
(
closure
->
algorithms
,
parameters
[
i
]);
newkeys
=
make_newkeys_handler
(
ALIST_GET
(
closure
->
alist
,
hostkey_algorithm
),
algorithms
);
return
KEYEXCHANGE_INIT
(
ALIST_GET
(
algorithms
,
kex_algorithm
),
connection
);
}
}
src/keyexchange.h
View file @
0d0f58bf
/* keyexchange.h
*
*
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Möller
*
* 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 of the
* License, 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_KEYEXCHANGE_H_INCLUDED
...
...
@@ -7,42 +28,81 @@
#include
"lsh_types.h"
#include
"abstract_io.h"
#include
"alist.h"
#define KEX_ENCRYPTION_CLIENT_TO_SERVER 0
#define KEX_ENCRYPTION_SERVER_TO_CLIENT 1
#define KEX_MAC_CLIENT_TO_SERVER 2
#define KEX_MAC_SERVER_TO_CLIENT 3
#define KEX_COMPRESSION_CLIENT_TO_SERVER 4
#define KEX_COMPRESSION_SERVER_TO_CLIENT 5
#define KEX_PARAMETERS 6
struct
keyexchange_algorithm
{
int
(
*
init
)(
struct
keyexchange_algorithm
*
closure
,
struct
ssh_connection
*
connection
);
};
#define KEYEXCHANGE_INIT(kex, connection) \
((kex)->init((kex), (connection)))
struct
kexinit
{
UINT8
cookie
[
16
];
/* Zero terminated list of atoms */
int
*
kex_algorithms
;
int
*
server_host_key_algorithms
;
int
*
encryption_algorithms_client_to_server
;
int
*
encryption_algorithms_server_to_client
;
int
*
mac_algorithms_client_to_server
;
int
*
mac_algorithms_server_to_client
;
int
*
compression_algorithms_client_to_server
;
int
*
compression_algorithms_server_to_client
;
int
*
parameters
[
KEX_PARAMETERS
];
int
*
languages_client_to_server
;
int
*
languages_server_to_client
;
int
first_kex_packet_follows
;
};
struct
handle_kexinit
/* This function generates a new kexinit message.
*
* FIXME: It could be replaced with a function that does more: Send
* the message, record it in the connection structure, and possibly
* send a first guessed message. */
struct
generate_kexinit
{
int
(
*
f
)(
struct
handle_kexinit
*
closure
,
struct
kexinit
*
msg
);
struct
kexinit
*
(
*
generate
)(
struct
generate_kexinit
*
closure
);
};
#define
HANDL
E_KEXINIT(
handler, msg) ((handler)->f((handler), (ms
g)))
#define
GENERAT
E_KEXINIT(
g) ((g)->generate((
g)))
struct
handle_kexinit
_packet
struct
handle_ke
ye
xinit
{
struct
abstract_write
super
;
struct
handle_kexinit
*
handler
;
};
struct
packet_handler
super
;
struct
choose_kexinit
*
init
;
/* Maps names to algorithms. It's dangerous to lookup random atoms
* in this table, as not all objects have the same type. This
* mapping is used only on atoms that have appeared in *both* the
* client's and the server's list of algorithms (of a certain type),
* and therefore the remote side can't screw things up. */
struct
abstract_write
*
make_packet_kexinit
(
struct
handle_kexinit
*
handler
);
struct
alist
*
algorithms
;
};
struct
handle_newkeys
{
struct
packet_handler
super
;
struct
crypto_algorithm
*
encryption_client_to_server
;
struct
crypto_algorithm
*
encryption_server_to_client
;
struct
mac_algorithm
*
mac_client_to_server
;
struct
mac_algorithm
*
mac_server_to_client
;
#if 0
struct lsh_string *make_keyexinit_packet(struct keyexinit *msg);
struct compression_algorithm *compression_client_to_server;
struct compression_algorithm *compression_server_to_client;
#endif
};
struct
packet_handler
*
make_kexinit_handler
();
struct
packet_handler
*
make_newkeys_handler
();
struct
lsh_string
*
format_kex
(
struct
kexinit
*
kex
);
#endif
/* LSH_KEYEXCHANGE_H_INCLUDED */
Write
Preview
Supports
Markdown
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