00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #ifdef BSP_ENABLED
00022
00023 #include "PS_BlockProcessor.h"
00024 #include "bundling/Bundle.h"
00025 #include "bundling/BundleDaemon.h"
00026 #include "bundling/BundleProtocol.h"
00027 #include "contacts/Link.h"
00028
00029 namespace dtn {
00030
00031 static const char * log = "/dtn/bundle/ciphersuite";
00032
00033
00034 PS_BlockProcessor::PS_BlockProcessor()
00035 : BlockProcessor(BundleProtocol::PAYLOAD_SECURITY_BLOCK)
00036 {
00037 }
00038
00039
00040 int
00041 PS_BlockProcessor::consume(Bundle* bundle, BlockInfo* block,
00042 u_char* buf, size_t len)
00043 {
00044 int cc = BlockProcessor::consume(bundle, block, buf, len);
00045
00046 if (cc == -1) {
00047 return -1;
00048 }
00049
00050
00051
00052
00053 if (! block->complete()) {
00054 ASSERT(cc == (int)len);
00055 return cc;
00056 }
00057
00058 if ( block->locals() == NULL ) {
00059 Ciphersuite::parse(block);
00060 }
00061
00062 return cc;
00063 }
00064
00065
00066 int
00067 PS_BlockProcessor::reload_post_process(Bundle* bundle,
00068 BlockInfoVec* block_list,
00069 BlockInfo* block)
00070 {
00071
00072
00073
00074
00075
00076
00077 Ciphersuite* p = NULL;
00078 int err = 0;
00079 int type = 0;
00080 BP_Local_CS* locals;
00081
00082 if ( ! block->reloaded() )
00083 return 0;
00084
00085 type = block->type();
00086 log_debug_p(log, "PS_BlockProcessor::reload block type %d", type);
00087
00088 Ciphersuite::parse(block);
00089 locals = dynamic_cast<BP_Local_CS*>(block->locals());
00090 CS_FAIL_IF_NULL(locals);
00091
00092 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00093 if ( p != NULL )
00094 err = p->reload_post_process(bundle, block_list, block);
00095
00096 block->set_reloaded(false);
00097 return err;
00098
00099 fail:
00100 if ( locals != NULL )
00101 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00102 return BP_FAIL;
00103 }
00104
00105
00106 bool
00107 PS_BlockProcessor::validate(const Bundle* bundle,
00108 BlockInfoVec* block_list,
00109 BlockInfo* block,
00110 status_report_reason_t* reception_reason,
00111 status_report_reason_t* deletion_reason)
00112 {
00113 (void)bundle;
00114 (void)block_list;
00115 (void)block;
00116 (void)reception_reason;
00117 (void)deletion_reason;
00118
00119 Ciphersuite* p = NULL;
00120 u_int16_t cs_flags = 0;
00121 EndpointID local_eid = BundleDaemon::instance()->local_eid();
00122 BP_Local_CS* locals = dynamic_cast<BP_Local_CS*>(block->locals());
00123 bool result = false;
00124
00125 CS_FAIL_IF_NULL(locals);
00126
00127 log_debug_p(log, "PS_BlockProcessor::validate() %p ciphersuite %d",
00128 block, locals->owner_cs_num());
00129 cs_flags = locals->cs_flags();
00130
00131 if ( Ciphersuite::destination_is_local_node(bundle, block) )
00132 {
00133
00134 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00135 if ( p != NULL ) {
00136 result = p->validate(bundle, block_list, block,
00137 reception_reason, deletion_reason);
00138 return result;
00139 } else {
00140 log_err_p(log, "block failed security validation PS_BlockProcessor");
00141 *deletion_reason = BundleProtocol::REASON_SECURITY_FAILED;
00142 return false;
00143 }
00144 } else {
00145
00146 locals->set_proc_flag(Ciphersuite::CS_BLOCK_DID_NOT_FAIL);
00147 }
00148
00149 return true;
00150
00151 fail:
00152 if ( locals != NULL )
00153 locals->set_proc_flag(Ciphersuite::CS_BLOCK_FAILED_VALIDATION |
00154 Ciphersuite::CS_BLOCK_COMPLETED_DO_NOT_FORWARD);
00155 *deletion_reason = BundleProtocol::REASON_SECURITY_FAILED;
00156 return false;
00157
00158 }
00159
00160
00161 int
00162 PS_BlockProcessor::prepare(const Bundle* bundle,
00163 BlockInfoVec* xmit_blocks,
00164 const BlockInfo* source,
00165 const LinkRef& link,
00166 BlockInfo::list_owner_t list)
00167 {
00168 (void)bundle;
00169 (void)link;
00170 (void)list;
00171
00172 Ciphersuite* p = NULL;
00173 int result = BP_FAIL;
00174 BP_Local_CS* locals = NULL;
00175 BP_Local_CS* source_locals = NULL;
00176
00177 if ( list == BlockInfo::LIST_RECEIVED ) {
00178
00179
00180
00181 ASSERT(source != NULL);
00182 u_int16_t cs_flags = 0;
00183
00184 if ( Ciphersuite::destination_is_local_node(bundle, source) )
00185 return BP_SUCCESS;
00186
00187 xmit_blocks->push_back(BlockInfo(this, source));
00188 BlockInfo* bp = &(xmit_blocks->back());
00189 bp->set_eid_list(source->eid_list());
00190 log_debug_p(log, "PS_BlockProcessor::prepare() - forward received block len %u",
00191 source->full_length());
00192
00193 CS_FAIL_IF_NULL( source->locals() );
00194
00195 source_locals = dynamic_cast<BP_Local_CS*>(source->locals());
00196 CS_FAIL_IF_NULL(locals);
00197 bp->set_locals(new BP_Local_CS);
00198 locals = dynamic_cast<BP_Local_CS*>(bp->locals());
00199 CS_FAIL_IF_NULL(locals);
00200 locals->set_owner_cs_num(source_locals->owner_cs_num());
00201 cs_flags = source_locals->cs_flags();
00202 locals->set_correlator(source_locals->correlator());
00203 locals->set_list_owner(BlockInfo::LIST_RECEIVED);
00204
00205
00206 if ( source_locals->cs_flags() & Ciphersuite::CS_BLOCK_HAS_SOURCE ) {
00207 ASSERT(source_locals->security_src().length() > 0 );
00208 cs_flags |= Ciphersuite::CS_BLOCK_HAS_SOURCE;
00209 locals->set_security_src(source_locals->security_src());
00210 log_debug_p(log, "PS_BlockProcessor::prepare() add security_src EID %s",
00211 source_locals->security_src().c_str());
00212 }
00213
00214 if ( source_locals->cs_flags() & Ciphersuite::CS_BLOCK_HAS_DEST ) {
00215 ASSERT(source_locals->security_dest().length() > 0 );
00216 cs_flags |= Ciphersuite::CS_BLOCK_HAS_DEST;
00217 locals->set_security_dest(source_locals->security_dest());
00218 log_debug_p(log, "PS_BlockProcessor::prepare() add security_dest EID %s",
00219 source_locals->security_dest().c_str());
00220 }
00221 locals->set_cs_flags(cs_flags);
00222 log_debug_p(log, "PS_BlockProcessor::prepare() - inserted block eid_list_count %zu",
00223 bp->eid_list().size());
00224 } else {
00225 if ( source != NULL ) {
00226 source_locals = dynamic_cast<BP_Local_CS*>(source->locals());
00227 CS_FAIL_IF_NULL(source_locals);
00228 p = Ciphersuite::find_suite( source_locals->owner_cs_num() );
00229 if ( p != NULL ) {
00230 result = p->prepare(bundle, xmit_blocks, source, link, list);
00231 } else {
00232 log_err_p(log, "PS_BlockProcessor::prepare() - ciphersuite %d is missing",
00233 source_locals->owner_cs_num());
00234 }
00235 }
00236 }
00237 return result;
00238
00239 fail:
00240 if ( locals != NULL )
00241 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00242 return BP_FAIL;
00243 }
00244
00245
00246 int
00247 PS_BlockProcessor::generate(const Bundle* bundle,
00248 BlockInfoVec* xmit_blocks,
00249 BlockInfo* block,
00250 const LinkRef& link,
00251 bool last)
00252 {
00253 (void)bundle;
00254 (void)link;
00255 (void)xmit_blocks;
00256
00257 Ciphersuite* p = NULL;
00258 int result = BP_FAIL;
00259 log_debug_p(log, "PS_BlockProcessor::generate()");
00260
00261 BP_Local_CS* locals = dynamic_cast<BP_Local_CS*>(block->locals());
00262 CS_FAIL_IF_NULL(locals);
00263
00264 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00265 if ( p != NULL ) {
00266 result = p->generate(bundle, xmit_blocks, block, link, last);
00267 } else {
00268
00269 size_t length = block->source()->data_length();
00270
00271 generate_preamble(xmit_blocks,
00272 block,
00273 BundleProtocol::PAYLOAD_SECURITY_BLOCK,
00274 BundleProtocol::BLOCK_FLAG_DISCARD_BUNDLE_ONERROR |
00275 (last ? BundleProtocol::BLOCK_FLAG_LAST_BLOCK : 0),
00276 length);
00277
00278 BlockInfo::DataBuffer* contents = block->writable_contents();
00279 contents->reserve(block->data_offset() + length);
00280 contents->set_len(block->data_offset() + length);
00281 memcpy(contents->buf() + block->data_offset(),
00282 block->source()->data(), length);
00283 result = BP_SUCCESS;
00284 }
00285 return result;
00286
00287 fail:
00288 if ( locals != NULL )
00289 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00290 return BP_FAIL;
00291 }
00292
00293
00294 int
00295 PS_BlockProcessor::finalize(const Bundle* bundle,
00296 BlockInfoVec* xmit_blocks,
00297 BlockInfo* block,
00298 const LinkRef& link)
00299 {
00300 (void)bundle;
00301 (void)link;
00302 (void)xmit_blocks;
00303 (void)block;
00304
00305 Ciphersuite* p = NULL;
00306 int result = BP_FAIL;
00307 log_debug_p(log, "PS_BlockProcessor::finalize()");
00308
00309 BP_Local_CS* locals = dynamic_cast<BP_Local_CS*>(block->locals());
00310 CS_FAIL_IF_NULL(locals);
00311
00312 p = Ciphersuite::find_suite( locals->owner_cs_num() );
00313 if ( p != NULL ) {
00314 result = p->finalize(bundle, xmit_blocks, block, link);
00315 }
00316
00317
00318 return result;
00319
00320 fail:
00321 if ( locals != NULL )
00322 locals->set_proc_flag(Ciphersuite::CS_BLOCK_PROCESSING_FAILED_DO_NOT_SEND);
00323 return BP_FAIL;
00324 }
00325
00326 }
00327
00328 #endif