00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 # include <dtn-config.h>
00022 #endif
00023
00024 #ifdef BSP_ENABLED
00025
00026 #include <cstring>
00027 #include <cstdio>
00028 #include <oasys/util/Base16.h>
00029
00030 #include "SecurityCommand.h"
00031 #include "security/SPD.h"
00032 #include "security/KeyDB.h"
00033 #include "security/Ciphersuite.h"
00034
00035 namespace dtn {
00036
00037 SecurityCommand::SecurityCommand()
00038 : TclCommand("security")
00039 {
00040 add_to_help("setpolicy [in | out] [psb] [cb] [bab]",
00041 "Set inbound or outbound policy to require the specified\n"
00042 "combination of PSB, CB, and/or BAB.");
00043 add_to_help("setkey <host> <cs_num> <key>",
00044 "Set the key to use for the specified host and ciphersuite\n"
00045 "number. <host> may also be the wildcard symbol \"*\".");
00046 add_to_help("dumpkeys",
00047 "Dump the contents of the keystore to the screen.");
00048 add_to_help("flushkeys",
00049 "Erase all keys from the keystore.");
00050 }
00051
00052 int
00053 SecurityCommand::exec(int argc, const char** argv, Tcl_Interp* interp)
00054 {
00055 (void)interp;
00056
00057 if (argc < 2) {
00058 resultf("need a security subcommand");
00059 return TCL_ERROR;
00060 }
00061
00062 const char* cmd = argv[1];
00063
00064 if (strcmp(cmd, "setpolicy") == 0) {
00065
00066 if (argc < 3 || argc > 6) {
00067 wrong_num_args(argc, argv, 2, 3, 6);
00068 return TCL_ERROR;
00069 }
00070
00071 SPD::spd_direction_t direction;
00072 if (strcmp(argv[2], "in") == 0)
00073 direction = SPD::SPD_DIR_IN;
00074 else if (strcmp(argv[2], "out") == 0)
00075 direction = SPD::SPD_DIR_OUT;
00076 else {
00077 resultf("invalid direction argument \"%s\" (must be one of "
00078 "\"in\" or \"out\")", argv[2]);
00079 return TCL_ERROR;
00080 }
00081
00082 int policy = SPD::SPD_USE_NONE;
00083 for (int i = 3; i < argc; i++) {
00084 if (strcmp(argv[i], "psb") == 0)
00085 policy |= SPD::SPD_USE_PSB;
00086 else if (strcmp(argv[i], "cb") == 0)
00087 policy |= SPD::SPD_USE_CB;
00088 else if (strcmp(argv[i], "bab") == 0)
00089 policy |= SPD::SPD_USE_BAB;
00090 else {
00091 resultf("invalid argument \"%s\"", argv[i]);
00092 return TCL_ERROR;
00093 }
00094 }
00095
00096 SPD::set_global_policy(direction, (SPD::spd_policy_t)policy);
00097
00098 return TCL_OK;
00099
00100 } else if (strcmp(cmd, "setkey") == 0) {
00101
00102 if (argc != 5) {
00103 wrong_num_args(argc, argv, 2, 5, 5);
00104 return TCL_ERROR;
00105 }
00106
00107 const char* host_arg = argv[2];
00108 const char* cs_num_arg = argv[3];
00109 const char* key_arg = argv[4];
00110
00111 int cs_num;
00112 if (sscanf(cs_num_arg, "%i", &cs_num) != 1) {
00113 resultf("invalid cs_num argument \"%s\"", cs_num_arg);
00114 return TCL_ERROR;
00115 }
00116 if (! KeyDB::validate_cs_num(cs_num)) {
00117 resultf("invalid ciphersuite number %#x", cs_num);
00118 return TCL_ERROR;
00119 }
00120
00121 size_t key_arg_len = strlen(key_arg);
00122 if ((key_arg_len % 2) != 0) {
00123 resultf("invalid key argument (must be even length)");
00124 return TCL_ERROR;
00125 }
00126
00127 size_t key_len = key_arg_len / 2;
00128 if (! KeyDB::validate_key_len(cs_num, &key_len)) {
00129 resultf("wrong key length for ciphersuite (expected %d bytes)",
00130 (int)key_len);
00131 return TCL_ERROR;
00132 }
00133
00134
00135 u_char* key = new u_char[key_len];
00136 for (int i = 0; i < (int)key_len; i++)
00137 {
00138 int b = 0;
00139
00140 for (int j = 0; j <= 1; j++)
00141 {
00142 int c = (int)key_arg[2*i+j];
00143 b <<= 4;
00144
00145 if (c >= '0' && c <= '9')
00146 b |= c - '0';
00147 else if (c >= 'A' && c <= 'F')
00148 b |= c - 'A' + 10;
00149 else if (c >= 'a' && c <= 'f')
00150 b |= c - 'a' + 10;
00151 else {
00152 resultf("invalid character '%c' in key argument",
00153 (char)c);
00154 delete key;
00155 return TCL_ERROR;
00156 }
00157 }
00158
00159 key[i] = (u_char)(b);
00160 }
00161
00162 KeyDB::Entry new_entry =
00163 KeyDB::Entry(host_arg, cs_num, key, key_len);
00164 KeyDB::set_key(new_entry);
00165
00166 delete key;
00167 return TCL_OK;
00168
00169 } else if (strcmp(cmd, "dumpkeys") == 0) {
00170
00171 if (argc != 2) {
00172 wrong_num_args(argc, argv, 2, 2, 2);
00173 return TCL_ERROR;
00174 }
00175
00176 oasys::StringBuffer buf;
00177 KeyDB::dump_header(&buf);
00178 KeyDB::dump(&buf);
00179 set_result(buf.c_str());
00180 return TCL_OK;
00181
00182 } else if (strcmp(cmd, "flushkeys") == 0) {
00183
00184 if (argc != 2) {
00185 wrong_num_args(argc, argv, 2, 2, 2);
00186 return TCL_ERROR;
00187 }
00188
00189 KeyDB::flush_keys();
00190
00191 } else {
00192 resultf("no such security subcommand %s", cmd);
00193 return TCL_ERROR;
00194 }
00195
00196 return TCL_OK;
00197 }
00198
00199 }
00200
00201 #endif