⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rshd.c

📁 linux下常用的网络工具的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
       * to it, plus.       */      int lport = IPPORT_RESERVED - 1;      s = rresvport (&lport);      if (s < 0)	{	  syslog (LOG_ERR, "can't get stderr port: %m");	  exit (1);	}#if defined(KERBEROS) || defined(SHISHI)      if (!use_kerberos)#endif	if (port >= IPPORT_RESERVED || port < IPPORT_RESERVED/2)	  {	    syslog (LOG_ERR, "2nd port not reserved\n");	    exit (1);	  }      /* Use the fromp structure taht we already have.       * The 32-bit Internet address is obviously that of the       * client's, just change the port# to the one specified       * by the clent as the secondary port.       */      syslog (LOG_ERR, "2nd port not reserved %d\n", port);      fromp->sin_port = htons (port);      if (connect (s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0)	{	  syslog (LOG_INFO, "connect second port %d: %m", port);	  exit (1);	}    }#if defined(KERBEROS) || defined(SHISHI)  if (vacuous)    {      rshd_error ("rshd: remote host requires Kerberos authentication\n");      exit (1);    }#endif  /* from inetd, socket is already on 0, 1, 2 */  if (sockfd != STDIN_FILENO)    {      dup2 (sockfd, STDIN_FILENO);      dup2 (sockfd, STDOUT_FILENO);      dup2 (sockfd, STDERR_FILENO);    }  /* Get the "name" of the client from its Internet address.  This is   * used for the authentication below.   */  errorstr = NULL;  hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (struct in_addr),		     fromp->sin_family);  if (hp)    {      /*       * If name returned by gethostbyaddr is in our domain,       * attempt to verify that we haven't been fooled by someone       * in a remote net; look up the name and check that this       * address corresponds to the name.       */      hostname = strdup (hp->h_name);#if defined(KERBEROS) || defined(SHISHI)      if (!use_kerberos)#endif	if (check_all || local_domain (hp->h_name))	  {	    char *remotehost = (char *) alloca (strlen (hostname) + 1);	    if (! remotehost)	      errorstr = "Out of memory\n";	    else	      {		strcpy (remotehost, hostname);		errorhost = remotehost;		hp = gethostbyname (remotehost);		if (hp == NULL)		  {		    syslog (LOG_INFO,			    "Couldn't look up address for %s", remotehost);		    errorstr = "Couldn't look up address for your host (%s)\n";		    hostname = inet_ntoa (fromp->sin_addr);		  }		else		  for (; ; hp->h_addr_list++)		    {		      if (hp->h_addr_list[0] == NULL)			{			  syslog (LOG_NOTICE,				  "Host addr %s not listed for host %s",				  inet_ntoa (fromp->sin_addr), hp->h_name);			  errorstr = "Host address mismatch for %s\n";			  hostname = inet_ntoa (fromp->sin_addr);			  break;			}		      if (!memcmp (hp->h_addr_list[0],				   (caddr_t)&fromp->sin_addr,				   sizeof fromp->sin_addr))			{			  hostname = hp->h_name;			  break; /* equal, OK */			}		    }	      }	  }    }  else    errorhost = hostname = inet_ntoa (fromp->sin_addr);#ifdef	KERBEROS  if (use_kerberos)    {      kdata = (AUTH_DAT *) authbuf;      ticket = (KTEXT) tickbuf;      authopts = 0L;      strcpy (instance, "*");      version[VERSION_SIZE - 1] = '\0';#ifdef ENCRYPTION      if (doencrypt)	{	  struct sockaddr_in local_addr;	  rc = sizeof local_addr;	  if (getsockname (STDIN_FILENO,			   (struct sockaddr *)&local_addr, &rc) < 0)	    {	      syslog (LOG_ERR, "getsockname: %m");	      rshd_error ("rlogind: getsockname: %s", strerror (errno));	      exit (1);	    }	  authopts = KOPT_DO_MUTUAL;	  rc = krb_recvauth (authopts, 0, ticket,			     "rcmd", instance, &fromaddr,			     &local_addr, kdata, "", schedule,			     version);	  des_set_key (kdata->session, schedule);	}      else#endif	rc = krb_recvauth (authopts, 0, ticket, "rcmd",			   instance, &fromaddr,			   (struct sockaddr_in *) 0,			   kdata, "", (bit_64 *) 0, version);      if (rc != KSUCCESS)	{	  rshd_error ("Kerberos authentication failure: %s\n", krb_err_txt[rc]);	  exit (1);	}    }  else#elif defined (SHISHI)    if (use_kerberos)      {	int rc;	char *err_msg;	rc = get_auth (STDIN_FILENO, &h, &ap, &enckey, &err_msg, &protocol,		       &cksumtype, &cksum, &cksumlen);	if (rc != SHISHI_OK)	  {	    rshd_error ("Kerberos authentication failure: %s\n",			err_msg ? err_msg : shishi_strerror (rc));	  exit (1);	}      }  else#endif      remuser = getstr ("remuser");  /* Read three strings from the client. */  locuser = getstr ("locuser");  cmdbuf = getstr ("command");#ifdef SHISHI {   int error;   int rc;   char * compcksum;   size_t compcksumlen;   char cksumdata[100];   struct sockaddr_in sock;   size_t socklen;    #ifdef ENCRYPTION   if (strlen (cmdbuf) >= 3)     if (!strncmp (cmdbuf, "-x ", 3))       {	 doencrypt = 1;	 int i;	 ivtab[0] = &iv1;	 ivtab[1] = &iv2;	 ivtab[2] = &iv3;	 ivtab[3] = &iv4;	 keytype = shishi_key_type (enckey);	 keylen = shishi_cipher_blocksize (keytype);			 for (i=0; i<4; i++)	   {	     ivtab[i]->ivlen = keylen;	     switch (keytype)	       {	       case SHISHI_DES_CBC_CRC:	       case SHISHI_DES_CBC_MD4:	       case SHISHI_DES_CBC_MD5:	       case SHISHI_DES_CBC_NONE:	       case SHISHI_DES3_CBC_HMAC_SHA1_KD:		 ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;		 ivtab[i]->iv = malloc (ivtab[i]->ivlen);		 memset (ivtab[i]->iv, 2*i -3*(i>=2), ivtab[i]->ivlen);		 ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),						ivtab[i]->iv, ivtab[i]->ivlen);		 break;		 	       case SHISHI_ARCFOUR_HMAC:	       case SHISHI_ARCFOUR_HMAC_EXP:		 ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 4*(i<2) + 2 + 2*(i%2);		 ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),						NULL, 0);		 break;		 	       default :  		 ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 4*(i<2) + 2 + 2*(i%2);		 ivtab[i]->iv = malloc (ivtab[i]->ivlen);		 memset (ivtab[i]->iv, 0, ivtab[i]->ivlen);		 if (protocol == 2)		   ivtab[i]->ctx = shishi_crypto (h, enckey, ivtab[i]->keyusage, shishi_key_type (enckey),						  ivtab[i]->iv, ivtab[i]->ivlen);	       }	   }       }#endif   remuser = getstr ("remuser");   rc = read (STDIN_FILENO, &error, sizeof (int));   if ((rc != sizeof (int)) && rc)     exit (1);   /* verify checksum */      /* Doesn't give socket port ?    if (getsockname (STDIN_FILENO, (struct sockaddr *)&sock, &socklen) < 0)     {       syslog (LOG_ERR, "Can't get sock name");       exit (1);     }   */   snprintf (cksumdata, 100, "544:%s%s", /*ntohs(sock.sin_port),*/ cmdbuf, locuser);     rc = shishi_checksum (h, enckey, 0, cksumtype, cksumdata,			 strlen (cksumdata), &compcksum, &compcksumlen);   free (cksum);   if (rc != SHISHI_OK       || compcksumlen != cksumlen       || memcmp (compcksum, cksum, cksumlen) != 0)     {       /* err_msg crash ? */       /* *err_msg = "checksum verify failed"; */       syslog (LOG_ERR, "checksum verify failed: %s", shishi_error (h));       free (compcksum);       exit (1);            }   rc = shishi_authorized_p (h, shishi_ap_tkt (ap), locuser);   if (!rc)     {       syslog (LOG_ERR, "User is not authorized to log in as: %s", locuser);       shishi_ap_done (ap);       exit (1);     }   free (compcksum);   shishi_ap_done (ap); }#endif  /* Look up locuser in the passerd file.  The locuser has\* to be a   * valid account on this system.   */  setpwent ();  pwd = getpwnam (locuser);  if (pwd == NULL)    {      syslog (LOG_INFO|LOG_AUTH, "%s@%s as %s: unknown login. cmd='%.80s'",	      remuser, hostname, locuser, cmdbuf);      if (errorstr == NULL)	errorstr = "Login incorrect.\n";      goto fail;    }#ifdef	KERBEROS  if (use_kerberos)    {      if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0')	{	  if (kuserok (kdata, locuser) != 0)	    {	      syslog (LOG_INFO|LOG_AUTH, "Kerberos rsh denied to %s.%s@%s",		      kdata->pname, kdata->pinst, kdata->prealm);	      rshd_error ("Permission denied.\n");	      exit (1);	    }	}    }  else#elif defined(SHISHI)  if (use_kerberos)    {/*      if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0')	{	  if (kuserok (kdata, locuser) != 0)	    {	      syslog (LOG_INFO|LOG_AUTH, "Kerberos rsh denied to %s.%s@%s",		      kdata->pname, kdata->pinst, kdata->prealm);	      rshd_error ("Permission denied.\n");	      exit (1);	    }	    }*/    }  else#endif    if (errorstr || pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0'	&& (iruserok (fromp->sin_addr.s_addr, pwd->pw_uid == 0,		      remuser, locuser)) < 0)      {	if (__rcmd_errstr)	  syslog (LOG_INFO|LOG_AUTH,		  "%s@%s as %s: permission denied (%s). cmd='%.80s'",		  remuser, hostname, locuser, __rcmd_errstr, cmdbuf);	else	  syslog (LOG_INFO|LOG_AUTH,		  "%s@%s as %s: permission denied. cmd='%.80s'",		  remuser, hostname, locuser, cmdbuf);      fail:	if (errorstr == NULL)	  errorstr = "Permission denied.\n";	rshd_error (errorstr, errorhost);	exit (1);      }  /* If the locuser isn't root, then check if logins are disabled. */  if (pwd->pw_uid && !access (PATH_NOLOGIN, F_OK))    {      rshd_error ("Logins currently disabled.\n");      exit (1);    }  /* Now write the null byte back to the client telling it   * that everything is OK.   * Note that this means that any error message that we generate   * from now on (such as the perror() if the execl() fails), won't   * be seen by the rcomd() fucntion, but will be seen by the   * application that called rcmd() when it reads from the socket.   */  if (write (STDERR_FILENO, "\0", 1) < 0)    {      rshd_error ("Lost connection.\n");      exit (1);    }  sent_null = 1;  if (port)    {      /* We nee a secondary channel,  Here's where we create       * the control process that'll handle this secondary       * channel.       * First create a pipe to use for communication between       * the parent and child, then fork.       */      if (pipe (pv) < 0)	{	  rshd_error ("Can't make pipe.\n");	  exit (1);	}#ifdef ENCRYPTION#if defined(KERBEROS) || defined(SHISHI)      if (doencrypt)	{	  if (pipe (pv1) < 0)	    {	      rshd_error ("Can't make 2nd pipe.\n");	      exit (1);	    }	  if (pipe (pv2) < 0)	    {	      rshd_error ("Can't make 3rd pipe.\n");	      exit (1);	    }	}#endif#endif      pid = fork ();      if (pid == -1)	{	  rshd_error ("Can't fork; try again.\n");	  exit (1);	}      if (pid)	{	  /* Parent process == control process.	   * We: (1) read from the pipe and write to s;	   *     (2) read from s and send corresponding	   *         signal.	   */#ifdef ENCRYPTION#if defined(KERBEROS)	  if (doencrypt)	    {	      static char msg[] = SECURE_MESSAGE;	      close (pv1[1]);	      close (pv2[1]);	      des_write (s, msg, sizeof(msg) - 1);	    }	  else#elif defined(SHISHI)	  if (doencrypt)	    {	      close (pv1[1]);	      close (pv2[1]);

⌨️ 快捷键说明

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