00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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* , int )
00107 {
00108 }
00109
00110 void TelnetOption::SetActive(int is_active)
00111 {
00112 active = is_active;
00113 }
00114
00115 void TelnetOption::InconsistentOption(unsigned int )
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
00242
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
00278 return;
00279
00280 if ( data[0] != ENVIRON_IS && data[0] != ENVIRON_INFO )
00281 {
00282 BadOption();
00283 return;
00284 }
00285
00286 --len;
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 {
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
00322 --len;
00323 ++data;
00324
00325
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;
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
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 )
00372 {
00373
00374
00375
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
00404
00405
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 {
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
00496
00497
00498 if ( pending_IAC )
00499 {
00500 ScanOption(seq, len, data);
00501 return;
00502 }
00503
00504
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
00535 ;
00536 else
00537 {
00538 --offset;
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
00557
00558
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 {
00599 unsigned int code = data[0];
00600
00601 if ( code == TELNET_IAC )
00602 {
00603
00604
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
00625 SawOption(code);
00626
00627
00628 --offset;
00629 pending_IAC = 0;
00630 }
00631
00632
00633 Deliver(seq, len - 1, data + 1);
00634 return;
00635 }
00636
00637 if ( ! is_suboption )
00638 {
00639
00640 SawOption(u_char(buf[offset-1]), data[0]);
00641
00642
00643 offset -= 2;
00644 pending_IAC = 0;
00645
00646 Deliver(seq, len - 1, data + 1);
00647 return;
00648 }
00649
00650
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
00662
00663 continue;
00664 }
00665
00666 if ( code != TELNET_OPT_SE )
00667
00668
00669
00670
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
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
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 )
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 )
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
00744
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 }