/* $Id: log.c,v 1.12 1999/06/24 18:52:07 levitte Exp $ */ #include "gnu_extras.h" #include #include #include #include #include #include #include "fish.h" #include "ssh.h" #include "log.h" #include "util.h" #include "fishmsg.h" /* I stole this from Dave Jones' SSH_SERVER */ /* * Define table of format strings for format and scan functions, used to * pack and unpack data into SSH protocol messages. String encodes layout of * message: * i 32-bit integer, stored into next arg in host order. * m multi-precision integer, stored into next 2 args. * nb 'n' bytes (e.g. 8b). * s Counted string, stored into next 2 args: count and pointer. * p Counted string containing password, stored into next 2 args: * count and pointer. * nx Return current buffer pointer, advance by n if n not zero. * . Terminates format, REQUIRED. Remainder of string is * descriptive text. */ static char *msg_format[] = { ".MSG_NONE", /* 0 - none */ "s.MSG_DISCONNECT", /* 1 - disconnect */ "8bimmimmiii.SMSG_PUBLIC_KEY", /* 2 - public_key */ "b8bmi.CMSG_SESSION_KEY", /* 3 - sesion_key */ "s.CMSG_USER", /* 4 - user */ "s.CMSG_AUTH_RHOSTS", /* 5 - auth rhosts */ "m.CMSG_AUTH_RSA", /* 6 - auth rsa */ "m.SMSG_AUTH_RSA_CHALLENGE", /* 7 - auth rsa challenge */ "16b.CMSG_AUTH_RSA_RESPONSE", /* 8 - auth rsa response */ "p.CMSG_AUTH_PASSWORD", /* 9 - password */ "siiiix.CMSG_REQUEST_PTY", /* 10 - request pty */ "iiii.CMSG_WINDOW_SIZE", /* 11 - window size */ ".CMSG_EXEC_SHELL", /* 12 - exec shell */ "s.CMSG_EXEC_CMD", /* 13 - exec cmd */ ".SMSG_SUCCESS", /* 14 - success */ ".SMSG_FAILURE", /* 15 - failure */ "s.CMSG_STDIN_DATA", /* 16 - stdin data */ "s.SMSG_STDOUT_DATA", /* 17 - stdout data */ "s.SMSG_STDERR_DATA", /* 18 - stderr data */ ".CMSG_EOF", /* 19 - stdin EOF */ "i.SMSG_EXITSTATUS", /* 20 - exit status*/ "ii.MSG_CHANNEL_OPEN_CONFIRMATION", /* 21 - channel open confirm */ "i.MSG_CHANNEL_OPEN_FAILURE", /* 22 - channel open failure */ "is.MSG_CHANNEL_DATA", /* 23 - channel data */ "i.MSG_CHANNEL_CLOSE", /* 24 - channel close */ "i.MSG_CHANNEL_CLOSE_CONFIRMATION", /* 25 - channel close confirm */ ".CMSG_X11_REQUEST_FORWARDING", /* 26 - X11 request forwarding */ "is.SMSG_X11_OPEN", /* 27 - X11 open */ "isi.CMSG_PORT_FORWARD_REQUEST", /* 28 - port forward request */ "isis.MSG_PORT_OPEN", /* 29 - port open */ ".CMSG_AGENT_REQUEST_FORWARDING", /* 30 - agent request forwarding */ "i.SMSG_AGENT_OPEN", /* 31 - agent open */ "s.MSG_IGNORE", /* 32 - NOP message */ ".CMSG_EXIT_CONFIRMATION", /* 33 - exit confirmation */ "ssi.CMSG_X11_REQUEST_FORWARDING", /* 34 - x11 forward with auth spoof */ "simm.CMSG_AUTH_RHOSTS_RSA", /* 35 - auth rhosts rsa */ "s.MSG_DEBUG", /* 36 - debug message */ "i.CMSG_REQUEST_COMPRESSION", /* 37 - compression request */ "i.CMSG_MAX_PACKET_SIZE", /* 38 - max packet size */ ".CMSG_AUTH_TIS", /* 39 - start TIS authorization */ "s.SMSG_AUTH_TIS_CHALLENGE", /* 40 - server TIS challenge */ "p.CMSG_AUTH_TIS_RESPONSE", /* 41 - challenge response */ "s.CMSG_AUTH_KERBEROS", /* 42 - start Kerberos authorization */ "s.SMSG_AUTH_KERBEROS_RESPONSE", /* 43 - server response */ "s.CMSG_HAVE_KERBEROS_TGT", /* 43 - kerberos creadentials */ }; int log_verbose(int type, general_buffer_reader *data, ssh_state *state) { char *msg_type = 0; char *fmt; int i; int count = 0; general_buffer *buf; general_buffer_reader br; /* We want to duplicate the reader, so the pointers needed by others will stay the same... */ memcpy(&br, data, sizeof(general_buffer_reader)); if (type == -1) return SS$_NORMAL; switch(type) { case SSH_CMSG_STDIN_DATA: case SSH_SMSG_STDOUT_DATA: case SSH_SMSG_STDERR_DATA: case SSH_CMSG_EOF: case SSH_MSG_CHANNEL_DATA: if (!(verbose & VERBOSE_M_IO)) return SS$_NORMAL; break; } buf = buf_init(1024); fmt = msg_format[type]; for (i = count = 0; fmt[i] != '.'; i++) switch(fmt[i]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': count = count*10 + (fmt[i] - '0'); break; case '?': case 'b': case 'x': { int j; char *prefix = ""; int prefix_l = 0; char tmpbuf[15]; int tmptotal; char tmpc; buf_append_chars_nocount(buf, ", "); if (count == 0) count = 1; else { sprintf(tmpbuf, "(%d)", count); buf_append_chars_nocount(buf, tmpbuf); } switch(fmt[i]) { case '?': count = bufread_remaining(&br);; buf_append_chars_nocount(buf, "?"); break; case 'x': buf_append_chars_nocount(buf, "{Raw}"); break; } tmpc = '['; for (j = count; j-- > 0;) { unsigned char c; bufread_bytes(&br, &c, 1); sprintf(tmpbuf,"%02X", c); buf_append_bytes(buf, &tmpc, 1); tmpc = ' '; buf_append_chars_nocount(buf, tmpbuf); } buf_append_chars_nocount(buf, "]"); count = 0; break; } case 'i': { unsigned long j; char tmpbuf[11]; bufread_int(&br, &j); sprintf(tmpbuf, ", %08X", j); buf_append_chars_nocount(buf, tmpbuf); break; } case 'm': { int j; unsigned short size; unsigned short bytes; char tmpbuf[30]; int tmptotal; bufread_word(&br, &size); bytes = (size+7)/8; sprintf(tmpbuf, ", (%d/%d)", size, bytes); buf_append_chars_nocount(buf, tmpbuf); for (j = bytes; j-- > 0;) { unsigned char c; bufread_bytes(&br, &c, 1); sprintf(tmpbuf,"%02X", c); buf_append_chars_nocount(buf, tmpbuf); } break; } case 's': case 'p': { unsigned long size; char *data_p; char tmpbuf[30]; int tmptotal; bufread_int(&br, &size); sprintf(tmpbuf, ", (%d)", size); buf_append_chars_nocount(buf, tmpbuf); if (fmt[i] == 'p' && !(verbose & VERBOSE_M_PASSWORD)) { buf_append_chars_nocount(buf, "\"\""); } else { buf_append_chars_nocount(buf, "\""); buf_append_bytes(buf, bufread_chars_noadjust(&br), size); bufread_glob(&br, size); buf_append_chars_nocount(buf, "\""); } break; } } buf_append_bytes(buf, "\0", 1); /* To make sure it's NUL-terminated */ i++; { int oldast = sys$setast(0); unsigned int status, space; if (fmt[i] == 'C') { status = FISH_M_CLIENTMSG; space = 77-19; } else { status = FISH_M_SERVMSG; space = 77-17; } if (!(verbose & VERBOSE_M_LONGINFO)) { if (buf_amount(buf) > 80) { buf_chop_at(buf, space - strlen(fmt+i)); buf_append_chars_nocount(buf, " .."); } lib$signal(status, 2, fmt+i, buf_chars_noadjust(buf)); } else { /* kludge because $PUTMSG won't output more than 255 bytes */ lib$signal(status, 2, fmt+i, ""); if (buf_amount(buf) >= 2) fprintf(stderr, "Data: %s\n", buf_chars_noadjust(buf) + 2); } sys$setast(oldast == SS$_WASSET); buf_destroy(buf); } return SS$_NORMAL; } /* Emacs local variables Local variables: eval: (set-c-style "BSD") end: */