ssltap.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,340 行 · 第 1/3 页

C
1,340
字号
      break;    case 23 :      PR_fprintf(PR_STDOUT,"application_data)\n");      break;    default:      PR_fprintf(PR_STDOUT,"unknown)\n");      break;    }    PR_fprintf(PR_STDOUT,"   version = { %d,%d }\n",	       (PRUint32)sr.ver_maj,(PRUint32)sr.ver_min);    PR_fprintf(PR_STDOUT,"   length  = %d (0x%x)\n",    	(PRUint32)GET_SHORT(sr.length), (PRUint32)GET_SHORT(sr.length));    alloclen = recordsize;    PR_ASSERT(s->size >= alloclen);    if (s->size >= alloclen) {      tbuf = (unsigned char*) PR_Malloc(alloclen);      read_stream_bytes(tbuf, s, alloclen);      if (s->isEncrypted) {	PR_fprintf(PR_STDOUT,"            < encrypted >\n");      } else       switch(sr.type) {      case 20 : /* change_cipher_spec */	if (sslhexparse) print_hex(alloclen,tbuf);	s->isEncrypted = 1;  /* mark to say we can only dump hex form now on */	break;      case 21 : /* alert */	switch(tbuf[0]) {	case 1: PR_fprintf(PR_STDOUT, "   warning: "); break;	case 2: PR_fprintf(PR_STDOUT, "   fatal: "); break;	default: PR_fprintf(PR_STDOUT, "   unknown level %d: ", tbuf[0]); break;	}	switch(tbuf[1]) {	case 0:   PR_fprintf(PR_STDOUT, "close notify\n"); break;	case 10:  PR_fprintf(PR_STDOUT, "unexpected message\n"); break;	case 20:  PR_fprintf(PR_STDOUT, "bad record mac\n"); break;	case 21:  PR_fprintf(PR_STDOUT, "decryption failed\n"); break;	case 22:  PR_fprintf(PR_STDOUT, "record overflow\n"); break;	case 30:  PR_fprintf(PR_STDOUT, "decompression failure\n"); break;	case 40:  PR_fprintf(PR_STDOUT, "handshake failure\n"); break;	case 41:  PR_fprintf(PR_STDOUT, "no certificate\n"); break;	case 42:  PR_fprintf(PR_STDOUT, "bad certificate\n"); break;	case 43:  PR_fprintf(PR_STDOUT, "unsupported certificate\n"); break;	case 44:  PR_fprintf(PR_STDOUT, "certificate revoked\n"); break;	case 45:  PR_fprintf(PR_STDOUT, "certificate expired\n"); break;	case 46:  PR_fprintf(PR_STDOUT, "certificate unknown\n"); break;	case 47:  PR_fprintf(PR_STDOUT, "illegal parameter\n"); break;	case 48:  PR_fprintf(PR_STDOUT, "unknown CA\n"); break;	case 49:  PR_fprintf(PR_STDOUT, "access denied\n"); break;	case 50:  PR_fprintf(PR_STDOUT, "decode error\n"); break;	case 51:  PR_fprintf(PR_STDOUT, "decrypt error\n"); break;	case 60:  PR_fprintf(PR_STDOUT, "export restriction\n"); break;	case 70:  PR_fprintf(PR_STDOUT, "protocol version\n"); break;	case 71:  PR_fprintf(PR_STDOUT, "insufficient security\n"); break;	case 80:  PR_fprintf(PR_STDOUT, "internal error\n"); break;	case 90:  PR_fprintf(PR_STDOUT, "user canceled\n"); break;	case 100: PR_fprintf(PR_STDOUT, "no renegotiation\n"); break;	default:  PR_fprintf(PR_STDOUT, "unknown error %d\n", tbuf[1]); break;	}	if (sslhexparse) print_hex(alloclen,tbuf);	break;      case 22 : /* handshake */ 	        print_ssl3_handshake( tbuf, alloclen, &sr );	break;      case 23 : /* application data */      default:	print_hex(alloclen,tbuf);	break;      }    }    PR_fprintf(PR_STDOUT,"}\n");    PR_FREEIF(tbuf);    check_integrity(s);  }}void print_hex(int amt, unsigned char *buf) {  int i,j,k;  char *string = (char*)PR_Malloc(5000);  char t[20];  for(i=0;i<amt;i++) {    t[1] =0;    if (i%16 ==0) {  /* if we are at the beginning of a line */      PR_fprintf(PR_STDOUT,"%4x:",i); /* print the line number  */      strcpy(string,"");    }    if (i%4 == 0) {      PR_fprintf(PR_STDOUT," ");    }    t[0] = buf[i];    if (!isprint(t[0])) {      t[0] = '.';    }    if (fancy)  {      switch (t[0]) {      case '<':        strcpy(t,"&lt;");        break;      case '>':        strcpy(t,"&gt;");        break;      case '&':        strcpy(t,"&amp;");        break;      }    }    strcat(string,t);    PR_fprintf(PR_STDOUT,"%02x ",(PRUint8) buf[i]);    /* if we've reached the end of the line - add the string */    if (i%16 == 15) PR_fprintf(PR_STDOUT," | %s\n",string);  }  /* we reached the end of the buffer,*/  /* do we have buffer left over? */  j = i%16;  if (j > 0) {    for (k=0;k<(16-j);k++) PR_fprintf(PR_STDOUT,"   ");    PR_fprintf(PR_STDOUT," |%s\n",string);  }  PR_Free(string);}void Usage(void) {  PR_fprintf(PR_STDERR, "SSLTAP (C) 1997, 1998 Netscape Communications Corporation.\n");  PR_fprintf(PR_STDERR, "Usage: ssltap [-vhfsxl] [-p port] hostname:port\n");  PR_fprintf(PR_STDERR, "   -v      [prints version string]\n");  PR_fprintf(PR_STDERR, "   -h      [outputs hex instead of ASCII]\n");  PR_fprintf(PR_STDERR, "   -f      [turn on Fancy HTML coloring]\n");  PR_fprintf(PR_STDERR, "   -s      [turn on SSL decoding]\n");  PR_fprintf(PR_STDERR, "   -x      [turn on extra SSL hex dumps]\n");  PR_fprintf(PR_STDERR, "   -p port [specify rendezvous port (default 1924)]\n");  PR_fprintf(PR_STDERR, "   -l      [loop - continue to wait for more connections]\n");}voidshowErr(const char * msg) {  PRErrorCode  err       = PR_GetError();  const char * errString;  if (err == PR_UNKNOWN_ERROR)    err = PR_CONNECT_RESET_ERROR;	/* bug in NSPR. */  errString = SECU_Strerror(err);  if (!errString)    errString = "(no text available)";  PR_fprintf(PR_STDERR, "Error %d: %s: %s", err, errString, msg);}int main(int argc,  char *argv[]){  char *hostname;  PRUint16 rendport=DEFPORT,port;  PRHostEnt hp;  PRStatus r;  PRNetAddr na_client,na_server,na_rend;  PRFileDesc *s_server,*s_client,*s_rend; /*rendezvous */  char netdbbuf[PR_NETDB_BUF_SIZE];  int c_count=0;  PLOptState *optstate;  PLOptStatus status;  optstate = PL_CreateOptState(argc,argv,"fvxhslp:");    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {    switch (optstate->option) {    case 'f':      fancy++;      break;    case 'h':      hexparse++;      break;    case 'v':      PR_fprintf(PR_STDOUT,"Version: %s\n",VERSIONSTRING);      break;    case 's':      sslparse++;      break;    case 'x':      sslhexparse++;      break;    case 'l':      looparound++;      break;    case 'p':      rendport = atoi(optstate->value);      break;    case '\0':      hostname = PL_strdup(optstate->value);    }  }  if (status == PL_OPT_BAD)    Usage();  if (fancy) {    if (!hexparse && !sslparse) {      PR_fprintf(PR_STDERR,"Note: use of -f without -s or -h not recommended, \n""as the output looks a little strange. It may be useful, however\n");    }  }  if(! hostname ) Usage(), exit(2);  {    char *colon = (char *)strchr(hostname, ':');    if (!colon) {      PR_fprintf(PR_STDERR,      "You must specify the host AND port you wish to connect to\n");      Usage(), exit(3);    }    port = atoi(&colon[1]);    *colon = '\0';    if (port == 0) {	PR_fprintf(PR_STDERR, "Port must be a nonzero number.\n");	exit(4);      }  }  /* find the 'server' IP address so we don't have to look it up later */  if (fancy) {      PR_fprintf(PR_STDOUT,"<HTML><HEAD><TITLE>SSLTAP output</TITLE></HEAD>\n");      PR_fprintf(PR_STDOUT,"<BODY><PRE>\n");    }  PR_fprintf(PR_STDERR,"Looking up \"%s\"...\n", hostname);  r = PR_GetHostByName(hostname,netdbbuf,PR_NETDB_BUF_SIZE,&hp);  if (r) {    showErr("Host Name lookup failed\n");    exit(5);  }  PR_EnumerateHostEnt(0,&hp,0,&na_server);  PR_InitializeNetAddr(PR_IpAddrNull,port,&na_server);  /* set up the port which the client will connect to */  r = PR_InitializeNetAddr(PR_IpAddrAny,rendport,&na_rend);  if (r == PR_FAILURE) {    PR_fprintf(PR_STDERR,    "PR_InitializeNetAddr(,%d,) failed with error %d\n",PR_GetError());    exit(0);  }  s_rend = PR_NewTCPSocket();  if (!s_rend) {    showErr("Couldn't create socket\n");    exit(6);  }  if (PR_Bind(s_rend, &na_rend )) {    PR_fprintf(PR_STDERR,"Couldn't bind to port %d (error %d)\n",rendport, PR_GetError());    exit(-1);  }  if ( PR_Listen(s_rend, 5)) {    showErr("Couldn't listen\n");    exit(-1);  }  PR_fprintf(PR_STDERR,"Proxy socket ready and listening\n");  do {	/* accept one connection and process it. */      PRPollDesc pds[2];      s_client = PR_Accept(s_rend,&na_client,PR_SecondsToInterval(3600));      if (s_client == NULL) {	showErr("accept timed out\n");	exit(7);      }      s_server = PR_NewTCPSocket();      if (s_server == NULL) {	showErr("couldn't open new socket to connect to server \n");	exit(8);      }      r = PR_Connect(s_server,&na_server,PR_SecondsToInterval(5));      if ( r == PR_FAILURE )        {	  showErr("Couldn't connect\n");	  return -1;        }      if (looparound) {	if (fancy)  PR_fprintf(PR_STDOUT,"<p><HR><H2>");	PR_fprintf(PR_STDOUT,"Connection #%d [%s]\n", c_count+1,	                     get_time_string());	if (fancy)  PR_fprintf(PR_STDOUT,"</H2>");	}      PR_fprintf(PR_STDOUT,"Connected to %s:%d\n", hostname, port);#define PD_C 0#define PD_S 1      pds[PD_C].fd = s_client;      pds[PD_S].fd = s_server;      pds[PD_C].in_flags = PR_POLL_READ;      pds[PD_S].in_flags = PR_POLL_READ;      /* make sure the new connections don't start out encrypted. */      clientstream.isEncrypted = 0;      serverstream.isEncrypted = 0;      isV2Session = 0;      while( (pds[PD_C].in_flags & PR_POLL_READ) != 0 ||             (pds[PD_S].in_flags & PR_POLL_READ) != 0 )        {  /* Handle all messages on the connection */	  PRInt32 amt;	  PRInt32 wrote;	  unsigned char buffer[ TAPBUFSIZ ];	  amt = PR_Poll(pds,2,PR_INTERVAL_NO_TIMEOUT);	  if (amt <= 0) {	    if (amt)		showErr( "PR_Poll failed.\n");	    else		showErr( "PR_Poll timed out.\n");	    break;	  }	  if (pds[PD_C].out_flags & PR_POLL_EXCEPT) {	    showErr( "Exception on client-side socket.\n");	    break;	  }	  if (pds[PD_S].out_flags & PR_POLL_EXCEPT) {	    showErr( "Exception on server-side socket.\n");	    break;	  }/* read data, copy it to stdout, and write to other socket */	  if ((pds[PD_C].in_flags  & PR_POLL_READ) != 0 &&	      (pds[PD_C].out_flags & PR_POLL_READ) != 0 ) {	    amt = PR_Read(s_client, buffer, sizeof(buffer));	    if ( amt < 0)  {	      showErr( "Client socket read failed.\n");	      break;	    }	    if( amt == 0 ) {	      PR_fprintf(PR_STDOUT, "Read EOF on Client socket. [%s]\n",	                            get_time_string() );	      pds[PD_C].in_flags &= ~PR_POLL_READ;	      PR_Shutdown(s_server, PR_SHUTDOWN_SEND);	      continue;	    }	    PR_fprintf(PR_STDOUT,"--> [\n");	    if (fancy) PR_fprintf(PR_STDOUT,"<font color=blue>");	    if (hexparse)  print_hex(amt, buffer);	    if (sslparse)  print_ssl(&clientstream,amt,buffer);	    if (!hexparse && !sslparse)  PR_Write(PR_STDOUT,buffer,amt);	    if (fancy) PR_fprintf(PR_STDOUT,"</font>");	    PR_fprintf(PR_STDOUT,"]\n");	    wrote = PR_Write(s_server, buffer, amt);	    if (wrote != amt )  {	      if (wrote < 0) {	        showErr("Write to server socket failed.\n");		break;	      } else {		PR_fprintf(PR_STDERR, "Short write to server socket!\n");	      }	    }	  }  /* end of read from client socket. *//* read data, copy it to stdout, and write to other socket */	  if ((pds[PD_S].in_flags  & PR_POLL_READ) != 0 &&	      (pds[PD_S].out_flags & PR_POLL_READ) != 0 ) {	    amt = PR_Read(s_server, buffer, sizeof(buffer));	    if ( amt < 0)  {	      showErr( "error on server-side socket.\n");	      break;	    }	    if( amt == 0 ) {	      PR_fprintf(PR_STDOUT, "Read EOF on Server socket. [%s]\n",	                            get_time_string() );	      pds[PD_S].in_flags &= ~PR_POLL_READ;	      PR_Shutdown(s_client, PR_SHUTDOWN_SEND);	      continue;	    } 	    PR_fprintf(PR_STDOUT,"<-- [\n");	    if (fancy) PR_fprintf(PR_STDOUT,"<font color=red>");	    if (hexparse)  print_hex(amt, (unsigned char *)buffer);	    if (sslparse)  print_ssl(&serverstream,amt,(unsigned char *)buffer);	    if (!hexparse && !sslparse)  PR_Write(PR_STDOUT,buffer,amt);	    if (fancy) PR_fprintf(PR_STDOUT,"</font>");	    PR_fprintf(PR_STDOUT,"]\n");	    wrote = PR_Write(s_client, buffer, amt);	    if (wrote != amt )  {	      if (wrote < 0) {	        showErr("Write to client socket failed.\n");		break;	      } else {		PR_fprintf(PR_STDERR, "Short write to client socket!\n");	      }	    }	  } /* end of read from server socket. *//* Loop, handle next message. */        }	/* handle messages during a connection loop */      PR_Close(s_client);      PR_Close(s_server);      flush_stream(&clientstream);      flush_stream(&serverstream);      c_count++;      PR_fprintf(PR_STDERR,"Connection %d Complete [%s]\n", c_count,                            get_time_string() );    }  while (looparound); /* accept connection and process it. */    PR_Close(s_rend);    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?