aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-10-21 07:36:45 +0000
committerChristian Grothoff <christian@grothoff.org>2011-10-21 07:36:45 +0000
commitaa8bd9308ea05cd501348ae5f17447253b92ac5c (patch)
treed9eaa0ad2dd9b431802661a686d79feac4a491c5 /src
parent89812cb07bbdf334afdfd341512d54426bb2db2b (diff)
downloadgnunet-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.c4
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c76
-rw-r--r--src/transport/gnunet-service-transport_neighbours.h11
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 */
1212void
1213GST_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 */
242void
243GST_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 */