LCOV - code coverage report
Current view: top level - src - Rlogin.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2 120 1.7 %
Date: 2010-12-13 Functions: 2 14 14.3 %
Branches: 2 88 2.3 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Rlogin.cc 6219 2008-10-01 05:39:07Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include "NetVar.h"
       8                 :            : #include "Event.h"
       9                 :            : #include "Rlogin.h"
      10                 :            : 
      11                 :            : 
      12                 :          0 : Contents_Rlogin_Analyzer::Contents_Rlogin_Analyzer(Connection* conn, bool orig, Rlogin_Analyzer* arg_analyzer)
      13                 :          0 : : ContentLine_Analyzer(AnalyzerTag::Contents_Rlogin, conn, orig)
      14                 :            :         {
      15                 :          0 :         num_bytes_to_scan = num_bytes_to_scan = 0;
      16                 :          0 :         analyzer = arg_analyzer;
      17                 :          0 :         peer = 0;
      18                 :            : 
      19   [ #  #  #  # ]:          0 :         if ( orig )
      20                 :          0 :                 state = save_state = RLOGIN_FIRST_NULL;
      21                 :            :         else
      22                 :          0 :                 state = save_state = RLOGIN_SERVER_ACK;
      23                 :          0 :         }
      24                 :            : 
      25                 :          0 : Contents_Rlogin_Analyzer::~Contents_Rlogin_Analyzer()
      26                 :            :         {
      27 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
      28                 :            : 
      29                 :          0 : void Contents_Rlogin_Analyzer::DoDeliver(int len, const u_char* data)
      30                 :            :         {
      31                 :          0 :         TCP_Analyzer* tcp = static_cast<TCP_ApplicationAnalyzer*>(Parent())->TCP();
      32         [ #  # ]:          0 :         assert(tcp);
      33                 :            : 
      34         [ #  # ]:          0 :         int endp_state = IsOrig() ? tcp->OrigState() : tcp->RespState();
      35                 :            : 
      36         [ #  # ]:          0 :         for ( ; len > 0; --len, ++data )
      37                 :            :                 {
      38         [ #  # ]:          0 :                 if ( offset >= buf_len )
      39                 :          0 :                         InitBuffer(buf_len * 2);
      40                 :            : 
      41                 :          0 :                 unsigned int c = data[0];
      42                 :            : 
      43 [ #  #  #  #  # :          0 :                 switch ( state ) {
                #  #  # ]
      44                 :            :                 case RLOGIN_FIRST_NULL:
      45 [ #  # ][ #  # ]:          0 :                         if ( endp_state == TCP_ENDPOINT_PARTIAL ||
      46                 :            :                              // We can be in closed if the data's due to
      47                 :            :                              // a dataful FIN being the first thing we see.
      48                 :            :                              endp_state == TCP_ENDPOINT_CLOSED )
      49                 :            :                                 {
      50                 :          0 :                                 state = RLOGIN_UNKNOWN;
      51                 :          0 :                                 ++len, --data;  // put back c and reprocess
      52                 :          0 :                                 continue;
      53                 :            :                                 }
      54                 :            : 
      55         [ #  # ]:          0 :                         if ( c == '\0' )
      56                 :          0 :                                 state = RLOGIN_CLIENT_USER_NAME;
      57                 :            :                         else
      58                 :          0 :                                 BadProlog();
      59                 :          0 :                         break;
      60                 :            : 
      61                 :            :                 case RLOGIN_CLIENT_USER_NAME:
      62                 :            :                 case RLOGIN_SERVER_USER_NAME:
      63                 :            :                 case RLOGIN_TERMINAL_TYPE:
      64                 :          0 :                         buf[offset++] = c;
      65         [ #  # ]:          0 :                         if ( c == '\0' )
      66                 :            :                                 {
      67         [ #  # ]:          0 :                                 if ( state == RLOGIN_CLIENT_USER_NAME )
      68                 :            :                                         {
      69                 :          0 :                                         analyzer->ClientUserName((const char*) buf);
      70                 :          0 :                                         state = RLOGIN_SERVER_USER_NAME;
      71                 :            :                                         }
      72                 :            : 
      73         [ #  # ]:          0 :                                 else if ( state == RLOGIN_SERVER_USER_NAME )
      74                 :            :                                         {
      75                 :          0 :                                         analyzer->ServerUserName((const char*) buf);
      76                 :          0 :                                         state = RLOGIN_TERMINAL_TYPE;
      77                 :            :                                         }
      78                 :            : 
      79         [ #  # ]:          0 :                                 else if ( state == RLOGIN_TERMINAL_TYPE )
      80                 :            :                                         {
      81                 :          0 :                                         analyzer->TerminalType((const char*) buf);
      82                 :          0 :                                         state = RLOGIN_LINE_MODE;
      83                 :            :                                         }
      84                 :            : 
      85                 :          0 :                                 offset = 0;
      86                 :            :                                 }
      87                 :          0 :                         break;
      88                 :            : 
      89                 :            :                 case RLOGIN_SERVER_ACK:
      90 [ #  # ][ #  # ]:          0 :                         if ( endp_state == TCP_ENDPOINT_PARTIAL ||
      91                 :            :                              // We can be in closed if the data's due to
      92                 :            :                              // a dataful FIN being the first thing we see.
      93                 :            :                              endp_state == TCP_ENDPOINT_CLOSED )
      94                 :            :                                 {
      95                 :          0 :                                 state = RLOGIN_UNKNOWN;
      96                 :          0 :                                 ++len, --data;  // put back c and reprocess
      97                 :          0 :                                 continue;
      98                 :            :                                 }
      99                 :            : 
     100         [ #  # ]:          0 :                         if ( c == '\0' )
     101                 :          0 :                                 state = RLOGIN_LINE_MODE;
     102                 :            :                         else
     103                 :          0 :                                 state = RLOGIN_PRESUMED_REJECTED;
     104                 :          0 :                         break;
     105                 :            : 
     106                 :            :                 case RLOGIN_IN_BAND_CONTROL_FF2:
     107         [ #  # ]:          0 :                         if ( c == 255 )
     108                 :          0 :                                 state = RLOGIN_WINDOW_CHANGE_S1;
     109                 :            :                         else
     110                 :            :                                 {
     111                 :            :                                 // Put back the \ff that took us into
     112                 :            :                                 // this state.
     113                 :          0 :                                 buf[offset++] = 255;
     114                 :          0 :                                 state = save_state;
     115                 :          0 :                                 ++len, --data;  // put back c and reprocess
     116                 :          0 :                                 continue;
     117                 :            :                                 }
     118                 :          0 :                         break;
     119                 :            : 
     120                 :            :                 case RLOGIN_WINDOW_CHANGE_S1:
     121                 :            :                 case RLOGIN_WINDOW_CHANGE_S2:
     122         [ #  # ]:          0 :                         if ( c == 's' )
     123                 :            :                                 {
     124         [ #  # ]:          0 :                                 if ( state == RLOGIN_WINDOW_CHANGE_S1 )
     125                 :          0 :                                         state = RLOGIN_WINDOW_CHANGE_S2;
     126                 :            :                                 else
     127                 :            :                                         {
     128                 :          0 :                                         state = RLOGIN_WINDOW_CHANGE_REMAINDER;
     129                 :          0 :                                         num_bytes_to_scan = 8;
     130                 :            :                                         }
     131                 :            :                                 }
     132                 :            :                         else
     133                 :            :                                 { 
     134                 :            :                                 // Unknown control, or we're confused.
     135                 :            :                                 // Put back what we've consumed.
     136                 :            :                                 unsigned char buf[64];
     137                 :          0 :                                 int n = 0;
     138                 :          0 :                                 buf[n++] = '\xff';
     139                 :          0 :                                 buf[n++] = '\xff';
     140                 :            : 
     141         [ #  # ]:          0 :                                 if ( state == RLOGIN_WINDOW_CHANGE_S2 )
     142                 :          0 :                                         buf[n++] = 's';
     143                 :            : 
     144                 :          0 :                                 state = RLOGIN_UNKNOWN;
     145                 :            : 
     146                 :          0 :                                 DoDeliver(n, buf);
     147                 :            :                                 }
     148                 :          0 :                         break;
     149                 :            : 
     150                 :            :                 case RLOGIN_WINDOW_CHANGE_REMAINDER:
     151         [ #  # ]:          0 :                         if ( --num_bytes_to_scan == 0 )
     152                 :          0 :                                 state = save_state;
     153                 :          0 :                         break;
     154                 :            : 
     155                 :            :                 case RLOGIN_LINE_MODE:
     156                 :            :                 case RLOGIN_UNKNOWN:
     157                 :            :                 case RLOGIN_PRESUMED_REJECTED:
     158         [ #  # ]:          0 :                         assert(peer);
     159 [ #  # ][ #  # ]:          0 :                         if ( state == RLOGIN_LINE_MODE &&
     160                 :            :                              peer->state == RLOGIN_PRESUMED_REJECTED )
     161                 :            :                                 {
     162                 :          0 :                                 Conn()->Weird("rlogin_text_after_rejected");
     163                 :          0 :                                 state = RLOGIN_UNKNOWN;
     164                 :            :                                 }
     165                 :            : 
     166 [ #  # ][ #  # ]:          0 :                         if ( c == '\n' || c == '\r' ) // CR or LF (RFC 1282)
     167                 :            :                                 {
     168 [ #  # ][ #  # ]:          0 :                                 if ( c == '\n' && last_char == '\r' )
     169                 :            :                                         // Compress CRLF to just 1 termination.
     170                 :            :                                         ;
     171                 :            :                                 else
     172                 :            :                                         {
     173                 :          0 :                                         buf[offset] = '\0';
     174                 :          0 :                                         ForwardStream(offset, buf, IsOrig()); \
     175                 :            :                                         offset = 0;
     176                 :          0 :                                         break;
     177                 :            :                                         }
     178                 :            :                                 }
     179                 :            : 
     180 [ #  # ][ #  # ]:          0 :                         else if ( c == 255 && IsOrig() &&
         [ #  # ][ #  # ]
                 [ #  # ]
     181                 :            :                                   state != RLOGIN_PRESUMED_REJECTED &&
     182                 :            :                                   state != RLOGIN_UNKNOWN )
     183                 :            :                                 {
     184                 :          0 :                                 save_state = state;
     185                 :          0 :                                 state = RLOGIN_IN_BAND_CONTROL_FF2;
     186                 :            :                                 }
     187                 :            : 
     188                 :            :                         else
     189                 :          0 :                                 buf[offset++] = c;
     190                 :            : 
     191                 :          0 :                         last_char = c;
     192                 :          0 :                         break;
     193                 :            : 
     194                 :            :                 default:
     195                 :          0 :                         internal_error("bad state in Contents_Rlogin_Analyzer::DoDeliver");
     196                 :            :                         break;
     197                 :            :                 }
     198                 :            :                 }
     199                 :          0 :         }
     200                 :            : 
     201                 :          0 : void Contents_Rlogin_Analyzer::BadProlog()
     202                 :            :         {
     203                 :          0 :         Conn()->Weird("bad_rlogin_prolog");
     204                 :          0 :         state = RLOGIN_UNKNOWN;
     205                 :          0 :         }
     206                 :            : 
     207                 :            : 
     208                 :          0 : Rlogin_Analyzer::Rlogin_Analyzer(Connection* conn)
     209                 :          0 : : Login_Analyzer(AnalyzerTag::Rlogin, conn)
     210                 :            :         {
     211                 :            :         Contents_Rlogin_Analyzer* orig =
     212                 :          0 :                 new Contents_Rlogin_Analyzer(conn, true, this);
     213                 :            :         Contents_Rlogin_Analyzer* resp =
     214                 :          0 :                 new Contents_Rlogin_Analyzer(conn, false, this);
     215                 :            : 
     216                 :          0 :         orig->SetPeer(resp);
     217                 :          0 :         resp->SetPeer(orig);
     218                 :            : 
     219                 :          0 :         AddSupportAnalyzer(orig);
     220                 :          0 :         AddSupportAnalyzer(resp);
     221                 :          0 :         }
     222                 :            : 
     223                 :          0 : void Rlogin_Analyzer::ClientUserName(const char* s)
     224                 :            :         {
     225         [ #  # ]:          0 :         if ( client_name )
     226                 :          0 :                 internal_error("multiple rlogin client names");
     227                 :            : 
     228                 :          0 :         client_name = new StringVal(s);
     229                 :          0 :         }
     230                 :            : 
     231                 :          0 : void Rlogin_Analyzer::ServerUserName(const char* s)
     232                 :            :         {
     233                 :          0 :         ++num_user_lines_seen;
     234                 :          0 :         ++login_prompt_line;
     235                 :          0 :         AddUserText(s);
     236                 :          0 :         }
     237                 :            : 
     238                 :          0 : void Rlogin_Analyzer::TerminalType(const char* s)
     239                 :            :         {
     240         [ #  # ]:          0 :         if ( login_terminal )
     241                 :            :                 {
     242                 :          0 :                 val_list* vl = new val_list;
     243                 :            : 
     244                 :          0 :                 vl->append(BuildConnVal());
     245                 :          0 :                 vl->append(new StringVal(s));
     246                 :            : 
     247                 :          0 :                 ConnectionEvent(login_terminal, vl);
     248                 :            :                 }
     249 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8