diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-10-21 07:36:45 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-10-21 07:36:45 +0000 |
commit | aa8bd9308ea05cd501348ae5f17447253b92ac5c (patch) | |
tree | d9eaa0ad2dd9b431802661a686d79feac4a491c5 /src | |
parent | 89812cb07bbdf334afdfd341512d54426bb2db2b (diff) | |
download | gnunet-aa8bd9308ea05cd501348ae5f17447253b92ac5c.tar.gz gnunet-aa8bd9308ea05cd501348ae5f17447253b92ac5c.zip |
fixing 1792: validate signature in disconnect request
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 4 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 76 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.h | 11 |
3 files changed, 87 insertions, 4 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 561873cd9..6273816c7 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -276,9 +276,7 @@ plugin_env_receive_callback (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
276 | NULL); | 276 | NULL); |
277 | break; | 277 | break; |
278 | case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: | 278 | case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT: |
279 | /* FIXME: do some validation to prevent an attacker from sending | 279 | GST_neighbours_handle_disconnect_message (peer, message); |
280 | * a fake disconnect message... */ | ||
281 | GST_neighbours_force_disconnect (peer); | ||
282 | break; | 280 | break; |
283 | case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: | 281 | case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: |
284 | GST_neighbours_keepalive (peer); | 282 | GST_neighbours_keepalive (peer); |
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 23ff82f91..efb94b6f1 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -112,11 +112,17 @@ struct SessionDisconnectMessage | |||
112 | struct GNUNET_TIME_AbsoluteNBO timestamp; | 112 | struct GNUNET_TIME_AbsoluteNBO timestamp; |
113 | 113 | ||
114 | /** | 114 | /** |
115 | * Public key of the sender. | ||
116 | */ | ||
117 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; | ||
118 | |||
119 | /** | ||
115 | * Signature of the peer that sends us the disconnect. Only | 120 | * Signature of the peer that sends us the disconnect. Only |
116 | * valid if the timestamp is AFTER the timestamp from the | 121 | * valid if the timestamp is AFTER the timestamp from the |
117 | * corresponding 'CONNECT' message. | 122 | * corresponding 'CONNECT' message. |
118 | */ | 123 | */ |
119 | struct GNUNET_CRYPTO_RsaSignature signature; | 124 | struct GNUNET_CRYPTO_RsaSignature signature; |
125 | |||
120 | }; | 126 | }; |
121 | 127 | ||
122 | 128 | ||
@@ -1169,9 +1175,11 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) | |||
1169 | disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); | 1175 | disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); |
1170 | disconnect_msg.reserved = htonl (0); | 1176 | disconnect_msg.reserved = htonl (0); |
1171 | disconnect_msg.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | 1177 | disconnect_msg.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + |
1172 | sizeof (struct GNUNET_TIME_AbsoluteNBO)); | 1178 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + |
1179 | sizeof (struct GNUNET_TIME_AbsoluteNBO) ); | ||
1173 | disconnect_msg.purpose.purpose = htonl (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT); | 1180 | disconnect_msg.purpose.purpose = htonl (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT); |
1174 | disconnect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | 1181 | disconnect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); |
1182 | disconnect_msg.public_key = GST_my_public_key; | ||
1175 | GNUNET_assert (GNUNET_OK == | 1183 | GNUNET_assert (GNUNET_OK == |
1176 | GNUNET_CRYPTO_rsa_sign (GST_my_private_key, | 1184 | GNUNET_CRYPTO_rsa_sign (GST_my_private_key, |
1177 | &disconnect_msg.purpose, | 1185 | &disconnect_msg.purpose, |
@@ -1195,6 +1203,72 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) | |||
1195 | 1203 | ||
1196 | 1204 | ||
1197 | /** | 1205 | /** |
1206 | * We received a disconnect message from the given peer, | ||
1207 | * validate and process. | ||
1208 | * | ||
1209 | * @param peer sender of the message | ||
1210 | * @param msg the disconnect message | ||
1211 | */ | ||
1212 | void | ||
1213 | GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity *peer, | ||
1214 | const struct GNUNET_MessageHeader *msg) | ||
1215 | { | ||
1216 | struct NeighbourMapEntry *n; | ||
1217 | const struct SessionDisconnectMessage *sdm; | ||
1218 | GNUNET_HashCode hc; | ||
1219 | |||
1220 | if (ntohs (msg->size) != sizeof (struct SessionDisconnectMessage)) | ||
1221 | { | ||
1222 | // GNUNET_break_op (0); | ||
1223 | GNUNET_STATISTICS_update (GST_stats, | ||
1224 | gettext_noop ("# disconnect messages ignored (old format)"), 1, | ||
1225 | GNUNET_NO); | ||
1226 | return; | ||
1227 | } | ||
1228 | sdm = (const struct SessionDisconnectMessage* ) msg; | ||
1229 | n = lookup_neighbour (peer); | ||
1230 | if (NULL == n) | ||
1231 | return; /* gone already */ | ||
1232 | if (GNUNET_TIME_absolute_ntoh (sdm->timestamp).abs_value <= | ||
1233 | n->connect_ts.abs_value) | ||
1234 | { | ||
1235 | GNUNET_STATISTICS_update (GST_stats, | ||
1236 | gettext_noop ("# disconnect messages ignored (timestamp)"), 1, | ||
1237 | GNUNET_NO); | ||
1238 | return; | ||
1239 | } | ||
1240 | GNUNET_CRYPTO_hash (&sdm->public_key, | ||
1241 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
1242 | &hc); | ||
1243 | if (0 != memcmp (peer, | ||
1244 | &hc, | ||
1245 | sizeof (struct GNUNET_PeerIdentity))) | ||
1246 | { | ||
1247 | GNUNET_break_op (0); | ||
1248 | return; | ||
1249 | } | ||
1250 | if (ntohl (sdm->purpose.size) != | ||
1251 | sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
1252 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + | ||
1253 | sizeof (struct GNUNET_TIME_AbsoluteNBO)) | ||
1254 | { | ||
1255 | GNUNET_break_op (0); | ||
1256 | return; | ||
1257 | } | ||
1258 | if (GNUNET_OK != | ||
1259 | GNUNET_CRYPTO_rsa_verify (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT, | ||
1260 | &sdm->purpose, | ||
1261 | &sdm->signature, | ||
1262 | &sdm->public_key)) | ||
1263 | { | ||
1264 | GNUNET_break_op (0); | ||
1265 | return; | ||
1266 | } | ||
1267 | GST_neighbours_force_disconnect (peer); | ||
1268 | } | ||
1269 | |||
1270 | |||
1271 | /** | ||
1198 | * We received a 'SESSION_CONNECT' message from the other peer. | 1272 | * We received a 'SESSION_CONNECT' message from the other peer. |
1199 | * Consider switching to it. | 1273 | * Consider switching to it. |
1200 | * | 1274 | * |
diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index 2f6962a67..27f7aae31 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h | |||
@@ -232,6 +232,17 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, | |||
232 | const struct GNUNET_ATS_Information *ats, | 232 | const struct GNUNET_ATS_Information *ats, |
233 | uint32_t ats_count); | 233 | uint32_t ats_count); |
234 | 234 | ||
235 | /** | ||
236 | * We received a disconnect message from the given peer, | ||
237 | * validate and process. | ||
238 | * | ||
239 | * @param peer sender of the message | ||
240 | * @param msg the disconnect message | ||
241 | */ | ||
242 | void | ||
243 | GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity *peer, | ||
244 | const struct GNUNET_MessageHeader *msg); | ||
245 | |||
235 | 246 | ||
236 | #endif | 247 | #endif |
237 | /* end of file gnunet-service-transport_neighbours.h */ | 248 | /* end of file gnunet-service-transport_neighbours.h */ |