Changeset 828


Ignore:
Timestamp:
11/26/08 02:51:23 (3 years ago)
Author:
wd
Message:

Prevent data that shoots past the buffer limit in 1459-style protocols from
being treated as a new command.

Location:
branches/ithildin-1.1/modules/ircd
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/ithildin-1.1/modules/ircd/connection.h

    r772 r828  
    4646    } stats; 
    4747 
    48 #define IRCD_CONNFL_DNS_PTR     0x1 
    49 #define IRCD_CONNFL_DNS_ADDR    0x2 
    50 #define IRCD_CONNFL_DNS        (IRCD_CONNFL_DNS_PTR | IRCD_CONNFL_DNS_ADDR) 
    51 #define IRCD_CONNFL_IDENT       0x4 
    52 #define IRCD_CONNFL_STAGE2      0x8 
     48#define IRCD_CONNFL_DNS_PTR         0x1 
     49#define IRCD_CONNFL_DNS_ADDR        0x2 
     50#define IRCD_CONNFL_DNS            (IRCD_CONNFL_DNS_PTR | IRCD_CONNFL_DNS_ADDR) 
     51#define IRCD_CONNFL_IDENT           0x4 
     52#define IRCD_CONNFL_STAGE2          0x8 
    5353#define IRCD_CONN_DONE(x)                                                     \ 
    5454    (((x)->flags & (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) ==                  \ 
     
    5656#define IRCD_CONN_NEED_STAGE2(x) (!((x)->flags & IRCD_CONNFL_STAGE2)) 
    5757 
    58 #define IRCD_CONNFL_WRITEABLE 0x100 /* set if the socket is writeable */ 
     58#define IRCD_CONNFL_WRITEABLE       0x100 /* set if the socket is writeable */ 
    5959#define CONN_PINGSENT(conn) (conn->flags & IRCD_CONNFL_PINGSENT) 
    60 #define IRCD_CONNFL_PINGSENT  0x200 /* set when a PING is sent to test for 
    61                                        activity */ 
     60#define IRCD_CONNFL_PINGSENT        0x200 /* set when a PING is sent to test 
     61                                             for activity */ 
    6262         
    63 #define IRCD_CONNFL_NOSENDQ   0x400 /* this is set if we don't want to observe 
    64                                        send queue limits on the connection 
    65                                        (mostly useful for sending 
    66                                        synchronization data to servers).  it is 
    67                                        not unset until sendq drops to 0. */ 
     63#define IRCD_CONNFL_NOSENDQ         0x400 /* this is set if we don't want to 
     64                                             observe send queue limits on the 
     65                                             connection (mostly useful for 
     66                                             sending synchronization data to 
     67                                             servers).  it is not unset until 
     68                                             sendq drops to 0. */ 
    6869#ifdef HAVE_OPENSSL 
    69 #define IRCD_CONNFL_SSLINIT   0x800 /* set when we're waiting for the first 
    70                                        data event for an initiating SSL socket. 
    71                                        when we get this event we can begin the 
    72                                        regular connection initiation. */ 
     70#define IRCD_CONNFL_SSLINIT         0x800 /* set when we're waiting for the 
     71                                             first data event for an initiating 
     72                                             SSL socket.  when we get this 
     73                                             event we can begin the regular 
     74                                             connection initiation. */ 
    7375#endif 
     76#define IRCD_CONNFL_DIRTYBUFFER    0x1000 /* set when the contents of the 
     77                                             buffer are 'dirty' (typically 
     78                                             an overflow command which must 
     79                                             be discarded) */ 
    7480 
    7581    int     flags;                  /* connection flags (DO NOT PUT 
  • branches/ithildin-1.1/modules/ircd/protocols/shared/rfc1459_io.c

    r825 r828  
    2222    int ret = 0; 
    2323    char *s; 
     24    bool dirtybuffer; 
    2425 
    2526    /* If we were force-called (ep is NULL) we assume there is data in our 
     
    3536 
    3637        while (cp->buflen > 0) { 
     38            dirtybuffer = false; 
    3739            /* if the buffer is full but no terminating character (\n) is 
    3840               found, we cheat */ 
     
    4547                    s++; 
    4648 
     49                /* A command without a newline, add it and note that the 
     50                 * future contents of the buffer are dirty (handled below 
     51                 * when we pass out the data) */ 
    4752                if (s == cp->buf + cp->bufsize) { 
    4853                    cp->buf[cp->bufsize - 1] = '\n'; 
    4954                    s = cp->buf + cp->bufsize - 1; 
     55                    dirtybuffer = true; 
    5056                } 
    5157            } else { 
     
    5561                    break; /* no separator found, try reading some more */ 
    5662            } 
    57             /* make a local copy of the packet, then pass it off to the parser.  
    58              * Bump the rest of the contents of 'buf' down if we read more than 
    59              * we have parsed. */ 
     63 
    6064            /* null-terminate and get rid of the [\r]\n sequence. */ 
    6165            if (s > cp->buf && *(s - 1) == '\r') 
     
    6367            else 
    6468                *s = '\0'; 
     69 
    6570            log_debug("[%s] <%s< %s", ircd.me->name, 
    6671                    (cp->cli != NULL ? cp->cli->nick : 
    6772                     (cp->srv != NULL ? cp->srv->name : "")), cp->buf); 
    68             if ((ret = packet_parse(cp)) == IRCD_CONNECTION_CLOSED) 
    69                 return (void *)ret; /* connection closed, stop immediately */ 
     73            /* Don't parse the packet if the buffer is dirty, otherwise do 
     74             * call the parser. */ 
     75            if (!(cp->flags & IRCD_CONNFL_DIRTYBUFFER)) 
     76            { 
     77                if ((ret = packet_parse(cp)) == IRCD_CONNECTION_CLOSED) 
     78                    return (void *)ret; /* connection closed, stop immediately */ 
     79            } else 
     80                cp->flags &= ~IRCD_CONNFL_DIRTYBUFFER; 
     81 
    7082            s++; /* increment s, now we see if our packet contains more data */ 
    7183            if (s - cp->buf < cp->buflen) { 
     
    7789                *cp->buf = '\0'; /* zero it out */ 
    7890            } 
     91 
     92            /* If the buffer is marked dirty, set the flag now on the 
     93             * connection (since we have passed off the previous command) */ 
     94            if (dirtybuffer) 
     95                cp->flags |= IRCD_CONNFL_DIRTYBUFFER; 
    7996 
    8097            if (ret == IRCD_PROTOCOL_CHANGED) 
     
    128145            buf[sm.len++] = ' '; 
    129146 
    130         sm.len += vsnprintf(&buf[sm.len], MAX_PACKET_LEN - 3 - sm.len, msg, 
    131                 args); 
     147        sm.len += vsnprintf(&buf[sm.len], MAX_PACKET_LEN - sm.len, msg, args); 
    132148    } 
    133149 
     
    139155            (to != NULL ? to : ""), buf); 
    140156 
    141     strcpy(&buf[sm.len], "\r\n"); 
    142     sm.len += 2; 
     157    /* Terminate the command */ 
     158    if (sm.len > MAX_PACKET_LEN - 2) 
     159        sm.len = MAX_PACKET_LEN - 2; 
     160    buf[sm.len++] = '\r'; 
     161    buf[sm.len++] = '\n'; 
    143162 
    144163    return &sm; 
Note: See TracChangeset for help on using the changeset viewer.