Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

NVT.cc

Go to the documentation of this file.
00001 // $Id: NVT.cc,v 1.5 2005/09/08 07:42:11 vern Exp $
00002 //
00003 // Copyright (c) 1999, 2000, 2001, 2002, 2003
00004 //      The Regents of the University of California.  All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that: (1) source code distributions
00008 // retain the above copyright notice and this paragraph in its entirety, (2)
00009 // distributions including binary code include the above copyright notice and
00010 // this paragraph in its entirety in the documentation or other materials
00011 // provided with the distribution, and (3) all advertising materials mentioning
00012 // features or use of this software display the following acknowledgement:
00013 // ``This product includes software developed by the University of California,
00014 // Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
00015 // the University nor the names of its contributors may be used to endorse
00016 // or promote products derived from this software without specific prior
00017 // written permission.
00018 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00019 // WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022 #include "config.h"
00023 
00024 #include <stdlib.h>
00025 
00026 #include "NVT.h"
00027 #include "NetVar.h"
00028 #include "Event.h"
00029 
00030 #define IS_3_BYTE_OPTION(c) (c >= 251 && c <= 254)
00031 
00032 #define TELNET_OPT_SB 250
00033 #define TELNET_OPT_SE 240
00034 
00035 #define TELNET_OPT_IS 0
00036 #define TELNET_OPT_SEND 1
00037 
00038 #define TELNET_OPT_WILL 251
00039 #define TELNET_OPT_WONT 252
00040 #define TELNET_OPT_DO 253
00041 #define TELNET_OPT_DONT 254
00042 
00043 #define TELNET_IAC 255
00044 
00045 TelnetOption::TelnetOption(TCP_NVT* arg_endp, unsigned int arg_code)
00046         {
00047         endp = arg_endp;
00048         code = arg_code;
00049         flags = 0;
00050         active = 0;
00051         }
00052 
00053 void TelnetOption::RecvOption(unsigned int type)
00054         {
00055         TelnetOption* peer = endp->FindPeerOption(code);
00056         if ( ! peer )
00057                 internal_error("option peer missing in TelnetOption::RecvOption");
00058 
00059         // WILL/WONT/DO/DONT are messages we've *received* from our peer.
00060         switch ( type ) {
00061         case TELNET_OPT_WILL:
00062                 if ( SaidDont() || peer->SaidWont() || peer->IsActive() )
00063                         InconsistentOption(type);
00064 
00065                 peer->SetWill();
00066 
00067                 if ( SaidDo() )
00068                         peer->SetActive(1);
00069                 break;
00070 
00071         case TELNET_OPT_WONT:
00072                 if ( peer->SaidWill() && ! SaidDont() )
00073                         InconsistentOption(type);
00074 
00075                 peer->SetWont();
00076 
00077                 if ( SaidDont() )
00078                         peer->SetActive(0);
00079                 break;
00080 
00081         case TELNET_OPT_DO:
00082                 if ( SaidWont() || peer->SaidDont() || IsActive() )
00083                         InconsistentOption(type);
00084 
00085                 peer->SetDo();
00086 
00087                 if ( SaidWill() )
00088                         SetActive(1);
00089                 break;
00090 
00091         case TELNET_OPT_DONT:
00092                 if ( peer->SaidDo() && ! SaidWont() )
00093                         InconsistentOption(type);
00094 
00095                 peer->SetDont();
00096 
00097                 if ( SaidWont() )
00098                         SetActive(0);
00099                 break;
00100 
00101         default:
00102                 internal_error("bad option type in TelnetOption::RecvOption");
00103         }
00104         }
00105 
00106 void TelnetOption::RecvSubOption(u_char* /* data */, int /* len */)
00107         {
00108         }
00109 
00110 void TelnetOption::SetActive(int is_active)
00111         {
00112         active = is_active;
00113         }
00114 
00115 void TelnetOption::InconsistentOption(unsigned int /* type */)
00116         {
00117         endp->Conn()->Event(inconsistent_option);
00118         }
00119 
00120 void TelnetOption::BadOption()
00121         {
00122         endp->Conn()->Event(bad_option);
00123         }
00124 
00125 
00126 void TelnetTerminalOption::RecvSubOption(u_char* data, int len)
00127         {
00128         if ( len <= 0 )
00129                 {
00130                 BadOption();
00131                 return;
00132                 }
00133 
00134         if ( data[0] == TELNET_OPT_SEND )
00135                 return;
00136 
00137         if ( data[0] != TELNET_OPT_IS )
00138                 {
00139                 BadOption();
00140                 return;
00141                 }
00142 
00143         endp->SetTerminal(data + 1, len - 1);
00144         }
00145 
00146 
00147 #define ENCRYPT_SET_ALGORITHM 0
00148 #define ENCRYPT_SUPPORT_ALGORITM 1
00149 #define ENCRYPT_REPLY 2
00150 #define ENCRYPT_STARTING_TO_ENCRYPT 3
00151 #define ENCRYPT_NO_LONGER_ENCRYPTING 4
00152 #define ENCRYPT_REQUEST_START_TO_ENCRYPT 5
00153 #define ENCRYPT_REQUEST_NO_LONGER_ENCRYPT 6
00154 #define ENCRYPT_ENCRYPT_KEY 7
00155 #define ENCRYPT_DECRYPT_KEY 8
00156 
00157 void TelnetEncryptOption::RecvSubOption(u_char* data, int len)
00158         {
00159         if ( ! active )
00160                 {
00161                 InconsistentOption(0);
00162                 return;
00163                 }
00164 
00165         if ( len <= 0 )
00166                 {
00167                 BadOption();
00168                 return;
00169                 }
00170 
00171         unsigned int opt = data[0];
00172 
00173         if ( opt == ENCRYPT_REQUEST_START_TO_ENCRYPT )
00174                 ++did_encrypt_request;
00175 
00176         else if ( opt == ENCRYPT_STARTING_TO_ENCRYPT )
00177                 {
00178                 TelnetEncryptOption* peer =
00179                         (TelnetEncryptOption*) endp->FindPeerOption(code);
00180 
00181                 if ( ! peer )
00182                         internal_error("option peer missing in TelnetEncryptOption::RecvSubOption");
00183 
00184                 if ( peer->DidRequest() || peer->DoingEncryption() ||
00185                      peer->Endpoint()->AuthenticationHasBeenAccepted() )
00186                         {
00187                         endp->SetEncrypting(1);
00188                         ++doing_encryption;
00189                         }
00190                 else
00191                         InconsistentOption(0);
00192                 }
00193         }
00194 
00195 #define HERE_IS_AUTHENTICATION 0
00196 #define SEND_ME_AUTHENTICATION 1
00197 #define AUTHENTICATION_STATUS 2
00198 #define AUTHENTICATION_NAME 3
00199 
00200 #define AUTH_REJECT 1
00201 #define AUTH_ACCEPT 2
00202 
00203 void TelnetAuthenticateOption::RecvSubOption(u_char* data, int len)
00204         {
00205         if ( len <= 0 )
00206                 {
00207                 BadOption();
00208                 return;
00209                 }
00210 
00211         switch ( data[0] ) {
00212         case HERE_IS_AUTHENTICATION:
00213                 {
00214                 TelnetAuthenticateOption* peer =
00215                         (TelnetAuthenticateOption*) endp->FindPeerOption(code);
00216 
00217                 if ( ! peer )
00218                         internal_error("option peer missing in TelnetAuthenticateOption::RecvSubOption");
00219 
00220                 if ( ! peer->DidRequestAuthentication() )
00221                         InconsistentOption(0);
00222                 }
00223                 break;
00224 
00225         case SEND_ME_AUTHENTICATION:
00226                 ++authentication_requested;
00227                 break;
00228 
00229         case AUTHENTICATION_STATUS:
00230                 if ( len <= 1 )
00231                         {
00232                         BadOption();
00233                         return;
00234                         }
00235 
00236                 if ( data[1] == AUTH_REJECT )
00237                         endp->AuthenticationRejected();
00238                 else if ( data[1] == AUTH_ACCEPT )
00239                         endp->AuthenticationAccepted();
00240                 else
00241                         // Don't complain, there may be replies we don't
00242                         // know about.
00243                         ;
00244                 break;
00245 
00246         case AUTHENTICATION_NAME:
00247                 {
00248                 char* auth_name = new char[len];
00249                 safe_strncpy(auth_name, (char*) data + 1, len);
00250                 endp->SetAuthName(auth_name);
00251                 }
00252                 break;
00253 
00254         default:
00255                 BadOption();
00256         }
00257         }
00258 
00259 #define ENVIRON_IS 0
00260 #define ENVIRON_SEND 1
00261 #define ENVIRON_INFO 2
00262 
00263 #define ENVIRON_VAR 0
00264 #define ENVIRON_VAL 1
00265 #define ENVIRON_ESC 2
00266 #define ENVIRON_USERVAR 3
00267 
00268 void TelnetEnvironmentOption::RecvSubOption(u_char* data, int len)
00269         {
00270         if ( len <= 0 )
00271                 {
00272                 BadOption();
00273                 return;
00274                 }
00275 
00276         if ( data[0] == ENVIRON_SEND )
00277                 //### We should track the dialog and make sure both sides agree.
00278                 return;
00279 
00280         if ( data[0] != ENVIRON_IS && data[0] != ENVIRON_INFO )
00281                 {
00282                 BadOption();
00283                 return;
00284                 }
00285 
00286         --len;  // Discard code.
00287         ++data;
00288 
00289         while ( len > 0 )
00290                 {
00291                 int code1, code2;
00292                 char* var_name = ExtractEnv(data, len, code1);
00293                 char* var_val = ExtractEnv(data, len, code2);
00294 
00295                 if ( ! var_name || ! var_val ||
00296                      (code1 != ENVIRON_VAR && code1 != ENVIRON_USERVAR) ||
00297                      code2 != ENVIRON_VAL )
00298                         {
00299                         BadOption();
00300                         break;
00301                         }
00302 
00303                 if ( var_name && var_val )
00304                         endp->Conn()->SetEnv(endp->IsOrig(), var_name, var_val);
00305                 else
00306                         { // One of var_name/var_val might be set; avoid leak.
00307                         delete var_name;
00308                         delete var_val;
00309                         }
00310                 }
00311         }
00312 
00313 char* TelnetEnvironmentOption::ExtractEnv(u_char*& data, int& len, int& code)
00314         {
00315         code = data[0];
00316 
00317         if ( code != ENVIRON_VAR && code != ENVIRON_VAL &&
00318              code != ENVIRON_USERVAR )
00319                 return 0;
00320 
00321         // Move past code.
00322         --len;
00323         ++data;
00324 
00325         // Find the end of this piece of the option.
00326         u_char* data_end = data + len;
00327         u_char* d;
00328         for ( d = data; d < data_end; ++d )
00329                 {
00330                 if ( *d == ENVIRON_VAR || *d == ENVIRON_VAL || *d == ENVIRON_USERVAR )
00331                         break;
00332 
00333                 if ( *d == ENVIRON_ESC )
00334                         {
00335                         ++d;    // move past ESC
00336                         if ( d >= data_end )
00337                                 return 0;
00338                         break;
00339                         }
00340                 }
00341 
00342         int size = d - data;
00343         char* env = new char[size+1];
00344 
00345         // Now copy into env.
00346         int d_ind = 0;
00347         int i;
00348         for ( i = 0; i < size; ++i )
00349                 {
00350                 if ( data[d_ind] == ENVIRON_ESC )
00351                         ++d_ind;
00352 
00353                 env[i] = data[d_ind];
00354                 ++d_ind;
00355                 }
00356 
00357         env[i] = '\0';
00358 
00359         data = d;
00360         len -= size;
00361 
00362         return env;
00363         }
00364 
00365 void TelnetBinaryOption::SetActive(int is_active)
00366         {
00367         endp->SetBinaryMode(is_active);
00368         active = is_active;
00369         }
00370 
00371 void TelnetBinaryOption::InconsistentOption(unsigned int /* type */)
00372         {
00373         // I don't know why, but this gets turned on redundantly -
00374         // doesn't do any harm, so ignore it.  Example is
00375         // in ex/redund-binary-opt.trace.
00376         }
00377 
00378 
00379 TCP_NVT::TCP_NVT(TCP_Endpoint* arg_endp,
00380                 int arg_is_NUL_sensitive, int arg_skip_partial, int CRLF_as_EOL)
00381 : TCP_ContentLine(arg_endp, arg_is_NUL_sensitive,
00382                    arg_skip_partial, CRLF_as_EOL)
00383         {
00384         is_suboption = last_was_IAC = pending_IAC = 0;
00385         IAC_pos = 0;
00386         num_options = 0;
00387         authentication_has_been_accepted = encrypting_mode = binary_mode = 0;
00388         auth_name = 0;
00389         peer = 0;
00390         }
00391 
00392 TCP_NVT::~TCP_NVT()
00393         {
00394         for ( int i = 0; i < num_options; ++i )
00395                 delete options[i];
00396 
00397         delete auth_name;
00398         }
00399 
00400 TelnetOption* TCP_NVT::FindOption(unsigned int code)
00401         {
00402         if ( ! peer )
00403                 // We can't do option processing if our peer doesn't
00404                 // keep track of connection contents, as then we can't
00405                 // see what's ack'd and what isn't.
00406                 return 0;
00407 
00408         int i;
00409         for ( i = 0; i < num_options; ++i )
00410                 if ( options[i]->Code() == code )
00411                         return options[i];
00412 
00413         TelnetOption* opt = 0;
00414         if ( i < NUM_TELNET_OPTIONS )
00415                 { // Maybe we haven't created this option yet.
00416                 switch ( code ) {
00417                 case TELNET_OPTION_BINARY:
00418                         opt = new TelnetBinaryOption(this);
00419                         break;
00420 
00421                 case TELNET_OPTION_TERMINAL:
00422                         opt = new TelnetTerminalOption(this);
00423                         break;
00424 
00425                 case TELNET_OPTION_ENCRYPT:
00426                         opt = new TelnetEncryptOption(this);
00427                         break;
00428 
00429                 case TELNET_OPTION_AUTHENTICATE:
00430                         opt = new TelnetAuthenticateOption(this);
00431                         break;
00432 
00433                 case TELNET_OPTION_ENVIRON:
00434                         opt = new TelnetEnvironmentOption(this);
00435                         break;
00436                 }
00437                 }
00438 
00439         if ( opt )
00440                 options[num_options++] = opt;
00441 
00442         return opt;
00443         }
00444 
00445 TelnetOption* TCP_NVT::FindPeerOption(unsigned int code)
00446         {
00447         if ( peer )
00448                 return peer->FindOption(code);
00449         else
00450                 return 0;
00451         }
00452 
00453 void TCP_NVT::AuthenticationAccepted()
00454         {
00455         authentication_has_been_accepted = 1;
00456         Conn()->Event(authentication_accepted, PeerAuthName());
00457         }
00458 
00459 void TCP_NVT::AuthenticationRejected()
00460         {
00461         authentication_has_been_accepted = 0;
00462         Conn()->Event(authentication_rejected, PeerAuthName());
00463         }
00464 
00465 const char* TCP_NVT::PeerAuthName() const
00466         {
00467         const char* p_auth_name = peer ? peer->AuthName() : 0;
00468         return p_auth_name ? p_auth_name : "<unknown>";
00469         }
00470 
00471 
00472 void TCP_NVT::SetTerminal(const u_char* terminal, int len)
00473         {
00474         if ( login_terminal )
00475                 {
00476                 val_list* vl = new val_list;
00477                 vl->append(Conn()->BuildConnVal());
00478                 vl->append(new StringVal(new BroString(terminal, len, 0)));
00479 
00480                 Conn()->ConnectionEvent(login_terminal, vl);
00481                 }
00482         }
00483 
00484 void TCP_NVT::SetEncrypting(int mode)
00485         {
00486         skip_deliveries = encrypting_mode = mode;
00487         if ( mode )
00488                 Conn()->Event(activating_encryption);
00489         }
00490 
00491 #define MAX_DELIVER_UNIT 128
00492 
00493 void TCP_NVT::DoDeliver(int seq, int len, const u_char* data)
00494         {
00495         // This code is very similar to that for TCP_ContentLine.  We
00496         // don't virtualize out the differences because some of them
00497         // would require per-character function calls, too expensive.
00498         if ( pending_IAC )
00499                 {
00500                 ScanOption(seq, len, data);
00501                 return;
00502                 }
00503 
00504         // Add data up to IAC or end.
00505         for ( ; len > 0; --len, ++data )
00506                 {
00507                 if ( offset >= buf_len )
00508                         Init(buf_len * 2);
00509 
00510                 int c = data[0];
00511 
00512                 if ( binary_mode && c != TELNET_IAC )
00513                         c &= 0x7f;
00514 
00515 #define EMIT_LINE \
00516         { \
00517         buf[offset] = '\0'; \
00518         Conn()->NewLine(this, offset, buf); \
00519         offset = 0; \
00520         }
00521 
00522                 switch ( c ) {
00523                 case '\r':
00524                         if ( CR_LF_as_EOL & CR_as_EOL )
00525                                 EMIT_LINE
00526                         else
00527                                 buf[offset++] = c;
00528                         break;
00529 
00530                 case '\n':
00531                         if ( last_char == '\r' )
00532                                 {
00533                                 if ( CR_LF_as_EOL & CR_as_EOL )
00534                                         // we already emited, skip
00535                                         ;
00536                                 else
00537                                         {
00538                                         --offset; // remove '\r'
00539                                         EMIT_LINE
00540                                         }
00541                                 }
00542 
00543                         else if ( CR_LF_as_EOL & LF_as_EOL )
00544                                 EMIT_LINE
00545 
00546                         else
00547                                 {
00548                                 if ( Conn()->FlagEvent(SINGULAR_LF) )
00549                                         Conn()->Weird("line_terminated_with_single_LF");
00550                                 buf[offset++] = c;
00551                                 }
00552                         break;
00553 
00554                 case '\0':
00555                         if ( last_char == '\r' )
00556                                 // Allow a NUL just after a \r - Solaris
00557                                 // Telnet servers generate these, and they
00558                                 // appear harmless.
00559                                 ;
00560 
00561                         else if ( flag_NULs )
00562                                 CheckNUL();
00563 
00564                         else
00565                                 buf[offset++] = c;
00566                         break;
00567 
00568                 case TELNET_IAC:
00569                         pending_IAC = 1;
00570                         IAC_pos = offset;
00571                         is_suboption = 0;
00572                         buf[offset++] = c;
00573                         ScanOption(seq, len - 1, data + 1);
00574                         return;
00575 
00576                 default:
00577                         buf[offset++] = c;
00578                         break;
00579                 }
00580 
00581                 if ( ! (CR_LF_as_EOL & CR_as_EOL) && 
00582                      last_char == '\r' && c != '\n' && c != '\0' )
00583                         {
00584                         if ( Conn()->FlagEvent(SINGULAR_CR) )
00585                                 Conn()->Weird("line_terminated_with_single_CR");
00586                         }
00587 
00588                 last_char = c;
00589                 }
00590         }
00591 
00592 void TCP_NVT::ScanOption(int seq, int len, const u_char* data)
00593         {
00594         if ( len <= 0 )
00595                 return;
00596 
00597         if ( IAC_pos == offset - 1 )
00598                 { // All we've seen so far is the IAC.
00599                 unsigned int code = data[0];
00600 
00601                 if ( code == TELNET_IAC )
00602                         {
00603                         // An escaped 255, throw away the second
00604                         // instance and drop the IAC state.
00605                         pending_IAC = 0;
00606                         last_char = code;
00607                         }
00608 
00609                 else if ( code == TELNET_OPT_SB )
00610                         {
00611                         is_suboption = 1;
00612                         last_was_IAC = 0;
00613                         buf[offset++] = code;
00614                         }
00615 
00616                 else if ( IS_3_BYTE_OPTION(code) )
00617                         {
00618                         is_suboption = 0;
00619                         buf[offset++] = code;
00620                         }
00621 
00622                 else
00623                         {
00624                         // We've got the whole 2-byte option.
00625                         SawOption(code);
00626 
00627                         // Throw it and the IAC away.
00628                         --offset;
00629                         pending_IAC = 0;
00630                         }
00631 
00632                 // Recurse to munch on the remainder.
00633                 Deliver(seq, len - 1, data + 1);
00634                 return;
00635                 }
00636 
00637         if ( ! is_suboption )
00638                 {
00639                 // We now have the full 3-byte option.
00640                 SawOption(u_char(buf[offset-1]), data[0]);
00641 
00642                 // Delete the option.
00643                 offset -= 2;    // code + IAC
00644                 pending_IAC = 0;
00645 
00646                 Deliver(seq, len - 1, data + 1);
00647                 return;
00648                 }
00649 
00650         // A suboption.  Spin looking for end.
00651         for ( ; len > 0; --len, ++data )
00652                 {
00653                 unsigned int code = data[0];
00654 
00655                 if ( last_was_IAC )
00656                         {
00657                         last_was_IAC = 0;
00658 
00659                         if ( code == TELNET_IAC )
00660                                 {
00661                                 // This is an escaped IAC, eat
00662                                 // the second copy.
00663                                 continue;
00664                                 }
00665 
00666                         if ( code != TELNET_OPT_SE )
00667                                 // BSD Telnet treats this case as terminating
00668                                 // the suboption, so that's what we do here
00669                                 // too.  Below we make sure to munch on the
00670                                 // new IAC.
00671                                 BadOptionTermination(code);
00672 
00673                         int opt_start = IAC_pos + 2;
00674                         int opt_stop = offset - 1;
00675                         int opt_len = opt_stop - opt_start;
00676                         SawSubOption(&buf[opt_start], opt_len);
00677 
00678                         // Delete suboption.
00679                         offset = IAC_pos;
00680                         pending_IAC = is_suboption = 0;
00681 
00682                         if ( code == TELNET_OPT_SE )
00683                                 Deliver(seq, len - 1, data + 1);
00684                         else
00685                                 {
00686                                 // Munch on the new (broken) option.
00687                                 pending_IAC = 1;
00688                                 IAC_pos = offset;
00689                                 buf[offset++] = TELNET_IAC;
00690                                 Deliver(seq, len, data);
00691                                 }
00692                         return;
00693                         }
00694 
00695                 else
00696                         {
00697                         buf[offset++] = code;
00698                         last_was_IAC = (code == TELNET_IAC);
00699                         }
00700                 }
00701         }
00702 
00703 void TCP_NVT::SawOption(unsigned int /* code */)
00704         {
00705         }
00706 
00707 void TCP_NVT::SawOption(unsigned int code, unsigned int subcode)
00708         {
00709         TelnetOption* opt = FindOption(subcode);
00710         if ( opt )
00711                 opt->RecvOption(code);
00712         }
00713 
00714 void TCP_NVT::SawSubOption(const char* subopt, int len)
00715         {
00716         unsigned int subcode = u_char(subopt[0]);
00717 
00718         ++subopt;
00719         --len;
00720 
00721         TelnetOption* opt = FindOption(subcode);
00722         if ( opt )
00723                 opt->RecvSubOption((u_char*) subopt, len);
00724         }
00725 
00726 void TCP_NVT::BadOptionTermination(unsigned int /* code */)
00727         {
00728         Conn()->Event(bad_option_termination);
00729         }
00730 
00731 IMPLEMENT_SERIAL(TCP_NVT, SER_TCP_NVT)
00732 
00733 bool TCP_NVT::DoSerialize(SerialInfo* info) const
00734         {
00735         DO_SERIALIZE(SER_TCP_NVT, TCP_ContentLine);
00736 
00737         if ( ! peer->Serialize(info) )
00738                 return false;
00739 
00740         if ( ! SERIALIZE(num_options) )
00741                 return false;
00742 
00743         // For simplicity, we don't add the serialization stuff to the
00744         // TelnetOptions, but hard-code this here.
00745         for ( int i = 0; i < num_options; ++i )
00746                 {
00747                 TelnetOption* o = options[i];
00748                 if ( ! SERIALIZE(o->code) )
00749                         return false;
00750 
00751                 switch ( o->code ) {
00752 
00753                 case TELNET_OPTION_ENCRYPT:
00754                         {
00755                         TelnetEncryptOption* eo = (TelnetEncryptOption*) o;
00756                         if ( ! (SERIALIZE(eo->doing_encryption) &&
00757                                 SERIALIZE(eo->did_encrypt_request)) )
00758                                 return false;
00759                         break;
00760                         }
00761 
00762                 case TELNET_OPTION_AUTHENTICATE:
00763                         {
00764                         TelnetAuthenticateOption* ao =
00765                                 (TelnetAuthenticateOption*) o;
00766                         if ( ! SERIALIZE(ao->authentication_requested) )
00767                                 return false;
00768                         break;
00769                         }
00770                 }
00771 
00772                 if ( ! (SERIALIZE(o->flags) && SERIALIZE(o->active) &&
00773                         o->endp->Serialize(info)) )
00774                         return false;
00775                 }
00776 
00777         SERIALIZE_OPTIONAL_STR(auth_name);
00778 
00779         return SERIALIZE(pending_IAC) &&
00780                 SERIALIZE(IAC_pos) &&
00781                 SERIALIZE(is_suboption) &&
00782                 SERIALIZE(last_was_IAC) &&
00783                 SERIALIZE(binary_mode) &&
00784                 SERIALIZE(encrypting_mode) &&
00785                 SERIALIZE(authentication_has_been_accepted);
00786         }
00787 
00788 bool TCP_NVT::DoUnserialize(UnserialInfo* info)
00789         {
00790         DO_UNSERIALIZE(TCP_ContentLine);
00791 
00792         peer = (TCP_NVT*) TCP_Contents::Unserialize(info);
00793         if ( ! peer )
00794                 return false;
00795 
00796         if ( ! UNSERIALIZE(&num_options) )
00797                 return false;
00798 
00799         for ( int i = 0; i < num_options; ++i )
00800                 {
00801                 TelnetOption* o = 0;
00802                 unsigned int code;
00803                 if ( ! UNSERIALIZE(&code) )
00804                         return false;
00805 
00806                 switch ( code ) {
00807 
00808                 case TELNET_OPTION_BINARY:
00809                         o = new TelnetBinaryOption(0);
00810                         break;
00811 
00812                 case TELNET_OPTION_TERMINAL:
00813                         o = new TelnetTerminalOption(0);
00814                         break;
00815 
00816                 case TELNET_OPTION_ENCRYPT:
00817                         {
00818                         TelnetEncryptOption* eo = new TelnetEncryptOption(0);
00819                         if ( ! (UNSERIALIZE(&eo->doing_encryption) &&
00820                                 UNSERIALIZE(&eo->did_encrypt_request)) )
00821                                 return false;
00822                         o = eo;
00823                         break;
00824                         }
00825 
00826                 case TELNET_OPTION_AUTHENTICATE:
00827                         {
00828                         TelnetAuthenticateOption* ao =
00829                                 new TelnetAuthenticateOption(0);
00830                         if ( ! UNSERIALIZE(&ao->authentication_requested) )
00831                                 return false;
00832                         o = ao;
00833                         break;
00834                         }
00835 
00836                 case TELNET_OPTION_ENVIRON:
00837                         o = new TelnetEnvironmentOption(0);
00838                         break;
00839 
00840                 default:
00841                         info->s->Error("unknown telnet option");
00842                         return false;
00843                 }
00844 
00845                 if ( ! (UNSERIALIZE(&o->flags) && UNSERIALIZE(&o->active)) )
00846                         return false;
00847 
00848                 o->endp = (TCP_NVT*) TCP_Contents::Unserialize(info);
00849                 if ( ! o->endp )
00850                         return false;
00851 
00852                 options[i] = o;
00853                 }
00854 
00855         UNSERIALIZE_OPTIONAL_STR(auth_name);
00856 
00857         return UNSERIALIZE(&pending_IAC) &&
00858                 UNSERIALIZE(&IAC_pos) &&
00859                 UNSERIALIZE(&is_suboption) &&
00860                 UNSERIALIZE(&last_was_IAC) &&
00861                 UNSERIALIZE(&binary_mode) &&
00862                 UNSERIALIZE(&encrypting_mode) &&
00863                 UNSERIALIZE(&authentication_has_been_accepted);
00864         }

Generated on Wed Sep 14 02:56:17 2005 for bro_docs by doxygen 1.3.5