[ Team LiB ] |
19.3 Dumping the Security Association Database (SADB)To dump the current SADB, a process uses the SADB_DUMP message. This is the simplest message to send since the message does not require any extensions, simply the 16-byte sadb_msg header. After the process sends the SADB_DUMP message to the kernel on a key management socket, the kernel replies with a series of SADB_DUMP messages back to the same socket, each with one entry from the SADB. The end of the list is indicated by a message with a value of 0 for the sadb_msg_seq field. The type of SA can be limited by setting the sadb_msg_satype field in the request to one of the values in Figure 19.3. If it is set to SADB_SATYPE_UNSPEC, then all SAs in the database are returned. Otherwise, only SAs of the specified type are returned. Not all types of security associations are supported by all implementations. The KAME implementation only supports IPsec SAs (SADB_SATYPE_AH and SADB_SATYPE_ESP), so an attempt to dump SADB_SATYPE_RIPV2 SADB entries will get an error reply with errno EINVAL. When requesting a specific type whose table is empty, the errno ENOENT is returned. Our program to dump the SADB follows in Figure 19.5. Figure 19.5 Program to issue SADB_DUMP command on key management socket.key/dump.c 1 void 2 sadb_dump(int type) 3 { 4 int s; 5 char buf[4096]; 6 struct sadb_msg msg; 7 int goteof; 8 s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2); 9 /* Build and write SADB_DUMP request */ 10 bzero(&msg, sizeof (msg)); 11 msg.sadb_msg_version = PF_KEY_V2; 12 msg.sadb_msg_type = SADB_DUMP; 13 msg.sadb_msg_satype = type; 14 msg.sadb_msg_len = sizeof (msg) / 8; 15 msg.sadb_msg_pid = getpid(); 16 printf("Sending dump message:\n"); 17 print_sadb_msg (&msg, sizeof (msg)); 18 Write(s, &msg, sizeof (msg)); 19 printf("\nMessages returned:\n"); 20 /* Read and print SADB_DUMP replies until done */ 21 goteof = 0; 22 while (goteof == 0) { 23 int msglen; 24 struct sadb_msg *msgp; 25 msglen = Read(s, &buf, sizeof (buf)); 26 msgp = (struct sadb_msg *) &buf; 27 print_sadb_msg(msgp, msglen); 28 if (msgp->sadb_msg_seq == 0) 29 goteof = 1; 30 } 31 close(s); 32 } 33 int 34 main(int argc, char **argv) 35 { 36 int satype = SADB_SATYPE_UNSPEC; 37 int c; 38 opterr = 0; /* don't want getopt () writing to stderr */ 39 while ( (c = getopt(argc, argv, "t:")) != -1) { 40 switch (c) { 41 case 't': 42 if ( (satype = getsatypebyname (optarg) ) == -1) 43 err_quit("invalid -t option %s", optarg); 44 break; 45 default: 46 err_quit("unrecognized option: %c", c); 47 } 48 } 49 sadb_dump(satype); 50 }
Open PF_KEY socket1–8 We first open a PF_KEY socket. This requires system privileges, as described earlier, since this allows access to sensitive keying material. Build SADB_DUMP request9–15 We first zero out the sadb_msg struct so that we can skip initializing the fields that we wish to remain zero. We fill in each remaining field in the sadb_msg struct individually. All messages on sockets opened with PF_KEY_V2 as the third argument must also use PF_KEY_V2 as the message version. The message type is SADB_DUMP. We set the length to the length of the base header with no extensions since the dump message does not take extensions. Finally, we set the process ID (PID) to our own PID since all messages must be identified by the PID of the sender. Display and write SADB_DUMP message16–18 We display the message using our print_sadb_msg routine. We don't show this routine since it is long and uninteresting, but it is included in the freely available source code. This routine accepts a message that is being written to or has been received from a key management socket and prints all the information from the message in a human-readable form. We then write the message to the socket. Read replies19–30 We loop, reading replies and printing them using our print_sadb_msg function. The last message in the dump sequence has a message sequence number of zero, so we use this as our "end-of-file" indication. Close PF_KEY socket31 Finally, we close the socket that we opened. Handle command-line arguments38–48 The main function has very little work to do. This program takes a single optional argument, which is the type of SA to dump. By default, the type is SADB_SATYPE_UNSPEC, which dumps all SAs of any type. By specifying a command-line argument, the user can select which type of SAs to dump. This program uses our getsatypebyname function, which returns the type value for a text string. Call sadb_dump routine49 Finally, we call the sadb_dump function we defined above to do all the work. Sample RunThe following is a sample run of the dump program on a system with two static SAs.
macosx % dump
Sending dump message:
SADB Message Dump, errno 0, satype Unspecified, seq 0, pid 20623
Messages returned:
SADB Message Dump, errno 0, satype IPsec AH, seq 1, pid 20623
SA: SPI=258 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-MD5
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
0 allocations, 0 bytes
added at Sun May 18 16:28:11 2003, never used
Source address: 2.3.4.5/128 (IP proto 255)
Dest address: 6.7.8.9/128 (IP proto 255)
Authentication key, 128 bits: 0x20202020202020200202020202020202
SADB Message Dump, errno 0, satype IPsec AH, seq 0, pid 20623
SA: SPI=257 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-MD5
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
0 allocations, 0 bytes
added at Sun May 18 16:26:24 2003, never used
Source address: 1.2.3.4/128 (IP proto 255)
Dest address: 5.6.7.8/128 (IP proto 255)
Authentication key, 128 bits: 0x10101010101010100101010101010101
|
[ Team LiB ] |